diff options
| author | flyingcys <[email protected]> | 2023-10-26 09:34:58 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-26 09:34:58 +0800 |
| commit | c701b3e81a74374e3a0f1efda50c7096273c69eb (patch) | |
| tree | 60f2df7f9a075e557a78ca50f34fa42096146c17 | |
| parent | 3283f54c7a0444b2e51ec79a4da57e7871528f05 (diff) | |
[bsp]update cv1800b drv_uart (#8188)
| -rw-r--r-- | bsp/cv1800b/.config | 27 | ||||
| -rw-r--r-- | bsp/cv1800b/drivers/drv_uart.c | 109 | ||||
| -rw-r--r-- | bsp/cv1800b/drivers/drv_uart.h | 62 | ||||
| -rw-r--r-- | bsp/cv1800b/rtconfig.h | 13 |
4 files changed, 128 insertions, 83 deletions
diff --git a/bsp/cv1800b/.config b/bsp/cv1800b/.config index b06ace2ff9..d1fbecdd3c 100644 --- a/bsp/cv1800b/.config +++ b/bsp/cv1800b/.config @@ -11,6 +11,7 @@ CONFIG_RT_NAME_MAX=8 CONFIG_RT_USING_SMART=y # CONFIG_RT_USING_AMP is not set # CONFIG_RT_USING_SMP is not set +CONFIG_RT_CPUS_NR=1 CONFIG_RT_ALIGN_SIZE=8 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y @@ -68,19 +69,15 @@ CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y # CONFIG_RT_USING_MEMTRACE is not set # CONFIG_RT_USING_HEAP_ISR is not set CONFIG_RT_USING_HEAP=y - -# -# Kernel Device Object -# CONFIG_RT_USING_DEVICE=y # CONFIG_RT_USING_DEVICE_OPS is not set -# CONFIG_RT_USING_DM is not set # CONFIG_RT_USING_INTERRUPT_INFO is not set CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -CONFIG_RT_VER_NUM=0x50002 +CONFIG_RT_VER_NUM=0x50100 # CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 CONFIG_ARCH_CPU_64BIT=y CONFIG_RT_USING_CACHE=y # CONFIG_RT_USING_HW_ATOMIC is not set @@ -138,6 +135,7 @@ CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_MQUEUE is not set # CONFIG_RT_USING_FAL is not set CONFIG_RT_USING_LWP=y +# CONFIG_LWP_DEBUG is not set CONFIG_RT_LWP_MAX_NR=30 CONFIG_LWP_TASK_STACK_SIZE=16384 CONFIG_RT_CH_MSG_MAX_NR=1024 @@ -149,9 +147,12 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # # Device Drivers # +# CONFIG_RT_USING_DM is not set CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_UNAMED_PIPE_NUMBER=64 -# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set @@ -174,7 +175,6 @@ CONFIG_RT_USING_RANDOM=y # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set -# CONFIG_RT_USING_FDT is not set CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_ALARM is not set # CONFIG_RT_USING_SOFT_RTC is not set @@ -276,6 +276,11 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_RT_USING_VBUS is not set # +# Memory management +# +# CONFIG_RT_USING_MEMBLOCK is not set + +# # RT-Thread Utestcases # # CONFIG_RT_USING_UTESTCASES is not set @@ -422,7 +427,6 @@ CONFIG_RT_USING_ADT_REF=y # LVGL: powerful and easy-to-use embedded GUI library # # CONFIG_PKG_USING_LVGL is not set -# CONFIG_PKG_USING_LITTLEVGL2RTT is not set # CONFIG_PKG_USING_LV_MUSIC_DEMO is not set # CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set @@ -633,6 +637,7 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_PKG_USING_BALANCE is not set # CONFIG_PKG_USING_SHT2X is not set # CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_SHT4X is not set # CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_ADT74XX is not set # CONFIG_PKG_USING_MAX17048 is not set @@ -734,6 +739,7 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_PKG_USING_FINGERPRINT is not set # CONFIG_PKG_USING_BT_ECB02C is not set # CONFIG_PKG_USING_UAT is not set +# CONFIG_PKG_USING_ST7789 is not set # CONFIG_PKG_USING_SPI_TOOLS is not set # @@ -978,6 +984,7 @@ CONFIG_RT_USING_ADT_REF=y # # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set # CONFIG_PKG_USING_ARDUINO_U8G2 is not set +# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set @@ -986,6 +993,7 @@ CONFIG_RT_USING_ADT_REF=y # # Timing # +# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set # CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set # CONFIG_PKG_USING_ARDUINO_TICKER is not set # CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set @@ -1022,7 +1030,6 @@ CONFIG_RT_USING_ADT_REF=y # # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set -# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set # # Signal IO diff --git a/bsp/cv1800b/drivers/drv_uart.c b/bsp/cv1800b/drivers/drv_uart.c index 265cbde5a0..5ecfd0ead6 100644 --- a/bsp/cv1800b/drivers/drv_uart.c +++ b/bsp/cv1800b/drivers/drv_uart.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2023/06/25 flyingcys first version + * 2023/10/25 flyingcys update uart configure */ #include <rthw.h> #include <rtthread.h> @@ -19,46 +20,22 @@ #include <rtdbg.h> /* - * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the - * LCR is written whilst busy. If it is, then a busy detect interrupt is - * raised, the LCR needs to be rewritten and the uart status register read. + * Divide positive or negative dividend by positive divisor and round + * to closest integer. Result is undefined for negative divisors and + * for negative dividends if the divisor variable type is unsigned. */ +#define DIV_ROUND_CLOSEST(x, divisor)( \ +{ \ + typeof(x) __x = x; \ + typeof(divisor) __d = divisor; \ + (((typeof(x))-1) > 0 || \ + ((typeof(divisor))-1) > 0 || (__x) > 0) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ +} \ +) -#define UART_RX 0 /* In: Receive buffer */ -#define UART_TX 0 /* Out: Transmit buffer */ - -#define UART_DLL 0 /* Out: Divisor Latch Low */ -#define UART_DLM 1 /* Out: Divisor Latch High */ - -#define UART_IER 1 /* Out: Interrupt Enable Register */ -#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ - -#define UART_SSR 0x22 /* In: Software Reset Register */ -#define UART_USR 0x1f /* UART Status Register */ - -#define UART_LCR 3 /* Out: Line Control Register */ -#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ -#define UART_LCR_PARITY 0x8 /* Parity Enable */ -#define UART_LCR_STOP 0x4 /* Stop bits: 0=1 bit, 1=2 bits */ -#define UART_LCR_WLEN8 0x3 /* Wordlength: 8 bits */ - -#define UART_MCR 4 /* Out: Modem Control Register */ -#define UART_MCR_RTS 0x02 /* RTS complement */ - -#define UART_LSR 5 /* In: Line Status Register */ -#define UART_LSR_BI 0x10 /* Break interrupt indicator */ -#define UART_LSR_DR 0x01 /* Receiver data ready */ - -#define UART_IIR 2 /* In: Interrupt ID Register */ -#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ -#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ -#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */ - -#define UART_FCR 2 /* Out: FIFO Control Register */ -#define UART_FCR_EN_FIFO 0x01 /* Enable the FIFO */ -#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ -#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) struct hw_uart_device { @@ -108,12 +85,12 @@ rt_inline void dw8250_write32(rt_ubase_t addr, rt_ubase_t offset, rt_uint32_t va { unsigned int lcr = dw8250_read32(addr, UART_LCR); - if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) + if ((value & ~UART_LCR_STKP) == (lcr & ~UART_LCR_STKP)) { return; } - dw8250_write32(addr, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + dw8250_write32(addr, UART_FCR, UART_FCR_DEFVAL); dw8250_read32(addr, UART_RX); *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value; @@ -121,41 +98,39 @@ rt_inline void dw8250_write32(rt_ubase_t addr, rt_ubase_t offset, rt_uint32_t va } } +static void dw8250_uart_setbrg(rt_ubase_t addr, int baud_divisor) +{ + /* to keep serial format, read lcr before writing BKSE */ + int lcr_val = dw8250_read32(addr, UART_LCR) & ~UART_LCR_BKSE; + + dw8250_write32(addr, UART_LCR, UART_LCR_BKSE | lcr_val); + dw8250_write32(addr, UART_DLL, baud_divisor & 0xff); + + dw8250_write32(addr, UART_DLM, (baud_divisor >> 8) & 0xff); + dw8250_write32(addr, UART_LCR, lcr_val); +} + static rt_err_t dw8250_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { - rt_base_t base, rate; + rt_base_t base; struct hw_uart_device *uart; + int clock_divisor; RT_ASSERT(serial != RT_NULL); uart = (struct hw_uart_device *)serial->parent.user_data; base = uart->hw_base; - /* Resset UART */ - dw8250_write32(base, UART_SSR, 1); - dw8250_write32(base, UART_SSR, 0); - - dw8250_write32(base, UART_IER, !UART_IER_RDI); - dw8250_write32(base, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + while (!(dw8250_read32(base, UART_LSR) & UART_LSR_TEMT)); - /* Disable flow ctrl */ - dw8250_write32(base, UART_MCR, 0); - /* Clear RTS */ - dw8250_write32(base, UART_MCR, dw8250_read32(base, UART_MCR) | UART_MCR_RTS); + dw8250_write32(base, UART_IER, 0); + dw8250_write32(base, UART_MCR, UART_MCRVAL); + dw8250_write32(base, UART_FCR, UART_FCR_DEFVAL); - rate = UART_INPUT_CLK / 16 / serial->config.baud_rate; + /* initialize serial config to 8N1 before writing baudrate */ + dw8250_write32(base, UART_LCR, UART_LCR_8N1); - /* Enable access DLL & DLH */ - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) | UART_LCR_DLAB); - dw8250_write32(base, UART_DLL, (rate & 0xff)); - dw8250_write32(base, UART_DLM, (rate & 0xff00) >> 8); - /* Clear DLAB bit */ - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_DLAB)); - - dw8250_write32(base, UART_LCR, (dw8250_read32(base, UART_LCR) & (~UART_LCR_WLEN8)) | UART_LCR_WLEN8); - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_STOP)); - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_PARITY)); - - dw8250_write32(base, UART_IER, UART_IER_RDI); + clock_divisor = DIV_ROUND_CLOSEST(UART_INPUT_CLK, 16 * serial->config.baud_rate); + dw8250_uart_setbrg(base, clock_divisor); return RT_EOK; } @@ -194,9 +169,7 @@ static int dw8250_uart_putc(struct rt_serial_device *serial, char c) uart = (struct hw_uart_device *)serial->parent.user_data; base = uart->hw_base; - while ((dw8250_read32(base, UART_USR) & 0x2) == 0) - { - } + while ((dw8250_read32(base, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY); dw8250_write32(base, UART_TX, c); @@ -213,7 +186,7 @@ static int dw8250_uart_getc(struct rt_serial_device *serial) uart = (struct hw_uart_device *)serial->parent.user_data; base = uart->hw_base; - if ((dw8250_read32(base, UART_LSR) & 0x1)) + if (dw8250_read32(base, UART_LSR) & UART_LSR_DR) { ch = dw8250_read32(base, UART_RX) & 0xff; } diff --git a/bsp/cv1800b/drivers/drv_uart.h b/bsp/cv1800b/drivers/drv_uart.h index 50464774bd..e983f7396e 100644 --- a/bsp/cv1800b/drivers/drv_uart.h +++ b/bsp/cv1800b/drivers/drv_uart.h @@ -14,7 +14,7 @@ #include "rtdevice.h" #include <rthw.h> -#define UART_REG_SHIFT 0x2 /* Register Shift*/ +#define UART_REG_SHIFT 0x2 /* Register Shift*/ #define UART_INPUT_CLK 25000000 #define UART0_BASE 0x04140000 @@ -30,6 +30,66 @@ #define UART3_IRQ (UART_IRQ_BASE + 3) #define UART4_IRQ (UART_IRQ_BASE + 4) +/* + * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the + * LCR is written whilst busy. If it is, then a busy detect interrupt is + * raised, the LCR needs to be rewritten and the uart status register read. + */ + +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ + +#define UART_SSR 0x22 /* In: Software Reset Register */ +#define UART_USR 0x1f /* UART Status Register */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ +#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */ + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */ +#define UART_FCR_RXSR 0x02 /* Receiver soft reset */ +#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */ + +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_LCR_WLS_MSK 0x03 /* character length select mask */ +#define UART_LCR_WLS_5 0x00 /* 5 bit character length */ +#define UART_LCR_WLS_6 0x01 /* 6 bit character length */ +#define UART_LCR_WLS_7 0x02 /* 7 bit character length */ +#define UART_LCR_WLS_8 0x03 /* 8 bit character length */ +#define UART_LCR_STB 0x04 /* # stop Bits, off=1, on=1.5 or 2) */ +#define UART_LCR_PEN 0x08 /* Parity eneble */ +#define UART_LCR_EPS 0x10 /* Even Parity Select */ +#define UART_LCR_STKP 0x20 /* Stick Parity */ +#define UART_LCR_SBRK 0x40 /* Set Break */ +#define UART_LCR_BKSE 0x80 /* Bank select enable */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ + + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_DTR 0x01 /* DTR */ +#define UART_MCR_RTS 0x02 /* RTS */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_TEMT 0x40 /* Transmitter empty */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ + +#define UART_MCRVAL (UART_MCR_DTR | UART_MCR_RTS) /* RTS/DTR */ + +/* Clear & enable FIFOs */ +#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR) + +#define UART_LCR_8N1 0x03 + int rt_hw_uart_init(void); #endif /* __DRV_USART_H__ */ diff --git a/bsp/cv1800b/rtconfig.h b/bsp/cv1800b/rtconfig.h index 6f977d5000..a6f6c2fb4b 100644 --- a/bsp/cv1800b/rtconfig.h +++ b/bsp/cv1800b/rtconfig.h @@ -8,6 +8,7 @@ #define RT_NAME_MAX 8 #define RT_USING_SMART +#define RT_CPUS_NR 1 #define RT_ALIGN_SIZE 8 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 @@ -45,14 +46,12 @@ #define RT_USING_SMALL_MEM #define RT_USING_SMALL_MEM_AS_HEAP #define RT_USING_HEAP - -/* Kernel Device Object */ - #define RT_USING_DEVICE #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x50002 +#define RT_VER_NUM 0x50100 +#define RT_BACKTRACE_LEVEL_MAX_NR 32 #define ARCH_CPU_64BIT #define RT_USING_CACHE #define ARCH_MM_MMU @@ -103,6 +102,9 @@ #define RT_USING_DEVICE_IPC #define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA @@ -157,6 +159,9 @@ #define RT_USING_ADT_HASHMAP #define RT_USING_ADT_REF +/* Memory management */ + + /* RT-Thread Utestcases */ |
