Fixed Length Transmit and Receive - GDMA
This sample demonstrates data communication with a PC terminal using UART and GDMA.
The SoC transmits data to the PC terminal using GDMA, which transfers data from memory to the peripheral of UART TX FIFO.
The SoC receives data from the PC terminal using GDMA, which transfers data from the peripheral of UART TX FIFO to memory.
The SoC sends the buffer data back to the PC terminal once the GDMA transfer is complete.
In this sample, the PC terminal program must send data greater than or equal to UART_RX_GDMA_BUFFER_SIZE
bytes to trigger the GDMA interrupt.
Users can change the pin configuration, GDMA configuration, and other information in the example through different macro configurations. For specific macro configurations, refer to Configuration.
Requirements
For requirements, please refer to the Requirements.
In addition, it is necessary to install serial port assistant tools such as PuTTY or UartAssist on the PC terminal.
Configurations
The following macros can be configured to modify GDMA channel settings.
// Set the following macros to modify the UART TX GDMA Channel configurations. #define UART_TX_GDMA_CHANNEL_NUM GDMA_CH_NUM3 #define UART_TX_GDMA_CHANNEL GDMA_Channel3 #define UART_TX_GDMA_CHANNEL_IRQN GDMA_Channel3_IRQn #define UART_TX_GDMA_Handler GDMA_Channel3_Handler // Set the following macros to modify the UART RX GDMA Channel configurations. #define UART_RX_GDMA_CHANNEL_NUM GDMA_CH_NUM4 #define UART_RX_GDMA_CHANNEL GDMA_Channel4 #define UART_RX_GDMA_CHANNEL_IRQN GDMA_Channel4_IRQn #define UART_RX_GDMA_Handler GDMA_Channel4_Handler
The following macros can be configured to modify the transmission data size of the GDMA TX/RX channels.
#define UART_TX_GDMA_BUFFER_SIZE 29 /*< Set this macro to modify the UART TX GDMA transfer size. */ #define UART_RX_GDMA_BUFFER_SIZE 29 /*< Set this macro to modify the UART RX GDMA transfer size. */
The following macros can be configured to modify the pin definitions.
#define UART_TX_PIN P3_0 #define UART_RX_PIN P3_1
Wiring
Connect P3_0(UART TX Pin) to the RX pin of the FT232 and P3_1(UART RX Pin) to the TX pin of the FT232.
Building and Downloading
For building and downloading, please refer to the Building and Downloading.
Experimental Verification
Preparation Phase
Start a PC terminal like PuTTY or UartAssist and connect to the used COM port with the following UART settings:
Baud rate: 115200
8 data bits
1 stop bit
No parity
No hardware flow control
Testing Phase
After resetting the EVB, observe the log information as shown in the Debug Analyzer.
Start uart tx rx by gdma test!
This sample starts with transmitting
### Uart trx gdma sample\r\n
. Observe that the string appears on the PC terminal.The SoC sends 29 hexadecimal numbers to the PC terminal (in this sample, the TX Block size
UART_TX_GDMA_BUFFER_SIZE
is set to 29): 10 11 12 … 2C. Observe that these 29 hexadecimal numbers appear on the PC terminal.Type more than 29 characters on the PC terminal (in this sample, the RX Block size
UART_RX_GDMA_BUFFER_SIZE
is set to 29). Observe that the same characters appear on the PC terminal.
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\uart\trx_gdma\proj
Source code directory:
sdk\samples\peripheral\uart\trx_gdma\src
Initialization
The initialization flow for peripherals can refer to Initialization Flow in General Introduction.
Call
Pad_Config()
andPinmux_Config()
to configure the PAD and PINMUX of the corresponding pins. IfUART_CONFIG_HW_FLOW_CTRL
is set to1
, the CTS and RTS pins still need to be configured.void board_uart_init(void) { Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pinmux_Config(UART_TX_PIN, UART3_TX); Pinmux_Config(UART_RX_PIN, UART3_RX); }
Call
RCC_PeriphClockCmd()
to enable the UART clock.Initialize the UART peripheral:
Define the
UART_InitTypeDef
typeUART_InitStruct
, and callUART_StructInit()
to pre-fillUART_InitStruct
with default values.Modify the
UART_InitStruct
parameters as needed. The UART initialization parameter configuration is shown in the table below.Call
UART_Init()
to initialize the UART peripheral.
UART Hardware Parameters |
Setting in the |
UART |
---|---|---|
UART Baudrate Parameter - div |
|
|
UART Baudrate Parameter - ovsr |
|
|
UART Baudrate Parameter - ovsr_adj |
|
|
GDMA Enable |
||
TX GDMA Enable |
||
RX GDMA Enable |
||
TX Waterlevel |
1 |
|
RX Waterlevel |
1 |
Initialize the GDMA peripheral:
Define a
GDMA_InitTypeDef
typeGDMA_InitStruct
, and callGDMA_StructInit()
to pre-fillGDMA_InitStruct
with default values.Modify the
GDMA_InitStruct
parameters as needed. The initialization parameters for the GDMA TX and RX channels are configured as shown in the table below. CallGDMA_Init()
to initialize the GDMA peripheral.Configure the GDMA total transfer complete interrupt
GDMA_INT_Transfer
and NVIC. For NVIC configurations, refer to Interrupt Configuration.Call
GDMA_Cmd()
to enable the corresponding GDMA channel transfer.
GDMA Hardware Parameters |
Setting in the |
GDMA TX Channel |
GDMA RX Channel |
---|---|---|---|
Channel Num |
3 |
4 |
|
Transfer Direction |
|||
Buffer Size |
|
|
|
Source Address Increment or Decrement |
|||
Destination Address Increment or Decrement |
|||
Source Data Size |
|||
Destination Data Size |
|||
Source Burst Transaction Length |
|||
Destination Burst Transaction Length |
|||
Source Address |
|
|
|
Destination Address |
|
|
|
Source Handshake |
- |
||
Destination Handshake |
- |
Functional Implementation
Call
uart_senddata_continuous
to transmit### Uart trx gdma sample ###\r\n
to PC terminal. Within the functionuart_senddata_continuous
, wait for the UART TX FIFO to be empty, and then fill the data into the FIFO in batches.void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount) { uint8_t count; while (vCount / UART_TX_FIFO_SIZE > 0) { while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0); for (count = UART_TX_FIFO_SIZE; count > 0; count--) { UARTx->UART_RBR_THR = *pSend_Buf++; } vCount -= UART_TX_FIFO_SIZE; } while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0); while (vCount--) { UARTx->UART_RBR_THR = *pSend_Buf++; } }
After enabling the GDMA TX channel transmission, the GDMA TX channel transfers data from
GDMA_SendData_Buffer
to(&(UART_DEMO->UART_RBR_THR))
. Once the GDMA TX data transmission is complete, it triggers the GDMA TX channelGDMA_INT_Transfer
interrupt. Print the corresponding information within the interrupt handling function.void UART_TX_GDMA_Handler(void) { GDMA_ClearINTPendingBit(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer); DBG_DIRECT("UART_TX_GDMA_Handler, Data transmission completion!"); }
After enabling the GDMA RX channel transmission, when characters are entered on the PC terminal, the GDMA RX channel transfers data from
(&(UART_DEMO->UART_RBR_THR))
toGDMA_ReceiveData_Buffer
. When more than 29 bytes (1 Block) are entered, it triggers the GDMA RX channelGDMA_INT_Transfer
interrupt:Clear the GDMA
GDMA_INT_Transfer
interrupt flag.Call
uart_senddata_continuous
to send the data received by GDMAGDMA_ReceiveData_Buffer
back to the PC terminal.Print the GDMA transfer completion information.
void UART_RX_GDMA_Handler(void)
{
GDMA_ClearINTPendingBit(UART_RX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
DBG_DIRECT("UART_RX_GDMA_Handler, Data transmission completion!");
uart_senddata_continuous(UART_DEMO, GDMA_ReceiveData_Buffer, UART_RX_GDMA_BUFFER_SIZE);
}