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

Functional analogWrite

parent cef25b74
......@@ -27,8 +27,9 @@
#include <stdint.h>
#include "nrf.h"
#ifndef ARDUINO
#include "nrf_assert.h"
#endif
/**
* @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,
nrf_pwm_mode_t mode,
uint16_t top_value)
{
#ifndef ARDUINO
ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
#endif
p_pwm->PRESCALER = base_clock;
p_pwm->MODE = mode;
......@@ -595,7 +598,9 @@ __STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_seq)
{
#ifndef ARDUINO
ASSERT(p_seq != NULL);
#endif
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);
......@@ -607,8 +612,10 @@ __STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint16_t const * p_values)
{
#ifndef ARDUINO
ASSERT(seq_id <= 1);
ASSERT(p_values != NULL);
#endif
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,
uint8_t seq_id,
uint16_t length)
{
#ifndef ARDUINO
ASSERT(seq_id <= 1);
ASSERT(length != 0);
ASSERT(length <= PWM_SEQ_CNT_CNT_Msk);
#endif
p_pwm->SEQ[seq_id].CNT = length;
}
......@@ -626,8 +635,10 @@ __STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint32_t refresh)
{
#ifndef ARDUINO
ASSERT(seq_id <= 1);
ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk);
#endif
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,
uint8_t seq_id,
uint32_t end_delay)
{
#ifndef ARDUINO
ASSERT(seq_id <= 1);
ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk);
#endif
p_pwm->SEQ[seq_id].ENDDELAY = end_delay;
}
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "nrf_saadc.h"
#include "nrf_pwm.h"
#include "Arduino.h"
#include "wiring_private.h"
......@@ -23,78 +26,49 @@
extern "C" {
#endif
// static int _readResolution = 10;
// 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)
// ;
// }
#define PWM_COUNT 3
// // Wait for synchronization of registers between the clock domains
// static __inline__ void syncDAC() __attribute__((always_inline, unused));
// static void syncDAC() {
// while (DAC->STATUS.bit.SYNCBUSY == 1)
// ;
// }
static NRF_PWM_Type* pwms[PWM_COUNT] = {
NRF_PWM0,
NRF_PWM1,
NRF_PWM2
};
// // Wait for synchronization of registers between the clock domains
// static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused));
// static void syncTC_8(Tc* TCx) {
// while (TCx->COUNT8.STATUS.bit.SYNCBUSY);
// }
static uint32_t pwmChannelPins[PWM_COUNT] = {
NRF_PWM_PIN_NOT_CONNECTED,
NRF_PWM_PIN_NOT_CONNECTED,
NRF_PWM_PIN_NOT_CONNECTED
};
// // Wait for synchronization of registers between the clock domains
// static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
// static void syncTCC(Tcc* TCCx) {
// while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
// }
static uint16_t pwmChannelSequence[PWM_COUNT];
// void analogReadResolution( int res )
// {
// _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();
// }
static int writeResolution = 8;
// void analogWriteResolution( int res )
// {
// _writeResolution = res ;
// }
void analogReadResolution( int res )
{
}
// static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to )
// {
// if ( from == to )
// {
// return value ;
// }
void analogWriteResolution( int res )
{
writeResolution = res;
}
// if ( from > to )
// {
// return value >> (from-to) ;
// }
// else
// {
// return value << (to-from) ;
// }
// }
static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to )
{
if ( from == to )
{
return value ;
}
if ( from > to )
{
return value >> (from-to) ;
}
else
{
return value << (to-from) ;
}
}
/*
* Internal Reference is at 1.0v
......@@ -104,242 +78,40 @@ extern "C" {
*/
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 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;
}
// Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default
// to digital output.
void analogWrite( uint32_t ulPin, uint32_t ulValue )
{
// uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ;
// if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG )
// {
// if ( ulPin != PIN_A0 ) // Only 1 DAC on A0 (PA02)
// {
// return;
// }
// ulValue = mapResolution(ulValue, _writeResolution, 10);
// syncDAC();
// DAC->DATA.reg = ulValue & 0x3FF; // DAC on 10 bits.
// syncDAC();
// DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC
// syncDAC();
// return ;
// }
// 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 ) ;
// }
for (int i = 0; i < PWM_COUNT; i++) {
if (pwmChannelPins[i] == NRF_PWM_PIN_NOT_CONNECTED || pwmChannelPins[i] == ulPin) {
pwmChannelPins[i] = ulPin;
pwmChannelSequence[i] = ulValue;
NRF_PWM_Type* pwm = pwms[i];
nrf_pwm_pins_set(pwm, pwmChannelPins);
nrf_pwm_enable(pwm);
nrf_pwm_configure(pwm, NRF_PWM_CLK_16MHz, NRF_PWM_MODE_UP, (1 << writeResolution) - 1);
nrf_pwm_loop_set(pwm, 0);
nrf_pwm_decoder_set(pwm, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO);
nrf_pwm_seq_ptr_set(pwm, 0, &pwmChannelSequence[i]);
nrf_pwm_seq_cnt_set(pwm, 0, 1);
nrf_pwm_seq_refresh_set(pwm, 0, 1);
nrf_pwm_seq_end_delay_set(pwm, 0, 0);
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
break;
}
}
}
#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