• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "stm32mp1_uart_hw.h"
17 
18 #include "los_magickey.h"
19 #include "console.h"
20 
21 // offset
22 #define USART_CR1       (0x00)
23 #define USART_CR2       (0x04)
24 #define USART_CR3       (0x08)
25 #define USART_BRR       (0x0C)
26 #define USART_GTPR      (0x10)
27 #define USART_RTOR      (0x14)
28 #define USART_RQR       (0x18)
29 #define USART_ISR       (0x1C)
30 #define USART_ICR       (0x20)
31 #define USART_RDR		(0x24)
32 #define USART_TDR		(0x28)
33 #define USART_PRESC     (0x2C)
34 
35 #define USART_CR1_EN        BIT(0)  // 串口使能
36 #define USART_CR1_RE        BIT(2)  // 串口接收使能
37 #define USART_CR1_TE        BIT(3)  // 串口发送使能
38 #define USART_CR1_RXNEIE    BIT(5)  // 串口接收中断使能
39 #define USART_CR1_FIFOEN    BIT(29) // fifo模式使能
40 
41 #define USART_ISR_TXE   BIT(7) // 该位为 1 表示可以写
42 #define USART_ISR_RXNE  BIT(5) // 该位为 1 表示可读
43 
44 /* Parity control enable */
45 #define USART_CR1_PCE       BIT(10) // 串口校验使能
46 #define USART_CR1_PS        BIT(9)
47 
48 /* word length */
49 #define USART_CR1_M0        BIT(12)
50 #define USART_CR1_M1        BIT(28)
51 #define USART_CR1_WL_MASK   (USART_CR1_M0 | USART_CR1_M1)
52 #define USART_CR1_WL_8B     (0)
53 #define USART_CR1_WL_9B     (USART_CR1_M0)
54 #define USART_CR1_WL_7B     (USART_CR1_M1)
55 
56 /* stop bit */
57 #define USART_CR2_STOP_OFFSET   (12)
58 #define USART_CR2_STOP_MASK     ((0x3) << USART_CR2_STOP_OFFSET)
59 #define USART_CR2_STOP_1P       ((0x0) << USART_CR2_STOP_OFFSET)
60 #define USART_CR2_STOP_P5       ((0x1) << USART_CR2_STOP_OFFSET)
61 #define USART_CR2_STOP_2P       ((0x2) << USART_CR2_STOP_OFFSET)
62 #define USART_CR2_STOP_1P5      ((0x3) << USART_CR2_STOP_OFFSET)
63 
RegRead(void volatile * base,uint32_t reg)64 static inline uint32_t RegRead(void volatile *base, uint32_t reg)
65 {
66     return OSAL_READL((uintptr_t)base + reg);
67 }
68 
RegWrite(void volatile * base,uint32_t reg,uint32_t val)69 static inline void RegWrite(void volatile *base, uint32_t reg, uint32_t val)
70 {
71     OSAL_WRITEL(val, (uintptr_t)base + reg);
72 }
73 
Mp1xxUartDump(struct Mp1xxUart * uart)74 void Mp1xxUartDump(struct Mp1xxUart *uart)
75 {
76 #ifdef STM32MP1_UART_DEBUG
77     dprintf("-------------------------------------\r\n");
78     dprintf("USART_CR1 : %#x.\r\n", RegRead(uart->base, USART_CR1));
79     dprintf("USART_CR2 : %#x.\r\n", RegRead(uart->base, USART_CR2));
80     dprintf("USART_CR3 : %#x.\r\n", RegRead(uart->base, USART_CR3));
81     dprintf("USART_BRR : %#x.\r\n", RegRead(uart->base, USART_BRR));
82     dprintf("USART_GTPR : %#x.\r\n", RegRead(uart->base, USART_GTPR));
83     dprintf("USART_RTOR : %#x.\r\n", RegRead(uart->base, USART_RTOR));
84     dprintf("USART_ISR : %#x.\r\n", RegRead(uart->base, USART_ISR));
85     dprintf("USART_ICR : %#x.\r\n", RegRead(uart->base, USART_ICR));
86     dprintf("USART_RDR : %#x.\r\n", RegRead(uart->base, USART_RDR));
87     dprintf("USART_TDR : %#x.\r\n", RegRead(uart->base, USART_TDR));
88     dprintf("USART_PRESC : %#x.\r\n", RegRead(uart->base, USART_PRESC));
89     dprintf("-------------------------------------\r\n");
90 #else
91     (void)uart;
92 #endif
93 }
94 
Mp1xxUartHwRxEnable(struct Mp1xxUart * uart,int enable)95 int32_t Mp1xxUartHwRxEnable(struct Mp1xxUart *uart, int enable)
96 {
97     uint32_t val;
98 
99     val = RegRead(uart->base, USART_CR1);
100 
101     if (enable) {
102         val |= USART_CR1_RXNEIE;
103     } else {
104         val &= ~USART_CR1_RXNEIE;
105     }
106 
107     RegWrite(uart->base, USART_CR1, val);
108 
109     return 0;
110 }
111 
Mp1xxUartHwPutc(void * base,char c)112 void Mp1xxUartHwPutc(void *base, char c)
113 {
114     while ((RegRead(base, USART_ISR) & USART_ISR_TXE) == 0) {};
115     RegWrite(base, USART_TDR, c);
116 }
117 
Mp1xxUartHwPuts(void * base,char * s,uint32_t len)118 void Mp1xxUartHwPuts(void *base, char *s, uint32_t len)
119 {
120     uint32_t i;
121 
122     for (i = 0; i < len; i++) {
123         if (*(s + i) == '\n') {
124             Mp1xxUartHwPutc(base, '\r');
125         }
126         Mp1xxUartHwPutc(base, *(s + i));
127     }
128 }
129 
Mp1xxUartHwGetIsr(struct Mp1xxUart * uart)130 uint32_t Mp1xxUartHwGetIsr(struct Mp1xxUart *uart)
131 {
132     return RegRead(uart->base, USART_ISR);
133 }
134 
135 // enable uart, and enable tx/rx mode
Mp1xxUartHwEnable(struct Mp1xxUart * uart,int enable)136 int32_t Mp1xxUartHwEnable(struct Mp1xxUart *uart, int enable)
137 {
138     uint32_t val;
139 
140     val = RegRead(uart->base, USART_CR1);
141     val &= ~(USART_CR1_EN | USART_CR1_RE | USART_CR1_TE);
142 
143     if (enable) {
144         val |= (USART_CR1_EN | USART_CR1_RE | USART_CR1_TE);
145     } else {
146         val &= ~(USART_CR1_EN | USART_CR1_RE | USART_CR1_TE);
147     }
148 
149     RegWrite(uart->base, USART_CR1, val);
150 
151     return 0;
152 }
153 
Mp1xxUartHwFifoEnable(struct Mp1xxUart * uart,int enable)154 int32_t Mp1xxUartHwFifoEnable(struct Mp1xxUart *uart, int enable)
155 {
156     uint32_t val;
157 
158     val = RegRead(uart->base, USART_CR1);
159 
160     if (enable) {
161         val |= USART_CR1_FIFOEN; // fifo mode enable
162     } else {
163         val &= ~USART_CR1_FIFOEN; // fifo mode disable
164     }
165 
166     RegWrite(uart->base, USART_CR1, val);
167 
168     return 0;
169 }
170 
171 // set data bits
Mp1xxUartHwDataBits(struct Mp1xxUart * uart,uint32_t bits)172 int32_t Mp1xxUartHwDataBits(struct Mp1xxUart *uart, uint32_t bits)
173 {
174     uint32_t val;
175 
176     val = RegRead(uart->base, USART_CR1);
177 
178     val &= ~USART_CR1_WL_MASK;
179 
180     switch (bits) {
181         case UART_HW_DATABIT_8:
182             val |= USART_CR1_WL_8B;
183             break;
184         case UART_HW_DATABIT_7:
185             val |= USART_CR1_WL_7B;
186             break;
187         default:
188             HDF_LOGE("only support 8b.\r\n");
189             break;
190     }
191 
192     RegWrite(uart->base, USART_CR1, val);
193 
194     return 0;
195 }
196 
Mp1xxUartHwStopBits(struct Mp1xxUart * uart,uint32_t bits)197 int32_t Mp1xxUartHwStopBits(struct Mp1xxUart *uart, uint32_t bits)
198 {
199     uint32_t val;
200 
201     val = RegRead(uart->base, USART_CR2);
202 
203     val &= ~USART_CR2_STOP_MASK;
204 
205     if (bits == UART_HW_STOPBIT_1P5) {
206         val |= USART_CR2_STOP_1P5;
207     } else if (bits == UART_HW_STOPBIT_2) {
208         val |= USART_CR2_STOP_2P;
209     }
210 
211     RegWrite(uart->base, USART_CR2, val);
212 
213     return 0;
214 }
215 
Mp1xxUartHwParity(struct Mp1xxUart * uart,uint32_t parity)216 int32_t Mp1xxUartHwParity(struct Mp1xxUart *uart, uint32_t parity)
217 {
218     uint32_t val;
219     val = RegRead(uart->base, USART_CR1);
220 
221     val &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 | USART_CR1_M0);
222 
223     switch (parity) {
224         case UART_HW_PARITY_NONE:
225             break;
226 
227         // if enable parity, use 9 bit mode
228         case UART_HW_PARITY_ODD:
229             val |= (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0);
230             break;
231         case UART_HW_PARITY_EVEN:
232             val |= (USART_CR1_PCE | USART_CR1_M0);
233             break;
234         default:
235             break;
236     }
237 
238     RegWrite(uart->base, USART_CR1, val);
239 
240     return 0;
241 }
242 
Mp1xxUartHwBaudrate(struct Mp1xxUart * uart,uint32_t baudrate)243 int32_t Mp1xxUartHwBaudrate(struct Mp1xxUart *uart, uint32_t baudrate)
244 {
245     uint32_t val;
246     uint32_t sorce_rate = uart->clock_rate;
247 
248     val = (sorce_rate + baudrate - 1) / baudrate;
249     RegWrite(uart->base, USART_BRR, val);
250 
251     return 0;
252 }
253 
254 #define FIFO_SIZE    (128)
Mp1xxUartIrqHandler(uint32_t irq,void * data)255 uint32_t Mp1xxUartIrqHandler(uint32_t irq, void *data)
256 {
257     (void)irq;
258 
259     unsigned char ch = 0;
260     char buf[FIFO_SIZE];
261     uint32_t count = 0;
262     int max_count = FIFO_SIZE;
263 
264     struct Mp1xxUart *uart = (struct Mp1xxUart *)data;
265     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
266 
267     if (Mp1xxUartHwGetIsr(uart) & USART_ISR_RXNE) {
268         do {
269             // read data from RDR
270             ch = RegRead(uart->base, USART_RDR);
271 
272             // add data to buffer
273             buf[count++] = (char)ch;
274 
275             if (CheckMagicKey(buf[count - 1], CONSOLE_SERIAL)) {
276                 goto end;
277             }
278         } while ((Mp1xxUartHwGetIsr(uart) & USART_ISR_RXNE) && (max_count-- > 0));
279 
280         if (rx_ctl->stm32mp1_uart_recv_hook) {
281             rx_ctl->stm32mp1_uart_recv_hook(uart, buf, count);
282         }
283     }
284 
285 end:
286     return 0;
287 }
288