Prescaler Comparator

This example achieves timing functionality using the frequency divider comparator of the RTC.

After the RTC clock source (32kHz) undergoes pre-division, the regular comparator timing can only time in integer multiples of the RTC clock cycle. (For example, if the pre-divided RTC clock cycle is 0.1s, then the RTC comparator can only support timing in integer multiples of 0.1s.) To achieve more precise timing, frequency divider comparator timing can be used.

If the desired timing is less than the RTC clock cycle, the RTC_INT_PRE_COMP interrupt should be used for timing. The timing duration is PreCompValue * (1/32kHz).

If the desired timing is greater than the RTC clock cycle, the RTC_INT_PRE_COMP3 interrupt should be used for timing, along with RTC_COMP3. The timing duration is RTC_COMP3_VALUE * (RTC_Clock) + PreCompValue * (1/32kHz).

Requirements

The sample supports the following development kits:

Development Kits

Hardware Platforms

Board Name

RTL8752H HDK

RTL8752H EVB

For more requirements, please refer to Quick Start.

Configurations

The macros that can be configured in this example are as follows:

RTC_PRECOMP3_INT : Configuring this macro allows for selecting the RTC pre-divider comparator mode:

  • 1 : indicates using the RTC_INT_PRE_COMP3 interrupt for timing, meaning the timing duration exceeds the RTC clock cycle.

  • 0 : indicates using the RTC_INT_PRE_COMP interrupt for timing, meaning the timing duration is less than the RTC clock cycle.

Building and Downloading

This sample can be found in the SDK folder:

Project file: board\evb\io_sample\RTC\Pre_comp3\mdk

Project file: board\evb\io_sample\RTC\Pre_comp3\gcc

Please follow these steps to build and run the example:

  1. Open sample project file.

  2. To build the target, follow the steps listed on the Generating App Image in Quick Start.

  3. After a successful compilation, the app bin app_MP_xxx.bin will be generated in the directory mdk\bin or gcc\bin.

  4. To download app bin into EVB board, follow the steps listed on the MP Tool Download in Quick Start.

  5. Press reset button on EVB board and it will start running.

Experimental Verification

  1. If the macro RTC_PRECOMP3_INT is enabled, the RTC timer period is 1.1 seconds. An RTC interrupt is triggered every 1.1 seconds, and the corresponding information is printed in the interrupt function.

    RTC_Handler
    RTC_INT_PRE_COMP3
    
  2. If the macro RTC_PRECOMP3_INT is not enabled, the RTC timer period is 0.1 seconds. An RTC interrupt is triggered every 0.1 seconds, and the corresponding information is printed in the interrupt function.

    RTC_Handler
    RTC_INT_PRE_COMP
    

Code Overview

This chapter will be introduced according to the following several parts:

  1. Source Code Directory.

  2. Peripheral initialization will be introduced in chapter Initialization.

  3. Functional implementation after initialization will be introduced in chapter Function Implementation.

Source Code Directory

  • Project directory: sdk\board\evb\io_sample\RTC\Pre_comp3

  • Source code directory: sdk\src\sample\io_sample\RTC\Pre_comp3

Source files are currently categorized into several groups as below.

└── Project: rtc_pre_comp3
    └── secure_only_app
        └── include
            ├── app_define.h
            └── rom_uuid.h
        ├── cmsis                    includes CMSIS header files and startup files
            ├── overlay_mgr.c
            ├── system_rtl876x.c
            └── startup_rtl876x.s
        ├── lib                      includes all binary symbol files that user application is built on
            ├── rtl8752h_sdk.lib
            ├── gap_utils.lib
            └── ROM.lib
        ├── peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl876x_rcc.c
            ├── rtl876x_nvic.c
            └── rtl876x_rtc.c
        ├── profile
        └── app                      includes the ble_peripheral user application implementation
            └── main.c

Initialization

When the EVB reset, the “main” function is executed. In rtc_demo, it includes the initialization of the RTC peripheral.

int main(void)
{
    extern uint32_t random_seed_value;
    srand(random_seed_value);
    __enable_irq();

    rtc_demo();
    while (1)
    {
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
    }
}

void rtc_demo(void)
{
    /* Initialize RTC peripheral */
    driver_rtc_init();
}

driver_rtc_init is the initialization of the RTC peripheral, including the following process:

  1. Reset the RTC peripheral.

  2. If macro RTC_PRECOMP3_INT is enabled:

    1. Set the RTC prescaler value to (3200-1), with an RTC clock frequency of 10Hz.

    2. Set the prescaler comparison value to 320, which means the prescaler comparator time is 0.1s.

    3. Set the comparison value of the RTC_COMP3 comparator to 10, which means the comparator time is 1s, with a total timer time of 1.1s.

    4. Configure the prescaler comparator 3 count interrupt RTC_INT_PRE_COMP3.

  3. If macro RTC_PRECOMP3_INT is not enabled:

    1. Set the RTC prescaler value to (3200-1), with an RTC clock frequency of 10Hz.

    2. Set the prescaler comparison value to 320, which means the prescaler comparator time is 0.1s.

    3. Set the prescaler comparator interrupt RTC_INT_PRE_COMP.

  4. Configure and enable the RTC IRQ channel. Enable interrupt signal to CPU NVIC.

  5. Reset the RTC counter and enable the RTC timer.

void driver_rtc_init(void)
{
    RTC_DeInit();

#if (RTC_PRECOMP3_INT)
    RTC_SetPrescaler(RTC_PRESCALER_VALUE);
    RTC_SetPreCompValue(RTC_PRECOMP_VALUE);
    RTC_SetCompValue(RTC_COMP3, RTC_COMP3_VALUE);

    RTC_INTConfig(RTC_INT_PRE_COMP3, ENABLE);

#else
    RTC_SetPrescaler(RTC_PRESCALER_VALUE);
    RTC_SetPreCompValue(RTC_PRECOMP_VALUE);

    RTC_INTConfig(RTC_INT_PRE_COMP, ENABLE);
#endif
    /* Config RTC interrupt */
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    RTC_NvCmd(ENABLE);
    /* Start RTC */
    RTC_ResetCounter();
    RTC_Cmd(ENABLE);
}

Functional Implementation

RTC time is up, triggering RTC interrupt and entering the interrupt handler function RTC_Handler.

  1. If the macro RTC_PRECOMP3_INT is enabled, the interrupt occurs at 1.1s. In the interrupt function, read the counter value, reset the prescaler counter, set the comparison value again, and clear the interrupt flag.

  2. If the macro RTC_PRECOMP3_INT is not enabled, the interrupt occurs at 0.1s. In the interrupt function, reset the prescaler counter and clear the interrupt flag.

void RTC_Handler(void)
{
    DBG_DIRECT("RTC_Handler");
#if (RTC_PRECOMP3_INT)
    if (RTC_GetINTStatus(RTC_INT_PRE_COMP3) == SET)
    {
        DBG_DIRECT("RTC_INT_PRE_COMP3");
        uint32_t counter  = RTC_GetCounter();
        RTC_ResetPrescalerCounter();
        RTC_SetCompValue(RTC_COMP3, counter + RTC_COMP3_VALUE);
        RTC_ClearINTPendingBit(RTC_INT_PRE_COMP3);
    }
#else
    if (RTC_GetINTStatus(RTC_INT_PRE_COMP) == SET)
    {
        DBG_DIRECT("RTC_INT_PRE_COMP");
        RTC_ResetPrescalerCounter();
        RTC_ClearINTPendingBit(RTC_INT_PRE_COMP);
    }
#endif
}