diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-arm32/board/hardware/ch438/ch438.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-arm32/board/hardware/ch438/ch438.c new file mode 100644 index 000000000..4b5b21688 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-arm32/board/hardware/ch438/ch438.c @@ -0,0 +1,1323 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file .c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.06.30 + */ + +#include "ch438.h" +#include + +#ifdef BSP_USING_CH438 + +#define RT (0U) // If config this macro ,we can use rt gpio for ch438 us + +/* This array shows whether the current serial port is selected */ +static bool const g_uart_selected[CH438PORTNUM] = +{ +#ifdef CONFIG_CH438_EXTUART0 + [0] = true, +#endif +#ifdef CONFIG_CH438_EXTUART1 + [1] = true, +#endif +#ifdef CONFIG_CH438_EXTUART2 + [2] = true, +#endif +#ifdef CONFIG_CH438_EXTUART3 + [3] = true, +#endif +#ifdef CONFIG_CH438_EXTUART4 + [4] = true, +#endif +#ifdef CONFIG_CH438_EXTUART5 + [5] = true, +#endif +#ifdef CONFIG_CH438_EXTUART6 + [6] = true, +#endif +#ifdef CONFIG_CH438_EXTUART7 + [7] = true, +#endif +}; + + +/* rt-thread sem and serial definition */ +struct rt_serial_device *extuart_serial_parm[CH438PORTNUM]; +static rt_sem_t rx_sem[CH438PORTNUM]={RT_NULL}; +char * sem[CH438PORTNUM]={"sem0","sem1","sem2","sem3","sem4","sem5","sem6","sem7"}; +/* rt-thread workqueue*/ +struct rt_workqueue* rq; +/* there is data available on the corresponding port */ +static volatile bool done[CH438PORTNUM] = {false,false,false,false,false,false,false,false}; + +/* Eight port data buffer */ +static uint8_t buff[CH438PORTNUM][CH438_BUFFSIZE]; + +/* the value of interrupt number of SSR register */ +static uint8_t Interruptnum[CH438PORTNUM] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; + +/* Offset address of serial port number */ +static uint8_t offsetadd[CH438PORTNUM] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; + + +const struct rt_uart_ops ch438_ops={ + rt_ch438_configure, + rt_ch438_control, + rt_ch438_putc, + rt_ch438_getc, + RT_NULL +}; + + +void Config_Interrupt(void){ + gpio_pin_config_t int_config = { + kGPIO_DigitalInput, + 0, + kGPIO_IntFallingEdge, + }; + GPIO_PinInit(CH438_CTL_GPIO, CH438_INT_PIN, &int_config); + /* Enable GPIO pin interrupt */ + GPIO_PortEnableInterrupts(CH438_CTL_GPIO, 1U << CH438_INT_PIN); +} + + +static void Ch438Irq(void * parameter) +{ + rt_uint8_t gInterruptStatus; + rt_uint8_t port = 0; + struct rt_serial_device *serial = (struct rt_serial_device *)parameter; + /* multi irq may happen*/ + gInterruptStatus = ReadCH438Data(REG_SSR_ADDR); + port=CH438_INT_PORT; + rt_hw_serial_isr(extuart_serial_parm[port], RT_SERIAL_EVENT_RX_IND); +} + + +static rt_err_t rt_ch438_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + rt_uint32_t baud_rate = cfg->baud_rate; + rt_uint16_t port = cfg->reserved; + CH438PortInit(port, baud_rate); + return RT_EOK; +} + +static rt_err_t rt_ch438_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + rt_uint16_t ext_uart_no = serial->config.reserved; + static rt_uint16_t register_flag = 0; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + if(1 == register_flag) + { + /* Close interrupt of CH438 */ + /* GPIO3_3 INT*/ + rt_pin_irq_enable(CH438_INT, PIN_IRQ_DISABLE ); + register_flag = 0; + }break; + case RT_DEVICE_CTRL_SET_INT: + if(0 == register_flag) + { + rt_pin_mode(CH438_INT, PIN_MODE_INPUT_PULLUP); + rt_pin_attach_irq(CH438_INT, PIN_IRQ_MODE_FALLING,Ch438Irq,(void *)serial); + rt_pin_irq_enable(CH438_INT, PIN_IRQ_ENABLE); + register_flag = 1; + }break; + } + return (RT_EOK); +} + +static int rt_ch438_putc(struct rt_serial_device *serial, char c) +{ + uint16_t ext_uart_no = serial->config.reserved; + rt_uint8_t REG_LSR_ADDR,REG_THR_ADDR; + + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_THR_ADDR = offsetadd[ext_uart_no] | REG_THR0_ADDR; + rt_thread_mdelay(5); + if((ReadCH438Data( REG_LSR_ADDR ) & BIT_LSR_TEMT) != 0) + { + + WriteCH438Block( REG_THR_ADDR, 1, &c ); + return 1; + } else { + return 0; + } + +} + + +static int rt_ch438_getc(struct rt_serial_device *serial) +{ + + rt_uint8_t dat = 0; + rt_uint8_t REG_LSR_ADDR,REG_RBR_ADDR; + uint16_t ext_uart_no = serial->config.reserved;///< get extern uart port + + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_RBR_ADDR = offsetadd[ext_uart_no] | REG_RBR0_ADDR; + rt_thread_mdelay(5); + if((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0x01) + { + dat = ReadCH438Data( REG_RBR_ADDR ); + if(dat >= 0) + return dat; + }else{ + return -1; + } + +} + + +int rt_hw_ch438_init(void) +{ + struct rt_serial_device *extserial; + struct device_uart *extuart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + rt_err_t ret; + #ifdef CONFIG_CH438_EXTUART0 + static struct rt_serial_device extserial0; + + extserial = &extserial0; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 115200; + extserial->config.reserved = 0; ///< extern uart port + + extuart_serial_parm[0] = &extserial0; + + ret = rt_hw_serial_register(extserial, + "dev0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev0 register failed.\n"); + } + #endif + #ifdef CONFIG_CH438_EXTUART1 + static struct rt_serial_device extserial1; + + extserial = &extserial1; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 115200; + extserial->config.reserved = 1; ///< extern uart port + + extuart_serial_parm[1] = &extserial1; + + ret = rt_hw_serial_register(extserial, + "dev1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev1 register failed.\n"); + } + #endif + #ifdef CONFIG_CH438_EXTUART2 + static struct rt_serial_device extserial2; + + extserial = &extserial2; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 9600; + extserial->config.reserved = 2; ///< extern uart port + + extuart_serial_parm[2] = &extserial2; + + ret = rt_hw_serial_register(extserial, + "dev2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev2 register failed.\n"); + } + rt_kprintf("extuart_dev2 register succeed.\n"); + #endif + #ifdef CONFIG_CH438_EXTUART3 + static struct rt_serial_device extserial3; + + extserial = &extserial3; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 9600; + extserial->config.reserved = 3; ///< extern uart port + + ret = rt_hw_serial_register(extserial, + "dev3", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev3 register failed.\n"); + } + + extuart_serial_parm[3] = &extserial3; + #endif + #ifdef CONFIG_CH438_EXTUART4 + static struct rt_serial_device extserial4; + + extserial = &extserial4; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 9600; + extserial->config.reserved = 4; ///< extern uart port + + ret = rt_hw_serial_register(extserial, + "dev4", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev4 register failed.\n"); + } + + extuart_serial_parm[4] = &extserial4; + #endif + #ifdef CONFIG_CH438_EXTUART5 + static struct rt_serial_device extserial5; + + extserial = &extserial5; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 115200; + extserial->config.reserved = 5; ///< extern uart port + + ret = rt_hw_serial_register(extserial, + "dev5", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev5 register failed.\n"); + } + + extuart_serial_parm[5] = &extserial5; + #endif + #ifdef CONFIG_CH438_EXTUART6 + static struct rt_serial_device extserial6; + + extserial = &extserial6; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 57600; + extserial->config.reserved = 6; ///< extern uart port + + ret = rt_hw_serial_register(extserial, + "dev6", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev6 register failed.\n"); + } + + extuart_serial_parm[6] = &extserial6; + #endif + #ifdef CONFIG_CH438_EXTUART7 + static struct rt_serial_device extserial7; + + extserial = &extserial7; + extserial->ops = &ch438_ops; + extserial->config = config; + extserial->config.baud_rate = 9600; + extserial->config.reserved = 7; ///< extern uart port + + ret = rt_hw_serial_register(extserial, + "dev7", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + extuart); + if(ret < 0){ + rt_kprintf("extuart_dev7 register failed.\n"); + } + rt_kprintf("extuart_dev7 register succeed.\n"); + extuart_serial_parm[7] = &extserial7; + #endif + Ch438InitDefault(); + + return 0; + +} +INIT_DEVICE_EXPORT(rt_hw_ch438_init); + + +void up_udelay(void) +{ + volatile uint32_t i = 0; + for (i = 0; i < EXAMPLE_DELAY_COUNT; ++i) + { + __asm("NOP"); /* delay */ + } +} + +void up_mdelay(uint32_t time){ + + while(time--){ + udelay(1000); + } +} +/**************************************************************************** + * Name: CH438SetOutput + * + * Description: + * Configure pin mode to output + * + ****************************************************************************/ +static void CH438SetOutput(void) +{ + gpio_pin_config_t ch438_d0_config ={kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + GPIO_PinInit(CH438_D_GPIO,CH438_D0_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D1_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D2_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D3_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D4_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D5_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D6_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D7_PIN,&ch438_d0_config); + +} + +/**************************************************************************** + * Name: CH438SetInput + * + * Description: + * Configure pin mode to input + * + ****************************************************************************/ +static void CH438SetInput(void) +{ + gpio_pin_config_t ch438_d0_config ={kGPIO_DigitalInput, 0, kGPIO_NoIntmode}; + GPIO_PinInit(CH438_D_GPIO,CH438_D0_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D1_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D2_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D3_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D4_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D5_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D6_PIN,&ch438_d0_config); + GPIO_PinInit(CH438_D_GPIO,CH438_D7_PIN,&ch438_d0_config); + +} +//#define ADAPTER_ZIGBEE_E18 +/**************************************************************************** + * Name: ReadCH438Data + * + * Description: + * Read data from ch438 address + * + ****************************************************************************/ +static uint8_t ReadCH438Data(uint8_t addr) +{ + uint8_t dat = 0; + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NWR_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NRD_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_HIGH); + + + CH438SetOutput(); + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + if(addr &0x80) GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_LOW); + if(addr &0x40) GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_LOW); + if(addr &0x20) GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_LOW); + if(addr &0x10) GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_LOW); + if(addr &0x08) GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_LOW); + if(addr &0x04) GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_LOW); + if(addr &0x02) GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_LOW); + if(addr &0x01) GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_LOW); + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_LOW); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + + CH438SetInput(); + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NRD_PIN,PIN_LOW); + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + + + if (GPIO_PinRead(CH438_D_GPIO,CH438_D7_PIN)) dat |= 0x80; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D6_PIN)) dat |= 0x40; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D5_PIN)) dat |= 0x20; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D4_PIN)) dat |= 0x10; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D3_PIN)) dat |= 0x08; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D2_PIN)) dat |= 0x04; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D1_PIN)) dat |= 0x02; + if (GPIO_PinRead(CH438_D_GPIO,CH438_D0_PIN)) dat |= 0x01; + + + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NRD_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_HIGH); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(10); + #else + udelay(1); + #endif + + + return dat; +} + +/**************************************************************************** + * Name: WriteCH438Data + * + * Description: + * write data to ch438 address + * + ****************************************************************************/ +static void WriteCH438Data(uint8_t addr, const uint8_t dat) +{ + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NRD_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NWR_PIN,PIN_HIGH); + + + CH438SetOutput(); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + + if(addr &0x80) GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_LOW); + if(addr &0x40) GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_LOW); + if(addr &0x20) GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_LOW); + if(addr &0x10) GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_LOW); + if(addr &0x08) GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_LOW); + if(addr &0x04) GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_LOW); + if(addr &0x02) GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_LOW); + if(addr &0x01) GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_LOW); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_LOW); + + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + + if(dat &0x80) GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D7_PIN,PIN_LOW); + if(dat &0x40) GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D6_PIN,PIN_LOW); + if(dat &0x20) GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D5_PIN,PIN_LOW); + if(dat &0x10) GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D4_PIN,PIN_LOW); + if(dat &0x08) GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D3_PIN,PIN_LOW); + if(dat &0x04) GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D2_PIN,PIN_LOW); + if(dat &0x02) GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D1_PIN,PIN_LOW); + if(dat &0x01) GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_HIGH); else GPIO_PinWrite(CH438_D_GPIO,CH438_D0_PIN,PIN_LOW); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NWR_PIN,PIN_LOW); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NWR_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_HIGH); + + + #ifdef ADAPTER_ZIGBEE_E18 + udelay(100); + #else + udelay(1); + #endif + + CH438SetInput(); + + return; +} + +/**************************************************************************** + * Name: WriteCH438Block + * + * Description: + * Write data block from ch438 address + * + ****************************************************************************/ +static void WriteCH438Block(uint8_t mAddr, uint8_t mLen, const uint8_t *mBuf) +{ + while(mLen--) + WriteCH438Data(mAddr, *mBuf++); +} + +/**************************************************************************** + * Name: CH438UARTSend + * + * Description: + * Enable FIFO mode, which is used for ch438 serial port to send multi byte data, + * with a maximum of 128 bytes of data sent at a time + * + ****************************************************************************/ +static void Ch438UartSend(uint8_t ext_uart_no, const uint8_t *Data, uint16_t Num) +{ + uint8_t REG_LSR_ADDR,REG_THR_ADDR; + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_THR_ADDR = offsetadd[ext_uart_no] | REG_THR0_ADDR; + + while(1) + { + while((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_TEMT) == 0); /* wait for sending data done, THR and TSR is NULL */ + if(Num <= 128) + { + WriteCH438Block(REG_THR_ADDR, Num, Data); + break; + } + else + { + WriteCH438Block(REG_THR_ADDR, 128, Data); + Num -= 128; + Data += 128; + } + } + +} + +/**************************************************************************** + * Name: CH438UARTRcv + * + * Description: + * Disable FIFO mode for ch438 serial port to receive multi byte data + * + ****************************************************************************/ +uint8_t CH438UARTRcv(uint8_t ext_uart_no, uint8_t *buf, size_t size) +{ + uint8_t rcv_num = 0; + uint8_t dat = 0; + uint8_t REG_LSR_ADDR,REG_RBR_ADDR; + uint8_t *read_buffer; + size_t buffer_index = 0; + + read_buffer = buf; + + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_RBR_ADDR = offsetadd[ext_uart_no] | REG_RBR0_ADDR; + + /* Wait for the data to be ready */ + int count=0; + while ((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0){ + } + while (((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0x01) && (size != 0)) + { count++; + if(1==count){ + rt_thread_mdelay(5000); + } + rt_thread_mdelay(5); + dat = ReadCH438Data(REG_RBR_ADDR); + *read_buffer = dat; + read_buffer++; + buffer_index++; + if (255 == buffer_index) { + buffer_index = 0; + read_buffer = buf; + } + + ++rcv_num; + --size; + } + + return rcv_num; +} + +/**************************************************************************** + * Name: ImxrtCH438Init + * + * Description: + * ch438 initialization + * + ****************************************************************************/ +static void ImxrtCH438Init(void) +{ + CH438SetOutput(); + gpio_pin_config_t ch438_ctl_config ={kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + GPIO_PinInit(CH438_CTL_GPIO,CH438_NWR_PIN,&ch438_ctl_config); + GPIO_PinInit(CH438_CTL_GPIO,CH438_NRD_PIN,&ch438_ctl_config); + GPIO_PinInit(CH438_CTL_GPIO,CH438_ALE_PIN,&ch438_ctl_config); + + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NWR_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_NRD_PIN,PIN_HIGH); + GPIO_PinWrite(CH438_CTL_GPIO,CH438_ALE_PIN,PIN_HIGH); +} + +/**************************************************************************** + * Name: CH438PortInit + * + * Description: + * ch438 port initialization + * + ****************************************************************************/ +static void CH438PortInit(uint8_t ext_uart_no, uint32_t baud_rate) +{ + uint32_t div; + uint8_t DLL,DLM,dlab; + uint8_t REG_LCR_ADDR; + uint8_t REG_DLL_ADDR; + uint8_t REG_DLM_ADDR; + uint8_t REG_IER_ADDR; + uint8_t REG_MCR_ADDR; + uint8_t REG_FCR_ADDR; + + REG_LCR_ADDR = offsetadd[ext_uart_no] | REG_LCR0_ADDR; + REG_DLL_ADDR = offsetadd[ext_uart_no] | REG_DLL0_ADDR; + REG_DLM_ADDR = offsetadd[ext_uart_no] | REG_DLM0_ADDR; + REG_IER_ADDR = offsetadd[ext_uart_no] | REG_IER0_ADDR; + REG_MCR_ADDR = offsetadd[ext_uart_no] | REG_MCR0_ADDR; + REG_FCR_ADDR = offsetadd[ext_uart_no] | REG_FCR0_ADDR; + + /* reset the uart */ + WriteCH438Data(REG_IER_ADDR, BIT_IER_RESET); + up_mdelay(50); + + dlab = ReadCH438Data(REG_IER_ADDR); + dlab &= 0xDF; + WriteCH438Data(REG_IER_ADDR, dlab); + + /* set LCR register DLAB bit 1 */ + dlab = ReadCH438Data(REG_LCR_ADDR); + dlab |= 0x80; + WriteCH438Data(REG_LCR_ADDR, dlab); + + div = (Fpclk >> 4) / baud_rate; + DLM = div >> 8; + DLL = div & 0xff; + + /* set bps */ + WriteCH438Data(REG_DLL_ADDR, DLL); + WriteCH438Data(REG_DLM_ADDR, DLM); + + /* set FIFO mode, 112 bytes */ + WriteCH438Data(REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN); + + /* 8 bit word size, 1 bit stop bit, no crc */ + WriteCH438Data(REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0); + + /* enable interrupt */ + WriteCH438Data(REG_IER_ADDR, BIT_IER_IERECV); + + /* allow interrupt output, DTR and RTS is 1 */ + WriteCH438Data(REG_MCR_ADDR, BIT_MCR_OUT2); + + /* release the data in FIFO */ + WriteCH438Data(REG_FCR_ADDR, ReadCH438Data(REG_FCR_ADDR)| BIT_FCR_TFIFORST); +} +/**************************************************************************** + * Name: ImxrtCh438ReadData + * + * Description: + * Read data from ch438 port + * + ****************************************************************************/ +static int ImxrtCh438WriteData(uint8_t ext_uart_no, const uint8_t *write_buffer, size_t size) +{ + int write_len, write_len_continue; + int i, write_index; + if(write_buffer == NULL){ + return ERROR; + } + + write_len = size; + write_len_continue = size; + + if(write_len > 256) + { + if(0 == write_len % 256) + { + write_index = write_len / 256; + for(i = 0; i < write_index; i ++) + { + Ch438UartSend(ext_uart_no, write_buffer + i * 256, 256); + } + } + else + { + write_index = 0; + while(write_len_continue > 256) + { + Ch438UartSend(ext_uart_no, write_buffer + write_index * 256, 256); + write_index++; + write_len_continue = write_len - write_index * 256; + } + Ch438UartSend(ext_uart_no, write_buffer + write_index * 256, write_len_continue); + } + } + else + { + Ch438UartSend(ext_uart_no, write_buffer, write_len); + } + + return OK; +} + +/**************************************************************************** + * Name: ImxrtCh438ReadData + * + * Description: + * Read data from ch438 port + * + ****************************************************************************/ +static size_t ImxrtCh438ReadData(uint8_t ext_uart_no, size_t size) +{ + size_t RevLen = 0; + uint8_t InterruptStatus; + uint8_t REG_IIR_ADDR; + uint8_t REG_LSR_ADDR; + uint8_t REG_MSR_ADDR; + + REG_IIR_ADDR = offsetadd[ext_uart_no] | REG_IIR0_ADDR; + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_MSR_ADDR = offsetadd[ext_uart_no] | REG_MSR0_ADDR; + /* Read the interrupt status of the serial port */ + InterruptStatus = ReadCH438Data(REG_IIR_ADDR) & 0x0f; + rt_kprintf("InterruptStatus is %d\n", InterruptStatus); + + switch(InterruptStatus) + { + case INT_NOINT: /* no interrupt */ + break; + case INT_THR_EMPTY: /* the transmit hold register is not interrupted */ + break; + case INT_RCV_OVERTIME: /* receive data timeout interrupt */ + case INT_RCV_SUCCESS: /* receive data available interrupt */ + RevLen = CH438UARTRcv(ext_uart_no, buff[ext_uart_no], size); + break; + case INT_RCV_LINES: /* receive line status interrupt */ + ReadCH438Data(REG_LSR_ADDR); + break; + case INT_MODEM_CHANGE: /* modem input change interrupt */ + ReadCH438Data(REG_MSR_ADDR); + break; + default: + break; + } + + return RevLen; +} + +/**************************************************************************** + * Name: Ch438InitDefault + * + * Description: + * Ch438 default initialization function + * + ****************************************************************************/ +static void Ch438InitDefault(void) +{ + /*Dynamically create semaphores */ + semaphoreChInit(); + + ImxrtCH438Init(); + +/* If a port is checked, the port will be initialized. Otherwise, the interrupt of the port will be disabled. */ + +#ifdef CONFIG_CH438_EXTUART0 + CH438PortInit(0, CONFIG_CH438_EXTUART0_BAUD); +#else + WriteCH438Data(REG_IER0_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART1 + CH438PortInit(1, CONFIG_CH438_EXTUART1_BAUD); +#else + WriteCH438Data(REG_IER1_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART2 + CH438PortInit(2, CONFIG_CH438_EXTUART2_BAUD); +#else + WriteCH438Data(REG_IER2_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART3 + CH438PortInit(3, CONFIG_CH438_EXTUART3_BAUD); +#else + WriteCH438Data(REG_IER3_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART4 + CH438PortInit(4, CONFIG_CH438_EXTUART4_BAUD); +#else + WriteCH438Data(REG_IER4_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART5 + CH438PortInit(5, CONFIG_CH438_EXTUART5_BAUD); +#else + WriteCH438Data(REG_IER5_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART6 + CH438PortInit(6, CONFIG_CH438_EXTUART6_BAUD); +#else + WriteCH438Data(REG_IER6_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART7 + CH438PortInit(7, CONFIG_CH438_EXTUART7_BAUD); +#else + WriteCH438Data(REG_IER7_ADDR, 0x00); +#endif + + up_mdelay(10); + +} +/**************************************************************************** + * Name: static void getChInterruptStatus( void *arg) + * + * Description: + * read Interrupt register of ch438 + * + ****************************************************************************/ + +static int getCh438InterruptStatus(void ){ + uint8_t gChInterruptStatus=0; /*Interrupt register status*/ + uint8_t i=7; + gChInterruptStatus=ReadCH438Data(REG_SSR_ADDR); + rt_kprintf("gChInterruptStatus: %x",gChInterruptStatus); + if(gChInterruptStatus){ + for(i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "fsl_gpio.h" +#include "drv_gpio.h" +#include "MIMXRT1052.h" + + +/*self define*/ +/* output pin */ +#define CH438_D_GPIO GPIO1 +#define ZIGBEE_GPIO GPIO2 +#define CH438_CTL_GPIO GPIO3 + +#define CH438_INT_IRQ GPIO3_Combined_0_15_IRQn +#define CH438_INT_IRQ_HANDLER GPIO3_Combined_0_15_IRQHandler + +/* ch438 ctl pin */ +#define CH438_NWR 68 +#define CH438_NRD 69 +#define CH438_ALE 66 +#define CH438_INT 67 + +/* ch438 r/w pin*/ +#define CH438_D0 25 +#define CH438_D1 24 +#define CH438_D2 20 +#define CH438_D3 21 +#define CH438_D4 31 +#define CH438_D5 28 +#define CH438_D6 30 +#define CH438_D7 29 + + +#ifdef CONFIG_CH438_EXTUART0 +#define EXTU_UART_0 "dev0" +#endif + +#ifdef CONFIG_CH438_EXTUART1 +#define EXTU_UART_1 "dev1" +#endif + +#ifdef CONFIG_CH438_EXTUART2 +#define EXTU_UART_2 "dev2" +#endif + +#ifdef CONFIG_CH438_EXTUART3 +#define EXTU_UART_3 "dev3" +#endif + +#ifdef CONFIG_CH438_EXTUART4 +#define EXTU_UART_4 "dev4" +#endif + +#ifdef CONFIG_CH438_EXTUART5 +#define EXTU_UART_5 "dev5" +#endif + +#ifdef CONFIG_CH438_EXTUART6 +#define EXTU_UART_6 "dev6" +#endif + +#ifdef CONFIG_CH438_EXTUART7 +#define EXTU_UART_7 "dev7" +#endif + + +#define ZIGBEE_MODE_PIN (11U) + +#define CH438_D0_PIN (25U) +#define CH438_D1_PIN (24U) +#define CH438_D2_PIN (20U) +#define CH438_D3_PIN (21U) +#define CH438_D4_PIN (31U) +#define CH438_D5_PIN (28U) +#define CH438_D6_PIN (30U) +#define CH438_D7_PIN (29U) + +#define CH438_NWR_PIN (4U) +#define CH438_NRD_PIN (5U) +#define CH438_ALE_PIN (2U) +#define CH438_INT_PIN (3U) + +#define EXAMPLE_DELAY_COUNT 5000 +#define CH438PORTNUM 8 +#define CH438_BUFFSIZE 256 +#define CH438_INCREMENT MSEC2TICK(33) + +#define CONFIG_CH438_EXTUART0_BAUD 115200 +#define CONFIG_CH438_EXTUART1_BAUD 115200 +#define CONFIG_CH438_EXTUART2_BAUD 9600 +#define CONFIG_CH438_EXTUART3_BAUD 9600 +#define CONFIG_CH438_EXTUART4_BAUD 115200 +#define CONFIG_CH438_EXTUART5_BAUD 115200 +#define CONFIG_CH438_EXTUART6_BAUD 115200 +#define CONFIG_CH438_EXTUART7_BAUD 9600 +#define OK 0 +#define ERROR 1 + +/* chip definition */ +/* CH438serial port0 register address */ + +#define REG_RBR0_ADDR 0x00 /* serial port0receive buffer register address */ +#define REG_THR0_ADDR 0x00 /* serial port0send hold register address */ +#define REG_IER0_ADDR 0x01 /* serial port0interrupt enable register address */ +#define REG_IIR0_ADDR 0x02 /* serial port0interrupt identifies register address */ +#define REG_FCR0_ADDR 0x02 /* serial port0FIFO controls register address */ +#define REG_LCR0_ADDR 0x03 /* serial port0circuit control register address */ +#define REG_MCR0_ADDR 0x04 /* serial port0MODEM controls register address */ +#define REG_LSR0_ADDR 0x05 /* serial port0line status register address */ +#define REG_MSR0_ADDR 0x06 /* serial port0address of MODEM status register */ +#define REG_SCR0_ADDR 0x07 /* serial port0the user can define the register address */ +#define REG_DLL0_ADDR 0x00 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM0_ADDR 0x01 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port1 register address */ + +#define REG_RBR1_ADDR 0x10 /* serial port1receive buffer register address */ +#define REG_THR1_ADDR 0x10 /* serial port1send hold register address */ +#define REG_IER1_ADDR 0x11 /* serial port1interrupt enable register address */ +#define REG_IIR1_ADDR 0x12 /* serial port1interrupt identifies register address */ +#define REG_FCR1_ADDR 0x12 /* serial port1FIFO controls register address */ +#define REG_LCR1_ADDR 0x13 /* serial port1circuit control register address */ +#define REG_MCR1_ADDR 0x14 /* serial port1MODEM controls register address */ +#define REG_LSR1_ADDR 0x15 /* serial port1line status register address */ +#define REG_MSR1_ADDR 0x16 /* serial port1address of MODEM status register */ +#define REG_SCR1_ADDR 0x17 /* serial port1the user can define the register address */ +#define REG_DLL1_ADDR 0x10 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM1_ADDR 0x11 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port2 register address */ + +#define REG_RBR2_ADDR 0x20 /* serial port2receive buffer register address */ +#define REG_THR2_ADDR 0x20 /* serial port2send hold register address */ +#define REG_IER2_ADDR 0x21 /* serial port2interrupt enable register address */ +#define REG_IIR2_ADDR 0x22 /* serial port2interrupt identifies register address */ +#define REG_FCR2_ADDR 0x22 /* serial port2FIFO controls register address */ +#define REG_LCR2_ADDR 0x23 /* serial port2circuit control register address */ +#define REG_MCR2_ADDR 0x24 /* serial port2MODEM controls register address */ +#define REG_LSR2_ADDR 0x25 /* serial port2line status register address */ +#define REG_MSR2_ADDR 0x26 /* serial port2address of MODEM status register */ +#define REG_SCR2_ADDR 0x27 /* serial port2the user can define the register address */ +#define REG_DLL2_ADDR 0x20 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM2_ADDR 0x21 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port3 register address */ + +#define REG_RBR3_ADDR 0x30 /* serial port3receive buffer register address */ +#define REG_THR3_ADDR 0x30 /* serial port3send hold register address */ +#define REG_IER3_ADDR 0x31 /* serial port3interrupt enable register address */ +#define REG_IIR3_ADDR 0x32 /* serial port3interrupt identifies register address */ +#define REG_FCR3_ADDR 0x32 /* serial port3FIFO controls register address */ +#define REG_LCR3_ADDR 0x33 /* serial port3circuit control register address */ +#define REG_MCR3_ADDR 0x34 /* serial port3MODEM controls register address */ +#define REG_LSR3_ADDR 0x35 /* serial port3line status register address */ +#define REG_MSR3_ADDR 0x36 /* serial port3address of MODEM status register */ +#define REG_SCR3_ADDR 0x37 /* serial port3the user can define the register address */ +#define REG_DLL3_ADDR 0x30 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM3_ADDR 0x31 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port4 register address */ + +#define REG_RBR4_ADDR 0x08 /* serial port4receive buffer register address */ +#define REG_THR4_ADDR 0x08 /* serial port4send hold register address */ +#define REG_IER4_ADDR 0x09 /* serial port4interrupt enable register address */ +#define REG_IIR4_ADDR 0x0A /* serial port4interrupt identifies register address */ +#define REG_FCR4_ADDR 0x0A /* serial port4FIFO controls register address */ +#define REG_LCR4_ADDR 0x0B /* serial port4circuit control register address */ +#define REG_MCR4_ADDR 0x0C /* serial port4MODEM controls register address */ +#define REG_LSR4_ADDR 0x0D /* serial port4line status register address */ +#define REG_MSR4_ADDR 0x0E /* serial port4address of MODEM status register */ +#define REG_SCR4_ADDR 0x0F /* serial port4the user can define the register address */ +#define REG_DLL4_ADDR 0x08 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM4_ADDR 0x09 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port5 register address */ + +#define REG_RBR5_ADDR 0x18 /* serial port5receive buffer register address */ +#define REG_THR5_ADDR 0x18 /* serial port5send hold register address */ +#define REG_IER5_ADDR 0x19 /* serial port5interrupt enable register address */ +#define REG_IIR5_ADDR 0x1A /* serial port5interrupt identifies register address */ +#define REG_FCR5_ADDR 0x1A /* serial port5FIFO controls register address */ +#define REG_LCR5_ADDR 0x1B /* serial port5circuit control register address */ +#define REG_MCR5_ADDR 0x1C /* serial port5MODEM controls register address */ +#define REG_LSR5_ADDR 0x1D /* serial port5line status register address */ +#define REG_MSR5_ADDR 0x1E /* serial port5address of MODEM status register */ +#define REG_SCR5_ADDR 0x1F /* serial port5the user can define the register address */ +#define REG_DLL5_ADDR 0x18 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM5_ADDR 0x19 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port6 register address */ + +#define REG_RBR6_ADDR 0x28 /* serial port6receive buffer register address */ +#define REG_THR6_ADDR 0x28 /* serial port6send hold register address */ +#define REG_IER6_ADDR 0x29 /* serial port6interrupt enable register address */ +#define REG_IIR6_ADDR 0x2A /* serial port6interrupt identifies register address */ +#define REG_FCR6_ADDR 0x2A /* serial port6FIFO controls register address */ +#define REG_LCR6_ADDR 0x2B /* serial port6circuit control register address */ +#define REG_MCR6_ADDR 0x2C /* serial port6MODEM controls register address */ +#define REG_LSR6_ADDR 0x2D /* serial port6line status register address */ +#define REG_MSR6_ADDR 0x2E /* serial port6address of MODEM status register */ +#define REG_SCR6_ADDR 0x2F /* serial port6the user can define the register address */ +#define REG_DLL6_ADDR 0x28 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM6_ADDR 0x29 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port7 register address */ + +#define REG_RBR7_ADDR 0x38 /* serial port7receive buffer register address */ +#define REG_THR7_ADDR 0x38 /* serial port7send hold register address */ +#define REG_IER7_ADDR 0x39 /* serial port7interrupt enable register address */ +#define REG_IIR7_ADDR 0x3A /* serial port7interrupt identifies register address */ +#define REG_FCR7_ADDR 0x3A /* serial port7FIFO controls register address */ +#define REG_LCR7_ADDR 0x3B /* serial port7circuit control register address */ +#define REG_MCR7_ADDR 0x3C /* serial port7MODEM controls register address */ +#define REG_LSR7_ADDR 0x3D /* serial port7line status register address */ +#define REG_MSR7_ADDR 0x3E /* serial port7address of MODEM status register */ +#define REG_SCR7_ADDR 0x3F /* serial port7the user can define the register address */ +#define REG_DLL7_ADDR 0x38 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM7_ADDR 0x39 /* Baud rate divisor latch high 8-bit byte address */ + + +#define REG_SSR_ADDR 0x4F /* pecial status register address */ + + +/* IER register bit */ + +#define BIT_IER_RESET 0x80 /* The bit is 1 soft reset serial port */ +#define BIT_IER_LOWPOWER 0x40 /* The bit is 1 close serial port internal reference clock */ +#define BIT_IER_SLP 0x20 /* serial port0 is SLP, 1 close clock vibrator */ +#define BIT_IER1_CK2X 0x20 /* serial port1 is CK2X, 1 force the external clock signal after 2 times as internal */ +#define BIT_IER_IEMODEM 0x08 /* The bit is 1 allows MODEM input status to interrupt */ +#define BIT_IER_IELINES 0x04 /* The bit is 1 allow receiving line status to be interrupted */ +#define BIT_IER_IETHRE 0x02 /* The bit is 1 allows the send hold register to break in mid-air */ +#define BIT_IER_IERECV 0x01 /* The bit is 1 allows receiving data interrupts */ + +/* IIR register bit */ + +#define BIT_IIR_FIFOENS1 0x80 +#define BIT_IIR_FIFOENS0 0x40 /* The two is 1 said use FIFO */ + +/* Interrupt type: 0001 has no interrupt, 0110 receiving line status is interrupted, 0100 receiving data can be interrupted, +1100 received data timeout interrupt, 0010THR register air interrupt, 0000MODEM input change interrupt */ +#define BIT_IIR_IID3 0x08 +#define BIT_IIR_IID2 0x04 +#define BIT_IIR_IID1 0x02 +#define BIT_IIR_NOINT 0x01 + +/* FCR register bit */ + +/* Trigger point: 00 corresponds to 1 byte, 01 corresponds to 16 bytes, 10 corresponds to 64 bytes, 11 corresponds to 112 bytes */ +#define BIT_FCR_RECVTG1 0x80 /* Set the trigger point for FIFO interruption and automatic hardware flow control */ +#define BIT_FCR_RECVTG0 0x40 /* Set the trigger point for FIFO interruption and automatic hardware flow control */ + +#define BIT_FCR_TFIFORST 0x04 /* The bit is 1 empty the data sent in FIFO */ +#define BIT_FCR_RFIFORST 0x02 /* The bit is 1 empty the data sent in FIFO */ +#define BIT_FCR_FIFOEN 0x01 /* The bit is 1 use FIFO, 0 disable FIFO */ + +/* LCR register bit */ + +#define BIT_LCR_DLAB 0x80 /* To access DLL, DLM, 0 to access RBR/THR/IER */ +#define BIT_LCR_BREAKEN 0x40 /* 1 forces a BREAK line interval*/ + +/* Set the check format: when PAREN is 1, 00 odd check, 01 even check, 10 MARK (set 1), 11 blank (SPACE, clear 0) */ +#define BIT_LCR_PARMODE1 0x20 /* Sets the parity bit format */ +#define BIT_LCR_PARMODE0 0x10 /* Sets the parity bit format */ + +#define BIT_LCR_PAREN 0x08 /* A value of 1 allows you to generate and receive parity bits when sending */ +#define BIT_LCR_STOPBIT 0x04 /* If is 1, then two stop bits, is 0, a stop bit */ + +/* Set word length: 00 for 5 data bits, 01 for 6 data bits, 10 for 7 data bits and 11 for 8 data bits */ +#define BIT_LCR_WORDSZ1 0x02 /* Set the word length length */ +#define BIT_LCR_WORDSZ0 0x01 + +/* MCR register bit */ + +#define BIT_MCR_AFE 0x20 /* For 1 allows automatic flow control of CTS and RTS hardware */ +#define BIT_MCR_LOOP 0x10 /* Is the test mode of 1 enabling internal loop */ +#define BIT_MCR_OUT2 0x08 /* 1 Allows an interrupt request for the serial port output */ +#define BIT_MCR_OUT1 0x04 /* The MODEM control bit defined for the user */ +#define BIT_MCR_RTS 0x02 /* The bit is 1 RTS pin output effective */ +#define BIT_MCR_DTR 0x01 /* The bit is 1 DTR pin output effective */ + +/* LSR register bit */ + +#define BIT_LSR_RFIFOERR 0x80 /* 1 said There is at least one error in receiving FIFO */ +#define BIT_LSR_TEMT 0x40 /* 1 said THR and TSR are empty */ +#define BIT_LSR_THRE 0x20 /* 1 said THR is empty*/ +#define BIT_LSR_BREAKINT 0x10 /* The bit is 1 said the BREAK line interval was detected*/ +#define BIT_LSR_FRAMEERR 0x08 /* The bit is 1 said error reading data frame */ +#define BIT_LSR_PARERR 0x04 /* The bit is 1 said parity error */ +#define BIT_LSR_OVERR 0x02 /* 1 said receive FIFO buffer overflow */ +#define BIT_LSR_DATARDY 0x01 /* The bit is 1 said receive data received in FIFO */ + +/* MSR register bit */ + +#define BIT_MSR_DCD 0x80 /* The bit is 1 said DCD pin effective */ +#define BIT_MSR_RI 0x40 /* The bit is 1 said RI pin effective */ +#define BIT_MSR_DSR 0x20 /* The bit is 1 said DSR pin effective */ +#define BIT_MSR_CTS 0x10 /* The bit is 1 said CTS pin effective */ +#define BIT_MSR_DDCD 0x08 /* The bit is 1 said DCD pin The input state has changed */ +#define BIT_MSR_TERI 0x04 /* The bit is 1 said RI pin The input state has changed */ +#define BIT_MSR_DDSR 0x02 /* The bit is 1 said DSR pin The input state has changed */ +#define BIT_MSR_DCTS 0x01 /* The bit is 1 said CTS pin The input state has changed */ + +/* Interrupt status code */ + +#define INT_NOINT 0x01 /* There is no interruption */ +#define INT_THR_EMPTY 0x02 /* THR empty interruption */ +#define INT_RCV_OVERTIME 0x0C /* Receive timeout interrupt */ +#define INT_RCV_SUCCESS 0x04 /* Interrupts are available to receive data */ +#define INT_RCV_LINES 0x06 /* Receiving line status interrupted */ +#define INT_MODEM_CHANGE 0x00 /* MODEM input changes interrupt */ + +#define CH438_IIR_FIFOS_ENABLED 0xC0 /* use FIFO */ + +#define Fpclk 1843200 /* Define the internal clock frequency*/ + +/* For Interrupt */ +unsigned char CH438_CheckIIR(uint32_t iiraddr); /* Config serial port1interrupt identifies register function */ +void CH438_INTConfig(uint32_t ieraddr,uint32_t iiraddr,uint32_t mcraddr); /* Serial interrupt enable function */ +void Disable_Interrupt(void); /* Disable EXTI interrupt*/ +void Config_Interrupt(void); /* Config EXTI interrupt*/ + +/* For RT-Thread Config */ +static void Ch438Irq(void *parameter); +static rt_err_t rt_ch438_configure(struct rt_serial_device *serial, struct serial_configure *cfg); +static rt_err_t rt_ch438_control(struct rt_serial_device *serial, int cmd, void *arg); +static int rt_ch438_putc(struct rt_serial_device *serial, char c); +static int rt_ch438_getc(struct rt_serial_device *serial); +int rt_hw_ch438_init(void); + +int semaphoreChInit(void); + +/* Delay */ +void up_udelay(void); +void up_mdelay(uint32_t time); + +void udelay(unsigned long usecs); +/* CH438 Config */ +static void CH438SetOutput(void); +static void CH438SetInput(void); +static uint8_t ReadCH438Data(uint8_t addr); +static void WriteCH438Data(uint8_t addr, const uint8_t dat); +static void WriteCH438Block(uint8_t mAddr, uint8_t mLen, const uint8_t *mBuf); +static void Ch438UartSend(uint8_t ext_uart_no, const uint8_t *Data, uint16_t Num); +uint8_t CH438UARTRcv(uint8_t ext_uart_no, uint8_t *buf, size_t size); +static void ImxrtCH438Init(void); +static void CH438PortInit(uint8_t ext_uart_no, uint32_t baud_rate); +static int ImxrtCh438WriteData(uint8_t ext_uart_no, const uint8_t *write_buffer, size_t size); +static size_t ImxrtCh438ReadData(uint8_t ext_uart_no, size_t size); +static void Ch438InitDefault(void); + +static int getCh438InterruptStatus(void ); +/* CH438 Test Function */ +void CH438Test(void); +void HC08Test(void); +void ZigBeeTest(void); +void CH438Init(void); +#endif \ No newline at end of file