Modification of Mbed-dev library for LQFP48 package microcontrollers: STM32F103C8 (STM32F103C8T6) and STM32F103CB (STM32F103CBT6) (Bluepill boards, Maple mini etc. )

Fork of mbed-STM32F103C8_org by Nothing Special

Library for STM32F103C8 (Bluepill boards etc.).
Use this instead of mbed library.
This library allows the size of the code in the FLASH up to 128kB. Therefore, code also runs on microcontrollers STM32F103CB (eg. Maple mini).
But in the case of STM32F103C8, check the size of the resulting code would not exceed 64kB.

To compile a program with this library, use NUCLEO-F103RB as the target name. !

Changes:

  • Corrected initialization of the HSE + crystal clock (mbed permanent bug), allowing the use of on-board xtal (8MHz).(1)
  • Additionally, it also set USB clock (48Mhz).(2)
  • Definitions of pins and peripherals adjusted to LQFP48 case.
  • Board led LED1 is now PC_13 (3)
  • USER_BUTTON is now PC_14 (4)

    Now the library is complete rebuilt based on mbed-dev v160 (and not yet fully tested).

notes
(1) - In case 8MHz xtal on board, CPU frequency is 72MHz. Without xtal is 64MHz.
(2) - Using the USB interface is only possible if STM32 is clocking by on-board 8MHz xtal or external clock signal 8MHz on the OSC_IN pin.
(3) - On Bluepill board led operation is reversed, i.e. 0 - led on, 1 - led off.
(4) - Bluepill board has no real user button

Information

After export to SW4STM (AC6):

  • add line #include "mbed_config.h" in files Serial.h and RawSerial.h
  • in project properties change Optimisation Level to Optimise for size (-Os)
Committer:
mega64
Date:
Thu Mar 16 06:15:53 2017 +0000
Revision:
146:03e976389d16
fully rebuild, now based on mbed-dev v160

Who changed what in which revision?

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