From 3c87eba7e9eb514c4aa73b0332cc9b8b37581c36 Mon Sep 17 00:00:00 2001 From: slyant Date: Thu, 7 Apr 2022 16:05:58 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8DRT-Thread=E4=B8=B2=E5=8F=A3?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E6=A1=86=E6=9E=B6Serial=5Fv2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 3 + README.md | 21 +- SConscript | 13 +- sample/uart_int_sample.c | 73 +++-- sample/uart_sample.c | 72 ++--- wk2124_usart.c | 5 +- wk2124_usart_v2.c | 591 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 701 insertions(+), 77 deletions(-) create mode 100644 wk2124_usart_v2.c diff --git a/ChangeLog.md b/ChangeLog.md index 97888f4..afda15f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,3 +2,6 @@ 1. Release version 1.0.0 +2022-04-07: + +1. Release version 2.0.0 \ No newline at end of file diff --git a/README.md b/README.md index 6c47935..d18fa81 100644 --- a/README.md +++ b/README.md @@ -11,17 +11,18 @@ WK2124 软件包为串口设备资源不足的产品提供串口扩展的方法 ```shell wk2124-latest/ -├── ChangeLog.md # 修改记录 +├── ChangeLog.md # 修改记录 ├── LICENSE # 软件包许可证 -├── README.md # 软件包使用说明 -├── sample # 串口使用程序样例 +├── README.md # 软件包使用说明 +├── sample # 串口使用程序样例 │   ├── uart_int_sample.c # 中断模式 -│   └── uart_sample.c # 轮询模式 -├── SConscript # RT-Thread 默认的构建脚本 -├── wk2124s.c # wk2124 驱动 -├── wk2124s.h # wk2124 驱动头文件 -├── wk2124_usart.c # wk2124 spi及uart驱动文件 -└── wk2124_usart.h # wk2124 spi及uart驱动头文件 +│   └── uart_sample.c # 轮询模式 +├── SConscript # RT-Thread 默认的构建脚本 +├── wk2124s.c # wk2124 驱动 +├── wk2124s.h # wk2124 驱动头文件 +├── wk2124_usart.c # wk2124 spi及uart驱动文件 +├── wk2124_usart_v2.c # wk2124 spi及uart_v2驱动文件 +└── wk2124_usart.h # wk2124 spi及uart驱动头文件 ``` ### 1.2 许可证 @@ -108,7 +109,7 @@ uartswk1--4串行字符设备支持轮询和中断接收两种模式(不支持 - 获取软件包时,需要注意正确配置使用的 SPI 设备名称、中断引脚号和芯片晶振频率; - 推荐使用最新版,V1.0.0波特率计算存在BUG,且wk2124的串口关闭不彻底。 - +- _v2版本为适配RT-Thread serial_v2版本。 ## 5 联系方式 diff --git a/SConscript b/SConscript index 3a7f6cb..676be7e 100644 --- a/SConscript +++ b/SConscript @@ -2,9 +2,16 @@ from building import * cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') path = [cwd] - -group = DefineGroup('wk2124', src, depend = ['PKG_USING_WK2124'], CPPPATH = path) +src = Split(''' +wk2124s.c +''') +if GetDepend(['RT_USING_SERIAL']): + if GetDepend(['RT_USING_SERIAL_V1']): + src += Glob('wk2124_usart.c') + if GetDepend(['RT_USING_SERIAL_V2']): + src += Glob('wk2124_usart_v2.c') + +group = DefineGroup('wk2124', src, depend = ['RT_USING_SERIAL','PKG_USING_WK2124'], CPPPATH = path) Return('group') diff --git a/sample/uart_int_sample.c b/sample/uart_int_sample.c index e9b0252..c5eeb32 100644 --- a/sample/uart_int_sample.c +++ b/sample/uart_int_sample.c @@ -1,10 +1,12 @@ #include +#include -#define SAMPLE_UART_NAME "uartswk1" /* 串口设备名称 */ +/* 将子串口1和子串口2连接测试 */ +#define WK1_UART_NAME "uartswk1" /* 串口设备名称 */ +#define WK2_UART_NAME "uartswk2" /* 串口设备名称 */ -/* 用于接收消息的信号量 */ +static rt_device_t serial_1, serial_2; static struct rt_semaphore rx_sem; -static rt_device_t serial; /* 接收数据回调函数 */ static rt_err_t uart_input(rt_device_t dev, rt_size_t size) @@ -14,52 +16,67 @@ static rt_err_t uart_input(rt_device_t dev, rt_size_t size) return RT_EOK; } - -static int uart_int_sample(int argc, char *argv[]) +static int uart_int_sample(void) { rt_err_t ret = RT_EOK; - char uart_name[RT_NAME_MAX]; char str[] = "hello RT-Thread!\r\n"; char ch; - if (argc == 2) + /* 查找串口设备 */ + serial_1 = rt_device_find(WK1_UART_NAME); + serial_2 = rt_device_find(WK2_UART_NAME); + if (!serial_1) { - rt_strncpy(uart_name, argv[1], RT_NAME_MAX); + rt_kprintf("find %s failed!\n", WK1_UART_NAME); + return RT_ERROR; } - else + if (!serial_2) { - rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); - } - - /* 查找串口设备 */ - serial = rt_device_find(uart_name); - if (!serial) - { - rt_kprintf("find %s failed!\n", uart_name); + rt_kprintf("find %s failed!\n", WK2_UART_NAME); return RT_ERROR; } /* 初始化信号量 */ rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); - /* 以读写及中断接收方式打开串口设备 */ - rt_device_open(serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + /* 修改串口1配置 */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_4800; + config.rx_bufsz = 1024; + config.tx_bufsz = 0; //必须重新配置为0:阻塞发送,非阻塞接收 + rt_device_control(serial_1, RT_DEVICE_CTRL_CONFIG, &config); + rt_device_control(serial_2, RT_DEVICE_CTRL_CONFIG, &config); /* 设置接收回调函数 */ - rt_device_set_rx_indicate(serial, uart_input); + rt_device_set_rx_indicate(serial_2, uart_input); + /* 打开串口 */ + rt_device_open(serial_1, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_open(serial_2, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); /* 发送字符串 */ - rt_device_write(serial, 0, str, (sizeof(str) - 1)); + rt_device_write(serial_1, 0, str, (sizeof(str) - 1)); - while (1) { + while (1) + { /* 阻塞等待串口接收中断 */ - rt_sem_take(&rx_sem, RT_WAITING_FOREVER); - if (rt_device_read(serial, -1, &ch, 1)) { - rt_kprintf("%s: %c\n", uart_name, ch); - /* 发送已接收的数据 */ - rt_device_write(serial, 0, &ch, 1); + ret = rt_sem_take(&rx_sem, rt_tick_from_millisecond(50)); + if (ret == RT_EOK) + { + while (rt_device_read(serial_2, -1, &ch, 1)) + { + rt_kprintf("%s: %c\n", WK2_UART_NAME, ch); + } + } + else + { + break; } } + /* 关闭串口 */ + rt_device_close(serial_1); + rt_device_close(serial_2); + /* 脱离信号量 */ + rt_sem_detach(&rx_sem); return ret; } /* 导出到 msh 命令列表中 */ -MSH_CMD_EXPORT(uart_int_sample, uart device interrupt sample); \ No newline at end of file +MSH_CMD_EXPORT(uart_int_sample, uart device interrupt sample); diff --git a/sample/uart_sample.c b/sample/uart_sample.c index 64bf874..9cc7a03 100644 --- a/sample/uart_sample.c +++ b/sample/uart_sample.c @@ -1,57 +1,59 @@ #include +#include -#define SAMPLE_UART_NAME "uartswk2" /* 串口设备名称 */ +/* 将子串口1和子串口2连接测试 */ +#define WK1_UART_NAME "uartswk1" /* 串口设备名称 */ +#define WK2_UART_NAME "uartswk2" /* 串口设备名称 */ -/* 用于接收消息的信号量 */ -static struct rt_semaphore rx_sem; -static rt_device_t serial; +static rt_device_t serial_1, serial_2; -/* 接收数据回调函数 */ -static rt_err_t uart_input(rt_device_t dev, rt_size_t size) -{ - /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ - rt_sem_release(&rx_sem); - return RT_EOK; -} - - -static int uart_sample(int argc, char *argv[]) +static int uart_sample(void) { rt_err_t ret = RT_EOK; - char uart_name[RT_NAME_MAX]; char str[] = "hello RT-Thread!\r\n"; char ch; - if (argc == 2) - { - rt_strncpy(uart_name, argv[1], RT_NAME_MAX); - } - else + /* 查找串口设备 */ + serial_1 = rt_device_find(WK1_UART_NAME); + serial_2 = rt_device_find(WK2_UART_NAME); + if (!serial_1) { - rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); + rt_kprintf("find %s failed!\n", WK1_UART_NAME); + return RT_ERROR; } - - /* 查找串口设备 */ - serial = rt_device_find(uart_name); - if (!serial) + if (!serial_2) { - rt_kprintf("find %s failed!\n", uart_name); + rt_kprintf("find %s failed!\n", WK2_UART_NAME); return RT_ERROR; } - - /* 以读写及中断接收方式打开串口设备 */ - rt_device_open(serial, RT_DEVICE_OFLAG_RDWR); + /* 修改串口配置 */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_4800; + config.rx_bufsz = 1024; + config.tx_bufsz = 0; //必须重新配置为0:阻塞发送,非阻塞接收 + rt_device_control(serial_1, RT_DEVICE_CTRL_CONFIG, &config); + rt_device_control(serial_2, RT_DEVICE_CTRL_CONFIG, &config); + /* 打开串口 */ + rt_device_open(serial_1, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_open(serial_2, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); /* 发送字符串 */ - rt_device_write(serial, 0, str, (sizeof(str) - 1)); + rt_device_write(serial_1, 0, str, (sizeof(str) - 1)); - while (1) { + while (1) + { rt_thread_mdelay(100); - if (rt_device_read(serial, -1, &ch, 1)) { - rt_kprintf("%s: %c\n", uart_name, ch); - /* 发送已接收的数据 */ - rt_device_write(serial, 0, &ch, 1); + if (rt_device_read(serial_2, -1, &ch, 1)) + { + rt_kprintf("%s: %c\n", WK2_UART_NAME, ch); + } + else + { + break; } } + /* 关闭串口 */ + rt_device_close(serial_1); + rt_device_close(serial_2); return ret; } diff --git a/wk2124_usart.c b/wk2124_usart.c index 81f3db4..a123a24 100644 --- a/wk2124_usart.c +++ b/wk2124_usart.c @@ -9,7 +9,8 @@ #include // #define DRV_DEBUG - +#ifdef RT_USING_SERIAL +#ifdef RT_USING_SERIAL_V1 #ifdef PKG_USING_WK2124 //WK2124晶振频率,单位Hz @@ -506,3 +507,5 @@ int wk2124_device_init(void) INIT_ENV_EXPORT(wk2124_device_init); #endif /* PKG_USING_WK2124 */ +#endif /* RT_USING_SERIAL_V2 */ +#endif /* RT_USING_SERIAL */ diff --git a/wk2124_usart_v2.c b/wk2124_usart_v2.c new file mode 100644 index 0000000..92478cb --- /dev/null +++ b/wk2124_usart_v2.c @@ -0,0 +1,591 @@ +#include "board.h" +#include +#include +#include + +#include "wk2124_usart.h" +#include "wk2124s.h" + +#include +// #define DRV_DEBUG + +#ifdef RT_USING_SERIAL +#ifdef RT_USING_SERIAL_V2 +#ifdef PKG_USING_WK2124 + +#ifndef BSP_UARTSWK1_RX_BUFSIZE +#define BSP_UARTSWK1_RX_BUFSIZE RT_SERIAL_RX_MINBUFSZ +#endif +#ifndef BSP_UARTSWK1_TX_BUFSIZE +#define BSP_UARTSWK1_TX_BUFSIZE 0 +#endif + +#ifndef BSP_UARTSWK2_RX_BUFSIZE +#define BSP_UARTSWK2_RX_BUFSIZE RT_SERIAL_RX_MINBUFSZ +#endif +#ifndef BSP_UARTSWK2_TX_BUFSIZE +#define BSP_UARTSWK2_TX_BUFSIZE 0 +#endif + +#ifndef BSP_UARTSWK3_RX_BUFSIZE +#define BSP_UARTSWK3_RX_BUFSIZE RT_SERIAL_RX_MINBUFSZ +#endif +#ifndef BSP_UARTSWK3_TX_BUFSIZE +#define BSP_UARTSWK3_TX_BUFSIZE 0 +#endif + +#ifndef BSP_UARTSWK4_RX_BUFSIZE +#define BSP_UARTSWK4_RX_BUFSIZE RT_SERIAL_RX_MINBUFSZ +#endif +#ifndef BSP_UARTSWK4_TX_BUFSIZE +#define BSP_UARTSWK4_TX_BUFSIZE 0 +#endif + +//WK2124晶振频率,单位Hz +#ifndef WK2124_Fosc + #define WK2124_Fosc 11059200 +#endif + +#ifndef WK2124_IRQ_PIN + #define WK2124_IRQ_PIN 17 /* PB1 */ +#endif + +static struct rt_spi_device *wk2124_device = RT_NULL; + +/* wk2124 uart driver */ +struct wk2124_uart +{ + uint8_t swk_index; + uint8_t irq_enable; + struct rt_spi_device *spi_device; +}; + +/* 用于接收中断的信号量 */ +static struct rt_semaphore irq_sem; + +static rt_err_t wk2124_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + struct wk2124_uart *uart; + uint16_t baudrate; + uint8_t baudrate_h, baudrate_l, baudrate_dec, spage0_lcr; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + uart = (struct wk2124_uart *)serial->parent.user_data; + + /*切换到PAGE0页中的子串口寄存器组 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE(uart->swk_index),0x00); + + /*子串口 1 控制寄存器 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SCR(uart->swk_index),0x00); //子串口 发送使能 接收使能 + + spage0_lcr = 0; + if (cfg->stop_bits > 0) { + spage0_lcr |= 0x01; + } + if (cfg->parity == 1) { + spage0_lcr &= 0xfb; + spage0_lcr |= 0x02; + } else if (cfg->parity == 2) { + spage0_lcr &= 0xfd; + spage0_lcr |= 0x04; + } + if (cfg->data_bits == 9) { + spage0_lcr |= 0x08; + } + /*子串口 配置寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_LCR(uart->swk_index),spage0_lcr); //子串口 正常输出,普通模式,8位数据位,0校验,1位停止位 + + /*子串口 FIFO控制寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_FCR(uart->swk_index),0x03); //子串口 发送触发点,接收触发点 + //使能 发送,接收FIFO 复位发送接收FIFO + /*子串口 中断使能寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SIER(uart->swk_index),0x00); //子串口 禁止接收FIFO数据错误中断 + //禁止发送FIFO空中断 + //禁止发送FIFO触点中断 + //禁止接收FIFO接收超时中断 + //禁止接收FIFO接收触点中断 + + baudrate = WK2124_Fosc/cfg->baud_rate/16; + baudrate_h = baudrate/0x100; + baudrate_l = baudrate%0x100 -1; + baudrate_dec = (uint8_t)(((WK2124_Fosc/cfg->baud_rate/16.0f) - baudrate)*16); + + /*切换到PAGE1页中的子串口寄存器组 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE(uart->swk_index),0x01); + + /*子串口1 波特率配置寄存器高字节 [Reg = 11.0592/(115200*16) = 6] */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE1_BAUD1(uart->swk_index),baudrate_h); + /*子串口1 波特率配置寄存器低字节 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE1_BAUD0(uart->swk_index),baudrate_l); + /*子串口1 波特率配置寄存器小数部分*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE1_PRES(uart->swk_index),baudrate_dec); + + /*切换到PAGE0页中的子串口寄存器组 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE(uart->swk_index),0x00); + + return RT_EOK; +} + +static rt_err_t wk2124_control(struct rt_serial_device *serial, + int cmd, void *arg) +{ + struct wk2124_uart *uart; + RT_ASSERT(serial != RT_NULL); + uart = (struct wk2124_uart *)serial->parent.user_data; + rt_ubase_t ctrl_arg = (rt_ubase_t)arg; + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + // /* disable rx irq */ + /*切换到PAGE0页中的子串口寄存器组 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE(uart->swk_index),0x00); + /*子串口 控制寄存器 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SCR(uart->swk_index),0x00); //子串口 发送不使能 接收不使能 + /*子串口 FIFO控制寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_FCR(uart->swk_index),0x03); //子串口 发送触发点,接收触发点 + //不使能 发送,接收FIFO 复位发送接收FIFO + /*子串口 中断使能寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SIER(uart->swk_index),0x00); //子串口 禁止接收FIFO数据错误中断 + //禁止发送FIFO空中断 + //禁止发送FIFO触点中断 + //禁止接收FIFO接收超时中断 + //禁止接收FIFO接收触点中断 + uart->irq_enable = 0; + break; + case RT_DEVICE_CTRL_SET_INT: + break; + case RT_DEVICE_CTRL_CONFIG: + if (ctrl_arg & (RT_SERIAL_RX_NON_BLOCKING|RT_SERIAL_RX_BLOCKING)) + { + // /* enable rx irq */ + /*切换到PAGE0页中的子串口寄存器组 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE(uart->swk_index),0x00); + /*子串口 控制寄存器 */ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SCR(uart->swk_index),0x03); //子串口 发送使能 接收使能 + /*子串口 FIFO控制寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_FCR(uart->swk_index),0x0F); //子串口 发送触发点,接收触发点 + //使能 发送,接收FIFO 复位发送接收FIFO + /*子串口 中断使能寄存器*/ + EXHW_WK2124_Write_Reg(uart->spi_device, SPAGE0_SIER(uart->swk_index),0x83); //子串口 使能接收FIFO数据错误中断 + //禁止发送FIFO空中断 + //禁止发送FIFO触点中断 + //使能接收FIFO接收超时中断 + //使能接收FIFO接收触点中断 + } + uart->irq_enable = 1; + break; + case RT_DEVICE_CHECK_OPTMODE: + return RT_SERIAL_TX_BLOCKING_NO_BUFFER; + case RT_DEVICE_CTRL_CLOSE: + break; + default: + return RT_ERROR; + } + return RT_EOK; +} + +static int wk2124_putc(struct rt_serial_device *serial, char c) +{ + uint8_t sendbuf[10]; + struct wk2124_uart *uart; + RT_ASSERT(serial != RT_NULL); + uart = (struct wk2124_uart *)serial->parent.user_data; + + sendbuf[0] = c; + Wk2124_SendBuf(uart->spi_device, uart->swk_index, sendbuf, 1); + while(EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_TFCNT(uart->swk_index)) > 0); + while((EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_FSR(uart->swk_index)) & 0x01) == 1); + + return 1; +} + +static int wk2124_getc(struct rt_serial_device *serial) +{ + int ch; + uint8_t recbuf[10]; + + struct wk2124_uart *uart; + RT_ASSERT(serial != RT_NULL); + uart = (struct wk2124_uart *)serial->parent.user_data; + + ch = -1; //确保没有接收数据时rt_device_read返回值为0 + if(Wk2124_GetBuf(uart->spi_device, uart->swk_index, recbuf, 1)) { + ch = recbuf[0]; + } + return ch; +} + +static const struct rt_uart_ops wk2124_uart_ops = +{ + wk2124_configure, + wk2124_control, + wk2124_putc, + wk2124_getc, +}; + +#if defined(PKG_USING_UART_SWK1) +/* UART1 device driver structure */ +static struct wk2124_uart uart_swk1; +struct rt_serial_device serialswk1; +void WK2124_UART1_IRQHandler(void) +{ + struct wk2124_uart *uart; + uart = &uart_swk1; + volatile uint8_t uart_irq_stat = 0; + RT_ASSERT(uart != RT_NULL); + RT_ASSERT(&serialswk1 != RT_NULL); + RT_ASSERT(uart->spi_device->parent.type == RT_Device_Class_SPIDevice); + + if (uart->irq_enable == 0) { + return; + } + /*判断串口的中断类型*/ + uart_irq_stat = EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_SIFR(uart->swk_index)); + //子串口接收FIFO触点中断标志 , 子串口接收FIFO超时中断标志 + if(uart_irq_stat & (3 << 0)) { + int ch = -1; + struct rt_serial_rx_fifo *rx_fifo; + rx_fifo = (struct rt_serial_rx_fifo *) serialswk1.serial_rx; + while(1){ + ch = (serialswk1.ops->getc)(&serialswk1); + if (ch == -1) break; + rt_uint8_t temp = (rt_uint8_t)ch; + rt_ringbuffer_put(&(rx_fifo->rb), &temp, 1); + } + rt_hw_serial_isr(&serialswk1, RT_SERIAL_EVENT_RX_IND); + } +} +#endif /* PKG_USING_UART_SWK1 */ + +#if defined(PKG_USING_UART_SWK2) +/* UART2 device driver structure */ +static struct wk2124_uart uart_swk2; +struct rt_serial_device serialswk2; +void WK2124_UART2_IRQHandler(void) +{ + struct wk2124_uart *uart; + uart = &uart_swk2; + volatile uint8_t uart_irq_stat = 0; + + RT_ASSERT(uart != RT_NULL); + RT_ASSERT(&serialswk2 != RT_NULL); + RT_ASSERT(uart->spi_device->parent.type == RT_Device_Class_SPIDevice); + + if (uart->irq_enable == 0) { + return; + } + /*判断串口的中断类型*/ + uart_irq_stat = EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_SIFR(uart->swk_index)); + //子串口接收FIFO触点中断标志 , 子串口接收FIFO超时中断标志 + if(uart_irq_stat & (3 << 0)) { + int ch = -1; + struct rt_serial_rx_fifo *rx_fifo; + rx_fifo = (struct rt_serial_rx_fifo *) serialswk2.serial_rx; + while(1){ + ch = (serialswk2.ops->getc)(&serialswk2); + if (ch == -1) break; + rt_uint8_t temp = (rt_uint8_t)ch; + rt_ringbuffer_put(&(rx_fifo->rb), &temp, 1); + } + rt_hw_serial_isr(&serialswk2, RT_SERIAL_EVENT_RX_IND); + } +} +#endif /* PKG_USING_UART_SWK2 */ + +#if defined(PKG_USING_UART_SWK3) +/* UART3 device driver structure */ +static struct wk2124_uart uart_swk3; +struct rt_serial_device serialswk3; +void WK2124_UART3_IRQHandler(void) +{ + struct wk2124_uart *uart; + uart = &uart_swk3; + volatile uint8_t uart_irq_stat = 0; + + RT_ASSERT(uart != RT_NULL); + RT_ASSERT(&serialswk3 != RT_NULL); + RT_ASSERT(uart->spi_device->parent.type == RT_Device_Class_SPIDevice); + + if (uart->irq_enable == 0) { + return; + } + /*判断串口的中断类型*/ + uart_irq_stat = EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_SIFR(uart->swk_index)); + //子串口接收FIFO触点中断标志 , 子串口接收FIFO超时中断标志 + if(uart_irq_stat & (3 << 0)) { + int ch = -1; + struct rt_serial_rx_fifo *rx_fifo; + rx_fifo = (struct rt_serial_rx_fifo *) serialswk3.serial_rx; + while(1){ + ch = (serialswk3.ops->getc)(&serialswk3); + if (ch == -1) break; + rt_uint8_t temp = (rt_uint8_t)ch; + rt_ringbuffer_put(&(rx_fifo->rb), &temp, 1); + } + rt_hw_serial_isr(&serialswk3, RT_SERIAL_EVENT_RX_IND); + } +} +#endif /* PKG_USING_UART_SWK3 */ + +#if defined(PKG_USING_UART_SWK4) +/* UART4 device driver structure */ +static struct wk2124_uart uart_swk4; +struct rt_serial_device serialswk4; +void WK2124_UART4_IRQHandler(void) +{ + struct wk2124_uart *uart; + uart = &uart_swk4; + volatile uint8_t uart_irq_stat = 0; + + RT_ASSERT(uart != RT_NULL); + RT_ASSERT(&serialswk4 != RT_NULL); + RT_ASSERT(uart->spi_device->parent.type == RT_Device_Class_SPIDevice); + + if (uart->irq_enable == 0) { + return; + } + /*判断串口的中断类型*/ + uart_irq_stat = EXHW_WK2124_Read_Reg(uart->spi_device, SPAGE0_SIFR(uart->swk_index)); + //子串口接收FIFO触点中断标志 , 子串口接收FIFO超时中断标志 + if(uart_irq_stat & (3 << 0)) { + int ch = -1; + struct rt_serial_rx_fifo *rx_fifo; + rx_fifo = (struct rt_serial_rx_fifo *) serialswk4.serial_rx; + while(1){ + ch = (serialswk4.ops->getc)(&serialswk4); + if (ch == -1) break; + rt_uint8_t temp = (rt_uint8_t)ch; + rt_ringbuffer_put(&(rx_fifo->rb), &temp, 1); + } + rt_hw_serial_isr(&serialswk4, RT_SERIAL_EVENT_RX_IND); + } +} +#endif /* PKG_USING_UART_SWK4 */ + +/* 中断回调函数 */ +void WK2124_IRQHandler(void *args) +{ + rt_sem_release(&irq_sem); +} + +static void wk2124_irq_thread_entry(void *parameter) +{ + volatile uint8_t g_irq_stat = 0; + + while (1) + { + rt_sem_take(&irq_sem, RT_WAITING_FOREVER); + + /*使能子串口1,2,3,4的时钟*/ + g_irq_stat = EXHW_WK2124_Read_Reg(wk2124_device, GIFR); + if(g_irq_stat & (1 << 0)){//子串口 1 有中断 + #if defined(PKG_USING_UART_SWK1) + WK2124_UART1_IRQHandler(); + #endif + } + if(g_irq_stat & (1 << 1)){//子串口 2 有中断 + #if defined(PKG_USING_UART_SWK2) + WK2124_UART2_IRQHandler(); + #endif + } + if(g_irq_stat & (1 << 2)){//子串口 3 有中断 + #if defined(PKG_USING_UART_SWK3) + WK2124_UART3_IRQHandler(); + #endif + } + if(g_irq_stat & (1 << 3)){//子串口 4 有中断 + #if defined(PKG_USING_UART_SWK4) + WK2124_UART4_IRQHandler(); + #endif + } + } +} + +int WK2124_IRQ_Init(void) +{ + rt_err_t ret = 0; + + /* 设置引脚为输入模式 */ + rt_pin_mode(WK2124_IRQ_PIN, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为WK2124_IRQHandler */ + rt_pin_attach_irq(WK2124_IRQ_PIN, PIN_IRQ_MODE_FALLING, WK2124_IRQHandler, RT_NULL); + + /* 初始化信号量 */ + rt_sem_init(&irq_sem, "irq_sem", 0, RT_IPC_FLAG_FIFO); + rt_thread_t thread = rt_thread_create("wk2124_irq", wk2124_irq_thread_entry, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX / 6, 20); + if (thread != RT_NULL) { + rt_thread_startup(thread); + } else { + return -RT_ERROR; + } + + /* 使能中断 */ + ret = rt_pin_irq_enable(WK2124_IRQ_PIN, PIN_IRQ_ENABLE); + return ret; +} + + +int hw_wk2124_usart_init(struct rt_spi_device *device) +{ + struct wk2124_uart *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + rt_err_t ret = 0; + +#ifdef PKG_USING_UART_SWK1 + uart = &uart_swk1; + uart->swk_index = 0; + uart->irq_enable = 0; + uart->spi_device = device; + serialswk1.ops = &wk2124_uart_ops; + serialswk1.config = config; + serialswk1.config.rx_bufsz = BSP_UARTSWK1_RX_BUFSIZE; + serialswk1.config.tx_bufsz = BSP_UARTSWK1_TX_BUFSIZE; + /* register UART1 device */ + ret = rt_hw_serial_register(&serialswk1, "uartswk1", + RT_DEVICE_FLAG_RDWR, + uart); + if (ret) { + LOG_E("rt_hw_serial_register %s error", "uartswk1"); + } + RT_ASSERT(ret == RT_EOK); +#endif /* PKG_USING_UART_SWK1 */ + +#ifdef PKG_USING_UART_SWK2 + uart = &uart_swk2; + uart->swk_index = 1; + uart->irq_enable = 0; + uart->spi_device = device; + serialswk2.ops = &wk2124_uart_ops; + serialswk2.config = config; + serialswk2.config.rx_bufsz = BSP_UARTSWK2_RX_BUFSIZE; + serialswk2.config.tx_bufsz = BSP_UARTSWK2_TX_BUFSIZE; + /* register UART2 device */ + ret = rt_hw_serial_register(&serialswk2, "uartswk2", + RT_DEVICE_FLAG_RDWR, + uart); + if (ret) { + LOG_E("rt_hw_serial_register %s error", "uartswk2"); + } + RT_ASSERT(ret == RT_EOK); +#endif /* PKG_USING_UART_SWK2 */ + +#ifdef PKG_USING_UART_SWK3 + uart = &uart_swk3; + uart->swk_index = 2; + uart->irq_enable = 0; + uart->spi_device = device; + serialswk3.ops = &wk2124_uart_ops; + serialswk3.config = config; + serialswk3.config.rx_bufsz = BSP_UARTSWK3_RX_BUFSIZE; + serialswk3.config.tx_bufsz = BSP_UARTSWK3_TX_BUFSIZE; + /* register UART3 device */ + ret = rt_hw_serial_register(&serialswk3, "uartswk3", + RT_DEVICE_FLAG_RDWR, + uart); + if (ret) { + LOG_E("rt_hw_serial_register %s error", "uartswk3"); + } + RT_ASSERT(ret == RT_EOK); +#endif /* PKG_USING_UART_SWK3 */ + +#ifdef PKG_USING_UART_SWK4 + uart = &uart_swk4; + uart->swk_index = 3; + uart->irq_enable = 0; + uart->spi_device = device; + serialswk4.ops = &wk2124_uart_ops; + serialswk4.config = config; + serialswk4.config.rx_bufsz = BSP_UARTSWK4_RX_BUFSIZE; + serialswk4.config.tx_bufsz = BSP_UARTSWK4_TX_BUFSIZE; + /* register UART6 device */ + ret = rt_hw_serial_register(&serialswk4, "uartswk4", + RT_DEVICE_FLAG_RDWR, + uart); + if (ret) { + LOG_E("rt_hw_serial_register %s error", "uartswk4"); + } + RT_ASSERT(ret == RT_EOK); +#endif /* PKG_USING_UART_SWK4 */ + + return ret; +} + + +int wk2124_spi_init(const char *spi_dev_name) +{ + RT_ASSERT(spi_dev_name); + + if (wk2124_device != RT_NULL) + { + return 0; + } + + wk2124_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); + if (wk2124_device == RT_NULL) + { + LOG_E("You should attach [%s] into SPI bus firstly.", spi_dev_name); + return -RT_ENOSYS; + } + + /* check SPI device type */ + RT_ASSERT(wk2124_device->parent.type == RT_Device_Class_SPIDevice); + + /* configure SPI device*/ + { + struct rt_spi_configuration cfg; + cfg.data_width = 8; + cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ + cfg.max_hz = 40 * 1000 * 1000; /* SPI Interface with Clock Speeds Up to 40 MHz */ + if (rt_spi_configure(wk2124_device, &cfg)) { + LOG_E("rt_spi_configure SPI device %s error.", spi_dev_name); + return -RT_ERROR; + } + } + + if (rt_device_open((rt_device_t) wk2124_device, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + LOG_E("open WK2124 SPI device %s error.", spi_dev_name); + return -RT_ERROR; + } + + return RT_EOK; +} + + + +int wk2124_device_init(void) +{ + rt_err_t ret = 0; + +#ifdef WK2124_SPI_DEVICE + rt_thread_mdelay(100); + + ret = wk2124_spi_init(WK2124_SPI_DEVICE); + if (ret == RT_EOK) { + rt_thread_mdelay(100); + WK2124_IRQ_Init(); + EXHW_WK2124_Init(wk2124_device); + rt_thread_mdelay(100); + ret = hw_wk2124_usart_init(wk2124_device); + if (ret != RT_EOK) { + LOG_E("RT-Thread WK2124 package initialize fail."); + return -RT_ERROR; + } + } else { + LOG_E("RT-Thread WK2124 package initialize fail."); + return -RT_ERROR; + } +#else + return -RT_ERROR; +#endif + LOG_I("RT-Thread WK2124 package initialize success."); + return RT_EOK; +} + +INIT_DEVICE_EXPORT(wk2124_device_init); + +#endif /* PKG_USING_WK2124 */ +#endif /* RT_USING_SERIAL_V2 */ +#endif /* RT_USING_SERIAL */