Can the nRF52 output the 32.768kHz clock on a GPIO. If so, do I need the 32.768kHz xtal, or can I output the generated clock from the 32MHz xtal? I need this clock to sync other ICs.
Can the nRF52 output the 32.768kHz clock on a GPIO. If so, do I need the 32.768kHz xtal, or can I output the generated clock from the 32MHz xtal? I need this clock to sync other ICs.
Try this code
#define LFCLK_OUTPUT (11U)
#define DELAYED_LFCLK_OUTPUT (12U)
void start_timer(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)
{
// Do nothing.
}
NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
NRF_TIMER1->TASKS_CLEAR = 1;
NRF_TIMER1->PRESCALER = 0;
NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
// Timer expires 1
NRF_TIMER1->CC[0] = 244; // expires (1/4)*(1/16384) microseconds
}
void lfclk_config()
{
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {}
NRF_RTC1->PRESCALER = 0; //1kHz frequency
NRF_RTC1->EVTEN = (RTC_EVTENSET_TICK_Msk ); /* event on COMPARE0 and TICK */
}
int main(void) {
lfclk_config();
start_timer();
// configure GPIOTE
NRF_GPIOTE->CONFIG[0] = ( (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos)
| (LFCLK_OUTPUT << GPIOTE_CONFIG_PSEL_Pos)
| (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) )
| (0 << GPIOTE_CONFIG_OUTINIT_Pos);
// configure timer CC event to toggle DELAYED_LFCLK_OUTPUT
NRF_GPIOTE->CONFIG[1] = ( (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos)
| (DELAYED_LFCLK_OUTPUT << GPIOTE_CONFIG_PSEL_Pos)
| (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) )
| (1 << GPIOTE_CONFIG_OUTINIT_Pos);
// configure PPI channel 2 convert timer CC event to GPIOTE task out
NRF_PPI->CH[2].EEP = (uint32_t)(&NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_PPI->CH[2].TEP = (uint32_t)(&NRF_GPIOTE->TASKS_OUT[1]);
NRF_PPI->CHENSET |= PPI_CHENCLR_CH2_Msk; // enable
// configure PPI
NRF_PPI->CH[0].EEP = (uint32_t)(&NRF_RTC1->EVENTS_TICK);
NRF_PPI->CH[0].TEP = (uint32_t)(&NRF_GPIOTE->TASKS_OUT[0]);
NRF_PPI->CHENSET = PPI_CHENCLR_CH0_Msk;
// configure PPI channel 1 to clear timer counter
NRF_PPI->CH[1].EEP = (uint32_t)(&NRF_RTC1->EVENTS_TICK);
NRF_PPI->CH[1].TEP = (uint32_t)(&NRF_TIMER1->TASKS_CLEAR);
NRF_PPI->CHENSET |= PPI_CHENCLR_CH1_Msk; // enable
NRF_RTC1->TASKS_START = 1;
NRF_TIMER1->TASKS_START = 1; // Start TIMER1
while (true)
{
__SEV();
__WFE();
__WFE();
}
}
output is like below
XOR both outputs and you should have LFCLK with required accuracy. Hopefully the propagation delays within the chip for rerouting events are negligible.
I understand the TIMER1 (HFCLK) is used to create the second signal, but XORing it with first signal which is generated from RTC (LFCLK). So the signal that is generated by XORing these two should have better accuracy.
i am not aware of any method that you can do it with the MCU.
i am not aware of any method that you can do it with the MCU.