Fixed Length Transmit and Receive - GDMA
该示例使用 UART 和 GDMA 与 PC 终端进行固定长度的数据通信。
SoC 使用 GDMA 将数据发送到 PC 终端程序(如 PuTTY 或 UartAssist),GDMA 将数据从 Memory 传输到 UART TX FIFO 外设。
SoC 使用 GDMA 接收 PC 终端输入的数据,GDMA 将数据从 UART RX FIFO 外设传输到 Memory。
一旦 GDMA 传输完成,SoC 将缓冲数据发送回 PC 终端。
在该示例中,PC 终端程序必须发送大于等于 UART_RX_GDMA_BUFFER_SIZE
个字节的数据,才会触发 GDMA 中断。
用户可以通过不同的宏配置改变示例中的引脚配置,GDMA 配置等信息,具体宏配置详见 配置选项。
环境需求
该示例的环境需求,可参考 环境需求。
此外,需要在 PC 终端安装 PuTTY 或 UartAssist 等串口助手工具。
配置选项
可配置如下宏修改 GDMA 通道设置。
// 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
可配置如下宏修改 GDMA TX/RX 通道的传输数据量。
#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. */
可配置如下宏修改引脚定义。
#define UART_TX_PIN P3_0 #define UART_RX_PIN P3_1
硬件连线
连接 P3_0(UART TX Pin)和 FT232 的 RX,P3_1(UART RX Pin) 和 FT232 的 TX。
编译和下载
该示例的编译和下载流程,可参考 编译和下载。
测试验证
准备阶段
启动 PuTTY 或 UartAssist 等 PC 终端,连接到使用的 COM 端口,并进行以下 UART 设置:
波特率: 115200
8 数据位
1 停止位
无校验
无硬件流控
测试阶段
当 EVB 启动后,在 Debug Analyzer 工具内观察如下 log。
Start uart tx rx by gdma test!
该示例开始发送
### Uart trx gdma sample\r\n
,观察 PC 终端上出现的字符串。SoC 向 PC 终端发送 29 个十六进制数(该示例 TX Block size
UART_TX_GDMA_BUFFER_SIZE
设置为 29):10 11 12 … 2C, 观察 PC 终端上显示这 29 个十六进制数。在 PC 终端上输入超过 29 个字符(该示例 RX Block size
UART_RX_GDMA_BUFFER_SIZE
设置为 29)。观察 PC 终端上是否显示相同的字符。
代码介绍
该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。
源码路径
工程文件和源码路径如下:
工程路径:
sdk\samples\peripheral\uart\trx_gdma\proj
源码路径:
sdk\samples\peripheral\uart\trx_gdma\src
初始化
外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。
调用
Pad_Config()
与Pinmux_Config()
,配置对应引脚的 PAD 和 PINMUX。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); }
调用
RCC_PeriphClockCmd()
,开启 UART 时钟。对 UART 外设进行初始化:
定义
UART_InitTypeDef
类型UART_InitStruct
,调用UART_StructInit()
将UART_InitStruct
预填默认值。根据需求修改
UART_InitStruct
参数,UART 的初始化参数配置如下表。调用
UART_Init()
,初始化 UART 外设。
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 |
对 GDMA 外设进行初始化:
定义
GDMA_InitTypeDef
类型GDMA_InitStruct
,调用GDMA_StructInit()
将GDMA_InitStruct
预填默认值。根据需求修改
GDMA_InitStruct
参数。GDMA TX 和 RX 通道的初始化参数配置如下表。调用GDMA_Init()
,初始化 GDMA 外设。配置 GDMA 总传输完成中断
GDMA_INT_Transfer
和 NVIC,NVIC 相关配置可参考 中断配置。调用
GDMA_Cmd()
使能对应 GDMA 通道传输。
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 |
- |
功能实现
执行
uart_senddata_continuous
,发送### Uart trx gdma sample ###\r\n
到 PC 终端。在函数uart_senddata_continuous
内,等待 UART TX FIFO 为空时,分批将数据填入 FIFO 中。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++; } }
使能 GDMA TX 通道传输后,GDMA TX 通道将数据从
GDMA_SendData_Buffer
搬到(&(UART_DEMO->UART_RBR_THR))
。当 GDMA TX 数据传输完成后,触发 GDMA TX 通道GDMA_INT_Transfer
中断。在中断处理函数内打印相应信息。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!"); }
使能 GDMA RX 通道传输后,当在 PC 终端输入字符时,GDMA RX 通道将数据从
(&(UART_DEMO->UART_RBR_THR))
搬到GDMA_ReceiveData_Buffer
。当输入字符超过 29 个字节(1 Block)时,触发 GDMA RX 通道GDMA_INT_Transfer
中断:清除 GDMA
GDMA_INT_Transfer
中断标志位。执行
uart_senddata_continuous
,将 GDMA 收到的数据GDMA_ReceiveData_Buffer
发回 PC 终端。打印 GDMA 传输完成信息。
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);
}