GPIO Latch

This example demonstrates the use of ENHTIM to achieve GPIO-triggered latch status and record counter values.

P2_4 is set as a GPIO output pin, with its level continuously toggling over time.

P2_2 is set as a GPIO input pin and is also configured as the count trigger pin for ENHTIM.

By connecting P2_2 to P2_4, a rising edge on P2_2 will trigger the counting. After three cumulative changes, an ENHTIM interrupt is triggered, and the counter values at the three triggers are printed within the interrupt function.

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.

Wiring

Connect P2_4 (GPIO output) and P2_2 (GPIO input).

Building and Downloading

This sample can be found in the SDK folder:

Project file: board\evb\io_sample\TIM_ENHANCE\Latch_GPIO\mdk

Project file: board\evb\io_sample\TIM_ENHANCE\Latch_GPIO\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

When P2_2 and P2_4 pins are connected, the counter values triggered by GPIO will be continuously printed on the Debug Analyzer, and the counter values will keep increasing.

ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD
ENH_TIM0 fifo length = 3
ENH_TIM0 data[0] = 0x2f5
ENH_TIM0 data[1] = 0x125c6c
ENH_TIM0 data[2] = 0x1e91a7
...

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\TIM_ENHANCE\Latch_GPIO

  • Source code directory: sdk\src\sample\io_sample\TIM_ENHANCE\Latch_GPIO

Source files are currently categorized into several groups as below.

└── Project: latch_gpio
    └── 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_pinmux.c
            ├── rtl876x_nvic.c
            ├── rtl876x_gpio.c
            └── rtl876x_enh_tim.c
        ├── profile
        └── app                      includes the ble_peripheral user application implementation
            └── main.c

Initialization

When the EVB is reset, the main function is executed, following these steps:

int main(void)
{
    __enable_irq();

    enhance_tim_demo();

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

In enhance_tim_demo, it includes processes such as PAD/PINMUX settings, GPIO, and ENHTIM peripheral initialization.

void enhance_tim_demo(void)
{
    board_gpio_enhtim_init();
    driver_gpio_enhtim_init();
    driver_enhance_timer_init();

    /* GPIO output is only used to simulate the input signal, only for demo debugging. */
    board_gpio_init();
    driver_gpio_init();
    ...
}

board_gpio_enhtim_init is the PAD/PINMUX setup for GPIO input, including the following steps:

  1. Configure PAD: Set the pin, PINMUX mode, PowerOn, internal pull-up, disable output.

  2. Configure PINMUX: Set the pin to DWGPIO function.

void board_gpio_enhtim_init(void)
{
    Pad_Config(GPIO_INPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
    Pinmux_Config(GPIO_INPUT_PIN_0,  DWGPIO);
}

board_gpio_init is the PAD/PINMUX setup for GPIO output, including the following steps:

  1. Configure PAD: Set the pin, PINMUX mode, PowerOn, internal pull-up, output high.

  2. Configure PINMUX: Set the pin to DWGPIO function.

void board_gpio_init(void)
{
    Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
    Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
}

driver_gpio_enhtim_init is the initialization of the GPIO input peripheral, including the following steps:

  1. Enable the RCC clock.

  2. Set the GPIO pin to input mode.

void driver_gpio_enhtim_init(void)
{
    /* Initialize GPIO peripheral */
    RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_PIN_INPUT_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_Init(&GPIO_InitStruct);

    GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
}

driver_gpio_init is the initialization of the GPIO output peripheral, including the following steps:

  1. Enable the RCC clock.

  2. Set the GPIO pin to output mode.

void driver_gpio_init(void)
{
    /* Initialize GPIO peripheral */
    RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_PIN_OUTPUT_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(&GPIO_InitStruct);

    GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
}

driver_gpio_init is the initialization of the ENHTIM peripheral, including the following process:

  1. Enable the RCC clock.

  2. Set ENHTIM clock to prescaler of 1.

  3. Set ENHTIM to free-running mode.

  4. Set ENHTIM to enable GPIO trigger latch function.

  5. Set GPIO rising edge trigger latch, with interrupt FIFO threshold of 3.

  6. Enable GPIO trigger timing function.

  7. Configure and enable the ENHTIM IRQ channel.

  8. Configure ENHTIM timing interrupt, FIFO full interrupt, and FIFO threshold reached interrupt.

  9. Enable the ENHTIM peripheral.

void driver_enhance_timer_init(void)
{
    RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE);

    ENHTIM_InitTypeDef ENHTIM_InitStruct;
    ENHTIM_StructInit(&ENHTIM_InitStruct);

    ENHTIM_InitStruct.ENHTIM_ClockDiv               = ENHTIM_CLOCK_DIVIDER_1;
    ENHTIM_InitStruct.ENHTIM_Mode                   = ENHTIM_MODE_FreeRun;
    /* Only enhtim_ ENHTIM_LatchCountEn[2] latch triggered by GPIO. */
    ENHTIM_InitStruct.ENHTIM_LatchCountEn[2]        = ENHTIM_LATCH_COUNT_ENABLE;
    ENHTIM_InitStruct.ENHTIM_LatchCountTrigger[2]   = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
    ENHTIM_InitStruct.ENHTIM_LatchCount2Thd         = 3;
    ENHTIM_InitStruct.ENHTIM_LatchTriggerPad        = GPIO_INPUT_PIN_0;
    ENHTIM_InitStruct.ENHTIM_TimerGPIOTriggerEn     = ENABLE;

    ENHTIM_Init(ENHTIMER_NUM, &ENHTIM_InitStruct);

    /*  Enable TIMER IRQ  */
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = ENHTIMER_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_TIM);
    ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_TIM, ENABLE);

    ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_FULL);
    ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_FULL, ENABLE);

    ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD);
    ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD, ENABLE);

    ENHTIM_Cmd(ENHTIMER_NUM, ENABLE);
}

