This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem running a 10kHz PWM on a Timer

Hi,

I am trying to obtain a 10khz PWM (50%) on an output using Timer2 (see code below). It is working fine up to around 500Hz (2msec), above that (1kHz) I am getting only sporadic PWM bursts, PWM will run up to advertising then will stop, then timer has to overun to startPWM again.

As mentioned, I have S110 advertising running in background, I am certain that I am missing the Timer2 interrupt to update Compare 0 because advertising interrupt is in higer priority.

My question is, how can I easily output a 10kHz PWM without needing to enter an interrupt by software to update an output compare register?

Here's the code:

GPIOTE init:

// Configure GPIOTE channel 0 to toggle the PWM pin state
    nrf_gpiote_task_config(0, LED_6, NRF_GPIOTE_POLARITY_TOGGLE, RF_GPIOTE_INITIAL_VALUE_LOW);

PPI init:

// Configure PPI channel 0 to toggle PWM_OUTPUT_PIN on every TIMER2 COMPARE[0] match.
NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];

// Enable PPI channel 0.
NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);

Timer init + start:

 // Init TIMER2 for 10kHz PWM
NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;			// Set the timer in Counter Mode
NRF_TIMER2->TASKS_CLEAR = 1;						// Clear the tasks first to be usable for later
NRF_TIMER2->PRESCALER = 4;							// 2^PRESCALER (values authorized 1 to 9) 4 : 16MHz / 16 = 10MHz
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;	//Set counter to 16 bit resolution
NRF_TIMER2->CC[0] = 50;

// Enable OC1 interrupt on TIMER2
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
NVIC_EnableIRQ(TIMER2_IRQn);

// Start TIMER2
NRF_TIMER2->TASKS_START = true;

The interrupt:

void TIMER2_IRQHandler(void)
{
	
	if (NRF_TIMER2->EVENTS_COMPARE[0] != 0)
	{
		NRF_TIMER2->EVENTS_COMPARE[0] = 0; // Reset event
		
		// Set next compare in 50nsec
		NRF_TIMER2->CC[0] += 50;
			
	}
}

Thanks for any help on this.

Phil

Parents Reply Children
No Data
Related