S32K348-GPIO EIRQ 到 DMA 请求尊敬的恩智浦技术支持团队:
我现在尝试的方法,将 GPIO PTD6 设置为 EIRQ14,上升沿检测,我想将此引脚信号映射到 DMA 通道,我尝试从 PIT_1 Timer[0] 获取当前值。这是自由奔跑模式。
看起来 SIUL2 已正确设置为 PTDA,当信号发生器发出的信号 (1Hz) 连接到相关的 MCU 引脚时,我可以看到该引脚切换。
但是DMA对我来说不起作用
我的猜测是,我的问题在于找不到从 PTD6 -> DMAMUX -> DMA 通道 4 的正确链路,也找不到在哪里可以找到这些信息。
从 S32K3xx_DMAMUX_map.xlsx 文件中我得到了以下内容:
OndrejK_0-1784190602227.png
我的第一个问题是:哪个源->请求是专用的 PTD6(EIRQ14)?
RM手册中的表44与此有何关联?
OndrejK_1-1784190821068.png
以下是我目前正在编写的部分代码:
设置 PTD6
void Setup_PTD6_EIRQ14_for_DMA ( void )
{
/* 1. 通过 MSCR 寄存器配置物理引脚 PTD6 */
// PTD6 对应于索引 MSCR[102](如您的屏幕截图所示)
IP_SIUL2 -> MSCR [ 102 ] = 0 ; // 清除寄存器
IP_SIUL2 -> MSCR [ 102 ] |= ( 1 << 19 ); // IBE = 1(输入缓冲使能 - 将引脚配置为输入)
IP_SIUL2 -> IMCR [ 542 - ( 512 )] = 3u ;
// 可选:如果信号是浮动的,您可以启用上拉(PUE=1,PUS=1)或下拉(PUE=1,PUS=0)
/* 2. 激活 EIRQ[14] 线上的边缘检测 */
我们希望捕获每个上升沿的时间戳
IP_SIUL2 -> IREER0 |= ( 1 << 14 ); // IREER0[EIRE14] = 1 (启用上升沿)
IP_SIUL2 -> IFEER0 &= ~ ( 1 << 14 ); // IFEER0[EIRE14] = 0 (禁用下降沿)
/* 3. 请求路由:从中断更改为 DMA */
// 此步骤确保边沿不会唤醒 CPU(NVIC),而是触发 DMA 线路。
IP_SIUL2 -> DIRSR0 |= ( 1 << 14 ); // DIRSR0[DIRS14] = 1 (选择 DMA 请求而不是中断)
/* 4. 最终启用 EIRQ[14] 的 DMA 请求生成 */
IP_SIUL2 -> DIRER0 |= ( 1 << 14 ); // DIRER0[EIRE14] = 1 (激活 DMA 请求线)
}
并建立DMA通道:
void Setup_eDMA_Channel4_Capture_PIT1 ( void )
{
/* 1. eDMA 通道 4 的 DMAMUX 初始化 */
// 将 EIRQ14(源 14)映射到 eDMA 通道 4
IP_DMAMUX_1 -> CHCFG [ 4 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u ); // EIRQ14 是 DMAMUX_1 的源 7
//IP_DMAMUX_0->CHCFG[4] = 0U;
/* 2. 通道 4 的 TCD 配置指向 PIT_1(完全符合 S32K3 裸机语法) */
// 来源:PIT_1 定时器 0 的当前值
IP_TCD -> TCD4_SADDR = ( uint32_t ) & ( IP_PIT_1 -> TIMER [ 0 ]. CVAL );
IP_TCD -> TCD4_SOFF = 0 ; // 源值不递增
IP_TCD -> TCD4_ATTR = 0x0202 ; // 32 位源,32 位目标
// 次要循环:每次触发传输的字节数
// 在 S32K3 中,这对应于 NBYTES_MLOFFNO 寄存器(无次要循环链接)
IP_TCD -> NBYTES4 . TCD4_NBYTES_MLOFFNO = 4 ; // 每次触发信号传输 4 字节(32 位)
// 目标位置:内存中的数组
IP_TCD -> TCD4_DADDR = ( uint32_t ) dma_timestamps ;
IP_TCD -> TCD4_DOFF = 4 ; // 每次边沿移动后,RAM 中的数据左移 4 个字节
// 循环缓冲区:填充完整个数组后循环回到数组开头
IP_TCD -> TCD4_DLAST_SGA = - ( BUFFER_SIZE * 4 );
// 主要循环计数器:循环中的总迭代次数
//IP_TCD->CITTER4.TCD4_CITER_ELINKNO = BUFFER_SIZE;
IP_TCD -> CITER4 . TCD4_CITER_ELINKNO = BUFFER_SIZE ;
IP_TCD -> BITER4 . TCD4_BITER_ELINKNO = BUFFER_SIZE ;
/* 3. 通过官方宏激活硬件触发信号的 eDMA 通道 */
//IP_TCD->CH4_CSR |= DMA_TCD_CH4_CSR_ERQ_MASK;
/* 3. 硬件触发信号的 eDMA 通道激活(启用异步模式) */
// 位 0 (ERQ) = 1 -> 启用硬件触发信号
// 位 2 (EARQ) = 1 -> 启用来自外部引脚的异步请求 (SIUL2 EIRQ)
IP_TCD -> CH4_CSR |= 3u ; // ERQ=1,EARQ=1
}
我想关键就在这里:
IP_DMAMUX_1 -> CHCFG [ 4 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u ); // EIRQ14 是 DMAMUX_1 的源 7
我有点困惑,不知道应该使用哪个 IP_DMAMUX 和哪个 DMAMUX_CHCFG_SOURCE,也不知道哪里可以找到相关的正确信息。
此致
翁德雷
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
“这是否意味着MCU有32个TCD通道,其中TCD 0到15对DMAMUX_0有效,TCD 15到31对DMAMUX_1有效? ”
是的,这些信息可以在数据手册中找到,我复制下来供您参考。
Senlent_0-1784272853624.png
Re: S32K348-GPIO EIRQ to DMA request你好 Senlent,
感谢您的解答。
请问您能否指出您所说的TCD映射的含义是从哪里产生的?
这是否意味着,MCU 有 32 个 TCD 通道,其中 TCD 0 到 15 对 DMAMUX_0 有效,而 TCD 15 到 31 对 DMAMUX_0 无效?
对于 DMAMUX_1?
所以,我对DMAMUX和eDMA的相关信息仍然有些困惑。
此致
翁德雷
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
你的理解是正确的:
PTD6->EIRQ14->DMAMUX1.SOURCE 7.
IP_DMAMUX_1->CHCFG[4] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(7u); // EIRQ14 is source 7 for DMAMUX_1
但是,TDC 设置不正确。
我的理解是,它们应该如下所示:
IP_DMAMUX_1->CHCFG[0] ->TCD 16
IP_DMAMUX_1->CHCFG[4] -> TCD 20 而不是 TCD4
Re: S32K348-GPIO EIRQ to DMA request嗨 SenLent,
我根据观察结果对代码进行了一些修改。
这是我最新的代码:
主初始化:
Setup_PTD6_EIRQ14_for_DMA ();
setup_PIT1_Timer0_FreeRunning ();
Setup_DMAMUX_Channel0_ToTCD16_Capture_PIT1 ();
//清除 EIRQ14 中断标志
IP_SIUL2 -> DISR0 = ( 1 << 14 );
以下是其余代码:
void Setup_PTD6_EIRQ14_for_DMA ( void )
{
// 1. Aktivácia hodinového deliča pre filtre v SIUL2 (ak už nie je povolený inde)
IP_SIUL2 -> IFCPR = 0U ; // 功能时钟的 Nastavenie deličky filtra (bez dodatočného delenia)
// 2. Voliteľne vypnite 过滤器预 daný EIRQ 索引 alebo ho nastavte na minimálny počet cyklov
// Pre EIRQ14(v závislosti od mapovania registrov IFMCR):
IP_SIUL2 -> IFMCR [ 14 ] = 0U ; // 0U vypína digitalálny过滤器,hrana prechádza okamžite ako čistý Hardvérový触发器
/* 1. 通过 MSCR 寄存器配置物理引脚 PTD6 */
// PTD6 对应于索引 MSCR[102](如您的屏幕截图所示)
IP_SIUL2 -> MSCR [ 102 ] = 0 ; // 清除寄存器
IP_SIUL2 -> MSCR [ 102 ] |= ( 1 << 19 ); // IBE = 1(输入缓冲使能 - 将引脚配置为输入)
IP_SIUL2 -> IMCR [ 542 - ( 512 )] = 3u ;
// 可选:如果信号是浮动的,您可以启用上拉(PUE=1,PUS=1)或下拉(PUE=1,PUS=0)
/* 2. 激活 EIRQ[14] 线上的边缘检测 */
我们希望捕获每个上升沿的时间戳
IP_SIUL2 -> IREER0 |= ( 1 << 14 ); // IREER0[EIRE14] = 1 (启用上升沿)
IP_SIUL2 -> IFEER0 &= ~ ( 1 << 14 ); // IFEER0[EIRE14] = 0 (禁用下降沿)
/* 3. 请求路由:从中断更改为 DMA */
// 此步骤确保边沿不会唤醒 CPU(NVIC),而是触发 DMA 线路。
IP_SIUL2 -> DIRSR0 |= ( 1 << 14 ); // DIRSR0[DIRS14] = 1 (选择 DMA 请求而不是中断)
/* 4. 最终启用 EIRQ[14] 的 DMA 请求生成 */
IP_SIUL2 -> DIRER0 |= ( 1 << 14 ); // DIRER0[EIRE14] = 1 (激活 DMA 请求线)
}
void Setup_DMAMUX_Channel0_ToTCD16_Capture_PIT1 ( void )
{
/* 1. eDMA 通道 4 的 DMAMUX 初始化 */
// Podľa NXP tabuľky prislúcha SIUL2 DMA 请求 4 zdrojový 索引 7u
//IP_DMAMUX_1->CHCFG[4] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(7u);
//按照文档操作,先禁用通道 4,然后配置它,最后启用它。
IP_DMAMUX_1 -> CHCFG [ 0 ] = 0u ;
/* 2. 通道 4 的 TCD 配置指向 PIT_1(完全符合 S32K3 裸机语法) */
// 来源:PIT_1 定时器 0 的当前值
IP_TCD -> TCD16_SADDR = ( uint32_t ) & ( IP_PIT_1 -> TIMER [ 0 ]. CVAL );
IP_TCD -> TCD16_SOFF = 0 ; // 源值不递增
IP_TCD -> TCD16_ATTR = 0x0202 ; // 32 位源,32 位目标
// 次要循环:每次触发传输的字节数
// 在 S32K3 中,这对应于 NBYTES_MLOFFNO 寄存器(无次要循环链接)
IP_TCD -> NBYTES16 . TCD16_NBYTES_MLOFFNO = 4 ; // 每次触发传输 4 字节(32 位)
// 目标位置:内存中的数组
IP_TCD -> TCD16_DADDR = ( uint32_t ) dma_timestamps ;
IP_TCD -> TCD16_DOFF = 4 ; // 每次边沿移动后,RAM 中的数据左移 4 个字节
// 循环缓冲区:填充完整个数组后循环回到数组开头
IP_TCD -> TCD16_DLAST_SGA = - ( BUFFER_SIZE * 4 );
// 主要循环计数器:循环中的总迭代次数
//IP_TCD->CITTER20.TCD20_CITER_ELINKNO = BUFFER_SIZE;
IP_TCD -> CITER16 . TCD16_CITER_ELINKNO = BUFFER_SIZE ;
IP_TCD -> BITER16 . TCD16_BITER_ELINKNO = BUFFER_SIZE ;
//IP_TCD->CH16_CSR |= 3u; // ERQ=1,EARQ=1
//启用DMAMUX通道0
IP_DMAMUX_1 -> CHCFG [ 0 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 6u );
__asm volatile ( "nop" );
__asm volatile ( "nop" );
IP_TCD -> CH16_CSR |= 3u ;
}
我仍然无法通过 EIRQ(14) 启动 DMA 传输,即使出现此断言。在调试器中,当我改变MCU PTD6引脚上的信号时,可以看到标志出现。
接下来,我可以通过 TCD16_CSR START 位手动启动 DMA 传输,TCD 通道上的 CITTER 值会减小,并且 PIT1_TIMER[0] 中的值会被存储到我的 dma_timestamps 数组中。
顺便说一下:这应该在“普通”SRAM部分定义。我之前将其设置为数据缓存段,导致出现 DMA“目标总线错误”。
新定义:
__attribute__ ((对齐( 32 ))) __attribute__ ((部分( ".mcal_data" )))
uint32_t dma_timestamps [ BUFFER_SIZE ];
但是,如果我跳过手动 START(从代码开始就不需要设置),并且我更改 PTD6 引脚上的信号,DMA 通道不会执行任何操作,CITTER 寄存器保持在初始化值。
请问您能帮我找出问题所在吗?
我仍然认为 PTD6-EIRQ(14) 钳位标志与 TCD16 通道之间的连接存在问题。
可能是DMAMUX通道的正确来源?
对于 DMAMUX1-CH[0],我测试了所有信号源(1 到 我尝试了DMAMUX Excel表格中列出的SUIL2实例,但没有成功,而且我也不确定我的步骤是否正确。
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
我创建了一个演示供您参考,使用 PTD6 触发 DMA 进行单次数据传输。
它基于 S32K344 + RTD 7.0.1。
我已经测试过了;
我可以向你保证,我的理解是正确的。
对于 PTD6,来源应为 7。
IP_DMAMUX_1 -> CHCFG [ 0 ] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE ( 7u );
Senlent_1-1784689141057.png
Re: S32K348-GPIO EIRQ to DMA request你好 Senlent,
非常感谢你提供的例子。
经过一些修改,我现在有了可以运行的示例。我附上了修改后的项目文件,其中存在一个重要问题:
在整个 DMA TCD 通道完全配置之前,已设置了启用 DMA 请求的 SIUL ICU。在这种情况下,TCD_SADDR 和 TCD_DADDR 为空(值为零),之后在 SUIL 中启用 DMA 请求导致 DMA 错误 - “源总线错误”,这让我明白了。
更改初始化顺序后。例如,它开始对我有用。
但我仍然不太理解DMAMUX通道和TCD通道之间的确切关系。
您写道,DMAMUX 应该配置为 CHCGF[0]。
在我们的 S32k344 定制开发板上下载并启动应用程序后,我发现 DMAMUX-CHCFG[3] 已配置,并且确切地说,在函数Dma_Mux_Ip_Init_Privileged 的代码行中,有一行代码导致了此配置:
RegisterIndex = DMA_MUX_IP_GATE_OFFSET((pConfig->pChannelConfigArr[ChannelCount].Channel));
这是 lauterbach Trace32 调试器的屏幕截图,您可以在其中看到所有初始化步骤之后的最终设置:
OndrejK_0-1784795174339.png
在将 RTD 更新到 7.0.1 版本后,我在 Design Studio 中配置如下:
OndrejK_1-1784795478141.png
这样理解是否正确?这里可以选择 3 个 DMA 复用源,这意味着什么?
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
听到这个消息真好。
对于刚入门的开发人员来说,这个配置工具可能会让他们感到困惑。
对于 S32K348,没有 DMAMUX_3;只有 DMAMUX_0 和 DMAMUX_1。
•对于 S32K310、S32K311 和 S32K312:DMAMUX_0 通道 0–5 和 DMAMUX_1 通道 0–5 分别映射到 eDMA 传输控制描述符 (TCD) 0–5 和 eDMA 传输控制描述符 (TCD) 6–11。因此,不应编程 DMAMUX_0 通道 6-15 和 DMAMUX_1 通道 6-15;但是,如果进行了编程,任何访问都将导致通道 8-15 出现错误响应,或者通道 6-7 没有错误响应。
•对于其余的 S32K3xx 设备:DMAMUX_0 通道 0–15 和 DMAMUX_1 通道 0–15 分别映射到 eDMA 传输控制描述符 (TCD) 0–15 和 eDMA 传输控制描述符 (TCD) 16–31。
以上内容摘自数据手册,很容易理解:
“ DMA硬件通道”对应于TCD编号。
当您选择 DMA_CHANNEL_0 到 DMA_CHANNEL_15 时,默认使用 DMAMUX_0;
当您选择 16–31 时,默认使用 DMAMUX_1。
例如,在本主题中,PTD6 对应于 DMAMUX_1 的源 7,因此“DMA 硬件通道”可以设置为 DMA_CHANNEL_16 到 DMA_CHANNEL_31 之间的任何值。
我们再举一个例子:如果您选择 EIRQ 7 来触发 DMA,则“DMA 硬件通道”可以设置为 DMA_CHANNEL_0 到 DMA_CHANNEL_15 之间的任何值。
Re: S32K348-GPIO EIRQ to DMA request嗨 SenLent,
关于选择DMA通道,我的想法是可以从相关的DMA_MUX组中自由选择一个。
同时,我测试了其他 DMA_MUX<-> 和 TCD 的组合,在我这边只有下一个组合可以正常工作。 IP_DMAMUX_1->CHCFG[3] 和 TCD16。
接下来我尝试了其他方法:
IP_DMAMUX_1->CHCFG[4] 和 TCD17。
IP_DMAMUX_1->CHCFG[0] 和 TCD16。
请问为什么只有 IP_DMAMUX_1->CHCFG[3] 和 TCD16?在职的 ?
IP_DMAMUX_1->CHCFG[xx] 与 TCDyy 之间是什么关系?
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
正确的顺序是:
IP_DMAMUX_0>CHCFG[0] 和 TCD0。
IP_DMAMUX_0->CHCFG[1] 和 TCD1。
IP_DMAMUX_0->CHCFG[2] 和 TCD2。
IP_DMAMUX_0->CHCFG[3] 和 TCD3。
IP_DMAMUX_0->CHCFG[4] 和 TCD4。
IP_DMAMUX_0->CHCFG[5] 和 TCD5。
IP_DMAMUX_0->CHCFG[6] 和 TCD6。
IP_DMAMUX_0->CHCFG[7] 和 TCD7。
IP_DMAMUX_0->CHCFG[8] 和 TCD8。
IP_DMAMUX_0->CHCFG[9] 和 TCD9。
IP_DMAMUX_0->CHCFG[10] 和 TCD10。
IP_DMAMUX_0->CHCFG[11] 和 TCD11。
IP_DMAMUX_0->CHCFG[12] 和 TCD12。
IP_DMAMUX_0->CHCFG[13] 和 TCD13。
IP_DMAMUX_0->CHCFG[14] 和 TCD14。
IP_DMAMUX_0->CHCFG[15] 和 TCD15。
IP_DMAMUX_1->CHCFG[0] 和 TCD16。
IP_DMAMUX_1->CHCFG[1] 和 TCD17。
IP_DMAMUX_1->CHCFG[2] 和 TCD18。
IP_DMAMUX_1->CHCFG[3] 和 TCD19。
IP_DMAMUX_1->CHCFG[4] 和 TCD20。
IP_DMAMUX_1->CHCFG[5] 和 TCD21。
IP_DMAMUX_1->CHCFG[6] 和 TCD22。
IP_DMAMUX_1->CHCFG[7] 和 TCD23。
IP_DMAMUX_1->CHCFG[8] 和 TCD24。
IP_DMAMUX_1->CHCFG[9] 和 TCD25。
IP_DMAMUX_1->CHCFG[10] 和 TCD26。
IP_DMAMUX_1->CHCFG[11] 和 TCD27。
IP_DMAMUX_1->CHCFG[12] 和 TCD28。
IP_DMAMUX_1->CHCFG[13] 和 TCD29。
IP_DMAMUX_1->CHCFG[14] 和 TCD30。
IP_DMAMUX_1->CHCFG[15] 和 TCD31。
Re: S32K348-GPIO EIRQ to DMA request嗨 SenLent,
我在最新的 S32 DS 项目上进行了测试,并添加了更多 DMA_MUX 配置。
这是我的设置截图:
OndrejK_0-1785138171795.png
以下是将版本代码下载到我们的板后的结果:
OndrejK_2-1785138306423.png
如您所见,您所描述的 DMA_MUX 和 TCD 的分配顺序并未得到遵循。
RTD软件也存在同样的bug吗?
Re: S32K348-GPIO EIRQ to DMA request这是我的项目,我只是调整了我之前附上的最新版本。
我在 DMA_MUX_0 上创建了 2 个通道,分别命名为 DMA_Channel_0 和 DMA_Channel_1。
对于这些通道,分配了 DMA_MUX_0->CHCFG[3] 和 DMA-MUX_0-CHCFG[2]。
DMA_MUX_1 上也出现了同样的“混合”顺序。
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
这是您提供的演示版本;我没有做任何修改。
这是我的检测结果。
Senlent_0-1785142055872.png
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
我看不出问题出在哪里。您能否解释得更清楚一些,或者提供完整的测试项目,以便我能告诉您您的疑问出在哪里?
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
很明显,这可能与您使用的调试器或调试器的版本有关。
Re: S32K348-GPIO EIRQ to DMA request你好 Senlent,
同时,我与另一位同事一起测试了同一个项目,他使用的是 S32DS 3.6.3 版本。Ozone调试器及其结果与你的相同。
看来你是对的。但我完全不清楚我这边发生了什么?
Re: S32K348-GPIO EIRQ to DMA request嗨 SenLent,
我终于找到问题所在了。
问题在于 Ozone 和 Lauterbach 只是提出了不同的 DMA_MUX->CHCFG 方法,最终的技巧是这些 CHCFG 寄存器在 MCU 端按以下顺序映射(DMA_MUX_1 的基地址为 0x40284000):
0x40284000 ->CHCFG[3]
0x40284001 ->CHCFG[2]
0x40284002 ->CHCFG[1]
0x40284003 ->CHCFG[0]
0x40284004 ->CHCFG[7]
0x40284005 ->CHCFG[6]
0x40284006 ->CHCFG[5]
0x40284007 ->CHCFG[4]
0x40284008 ->CHCFG[11]
……
请看我下面的截图
OndrejK_0-1785316902701.png
从现在开始,我的结果让我有所感知,也与你的建议相符。
感谢您的支持
我想这个问题应该可以解决。
Re: S32K348-GPIO EIRQ to DMA request你好@OndrejK
好的,请点击“接受为解决方案”关闭此主题。