1 /*
2  * Copyright (c) 2012 Kent Ryhorchuk
3  * Copyright (c) 2015 Travis Geiselbrecht
4  *
5  * Use of this source code is governed by a MIT-style
6  * license that can be found in the LICENSE file or at
7  * https://opensource.org/licenses/MIT
8  */
9 #include <stdarg.h>
10 #include <lk/reg.h>
11 #include <lk/debug.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #include <lk/err.h>
15 #include <lib/cbuf.h>
16 #include <kernel/thread.h>
17 #include <platform/debug.h>
18 #include <arch/ops.h>
19 #include <dev/uart.h>
20 #include <target/debugconfig.h>
21 #include <platform/stm32.h>
22 #include <arch/arm/cm.h>
23 
24 #define DEFAULT_FLOWCONTROL UART_HWCONTROL_NONE
25 #define DEFAULT_BAUDRATE 115200
26 #define DEFAULT_RXBUF_SIZE 16
27 
28 #define NUM_UARTS 8
29 
30 struct uart_instance {
31     UART_HandleTypeDef handle;
32     cbuf_t rx_buf;
33 };
34 
35 #if ENABLE_UART1
36 static struct uart_instance uart1;
37 #ifndef UART1_FLOWCONTROL
38 #define UART1_FLOWCONTROL DEFAULT_FLOWCONTROL
39 #endif
40 #ifndef UART1_BAUDRATE
41 #define UART1_BAUDRATE DEFAULT_BAUDRATE
42 #endif
43 #ifndef UART1_RXBUF_SIZE
44 #define UART1_RXBUF_SIZE DEFAULT_RXBUF_SIZE
45 #endif
46 #endif
47 
48 #if ENABLE_UART3
49 static struct uart_instance uart3;
50 #ifndef UART3_FLOWCONTROL
51 #define UART3_FLOWCONTROL DEFAULT_FLOWCONTROL
52 #endif
53 #ifndef UART3_BAUDRATE
54 #define UART3_BAUDRATE DEFAULT_BAUDRATE
55 #endif
56 #ifndef UART3_RXBUF_SIZE
57 #define UART3_RXBUF_SIZE DEFAULT_RXBUF_SIZE
58 #endif
59 #endif
60 
61 #if ENABLE_UART2 || ENABLE_UART4 || ENABLE_UART5 || ENABLE_UART6 || ENABLE_UART7 || ENABLE_UART8
62 #error add support for additional uarts
63 #endif
64 
65 static struct uart_instance *const uart[NUM_UARTS + 1] = {
66 #if ENABLE_UART1
67     [1] = &uart1,
68 #endif
69 #if ENABLE_UART3
70     [3] = &uart3,
71 #endif
72 };
73 
74 // This function is called by HAL_UART_Init().
HAL_UART_MspInit(UART_HandleTypeDef * huart)75 void HAL_UART_MspInit(UART_HandleTypeDef *huart) {
76     RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
77 
78     /* Select SysClk as source of UART clocks */
79     switch ((uintptr_t)huart->Instance) {
80         case (uintptr_t)USART1:
81             RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
82             RCC_PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
83             HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
84 
85             __HAL_RCC_USART1_CLK_ENABLE();
86             break;
87         case (uintptr_t)USART3:
88             RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
89             RCC_PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_SYSCLK;
90             HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
91 
92             __HAL_RCC_USART3_CLK_ENABLE();
93             break;
94         default:
95             panic("unimplemented clock set up for uart\n");
96     }
97 }
98 
usart_init_early(struct uart_instance * u,USART_TypeDef * usart,uint32_t baud,uint16_t flowcontrol)99 static void usart_init_early(struct uart_instance *u, USART_TypeDef *usart, uint32_t baud, uint16_t flowcontrol) {
100     u->handle.Instance = usart;
101     u->handle.Init.BaudRate = baud;
102     u->handle.Init.WordLength = UART_WORDLENGTH_8B;
103     u->handle.Init.StopBits = UART_STOPBITS_1;
104     u->handle.Init.Parity = UART_PARITY_NONE;
105     u->handle.Init.Mode = UART_MODE_TX_RX;
106     u->handle.Init.HwFlowCtl  = flowcontrol;
107     u->handle.Init.OverSampling = UART_OVERSAMPLING_8;
108     HAL_UART_Init(&u->handle);
109 }
110 
usart_init(struct uart_instance * u,USART_TypeDef * usart,uint irqn,size_t rxsize)111 static void usart_init(struct uart_instance *u, USART_TypeDef *usart, uint irqn, size_t rxsize) {
112     cbuf_initialize(&u->rx_buf, rxsize);
113 
114     /* Enable the UART Parity Error Interrupt */
115     __HAL_UART_ENABLE_IT(&u->handle, UART_IT_PE);
116 
117     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
118     __HAL_UART_ENABLE_IT(&u->handle, UART_IT_ERR);
119 
120     /* Enable the UART Data Register not empty Interrupt */
121     __HAL_UART_ENABLE_IT(&u->handle, UART_IT_RXNE);
122 
123     HAL_NVIC_EnableIRQ(irqn);
124 }
125 
uart_init_early(void)126 void uart_init_early(void) {
127 #if ENABLE_UART1
128     usart_init_early(uart[1], USART1, UART1_BAUDRATE, UART1_FLOWCONTROL);
129 #endif
130 #if ENABLE_UART3
131     usart_init_early(uart[3], USART3, UART3_BAUDRATE, UART3_FLOWCONTROL);
132 #endif
133 }
134 
uart_init(void)135 void uart_init(void) {
136 #ifdef ENABLE_UART1
137     usart_init(uart[1], USART1, USART1_IRQn, UART1_RXBUF_SIZE);
138 #endif
139 #ifdef ENABLE_UART3
140     usart_init(uart[3], USART3, USART3_IRQn, UART3_RXBUF_SIZE);
141 #endif
142 }
143 
stm32_usart_shared_irq(struct uart_instance * u,const unsigned int id)144 static void stm32_usart_shared_irq(struct uart_instance *u, const unsigned int id) {
145     bool resched = false;
146 
147     arm_cm_irq_entry();
148 
149     /* UART parity error interrupt occurred -------------------------------------*/
150     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_PE) != RESET)) {
151         __HAL_UART_CLEAR_PEFLAG(&u->handle);
152 
153         printf("UART PARITY ERROR\n");
154     }
155 
156     /* UART frame error interrupt occurred --------------------------------------*/
157     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
158         __HAL_UART_CLEAR_FEFLAG(&u->handle);
159 
160         printf("UART FRAME ERROR\n");
161     }
162 
163     /* UART noise error interrupt occurred --------------------------------------*/
164     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
165         __HAL_UART_CLEAR_NEFLAG(&u->handle);
166 
167         printf("UART NOISE ERROR\n");
168     }
169 
170     /* UART Over-Run interrupt occurred -----------------------------------------*/
171     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_ERR) != RESET)) {
172         __HAL_UART_CLEAR_OREFLAG(&u->handle);
173 
174         printf("UART OVERRUN ERROR\n");
175     }
176 
177     /* UART in mode Receiver ---------------------------------------------------*/
178     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_RXNE) != RESET)) {
179 
180         /* we got a character */
181         uint8_t c = (uint8_t)(u->handle.Instance->RDR & 0xff);
182 
183         cbuf_t *target_buf = &u->rx_buf;
184 
185 #if CONSOLE_HAS_INPUT_BUFFER
186         if (id == DEBUG_UART) {
187             target_buf = &console_input_cbuf;
188         }
189 #endif
190 
191         if (cbuf_write_char(target_buf, c, false) != 1) {
192             printf("WARNING: uart cbuf overrun!\n");
193         }
194         resched = true;
195 
196         /* Clear RXNE interrupt flag */
197         __HAL_UART_SEND_REQ(&u->handle, UART_RXDATA_FLUSH_REQUEST);
198     }
199 
200     /* UART in mode Transmitter ------------------------------------------------*/
201     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_TXE) != RESET)) {
202         ;
203     }
204 
205     /* UART in mode Transmitter (transmission end) -----------------------------*/
206     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_TC) != RESET)) {
207         ;
208     }
209 
210     arm_cm_irq_exit(resched);
211 }
212 
213 #if ENABLE_UART1
stm32_USART1_IRQ(void)214 void stm32_USART1_IRQ(void) {
215     stm32_usart_shared_irq(uart[1], 1);
216 }
217 #endif
218 
219 #if ENABLE_UART3
stm32_USART3_IRQ(void)220 void stm32_USART3_IRQ(void) {
221     stm32_usart_shared_irq(uart[3], 3);
222 }
223 #endif
224 
uart_putc(int port,char c)225 int uart_putc(int port, char c) {
226     struct uart_instance *u = uart[port];
227     if (port < 0 || port > NUM_UARTS || !u)
228         return ERR_BAD_HANDLE;
229 
230     while (__HAL_UART_GET_FLAG(&u->handle, UART_FLAG_TXE) == RESET)
231         ;
232     u->handle.Instance->TDR = (c & (uint8_t)0xFF);
233 
234     return 1;
235 }
236 
uart_getc(int port,bool wait)237 int uart_getc(int port, bool wait) {
238     struct uart_instance *u = uart[port];
239     if (port < 0 || port > NUM_UARTS || !u)
240         return ERR_BAD_HANDLE;
241 
242     char c;
243     if (cbuf_read_char(&u->rx_buf, &c, wait) == 0)
244         return ERR_IO;
245     return c;
246 }
247 
uart_pputc(int port,char c)248 int uart_pputc(int port, char c) {
249     return uart_putc(port, c);
250 }
251 
uart_pgetc(int port)252 int uart_pgetc(int port) {
253     struct uart_instance *u = uart[port];
254     if (port < 0 || port > NUM_UARTS || !u)
255         return ERR_BAD_HANDLE;
256 
257     if ((__HAL_UART_GET_IT(&u->handle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&u->handle, UART_IT_RXNE) != RESET)) {
258         uint8_t c = (uint8_t)(u->handle.Instance->RDR & 0xff);
259         return c;
260     }
261     return ERR_IO;
262 }
263 
uart_flush_tx(int port)264 void uart_flush_tx(int port) {}
265 
uart_flush_rx(int port)266 void uart_flush_rx(int port) {}
267 
uart_init_port(int port,uint baud)268 void uart_init_port(int port, uint baud) {
269     // TODO - later
270     PANIC_UNIMPLEMENTED;
271 }
272