无线时代

关于AR9344高速串口的使用

技术文章  ·  

这几天有客户打算使用AR9344的高速串口(高于115200波特率),但是原有的硬件设计已将这个高速串口连接到北斗/GPS模块,无法连接到其他外部设备。为了让客户快速进行原型验证,我想到了一个简单的方法:将AR9344的高速串口映射到原来的LED指示灯插座。

AR9344的高速串口原来使用的是GPIO11,GPIO12,现在需要进行的工作是将这两个IO改为GPIO21,GPIO22。仿照原来的方式,修改uboot下board/ar7240/db12x/db12x.c,初始化GPIO时,直接将高速串口的IO改为GPIO21,GPIO22,代码如下:

ar7240_reg_rmw_clear(GPIO_OE_ADDRESS, 0x003de000);
ar7240_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS, GPIO_OUT_FUNCTION5_ENABLE_GPIO_22_SET(0x4f));
ar7240_reg_rmw_set(GPIO_IN_ENABLE9_ADDRESS, GPIO_IN_ENABLE9_UART1_SIN_SET(0x15));

然后编译得到新的uboot。接下来修改Linux下的mach-db120.c,将RSSI LED由原来的GPIO21,GPIO22改为GPIO11,GPIO12,然后编译得到新的固件。将新的uboot及新的固件写入板卡进行测试,发现只能发数据不能收数据,经过反复检查,对比,没有发现任何代码错误。无奈之下求助于ChatGPT,它给出如下的临时修改方法:

# 1) 读 GPIO_FUNCTION(UART1_RD/CTS 在这里)
devmem 0x1804006C 32

# 2) 把 UART1_RD 改成 21(只改 [23:16],其余位保持不动)
old=$(devmem 0x1804006C 32)
new=$(( (old & ~0x00FF0000) | (21<<16) ))
printf "old=%#x new=%#x\n" "$old" "$new"
devmem 0x1804006C 32 $new

# 3) 确保 GPIO21 方向为输入(GPIO_OE bit21 = 1)
oe=$(devmem 0x18040000 32)
newoe=$(( oe | (1<<21) ))
printf "oe=%#x newoe=%#x\n" "$oe" "$newoe"
devmem 0x18040000 32 $newoe

实测有效,解释如下:

GPIO21→UART1_RX 的选择位在 GPIO_FUNCTION(0x1804006C) 里,你的 OpenWrt 启动后这个寄存器没有保持为 21(通常被内核/板级默认配置写回了别的值),所以 UART1 仍在“旧 RX GPIO”上取数据,表现就是“能发不能收”。你用 devmem 临时改了就立刻恢复,说明硬件连线和 UART 本身都没问题。

本文做个简单记录,后续再遇到类似问题可以用同样的方法解决。

#