I have a very simple program that generates a 50% duty cycle clock using the NRF_PWM0 on the new nRF52 device. Unfortunately, my Tektronix 1GHz oscilloscope doesn't lock to the signal. If I used a Timer and GPIOTE with PPI then the clock was perfect.
I am wondering if the PWM_CLK input to the PWM hardware resource is not correct. The reference manual just uses the PWM_CLK in description but doesn't describe what it is or how do I configure or start/lock it. Any ideas?
Note that I am not using any SoftDevice and this is on a custom board with just the nRF52 part and nothing else.
int main (void)
{
// Start 16 MHz crystal oscillator .
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
// Wait for the external oscillator to start up.
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
}
NRF_PWM0->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
NRF_PWM0->PRESCALER = NRF_PWM_CLK_1MHz;
NRF_PWM0->MODE = NRF_PWM_MODE_UP;
NRF_PWM0->COUNTERTOP = 20;
NRF_PWM0->PSEL.OUT[0] = 6;
NRF_PWM0->PSEL.OUT[1] = NRF_PWM_PIN_NOT_CONNECTED;
NRF_PWM0->PSEL.OUT[2] = NRF_PWM_PIN_NOT_CONNECTED;
NRF_PWM0->PSEL.OUT[3] = NRF_PWM_PIN_NOT_CONNECTED;
NRF_PWM0->DECODER = ((uint32_t)NRF_PWM_LOAD_INDIVIDUAL << PWM_DECODER_LOAD_Pos) |
((uint32_t)NRF_PWM_STEP_AUTO << PWM_DECODER_MODE_Pos);
NRF_PWM0->SHORTS = 0;
NRF_PWM0->INTEN = 0;
static nrf_pwm_values_individual_t duty =
{
.channel_0 = 10,
.channel_1 = 10,
.channel_2 = 10,
.channel_3 = 10,
};
NRF_PWM0->SEQ[0].PTR = (uint32_t)&duty;
NRF_PWM0->SEQ[0].CNT = NRF_PWM_VALUES_LENGTH(duty);
NRF_PWM0->SEQ[0].REFRESH = 0;
NRF_PWM0->SEQ[0].ENDDELAY = 0;
NRF_PWM0->TASKS_SEQSTART[0] = 1;
while (1) {
}
}
Thanks a lot!