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