Commit 112fa786 authored by Sandeep Mistry's avatar Sandeep Mistry

Functional analogWrite

parent cef25b74
...@@ -27,8 +27,9 @@ ...@@ -27,8 +27,9 @@
#include <stdint.h> #include <stdint.h>
#include "nrf.h" #include "nrf.h"
#ifndef ARDUINO
#include "nrf_assert.h" #include "nrf_assert.h"
#endif
/** /**
* @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set * @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set
...@@ -584,7 +585,9 @@ __STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm, ...@@ -584,7 +585,9 @@ __STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm,
nrf_pwm_mode_t mode, nrf_pwm_mode_t mode,
uint16_t top_value) uint16_t top_value)
{ {
#ifndef ARDUINO
ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk); ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
#endif
p_pwm->PRESCALER = base_clock; p_pwm->PRESCALER = base_clock;
p_pwm->MODE = mode; p_pwm->MODE = mode;
...@@ -595,7 +598,9 @@ __STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm, ...@@ -595,7 +598,9 @@ __STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id, uint8_t seq_id,
nrf_pwm_sequence_t const * p_seq) nrf_pwm_sequence_t const * p_seq)
{ {
#ifndef ARDUINO
ASSERT(p_seq != NULL); ASSERT(p_seq != NULL);
#endif
nrf_pwm_seq_ptr_set( p_pwm, seq_id, p_seq->values.p_raw); nrf_pwm_seq_ptr_set( p_pwm, seq_id, p_seq->values.p_raw);
nrf_pwm_seq_cnt_set( p_pwm, seq_id, p_seq->length); nrf_pwm_seq_cnt_set( p_pwm, seq_id, p_seq->length);
...@@ -607,8 +612,10 @@ __STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm, ...@@ -607,8 +612,10 @@ __STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id, uint8_t seq_id,
uint16_t const * p_values) uint16_t const * p_values)
{ {
#ifndef ARDUINO
ASSERT(seq_id <= 1); ASSERT(seq_id <= 1);
ASSERT(p_values != NULL); ASSERT(p_values != NULL);
#endif
p_pwm->SEQ[seq_id].PTR = (uint32_t)p_values; p_pwm->SEQ[seq_id].PTR = (uint32_t)p_values;
} }
...@@ -616,9 +623,11 @@ __STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm, ...@@ -616,9 +623,11 @@ __STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id, uint8_t seq_id,
uint16_t length) uint16_t length)
{ {
#ifndef ARDUINO
ASSERT(seq_id <= 1); ASSERT(seq_id <= 1);
ASSERT(length != 0); ASSERT(length != 0);
ASSERT(length <= PWM_SEQ_CNT_CNT_Msk); ASSERT(length <= PWM_SEQ_CNT_CNT_Msk);
#endif
p_pwm->SEQ[seq_id].CNT = length; p_pwm->SEQ[seq_id].CNT = length;
} }
...@@ -626,8 +635,10 @@ __STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm, ...@@ -626,8 +635,10 @@ __STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id, uint8_t seq_id,
uint32_t refresh) uint32_t refresh)
{ {
#ifndef ARDUINO
ASSERT(seq_id <= 1); ASSERT(seq_id <= 1);
ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk); ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk);
#endif
p_pwm->SEQ[seq_id].REFRESH = refresh; p_pwm->SEQ[seq_id].REFRESH = refresh;
} }
...@@ -635,8 +646,10 @@ __STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm, ...@@ -635,8 +646,10 @@ __STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id, uint8_t seq_id,
uint32_t end_delay) uint32_t end_delay)
{ {
#ifndef ARDUINO
ASSERT(seq_id <= 1); ASSERT(seq_id <= 1);
ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk); ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk);
#endif
p_pwm->SEQ[seq_id].ENDDELAY = end_delay; p_pwm->SEQ[seq_id].ENDDELAY = end_delay;
} }
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "nrf_saadc.h"
#include "nrf_pwm.h"
#include "Arduino.h" #include "Arduino.h"
#include "wiring_private.h" #include "wiring_private.h"
...@@ -23,78 +26,49 @@ ...@@ -23,78 +26,49 @@
extern "C" { extern "C" {
#endif #endif
// static int _readResolution = 10; #define PWM_COUNT 3
// static int _ADCResolution = 10;
// static int _writeResolution = 8;
// // Wait for synchronization of registers between the clock domains
// static __inline__ void syncADC() __attribute__((always_inline, unused));
// static void syncADC() {
// while (ADC->STATUS.bit.SYNCBUSY == 1)
// ;
// }
// // Wait for synchronization of registers between the clock domains static NRF_PWM_Type* pwms[PWM_COUNT] = {
// static __inline__ void syncDAC() __attribute__((always_inline, unused)); NRF_PWM0,
// static void syncDAC() { NRF_PWM1,
// while (DAC->STATUS.bit.SYNCBUSY == 1) NRF_PWM2
// ; };
// }
// // Wait for synchronization of registers between the clock domains static uint32_t pwmChannelPins[PWM_COUNT] = {
// static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused)); NRF_PWM_PIN_NOT_CONNECTED,
// static void syncTC_8(Tc* TCx) { NRF_PWM_PIN_NOT_CONNECTED,
// while (TCx->COUNT8.STATUS.bit.SYNCBUSY); NRF_PWM_PIN_NOT_CONNECTED
// } };
// // Wait for synchronization of registers between the clock domains static uint16_t pwmChannelSequence[PWM_COUNT];
// static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
// static void syncTCC(Tcc* TCCx) {
// while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
// }
// void analogReadResolution( int res ) static int writeResolution = 8;
// {
// _readResolution = res ;
// if (res > 10)
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
// _ADCResolution = 12;
// }
// else if (res > 8)
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
// _ADCResolution = 10;
// }
// else
// {
// ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val;
// _ADCResolution = 8;
// }
// syncADC();
// }
// void analogWriteResolution( int res ) void analogReadResolution( int res )
// { {
// _writeResolution = res ; }
// }
// static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to ) void analogWriteResolution( int res )
// { {
// if ( from == to ) writeResolution = res;
// { }
// return value ;
// }
// if ( from > to ) static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to )
// { {
// return value >> (from-to) ; if ( from == to )
// } {
// else return value ;
// { }
// return value << (to-from) ;
// } if ( from > to )
// } {
return value >> (from-to) ;
}
else
{
return value << (to-from) ;
}
}
/* /*
* Internal Reference is at 1.0v * Internal Reference is at 1.0v
...@@ -104,242 +78,40 @@ extern "C" { ...@@ -104,242 +78,40 @@ extern "C" {
*/ */
void analogReference( eAnalogReference ulMode ) void analogReference( eAnalogReference ulMode )
{ {
// syncADC();
// switch ( ulMode )
// {
// case AR_INTERNAL:
// case AR_INTERNAL2V23:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
// break;
// case AR_EXTERNAL:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
// break;
// case AR_INTERNAL1V0:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val; // 1.0V voltage reference
// break;
// case AR_INTERNAL1V65:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
// break;
// case AR_DEFAULT:
// default:
// ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
// ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
// break;
// }
} }
uint32_t analogRead( uint32_t ulPin ) uint32_t analogRead( uint32_t ulPin )
{ {
// uint32_t valueRead = 0;
// if ( ulPin < A0 )
// {
// ulPin += A0 ;
// }
// pinPeripheral(ulPin, PIO_ANALOG);
// if (ulPin == A0) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
// {
// syncDAC();
// DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC
// //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off.
// syncDAC();
// }
// syncADC();
// ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber; // Selection for the positive ADC input
// // Control A
// * Bit 1 ENABLE: Enable
// * 0: The ADC is disabled.
// * 1: The ADC is enabled.
// * Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The
// * value written to CTRL.ENABLE will read back immediately and the Synchronization Busy bit in the Status register
// * (STATUS.SYNCBUSY) will be set. STATUS.SYNCBUSY will be cleared when the operation is complete.
// *
// * Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be
// * configured. The first conversion after the reference is changed must not be used.
// syncADC();
// ADC->CTRLA.bit.ENABLE = 0x01; // Enable ADC
// // Start conversion
// syncADC();
// ADC->SWTRIG.bit.START = 1;
// // Clear the Data Ready flag
// ADC->INTFLAG.bit.RESRDY = 1;
// // Start conversion again, since The first conversion after the reference is changed must not be used.
// syncADC();
// ADC->SWTRIG.bit.START = 1;
// // Store the value
// while ( ADC->INTFLAG.bit.RESRDY == 0 ); // Waiting for conversion to complete
// valueRead = ADC->RESULT.reg;
// syncADC();
// ADC->CTRLA.bit.ENABLE = 0x00; // Disable ADC
// syncADC();
// return mapResolution(valueRead, _ADCResolution, _readResolution);
return 0; return 0;
} }
// Right now, PWM output only works on the pins with // Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate // hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default // pins_*.c file. For the rest of the pins, we default
// to digital output. // to digital output.
void analogWrite( uint32_t ulPin, uint32_t ulValue ) void analogWrite( uint32_t ulPin, uint32_t ulValue )
{ {
// uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ; for (int i = 0; i < PWM_COUNT; i++) {
if (pwmChannelPins[i] == NRF_PWM_PIN_NOT_CONNECTED || pwmChannelPins[i] == ulPin) {
// if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG ) pwmChannelPins[i] = ulPin;
// { pwmChannelSequence[i] = ulValue;
// if ( ulPin != PIN_A0 ) // Only 1 DAC on A0 (PA02)
// { NRF_PWM_Type* pwm = pwms[i];
// return;
// } nrf_pwm_pins_set(pwm, pwmChannelPins);
nrf_pwm_enable(pwm);
// ulValue = mapResolution(ulValue, _writeResolution, 10); nrf_pwm_configure(pwm, NRF_PWM_CLK_16MHz, NRF_PWM_MODE_UP, (1 << writeResolution) - 1);
nrf_pwm_loop_set(pwm, 0);
// syncDAC(); nrf_pwm_decoder_set(pwm, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO);
// DAC->DATA.reg = ulValue & 0x3FF; // DAC on 10 bits. nrf_pwm_seq_ptr_set(pwm, 0, &pwmChannelSequence[i]);
// syncDAC(); nrf_pwm_seq_cnt_set(pwm, 0, 1);
// DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC nrf_pwm_seq_refresh_set(pwm, 0, 1);
// syncDAC(); nrf_pwm_seq_end_delay_set(pwm, 0, 0);
// return ; nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
// }
break;
// if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM ) }
// { }
// if (attr & PIN_ATTR_TIMER) {
// #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603)
// // Compatibility for cores based on SAMD core <=1.6.2
// if (g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT) {
// pinPeripheral(ulPin, PIO_TIMER_ALT);
// } else
// #endif
// {
// pinPeripheral(ulPin, PIO_TIMER);
// }
// } else {
// // We suppose that attr has PIN_ATTR_TIMER_ALT bit set...
// pinPeripheral(ulPin, PIO_TIMER_ALT);
// }
// Tc* TCx = 0 ;
// Tcc* TCCx = 0 ;
// uint8_t Channelx = GetTCChannelNumber( g_APinDescription[ulPin].ulPWMChannel ) ;
// if ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) >= TCC_INST_NUM )
// {
// TCx = (Tc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ;
// }
// else
// {
// TCCx = (Tcc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ;
// }
// // Enable clocks according to TCCx instance to use
// switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) )
// {
// case 0: // TCC0
// case 1: // TCC1
// // Enable GCLK for TCC0 and TCC1 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
// break ;
// case 2: // TCC2
// case 3: // TC3
// // Enable GCLK for TCC2 and TC3 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;
// break ;
// case 4: // TC4
// case 5: // TC5
// // Enable GCLK for TC4 and TC5 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 ));
// break ;
// case 6: // TC6 (not available on Zero)
// case 7: // TC7 (not available on Zero)
// // Enable GCLK for TC6 and TC7 (timer counter input clock)
// GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC6_TC7 ));
// break ;
// }
// while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
// ulValue = mapResolution(ulValue, _writeResolution, 8);
// // Set PORT
// if ( TCx )
// {
// // -- Configure TC
// // Disable TCx
// TCx->COUNT8.CTRLA.reg &= ~TC_CTRLA_ENABLE;
// syncTC_8(TCx);
// // Set Timer counter Mode to 8 bits
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8;
// // Set TCx as normal PWM
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
// // Set TCx in waveform mode Normal PWM
// TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue;
// syncTC_8(TCx);
// // Set PER to maximum counter value (resolution : 0xFF)
// TCx->COUNT8.PER.reg = 0xFF;
// syncTC_8(TCx);
// // Enable TCx
// TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
// syncTC_8(TCx);
// }
// else
// {
// // -- Configure TCC
// // Disable TCCx
// TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
// syncTCC(TCCx);
// // Set TCx as normal PWM
// TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
// syncTCC(TCCx);
// // Set TCx in waveform mode Normal PWM
// TCCx->CC[Channelx].reg = (uint32_t)ulValue;
// syncTCC(TCCx);
// // Set PER to maximum counter value (resolution : 0xFF)
// TCCx->PER.reg = 0xFF;
// syncTCC(TCCx);
// // Enable TCCx
// TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
// syncTCC(TCCx);
// }
// return ;
// }
// // -- Defaults to digital write
// pinMode( ulPin, OUTPUT ) ;
// ulValue = mapResolution(ulValue, _writeResolution, 8);
// if ( ulValue < 128 )
// {
// digitalWrite( ulPin, LOW ) ;
// }
// else
// {
// digitalWrite( ulPin, HIGH ) ;
// }
} }
#ifdef __cplusplus #ifdef __cplusplus
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment