This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using PPI to enable/disable HFCLK

Is it possible to use PPI and RTC to turn the HFCLK on or off ? (external Xtal)

Example - something like this ... NRF_PPI->CH[9].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1]; NRF_PPI->CH[9].TEP = (uint32_t) &NRF_CLOCK->TASKS_HFCLKSTART; NRF_PPI->CHENSET = PPI_CHENSET_CH9_Msk;

NRF_PPI->CH[10].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[2]; NRF_PPI->CH[10].TEP = (uint32_t) &NRF_CLOCK->TASKS_HFCLKSTOP; NRF_PPI->CHENSET = PPI_CHENSET_CH10_Msk;

Does the PPI system require the HFCLK External Xtal to be operational ?

Also, if I can't use PPI to do the above, is there another way to do it ? Perhaps using shortcuts ? As I understand, shortcuts are only for use within the same peripheral and so probably not.

Parents
  • Hi Stephan

    I tried your suggestion. See below. This code doesn't work. It asserts in the end (last line).

    ==========

    ASSERT(((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) == (CLOCK_HFCLKSTAT_STATE_NotRunning << CLOCK_HFCLKSTAT_STATE_Pos) ) || \
                   ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk) == (CLOCK_HFCLKSTAT_SRC_RC << CLOCK_HFCLKSTAT_SRC_Pos))); /* ensure clock is stopped */
    
    NRF_RTC0->INTENCLR = RTC_INTENCLR_COMPARE1_Msk;
    NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk;
    NRF_PPI->CH[9].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1];
    NRF_PPI->CH[9].TEP = (uint32_t) &NRF_CLOCK->TASKS_HFCLKSTART;
    NRF_PPI->CHENSET |= PPI_CHENSET_CH9_Msk;
    #define TEST_TICKS (3)
    #define TICKS_TO_US(ticks) ((uint64_t)ticks*(uint64_t)1000000/32768)
    NRF_RTC0->CC[1] = NRF_RTC0->COUNTER + TEST_TICKS;
    nrf_delay_us(TICKS_TO_US(TEST_TICKS)); /* wait until RTC fires TEST_TICKS */
    nrf_delay_us(TICKS_TO_US(TEST_TICKS)); /* a little extra wait to make sure */
    nrf_delay_ms(2); /* Wait 1 ms of warmup time and an extra 1 ms to make sure */
    ASSERT(((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) == (CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) ) && \
                 ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk) == (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)));
    

    ===============

Reply
  • Hi Stephan

    I tried your suggestion. See below. This code doesn't work. It asserts in the end (last line).

    ==========

    ASSERT(((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) == (CLOCK_HFCLKSTAT_STATE_NotRunning << CLOCK_HFCLKSTAT_STATE_Pos) ) || \
                   ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk) == (CLOCK_HFCLKSTAT_SRC_RC << CLOCK_HFCLKSTAT_SRC_Pos))); /* ensure clock is stopped */
    
    NRF_RTC0->INTENCLR = RTC_INTENCLR_COMPARE1_Msk;
    NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk;
    NRF_PPI->CH[9].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1];
    NRF_PPI->CH[9].TEP = (uint32_t) &NRF_CLOCK->TASKS_HFCLKSTART;
    NRF_PPI->CHENSET |= PPI_CHENSET_CH9_Msk;
    #define TEST_TICKS (3)
    #define TICKS_TO_US(ticks) ((uint64_t)ticks*(uint64_t)1000000/32768)
    NRF_RTC0->CC[1] = NRF_RTC0->COUNTER + TEST_TICKS;
    nrf_delay_us(TICKS_TO_US(TEST_TICKS)); /* wait until RTC fires TEST_TICKS */
    nrf_delay_us(TICKS_TO_US(TEST_TICKS)); /* a little extra wait to make sure */
    nrf_delay_ms(2); /* Wait 1 ms of warmup time and an extra 1 ms to make sure */
    ASSERT(((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk) == (CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) ) && \
                 ((NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk) == (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos)));
    

    ===============

Children
No Data
Related