2828extern "C" {
2929#endif
3030
31- #define PWM_COUNT 3
31+ #define PWM_COUNT 6
3232#define PIN_FREE 0xffffffff
3333
34+ struct PWMSrc {
35+ NRF_TIMER_Type * timer ;
36+ bool used ;
37+ };
38+
39+ struct PWMSrc srcs [2 ]= {
40+ {NRF_TIMER1 ,false},
41+ {NRF_TIMER2 ,false}
42+ };
43+
3444struct PWMContext {
3545 uint32_t pin ;
3646 uint32_t value ;
3747 uint32_t channel ;
3848 uint32_t mask ;
3949 uint32_t event ;
50+ int src ;
4051};
4152
4253static struct PWMContext pwmContext [PWM_COUNT ] = {
43- { PIN_FREE , 0 , 1 , TIMER_INTENSET_COMPARE1_Msk , 1 },
44- { PIN_FREE , 0 , 2 , TIMER_INTENSET_COMPARE2_Msk , 2 },
45- { PIN_FREE , 0 , 3 , TIMER_INTENSET_COMPARE3_Msk , 3 }
54+ { PIN_FREE , 0 , 1 , TIMER_INTENSET_COMPARE1_Msk , 1 , 0 },
55+ { PIN_FREE , 0 , 2 , TIMER_INTENSET_COMPARE2_Msk , 2 , 0 },
56+ { PIN_FREE , 0 , 3 , TIMER_INTENSET_COMPARE3_Msk , 3 , 0 },
57+ { PIN_FREE , 0 , 1 , TIMER_INTENSET_COMPARE1_Msk , 1 , 1 },
58+ { PIN_FREE , 0 , 2 , TIMER_INTENSET_COMPARE2_Msk , 2 , 1 },
59+ { PIN_FREE , 0 , 3 , TIMER_INTENSET_COMPARE3_Msk , 3 , 1 }
4660};
4761
48- static int timerEnabled = 0 ;
49-
5062static uint32_t adcReference = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling ;
5163static uint32_t adcPrescaling = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling ;
5264
@@ -217,6 +229,18 @@ uint32_t analogRead( uint32_t ulPin )
217229 return mapResolution (value , resolution , readResolution );
218230}
219231
232+ int getFreePwm () {
233+ for (int i = 0 ; i < PWM_COUNT ; i ++ )
234+ if (pwmContext [i ].pin == PIN_FREE ) return i ;
235+ return -1 ;
236+ }
237+
238+ int getPwmFromPin (uint32_t ulPin ) {
239+ for (int i = 0 ; i < PWM_COUNT ; i ++ )
240+ if (pwmContext [i ].pin == ulPin || pwmContext [i ].pin == PIN_FREE ) return i ;
241+ return -1 ;
242+ }
243+
220244// Right now, PWM output only works on the pins with
221245// hardware support. These are defined in the appropriate
222246// pins_*.c file. For the rest of the pins, we default
@@ -229,24 +253,34 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
229253
230254 ulPin = g_ADigitalPinMap [ulPin ];
231255
232- if (!timerEnabled ) {
233- NVIC_SetPriority (TIMER1_IRQn , 3 );
234- NVIC_ClearPendingIRQ (TIMER1_IRQn );
235- NVIC_EnableIRQ (TIMER1_IRQn );
256+ int pwm = getPwmFromPin (ulPin );
257+ struct PWMSrc * src = & srcs [pwmContext [pwm ].src ];
258+ NRF_TIMER_Type * pwmSrc = src -> timer ;
259+
260+ if (!src -> used ) {
236261
237- NRF_TIMER1 -> MODE = (NRF_TIMER1 -> MODE & ~TIMER_MODE_MODE_Msk ) | ((TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos ) & TIMER_MODE_MODE_Msk );
262+ if (pwmSrc == NRF_TIMER1 ) {
263+ NVIC_SetPriority (TIMER1_IRQn , 3 );
264+ NVIC_ClearPendingIRQ (TIMER1_IRQn );
265+ NVIC_EnableIRQ (TIMER1_IRQn );
266+ } else if (pwmSrc == NRF_TIMER2 ) {
267+ NVIC_SetPriority (TIMER2_IRQn , 4 );
268+ NVIC_ClearPendingIRQ (TIMER2_IRQn );
269+ NVIC_EnableIRQ (TIMER2_IRQn );
270+ } else return ;
271+ src -> used = true;
238272
239- NRF_TIMER1 -> BITMODE = (NRF_TIMER1 -> BITMODE & ~TIMER_BITMODE_BITMODE_Msk ) | ((TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos ) & TIMER_BITMODE_BITMODE_Msk );
273+ pwmSrc -> MODE = (pwmSrc -> MODE & ~TIMER_MODE_MODE_Msk ) | ((TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos ) & TIMER_MODE_MODE_Msk );
240274
241- NRF_TIMER1 -> PRESCALER = (NRF_TIMER1 -> PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk ) | ((7 << TIMER_PRESCALER_PRESCALER_Pos ) & TIMER_PRESCALER_PRESCALER_Msk );
275+ pwmSrc -> BITMODE = (pwmSrc -> BITMODE & ~TIMER_BITMODE_BITMODE_Msk ) | ((TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos ) & TIMER_BITMODE_BITMODE_Msk );
242276
243- NRF_TIMER1 -> CC [ 0 ] = 0 ;
277+ pwmSrc -> PRESCALER = ( pwmSrc -> PRESCALER & ~ TIMER_PRESCALER_PRESCALER_Msk ) | (( 7 << TIMER_PRESCALER_PRESCALER_Pos ) & TIMER_PRESCALER_PRESCALER_Msk ) ;
244278
245- NRF_TIMER1 -> INTENSET = TIMER_INTENSET_COMPARE0_Msk ;
279+ pwmSrc -> CC [ 0 ] = 0 ;
246280
247- NRF_TIMER1 -> TASKS_START = 0x1UL ;
281+ pwmSrc -> INTENSET = TIMER_INTENSET_COMPARE0_Msk ;
248282
249- timerEnabled = true ;
283+ pwmSrc -> TASKS_START = 0x1UL ;
250284 }
251285
252286 for (int i = 0 ; i < PWM_COUNT ; i ++ ) {
@@ -263,9 +297,9 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
263297
264298 pwmContext [i ].value = ulValue ;
265299
266- NRF_TIMER1 -> CC [pwmContext [i ].channel ] = ulValue ;
300+ pwmSrc -> CC [pwmContext [i ].channel ] = ulValue ;
267301
268- NRF_TIMER1 -> INTENSET = pwmContext [i ].mask ;
302+ pwmSrc -> INTENSET = pwmContext [i ].mask ;
269303
270304 break ;
271305 }
@@ -276,7 +310,7 @@ void TIMER1_IRQHandler(void)
276310{
277311 if (NRF_TIMER1 -> EVENTS_COMPARE [0 ]) {
278312 for (int i = 0 ; i < PWM_COUNT ; i ++ ) {
279- if (pwmContext [i ].pin != PIN_FREE && pwmContext [i ].value != 0 ) {
313+ if (pwmContext [i ].src == 0 && pwmContext [ i ]. pin != PIN_FREE /* && pwmContext[i].value != 0*/ ) {
280314 NRF_GPIO -> OUTSET = (1UL << pwmContext [i ].pin );
281315 }
282316 }
@@ -285,8 +319,8 @@ void TIMER1_IRQHandler(void)
285319 }
286320
287321 for (int i = 0 ; i < PWM_COUNT ; i ++ ) {
288- if (NRF_TIMER1 -> EVENTS_COMPARE [pwmContext [i ].event ]) {
289- if (pwmContext [i ].pin != PIN_FREE && pwmContext [i ].value != 255 ) {
322+ if (pwmContext [ i ]. src == 0 && NRF_TIMER1 -> EVENTS_COMPARE [pwmContext [i ].event ]) {
323+ if (pwmContext [i ].pin != PIN_FREE /* && pwmContext[i].value != 255*/ ) {
290324 NRF_GPIO -> OUTCLR = (1UL << pwmContext [i ].pin );
291325 }
292326
@@ -295,6 +329,29 @@ void TIMER1_IRQHandler(void)
295329 }
296330}
297331
332+ void TIMER2_IRQHandler (void )
333+ {
334+ if (NRF_TIMER2 -> EVENTS_COMPARE [0 ]) {
335+ for (int i = 0 ; i < PWM_COUNT ; i ++ ) {
336+ if (pwmContext [i ].src == 1 && pwmContext [i ].pin != PIN_FREE /*&& pwmContext[i].value != 0*/ ) {
337+ NRF_GPIO -> OUTSET = (1UL << pwmContext [i ].pin );
338+ }
339+ }
340+
341+ NRF_TIMER2 -> EVENTS_COMPARE [0 ] = 0x0UL ;
342+ }
343+
344+ for (int i = 0 ; i < PWM_COUNT ; i ++ ) {
345+ if (pwmContext [i ].src == 1 && NRF_TIMER2 -> EVENTS_COMPARE [pwmContext [i ].event ]) {
346+ if (pwmContext [i ].pin != PIN_FREE /*&& pwmContext[i].value != 255*/ ) {
347+ NRF_GPIO -> OUTCLR = (1UL << pwmContext [i ].pin );
348+ }
349+
350+ NRF_TIMER2 -> EVENTS_COMPARE [pwmContext [i ].event ] = 0x0UL ;
351+ }
352+ }
353+ }
354+
298355#ifdef __cplusplus
299356}
300357#endif
0 commit comments