打印
[N32WBxxx]

JTAG 相关管脚复用为 GPIO 的一个问题

[复制链接]
804|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 wangqy_ic 于 2022-3-14 22:40 编辑

这两天处理了一个关于 JTAG 相关管脚复用为 GPIO 的一个问题,整理一下免得大家再在这个问题耗费时间。

【问题描述】
我的板子上需要把 PB3 当做一个普通的数字输出口。根据手册说明,需要把 JTAG 关掉(可以开启 SWD),再按 GPIO 配置为合适的输出功能。一般的操作(包括官方提供的示例里)关键代码就两行:
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);
第一行开启 AFIO 电源,第二行关掉 JTAG,开启 SWD。

然后就是初始化 GPIO,这部分代码就省略了。

在官方示例里,这两行代码完全没有问题。但是在我实际的工程项目中,这两行并不起效。

【问题排查】
测试,有如下结果:
官方示例代码+开发板 --> OK。
官方示例代码+自有板子 --> OK。

自有代码+开发板 --> FAIL。
自有代码+自有板子 --> FAIL。


那问题肯定是在自己的代码里。反复检查核对,各个寄存器相关值都是没问题,除了 AFIO->RMP_CFG 这个寄存器的 SW_JTAG_CFG 值不一致。
核对手册,有如下描述:


读取 SW_JTAG_CFG 返回未定义的值

问题就出在这个点:我自己的代码里,后续还会复用另外的管脚,会多次操作 AFIO->RMP_CFG 这个寄存器。
虽然每次都是 读-改-写 的方式:
reg_val = AFIO->RMP_CFG;
        
reg_val &= ~(MASK);
reg_val |= VAL;
        
AFIO->RMP_CFG = reg_val;


但是由于 SW_JTAG_CFG 的值不能正确读取,所以每次修改前读取到的 SW_JTAG_CFG 的值可能都不是正确的,错误的值会被写到  SW_JTAG_CFG 进而导致后续的问题。

【处理办法】
嗯……很丑陋的一个解决办法:在每次修改 AFIO->RMP_CFG 后,再写个合适的值到 SW_JTAG_CFG 位置,我的代码里是 2。
// ...
// Ensure RMP_CFG.SW_JTAG_CFG=2
reg_val = AFIO->RMP_CFG;
       
reg_val &= (~(7UL << 24));
reg_val |= (2UL << 24);
       
AFIO->RMP_CFG = reg_val;


其他的复用管脚,也要特别注意这个问题。

以上,做个记录,大家遇到问题也省些时间……

-- END --



使用特权

评论回复
沙发
wangqy_ic|  楼主 | 2022-3-14 22:44 | 只看该作者
经查,N32G45x系列手册里关于 AFIO->RMP_CFG 也是这样的描述。

使用特权

评论回复
板凳
七毛钱| | 2022-3-15 14:54 | 只看该作者
楼主真是大好人,让我们坛友少走不少弯路

使用特权

评论回复
地板
elife| | 2022-3-15 21:27 | 只看该作者
只能写,不能读的特殊寄存器,可以用个变量保存,每次修改,都修改完变量后,再把变量写入特殊寄存器。

使用特权

评论回复
5
N32BLE| | 2022-3-16 20:02 | 只看该作者
感谢发帖分享,让其他开发者朋友少走弯路。

使用特权

评论回复
6
liangzheng63| | 2022-11-6 13:51 | 只看该作者
这确实是一个很麻烦的问题,调了几天才发现这几个位无法在DEBUG模式中读出来,读到的值一直是0,慢慢才找到问题在这

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:感恩的心对人。

17

主题

96

帖子

4

粉丝