rp2040中dma传输数据的函数配置

/ 8 bit transfers. Both read and write address increment after each // transfer (each pointing to a location in src or dst respectively). // No DREQ is selected, so the DMA transfers as fast as it can.

  1. 8 bit transfers: 这意味着DMA每次传输8位(即1字节)的数据。DMA传输数据的大小可以有所不同,从1字节到32字节或更多,这取决于DMA控制器的配置和所连接的设备。
  2. Both read and write address increment after each transfer: 当DMA完成一次数据传输后,无论是从源地址(src)读取还是从目标地址(dst)写入,其相应的地址都会增加。这意味着,如果DMA被配置为从源地址读取数据并写入目标地址,那么在每次传输后,源地址和目标地址都会向前移动一个位置。
  3. No DREQ is selected: DREQ通常是一个信号,它告诉DMA控制器何时开始或停止传输。如果DREQ没有被选中,那么DMA会尽可能快地进行传输,不受外部信号的控制。这通常意味着DMA将连续传输数据,直到它被其他方式(如软件命令或硬件中断)停止。

总的来说,这段描述表明DMA控制器被配置为以8位为单位进行传输,并且在每次传输后自动更新源和目标地址。由于没有选择DREQ,DMA将不受外部信号控制,而是尽可能快地进行数据传输。

/ Note the order of the fields here: it's important that the length is before // the read address, because the control channel is going to write to the last // two registers in alias 3 on the data channel: // +0x0 +0x4 +0x8 +0xC (Trigger) // Alias 0: READ_ADDR WRITE_ADDR TRANS_COUNT CTRL // Alias 1: CTRL READ_ADDR WRITE_ADDR TRANS_COUNT // Alias 2: CTRL TRANS_COUNT READ_ADDR WRITE_ADDR // Alias 3: CTRL WRITE_ADDR TRANS_COUNT READ_ADDR // // This will program the transfer count and read address of the data channel, // and trigger it. Once the data channel completes, it will restart the // control channel (via CHAIN_TO) to load the next two words into its control // registers.

这段代码和注释描述了一个DMA(直接内存访问)传输的配置和流程,特别是关于控制通道和数据通道之间的交互。这里的关键点在于如何设置数据通道的寄存器,以便进行DMA传输。

首先,让我们解析注释中的关键信息:

  • 字段的顺序很重要:长度(TRANS_COUNT)必须在读地址(READ_ADDR)之前,因为控制通道将写入数据通道别名3中的最后两个寄存器。
  • 别名(Alias)0、1、2和3表示数据通道的不同寄存器配置。每个别名都有不同的寄存器顺序。
  • 控制通道将通过写入这些别名寄存器来配置数据通道的传输。

现在,让我们详细解释每个别名的作用:

别名0 (Alias 0)

  • +0x0(READ_ADDR): 数据通道读取数据的源地址。
  • +0x4(WRITE_ADDR): 数据通道写入数据的目标地址。
  • +0x8(TRANS_COUNT): 要传输的数据量(以字节为单位)。
  • +0xC(CTRL): 控制寄存器,用于触发传输和其他控制功能。

别名1 (Alias 1)

  • +0x0(CTRL): 控制寄存器。
  • +0x4(READ_ADDR): 数据通道读取数据的源地址。
  • +0x8(WRITE_ADDR): 数据通道写入数据的目标地址。
  • +0xC(TRANS_COUNT): 要传输的数据量。

别名2 (Alias 2)

  • +0x0(CTRL): 控制寄存器。
  • +0x4(TRANS_COUNT): 要传输的数据量。
  • +0x8(READ_ADDR): 数据通道读取数据的源地址。
  • +0xC(WRITE_ADDR): 数据通道写入数据的目标地址。

别名3 (Alias 3)

  • +0x0(CTRL): 控制寄存器。
  • +0x4(WRITE_ADDR): 数据通道写入数据的目标地址。
  • +0x8(TRANS_COUNT): 要传输的数据量。
  • +0xC(READ_ADDR): 数据通道读取数据的源地址。

