WK2204 - spi转uart调试记录

WK2204 - spi转uart调试记录

  • 硬件
    • 芯片简介
    • 电路设计
  • 驱动
    • 添加设备树
    • 添加驱动
  • 调试
    • 查看启动加载
    • 检查串口通信
    • 数据乱码或丢失
    • RS485只能收不能发
    • 系统中断响应异常
  • 思考

硬件

芯片简介

  WK2204(DataSheet)是spi扩展uart的芯片,实现spi扩展4路uart,该芯片扩展的uart通道的具备以下功能特点:

  • 每个通道的波特率、字长、校验格式可以独立设置,最高可以提供2Mbps 的通信速率
  • 每个通道具有收/发独立的256 级FIFO,FIFO 中断可按用户需求进行编程触发方式且具备超时中断功能
  • 每个通道可以独立设置IrDA红外通信、RS485自动收发控制、9位网络地址自动识别、软/硬件自动流量控制等高级工作模式

电路设计

  典型电路设计如图所示:
WK2204 - spi转uart调试记录_第1张图片

  • 中断引脚需要外接上拉电阻,典型取值5.1K。驱动收发数据依赖于该中断信号,如果中断信号异常,子串口无法进行正常通信
  • 晶振电路,需要和晶振并联1M的电阻
  • SPI与CPU(Xavier)的SPI引脚连接,子串口输出TTL电平,与RS信号收发器连接
  • RTS引脚(只有子串口2/4具备)在RS485自动收发控制工作模式下,用于控制RS-485收发器的收发转换。

驱动

添加设备树

  • WK2204作为SPI从设备,SPI总线最高速率不 能超过10M
  • INT和RTS与CPU连接,设备树中需要添加这两个GPIO资源
  • 设备树中需添加晶振的频率

  添加设备树如下:

	spi@3230000{			// cpu是nvidia-jetson
		status = "okay"; 
 
		spi_test@00 { 
			compatible = "wkmic, wk2124spi"; 
			reg = <0>; 
 
			spi-max-frequency = <10000000>; 
 
			irq_gpio = <&tegra_main_gpio TEGRA194_MAIN_GPIO(T, 0) IRQ_TYPE_LEVEL_LOW>; 
			reset_gpio = <&tegra_main_gpio TEGRA194_MAIN_GPIO(M, 3) GPIO_ACTIVE_HIGH>; 
		}; 
	};

添加驱动

  • WK2204官方驱动是基于Rockchip平台和kernel-3.1基础开发的,删除rockchip的相关代码:
-#include <linux/platform_data/spi-rockchip.h> 
... ... 
 
//#ifdef CONFIG_OF 
-static int rockchip_spi_parse_dt(struct device *dev) 
+static int spi_parse_dt(struct device *dev) 
... ... 
 
static int wk2xxx_probe(struct spi_device *spi) 
{ 
	... ... 
	 
+	irq = spi_parse_dt(&spi->dev); 
+	if(irq < 0) 
+		return 1; 
	 
	do 
	{ 
		wk2xxx_read_global_reg(spi,WK2XXX_GENA,dat); 
		printk(KERN_ERR "wk2xxx_probe()  GENA = 0x%X\n",dat[0]); //GENA=0X30 
		wk2xxx_write_global_reg(spi,WK2XXX_GENA,0xf5); 
		wk2xxx_read_global_reg(spi,WK2XXX_GENA,dat); 
		printk(KERN_ERR "wk2xxx_probe()  GENA = 0x%X\n",dat[0]); //GENA=0X35 
		wk2xxx_write_global_reg(spi,WK2XXX_GENA,0xf0); 
		wk2xxx_read_global_reg(spi,WK2XXX_GENA,dat); 
		printk(KERN_ERR "wk2xxx_probe()  GENA = 0x%X\n",dat[0]); //GENA=0X30 
	}while(0); 
/test spi //	 
 
-	irq = rockchip_spi_parse_dt(&spi->dev); 
-	if(irq < 0) 
-		return 1; 
	... ... 
} 
... ...
 
-static int wk2xxx_resume(struct spi_device *spi) 
-{ 
-	#ifdef _DEBUG_WK_FUNCTION 
-	printk(KERN_ALERT "%s!!--in--\n", __func__); 
-	#endif 
-   return 0; 
-} 
... ... 
 
static struct spi_driver wk2xxx_driver = { 
	.driver = { 
		.name           = "wk2xxxspi", 
		.bus            = &spi_bus_type, 
		.owner          = THIS_MODULE, 
		.of_match_table = of_match_ptr(rockchip_spi_wk2xxx_dt_match), 
	}, 
	 
	.probe          = wk2xxx_probe, 
	.remove         = wk2xxx_remove, 
-	.resume         = wk2xxx_resume, 
}
  • WK2204子串口4的RST引脚电平可以自动控制485芯片的收发。官方驱动默认该RST引脚拉高,改为默认拉低:
+#define WK_RS485_FUNCTION 
…… 
 
