IR GDMA Receive

This sample demonstrates how to use GDMA to receive IR data.

Use the P2_6 pin as the PWM output pin to output a PWM waveform for simulating the transmitter data. Connect the PWM output pin to the IR input pin.

IR data is received via GDMA, and upon reaching the specified amount, a GDMA interrupt is triggered.

Requirements

For requirements, please refer to the Requirements.

Wiring

Connect PWM output pin P2_6 and IR receiver pin P2_5.

Configurations

  1. The following macro can be configured to modify the pin definitions.

    #define IR_RX_PIN               P2_5
    #define PWM_OUT_PIN             P2_6
    
  2. The following macros can be configured to modify PWM configuration information.

    #define PWM_HIGH_COUNT                          (20000 - 1)
    #define PWM_LOW_COUNT                           (20000 - 1)
    

Building and Downloading

For building and downloading, please refer to the Building and Downloading.

Experimental Verification

  1. After initialization is complete, the PWM begins to output waveforms. The duration of the high level and low level are determined by the number of 40 MHz cycles specified by PWM_HIGH_COUNT and PWM_LOW_COUNT, which is the same as the sampling frequency set for IR at 40 MHz.

  2. When the IR receives data, the GDMA transfers the IR data to memory. Once the GDMA completes the transfer of IR data, it triggers a GDMA interrupt. Within the GDMA interrupt function, the length and content of the transferred data are printed.

    io_handle_gdma_msg: IR_GDMA_Rev_Data_Len = 80
    io_handle_gdma_msg: GDMA_Recv_Buf[0] = 0x00004e1e
    io_handle_gdma_msg: GDMA_Recv_Buf[1] = 0x80004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[2] = 0x00004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[3] = 0x80004e1f
    ...
    io_handle_gdma_msg: GDMA_Recv_Buf[78] = 0x00004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[79] = 0x80004e1f
    ...
    

Note

0x00004e1f represents the number of cycles for IR reception at a low level, corresponding to the PWM_LOW_COUNT value. 0x80004e1f represents the number of cycles for IR reception at a high level, where 0x4e1f corresponds to the PWM_HIGH_COUNT value of PWM, and 0x80000000 represents the high level.

Code Overview

This section introduces the code and process description for initialization and corresponding function implementation in the sample.

Source Code Directory

The directory for project file and source code are as follows:

  • Project directory: sdk\samples\peripheral\ir\rx+gdma\proj

  • Source code directory: sdk\samples\peripheral\ir\rx+gdma\src

Initialization

The initialization flow for peripherals can refer to Initialization Flow in General Introduction.

  1. Call Pad_Config() and Pinmux_Config() to configure the PAD and PINMUX of the corresponding pins.

    void board_ir_init(void)
    {
        Pad_Config(IR_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
        Pad_PullConfigValue(IR_RX_PIN, PAD_PULL_STRONG);
    
        Pinmux_Config(IR_RX_PIN, IRDA_RX);
    }
    
    void board_pwm_init(void)
    {
        Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
        /* Normal mode */
        Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PINMUX);
    }
    
  2. Call RCC_PeriphClockCmd() to enable the IR clock.

  3. Initialize the IR peripheral:

    1. Define the IR_InitTypeDef type IR_InitStruct, and call IR_StructInit() to pre-fill IR_InitStruct with default values.

    2. Modify the IR_InitStruct parameters as needed. The IR initialization parameter configuration is shown in the table below.

    3. Call IR_Init() to initialize the IR peripheral.

IR Initialization Parameters

IR Hardware Parameters

Setting in the IR_InitStruct

IR

Sample Clock

IR_InitTypeDef::IR_Freq

40000000

IR Mode

IR_InitTypeDef::IR_Mode

IR_MODE_RX

IR Rx Mode

IR_InitTypeDef::IR_RxStartMode

IR_RX_AUTO_MODE

IR Rx Trigger Mode

IR_InitTypeDef::IR_RxTriggerMode

IR_RX_FALL_EDGE

IR Rx GDMA Enable

IR_InitTypeDef::IR_RxDmaEn

ENABLE

IR Rx Waterlevel

IR_InitTypeDef::IR_RxWaterLevel

4

  1. Call IR_Cmd() to enable the IR peripheral.

  2. Call RCC_PeriphClockCmd() to enable the TIM clock.

  3. Initialize the TIM peripheral:

    1. Define the TIM_TimeBaseInitTypeDef type TIM_InitStruct, and call TIM_StructInit() to pre-fill IR_InitStruct with default values.

    2. Modify the TIM_InitStruct parameters as needed. The TIM initialization parameter configuration is shown in the table below.

    3. Call TIM_TimeBaseInit() to initialize the TIM peripheral.

    4. Call TIM_Cmd() to enable the TIM peripheral.

