Commit d9eff10f authored by Sandeep Mistry's avatar Sandeep Mistry

Initial nRF51 analogWrite support via timer

parent 3c8c938d
......@@ -18,6 +18,9 @@
#ifdef NRF51
#include "nrf_timer.h"
#include "nrf_gpio.h"
#include "Arduino.h"
#include "wiring_private.h"
......@@ -25,8 +28,27 @@
extern "C" {
#endif
static int readResolution = 10;
static int writeResolution = 8;
#define PWM_COUNT 3
#define PIN_FREE 0xffffffff
struct PWMContext {
uint32_t pin;
uint32_t value;
nrf_timer_cc_channel_t channel;
nrf_timer_int_mask_t mask;
nrf_timer_event_t event;
};
static struct PWMContext pwmContext[PWM_COUNT] = {
{ PIN_FREE, 0, NRF_TIMER_CC_CHANNEL1, NRF_TIMER_INT_COMPARE1_MASK, NRF_TIMER_EVENT_COMPARE1 },
{ PIN_FREE, 0, NRF_TIMER_CC_CHANNEL2, NRF_TIMER_INT_COMPARE2_MASK, NRF_TIMER_EVENT_COMPARE2 },
{ PIN_FREE, 0, NRF_TIMER_CC_CHANNEL3, NRF_TIMER_INT_COMPARE3_MASK, NRF_TIMER_EVENT_COMPARE3 }
};
static int timerEnabled = 0;
static uint32_t readResolution = 10;
static uint32_t writeResolution = 8;
void analogReadResolution( int res )
{
......@@ -63,7 +85,6 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
*/
void analogReference( eAnalogReference ulMode )
{
return 0;
}
// Right now, PWM output only works on the pins with
......@@ -72,7 +93,67 @@ void analogReference( eAnalogReference ulMode )
// to digital output.
void analogWrite( uint32_t ulPin, uint32_t ulValue )
{
if (ulPin >= PINS_COUNT) {
return;
}
ulPin = g_ADigitalPinMap[ulPin];
if (!timerEnabled) {
NVIC_SetPriority(TIMER1_IRQn, 3);
NVIC_ClearPendingIRQ(TIMER1_IRQn);
NVIC_EnableIRQ(TIMER1_IRQn);
nrf_timer_mode_set(NRF_TIMER1, NRF_TIMER_MODE_TIMER);
nrf_timer_bit_width_set(NRF_TIMER1, NRF_TIMER_BIT_WIDTH_8);
nrf_timer_frequency_set(NRF_TIMER1, NRF_TIMER_FREQ_125kHz);
nrf_timer_cc_write(NRF_TIMER1, NRF_TIMER_CC_CHANNEL0, 0);
nrf_timer_int_enable(NRF_TIMER1, NRF_TIMER_INT_COMPARE0_MASK);
nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_START);
timerEnabled = true;
}
for (int i = 0; i < PWM_COUNT; i++) {
if (pwmContext[i].pin == PIN_FREE || pwmContext[i].pin == ulPin) {
pwmContext[i].pin = ulPin;
nrf_gpio_cfg_output(ulPin);
ulValue = mapResolution(ulValue, writeResolution, 8);
pwmContext[i].value = ulValue;
nrf_timer_cc_write(NRF_TIMER1, pwmContext[i].channel, ulValue);
nrf_timer_int_enable(NRF_TIMER1, pwmContext[i].mask);
break;
}
}
}
void TIMER1_IRQHandler(void)
{
if (nrf_timer_event_check(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0)) {
for (int i = 0; i < PWM_COUNT; i++) {
if (pwmContext[i].pin != PIN_FREE && pwmContext[i].value != 0) {
nrf_gpio_pin_write(pwmContext[i].pin, 1);
}
}
nrf_timer_event_clear(NRF_TIMER1, NRF_TIMER_EVENT_COMPARE0);
}
for (int i = 0; i < PWM_COUNT; i++) {
if (nrf_timer_event_check(NRF_TIMER1, pwmContext[i].event)) {
if (pwmContext[i].pin != PIN_FREE && pwmContext[i].value != 255) {
nrf_gpio_pin_write(pwmContext[i].pin, 0);
}
nrf_timer_event_clear(NRF_TIMER1, pwmContext[i].event);
}
}
}
#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