static int wk2xxx_startup(struct uart_port *port)//i 
{ 
	... ...
	 
#ifdef WK_RS485_FUNCTION 
+	// 通道4设置为485功能 
+	if (s->port.iobase == 4) { 
-		wk2xxx_write_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_RS485,0X02);	//default high 
+		wk2xxx_write_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_RS485,0X03);	//default low 
		wk2xxx_write_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_SPAGE,1); 
		wk2xxx_write_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_RRSDLY,0X10); 
		wk2xxx_write_slave_reg(s->spi_wk,s->port.iobase,WK2XXX_SPAGE,0); 
	} 
#endif 
	... ... 
	 
}
  • WK2204子串口的波特率由芯片外部晶振分频而来,官方驱动适配11.0592Mhz,以16Mhz晶振为例,改为:
static void wk2xxx_termios( struct uart_port *port, struct ktermios *termios, 
            struct ktermios *old) 
{ 
	... ...
	 
	switch (baud) 
	{ 
		case 600: 
-			baud1=0x4; 
-			baud0=0x7f; 
-			pres=0; 
+			baud1=0x6; 
+			baud0=0x81; 
+			pres=0xb; 
			break; 
		case 1200: 
-			baud1=0x2; 
-			baud0=0x3F; 
-			pres=0; 
+			baud1=0x3; 
+			baud0=0x40; 
+			pres=0x5; 
			break; 
		case 2400: 
			baud1=0x1; 
-			baud0=0x1f; 
-			pres=0; 
+			baud0=0x9f; 
+			pres=0xb; 
			break; 
		case 4800: 
			baud1=0x00; 
-			baud0=0x8f; 
-			pres=0; 
+			baud0=0xcf; 
+			pres=0x5; 
			break; 
		case 9600: 
			baud1=0x00; 
-			baud0=0x47; 
-			pres=0; 
+			baud0=0x67; 
+			pres=0x3; 
			break; 
		case 19200: 
			baud1=0x00; 
-			baud0=0x23; 
-			pres=0; 
+			baud0=0x33; 
+			pres=0x1; 
			break; 
		case 38400: 
			baud1=0x00; 
-			baud0=0x11; 
-			pres=0; 
+			baud0=0x19; 
+			pres=0x1; 
			break; 
		case 76800: 
			baud1=0x00; 
-			baud0=0x08; 
-			pres=0; 
+			baud0=0x0c; 
+			pres=0; 
			break; 
		case 1800: 
-			baud1=0x01; 
-			baud0=0x7f; 
-			pres=0; 
+			baud1=0x2; 
+			baud0=0x2a; 
+			pres=0x9; 
			break; 
		case 3600: 
-			baud1=0x00; 
-			baud0=0xbf; 
-			pres=0; 
+			baud1=0x1; 
+			baud0=0x14; 
+			pres=0xc; 
			break; 
		case 7200: 
			baud1=0x00; 
-			baud0=0x5f; 
-			pres=0; 
+			baud0=0x89; 
+			pres=0xe; 
			break; 
		case 14400: 
			baud1=0x00; 
-			baud0=0x2f; 
-			pres=0; 
+			baud0=0x44; 
+			pres=0x7; 
			break; 
		case 28800: 
			baud1=0x00; 
-			baud0=0x17; 
-			pres=0; 
+			baud0=0x21; 
+			pres=0xc; 
			break; 
		case 57600: 
			baud1=0x00; 
-			baud0=0x0b; 
-			pres=0; 
+			baud0=0x10; 
+			pres=0x6; 
			break; 
		case 115200: 
			baud1=0x00; 
-			baud0=0x05; 
-			pres=0; 
+			baud0=0x07; 
+			pres=0xb; 
			break; 
		case 230400: 
			baud1=0x00; 
-			baud0=0x02; 
-			pres=0; 
+			baud0=0x03; 
+			pres=0x6; 
			break; 
		default: 
			baud1=0x00; 
			baud0=0x00; 
			pres=0; 
			break; 
	} 
	... ...
	 
}

调试

查看启动加载

  驱动加载成功,会在/dev下生成4个串口设备:ttysWK0、ttysWK1、ttysWK2、ttysWK3。输入“dmesg | grep wk”或“ls /dev/ttysWK*”,查看驱动是否加载成功,如图所示:
WK2204 - spi转uart调试记录_第2张图片
  如果驱动加载失败,侦测RST信号是否在驱动加载前拉高。

检查串口通信

  Windows系统安装串口调试助手;Ubuntu系统建议使用串口通信工具minicom(参考使用方法)。

数据乱码或丢失

  • 检查晶振
  • 检查线束
  • 侦测INT信号
  • 更换调试工具

RS485只能收不能发

  • 驱动是否使能485自定收发控制功能
  • 示波器侦测RTS信号

系统中断响应异常

  如果系统在无数据通信的情况下一直响应中断,如图所示:
WK2204 - spi转uart调试记录_第3张图片
  检查中断来源,使能中断DEBUG信息(_DEBUG_WK_IRQ),如果寄存器显示芯片未发出中断:

  • 检查驱动设置的中断模式,是否低电平触发。
  • 示波器侦测数据通信前后的INT引脚电平,如果一直拉低,检查连接的上拉电阻阻值。

思考

  4路uart数据接收均通过gpio中断响应,CPU使用率较高。

你可能感兴趣的:(工作日志,linux,嵌入式)