TIM Initialization Parameters

TIM Hardware Parameters

Setting in the TIM_InitStruct

TIM

TIM Mode

TIM_TimeBaseInitTypeDef::TIM_Mode

TIM_Mode_UserDefine

PWM Enable

TIM_TimeBaseInitTypeDef::TIM_PWM_En

ENABLE

PWM High Count

TIM_TimeBaseInitTypeDef::TIM_PWM_High_Count

PWM_HIGH_COUNT

PWM Low Count

TIM_TimeBaseInitTypeDef::TIM_PWM_Low_Count

PWM_LOW_COUNT

  1. Call RCC_PeriphClockCmd() to enable the GDMA clock.

  2. Initialize the GDMA peripheral:

    1. Define a GDMA_InitTypeDef type GDMA_InitStruct, and call GDMA_StructInit() to pre-fill GDMA_InitStruct with default values.

    2. Modify the GDMA_InitStruct parameters as needed. The initialization parameters for the GDMA channel are configured as shown in the table below. Call GDMA_Init() to initialize the GDMA peripheral.

    3. Configure the GDMA total transfer complete interrupt GDMA_INT_Transfer and NVIC. For NVIC configurations, refer to Interrupt Configuration.

    4. Call GDMA_Cmd() to enable the corresponding GDMA channel transfer.

GDMA Initialization Parameters

GDMA Hardware Parameters

Setting in the GDMA_InitStruct

GDMA Channel

Channel Num

GDMA_InitTypeDef::GDMA_ChannelNum

1

Transfer Direction

GDMA_InitTypeDef::GDMA_DIR

GDMA_DIR_PeripheralToMemory

Buffer Size

GDMA_InitTypeDef::GDMA_BufferSize

80

Source Address Increment or Decrement

GDMA_InitTypeDef::GDMA_SourceInc

DMA_SourceInc_Fix

Destination Address Increment or Decrement

GDMA_InitTypeDef::GDMA_DestinationInc

DMA_DestinationInc_Inc

Source Data Size

GDMA_InitTypeDef::GDMA_SourceDataSize

GDMA_DataSize_Word

Destination Data Size

GDMA_InitTypeDef::GDMA_DestinationDataSize

GDMA_DataSize_Word

Source Burst Transaction Length

GDMA_InitTypeDef::GDMA_SourceMsize

GDMA_Msize_4

Destination Burst Transaction Length

GDMA_InitTypeDef::GDMA_DestinationMsize

GDMA_Msize_4

Source Address

GDMA_InitTypeDef::GDMA_SourceAddr

(&IR->IR_RX_FIFO)

Destination Address

GDMA_InitTypeDef::GDMA_DestinationAddr

GDMA_Recv_Buf

Source Handshake

GDMA_InitTypeDef::GDMA_SourceHandshake

GDMA_Handshake_IR_RX

Functional Implementation

  1. After enabling the TIM peripheral, TIM starts outputting a PWM waveform. Once the IR receives data, it transfers the data from (&IR->IR_RX_FIFO) to GDMA_Recv_Buf.

  2. When GDMA completes the data transfer, it triggers the GDMA_INT_Transfer interrupt. Within the interrupt function, the received data is printed, and the GDMA is re-enabled to continue transferring.

    void IO_TEST_GDMA_Channel_Handler(void)
    {
        GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, DISABLE);
        GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, DISABLE);
        IR_GDMA_Rev_Data_Len = IO_TEST_GDMA_TRANSFER_SIZE;
        io_handle_gdma_msg();
        GDMA_ClearINTPendingBit(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer);
        GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, ENABLE);
        GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, ENABLE);
    }
    
    void io_handle_gdma_msg(void)
    {
        DBG_DIRECT("io_handle_gdma_msg: IR_GDMA_Rev_Data_Len = %d \r\n", IR_GDMA_Rev_Data_Len);
        for (uint32_t i = 0; i < IR_GDMA_Rev_Data_Len; i++)
        {
            DBG_DIRECT("io_handle_gdma_msg: GDMA_Recv_Buf[%d] = 0x%x \r\n", i, GDMA_Recv_Buf[i]);
        }
    }
    

See Also

Please refer to the relevant API Reference: