test

Committer:
elijahsj
Date:
Mon Nov 09 00:33:19 2020 -0500
Revision:
2:4364577b5ad8
Parent:
1:8a094db1347f
copied mbed library

Who changed what in which revision?

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