Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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