Functional Implementation

  1. In the main function, continuously execute GPIO_WriteBit() to toggle the GPIO output pin P2_4 between high and low levels.

    void enhance_tim_demo(void)
    {
        ..
        while (1)
        {
            /* Simulate GPIO trigger signal */
            for (uint32_t i = 0; i < 100000; i++);
            GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(1));
            for (uint32_t i = 0; i < 100000; i++);
            GPIO_WriteBit(GPIO_PIN_OUTPUT_0, (BitAction)(0));
        }
    }
    
  2. After connecting P2_4 (GPIO output) and P2_2 (GPIO input) pins, each time P2_2 detects a rising edge from P2_4 output, it triggers the latch count function of ENHTIM. When the threshold is reached after accumulating three times, it triggers the ENHTIM_INT_LATCH_CNT2_FIFO_THD interrupt and enters the interrupt handler function Enhanced_Timer0_Handler.

    1. Disable the ENHTIM_INT_LATCH_CNT2_FIFO_THD interrupt.

    2. Read the data length in the ENHTIM latch count FIFO, read and print the latch count value.

    3. Clear the interrupt flag and re-enable the interrupt.

    void Enhanced_Timer0_Handler()
    {
        ...
        if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD))
        {
            APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD\r\n");
            ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT2_FIFO_THD, DISABLE);
            uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0);
            uint32_t data[4] = {0};
            ENHTIM_ReadLatchCount2FIFO(ENH_TIM0, data, length);
            /* Only for debugging, removed in actual application. */
            APP_PRINT_INFO1("ENH_TIM0 fifo length = %d\r\n", length);
            for (uint8_t i = 0; i < length; i++)
            {
                /* Only for debugging, removed in actual application. */
                APP_PRINT_INFO2("ENH_TIM0 data[%d] = 0x%x\r\n", i, data[i]);
            }
            //add user code here
            ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD);
            ENHTIM_INTConfig(ENH_TIM0, ENHTIM_INT_LATCH_CNT2_FIFO_THD, ENABLE);
        }
    }