鸣涧 发表于 2023-10-27 12:00:25

【openwrt】MT7628/7688 openwrt下启用串口2 UART2入坑指南

【openwrt】MT7628/7688 openwrt下启用串口2 UART2入坑指南


前言
【入坑】MT7628/7688有3个串口,UART0,UART1和UART2,但使用UART2 时碰到一些问题, MT7628/7688的UART2对应的IO口 默认是做网口功能,但未配置或开机状态,给MT7628/7688的UART2发送数据,会发现发送,MT7628/7688的UART2就会返回什么。刚开始用MT7628/7688的UART2时,我还以为焊板连锡了,检查板并没有连锡短路。后来又检查电路、查MT7628/7688 的手册、上网查资料,确定UART2电路没有错,是软件末配置好, openwrt源码里也没有相应代码。于是,我们这段历程写下来,让有此问题的小伙伴,少走一些弯路。

MT7628/7688串口简介

MT7628单网口模式下有3个串口,UART0默认为控制台使用,UART1和UART2用作和其他设备通信 。
多网口模式下只有两个串口,UART0默认为控制台使用,UART1用作和其他设备通信。
串口引脚对应关系表:
UART_RXD0      GPIO#13
UART_TXD0      GPIO#12
UART_RXD1      GPIO#46
UART_TXD1      GPIO#45
UART_RXD2      GPIO#21
UART_TXD2      GPIO#20


MT7628/7688串口2 UART2电路连接原理图

MT7628/7688串口2 UART2电路连接原理图,默认是网口功能,用网口功能时就不能用串口功能。




DTS文件

首先确保系统中启动/dev/ttyS2,先查看修改dts文件。

1)确保 ./target/linux/ramips/dts/mt7628an.dtsi中有如下代码
uart2: uart2@e00 {
                        compatible = "ns16550a";

                        reg = <0xe00 0x100>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        no-loopback-test;
                        clock-frequency = <40000000>;
                        resets = <&rstctrl 20>;
                        reset-names = "uart2";
                        interrupt-parent = <&intc>;

                        interrupts = <22>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&uart2_pins>;
                };
2)在 ./target/linux/ramips/dts/MT7628.dts中添加
MT7628芯片里面有很多管脚是复用,这里我们以“spis”功能为例做介绍如何配置JS76x8开发板的管脚功能复用。
找到DTS文件中的(源码目录下)
./target/linux/ramips/dts/MT7628.dts

spis {
                              ralink,group = "spis";
                              ralink,function = "pwm_uart2";
                        };
......
uart2_pins: uart2 {
                        uart2 {
                                        ralink,group = "uart2";
                              //ralink,function = "pwm";
                              ralink,function = "uart2";
                              };
&uart2 {
      status = "okay";
};
出MT7628芯片的SPIS管脚默认配置为"pwm_uart2"功能,具体可以配置哪几种功能是在
./build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.18.29/arch/mips/ralink/mt7620.cstatic struct rt2880_pmx_func spis_grp_mt7628[] = {
        FUNC("pwm_uart2", 3, 14, 4),
        FUNC("util", 2, 14, 4),
        FUNC("gpio", 1, 14, 4),
        FUNC("spis", 0, 14, 4),
};



MT7628/7688串口2 UART2寄存器配置

MT7688/7628分为IoT Device Mode和IoT Gateway Mode,即单网口模式和五网口模式。如要使用UART2,则必须使用单网口模式,需要配置的寄存器如下:


其中EPHY_GPIO_AIO_EN设置成digital pad。

1)修改内核源码方式

在./build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.132/arch/mips/ralink/mt7620.c中的prom_soc_init函数中添加u32 cfg;

cfg = __raw_readl(sysc + 0x3c);
cfg |= 0x0f<<17;
__raw_writel(cfg, sysc + 0x3c);编译openwrt源码,请参看:【Openwrt】开发环境搭建 编译openwrt源码-谷动谷力 (sunsili.com)

2)通过/dev/mem内存映射方式

编译openwrt时,先开启/dev/mem支持,make menuconfig

->Global build settings
      ->Kernel build options
                ->/dev/mem virtual device support

源码,每次开机时,执行该程序。
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

typedef enum{
      IOT_DEV_MODE,         //单网口模式
      IOT_GATEWAY_MODE      //五网口模式
}work_mode_7628_t;

int set_7628_work_mode(work_mode_7628_t mode)
{
      int ch;
      int mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
      if(mem_fd == -1)
      {
                perror("open /dev/mem");
                return -1;
      }
      int size = 0x100;
      int *addr = (int *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0x10000000);
      if(addr == MAP_FAILED)
      {
                perror("mmap");
                return -1;
      }

      if(mode == IOT_DEV_MODE)
      {
                *(addr+(0x3c/4)) |= 0x0f<<17;
      }
      else
      {
                *(addr+(0x3c/4)) &= ~(0x0f<<17);
      }

      close(mem_fd);
      munmap(addr, size);
      return 0;
}


int main(int argc, char **argv)
{
      work_mode_7628_t wrkMd = IOT_DEV_MODE;

      if(argc < 2)
      {
                set_7628_work_mode(wrkMd);
      }
      else
      {
                if(!strcmp(argv, "--iot-mode"))
                {
                        printf("Set iot_dev_mode\n\r");
                        set_7628_work_mode(IOT_DEV_MODE);
                }
                else if(!strcmp(argv, "--gateway-mode"))
                {
                        printf("Set gateway mode\n\r");
                        set_7628_work_mode(IOT_GATEWAY_MODE);
                }
                else
                {
                        printf("Usage: usemode --iot-mode | --gateay-mode\n\r");
                }
      }

      return 0;
}
保存编译、下载到开发板
具体操作请参阅:
【openwrt应用开发】openwrt交叉编译自己的应用程序入门-谷动谷力 (sunsili.com)

在开发板运行
./usemode --iot-mode
Set iot_dev_mode

设置为iot-dev-mode,如果没执行权限,需添加执行权限
chmod +x usemode
查看串口2配置
stty -F /dev/ttyS2
speed 9600 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>; flush = <undef>; min = 1; time = 0;
-brkint -icrnl -imaxbel
-opost
-isig -icanon -iexten -echo -echoe
stty应用请查看:【linux】OPENWRT串口通信stty安装使用-谷动谷力 (sunsili.com)
接收数据
cat /dev/ttyS2&

PC连接usb串口线,打开串口调试助手

发送数据
echo -e   "hello ttys2 " > /dev/ttyS2




页: [1]
查看完整版本: 【openwrt】MT7628/7688 openwrt下启用串口2 UART2入坑指南