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