WK2204-spi to uart debugging record

Keywords: Linux Embedded system

Hardware

Chip introduction

  WK2204(DataSheet) Is a spi extended UART chip, which implements spi extended 4 routes of uart. The expanded UART channel of the chip has the following features:

  • The baud rate, word length, and check format of each channel can be set independently, providing a maximum communication rate of 2 Mbps
  • Each channel has an independent 256-level FIFO receiving/sending. FIFO interrupts can be triggered programmatically according to user requirements and have timeout interrupt function
  • Each channel can independently set up advanced working modes such as IrDA infrared communication, RS485 automatic transceiver control, 9-bit network address automatic identification, software/hardware automatic flow control, etc.

circuit design

_Typical circuit design as shown in the figure:

  • The pin interruption requires an external pull-up resistance, typically 5.1K. The driver receives and receives data depending on the interrupt signal. If the interrupt signal is abnormal, the subsequence port cannot communicate properly.
  • Crystal Vibration Circuit, Requires 1M resistor in parallel with Crystal Vibration
  • SPI is connected to the SPI pin of the CPU (Xavier), the sub-serial port outputs TTL level, and the RS signal transceiver is connected
  • The RTS pin (only 2/4 of the sub-serial port) is used to control the transceiver/receiver conversion of the RS-485 transceiver in the RS485 automatic transceiver control working mode.

drive

Add Device Tree

  • As a SPI slave device, WK2204 SPI bus maximum rate cannot exceed 10M
  • INT and RTS are connected to CPU, and these two GPIO resources need to be added to the device tree
  • Frequency of Crystal Vibration in Device Tree

_Add the following device tree:

	spi@3230000{			// cpu is 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>; 
		}; 
	};

Add Driver

  • WK2204Official Driver Based on the Rockchip platform and the core-3.1 foundation, remove the relevant rockchip code:
-#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, 
}
  • The RST pin level of WK2204 sub-serial port 4 can automatically control the sending and receiving of 485 chips. Official driver defaults to the RST pin pull up, instead of the default pull down:
+#define WK_RS485_FUNCTION 
...... 
 
static int wk2xxx_startup(struct uart_port *port)//i 
{ 
	... ...
	 
#ifdef WK_RS485_FUNCTION 
+	// Channel 4 is set to 485 functions 
+	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 
	... ... 
	 
}
  • The baud rate of WK2204 sub-serial port comes from the frequency division of crystal oscillation outside the chip. The official drive adapter is 11.0592 Mhz. Take 16Mhz crystal oscillation as an example, change to:
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; 
	} 
	... ...
	 
}

debugging

View boot loads

_Driver loads successfully and generates four serial devices under / dev: ttysWK0, ttysWK1, ttysWK2, ttysWK3. Enter "dmesg | grep wk" or "ls/dev/ttysWK*" to see if the driver loaded successfully, as shown in the diagram:

_If the driver loading fails, detect if the RST signal is pulled up before the driver loading.

Check Serial Communication

_Windows System Installation Serial Debugging Assistant; The Ubuntu system recommends using the serial communication tool minicom (Reference) Usage method).

Data is out of order or missing

  • Check crystal vibration
  • Check harness
  • Detect INT signal
  • Change debugging tools

RS485 can only be received or not sent

  • Whether the driver enables 485 custom transceiver control functions
  • Oscilloscope Detecting RTS Signal

System Interrupt Response Exception

_If the system keeps responding to interruptions without data communication, as shown in the figure:

_Check the source of the interrupt to interrupt the DEBUG information (_DEBUG_WK_IRQ) if the register display chip does not issue an interrupt:

  • Check the interrupt mode of the driver settings and whether the low level triggers.
  • The oscilloscope detects the INT pin level before and after data communication. If it keeps pulling down, check the pull-up resistance value of the connection.

Reflection

_4 routes of uart data receipt are responded to by gpio interruption, which leads to higher CPU usage.

Posted by gardnc on Sun, 28 Nov 2021 11:15:33 -0800