1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #ifndef UART_PL011_SAMPLE_H
10 #define UART_PL011_SAMPLE_H
11
12 #include <stdint.h>
13 #include <stdbool.h>
14 #include "hdf_device_desc.h"
15 #include "buf_fifo.h"
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 struct UartRegisterMap {
22 volatile uint32_t dr; /* Offset: 0x000 TYPE: (RW) Data register */
23 union {
24 volatile uint32_t rsr; /* Offset: 0x004 TYPE: (RO) Receive status register */
25 volatile uint32_t ecr; /* Offset: 0x004 TYPE: (WO) Error clear register */
26 };
27 volatile uint32_t reserved0[4]; /* Offset: 0x008-0x014 Reserved */
28 volatile uint32_t fr; /* Offset: 0x018 TYPE: (RO) Flag register */
29 volatile uint32_t reserved1; /* Offset: 0x01C Reserved */
30 volatile uint32_t ilpr; /* Offset: 0x020 TYPE: (RW) IrDA low-power counter register */
31 volatile uint32_t ibrd; /* Offset: 0x024 TYPE: (RW) Integer baud rate register */
32 volatile uint32_t fbrd; /* Offset: 0x028 TYPE: (RW) Fractional baud rate register */
33 volatile uint32_t lcr; /* Offset: 0x02C TYPE: (RW) Line control register */
34 volatile uint32_t cr; /* Offset: 0x030 TYPE: (RW) Control register */
35 volatile uint32_t ifls; /* Offset: 0x034 TYPE: (RW) Interrupt FIFO level select register */
36 volatile uint32_t imsc; /* Offset: 0x038 TYPE: (RW) Interrupt mask set/clear register */
37 volatile uint32_t ris; /* Offset: 0x03C TYPE: (RO) Raw interrupt status register */
38 volatile uint32_t mis; /* Offset: 0x040 TYPE: (RO) Masked interrupt status register */
39 volatile uint32_t icr; /* Offset: 0x044 TYPE: (WO) Interrupt clear register */
40 volatile uint32_t dmacr; /* Offset: 0x048 TYPE: (RW) DMA control register */
41 };
42
43 struct UartResource {
44 uint32_t num; /* UART port num */
45 uint32_t base; /* UART PL011 base address */
46 uint32_t irqNum; /* UART PL011 IRQ num */
47 uint32_t baudrate; /* Default baudrate */
48 uint32_t wlen; /* Default word length */
49 uint32_t parity; /* Default parity */
50 uint32_t stopBit; /* Default stop bits */
51 uint32_t uartClk; /* UART clock */
52 unsigned long physBase;
53 };
54
55 enum UartDeviceState {
56 UART_DEVICE_UNINITIALIZED = 0x0u,
57 UART_DEVICE_INITIALIZED = 0x1u,
58 };
59
60 struct UartDevice {
61 struct IDeviceIoService ioService;
62 struct UartResource resource;
63 enum UartDeviceState state; /* UART State */
64 uint32_t uartClk; /* UART clock */
65 uint32_t baudrate; /* Baudrate */
66 struct BufferFifo rxFifo;
67 };
68
69 /* Receive Status Register/Error Clear Register data */
70 #define UART_PL011_RSR_FRAMING_ERROR_MASK (1 << 0x0u) /* Framing error bit mask */
71 #define UART_PL011_RSR_PARITY_ERROR_MASK (1 << 0x1u) /* Parity error bit mask */
72 #define UART_PL011_RSR_BREAK_ERROR_MASK (1 << 0x2u) /* Break error bit mask */
73 #define UART_PL011_RSR_OVERRUN_ERROR_MASK (1 << 0x3u) /* Overrun error bit mask */
74
75 /* Receive Status Register Error Mask */
76 #define UART_PL011_RSR_RX_ERROR_MASK \
77 (UART_PL011_RSR_FRAMING_ERROR_MASK | UART_PL011_RSR_PARITY_ERROR_MASK | UART_PL011_RSR_BREAK_ERROR_MASK | \
78 UART_PL011_RSR_OVERRUN_ERROR_MASK)
79
80 #define UART_PL011_FR_CTS_MASK (1 << 0x0u) /* Clear to send bit mask */
81 #define UART_PL011_FR_DSR_MASK (1 << 0x1u) /* Data set ready bit mask */
82 #define UART_PL011_FR_DCD_MASK (1 << 0x2u) /* Data carrier detect bit mask */
83 #define UART_PL011_FR_BUSY_MASK (1 << 0x3u) /* UART busy bit mask */
84 #define UART_PL011_FR_RX_FIFO_EMPTY_MASK (1 << 0x4u) /* Receive FIFO empty bit mask */
85 #define UART_PL011_FR_TX_FIFO_FULL_MASK (1 << 0x5u) /* Transmit FIFO full bit mask */
86 #define UART_PL011_FR_RX_FIFO_FULL_MASK (1 << 0x6u) /* Receive FIFO full bit mask */
87 #define UART_PL011_FR_TX_FIFO_EMPTY_MASK (1 << 0x7u) /* Transmit FIFO empty. bit mask */
88 #define UART_PL011_FR_RI_MASK (1 << 0x8u) /* Ring indicator bit mask */
89
90 /* PL011 Line Control Register Data bits */
91 #define UART_PL011_LCR_H_BRK_MASK (1 << 0x0u) /* Send Break bit mask */
92 #define UART_PL011_LCR_H_PEN_MASK (1 << 0x1u) /* Parity enable bit mask */
93 #define UART_PL011_LCR_H_EPS_MASK (1 << 0x2u) /* Even parity select bit mask . */
94 #define UART_PL011_LCR_H_FEN_MASK (1 << 0x4u) /* Enable FIFOs bit mask */
95 #define UART_PL011_LCR_H_SPS_MASK (1 << 0x7u) /* Stick parity select bit mask */
96
97 #define UART_PL011_LCR_H_WLEN_BIT_OFFSET 0x5u /* Word length bit offset */
98 #define UART_PL011_LCR_H_WLEN_MASK (0x3u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
99
100 #define UART_PL011_WLEN_5BITS (0x0u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
101 #define UART_PL011_WLEN_6BITS (0x1u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
102 #define UART_PL011_WLEN_7BITS (0x2u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
103 #define UART_PL011_WLEN_8BITS (0x3u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
104
105 #define UART_PL011_NONE_PARITY_CHECKED 0
106
107 #define UART_PL011_LCR_H_STP2_BIT_OFFSET 0x3u /* Two stop bits select */
108
109 #define UART_PL011_STOPBIT_1 (0x0u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
110 #define UART_PL011_STOPBIT_2 (0x1u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
111
112 #define UART_PL011_LCR_H_PARITY_MASK (UART_PL011_LCR_H_PEN_MASK | UART_PL011_LCR_H_EPS_MASK | UART_PL011_LCR_H_SPS_MASK)
113
114 #define UART_PL011_LCR_H_STOPBIT_MASK (0x1u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
115
116 #define UART_PL011_DATA_FORMAT_MASK \
117 (UART_PL011_LCR_H_PARITY_MASK | UART_PL011_LCR_H_STOPBIT_MASK | UART_PL011_LCR_H_WLEN_MASK)
118
119 /* Control Register */
120 #define UART_PL011_CR_UARTEN_MASK (0x1u << 0x0u) /* Uart enable bit mask */
121 #define UART_PL011_CR_SIREN_MASK (0x1u << 0x1u) /* Sir enable bit mask */
122 #define UART_PL011_CR_SIRLP_MASK (0x1u << 0x2u) /* SIR low-power IrDA mode bit mask */
123 #define UART_PL011_CR_LBE_MASK (0x1u << 0x7u) /* Loopback enable bit mask */
124 #define UART_PL011_CR_TXE_MASK (0x1u << 0x8u) /* Transmit enable bit mask */
125 #define UART_PL011_CR_RXE_MASK (0x1u << 0x9u) /* Receive enable bit mask */
126 #define UART_PL011_CR_DTR_MASK (0x1u << 0xAu) /* Data transmit ready.bit mask */
127 #define UART_PL011_CR_RTS_MASK (0x1u << 0xBu) /* Request to send bit mask */
128 #define UART_PL011_CR_OUT1_MASK (0x1u << 0xCu) /* Out1 bit field mask */
129 #define UART_PL011_CR_OUT2_MASK (0x1u << 0xDu) /* Out2 bit field mask */
130 #define UART_PL011_CR_RTSE_MASK (0x1u << 0xEu) /* RTS hardware flow control enable bit mask */
131 #define UART_PL011_CR_CTSE_MASK (0x1u << 0xFu) /* CTS hardware flow control enable bit mask */
132
133 /* Interrupt FIFO Level Select Register Transmit bit offset */
134 #define UART_PL011_IFLS_TX_BIT_OFFSET 0x0u
135 /* Interrupt FIFO Level Select Register Receive bit offset */
136 #define UART_PL011_IFLS_RX_BIT_OFFSET 0x3u
137
138 #define UART_PL011_RX_FIFO_LVL_1_8 (0x0u << UART_PL011_IFLS_RX_BIT_OFFSET)
139 #define UART_PL011_RX_FIFO_LVL_1_4 (0x1u << UART_PL011_IFLS_RX_BIT_OFFSET)
140 #define UART_PL011_RX_FIFO_LVL_1_2 (0x2u << UART_PL011_IFLS_RX_BIT_OFFSET)
141 #define UART_PL011_RX_FIFO_LVL_3_4 (0x3u << UART_PL011_IFLS_RX_BIT_OFFSET)
142 #define UART_PL011_RX_FIFO_LVL_7_8 (0x4u << UART_PL011_IFLS_RX_BIT_OFFSET)
143
144 #define UART_PL011_TX_FIFO_LVL_1_8 (0x0u << UART_PL011_IFLS_TX_BIT_OFFSET)
145 #define UART_PL011_TX_FIFO_LVL_1_4 (0x1u << UART_PL011_IFLS_TX_BIT_OFFSET)
146 #define UART_PL011_TX_FIFO_LVL_1_2 (0x2u << UART_PL011_IFLS_TX_BIT_OFFSET)
147 #define UART_PL011_TX_FIFO_LVL_3_4 (0x3u << UART_PL011_IFLS_TX_BIT_OFFSET)
148 #define UART_PL011_TX_FIFO_LVL_7_8 (0x4u << UART_PL011_IFLS_TX_BIT_OFFSET)
149
150 /* Default register values of UART PL011 */
151 #define UART_PL011_DEFAULT_DATA_REG_VALUE (0x0u)
152 #define UART_PL011_DEFAULT_ECR_VALUE (0xFFu)
153 #define UART_PL011_DEFAULT_ILPR_VALUE (0x0u)
154 #define UART_PL011_DEFAULT_IBRD_REG_VALUE (0x0u)
155 #define UART_PL011_DEFAULT_FBRD_REG_VALUE (0x0u)
156 /* Clear UARTLCR */
157 #define UART_PL011_DEFAULT_LCR_H_VALUE (0x0u)
158 #define UART_PL011_DEFAULT_CTRL_REG_VALUE (0x0300u)
159
160 #define UART_PL011_DEFAULT_IFLS_REG_VALUE (UART_PL011_RX_FIFO_LVL_1_2 | UART_PL011_TX_FIFO_LVL_7_8)
161
162 /* Clear interrupt mask */
163 #define UART_PL011_DEFAULT_IMSC_REG_VALUE (0x0u)
164 /* Clear interrupt */
165 #define UART_PL011_DEFAULT_ICR_VALUE (0x7FFu)
166 #define UART_PL011_DEFAULT_DMACR_VALUE (0x0u)
167
168 #define FREQ_IRLPBAUD16_MIN (1420000u) /* 1.42 MHz */
169 #define FREQ_IRLPBAUD16_MAX (2120000u) /* 2.12 MHz */
170 #define SAMPLING_FACTOR (16u)
171 #define UART_PL011_FBRD_WIDTH (6u)
172
173 /**
174 * \brief ARM UART PL011 error enumeration types
175 */
176 typedef enum UartPl011Error {
177 UART_PL011_ERR_NONE = (0x0u),
178 UART_PL011_ERR_RX_FRAME = UART_PL011_RSR_FRAMING_ERROR_MASK,
179 UART_PL011_ERR_RX_PARITY = UART_PL011_RSR_PARITY_ERROR_MASK,
180 UART_PL011_ERR_RX_BREAK = UART_PL011_RSR_BREAK_ERROR_MASK,
181 UART_PL011_ERR_RX_OVERFLOW = UART_PL011_RSR_OVERRUN_ERROR_MASK,
182 UART_PL011_ERR_INVALID_ARG = (UART_PL011_RSR_RX_ERROR_MASK + 1),
183 UART_PL011_ERR_NOT_READY,
184 UART_PL011_ERR_INVALID_BAUD,
185 UART_PL011_ERR_NOT_INIT,
186 } UartPl011Error;
187
UartPl011Enable(struct UartRegisterMap * regMap)188 static inline void UartPl011Enable(struct UartRegisterMap *regMap)
189 {
190 regMap->cr |= UART_PL011_CR_UARTEN_MASK;
191 }
192
UartPl011Disable(struct UartRegisterMap * regMap)193 static inline void UartPl011Disable(struct UartRegisterMap *regMap)
194 {
195 regMap->cr &= ~UART_PL011_CR_UARTEN_MASK;
196 }
197
UartPl011IsEnabled(struct UartRegisterMap * regMap)198 static inline bool UartPl011IsEnabled(struct UartRegisterMap *regMap)
199 {
200 return (bool)(regMap->cr & UART_PL011_CR_UARTEN_MASK);
201 }
202
UartPl011IsBusy(struct UartRegisterMap * regMap)203 static inline bool UartPl011IsBusy(struct UartRegisterMap *regMap)
204 {
205 return (bool)(regMap->fr & UART_PL011_FR_BUSY_MASK);
206 }
207
208 void UartPl011SetLcrBits(struct UartRegisterMap *regMap, uint32_t bits);
209
UartPl011Write(struct UartRegisterMap * regMap,uint8_t byte)210 static inline void UartPl011Write(struct UartRegisterMap *regMap, uint8_t byte)
211 {
212 while (UartPl011IsBusy(regMap)) {}
213 regMap->dr = byte;
214 }
215
216 UartPl011Error UartPl011SetBaudrate(struct UartRegisterMap *regMap, uint32_t clk, uint32_t baudrate);
217
218 void UartPl011SetDataFormat(struct UartRegisterMap *regMap, uint32_t wordLen, uint32_t parity, uint32_t stopBits);
219
220 void UartPl011ResetRegisters(struct UartRegisterMap *regMap);
221
UartPl011EnableFifo(struct UartRegisterMap * regMap)222 static inline void UartPl011EnableFifo(struct UartRegisterMap *regMap)
223 {
224 UartPl011SetLcrBits(regMap, UART_PL011_LCR_H_FEN_MASK);
225 }
226
227 #ifdef __cplusplus
228 }
229 #endif
230 #endif /* UART_PL011_SAMPLE_H */
231