Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-stm32l0l1-src-1 by
serial_api.c
00001 /* mbed Microcontroller Library 00002 ******************************************************************************* 00003 * Copyright (c) 2015, STMicroelectronics 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * 1. Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00021 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00024 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00025 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00027 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 ******************************************************************************* 00029 */ 00030 #include "mbed_assert.h" 00031 #include "serial_api.h" 00032 00033 #if DEVICE_SERIAL 00034 00035 #include "cmsis.h" 00036 #include "pinmap.h" 00037 #include "mbed_error.h" 00038 #include <string.h> 00039 #include "PeripheralPins.h" 00040 00041 #define UART_NUM (5) 00042 00043 static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0}; 00044 00045 static uart_irq_handler irq_handler; 00046 00047 UART_HandleTypeDef UartHandle; 00048 00049 int stdio_uart_inited = 0; 00050 serial_t stdio_uart; 00051 00052 static void init_uart(serial_t *obj) 00053 { 00054 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00055 00056 if (obj->uart == LPUART_1) { 00057 UartHandle.Init.BaudRate = obj->baudrate >> 1; 00058 } else { 00059 UartHandle.Init.BaudRate = obj->baudrate; 00060 } 00061 UartHandle.Init.WordLength = obj->databits; 00062 UartHandle.Init.StopBits = obj->stopbits; 00063 UartHandle.Init.Parity = obj->parity; 00064 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; 00065 00066 if (obj->pin_rx == NC) { 00067 UartHandle.Init.Mode = UART_MODE_TX; 00068 } else if (obj->pin_tx == NC) { 00069 UartHandle.Init.Mode = UART_MODE_RX; 00070 } else { 00071 UartHandle.Init.Mode = UART_MODE_TX_RX; 00072 } 00073 00074 // Disable the reception overrun detection 00075 UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; 00076 UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; 00077 00078 if (HAL_UART_Init(&UartHandle) != HAL_OK) { 00079 error("Cannot initialize UART"); 00080 } 00081 } 00082 00083 void serial_init(serial_t *obj, PinName tx, PinName rx) 00084 { 00085 // Determine the UART to use (UART_1, UART_2, ...) 00086 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); 00087 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); 00088 00089 // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object 00090 obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx); 00091 MBED_ASSERT(obj->uart != (UARTName)NC); 00092 00093 // Enable UART clock 00094 if (obj->uart == UART_1) { 00095 __HAL_RCC_USART1_CLK_ENABLE(); 00096 obj->index = 0; 00097 } 00098 00099 if (obj->uart == UART_2) { 00100 __HAL_RCC_USART2_CLK_ENABLE(); 00101 obj->index = 1; 00102 } 00103 00104 if (obj->uart == LPUART_1) { 00105 __HAL_RCC_LPUART1_CLK_ENABLE(); 00106 obj->index = 2; 00107 } 00108 00109 #if defined(USART4_BASE) 00110 if (obj->uart == UART_4) { 00111 __HAL_RCC_USART4_CLK_ENABLE(); 00112 obj->index = 3; 00113 } 00114 #endif 00115 00116 #if defined(USART5_BASE) 00117 if (obj->uart == UART_5) { 00118 __HAL_RCC_USART5_CLK_ENABLE(); 00119 obj->index = 4; 00120 } 00121 #endif 00122 00123 // Configure the UART pins 00124 pinmap_pinout(tx, PinMap_UART_TX); 00125 pinmap_pinout(rx, PinMap_UART_RX); 00126 if (tx != NC) { 00127 pin_mode(tx, PullUp); 00128 } 00129 if (rx != NC) { 00130 pin_mode(rx, PullUp); 00131 } 00132 00133 // Configure UART 00134 obj->baudrate = 9600; 00135 obj->databits = UART_WORDLENGTH_8B; 00136 obj->stopbits = UART_STOPBITS_1; 00137 obj->parity = UART_PARITY_NONE; 00138 obj->pin_tx = tx; 00139 obj->pin_rx = rx; 00140 00141 init_uart(obj); 00142 00143 // For stdio management 00144 if (obj->uart == STDIO_UART) { 00145 stdio_uart_inited = 1; 00146 memcpy(&stdio_uart, obj, sizeof(serial_t)); 00147 } 00148 } 00149 00150 void serial_free(serial_t *obj) 00151 { 00152 // Reset UART and disable clock 00153 if (obj->uart == UART_1) { 00154 __HAL_RCC_USART1_FORCE_RESET(); 00155 __HAL_RCC_USART1_RELEASE_RESET(); 00156 __HAL_RCC_USART1_CLK_DISABLE(); 00157 } 00158 00159 if (obj->uart == UART_2) { 00160 __HAL_RCC_USART2_FORCE_RESET(); 00161 __HAL_RCC_USART2_RELEASE_RESET(); 00162 __HAL_RCC_USART2_CLK_DISABLE(); 00163 } 00164 00165 if (obj->uart == LPUART_1) { 00166 __HAL_RCC_LPUART1_FORCE_RESET(); 00167 __HAL_RCC_LPUART1_RELEASE_RESET(); 00168 __HAL_RCC_LPUART1_CLK_DISABLE(); 00169 } 00170 00171 #if defined(USART4_BASE) 00172 if (obj->uart == UART_4) { 00173 __HAL_RCC_USART4_FORCE_RESET(); 00174 __HAL_RCC_USART4_RELEASE_RESET(); 00175 __HAL_RCC_USART4_CLK_DISABLE(); 00176 } 00177 #endif 00178 00179 #if defined(USART5_BASE) 00180 if (obj->uart == UART_5) { 00181 __HAL_RCC_USART5_FORCE_RESET(); 00182 __HAL_RCC_USART5_RELEASE_RESET(); 00183 __HAL_RCC_USART5_CLK_DISABLE(); 00184 } 00185 #endif 00186 00187 // Configure GPIOs 00188 pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); 00189 pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); 00190 00191 serial_irq_ids[obj->index] = 0; 00192 } 00193 00194 void serial_baud(serial_t *obj, int baudrate) 00195 { 00196 obj->baudrate = baudrate; 00197 init_uart(obj); 00198 } 00199 00200 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) 00201 { 00202 if (data_bits == 9) { 00203 obj->databits = UART_WORDLENGTH_9B; 00204 } else { 00205 obj->databits = UART_WORDLENGTH_8B; 00206 } 00207 00208 switch (parity) { 00209 case ParityOdd: 00210 case ParityForced0: 00211 obj->parity = UART_PARITY_ODD; 00212 break; 00213 case ParityEven: 00214 case ParityForced1: 00215 obj->parity = UART_PARITY_EVEN; 00216 break; 00217 default: // ParityNone 00218 obj->parity = UART_PARITY_NONE; 00219 break; 00220 } 00221 00222 if (stop_bits == 2) { 00223 obj->stopbits = UART_STOPBITS_2; 00224 } else { 00225 obj->stopbits = UART_STOPBITS_1; 00226 } 00227 00228 init_uart(obj); 00229 } 00230 00231 /****************************************************************************** 00232 * INTERRUPTS HANDLING 00233 ******************************************************************************/ 00234 00235 static void uart_irq(UARTName name, int id) 00236 { 00237 UartHandle.Instance = (USART_TypeDef *)name; 00238 if (serial_irq_ids[id] != 0) { 00239 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { 00240 irq_handler(serial_irq_ids[id], TxIrq); 00241 __HAL_UART_CLEAR_IT(&UartHandle, UART_CLEAR_TCF); 00242 } 00243 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) { 00244 irq_handler(serial_irq_ids[id], RxIrq); 00245 volatile uint32_t tmpval = UartHandle.Instance->RDR; // Clear RXNE bit 00246 } 00247 } 00248 } 00249 00250 static void uart1_irq(void) 00251 { 00252 uart_irq(UART_1, 0); 00253 } 00254 00255 static void uart2_irq(void) 00256 { 00257 uart_irq(UART_2, 1); 00258 } 00259 00260 static void lpuart1_irq(void) 00261 { 00262 uart_irq(LPUART_1, 2); 00263 } 00264 00265 #if defined(USART4_BASE) 00266 static void uart4_irq(void) 00267 { 00268 uart_irq(UART_4, 3); 00269 } 00270 #endif 00271 00272 #if defined(USART5_BASE) 00273 static void uart5_irq(void) 00274 { 00275 uart_irq(UART_5, 4); 00276 } 00277 #endif 00278 00279 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) 00280 { 00281 irq_handler = handler; 00282 serial_irq_ids[obj->index] = id; 00283 } 00284 00285 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) 00286 { 00287 IRQn_Type irq_n = (IRQn_Type)0; 00288 uint32_t vector = 0; 00289 00290 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00291 00292 if (obj->uart == UART_1) { 00293 irq_n = USART1_IRQn; 00294 vector = (uint32_t)&uart1_irq; 00295 } 00296 00297 if (obj->uart == UART_2) { 00298 irq_n = USART2_IRQn; 00299 vector = (uint32_t)&uart2_irq; 00300 } 00301 00302 if (obj->uart == LPUART_1) { 00303 irq_n = RNG_LPUART1_IRQn; 00304 vector = (uint32_t)&lpuart1_irq; 00305 } 00306 00307 #if defined(USART4_BASE) 00308 if (obj->uart == UART_4) { 00309 irq_n = USART4_5_IRQn; 00310 vector = (uint32_t)&uart4_irq; 00311 } 00312 #endif 00313 00314 #if defined(USART5_BASE) 00315 if (obj->uart == UART_5) { 00316 irq_n = USART4_5_IRQn; 00317 vector = (uint32_t)&uart5_irq; 00318 } 00319 #endif 00320 00321 if (enable) { 00322 00323 if (irq == RxIrq) { 00324 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); 00325 } else { // TxIrq 00326 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC); 00327 } 00328 00329 NVIC_SetVector(irq_n, vector); 00330 NVIC_EnableIRQ(irq_n); 00331 00332 } else { // disable 00333 00334 int all_disabled = 0; 00335 00336 if (irq == RxIrq) { 00337 __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); 00338 // Check if TxIrq is disabled too 00339 if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1; 00340 } else { // TxIrq 00341 __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC); 00342 // Check if RxIrq is disabled too 00343 if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; 00344 } 00345 00346 if (all_disabled) NVIC_DisableIRQ(irq_n); 00347 00348 } 00349 } 00350 00351 /****************************************************************************** 00352 * READ/WRITE 00353 ******************************************************************************/ 00354 00355 int serial_getc(serial_t *obj) 00356 { 00357 USART_TypeDef *uart = (USART_TypeDef *)(obj->uart); 00358 while (!serial_readable(obj)); 00359 return (int)(uart->RDR & (uint32_t)0xFF); 00360 } 00361 00362 void serial_putc(serial_t *obj, int c) 00363 { 00364 USART_TypeDef *uart = (USART_TypeDef *)(obj->uart); 00365 while (!serial_writable(obj)); 00366 uart->TDR = (uint32_t)(c & (uint32_t)0xFF); 00367 } 00368 00369 int serial_readable(serial_t *obj) 00370 { 00371 int status; 00372 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00373 // Check if data is received 00374 status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0); 00375 return status; 00376 } 00377 00378 int serial_writable(serial_t *obj) 00379 { 00380 int status; 00381 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00382 // Check if data is transmitted 00383 status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0); 00384 return status; 00385 } 00386 00387 void serial_clear(serial_t *obj) 00388 { 00389 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00390 __HAL_UART_CLEAR_IT(&UartHandle, UART_CLEAR_TCF); 00391 __HAL_UART_SEND_REQ(&UartHandle, UART_RXDATA_FLUSH_REQUEST); 00392 } 00393 00394 void serial_pinout_tx(PinName tx) 00395 { 00396 pinmap_pinout(tx, PinMap_UART_TX); 00397 } 00398 00399 void serial_break_set(serial_t *obj) 00400 { 00401 UartHandle.Instance = (USART_TypeDef *)(obj->uart); 00402 __HAL_UART_SEND_REQ(&UartHandle, UART_SENDBREAK_REQUEST); 00403 } 00404 00405 void serial_break_clear(serial_t *obj) 00406 { 00407 } 00408 00409 #endif
Generated on Tue Jul 12 2022 21:50:56 by
1.7.2
