• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  \
78           | UART_PL011_RSR_PARITY_ERROR_MASK   \
79           | UART_PL011_RSR_BREAK_ERROR_MASK    \
80           | UART_PL011_RSR_OVERRUN_ERROR_MASK)
81 
82 #define UART_PL011_FR_CTS_MASK                (1 << 0x0u)  /* Clear to send bit mask */
83 #define UART_PL011_FR_DSR_MASK                (1 << 0x1u)  /* Data set ready bit mask */
84 #define UART_PL011_FR_DCD_MASK                (1 << 0x2u)  /* Data carrier detect bit mask */
85 #define UART_PL011_FR_BUSY_MASK               (1 << 0x3u)  /* UART busy bit mask */
86 #define UART_PL011_FR_RX_FIFO_EMPTY_MASK      (1 << 0x4u)  /* Receive FIFO empty bit mask */
87 #define UART_PL011_FR_TX_FIFO_FULL_MASK       (1 << 0x5u)  /* Transmit FIFO full bit mask */
88 #define UART_PL011_FR_RX_FIFO_FULL_MASK       (1 << 0x6u)  /* Receive FIFO full bit mask */
89 #define UART_PL011_FR_TX_FIFO_EMPTY_MASK      (1 << 0x7u)  /* Transmit FIFO empty. bit mask */
90 #define UART_PL011_FR_RI_MASK                 (1 << 0x8u)  /* Ring indicator  bit mask */
91 
92 /* PL011 Line Control Register Data bits */
93 #define UART_PL011_LCR_H_BRK_MASK             (1 << 0x0u)  /* Send Break bit mask */
94 #define UART_PL011_LCR_H_PEN_MASK             (1 << 0x1u)  /* Parity enable bit mask */
95 #define UART_PL011_LCR_H_EPS_MASK             (1 << 0x2u)  /* Even parity select bit mask . */
96 #define UART_PL011_LCR_H_FEN_MASK             (1 << 0x4u)  /* Enable FIFOs bit mask */
97 #define UART_PL011_LCR_H_SPS_MASK             (1 << 0x7u)  /* Stick parity select bit mask */
98 
99 #define UART_PL011_LCR_H_WLEN_BIT_OFFSET      0x5u  /* Word length  bit offset */
100 #define UART_PL011_LCR_H_WLEN_MASK (  \
101             0x3u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
102 
103 #define UART_PL011_WLEN_5BITS                 (0x0u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
104 #define UART_PL011_WLEN_6BITS                 (0x1u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
105 #define UART_PL011_WLEN_7BITS                 (0x2u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
106 #define UART_PL011_WLEN_8BITS                 (0x3u << UART_PL011_LCR_H_WLEN_BIT_OFFSET)
107 
108 #define UART_PL011_NONE_PARITY_CHECKED  0
109 
110 #define UART_PL011_LCR_H_STP2_BIT_OFFSET        0x3u  /* Two stop bits select */
111 
112 #define UART_PL011_STOPBIT_1                  (0x0u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
113 #define UART_PL011_STOPBIT_2                  (0x1u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
114 
115 #define UART_PL011_LCR_H_PARITY_MASK (         \
116               UART_PL011_LCR_H_PEN_MASK        \
117             | UART_PL011_LCR_H_EPS_MASK        \
118             | UART_PL011_LCR_H_SPS_MASK)
119 
120 #define UART_PL011_LCR_H_STOPBIT_MASK         (0x1u << UART_PL011_LCR_H_STP2_BIT_OFFSET)
121 
122 #define UART_PL011_DATA_FORMAT_MASK (          \
123               UART_PL011_LCR_H_PARITY_MASK     \
124             | UART_PL011_LCR_H_STOPBIT_MASK    \
125             | UART_PL011_LCR_H_WLEN_MASK)
126 
127 /* Control Register */
128 #define UART_PL011_CR_UARTEN_MASK           (0x1u << 0x0u)  /* Uart enable bit mask */
129 #define UART_PL011_CR_SIREN_MASK            (0x1u << 0x1u)  /* Sir enable bit mask */
130 #define UART_PL011_CR_SIRLP_MASK            (0x1u << 0x2u)  /* SIR low-power IrDA mode bit mask */
131 #define UART_PL011_CR_LBE_MASK              (0x1u << 0x7u)  /* Loopback enable bit mask */
132 #define UART_PL011_CR_TXE_MASK              (0x1u << 0x8u)  /* Transmit enable bit mask */
133 #define UART_PL011_CR_RXE_MASK              (0x1u << 0x9u)  /* Receive enable bit mask */
134 #define UART_PL011_CR_DTR_MASK              (0x1u << 0xAu)  /* Data transmit ready.bit mask */
135 #define UART_PL011_CR_RTS_MASK              (0x1u << 0xBu)  /* Request to send bit mask */
136 #define UART_PL011_CR_OUT1_MASK             (0x1u << 0xCu)  /* Out1 bit field mask */
137 #define UART_PL011_CR_OUT2_MASK             (0x1u << 0xDu)  /* Out2 bit field mask */
138 #define UART_PL011_CR_RTSE_MASK             (0x1u << 0xEu)  /* RTS hardware flow control enable bit mask */
139 #define UART_PL011_CR_CTSE_MASK             (0x1u << 0xFu)  /* CTS hardware flow control enable bit mask */
140 
141 
142 /* Interrupt FIFO Level Select Register Transmit bit offset */
143 #define UART_PL011_IFLS_TX_BIT_OFFSET           0x0u
144 /* Interrupt FIFO Level Select Register Receive bit offset */
145 #define UART_PL011_IFLS_RX_BIT_OFFSET           0x3u
146 
147 #define UART_PL011_RX_FIFO_LVL_1_8          (0x0u << UART_PL011_IFLS_RX_BIT_OFFSET)
148 #define UART_PL011_RX_FIFO_LVL_1_4          (0x1u << UART_PL011_IFLS_RX_BIT_OFFSET)
149 #define UART_PL011_RX_FIFO_LVL_1_2          (0x2u << UART_PL011_IFLS_RX_BIT_OFFSET)
150 #define UART_PL011_RX_FIFO_LVL_3_4          (0x3u << UART_PL011_IFLS_RX_BIT_OFFSET)
151 #define UART_PL011_RX_FIFO_LVL_7_8          (0x4u << UART_PL011_IFLS_RX_BIT_OFFSET)
152 
153 #define UART_PL011_TX_FIFO_LVL_1_8          (0x0u << UART_PL011_IFLS_TX_BIT_OFFSET)
154 #define UART_PL011_TX_FIFO_LVL_1_4          (0x1u << UART_PL011_IFLS_TX_BIT_OFFSET)
155 #define UART_PL011_TX_FIFO_LVL_1_2          (0x2u << UART_PL011_IFLS_TX_BIT_OFFSET)
156 #define UART_PL011_TX_FIFO_LVL_3_4          (0x3u << UART_PL011_IFLS_TX_BIT_OFFSET)
157 #define UART_PL011_TX_FIFO_LVL_7_8          (0x4u << UART_PL011_IFLS_TX_BIT_OFFSET)
158 
159 /* Default register values of UART PL011 */
160 #define UART_PL011_DEFAULT_DATA_REG_VALUE     (0x0u)
161 #define UART_PL011_DEFAULT_ECR_VALUE          (0xFFu)
162 #define UART_PL011_DEFAULT_ILPR_VALUE         (0x0u)
163 #define UART_PL011_DEFAULT_IBRD_REG_VALUE     (0x0u)
164 #define UART_PL011_DEFAULT_FBRD_REG_VALUE     (0x0u)
165 /* Clear UARTLCR */
166 #define UART_PL011_DEFAULT_LCR_H_VALUE        (0x0u)
167 #define UART_PL011_DEFAULT_CTRL_REG_VALUE     (0x0300u)
168 
169 #define UART_PL011_DEFAULT_IFLS_REG_VALUE (              \
170             UART_PL011_RX_FIFO_LVL_1_2                   \
171             | UART_PL011_TX_FIFO_LVL_7_8)
172 
173 /* Clear interrupt mask */
174 #define UART_PL011_DEFAULT_IMSC_REG_VALUE     (0x0u)
175 /* Clear interrupt */
176 #define UART_PL011_DEFAULT_ICR_VALUE          (0x7FFu)
177 #define UART_PL011_DEFAULT_DMACR_VALUE        (0x0u)
178 
179 #define FREQ_IRLPBAUD16_MIN                   (1420000u)     /* 1.42 MHz */
180 #define FREQ_IRLPBAUD16_MAX                   (2120000u)     /* 2.12 MHz */
181 #define SAMPLING_FACTOR                       (16u)
182 #define UART_PL011_FBRD_WIDTH                 (6u)
183 
184 /**
185  * \brief ARM UART PL011 error enumeration types
186  */
187 typedef enum UartPl011Error {
188     UART_PL011_ERR_NONE = (0x0u),
189     UART_PL011_ERR_RX_FRAME = UART_PL011_RSR_FRAMING_ERROR_MASK,
190     UART_PL011_ERR_RX_PARITY = UART_PL011_RSR_PARITY_ERROR_MASK,
191     UART_PL011_ERR_RX_BREAK = UART_PL011_RSR_BREAK_ERROR_MASK,
192     UART_PL011_ERR_RX_OVERFLOW = UART_PL011_RSR_OVERRUN_ERROR_MASK,
193     UART_PL011_ERR_INVALID_ARG = (UART_PL011_RSR_RX_ERROR_MASK + 1),
194     UART_PL011_ERR_NOT_READY,
195     UART_PL011_ERR_INVALID_BAUD,
196     UART_PL011_ERR_NOT_INIT,
197 } UartPl011Error;
198 
UartPl011Enable(struct UartRegisterMap * regMap)199 static inline void UartPl011Enable(struct UartRegisterMap *regMap)
200 {
201     regMap->cr |= UART_PL011_CR_UARTEN_MASK;
202 }
203 
UartPl011Disable(struct UartRegisterMap * regMap)204 static inline void UartPl011Disable(struct UartRegisterMap *regMap)
205 {
206     regMap->cr &= ~UART_PL011_CR_UARTEN_MASK;
207 }
208 
UartPl011IsEnabled(struct UartRegisterMap * regMap)209 static inline bool UartPl011IsEnabled(struct UartRegisterMap *regMap)
210 {
211     return (bool)(regMap->cr & UART_PL011_CR_UARTEN_MASK);
212 }
213 
UartPl011IsBusy(struct UartRegisterMap * regMap)214 static inline bool UartPl011IsBusy(struct UartRegisterMap *regMap)
215 {
216     return (bool)(regMap->fr & UART_PL011_FR_BUSY_MASK);
217 }
218 
219 void UartPl011SetLcrBits(struct UartRegisterMap *regMap, uint32_t bits);
220 
UartPl011Write(struct UartRegisterMap * regMap,uint8_t byte)221 static inline void UartPl011Write(struct UartRegisterMap *regMap, uint8_t byte)
222 {
223     while (UartPl011IsBusy(regMap)) { }
224     regMap->dr = byte;
225 }
226 
227 UartPl011Error UartPl011SetBaudrate(struct UartRegisterMap *regMap, uint32_t clk, uint32_t baudrate);
228 
229 void UartPl011SetDataFormat(struct UartRegisterMap *regMap, uint32_t wordLen, uint32_t parity, uint32_t stopBits);
230 
231 void UartPl011ResetRegisters(struct UartRegisterMap *regMap);
232 
UartPl011EnableFifo(struct UartRegisterMap * regMap)233 static inline void UartPl011EnableFifo(struct UartRegisterMap *regMap)
234 {
235     UartPl011SetLcrBits(regMap, UART_PL011_LCR_H_FEN_MASK);
236 }
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 #endif /* UART_PL011_SAMPLE_H */
242 
243