fixed drive strength

Dependents:   capstone_i2c

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
Parent:
targets/hal/TARGET_STM/TARGET_STM32L0/serial_api.c@148:21d94c44109e
Child:
151:5eaa88a5bcc7
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /* mbed Microcontroller Library
<> 144:ef7eb2e8f9f7 2 *******************************************************************************
<> 144:ef7eb2e8f9f7 3 * Copyright (c) 2015, STMicroelectronics
<> 144:ef7eb2e8f9f7 4 * All rights reserved.
<> 144:ef7eb2e8f9f7 5 *
<> 144:ef7eb2e8f9f7 6 * Redistribution and use in source and binary forms, with or without
<> 144:ef7eb2e8f9f7 7 * modification, are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 8 *
<> 144:ef7eb2e8f9f7 9 * 1. Redistributions of source code must retain the above copyright notice,
<> 144:ef7eb2e8f9f7 10 * this list of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
<> 144:ef7eb2e8f9f7 12 * this list of conditions and the following disclaimer in the documentation
<> 144:ef7eb2e8f9f7 13 * and/or other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
<> 144:ef7eb2e8f9f7 15 * may be used to endorse or promote products derived from this software
<> 144:ef7eb2e8f9f7 16 * without specific prior written permission.
<> 144:ef7eb2e8f9f7 17 *
<> 144:ef7eb2e8f9f7 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 144:ef7eb2e8f9f7 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 144:ef7eb2e8f9f7 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 144:ef7eb2e8f9f7 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 144:ef7eb2e8f9f7 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 144:ef7eb2e8f9f7 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 144:ef7eb2e8f9f7 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 144:ef7eb2e8f9f7 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 144:ef7eb2e8f9f7 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 28 *******************************************************************************
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30 #include "mbed_assert.h"
<> 144:ef7eb2e8f9f7 31 #include "serial_api.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #if DEVICE_SERIAL
<> 144:ef7eb2e8f9f7 34
<> 144:ef7eb2e8f9f7 35 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 36 #include "pinmap.h"
<> 144:ef7eb2e8f9f7 37 #include <string.h>
<> 144:ef7eb2e8f9f7 38 #include "PeripheralPins.h"
<> 148:21d94c44109e 39 #include "mbed_error.h"
<> 144:ef7eb2e8f9f7 40
<> 144:ef7eb2e8f9f7 41 #define UART_NUM (5)
<> 144:ef7eb2e8f9f7 42
<> 148:21d94c44109e 43 static uint32_t serial_irq_ids[UART_NUM] = {0};
<> 148:21d94c44109e 44 static UART_HandleTypeDef uart_handlers[UART_NUM];
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 static uart_irq_handler irq_handler;
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48 int stdio_uart_inited = 0;
<> 144:ef7eb2e8f9f7 49 serial_t stdio_uart;
<> 144:ef7eb2e8f9f7 50
<> 148:21d94c44109e 51 #if DEVICE_SERIAL_ASYNCH
<> 148:21d94c44109e 52 #define SERIAL_S(obj) (&((obj)->serial))
<> 148:21d94c44109e 53 #else
<> 148:21d94c44109e 54 #define SERIAL_S(obj) (obj)
<> 148:21d94c44109e 55 #endif
<> 148:21d94c44109e 56
<> 144:ef7eb2e8f9f7 57 static void init_uart(serial_t *obj)
<> 144:ef7eb2e8f9f7 58 {
<> 148:21d94c44109e 59 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 60 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 61 huart->Instance = (USART_TypeDef *)(obj_s->uart);
<> 144:ef7eb2e8f9f7 62
<> 148:21d94c44109e 63 huart->Init.BaudRate = obj_s->baudrate;
<> 148:21d94c44109e 64 huart->Init.WordLength = obj_s->databits;
<> 148:21d94c44109e 65 huart->Init.StopBits = obj_s->stopbits;
<> 148:21d94c44109e 66 huart->Init.Parity = obj_s->parity;
<> 148:21d94c44109e 67 huart->Init.Parity = obj_s->parity;
<> 148:21d94c44109e 68 #if DEVICE_SERIAL_FC
<> 148:21d94c44109e 69 huart->Init.HwFlowCtl = obj_s->hw_flow_ctl;
<> 148:21d94c44109e 70 #else
<> 148:21d94c44109e 71 huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
<> 148:21d94c44109e 72 #endif
<> 148:21d94c44109e 73 huart->TxXferCount = 0;
<> 148:21d94c44109e 74 huart->TxXferSize = 0;
<> 148:21d94c44109e 75 huart->RxXferCount = 0;
<> 148:21d94c44109e 76 huart->RxXferSize = 0;
<> 144:ef7eb2e8f9f7 77
<> 148:21d94c44109e 78 if (obj_s->pin_rx == NC) {
<> 148:21d94c44109e 79 huart->Init.Mode = UART_MODE_TX;
<> 148:21d94c44109e 80 } else if (obj_s->pin_tx == NC) {
<> 148:21d94c44109e 81 huart->Init.Mode = UART_MODE_RX;
<> 144:ef7eb2e8f9f7 82 } else {
<> 148:21d94c44109e 83 huart->Init.Mode = UART_MODE_TX_RX;
<> 144:ef7eb2e8f9f7 84 }
<> 144:ef7eb2e8f9f7 85
<> 148:21d94c44109e 86 if (HAL_UART_Init(huart) != HAL_OK) {
<> 148:21d94c44109e 87 error("Cannot initialize UART\n");
<> 144:ef7eb2e8f9f7 88 }
<> 144:ef7eb2e8f9f7 89 }
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 void serial_init(serial_t *obj, PinName tx, PinName rx)
<> 144:ef7eb2e8f9f7 92 {
<> 148:21d94c44109e 93 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 94
<> 144:ef7eb2e8f9f7 95 // Determine the UART to use (UART_1, UART_2, ...)
<> 144:ef7eb2e8f9f7 96 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
<> 144:ef7eb2e8f9f7 97 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
<> 144:ef7eb2e8f9f7 98
<> 144:ef7eb2e8f9f7 99 // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
<> 148:21d94c44109e 100 obj_s->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
<> 148:21d94c44109e 101 MBED_ASSERT(obj_s->uart != (UARTName)NC);
<> 144:ef7eb2e8f9f7 102
<> 144:ef7eb2e8f9f7 103 // Enable UART clock
<> 144:ef7eb2e8f9f7 104 #if defined(USART1_BASE)
<> 148:21d94c44109e 105 if (obj_s->uart == UART_1) {
<> 144:ef7eb2e8f9f7 106 __HAL_RCC_USART1_FORCE_RESET();
<> 144:ef7eb2e8f9f7 107 __HAL_RCC_USART1_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 108 __HAL_RCC_USART1_CLK_ENABLE();
<> 148:21d94c44109e 109 obj_s->index = 0;
<> 144:ef7eb2e8f9f7 110 }
<> 144:ef7eb2e8f9f7 111 #endif
<> 144:ef7eb2e8f9f7 112
<> 148:21d94c44109e 113 if (obj_s->uart == UART_2) {
<> 144:ef7eb2e8f9f7 114 __HAL_RCC_USART2_FORCE_RESET();
<> 144:ef7eb2e8f9f7 115 __HAL_RCC_USART2_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 116 __HAL_RCC_USART2_CLK_ENABLE();
<> 148:21d94c44109e 117 obj_s->index = 1;
<> 144:ef7eb2e8f9f7 118 }
<> 144:ef7eb2e8f9f7 119
<> 148:21d94c44109e 120 if (obj_s->uart == LPUART_1) {
<> 144:ef7eb2e8f9f7 121 __HAL_RCC_LPUART1_FORCE_RESET();
<> 144:ef7eb2e8f9f7 122 __HAL_RCC_LPUART1_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 123 __HAL_RCC_LPUART1_CLK_ENABLE();
<> 148:21d94c44109e 124 obj_s->index = 2;
<> 144:ef7eb2e8f9f7 125 }
<> 144:ef7eb2e8f9f7 126
<> 144:ef7eb2e8f9f7 127 #if defined(USART4_BASE)
<> 148:21d94c44109e 128 if (obj_s->uart == UART_4) {
<> 144:ef7eb2e8f9f7 129 __HAL_RCC_USART4_FORCE_RESET();
<> 144:ef7eb2e8f9f7 130 __HAL_RCC_USART4_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 131 __HAL_RCC_USART4_CLK_ENABLE();
<> 148:21d94c44109e 132 obj_s->index = 3;
<> 144:ef7eb2e8f9f7 133 }
<> 144:ef7eb2e8f9f7 134 #endif
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 #if defined(USART5_BASE)
<> 148:21d94c44109e 137 if (obj_s->uart == UART_5) {
<> 144:ef7eb2e8f9f7 138 __HAL_RCC_USART5_FORCE_RESET();
<> 144:ef7eb2e8f9f7 139 __HAL_RCC_USART5_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 140 __HAL_RCC_USART5_CLK_ENABLE();
<> 148:21d94c44109e 141 obj_s->index = 4;
<> 144:ef7eb2e8f9f7 142 }
<> 144:ef7eb2e8f9f7 143 #endif
<> 144:ef7eb2e8f9f7 144
<> 144:ef7eb2e8f9f7 145 // Configure the UART pins
<> 144:ef7eb2e8f9f7 146 pinmap_pinout(tx, PinMap_UART_TX);
<> 144:ef7eb2e8f9f7 147 pinmap_pinout(rx, PinMap_UART_RX);
<> 148:21d94c44109e 148
<> 144:ef7eb2e8f9f7 149 if (tx != NC) {
<> 144:ef7eb2e8f9f7 150 pin_mode(tx, PullUp);
<> 144:ef7eb2e8f9f7 151 }
<> 144:ef7eb2e8f9f7 152 if (rx != NC) {
<> 144:ef7eb2e8f9f7 153 pin_mode(rx, PullUp);
<> 144:ef7eb2e8f9f7 154 }
<> 144:ef7eb2e8f9f7 155
<> 144:ef7eb2e8f9f7 156 // Configure UART
<> 148:21d94c44109e 157 obj_s->baudrate = 9600;
<> 148:21d94c44109e 158 obj_s->databits = UART_WORDLENGTH_8B;
<> 148:21d94c44109e 159 obj_s->stopbits = UART_STOPBITS_1;
<> 148:21d94c44109e 160 obj_s->parity = UART_PARITY_NONE;
<> 148:21d94c44109e 161
<> 148:21d94c44109e 162 #if DEVICE_SERIAL_FC
<> 148:21d94c44109e 163 obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
<> 148:21d94c44109e 164 #endif
<> 148:21d94c44109e 165
<> 148:21d94c44109e 166 obj_s->pin_tx = tx;
<> 148:21d94c44109e 167 obj_s->pin_rx = rx;
<> 144:ef7eb2e8f9f7 168
<> 144:ef7eb2e8f9f7 169 init_uart(obj);
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 // For stdio management
<> 148:21d94c44109e 172 if (obj_s->uart == STDIO_UART) {
<> 144:ef7eb2e8f9f7 173 stdio_uart_inited = 1;
<> 144:ef7eb2e8f9f7 174 memcpy(&stdio_uart, obj, sizeof(serial_t));
<> 144:ef7eb2e8f9f7 175 }
<> 144:ef7eb2e8f9f7 176 }
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178 void serial_free(serial_t *obj)
<> 144:ef7eb2e8f9f7 179 {
<> 148:21d94c44109e 180 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 181
<> 144:ef7eb2e8f9f7 182 // Reset UART and disable clock
<> 144:ef7eb2e8f9f7 183 #if defined(USART1_BASE)
<> 148:21d94c44109e 184 if (obj_s->uart == UART_1) {
<> 144:ef7eb2e8f9f7 185 __HAL_RCC_USART1_FORCE_RESET();
<> 144:ef7eb2e8f9f7 186 __HAL_RCC_USART1_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 187 __HAL_RCC_USART1_CLK_DISABLE();
<> 144:ef7eb2e8f9f7 188 }
<> 144:ef7eb2e8f9f7 189 #endif
<> 144:ef7eb2e8f9f7 190
<> 148:21d94c44109e 191 if (obj_s->uart == UART_2) {
<> 144:ef7eb2e8f9f7 192 __HAL_RCC_USART2_FORCE_RESET();
<> 144:ef7eb2e8f9f7 193 __HAL_RCC_USART2_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 194 __HAL_RCC_USART2_CLK_DISABLE();
<> 144:ef7eb2e8f9f7 195 }
<> 144:ef7eb2e8f9f7 196
<> 148:21d94c44109e 197 if (obj_s->uart == LPUART_1) {
<> 144:ef7eb2e8f9f7 198 __HAL_RCC_LPUART1_FORCE_RESET();
<> 144:ef7eb2e8f9f7 199 __HAL_RCC_LPUART1_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 200 __HAL_RCC_LPUART1_CLK_DISABLE();
<> 144:ef7eb2e8f9f7 201 }
<> 144:ef7eb2e8f9f7 202
<> 144:ef7eb2e8f9f7 203 #if defined(USART4_BASE)
<> 148:21d94c44109e 204 if (obj_s->uart == UART_4) {
<> 144:ef7eb2e8f9f7 205 __HAL_RCC_USART4_FORCE_RESET();
<> 144:ef7eb2e8f9f7 206 __HAL_RCC_USART4_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 207 __HAL_RCC_USART4_CLK_DISABLE();
<> 144:ef7eb2e8f9f7 208 }
<> 144:ef7eb2e8f9f7 209 #endif
<> 144:ef7eb2e8f9f7 210
<> 144:ef7eb2e8f9f7 211 #if defined(USART5_BASE)
<> 148:21d94c44109e 212 if (obj_s->uart == UART_5) {
<> 144:ef7eb2e8f9f7 213 __HAL_RCC_USART5_FORCE_RESET();
<> 144:ef7eb2e8f9f7 214 __HAL_RCC_USART5_RELEASE_RESET();
<> 144:ef7eb2e8f9f7 215 __HAL_RCC_USART5_CLK_DISABLE();
<> 144:ef7eb2e8f9f7 216 }
<> 144:ef7eb2e8f9f7 217 #endif
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 // Configure GPIOs
<> 148:21d94c44109e 220 pin_function(obj_s->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
<> 148:21d94c44109e 221 pin_function(obj_s->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
<> 144:ef7eb2e8f9f7 222
<> 148:21d94c44109e 223 serial_irq_ids[obj_s->index] = 0;
<> 144:ef7eb2e8f9f7 224 }
<> 144:ef7eb2e8f9f7 225
<> 144:ef7eb2e8f9f7 226 void serial_baud(serial_t *obj, int baudrate)
<> 144:ef7eb2e8f9f7 227 {
<> 148:21d94c44109e 228 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 229
<> 148:21d94c44109e 230 obj_s->baudrate = baudrate;
<> 144:ef7eb2e8f9f7 231 init_uart(obj);
<> 144:ef7eb2e8f9f7 232 }
<> 144:ef7eb2e8f9f7 233
<> 144:ef7eb2e8f9f7 234 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
<> 144:ef7eb2e8f9f7 235 {
<> 148:21d94c44109e 236 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 237
<> 144:ef7eb2e8f9f7 238 if (data_bits == 9) {
<> 148:21d94c44109e 239 obj_s->databits = UART_WORDLENGTH_9B;
<> 144:ef7eb2e8f9f7 240 } else {
<> 148:21d94c44109e 241 obj_s->databits = UART_WORDLENGTH_8B;
<> 144:ef7eb2e8f9f7 242 }
<> 144:ef7eb2e8f9f7 243
<> 144:ef7eb2e8f9f7 244 switch (parity) {
<> 144:ef7eb2e8f9f7 245 case ParityOdd:
<> 148:21d94c44109e 246 obj_s->parity = UART_PARITY_ODD;
<> 144:ef7eb2e8f9f7 247 break;
<> 144:ef7eb2e8f9f7 248 case ParityEven:
<> 148:21d94c44109e 249 obj_s->parity = UART_PARITY_EVEN;
<> 144:ef7eb2e8f9f7 250 break;
<> 144:ef7eb2e8f9f7 251 default: // ParityNone
<> 148:21d94c44109e 252 case ParityForced0: // unsupported!
<> 148:21d94c44109e 253 case ParityForced1: // unsupported!
<> 148:21d94c44109e 254 obj_s->parity = UART_PARITY_NONE;
<> 144:ef7eb2e8f9f7 255 break;
<> 144:ef7eb2e8f9f7 256 }
<> 144:ef7eb2e8f9f7 257
<> 144:ef7eb2e8f9f7 258 if (stop_bits == 2) {
<> 148:21d94c44109e 259 obj_s->stopbits = UART_STOPBITS_2;
<> 144:ef7eb2e8f9f7 260 } else {
<> 148:21d94c44109e 261 obj_s->stopbits = UART_STOPBITS_1;
<> 144:ef7eb2e8f9f7 262 }
<> 144:ef7eb2e8f9f7 263
<> 144:ef7eb2e8f9f7 264 init_uart(obj);
<> 144:ef7eb2e8f9f7 265 }
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 /******************************************************************************
<> 144:ef7eb2e8f9f7 268 * INTERRUPTS HANDLING
<> 144:ef7eb2e8f9f7 269 ******************************************************************************/
<> 144:ef7eb2e8f9f7 270
<> 148:21d94c44109e 271 static void uart_irq(int id)
<> 144:ef7eb2e8f9f7 272 {
<> 148:21d94c44109e 273 UART_HandleTypeDef * huart = &uart_handlers[id];
<> 148:21d94c44109e 274
<> 144:ef7eb2e8f9f7 275 if (serial_irq_ids[id] != 0) {
<> 148:21d94c44109e 276 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
<> 148:21d94c44109e 277 if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
<> 148:21d94c44109e 278 irq_handler(serial_irq_ids[id], TxIrq);
<> 148:21d94c44109e 279 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
<> 148:21d94c44109e 280 }
<> 144:ef7eb2e8f9f7 281 }
<> 148:21d94c44109e 282 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
<> 148:21d94c44109e 283 if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
<> 148:21d94c44109e 284 irq_handler(serial_irq_ids[id], RxIrq);
<> 148:21d94c44109e 285 volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
<> 148:21d94c44109e 286 }
<> 148:21d94c44109e 287 }
<> 148:21d94c44109e 288 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
<> 148:21d94c44109e 289 if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) {
<> 148:21d94c44109e 290 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
<> 148:21d94c44109e 291 }
<> 144:ef7eb2e8f9f7 292 }
<> 144:ef7eb2e8f9f7 293 }
<> 144:ef7eb2e8f9f7 294 }
<> 144:ef7eb2e8f9f7 295
<> 144:ef7eb2e8f9f7 296 #if defined(USART1_BASE)
<> 144:ef7eb2e8f9f7 297 static void uart1_irq(void)
<> 144:ef7eb2e8f9f7 298 {
<> 148:21d94c44109e 299 uart_irq(0);
<> 144:ef7eb2e8f9f7 300 }
<> 144:ef7eb2e8f9f7 301 #endif
<> 144:ef7eb2e8f9f7 302
<> 144:ef7eb2e8f9f7 303 static void uart2_irq(void)
<> 144:ef7eb2e8f9f7 304 {
<> 148:21d94c44109e 305 uart_irq(1);
<> 144:ef7eb2e8f9f7 306 }
<> 144:ef7eb2e8f9f7 307
<> 144:ef7eb2e8f9f7 308 static void lpuart1_irq(void)
<> 144:ef7eb2e8f9f7 309 {
<> 148:21d94c44109e 310 uart_irq(2);
<> 144:ef7eb2e8f9f7 311 }
<> 144:ef7eb2e8f9f7 312
<> 144:ef7eb2e8f9f7 313 #if defined(USART4_BASE)
<> 144:ef7eb2e8f9f7 314 static void uart4_irq(void)
<> 144:ef7eb2e8f9f7 315 {
<> 148:21d94c44109e 316 uart_irq(3);
<> 144:ef7eb2e8f9f7 317 }
<> 144:ef7eb2e8f9f7 318 #endif
<> 144:ef7eb2e8f9f7 319
<> 144:ef7eb2e8f9f7 320 #if defined(USART5_BASE)
<> 144:ef7eb2e8f9f7 321 static void uart5_irq(void)
<> 144:ef7eb2e8f9f7 322 {
<> 148:21d94c44109e 323 uart_irq(4);
<> 144:ef7eb2e8f9f7 324 }
<> 144:ef7eb2e8f9f7 325 #endif
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
<> 144:ef7eb2e8f9f7 328 {
<> 148:21d94c44109e 329 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 330
<> 144:ef7eb2e8f9f7 331 irq_handler = handler;
<> 148:21d94c44109e 332 serial_irq_ids[obj_s->index] = id;
<> 144:ef7eb2e8f9f7 333 }
<> 144:ef7eb2e8f9f7 334
<> 144:ef7eb2e8f9f7 335 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
<> 144:ef7eb2e8f9f7 336 {
<> 148:21d94c44109e 337 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 338 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 144:ef7eb2e8f9f7 339 IRQn_Type irq_n = (IRQn_Type)0;
<> 144:ef7eb2e8f9f7 340 uint32_t vector = 0;
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 #if defined(USART1_BASE)
<> 148:21d94c44109e 343 if (obj_s->uart == UART_1) {
<> 144:ef7eb2e8f9f7 344 irq_n = USART1_IRQn;
<> 144:ef7eb2e8f9f7 345 vector = (uint32_t)&uart1_irq;
<> 144:ef7eb2e8f9f7 346 }
<> 144:ef7eb2e8f9f7 347 #endif
<> 144:ef7eb2e8f9f7 348
<> 148:21d94c44109e 349 if (obj_s->uart == UART_2) {
<> 144:ef7eb2e8f9f7 350 irq_n = USART2_IRQn;
<> 144:ef7eb2e8f9f7 351 vector = (uint32_t)&uart2_irq;
<> 144:ef7eb2e8f9f7 352 }
<> 144:ef7eb2e8f9f7 353
<> 148:21d94c44109e 354 if (obj_s->uart == LPUART_1) {
<> 144:ef7eb2e8f9f7 355 irq_n = RNG_LPUART1_IRQn;
<> 144:ef7eb2e8f9f7 356 vector = (uint32_t)&lpuart1_irq;
<> 144:ef7eb2e8f9f7 357 }
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359 #if defined(USART4_BASE)
<> 148:21d94c44109e 360 if (obj_s->uart == UART_4) {
<> 144:ef7eb2e8f9f7 361 irq_n = USART4_5_IRQn;
<> 144:ef7eb2e8f9f7 362 vector = (uint32_t)&uart4_irq;
<> 144:ef7eb2e8f9f7 363 }
<> 144:ef7eb2e8f9f7 364 #endif
<> 144:ef7eb2e8f9f7 365
<> 144:ef7eb2e8f9f7 366 #if defined(USART5_BASE)
<> 148:21d94c44109e 367 if (obj_s->uart == UART_5) {
<> 144:ef7eb2e8f9f7 368 irq_n = USART4_5_IRQn;
<> 144:ef7eb2e8f9f7 369 vector = (uint32_t)&uart5_irq;
<> 144:ef7eb2e8f9f7 370 }
<> 144:ef7eb2e8f9f7 371 #endif
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 if (enable) {
<> 144:ef7eb2e8f9f7 374 if (irq == RxIrq) {
<> 148:21d94c44109e 375 __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
<> 144:ef7eb2e8f9f7 376 } else { // TxIrq
<> 148:21d94c44109e 377 __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
<> 144:ef7eb2e8f9f7 378 }
<> 144:ef7eb2e8f9f7 379 NVIC_SetVector(irq_n, vector);
<> 144:ef7eb2e8f9f7 380 NVIC_EnableIRQ(irq_n);
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 } else { // disable
<> 144:ef7eb2e8f9f7 383 int all_disabled = 0;
<> 144:ef7eb2e8f9f7 384 if (irq == RxIrq) {
<> 148:21d94c44109e 385 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
<> 144:ef7eb2e8f9f7 386 // Check if TxIrq is disabled too
<> 148:21d94c44109e 387 if ((huart->Instance->CR1 & USART_CR1_TXEIE) == 0) {
<> 148:21d94c44109e 388 all_disabled = 1;
<> 148:21d94c44109e 389 }
<> 144:ef7eb2e8f9f7 390 } else { // TxIrq
<> 148:21d94c44109e 391 __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
<> 144:ef7eb2e8f9f7 392 // Check if RxIrq is disabled too
<> 148:21d94c44109e 393 if ((huart->Instance->CR1 & USART_CR1_RXNEIE) == 0) {
<> 148:21d94c44109e 394 all_disabled = 1;
<> 148:21d94c44109e 395 }
<> 144:ef7eb2e8f9f7 396 }
<> 144:ef7eb2e8f9f7 397
<> 148:21d94c44109e 398 if (all_disabled) {
<> 148:21d94c44109e 399 NVIC_DisableIRQ(irq_n);
<> 148:21d94c44109e 400 }
<> 144:ef7eb2e8f9f7 401 }
<> 144:ef7eb2e8f9f7 402 }
<> 144:ef7eb2e8f9f7 403
<> 144:ef7eb2e8f9f7 404 /******************************************************************************
<> 144:ef7eb2e8f9f7 405 * READ/WRITE
<> 144:ef7eb2e8f9f7 406 ******************************************************************************/
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408 int serial_getc(serial_t *obj)
<> 144:ef7eb2e8f9f7 409 {
<> 148:21d94c44109e 410 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 411 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 412
<> 144:ef7eb2e8f9f7 413 while (!serial_readable(obj));
<> 148:21d94c44109e 414 return (int)(huart->Instance->RDR & (uint16_t)0xFF);
<> 144:ef7eb2e8f9f7 415 }
<> 144:ef7eb2e8f9f7 416
<> 144:ef7eb2e8f9f7 417 void serial_putc(serial_t *obj, int c)
<> 144:ef7eb2e8f9f7 418 {
<> 148:21d94c44109e 419 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 420 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 421
<> 144:ef7eb2e8f9f7 422 while (!serial_writable(obj));
<> 148:21d94c44109e 423 huart->Instance->TDR = (uint32_t)(c & (uint16_t)0xFF);
<> 144:ef7eb2e8f9f7 424 }
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 int serial_readable(serial_t *obj)
<> 144:ef7eb2e8f9f7 427 {
<> 148:21d94c44109e 428 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 429 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 430
<> 144:ef7eb2e8f9f7 431 // Check if data is received
<> 148:21d94c44109e 432 return (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) ? 1 : 0;
<> 144:ef7eb2e8f9f7 433 }
<> 144:ef7eb2e8f9f7 434
<> 144:ef7eb2e8f9f7 435 int serial_writable(serial_t *obj)
<> 144:ef7eb2e8f9f7 436 {
<> 148:21d94c44109e 437 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 438 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 439
<> 144:ef7eb2e8f9f7 440 // Check if data is transmitted
<> 148:21d94c44109e 441 return (__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE) != RESET) ? 1 : 0;
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443
<> 144:ef7eb2e8f9f7 444 void serial_clear(serial_t *obj)
<> 144:ef7eb2e8f9f7 445 {
<> 148:21d94c44109e 446 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 447 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 448
<> 148:21d94c44109e 449 huart->TxXferCount = 0;
<> 148:21d94c44109e 450 huart->RxXferCount = 0;
<> 144:ef7eb2e8f9f7 451 }
<> 144:ef7eb2e8f9f7 452
<> 144:ef7eb2e8f9f7 453 void serial_pinout_tx(PinName tx)
<> 144:ef7eb2e8f9f7 454 {
<> 144:ef7eb2e8f9f7 455 pinmap_pinout(tx, PinMap_UART_TX);
<> 144:ef7eb2e8f9f7 456 }
<> 144:ef7eb2e8f9f7 457
<> 144:ef7eb2e8f9f7 458 void serial_break_set(serial_t *obj)
<> 144:ef7eb2e8f9f7 459 {
<> 148:21d94c44109e 460 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 461 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 462
<> 148:21d94c44109e 463 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
<> 144:ef7eb2e8f9f7 464 }
<> 144:ef7eb2e8f9f7 465
<> 144:ef7eb2e8f9f7 466 void serial_break_clear(serial_t *obj)
<> 144:ef7eb2e8f9f7 467 {
<> 148:21d94c44109e 468 (void)obj;
<> 148:21d94c44109e 469 }
<> 148:21d94c44109e 470
<> 148:21d94c44109e 471 #if DEVICE_SERIAL_ASYNCH
<> 148:21d94c44109e 472
<> 148:21d94c44109e 473 /******************************************************************************
<> 148:21d94c44109e 474 * LOCAL HELPER FUNCTIONS
<> 148:21d94c44109e 475 ******************************************************************************/
<> 148:21d94c44109e 476
<> 148:21d94c44109e 477 /**
<> 148:21d94c44109e 478 * Configure the TX buffer for an asynchronous write serial transaction
<> 148:21d94c44109e 479 *
<> 148:21d94c44109e 480 * @param obj The serial object.
<> 148:21d94c44109e 481 * @param tx The buffer for sending.
<> 148:21d94c44109e 482 * @param tx_length The number of words to transmit.
<> 148:21d94c44109e 483 */
<> 148:21d94c44109e 484 static void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
<> 148:21d94c44109e 485 {
<> 148:21d94c44109e 486 (void)width;
<> 148:21d94c44109e 487
<> 148:21d94c44109e 488 // Exit if a transmit is already on-going
<> 148:21d94c44109e 489 if (serial_tx_active(obj)) {
<> 148:21d94c44109e 490 return;
<> 148:21d94c44109e 491 }
<> 148:21d94c44109e 492
<> 148:21d94c44109e 493 obj->tx_buff.buffer = tx;
<> 148:21d94c44109e 494 obj->tx_buff.length = tx_length;
<> 148:21d94c44109e 495 obj->tx_buff.pos = 0;
<> 148:21d94c44109e 496 }
<> 148:21d94c44109e 497
<> 148:21d94c44109e 498 /**
<> 148:21d94c44109e 499 * Configure the RX buffer for an asynchronous write serial transaction
<> 148:21d94c44109e 500 *
<> 148:21d94c44109e 501 * @param obj The serial object.
<> 148:21d94c44109e 502 * @param tx The buffer for sending.
<> 148:21d94c44109e 503 * @param tx_length The number of words to transmit.
<> 148:21d94c44109e 504 */
<> 148:21d94c44109e 505 static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
<> 148:21d94c44109e 506 {
<> 148:21d94c44109e 507 (void)width;
<> 148:21d94c44109e 508
<> 148:21d94c44109e 509 // Exit if a reception is already on-going
<> 148:21d94c44109e 510 if (serial_rx_active(obj)) {
<> 148:21d94c44109e 511 return;
<> 148:21d94c44109e 512 }
<> 148:21d94c44109e 513
<> 148:21d94c44109e 514 obj->rx_buff.buffer = rx;
<> 148:21d94c44109e 515 obj->rx_buff.length = rx_length;
<> 148:21d94c44109e 516 obj->rx_buff.pos = 0;
<> 148:21d94c44109e 517 }
<> 148:21d94c44109e 518
<> 148:21d94c44109e 519 /**
<> 148:21d94c44109e 520 * Configure events
<> 148:21d94c44109e 521 *
<> 148:21d94c44109e 522 * @param obj The serial object
<> 148:21d94c44109e 523 * @param event The logical OR of the events to configure
<> 148:21d94c44109e 524 * @param enable Set to non-zero to enable events, or zero to disable them
<> 148:21d94c44109e 525 */
<> 148:21d94c44109e 526 static void serial_enable_event(serial_t *obj, int event, uint8_t enable)
<> 148:21d94c44109e 527 {
<> 148:21d94c44109e 528 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 529
<> 148:21d94c44109e 530 // Shouldn't have to enable interrupt here, just need to keep track of the requested events.
<> 148:21d94c44109e 531 if (enable) {
<> 148:21d94c44109e 532 obj_s->events |= event;
<> 148:21d94c44109e 533 } else {
<> 148:21d94c44109e 534 obj_s->events &= ~event;
<> 148:21d94c44109e 535 }
<> 148:21d94c44109e 536 }
<> 148:21d94c44109e 537
<> 148:21d94c44109e 538
<> 148:21d94c44109e 539 /**
<> 148:21d94c44109e 540 * Get index of serial object TX IRQ, relating it to the physical peripheral.
<> 148:21d94c44109e 541 *
<> 148:21d94c44109e 542 * @param obj pointer to serial object
<> 148:21d94c44109e 543 * @return internal NVIC TX IRQ index of U(S)ART peripheral
<> 148:21d94c44109e 544 */
<> 148:21d94c44109e 545 static IRQn_Type serial_get_irq_n(serial_t *obj)
<> 148:21d94c44109e 546 {
<> 148:21d94c44109e 547 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 548 IRQn_Type irq_n;
<> 148:21d94c44109e 549
<> 148:21d94c44109e 550 switch (obj_s->index) {
<> 148:21d94c44109e 551 #if defined(USART1_BASE)
<> 148:21d94c44109e 552 case 0:
<> 148:21d94c44109e 553 irq_n = USART1_IRQn;
<> 148:21d94c44109e 554 break;
<> 148:21d94c44109e 555 #endif
<> 148:21d94c44109e 556 case 1:
<> 148:21d94c44109e 557 irq_n = USART2_IRQn;
<> 148:21d94c44109e 558 break;
<> 148:21d94c44109e 559
<> 148:21d94c44109e 560 case 2:
<> 148:21d94c44109e 561 irq_n = RNG_LPUART1_IRQn;
<> 148:21d94c44109e 562 break;
<> 148:21d94c44109e 563 #if defined(USART4_BASE)
<> 148:21d94c44109e 564 case 3:
<> 148:21d94c44109e 565 irq_n = USART4_5_IRQn;
<> 148:21d94c44109e 566 break;
<> 148:21d94c44109e 567 #endif
<> 148:21d94c44109e 568 #if defined(USART5_BASE)
<> 148:21d94c44109e 569 case 4:
<> 148:21d94c44109e 570 irq_n = USART4_5_IRQn;
<> 148:21d94c44109e 571 break;
<> 148:21d94c44109e 572 #endif
<> 148:21d94c44109e 573 default:
<> 148:21d94c44109e 574 irq_n = (IRQn_Type)0;
<> 148:21d94c44109e 575 }
<> 148:21d94c44109e 576
<> 148:21d94c44109e 577 return irq_n;
<> 148:21d94c44109e 578 }
<> 148:21d94c44109e 579
<> 148:21d94c44109e 580
<> 148:21d94c44109e 581 /******************************************************************************
<> 148:21d94c44109e 582 * MBED API FUNCTIONS
<> 148:21d94c44109e 583 ******************************************************************************/
<> 148:21d94c44109e 584
<> 148:21d94c44109e 585 /**
<> 148:21d94c44109e 586 * Begin asynchronous TX transfer. The used buffer is specified in the serial
<> 148:21d94c44109e 587 * object, tx_buff
<> 148:21d94c44109e 588 *
<> 148:21d94c44109e 589 * @param obj The serial object
<> 148:21d94c44109e 590 * @param tx The buffer for sending
<> 148:21d94c44109e 591 * @param tx_length The number of words to transmit
<> 148:21d94c44109e 592 * @param tx_width The bit width of buffer word
<> 148:21d94c44109e 593 * @param handler The serial handler
<> 148:21d94c44109e 594 * @param event The logical OR of events to be registered
<> 148:21d94c44109e 595 * @param hint A suggestion for how to use DMA with this transfer
<> 148:21d94c44109e 596 * @return Returns number of data transfered, or 0 otherwise
<> 148:21d94c44109e 597 */
<> 148:21d94c44109e 598 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
<> 148:21d94c44109e 599 {
<> 148:21d94c44109e 600 // TODO: DMA usage is currently ignored
<> 148:21d94c44109e 601 (void) hint;
<> 148:21d94c44109e 602
<> 148:21d94c44109e 603 // Check buffer is ok
<> 148:21d94c44109e 604 MBED_ASSERT(tx != (void*)0);
<> 148:21d94c44109e 605 MBED_ASSERT(tx_width == 8); // support only 8b width
<> 148:21d94c44109e 606
<> 148:21d94c44109e 607 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 608 UART_HandleTypeDef * huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 609
<> 148:21d94c44109e 610 if (tx_length == 0) {
<> 148:21d94c44109e 611 return 0;
<> 148:21d94c44109e 612 }
<> 148:21d94c44109e 613
<> 148:21d94c44109e 614 // Set up buffer
<> 148:21d94c44109e 615 serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
<> 148:21d94c44109e 616
<> 148:21d94c44109e 617 // Set up events
<> 148:21d94c44109e 618 serial_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events
<> 148:21d94c44109e 619 serial_enable_event(obj, event, 1); // Set only the wanted events
<> 148:21d94c44109e 620
<> 148:21d94c44109e 621 // Enable interrupt
<> 148:21d94c44109e 622 IRQn_Type irq_n = serial_get_irq_n(obj);
<> 148:21d94c44109e 623 NVIC_ClearPendingIRQ(irq_n);
<> 148:21d94c44109e 624 NVIC_DisableIRQ(irq_n);
<> 148:21d94c44109e 625 NVIC_SetPriority(irq_n, 1);
<> 148:21d94c44109e 626 NVIC_SetVector(irq_n, (uint32_t)handler);
<> 148:21d94c44109e 627 NVIC_EnableIRQ(irq_n);
<> 148:21d94c44109e 628
<> 148:21d94c44109e 629 // the following function will enable UART_IT_TXE and error interrupts
<> 148:21d94c44109e 630 if (HAL_UART_Transmit_IT(huart, (uint8_t*)tx, tx_length) != HAL_OK) {
<> 148:21d94c44109e 631 return 0;
<> 148:21d94c44109e 632 }
<> 148:21d94c44109e 633
<> 148:21d94c44109e 634 return tx_length;
<> 148:21d94c44109e 635 }
<> 148:21d94c44109e 636
<> 148:21d94c44109e 637 /**
<> 148:21d94c44109e 638 * Begin asynchronous RX transfer (enable interrupt for data collecting)
<> 148:21d94c44109e 639 * The used buffer is specified in the serial object, rx_buff
<> 148:21d94c44109e 640 *
<> 148:21d94c44109e 641 * @param obj The serial object
<> 148:21d94c44109e 642 * @param rx The buffer for sending
<> 148:21d94c44109e 643 * @param rx_length The number of words to transmit
<> 148:21d94c44109e 644 * @param rx_width The bit width of buffer word
<> 148:21d94c44109e 645 * @param handler The serial handler
<> 148:21d94c44109e 646 * @param event The logical OR of events to be registered
<> 148:21d94c44109e 647 * @param handler The serial handler
<> 148:21d94c44109e 648 * @param char_match A character in range 0-254 to be matched
<> 148:21d94c44109e 649 * @param hint A suggestion for how to use DMA with this transfer
<> 148:21d94c44109e 650 */
<> 148:21d94c44109e 651 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
<> 148:21d94c44109e 652 {
<> 148:21d94c44109e 653 // TODO: DMA usage is currently ignored
<> 148:21d94c44109e 654 (void) hint;
<> 148:21d94c44109e 655
<> 148:21d94c44109e 656 /* Sanity check arguments */
<> 148:21d94c44109e 657 MBED_ASSERT(obj);
<> 148:21d94c44109e 658 MBED_ASSERT(rx != (void*)0);
<> 148:21d94c44109e 659 MBED_ASSERT(rx_width == 8); // support only 8b width
<> 148:21d94c44109e 660
<> 148:21d94c44109e 661 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 662 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 663
<> 148:21d94c44109e 664 serial_enable_event(obj, SERIAL_EVENT_RX_ALL, 0);
<> 148:21d94c44109e 665 serial_enable_event(obj, event, 1);
<> 148:21d94c44109e 666
<> 148:21d94c44109e 667 // set CharMatch
<> 148:21d94c44109e 668 obj->char_match = char_match;
<> 148:21d94c44109e 669
<> 148:21d94c44109e 670 serial_rx_buffer_set(obj, rx, rx_length, rx_width);
<> 148:21d94c44109e 671
<> 148:21d94c44109e 672 IRQn_Type irq_n = serial_get_irq_n(obj);
<> 148:21d94c44109e 673 NVIC_ClearPendingIRQ(irq_n);
<> 148:21d94c44109e 674 NVIC_DisableIRQ(irq_n);
<> 148:21d94c44109e 675 NVIC_SetPriority(irq_n, 0);
<> 148:21d94c44109e 676 NVIC_SetVector(irq_n, (uint32_t)handler);
<> 148:21d94c44109e 677 NVIC_EnableIRQ(irq_n);
<> 148:21d94c44109e 678
<> 148:21d94c44109e 679 // following HAL function will enable the RXNE interrupt + error interrupts
<> 148:21d94c44109e 680 HAL_UART_Receive_IT(huart, (uint8_t*)rx, rx_length);
<> 148:21d94c44109e 681 }
<> 148:21d94c44109e 682
<> 148:21d94c44109e 683 /**
<> 148:21d94c44109e 684 * Attempts to determine if the serial peripheral is already in use for TX
<> 148:21d94c44109e 685 *
<> 148:21d94c44109e 686 * @param obj The serial object
<> 148:21d94c44109e 687 * @return Non-zero if the TX transaction is ongoing, 0 otherwise
<> 148:21d94c44109e 688 */
<> 148:21d94c44109e 689 uint8_t serial_tx_active(serial_t *obj)
<> 148:21d94c44109e 690 {
<> 148:21d94c44109e 691 MBED_ASSERT(obj);
<> 148:21d94c44109e 692
<> 148:21d94c44109e 693 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 694 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 695
<> 148:21d94c44109e 696 return ((HAL_UART_GetState(huart) == HAL_UART_STATE_BUSY_TX) ? 1 : 0);
<> 148:21d94c44109e 697 }
<> 148:21d94c44109e 698
<> 148:21d94c44109e 699 /**
<> 148:21d94c44109e 700 * Attempts to determine if the serial peripheral is already in use for RX
<> 148:21d94c44109e 701 *
<> 148:21d94c44109e 702 * @param obj The serial object
<> 148:21d94c44109e 703 * @return Non-zero if the RX transaction is ongoing, 0 otherwise
<> 148:21d94c44109e 704 */
<> 148:21d94c44109e 705 uint8_t serial_rx_active(serial_t *obj)
<> 148:21d94c44109e 706 {
<> 148:21d94c44109e 707 MBED_ASSERT(obj);
<> 148:21d94c44109e 708
<> 148:21d94c44109e 709 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 710 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 711
<> 148:21d94c44109e 712 return ((HAL_UART_GetState(huart) == HAL_UART_STATE_BUSY_RX) ? 1 : 0);
<> 148:21d94c44109e 713 }
<> 148:21d94c44109e 714
<> 148:21d94c44109e 715 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
<> 148:21d94c44109e 716 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
<> 148:21d94c44109e 717 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
<> 148:21d94c44109e 718 }
<> 148:21d94c44109e 719 }
<> 148:21d94c44109e 720
<> 148:21d94c44109e 721 /**
<> 148:21d94c44109e 722 * The asynchronous TX and RX handler.
<> 148:21d94c44109e 723 *
<> 148:21d94c44109e 724 * @param obj The serial object
<> 148:21d94c44109e 725 * @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise
<> 148:21d94c44109e 726 */
<> 148:21d94c44109e 727 int serial_irq_handler_asynch(serial_t *obj)
<> 148:21d94c44109e 728 {
<> 148:21d94c44109e 729 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 730 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 731
<> 148:21d94c44109e 732 volatile int return_event = 0;
<> 148:21d94c44109e 733 uint8_t *buf = (uint8_t*)(obj->rx_buff.buffer);
<> 148:21d94c44109e 734 uint8_t i = 0;
<> 148:21d94c44109e 735
<> 148:21d94c44109e 736 // TX PART:
<> 148:21d94c44109e 737 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
<> 148:21d94c44109e 738 if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
<> 148:21d94c44109e 739 // Return event SERIAL_EVENT_TX_COMPLETE if requested
<> 148:21d94c44109e 740 if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE ) != 0) {
<> 148:21d94c44109e 741 return_event |= (SERIAL_EVENT_TX_COMPLETE & obj_s->events);
<> 148:21d94c44109e 742 }
<> 148:21d94c44109e 743 }
<> 148:21d94c44109e 744 }
<> 148:21d94c44109e 745
<> 148:21d94c44109e 746 // Handle error events
<> 148:21d94c44109e 747 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
<> 148:21d94c44109e 748 if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
<> 148:21d94c44109e 749 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
<> 148:21d94c44109e 750 return_event |= (SERIAL_EVENT_RX_PARITY_ERROR & obj_s->events);
<> 148:21d94c44109e 751 }
<> 148:21d94c44109e 752 }
<> 148:21d94c44109e 753
<> 148:21d94c44109e 754 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
<> 148:21d94c44109e 755 if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
<> 148:21d94c44109e 756 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
<> 148:21d94c44109e 757 return_event |= (SERIAL_EVENT_RX_FRAMING_ERROR & obj_s->events);
<> 148:21d94c44109e 758 }
<> 148:21d94c44109e 759 }
<> 148:21d94c44109e 760
<> 148:21d94c44109e 761 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) {
<> 148:21d94c44109e 762 if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
<> 148:21d94c44109e 763 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
<> 148:21d94c44109e 764 }
<> 148:21d94c44109e 765 }
<> 148:21d94c44109e 766
<> 148:21d94c44109e 767 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
<> 148:21d94c44109e 768 if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) {
<> 148:21d94c44109e 769 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
<> 148:21d94c44109e 770 return_event |= (SERIAL_EVENT_RX_OVERRUN_ERROR & obj_s->events);
<> 148:21d94c44109e 771 }
<> 148:21d94c44109e 772 }
<> 148:21d94c44109e 773
<> 148:21d94c44109e 774 HAL_UART_IRQHandler(huart);
<> 148:21d94c44109e 775
<> 148:21d94c44109e 776 // Abort if an error occurs
<> 148:21d94c44109e 777 if (return_event & SERIAL_EVENT_RX_PARITY_ERROR ||
<> 148:21d94c44109e 778 return_event & SERIAL_EVENT_RX_FRAMING_ERROR ||
<> 148:21d94c44109e 779 return_event & SERIAL_EVENT_RX_OVERRUN_ERROR) {
<> 148:21d94c44109e 780 return return_event;
<> 148:21d94c44109e 781 }
<> 148:21d94c44109e 782
<> 148:21d94c44109e 783 //RX PART
<> 148:21d94c44109e 784 if (huart->RxXferSize != 0) {
<> 148:21d94c44109e 785 obj->rx_buff.pos = huart->RxXferSize - huart->RxXferCount;
<> 148:21d94c44109e 786 }
<> 148:21d94c44109e 787 if ((huart->RxXferCount == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
<> 148:21d94c44109e 788 return_event |= (SERIAL_EVENT_RX_COMPLETE & obj_s->events);
<> 148:21d94c44109e 789 }
<> 148:21d94c44109e 790
<> 148:21d94c44109e 791 // Check if char_match is present
<> 148:21d94c44109e 792 if (obj_s->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
<> 148:21d94c44109e 793 if (buf != NULL) {
<> 148:21d94c44109e 794 for (i = 0; i < obj->rx_buff.pos; i++) {
<> 148:21d94c44109e 795 if (buf[i] == obj->char_match) {
<> 148:21d94c44109e 796 obj->rx_buff.pos = i;
<> 148:21d94c44109e 797 return_event |= (SERIAL_EVENT_RX_CHARACTER_MATCH & obj_s->events);
<> 148:21d94c44109e 798 serial_rx_abort_asynch(obj);
<> 148:21d94c44109e 799 break;
<> 148:21d94c44109e 800 }
<> 148:21d94c44109e 801 }
<> 148:21d94c44109e 802 }
<> 148:21d94c44109e 803 }
<> 148:21d94c44109e 804
<> 148:21d94c44109e 805 return return_event;
<> 148:21d94c44109e 806 }
<> 148:21d94c44109e 807
<> 148:21d94c44109e 808 /**
<> 148:21d94c44109e 809 * Abort the ongoing TX transaction. It disables the enabled interupt for TX and
<> 148:21d94c44109e 810 * flush TX hardware buffer if TX FIFO is used
<> 148:21d94c44109e 811 *
<> 148:21d94c44109e 812 * @param obj The serial object
<> 148:21d94c44109e 813 */
<> 148:21d94c44109e 814 void serial_tx_abort_asynch(serial_t *obj)
<> 148:21d94c44109e 815 {
<> 148:21d94c44109e 816 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 817 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 818
<> 148:21d94c44109e 819 __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
<> 148:21d94c44109e 820 __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
<> 148:21d94c44109e 821
<> 148:21d94c44109e 822 // clear flags
<> 148:21d94c44109e 823 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
<> 148:21d94c44109e 824
<> 148:21d94c44109e 825 // reset states
<> 148:21d94c44109e 826 huart->TxXferCount = 0;
<> 148:21d94c44109e 827 // update handle state
<> 148:21d94c44109e 828 if(huart->State == HAL_UART_STATE_BUSY_TX_RX) {
<> 148:21d94c44109e 829 huart->State = HAL_UART_STATE_BUSY_RX;
<> 148:21d94c44109e 830 } else {
<> 148:21d94c44109e 831 huart->State = HAL_UART_STATE_READY;
<> 148:21d94c44109e 832 }
<> 148:21d94c44109e 833 }
<> 148:21d94c44109e 834
<> 148:21d94c44109e 835 /**
<> 148:21d94c44109e 836 * Abort the ongoing RX transaction It disables the enabled interrupt for RX and
<> 148:21d94c44109e 837 * flush RX hardware buffer if RX FIFO is used
<> 148:21d94c44109e 838 *
<> 148:21d94c44109e 839 * @param obj The serial object
<> 148:21d94c44109e 840 */
<> 148:21d94c44109e 841 void serial_rx_abort_asynch(serial_t *obj)
<> 148:21d94c44109e 842 {
<> 148:21d94c44109e 843 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 844 UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
<> 148:21d94c44109e 845
<> 148:21d94c44109e 846 // disable interrupts
<> 148:21d94c44109e 847 __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
<> 148:21d94c44109e 848 __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
<> 148:21d94c44109e 849 __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
<> 148:21d94c44109e 850
<> 148:21d94c44109e 851 // clear flags
<> 148:21d94c44109e 852 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF | UART_CLEAR_FEF | UART_CLEAR_OREF);
<> 148:21d94c44109e 853 volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
<> 148:21d94c44109e 854
<> 148:21d94c44109e 855 // reset states
<> 148:21d94c44109e 856 huart->RxXferCount = 0;
<> 148:21d94c44109e 857 // update handle state
<> 148:21d94c44109e 858 if(huart->State == HAL_UART_STATE_BUSY_TX_RX) {
<> 148:21d94c44109e 859 huart->State = HAL_UART_STATE_BUSY_TX;
<> 148:21d94c44109e 860 } else {
<> 148:21d94c44109e 861 huart->State = HAL_UART_STATE_READY;
<> 148:21d94c44109e 862 }
<> 144:ef7eb2e8f9f7 863 }
<> 144:ef7eb2e8f9f7 864
<> 144:ef7eb2e8f9f7 865 #endif
<> 148:21d94c44109e 866
<> 148:21d94c44109e 867 #if DEVICE_SERIAL_FC
<> 148:21d94c44109e 868
<> 148:21d94c44109e 869 /**
<> 148:21d94c44109e 870 * Set HW Control Flow
<> 148:21d94c44109e 871 * @param obj The serial object
<> 148:21d94c44109e 872 * @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
<> 148:21d94c44109e 873 * @param rxflow Pin for the rxflow
<> 148:21d94c44109e 874 * @param txflow Pin for the txflow
<> 148:21d94c44109e 875 */
<> 148:21d94c44109e 876 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
<> 148:21d94c44109e 877 {
<> 148:21d94c44109e 878 struct serial_s *obj_s = SERIAL_S(obj);
<> 148:21d94c44109e 879
<> 148:21d94c44109e 880 // Determine the UART to use (UART_1, UART_2, ...)
<> 148:21d94c44109e 881 UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
<> 148:21d94c44109e 882 UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
<> 148:21d94c44109e 883
<> 148:21d94c44109e 884 // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
<> 148:21d94c44109e 885 obj_s->uart = (UARTName)pinmap_merge(uart_cts, uart_rts);
<> 148:21d94c44109e 886 MBED_ASSERT(obj_s->uart != (UARTName)NC);
<> 148:21d94c44109e 887
<> 148:21d94c44109e 888 if(type == FlowControlNone) {
<> 148:21d94c44109e 889 // Disable hardware flow control
<> 148:21d94c44109e 890 obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
<> 148:21d94c44109e 891 }
<> 148:21d94c44109e 892 if (type == FlowControlRTS) {
<> 148:21d94c44109e 893 // Enable RTS
<> 148:21d94c44109e 894 MBED_ASSERT(uart_rts != (UARTName)NC);
<> 148:21d94c44109e 895 obj_s->hw_flow_ctl = UART_HWCONTROL_RTS;
<> 148:21d94c44109e 896 obj_s->pin_rts = rxflow;
<> 148:21d94c44109e 897 // Enable the pin for RTS function
<> 148:21d94c44109e 898 pinmap_pinout(rxflow, PinMap_UART_RTS);
<> 148:21d94c44109e 899 }
<> 148:21d94c44109e 900 if (type == FlowControlCTS) {
<> 148:21d94c44109e 901 // Enable CTS
<> 148:21d94c44109e 902 MBED_ASSERT(uart_cts != (UARTName)NC);
<> 148:21d94c44109e 903 obj_s->hw_flow_ctl = UART_HWCONTROL_CTS;
<> 148:21d94c44109e 904 obj_s->pin_cts = txflow;
<> 148:21d94c44109e 905 // Enable the pin for CTS function
<> 148:21d94c44109e 906 pinmap_pinout(txflow, PinMap_UART_CTS);
<> 148:21d94c44109e 907 }
<> 148:21d94c44109e 908 if (type == FlowControlRTSCTS) {
<> 148:21d94c44109e 909 // Enable CTS & RTS
<> 148:21d94c44109e 910 MBED_ASSERT(uart_rts != (UARTName)NC);
<> 148:21d94c44109e 911 MBED_ASSERT(uart_cts != (UARTName)NC);
<> 148:21d94c44109e 912 obj_s->hw_flow_ctl = UART_HWCONTROL_RTS_CTS;
<> 148:21d94c44109e 913 obj_s->pin_rts = rxflow;
<> 148:21d94c44109e 914 obj_s->pin_cts = txflow;
<> 148:21d94c44109e 915 // Enable the pin for CTS function
<> 148:21d94c44109e 916 pinmap_pinout(txflow, PinMap_UART_CTS);
<> 148:21d94c44109e 917 // Enable the pin for RTS function
<> 148:21d94c44109e 918 pinmap_pinout(rxflow, PinMap_UART_RTS);
<> 148:21d94c44109e 919 }
<> 148:21d94c44109e 920
<> 148:21d94c44109e 921 init_uart(obj);
<> 148:21d94c44109e 922 }
<> 148:21d94c44109e 923
<> 148:21d94c44109e 924 #endif
<> 148:21d94c44109e 925
<> 148:21d94c44109e 926 #endif