UART - dma
本 demo 主要演示 UART dma 模式收发功能。
硬件连接
芯片 UART TX 引脚连接 USB2TTL 模块 RX
芯片 UART RX 引脚连接 USB2TTL 模块 TX
本 demo 使用到的 gpio 如下表:
名称 |
芯片型号 |
GPIO |
---|---|---|
UART1_TX |
BL702 |
GPIO 18 |
BL616 |
GPIO 23 |
|
UART1_RX |
BL702 |
GPIO 19 |
BL616 |
GPIO 24 |
软件实现
具体软件代码见 examples/peripherals/uart/uart_podma
1board_init();
board_init
中会开启 UART IP 时钟,并选择 UART 时钟源和分频。
1board_uartx_gpio_init();
配置相关引脚为
UARTx TX
、UARTx RX
功能,默认 demo 使用 UART1 外设。
1uartx = bflb_device_get_by_name(DEFAULT_TEST_UART);
2
3struct bflb_uart_config_s cfg;
4
5cfg.baudrate = 2000000;
6cfg.data_bits = UART_DATA_BITS_8;
7cfg.stop_bits = UART_STOP_BITS_1;
8cfg.parity = UART_PARITY_NONE;
9cfg.flow_ctrl = 0;
10cfg.tx_fifo_threshold = 7;
11cfg.rx_fifo_threshold = 7;
12bflb_uart_init(uartx, &cfg);
获取 DEFAULT_TEST_UART 句柄,并初始化 UART
1bflb_uart_link_txdma(uartx, true);
2bflb_uart_link_rxdma(uartx, true);
使能 uart tx、rx dma 功能
1struct bflb_dma_channel_config_s config;
2
3config.direction = DMA_MEMORY_TO_PERIPH;
4config.src_req = DMA_REQUEST_NONE;
5config.dst_req = DEFAULT_TEST_UART_DMA_TX_REQUEST;
6config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
7config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
8config.src_burst_count = DMA_BURST_INCR1;
9config.dst_burst_count = DMA_BURST_INCR1;
10config.src_width = DMA_DATA_WIDTH_8BIT;
11config.dst_width = DMA_DATA_WIDTH_8BIT;
12bflb_dma_channel_init(dma0_ch0, &config);
13
14struct bflb_dma_channel_config_s rxconfig;
15
16rxconfig.direction = DMA_PERIPH_TO_MEMORY;
17rxconfig.src_req = DEFAULT_TEST_UART_DMA_RX_REQUEST;
18rxconfig.dst_req = DMA_REQUEST_NONE;
19rxconfig.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
20rxconfig.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
21rxconfig.src_burst_count = DMA_BURST_INCR1;
22rxconfig.dst_burst_count = DMA_BURST_INCR1;
23rxconfig.src_width = DMA_DATA_WIDTH_8BIT;
24rxconfig.dst_width = DMA_DATA_WIDTH_8BIT;
25bflb_dma_channel_init(dma0_ch1, &rxconfig);
26
27bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL);
28bflb_dma_channel_irq_attach(dma0_ch1, dma0_ch1_isr, NULL);
配置 DMA CH0 为 UARTx TX , DMA CH1 为 UARTx RX .
注册 dma 通道中断
1struct bflb_dma_channel_lli_pool_s tx_llipool[20]; /* max trasnfer size 4064 * 20 */
2struct bflb_dma_channel_lli_transfer_s tx_transfers[3];
3
4tx_transfers[0].src_addr = (uint32_t)src_buffer;
5tx_transfers[0].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR;
6tx_transfers[0].nbytes = 4100;
7
8tx_transfers[1].src_addr = (uint32_t)src2_buffer;
9tx_transfers[1].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR;
10tx_transfers[1].nbytes = 4100;
11
12tx_transfers[2].src_addr = (uint32_t)src3_buffer;
13tx_transfers[2].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR;
14tx_transfers[2].nbytes = 4100;
15
16struct bflb_dma_channel_lli_pool_s rx_llipool[20];
17struct bflb_dma_channel_lli_transfer_s rx_transfers[1];
18rx_transfers[0].src_addr = (uint32_t)DEFAULT_TEST_UART_DMA_RDR;
19rx_transfers[0].dst_addr = (uint32_t)receive_buffer;
20rx_transfers[0].nbytes = 50;
21
22bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 20, tx_transfers, 3);
23bflb_dma_channel_lli_reload(dma0_ch1, rx_llipool, 20, rx_transfers, 1);
24bflb_dma_channel_start(dma0_ch0);
25bflb_dma_channel_start(dma0_ch1);
分配一块 lli 内存池,个数为20,最多可以传输 4094 * 20 字节
配置三块不连续的内存进行传输
调用
bflb_dma_channel_lli_reload
初始化调用
bflb_dma_channel_start
启动传输等待传输完成并进入中断
编译和烧录
参考 环境搭建