UART - dma

本 demo 主要演示 UART dma 模式收发功能。

硬件连接

  • 芯片 UART TX 引脚连接 USB2TTL 模块 RX

  • 芯片 UART RX 引脚连接 USB2TTL 模块 TX

本 demo 使用到的 gpio 如下表:

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 TXUARTx 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 CH0UARTx TXDMA CH1UARTx 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 启动传输

  • 等待传输完成并进入中断

编译和烧录

参考 环境搭建

实验现象