# 功能特性 ## DMA 系统传输 ### 源和目的设备 在 DMA 系统中,源设备和目的设备可以是内存或外设,支持以下传输模式:`内存到内存`、`内存到外设`、`外设到内存`、`外设到外设`。当源设备和目的设备为外设时,需要进行握手。握手方式分为`硬件握手`和`软件握手`。软件握手通过软件寄存器进行操作,适用于未验证的模块,推荐使用硬件握手方式。接内存时无需握手,握手信号填 0 即可。 握手信号分配如下: | 握手号 | 对应外设 | | ------ | --------------------- | | 0 | i2c0 接收 | | 1 | i2c0 TX | | 2 | 串口接收 | | 3 | 串口发送 | | 4 | 串口 1 接收 | | 5 | 串口 1 TX | | 6 | 串口 2 接收 | | 7 | 串口 2 发送 | | 8 | SPIO(闪存 SPI)接收 | | 9 | SPIO(闪存 SPI) TX | | 10 | SPI1(PSRAM SPI)接收 | | 11 | SPI1(PSRAM SPI)发送 | | 12 | SPI2(通用 SPI) RX | | 13 | SPI2(通用 SPI) TX | DMA Master 接口使用 - DMA0 接入 Flash SPI XIP 入口,用于 Flash 的读访问 - DMA1 接入 System Bus,用于支持 DMA 外设的访问 - DMA2 接入内存系统的 Bus Matrix,用于内存访问,以提高 memory to memory 的性能 ```c struct gx_dma_config dma_config = {0}; dma_config.src = (void *)(GX_REG_BASE_SPI2 + GX_HAL_SPI_RXDR); dma_config.dst = (void *)((unsigned int)buf & 0x0FFFFFFF); dma_config.config.src_hs_per = DMA_HS_PRE_SPI2_RX; dma_config.config.dst_hs_per = 0; ``` ### 流控 在 DMA 传输过程中,流控可以由 DMA 或外设来控制。当 DMA 作为流控时,DMA 传输完成后会通知外设传输完成;当外设作为流控时,外设会通知 DMA 进行最后一次传输,随后 DMA 再通知外设传输完成。 ```c struct gx_dma_config dma_config; dma_config.config.flow_ctrl = GX_HAL_DMA_AHB_TT_FC_PER_TO_MEM_DMAC; ``` ### 数据位宽 可以通过 \ref GX_HAL_DMA_AHB_TRANSFRE_WIDTH 配置传输数据的位宽。传输的数据将以配置的位宽为单位进行计量。例如,若配置为 16bit 宽度,传输 100 个单位,即传输 100 个 16bit 数据。 ```c struct gx_dma_config dma_config; dma_config.config.trans_width = GX_HAL_DMA_AHB_TRANS_WIDTH_16; ``` ### 突发传输 突发传输将若干数据组合成一个数据序列,在一次总线传输中完成整个数据序列的传输,从而减少频繁的端口握手请求。可以通过 msize 配置一次突发传输的大小,最大为 256 个数据,最小为 1 个数据。msize 的单位为数据位宽,例如数据位宽为 32bit,则 msize=8 代表 8 个 32bit 数据为一组。 ```c struct gx_dma_config dma_config; dma_config.config.src_msize = GX_HAL_DMA_AHB_BURST_TRANS_LEN_8; ``` ### Master 接口 外设固定连接在不同的 DMA 端口上,这些端口称为 DMA Master。DMA Master 用于与外设进行交互,如握手、流控、结束等控制信号的交互。 DMA Master 接口分配: * GX_DMA_AHB_MASTER_1:接入 flash spi XIP,用于 flash XIP 的读访问 * GX_DMA_AHB_MASTER_2:接入 system bus, 用于支持外设访问 * GX_DMA_AHB_MASTER_3:接入内存的 bus Matrix,用于内存访问,提高 memory to memory 的性能 ### 传输通道 DMA 包含多个通道,每个通道独立运行。源设备和目的设备通过读写通道中的 FIFO 进行数据传输。通道申请通过使用 \ref gx_dma_select_channel 接口进行。在申请通道时,需要保护临界区,关闭中断和任务切换,以防止通道申请时发生冲突。 ```c int rx_channel = -1; rx_channel = gx_dma_select_channel(); if (rx_channel < 0) return -1; ``` ### 链表传输 `DMA single block` 传输数据的最大长度为 4095 个单位,超过此长度将使用链表来组织传输数据信息。链表中会配置`源地址`、`目的地址`、`数据地址`、`数据长度`、`控制寄存器`等信息。传输接口中已实现根据传输长度自动启用链表传输:小于等于 4095 字节时使用单块 block 传输,超过时使用链表传输。