li lei / mbed-stm32l0l1-src

Fork of mbed-stm32l0l1-src-1 by lzbp li

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers serial_api.c Source File

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