Aditya Mehrotra / mbed-dev

Dependents:   CAN_TEST SPIne_Plus_DYNO_SENSORS SPIne_Plus_v2 SPIne_Plus_Dyno_v2

Committer:
saloutos
Date:
Thu Nov 26 04:08:56 2020 +0000
Revision:
0:083111ae2a11
first commit of leaned mbed dev lib

Who changed what in which revision?

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