最后,注释中提到:“这将设置数据通道的传输计数和读地址,并触发它。一旦数据通道完成,它将通过CHAIN_TO重启控制通道,以将下一个两个单词加载到其控制寄存器中。” 这意味着控制通道将配置数据通道进行一次DMA传输,然后在传输完成后,控制通道将自身重启,以便加载下一组配置参数进行下一次传输。

总的来说,这段代码和注释描述了一个DMA传输的详细流程,包括如何配置数据通道的寄存器以及控制通道如何管理这些传输。

dma_channel_configure( chan, // Channel to be configured &c, // The configuration we just created dst, // The initial write address src, // The initial read address count_of(src), // Number of transfers; in this case each is 1 byte. true // Start immediately. );

这段代码调用了一个名为 dma_channel_configure 的函数,用于配置一个DMA通道。让我们逐一分析参数的含义:

  1. chan: 这是要配置的DMA通道的标识符。每个系统可能有多个DMA通道,chan 用于指定哪个通道需要配置。

  2. &c: 这是一个指向配置结构体的指针,该结构体包含了DMA传输的各种参数设置。这些参数可能包括传输模式、数据宽度、中断使能等。&c 表示我们传递的是配置结构体的地址,这样函数内部可以修改该结构体的内容以配置DMA通道。

  3. dst: 这是DMA传输的目标地址,即数据应该被写入的内存位置。DMA控制器会将数据从源地址复制到这个地址。

  4. src: 这是DMA传输的源地址,即数据应该被读取的内存位置。DMA控制器会从这个地址读取数据,并将其传输到目标地址。

  5. count_of(src): 这个参数指定了DMA传输的数据量。count_of 可能是一个宏或函数,用于计算从源地址开始的数据量。在这个例子中,每个传输是1字节,所以 count_of(src) 将返回源地址处数据的字节数。

  6. true: 这个布尔值参数指示DMA传输是否应该立即开始。如果为 true,那么在配置完成后,DMA传输将立即启动。如果为 false,则可能需要额外的命令或事件来触发传输的开始。

综上所述,dma_channel_configure 函数的作用是配置一个DMA通道,指定源地址、目标地址、传输的数据量以及其他可能的参数,并决定是否立即启动DMA传输。这个函数是DMA数据传输之前必须调用的,以确保DMA控制器按照预定的参数正确地进行数据传输。

基于RP2040(Arduino框架)运行频率200Mhz,实现以50Msps速率驱动AD9220读取一定数量数据。 IO13作为按钮btn1设计为低电平触发,使用内部上拉,在主程序里运行,并软件消抖,触发一次,就启动sm0发射单个100ns宽度低电平脉冲,然后启动sm1读取一定数据,等待下一次按钮触发。 设计两个pio状态机sm0,sm1,分频均设置为1。IO14负责发射单个100ns宽度的低电平,100ns宽度使用pio指令内置延时[]功能,然后IO14恢复高电平,由状态机sm0负责驱动,状态机sm0中增加同步标记,发射100ns低电平后,立刻启动状态机sm1开始读取数据。 状态机sm1驱动IO15作为pclk输出到ad9220工作时钟,rp2040读取12位数据读取脚是io0~IO11, sm1在IO15输出50mhz时钟pclk,涉及延时的使用pio内置延时 [],ad9220在pclk低电平开始自行采样,在上升沿高锁存数据,使用测设置功能,在pclk高电平期间状态机sm1并行读取io0~IO11的12位数据,并存入一个buff数组。当一定数量(20000)数据被读取后,停止sm1 ,使用proce_data()函数处理。IO16负责LED指示灯使用反馈触发状态。请确认各个io口功能使用,请进行dma优化,分别给出pio代码和arduino代码,复核pio代码,特别是在pclk高电平期间是否读取12位数据,符合功能要求。 并扩展优化: 添加双缓冲机制实现连续采样 使用PIO IRQ实现精确同步 实现数据校验机制 添加tinyUSB数据传输接口
03-19
### PCIe 数据传输协议、原理及实现方式 #### 1. PCIe 数据传输概述 PCI Express (Peripheral Component Interconnect Express, 简称 PCIe) 是一种高速串行计算机扩展总线标准,用于连接主板上的设备与外部组件。它采用点对点拓扑结构,支持全双工通信,并提供高带宽和低延迟的数据传输能力。 在 PCIe 的数据传输过程中,主机处理器通过根复合体(Root Complex)与终端设备(Endpoint)或其他桥接器进行通信[^1]。这种架构允许多条链路并存,每条链路由多个通道组成,每个通道可以独立运行。 #### 2. PCIe 协议分层模型 PCIe 使用类似于 OSI 模型的分层体系来定义其协议栈: - **事务层(Transaction Layer)**: 负责管理读写请求以及完成消息传递的任务。此层会生成 TLPs(Transaction Layer Packets),这些包封装了所有的控制信息和有效载荷。 - **数据链接层(Data Link Layer)**: 提供可靠性的机制,比如序列号跟踪、CRC 校验等功能,确保上一层发出的信息能够无误地到达接收方。 - **物理层(Physical Layer)**: 包括电气特性和逻辑功能两部分,负责实际比特流的发送与接收。这一层还包含了 LTSSM(Link Training and Status State Machine),它是初始化阶段的关键状态机之一[^2]。 #### 3. PCIe 数据传输的具体实现方法 以下是关于如何利用 PCIe 进行高效数据交换的一些具体技术和实践案例: ##### (1)AXI 接口适配 Advanced eXtensible Interface (AXI),作为 AMBA 中的一种高性能接口规范,常被用来对接 FPGA 或 ASIC 设计中的 PCIe IP Core 。当 EP 输入的数据经由 AXI 和 PCIe 核处理之后再传送到另一侧时,整个流程遵循严格的同步与时序要求。 示例代码展示了一个简单的基于 AXI 流模式下主控模块向目标设备发起 DMA 请求的操作: ```verilog always @(posedge clk or negedge reset_n) begin if (!reset_n) begin axi_awvalid <= 0; axi_wvalid <= 0; end else begin // Address phase setup if (!axi_awready && !axi_awvalid) begin axi_awaddr <= addr_to_write; axi_awlen <= burst_length - 1; // Burst length minus one axi_awsize <= `SIZE_4BYTES ; axi_awburst<= `INCR_BURST_TYPE; axi_awcache<= `NORMAL_ACCESS_CACHE_POLICY; axi_awprot <= 3'b000; axi_awvalid<= 1; end // Data phase setup if(axi_awready && axi_awvalid && !axi_wlast_sent )begin ... ``` ##### (2)中断驱动 vs DMA 技术比较 对于大规模连续性数据块搬运场景而言,直接存储访问(DMA)无疑是最优解法因为它无需 CPU 干预即可自动完成大量资料搬移动作从而极大提升了整体效率减少系统资源消耗;而针对少量随机事件通知类业务则更适合采取传统软件轮询或者硬件触发式中断服务程序来进行响应处理。 #### 4. 示例分析:EP 回发 RP 数据路径描述 假设在一个典型的嵌入式开发环境中存在如下情况——远程处理器(RP)需要获取本地加速单元(EP)计算后的结果集并通过 PCIe 链路返回给自己用户空间的应用进程使用,则完整的往返路线可能涉及到以下几个主要环节: 1. 用户层调用函数库API提交作业指令至RP内部缓冲区等待执行; 2. 经过一系列中间件转换后形成标准化格式TLP包裹送达到对应端口号关联起来的目标位置即EP处启动相应算法运算活动; 3. 计算完成后重新打包成新的TLP形式沿着相反方向逆向传播直至回到起点再次进入操作系统内核区域接受进一步解析调度最后交付给最初发起者消费掉得到预期成果反馈出来显示界面之上呈现给最终使用者查看参考引用说明文档里提到相关内容片段解释清楚上述现象背后隐藏的技术细节要点. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星海露水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值