1 /* 2 * Copyright (c) 2006-2023, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2022-07-15 Emuzit first version 9 */ 10 #ifndef __CH56X_UART_H__ 11 #define __CH56X_UART_H__ 12 13 #include "soc.h" 14 #include "ch56x_gpio.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #define UART_RXD0_ALT GET_PIN(A, 5) 21 #define UART_TXD0_ALT GET_PIN(A, 6) 22 23 #define UART_RXD0_PIN GET_PIN(B, 5) 24 #define UART_TXD0_PIN GET_PIN(B, 6) 25 #define UART_RXD1_PIN GET_PIN(A, 7) 26 #define UART_TXD1_PIN GET_PIN(A, 8) 27 #define UART_RXD2_PIN GET_PIN(A, 2) 28 #define UART_TXD2_PIN GET_PIN(A, 3) 29 #define UART_RXD3_PIN GET_PIN(B, 3) 30 #define UART_TXD3_PIN GET_PIN(B, 4) 31 32 #ifndef UART_FIFO_SIZE 33 #define UART_FIFO_SIZE 8 34 #endif 35 36 #ifndef UART_RECV_RDY_SZ 37 #define UART_RECV_RDY_SZ 7 // FIFO trigger level for rx data available 38 #endif 39 40 union _uart_mcr 41 { 42 uint8_t reg; 43 struct 44 { 45 uint8_t dtr : 1; // B.0 : RW, DTR output (UART0 only) 46 uint8_t rts : 1; // B.1 : RW, RTS output (UART0 only) 47 uint8_t out1 : 1; // B.2 : RW, user defined modem control (UART0 only) 48 uint8_t int_oe : 1; // B.3 : RW, interrupt output enable / OUT2 49 uint8_t loop : 1; // B.4 : RW, enable internal loop test (UART0 only) 50 uint8_t au_flow_en : 1; // B.5 : RW, enable CTS/RTS autoflow control 51 uint8_t tnow : 1; // B.6 : RW, enable DTR TNOW output (UART0 only) 52 uint8_t half : 1; // B.7 : RW, enable half-duplex mode (UART0 only) 53 }; 54 }; 55 #define RB_MCR_DTR 0x01 56 #define RB_MCR_RTS 0x02 57 #define RB_MCR_OUT1 0x04 58 #define RB_MCR_OUT2 0x08 59 #define RB_MCR_INT_OE 0x08 60 #define RB_MCR_LOOP 0x10 61 #define RB_MCR_AU_FLOW_EN 0x20 62 #define RB_MCR_TNOW 0x40 63 #define RB_MCR_HALF 0x80 64 65 union _uart_ier 66 { 67 uint8_t reg; 68 struct 69 { 70 uint8_t recv_rdy : 1; // B.0 : RW, enable rx data ready intr 71 uint8_t thr_empty : 1; // B.1 : RW, enable THR empty intr 72 uint8_t line_stat : 1; // B.2 : RW, enable rx line status intr 73 uint8_t modem_chg : 1; // B.3 : RW, enable modem status change intr (UART0 only) 74 uint8_t dtr_en : 1; // B.4 : RW, DTR/TNOW output pin enable (UART0 only) 75 uint8_t rts_en : 1; // B.5 : RW, RTS output pin enable (UART0 only) 76 uint8_t txd_en : 1; // B.6 : RW, TXD pin enable 77 uint8_t reset : 1; // B.7 : WZ, software reset control, active high, auto clear 78 }; 79 }; 80 #define RB_IER_RECV_RDY 0x01 81 #define RB_IER_THR_EMPTY 0x02 82 #define RB_IER_LINE_STAT 0x04 83 #define RB_IER_MODEM_CHG 0x08 84 #define RB_IER_DTR_EN 0x10 85 #define RB_IER_RTS_EN 0x20 86 #define RB_IER_TXD_EN 0x40 87 #define RB_IER_RESET 0x80 88 89 union _uart_fcr 90 { 91 uint8_t reg; 92 struct 93 { 94 uint8_t fifo_en : 1; // B.0 : RW, FIFO enable 95 uint8_t rx_fifo_clr : 1; // B.1 : WZ, write 1 to clear rx FIFO, auto clear 96 uint8_t tx_fifo_clr : 1; // B.2 : WZ, write 1 to clear tx FIFO, auto clear 97 uint8_t resv_3 : 3; 98 uint8_t fifo_trig : 2; // B.7-6 : RW, rx FIFO trigger level, 1/2/4/7 bytes 99 }; 100 }; 101 #define RB_FCR_FIFO_EN 0x01 102 #define RB_FCR_RX_FIFO_CLR 0x02 103 #define RB_FCR_TX_FIFO_CLR 0x04 104 #define RB_FCR_FIFO_TRIG 0xc0 105 106 #define UART_1BYTE_TRIG 0 107 #define UART_2BYTE_TRIG 1 108 #define UART_4BYTE_TRIG 2 109 #define UART_7BYTE_TRIG 3 110 111 union _uart_lcr 112 { 113 uint8_t reg; 114 struct 115 { 116 uint8_t word_sz : 2; // B.1-0 : RW, word bit length, 5/6/7/8 bits 117 uint8_t stop_bit : 1; // B.2 : RW, stop bit length, 1/2 bits 118 uint8_t par_en : 1; // B.3 : RW, parity enable 119 uint8_t par_mod : 2; // B.5-4 : RW, parity mode, odd/even/mark/space 120 uint8_t break_en : 1; // B.6 : RW, force BREAK line condition 121 uint8_t dlab : 1; // B.7 : RW, user defined general purpose bit 122 }; 123 }; 124 #define RB_LCR_WORD_SZ 0x03 125 #define RB_LCR_STOP_BIT 0x04 126 #define RB_LCR_PAR_EN 0x08 127 #define RB_LCR_PAR_MOD 0x30 128 #define RB_LCR_BREAK_EN 0x40 129 #define RB_LCR_DLAB 0x80 130 #define RB_LCR_GP_BIT 0x80 131 132 #define LCR_DATA_BITS_5 0 133 #define LCR_DATA_BITS_6 1 134 #define LCR_DATA_BITS_7 2 135 #define LCR_DATA_BITS_8 3 136 137 #define LCR_STOP_BITS_1 0 138 #define LCR_STOP_BITS_2 1 139 140 #define LCR_PARITY_ODD 0 141 #define LCR_PARITY_EVEN 1 142 #define LCR_PARITY_MARK 2 143 #define LCR_PARITY_SPACE 3 144 145 union _uart_iir 146 { 147 uint8_t reg; 148 struct 149 { 150 uint8_t int_mask : 4; // B.3-0 : RO, interrupt mask (intr if B.0 is 0) 151 uint8_t resv_4 : 2; 152 uint8_t fifo_id : 2; // B.7-6 : RO, FIFO enabled flag 153 }; 154 }; 155 #define RB_IIR_NO_INT 0x01 156 #define RB_IIR_INT_MASK 0x0f 157 #define RB_IIR_FIFO_ID 0xc0 158 159 /* RB_IIR_INT_MASK (IIR bits 3:0) definition 160 */ 161 #define UART_II_SLV_ADDR 0x0e // UART0 slave address match interrupt 162 #define UART_II_LINE_STAT 0x06 // rx line status interrupt 163 #define UART_II_RECV_RDY 0x04 // rx data available interrupt 164 #define UART_II_RECV_TOUT 0x0c // rx fifo timeout interrupt 165 #define UART_II_THR_EMPTY 0x02 // THR empty interrupt 166 #define UART_II_MODEM_CHG 0x00 // UART0 modem status change interrupt 167 #define UART_II_NO_INTER 0x01 // no interrupt pending 168 169 union _uart_lsr 170 { 171 uint8_t reg; 172 struct 173 { 174 uint8_t data_rdy : 1; // B.0 : RO, rx FIFO data ready 175 uint8_t over_err : 1; // B.1 : RZ, rx FIFO data overrun 176 uint8_t par_err : 1; // B.2 : RZ, rx parity error 177 uint8_t frame_err : 1; // B.3 : RZ, rx frame error 178 uint8_t break_err : 1; // B.4 : RZ, rx BREAK detected 179 uint8_t tx_fifo_emp : 1; // B.5 : RO, tx FIFO empty 180 uint8_t tx_all_emp : 1; // B.6 : RO, THR/TSR all empty 181 uint8_t err_rx_fifo : 1; // B.7 : RO, PAR/FRAME/BREAK ERR in rx FIFO 182 }; 183 }; 184 #define RB_LSR_DATA_RDY 0x01 185 #define RB_LSR_OVER_ERR 0x02 186 #define RB_LSR_PAR_ERR 0x04 187 #define RB_LSR_FRAME_ERR 0x08 188 #define RB_LSR_BREAK_ERR 0x10 189 #define RB_LSR_TX_FIFO_EMP 0x20 190 #define RB_LSR_TX_ALL_EMP 0x40 191 #define RB_LSR_ERR_RX_FIFO 0x80 192 193 union _uart_msr 194 { 195 uint8_t reg; 196 struct 197 { 198 uint8_t cts_chg : 1; // B.0 : RZ, CTS input changed 199 uint8_t dsr_chg : 1; // B.1 : RZ, DSR input changed 200 uint8_t ri_chg : 1; // B.2 : RZ, RI input changed 201 uint8_t dcd_chg : 1; // B.3 : RZ, DCD input changed 202 uint8_t cts : 1; // B.4 : RO, CTS action status 203 uint8_t dsr : 1; // B.5 : RO, DSR action status 204 uint8_t ri : 1; // B.6 : RO, RI action status 205 uint8_t dcd : 1; // B.7 : RO, DCD action status 206 }; 207 }; 208 #define RB_MSR_CTS_CHG 0x01 209 #define RB_MSR_DSR_CHG 0x02 210 #define RB_MSR_RI_CHG 0x04 211 #define RB_MSR_DCD_CHG 0x08 212 #define RB_MSR_CTS 0x10 213 #define RB_MSR_DSR 0x20 214 #define RB_MSR_RI 0x40 215 #define RB_MSR_DCD 0x80 216 217 /* 218 * 0x00 R8_UARTx_MCR: Modem Control Register 219 * 0x01 R8_UARTx_IER: Interrupt Enable Register 220 * 0x02 R8_UARTx_FCR: FIFO Control Register 221 * 0x03 R8_UARTx_LCR: Line Control Register 222 * 0x04 R8_UARTx_IIR: Interrupt Identification Register 223 * 0x05 R8_UARTx_LSR: Line Status Register 224 * 0x06 R8_UARTx_MSR: Modem Status Register (UART0 only) 225 * 0x08 R8_UARTx_RBR: Rx Buffer Register 226 * 0x08 R8_UARTx_THR: Tx Hold Register 227 * 0x0a R8_UARTx_RFC: Rx FIFO count register 228 * 0x0b R8_UARTx_TFC: Tx FIFO count register 229 * 0x0c R16_UARTx_DL: Divisor Latch 230 * 0x0e R8_UARTx_DIV: frequency pre divider 231 * 0x0f R8_UARTx_ADR: Address Register (UART0 only) 232 * 233 * CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test. 234 * Be careful for those with side effect for read (e.g. RBR, IIR). 235 */ 236 struct uart_registers 237 { 238 union _uart_mcr MCR; 239 union _uart_ier IER; 240 union _uart_fcr FCR; 241 union _uart_lcr LCR; 242 union _uart_iir IIR; 243 union _uart_lsr LSR; 244 union _uart_lsr MSR; 245 uint8_t resv_7; 246 union 247 { 248 uint8_t RBR; 249 uint8_t THR; 250 }; 251 uint8_t resv_9; 252 uint8_t RFC; 253 uint8_t TFC; 254 uint16_t DL; 255 uint8_t DIV; 256 uint8_t ADR; 257 } __packed; 258 259 CHECK_STRUCT_SIZE(struct uart_registers, 0x10); 260 261 int rt_hw_uart_init(void); 262 263 #ifdef __cplusplus 264 } 265 #endif 266 267 #endif 268