]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/serial_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32F1 / 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 (3)
41
42 static uint32_t serial_irq_ids[UART_NUM] = {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     HAL_UART_Init(&UartHandle);
70 }
71
72 void serial_init(serial_t *obj, PinName tx, PinName rx)
73 {
74     // Determine the UART to use (UART_1, UART_2, ...)
75     UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
76     UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
77
78     // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
79     obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
80     MBED_ASSERT(obj->uart != (UARTName)NC);
81
82     // Enable UART clock
83     if (obj->uart == UART_1) {
84         __HAL_RCC_USART1_CLK_ENABLE();
85         obj->index = 0;
86     }
87     if (obj->uart == UART_2) {
88         __HAL_RCC_USART2_CLK_ENABLE();
89         obj->index = 1;
90     }
91     if (obj->uart == UART_3) {
92         __HAL_RCC_USART3_CLK_ENABLE();
93         obj->index = 2;
94     }
95
96     // Configure UART pins
97     pinmap_pinout(tx, PinMap_UART_TX);
98     pinmap_pinout(rx, PinMap_UART_RX);
99     if (tx != NC) {
100         pin_mode(tx, PullUp);
101     }
102     if (rx != NC) {
103         pin_mode(rx, PullUp);
104     }
105
106     // Configure UART
107     obj->baudrate = 9600;
108     obj->databits = UART_WORDLENGTH_8B;
109     obj->stopbits = UART_STOPBITS_1;
110     obj->parity   = UART_PARITY_NONE;
111
112     obj->pin_tx = tx;
113     obj->pin_rx = rx;
114
115     init_uart(obj);
116
117     // For stdio management
118     if (obj->uart == STDIO_UART) {
119         stdio_uart_inited = 1;
120         memcpy(&stdio_uart, obj, sizeof(serial_t));
121     }
122 }
123
124 void serial_free(serial_t *obj)
125 {
126     // Reset UART and disable clock
127     if (obj->uart == UART_1) {
128         __USART1_FORCE_RESET();
129         __USART1_RELEASE_RESET();
130         __USART1_CLK_DISABLE();
131     }
132     if (obj->uart == UART_2) {
133         __USART2_FORCE_RESET();
134         __USART2_RELEASE_RESET();
135         __USART2_CLK_DISABLE();
136     }
137     if (obj->uart == UART_3) {
138         __USART3_FORCE_RESET();
139         __USART3_RELEASE_RESET();
140         __USART3_CLK_DISABLE();
141     }
142
143     // Configure GPIOs
144     pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
145     pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
146
147     serial_irq_ids[obj->index] = 0;
148 }
149
150 void serial_baud(serial_t *obj, int baudrate)
151 {
152     obj->baudrate = baudrate;
153     init_uart(obj);
154 }
155
156 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
157 {
158     if (data_bits == 9) {
159         obj->databits = UART_WORDLENGTH_9B;
160     } else {
161         obj->databits = UART_WORDLENGTH_8B;
162     }
163
164     switch (parity) {
165         case ParityOdd:
166         case ParityForced0:
167             obj->parity = UART_PARITY_ODD;
168             break;
169         case ParityEven:
170         case ParityForced1:
171             obj->parity = UART_PARITY_EVEN;
172             break;
173         default: // ParityNone
174             obj->parity = UART_PARITY_NONE;
175             break;
176     }
177
178     if (stop_bits == 2) {
179         obj->stopbits = UART_STOPBITS_2;
180     } else {
181         obj->stopbits = UART_STOPBITS_1;
182     }
183
184     init_uart(obj);
185 }
186
187 /******************************************************************************
188  * INTERRUPTS HANDLING
189  ******************************************************************************/
190
191 static void uart_irq(UARTName name, int id)
192 {
193     UartHandle.Instance = (USART_TypeDef *)name;
194     if (serial_irq_ids[id] != 0) {
195         if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
196             irq_handler(serial_irq_ids[id], TxIrq);
197             __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TC);
198         }
199         if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) {
200             irq_handler(serial_irq_ids[id], RxIrq);
201             __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE);
202         }
203     }
204 }
205
206 static void uart1_irq(void)
207 {
208     uart_irq(UART_1, 0);
209 }
210
211 static void uart2_irq(void)
212 {
213     uart_irq(UART_2, 1);
214 }
215
216 static void uart3_irq(void)
217 {
218     uart_irq(UART_3, 2);
219 }
220
221 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
222 {
223     irq_handler = handler;
224     serial_irq_ids[obj->index] = id;
225 }
226
227 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
228 {
229     IRQn_Type irq_n = (IRQn_Type)0;
230     uint32_t vector = 0;
231
232     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
233
234     if (obj->uart == UART_1) {
235         irq_n = USART1_IRQn;
236         vector = (uint32_t)&uart1_irq;
237     }
238
239     if (obj->uart == UART_2) {
240         irq_n = USART2_IRQn;
241         vector = (uint32_t)&uart2_irq;
242     }
243
244     if (obj->uart == UART_3) {
245         irq_n = USART3_IRQn;
246         vector = (uint32_t)&uart3_irq;
247     }
248
249     if (enable) {
250
251         if (irq == RxIrq) {
252             __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
253         } else { // TxIrq
254             __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
255         }
256
257         NVIC_SetVector(irq_n, vector);
258         NVIC_EnableIRQ(irq_n);
259
260     } else { // disable
261
262         int all_disabled = 0;
263
264         if (irq == RxIrq) {
265             __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
266             // Check if TxIrq is disabled too
267             if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1;
268         } else { // TxIrq
269             __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
270             // Check if RxIrq is disabled too
271             if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
272         }
273
274         if (all_disabled) NVIC_DisableIRQ(irq_n);
275
276     }
277 }
278
279 /******************************************************************************
280  * READ/WRITE
281  ******************************************************************************/
282
283 int serial_getc(serial_t *obj)
284 {
285     USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
286     while (!serial_readable(obj));
287     if (obj->databits == UART_WORDLENGTH_8B) {
288         return (int)(uart->DR & (uint8_t)0xFF);
289     } else {
290         return (int)(uart->DR & (uint16_t)0x1FF);
291     }
292 }
293
294 void serial_putc(serial_t *obj, int c)
295 {
296     USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
297     while (!serial_writable(obj));
298     if (obj->databits == UART_WORDLENGTH_8B) {
299         uart->DR = (uint8_t)(c & (uint8_t)0xFF);
300     } else {
301         uart->DR = (uint16_t)(c & (uint16_t)0x1FF);
302     }
303 }
304
305 int serial_readable(serial_t *obj)
306 {
307     int status;
308     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
309     // Check if data is received
310     status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
311     return status;
312 }
313
314 int serial_writable(serial_t *obj)
315 {
316     int status;
317     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
318     // Check if data is transmitted
319     status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0);
320     return status;
321 }
322
323 void serial_clear(serial_t *obj)
324 {
325     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
326     __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TXE);
327     __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE);
328 }
329
330 void serial_pinout_tx(PinName tx)
331 {
332     pinmap_pinout(tx, PinMap_UART_TX);
333 }
334
335 void serial_break_set(serial_t *obj)
336 {
337     UartHandle.Instance = (USART_TypeDef *)(obj->uart);
338     HAL_LIN_SendBreak(&UartHandle);
339 }
340
341 void serial_break_clear(serial_t *obj)
342 {
343 }
344
345 #endif