]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/serial_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32F3 / serial_api.c
1 /* mbed Microcontroller Library
2  *******************************************************************************
3  * Copyright (c) 2014, STMicroelectronics
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  * 3. Neither the name of STMicroelectronics nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *******************************************************************************
29  */
30 #include "mbed_assert.h"
31 #include "serial_api.h"
32
33 #if DEVICE_SERIAL
34
35 #include "cmsis.h"
36 #include "pinmap.h"
37 #include <string.h>
38 #include "PeripheralPins.h"
39
40 #define UART_NUM (5)
41
42 static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0};
43
44 static uart_irq_handler irq_handler;
45
46 UART_HandleTypeDef UartHandle;
47
48 int stdio_uart_inited = 0;
49 serial_t stdio_uart;
50
51 static void init_uart(serial_t *obj)
52 {
53     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
54
55     UartHandle.Init.BaudRate   = obj->baudrate;
56     UartHandle.Init.WordLength = obj->databits;
57     UartHandle.Init.StopBits   = obj->stopbits;
58     UartHandle.Init.Parity     = obj->parity;
59     UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
60
61     if (obj->pin_rx == NC) {
62         UartHandle.Init.Mode = UART_MODE_TX;
63     } else if (obj->pin_tx == NC) {
64         UartHandle.Init.Mode = UART_MODE_RX;
65     } else {
66         UartHandle.Init.Mode = UART_MODE_TX_RX;
67     }
68
69     // Disable the reception overrun detection
70     UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
71     UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
72
73     HAL_UART_Init(&UartHandle);
74 }
75
76 void serial_init(serial_t *obj, PinName tx, PinName rx)
77 {
78     // Determine the UART to use (UART_1, UART_2, ...)
79     UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
80     UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
81
82     // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
83     obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
84     MBED_ASSERT(obj->uart != (UARTName)NC);
85
86     // Enable USART clock + switch to SystemClock
87     if (obj->uart == UART_1) {
88         __USART1_CLK_ENABLE();
89         __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK);
90         obj->index = 0;
91     }
92     if (obj->uart == UART_2) {
93         __USART2_CLK_ENABLE();
94         __HAL_RCC_USART2_CONFIG(RCC_USART2CLKSOURCE_SYSCLK);
95         obj->index = 1;
96     }
97     if (obj->uart == UART_3) {
98         __USART3_CLK_ENABLE();
99         __HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK);
100         obj->index = 2;
101     }
102 #if defined(UART4_BASE)
103     if (obj->uart == UART_4) {
104         __UART4_CLK_ENABLE();
105         __HAL_RCC_UART4_CONFIG(RCC_UART4CLKSOURCE_SYSCLK);
106         obj->index = 3;
107     }
108 #endif
109 #if defined(UART5_BASE)
110     if (obj->uart == UART_5) {
111         __UART5_CLK_ENABLE();
112         __HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_SYSCLK);
113         obj->index = 4;
114     }
115 #endif
116
117     // Configure the UART pins
118     pinmap_pinout(tx, PinMap_UART_TX);
119     pinmap_pinout(rx, PinMap_UART_RX);
120     if (tx != NC) {
121         pin_mode(tx, PullUp);
122     }
123     if (rx != NC) {
124         pin_mode(rx, PullUp);
125     }
126
127     // Configure UART
128     obj->baudrate = 9600;
129     obj->databits = UART_WORDLENGTH_8B;
130     obj->stopbits = UART_STOPBITS_1;
131     obj->parity   = UART_PARITY_NONE;
132
133     obj->pin_tx = tx;
134     obj->pin_rx = rx;
135
136     init_uart(obj);
137
138     // For stdio management
139     if (obj->uart == STDIO_UART) {
140         stdio_uart_inited = 1;
141         memcpy(&stdio_uart, obj, sizeof(serial_t));
142     }
143 }
144
145 void serial_free(serial_t *obj)
146 {
147     // Reset UART and disable clock
148     if (obj->uart == UART_1) {
149         __USART1_FORCE_RESET();
150         __USART1_RELEASE_RESET();
151         __USART1_CLK_DISABLE();
152     }
153     if (obj->uart == UART_2) {
154         __USART2_FORCE_RESET();
155         __USART2_RELEASE_RESET();
156         __USART2_CLK_DISABLE();
157     }
158     if (obj->uart == UART_3) {
159         __USART3_FORCE_RESET();
160         __USART3_RELEASE_RESET();
161         __USART3_CLK_DISABLE();
162     }
163 #if defined(UART4_BASE)
164     if (obj->uart == UART_4) {
165         __UART4_FORCE_RESET();
166         __UART4_RELEASE_RESET();
167         __UART4_CLK_DISABLE();
168     }
169 #endif
170 #if defined(UART5_BASE)
171     if (obj->uart == UART_5) {
172         __UART5_FORCE_RESET();
173         __UART5_RELEASE_RESET();
174         __UART5_CLK_DISABLE();
175     }
176 #endif
177
178     // Configure GPIOs
179     pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
180     pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
181
182     serial_irq_ids[obj->index] = 0;
183 }
184
185 void serial_baud(serial_t *obj, int baudrate)
186 {
187     obj->baudrate = baudrate;
188     init_uart(obj);
189 }
190
191 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
192 {
193     if (data_bits == 9) {
194         obj->databits = UART_WORDLENGTH_9B;
195     } else {
196         obj->databits = UART_WORDLENGTH_8B;
197     }
198
199     switch (parity) {
200         case ParityOdd:
201         case ParityForced0:
202             obj->parity = UART_PARITY_ODD;
203             break;
204         case ParityEven:
205         case ParityForced1:
206             obj->parity = UART_PARITY_EVEN;
207             break;
208         default: // ParityNone
209             obj->parity = UART_PARITY_NONE;
210             break;
211     }
212
213     if (stop_bits == 2) {
214         obj->stopbits = UART_STOPBITS_2;
215     } else {
216         obj->stopbits = UART_STOPBITS_1;
217     }
218
219     init_uart(obj);
220 }
221
222 /******************************************************************************
223  * INTERRUPTS HANDLING
224  ******************************************************************************/
225
226 static void uart_irq(UARTName name, int id)
227 {
228     UartHandle.Instance = (USART_TypeDef *)name;
229     if (serial_irq_ids[id] != 0) {
230         if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
231             irq_handler(serial_irq_ids[id], TxIrq);
232             __HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
233         }
234         if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) {
235             irq_handler(serial_irq_ids[id], RxIrq);
236             volatile uint32_t tmpval = UartHandle.Instance->RDR; // Clear RXNE bit
237         }
238     }
239 }
240
241 static void uart1_irq(void)
242 {
243     uart_irq(UART_1, 0);
244 }
245
246 static void uart2_irq(void)
247 {
248     uart_irq(UART_2, 1);
249 }
250
251 static void uart3_irq(void)
252 {
253     uart_irq(UART_3, 2);
254 }
255
256 #if defined(UART4_BASE)
257 static void uart4_irq(void)
258 {
259     uart_irq(UART_4, 3);
260 }
261 #endif
262
263 #if defined(UART5_BASE)
264 static void uart5_irq(void)
265 {
266     uart_irq(UART_5, 4);
267 }
268 #endif
269
270 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
271 {
272     irq_handler = handler;
273     serial_irq_ids[obj->index] = id;
274 }
275
276 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
277 {
278     IRQn_Type irq_n = (IRQn_Type)0;
279     uint32_t vector = 0;
280
281     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
282
283     if (obj->uart == UART_1) {
284         irq_n = USART1_IRQn;
285         vector = (uint32_t)&uart1_irq;
286     }
287
288     if (obj->uart == UART_2) {
289         irq_n = USART2_IRQn;
290         vector = (uint32_t)&uart2_irq;
291     }
292
293     if (obj->uart == UART_3) {
294         irq_n = USART3_IRQn;
295         vector = (uint32_t)&uart3_irq;
296     }
297
298 #if defined(UART4_BASE)
299     if (obj->uart == UART_4) {
300         irq_n = UART4_IRQn;
301         vector = (uint32_t)&uart4_irq;
302     }
303 #endif
304
305 #if defined(UART5_BASE)
306     if (obj->uart == UART_5) {
307         irq_n = UART5_IRQn;
308         vector = (uint32_t)&uart5_irq;
309     }
310 #endif
311
312     if (enable) {
313
314         if (irq == RxIrq) {
315             __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
316         } else { // TxIrq
317             __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
318         }
319
320         NVIC_SetVector(irq_n, vector);
321         NVIC_EnableIRQ(irq_n);
322
323     } else { // disable
324
325         int all_disabled = 0;
326
327         if (irq == RxIrq) {
328             __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
329             // Check if TxIrq is disabled too
330             if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1;
331         } else { // TxIrq
332             __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
333             // Check if RxIrq is disabled too
334             if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
335         }
336
337         if (all_disabled) NVIC_DisableIRQ(irq_n);
338
339     }
340 }
341
342 /******************************************************************************
343  * READ/WRITE
344  ******************************************************************************/
345
346 int serial_getc(serial_t *obj)
347 {
348     USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
349     while (!serial_readable(obj));
350     if (obj->databits == UART_WORDLENGTH_8B) {
351         return (int)(uart->RDR & (uint8_t)0xFF);
352     } else {
353         return (int)(uart->RDR & (uint16_t)0x1FF);
354     }
355 }
356
357 void serial_putc(serial_t *obj, int c)
358 {
359     USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
360     while (!serial_writable(obj));
361     if (obj->databits == UART_WORDLENGTH_8B) {
362         uart->TDR = (uint8_t)(c & (uint8_t)0xFF);
363     } else {
364         uart->TDR = (uint16_t)(c & (uint16_t)0x1FF);
365     }
366 }
367
368 int serial_readable(serial_t *obj)
369 {
370     int status;
371     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
372     // Check if data is received
373     status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
374     return status;
375 }
376
377 int serial_writable(serial_t *obj)
378 {
379     int status;
380     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
381     // Check if data is transmitted
382     status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0);
383     return status;
384 }
385
386 void serial_clear(serial_t *obj)
387 {
388     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
389     __HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
390     __HAL_UART_SEND_REQ(&UartHandle, UART_RXDATA_FLUSH_REQUEST);
391 }
392
393 void serial_pinout_tx(PinName tx)
394 {
395     pinmap_pinout(tx, PinMap_UART_TX);
396 }
397
398 void serial_break_set(serial_t *obj)
399 {
400     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
401     HAL_LIN_SendBreak(&UartHandle);
402 }
403
404 void serial_break_clear(serial_t *obj)
405 {
406 }
407
408 #endif