mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 189:f392fc9709a3 1 /* mbed Microcontroller Library
AnnaBridge 189:f392fc9709a3 2 * Copyright (c) 2018 GigaDevice Semiconductor Inc.
AnnaBridge 189:f392fc9709a3 3 *
AnnaBridge 189:f392fc9709a3 4 * SPDX-License-Identifier: Apache-2.0
AnnaBridge 189:f392fc9709a3 5 *
AnnaBridge 189:f392fc9709a3 6 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 189:f392fc9709a3 7 * you may not use this file except in compliance with the License.
AnnaBridge 189:f392fc9709a3 8 * You may obtain a copy of the License at
AnnaBridge 189:f392fc9709a3 9 *
AnnaBridge 189:f392fc9709a3 10 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 189:f392fc9709a3 11 *
AnnaBridge 189:f392fc9709a3 12 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 189:f392fc9709a3 13 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 189:f392fc9709a3 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 189:f392fc9709a3 15 * See the License for the specific language governing permissions and
AnnaBridge 189:f392fc9709a3 16 * limitations under the License.
AnnaBridge 189:f392fc9709a3 17 */
AnnaBridge 189:f392fc9709a3 18 #include "mbed_assert.h"
AnnaBridge 189:f392fc9709a3 19 #include "serial_api.h"
AnnaBridge 189:f392fc9709a3 20
AnnaBridge 189:f392fc9709a3 21 #if DEVICE_SERIAL
AnnaBridge 189:f392fc9709a3 22
AnnaBridge 189:f392fc9709a3 23 #include "cmsis.h"
AnnaBridge 189:f392fc9709a3 24 #include "pinmap.h"
AnnaBridge 189:f392fc9709a3 25 #include "mbed_error.h"
AnnaBridge 189:f392fc9709a3 26 #include <string.h>
AnnaBridge 189:f392fc9709a3 27 #include "PeripheralPins.h"
AnnaBridge 189:f392fc9709a3 28
AnnaBridge 189:f392fc9709a3 29 #define USART_NUM (5)
AnnaBridge 189:f392fc9709a3 30
AnnaBridge 189:f392fc9709a3 31 static uint32_t serial_irq_ids[USART_NUM] = {0};
AnnaBridge 189:f392fc9709a3 32 static rcu_periph_enum usart_clk[USART_NUM] = {RCU_USART0, RCU_USART1, RCU_USART2, RCU_UART3, RCU_UART4};
AnnaBridge 189:f392fc9709a3 33 static IRQn_Type usart_irq_n[USART_NUM] = {USART0_IRQn, USART1_IRQn, USART2_IRQn, UART3_IRQn, UART4_IRQn};
AnnaBridge 189:f392fc9709a3 34
AnnaBridge 189:f392fc9709a3 35 static uart_irq_handler irq_handler;
AnnaBridge 189:f392fc9709a3 36
AnnaBridge 189:f392fc9709a3 37 int stdio_uart_inited = 0;
AnnaBridge 189:f392fc9709a3 38 serial_t stdio_uart;
AnnaBridge 189:f392fc9709a3 39
AnnaBridge 189:f392fc9709a3 40 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 189:f392fc9709a3 41 #define GET_SERIAL_S(obj) (&((obj)->serial))
AnnaBridge 189:f392fc9709a3 42 #else
AnnaBridge 189:f392fc9709a3 43 #define GET_SERIAL_S(obj) (obj)
AnnaBridge 189:f392fc9709a3 44 #endif /* DEVICE_SERIAL_ASYNCH */
AnnaBridge 189:f392fc9709a3 45
AnnaBridge 189:f392fc9709a3 46 /** Initialize the USART peripheral.
AnnaBridge 189:f392fc9709a3 47 *
AnnaBridge 189:f392fc9709a3 48 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 49 */
AnnaBridge 189:f392fc9709a3 50 static void usart_init(struct serial_s *obj_s)
AnnaBridge 189:f392fc9709a3 51 {
AnnaBridge 189:f392fc9709a3 52 if (obj_s->index >= USART_NUM) {
AnnaBridge 189:f392fc9709a3 53 return;
AnnaBridge 189:f392fc9709a3 54 }
AnnaBridge 189:f392fc9709a3 55
AnnaBridge 189:f392fc9709a3 56 /* USART configuration */
AnnaBridge 189:f392fc9709a3 57 usart_deinit(obj_s->uart);
AnnaBridge 189:f392fc9709a3 58 usart_word_length_set(obj_s->uart, obj_s->databits);
AnnaBridge 189:f392fc9709a3 59 usart_baudrate_set(obj_s->uart, obj_s->baudrate);
AnnaBridge 189:f392fc9709a3 60 usart_stop_bit_set(obj_s->uart, obj_s->stopbits);
AnnaBridge 189:f392fc9709a3 61 usart_parity_config(obj_s->uart, obj_s->parity);
AnnaBridge 189:f392fc9709a3 62 #if DEVICE_SERIAL_FC
AnnaBridge 189:f392fc9709a3 63 if (obj_s->hw_flow_ctl == USART_HWCONTROL_NONE) {
AnnaBridge 189:f392fc9709a3 64 usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_DISABLE);
AnnaBridge 189:f392fc9709a3 65 usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_DISABLE);
AnnaBridge 189:f392fc9709a3 66 } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_RTS) {
AnnaBridge 189:f392fc9709a3 67 usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_DISABLE);
AnnaBridge 189:f392fc9709a3 68 usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_ENABLE);
AnnaBridge 189:f392fc9709a3 69 } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_CTS) {
AnnaBridge 189:f392fc9709a3 70 usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_ENABLE);
AnnaBridge 189:f392fc9709a3 71 usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_DISABLE);
AnnaBridge 189:f392fc9709a3 72 } else if (obj_s->hw_flow_ctl == USART_HWCONTROL_RTS_CTS) {
AnnaBridge 189:f392fc9709a3 73 usart_hardware_flow_cts_config(obj_s->uart, USART_CTS_ENABLE);
AnnaBridge 189:f392fc9709a3 74 usart_hardware_flow_rts_config(obj_s->uart, USART_RTS_ENABLE);
AnnaBridge 189:f392fc9709a3 75 }
AnnaBridge 189:f392fc9709a3 76 #endif /* DEVICE_SERIAL_FC */
AnnaBridge 189:f392fc9709a3 77 usart_receive_config(obj_s->uart, USART_RECEIVE_ENABLE);
AnnaBridge 189:f392fc9709a3 78 usart_transmit_config(obj_s->uart, USART_TRANSMIT_ENABLE);
AnnaBridge 189:f392fc9709a3 79 usart_enable(obj_s->uart);
AnnaBridge 189:f392fc9709a3 80 }
AnnaBridge 189:f392fc9709a3 81
AnnaBridge 189:f392fc9709a3 82 /** Initialize the serial peripheral. It sets the default parameters for serial
AnnaBridge 189:f392fc9709a3 83 * peripheral, and configures its specifieds pins.
AnnaBridge 189:f392fc9709a3 84 *
AnnaBridge 189:f392fc9709a3 85 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 86 * @param tx The TX pin name
AnnaBridge 189:f392fc9709a3 87 * @param rx The RX pin name
AnnaBridge 189:f392fc9709a3 88 */
AnnaBridge 189:f392fc9709a3 89 void serial_init(serial_t *obj, PinName tx, PinName rx)
AnnaBridge 189:f392fc9709a3 90 {
AnnaBridge 189:f392fc9709a3 91 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 92
AnnaBridge 189:f392fc9709a3 93 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 94 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
AnnaBridge 189:f392fc9709a3 95
AnnaBridge 189:f392fc9709a3 96 p_obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
AnnaBridge 189:f392fc9709a3 97 MBED_ASSERT(p_obj->uart != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 98
AnnaBridge 189:f392fc9709a3 99 /* enable UART peripheral clock */
AnnaBridge 189:f392fc9709a3 100 if (p_obj->uart == UART_0) {
AnnaBridge 189:f392fc9709a3 101 p_obj->index = 0;
AnnaBridge 189:f392fc9709a3 102 rcu_periph_clock_enable(usart_clk[p_obj->index]);
AnnaBridge 189:f392fc9709a3 103 } else if (p_obj->uart == UART_1) {
AnnaBridge 189:f392fc9709a3 104 p_obj->index = 1;
AnnaBridge 189:f392fc9709a3 105 rcu_periph_clock_enable(usart_clk[p_obj->index]);
AnnaBridge 189:f392fc9709a3 106 } else if (p_obj->uart == UART_2) {
AnnaBridge 189:f392fc9709a3 107 p_obj->index = 2;
AnnaBridge 189:f392fc9709a3 108 rcu_periph_clock_enable(usart_clk[p_obj->index]);
AnnaBridge 189:f392fc9709a3 109 } else if (p_obj->uart == UART_3) {
AnnaBridge 189:f392fc9709a3 110 p_obj->index = 3;
AnnaBridge 189:f392fc9709a3 111 rcu_periph_clock_enable(usart_clk[p_obj->index]);
AnnaBridge 189:f392fc9709a3 112 } else if (p_obj->uart == UART_4) {
AnnaBridge 189:f392fc9709a3 113 p_obj->index = 4;
AnnaBridge 189:f392fc9709a3 114 rcu_periph_clock_enable(usart_clk[p_obj->index]);
AnnaBridge 189:f392fc9709a3 115 }
AnnaBridge 189:f392fc9709a3 116
AnnaBridge 189:f392fc9709a3 117 /* configurte the pins */
AnnaBridge 189:f392fc9709a3 118 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 119 pinmap_pinout(rx, PinMap_UART_RX);
AnnaBridge 189:f392fc9709a3 120
AnnaBridge 189:f392fc9709a3 121 /* default UART parameters */
AnnaBridge 189:f392fc9709a3 122 p_obj->baudrate = 9600U;
AnnaBridge 189:f392fc9709a3 123 p_obj->databits = USART_WL_8BIT;
AnnaBridge 189:f392fc9709a3 124 p_obj->stopbits = USART_STB_1BIT;
AnnaBridge 189:f392fc9709a3 125 p_obj->parity = USART_PM_NONE;
AnnaBridge 189:f392fc9709a3 126
AnnaBridge 189:f392fc9709a3 127 #if DEVICE_SERIAL_FC
AnnaBridge 189:f392fc9709a3 128 p_obj->hw_flow_ctl = USART_HWCONTROL_NONE;
AnnaBridge 189:f392fc9709a3 129 #endif /* DEVICE_SERIAL_FC */
AnnaBridge 189:f392fc9709a3 130
AnnaBridge 189:f392fc9709a3 131 p_obj->pin_tx = tx;
AnnaBridge 189:f392fc9709a3 132 p_obj->pin_rx = rx;
AnnaBridge 189:f392fc9709a3 133
AnnaBridge 189:f392fc9709a3 134 p_obj->tx_state = OP_STATE_BUSY;
AnnaBridge 189:f392fc9709a3 135 p_obj->rx_state = OP_STATE_BUSY;
AnnaBridge 189:f392fc9709a3 136
AnnaBridge 189:f392fc9709a3 137 usart_init(p_obj);
AnnaBridge 189:f392fc9709a3 138
AnnaBridge 189:f392fc9709a3 139 p_obj->tx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 140 p_obj->rx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 141
AnnaBridge 189:f392fc9709a3 142 if (p_obj->uart == STDIO_UART) {
AnnaBridge 189:f392fc9709a3 143 stdio_uart_inited = 1;
AnnaBridge 189:f392fc9709a3 144 memcpy(&stdio_uart, obj, sizeof(serial_t));
AnnaBridge 189:f392fc9709a3 145 }
AnnaBridge 189:f392fc9709a3 146 }
AnnaBridge 189:f392fc9709a3 147
AnnaBridge 189:f392fc9709a3 148 /** Release the serial peripheral, not currently invoked. It requires further
AnnaBridge 189:f392fc9709a3 149 * resource management.
AnnaBridge 189:f392fc9709a3 150 *
AnnaBridge 189:f392fc9709a3 151 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 152 */
AnnaBridge 189:f392fc9709a3 153 void serial_free(serial_t *obj)
AnnaBridge 189:f392fc9709a3 154 {
AnnaBridge 189:f392fc9709a3 155 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 156 rcu_periph_enum rcu_periph = usart_clk[p_obj->index];
AnnaBridge 189:f392fc9709a3 157
AnnaBridge 189:f392fc9709a3 158 /* reset USART and disable clock */
AnnaBridge 189:f392fc9709a3 159 usart_deinit(p_obj->uart);
AnnaBridge 189:f392fc9709a3 160 rcu_periph_clock_disable(rcu_periph);
AnnaBridge 189:f392fc9709a3 161
AnnaBridge 189:f392fc9709a3 162 serial_irq_ids[p_obj->index] = 0;
AnnaBridge 189:f392fc9709a3 163
AnnaBridge 189:f392fc9709a3 164 /* reset the GPIO state */
AnnaBridge 189:f392fc9709a3 165 pin_function(p_obj->pin_tx, MODE_IN_FLOATING);
AnnaBridge 189:f392fc9709a3 166 pin_function(p_obj->pin_rx, MODE_IN_FLOATING);
AnnaBridge 189:f392fc9709a3 167 }
AnnaBridge 189:f392fc9709a3 168
AnnaBridge 189:f392fc9709a3 169 /** Configure the baud rate
AnnaBridge 189:f392fc9709a3 170 *
AnnaBridge 189:f392fc9709a3 171 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 172 * @param baudrate The baud rate to be configured
AnnaBridge 189:f392fc9709a3 173 */
AnnaBridge 189:f392fc9709a3 174 void serial_baud(serial_t *obj, int baudrate)
AnnaBridge 189:f392fc9709a3 175 {
AnnaBridge 189:f392fc9709a3 176 uint16_t uen_flag = 0U;
AnnaBridge 189:f392fc9709a3 177 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 178
AnnaBridge 189:f392fc9709a3 179 /* store the UEN flag */
AnnaBridge 189:f392fc9709a3 180 uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
AnnaBridge 189:f392fc9709a3 181
AnnaBridge 189:f392fc9709a3 182 /* disable the USART first */
AnnaBridge 189:f392fc9709a3 183 usart_disable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 184
AnnaBridge 189:f392fc9709a3 185 usart_baudrate_set(p_obj->uart, baudrate);
AnnaBridge 189:f392fc9709a3 186
AnnaBridge 189:f392fc9709a3 187 p_obj->baudrate = baudrate;
AnnaBridge 189:f392fc9709a3 188
AnnaBridge 189:f392fc9709a3 189 /* restore the UEN flag */
AnnaBridge 189:f392fc9709a3 190 if (RESET != uen_flag) {
AnnaBridge 189:f392fc9709a3 191 usart_enable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 192 }
AnnaBridge 189:f392fc9709a3 193 }
AnnaBridge 189:f392fc9709a3 194
AnnaBridge 189:f392fc9709a3 195 /** Configure the format. Set the number of bits, parity and the number of stop bits
AnnaBridge 189:f392fc9709a3 196 *
AnnaBridge 189:f392fc9709a3 197 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 198 * @param data_bits The number of data bits
AnnaBridge 189:f392fc9709a3 199 * @param parity The parity
AnnaBridge 189:f392fc9709a3 200 * @param stop_bits The number of stop bits
AnnaBridge 189:f392fc9709a3 201 */
AnnaBridge 189:f392fc9709a3 202 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
AnnaBridge 189:f392fc9709a3 203 {
AnnaBridge 189:f392fc9709a3 204 uint16_t uen_flag = 0U;
AnnaBridge 189:f392fc9709a3 205 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 206
AnnaBridge 189:f392fc9709a3 207 /* store the UEN flag */
AnnaBridge 189:f392fc9709a3 208 uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
AnnaBridge 189:f392fc9709a3 209
AnnaBridge 189:f392fc9709a3 210 /* disable the UART clock first */
AnnaBridge 189:f392fc9709a3 211 usart_disable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 212
AnnaBridge 189:f392fc9709a3 213 /* configurate the UART parity */
AnnaBridge 189:f392fc9709a3 214 switch (parity) {
AnnaBridge 189:f392fc9709a3 215 case ParityOdd:
AnnaBridge 189:f392fc9709a3 216 p_obj->parity = USART_PM_ODD;
AnnaBridge 189:f392fc9709a3 217 usart_parity_config(p_obj->uart, USART_PM_ODD);
AnnaBridge 189:f392fc9709a3 218 break;
AnnaBridge 189:f392fc9709a3 219
AnnaBridge 189:f392fc9709a3 220 case ParityEven:
AnnaBridge 189:f392fc9709a3 221 p_obj->parity = USART_PM_EVEN;
AnnaBridge 189:f392fc9709a3 222 usart_parity_config(p_obj->uart, USART_PM_EVEN);
AnnaBridge 189:f392fc9709a3 223 break;
AnnaBridge 189:f392fc9709a3 224
AnnaBridge 189:f392fc9709a3 225 case ParityForced0:
AnnaBridge 189:f392fc9709a3 226 case ParityForced1:
AnnaBridge 189:f392fc9709a3 227 default:
AnnaBridge 189:f392fc9709a3 228 p_obj->parity = USART_PM_NONE;
AnnaBridge 189:f392fc9709a3 229 usart_parity_config(p_obj->uart, USART_PM_NONE);
AnnaBridge 189:f392fc9709a3 230 break;
AnnaBridge 189:f392fc9709a3 231 }
AnnaBridge 189:f392fc9709a3 232
AnnaBridge 189:f392fc9709a3 233 if (p_obj->parity == USART_PM_NONE) {
AnnaBridge 189:f392fc9709a3 234 if (data_bits == 9) {
AnnaBridge 189:f392fc9709a3 235 usart_word_length_set(p_obj->uart, USART_WL_9BIT);
AnnaBridge 189:f392fc9709a3 236 } else if (data_bits == 8) {
AnnaBridge 189:f392fc9709a3 237 usart_word_length_set(p_obj->uart, USART_WL_8BIT);
AnnaBridge 189:f392fc9709a3 238 } else if (data_bits == 7) {
AnnaBridge 189:f392fc9709a3 239 return;
AnnaBridge 189:f392fc9709a3 240 }
AnnaBridge 189:f392fc9709a3 241 } else {
AnnaBridge 189:f392fc9709a3 242 if (data_bits == 9) {
AnnaBridge 189:f392fc9709a3 243 return;
AnnaBridge 189:f392fc9709a3 244 } else if (data_bits == 8) {
AnnaBridge 189:f392fc9709a3 245 usart_word_length_set(p_obj->uart, USART_WL_9BIT);
AnnaBridge 189:f392fc9709a3 246 } else if (data_bits == 7) {
AnnaBridge 189:f392fc9709a3 247 usart_word_length_set(p_obj->uart, USART_WL_8BIT);
AnnaBridge 189:f392fc9709a3 248 }
AnnaBridge 189:f392fc9709a3 249 }
AnnaBridge 189:f392fc9709a3 250
AnnaBridge 189:f392fc9709a3 251 if (stop_bits == 2) {
AnnaBridge 189:f392fc9709a3 252 usart_stop_bit_set(p_obj->uart, USART_STB_2BIT);
AnnaBridge 189:f392fc9709a3 253 } else {
AnnaBridge 189:f392fc9709a3 254 usart_stop_bit_set(p_obj->uart, USART_STB_1BIT);
AnnaBridge 189:f392fc9709a3 255 }
AnnaBridge 189:f392fc9709a3 256
AnnaBridge 189:f392fc9709a3 257 /* restore the UEN flag */
AnnaBridge 189:f392fc9709a3 258 if (RESET != uen_flag) {
AnnaBridge 189:f392fc9709a3 259 usart_enable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 260 }
AnnaBridge 189:f392fc9709a3 261 }
AnnaBridge 189:f392fc9709a3 262
AnnaBridge 189:f392fc9709a3 263 /** The serial interrupt handler registration
AnnaBridge 189:f392fc9709a3 264 *
AnnaBridge 189:f392fc9709a3 265 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 266 * @param handler The interrupt handler which will be invoked when the interrupt fires
AnnaBridge 189:f392fc9709a3 267 * @param id The SerialBase object
AnnaBridge 189:f392fc9709a3 268 */
AnnaBridge 189:f392fc9709a3 269 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
AnnaBridge 189:f392fc9709a3 270 {
AnnaBridge 189:f392fc9709a3 271 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 272
AnnaBridge 189:f392fc9709a3 273 irq_handler = handler;
AnnaBridge 189:f392fc9709a3 274 serial_irq_ids[p_obj->index] = id;
AnnaBridge 189:f392fc9709a3 275 }
AnnaBridge 189:f392fc9709a3 276
AnnaBridge 189:f392fc9709a3 277 /** This function handles USART interrupt handler
AnnaBridge 189:f392fc9709a3 278 *
AnnaBridge 189:f392fc9709a3 279 * @param usart_index The index of UART
AnnaBridge 189:f392fc9709a3 280 * @param usart_periph The UART peripheral
AnnaBridge 189:f392fc9709a3 281 */
AnnaBridge 189:f392fc9709a3 282 static void usart_irq(int usart_index, uint32_t usart_periph)
AnnaBridge 189:f392fc9709a3 283 {
AnnaBridge 189:f392fc9709a3 284 if (serial_irq_ids[usart_index] != 0) {
AnnaBridge 189:f392fc9709a3 285 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_TC) != RESET) {
AnnaBridge 189:f392fc9709a3 286 usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_TC);
AnnaBridge 189:f392fc9709a3 287 irq_handler(serial_irq_ids[usart_index], TxIrq);
AnnaBridge 189:f392fc9709a3 288 }
AnnaBridge 189:f392fc9709a3 289
AnnaBridge 189:f392fc9709a3 290 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_RBNE) != RESET) {
AnnaBridge 189:f392fc9709a3 291 usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_RBNE);
AnnaBridge 189:f392fc9709a3 292 irq_handler(serial_irq_ids[usart_index], RxIrq);
AnnaBridge 189:f392fc9709a3 293 }
AnnaBridge 189:f392fc9709a3 294
AnnaBridge 189:f392fc9709a3 295 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_ORERR) != RESET) {
AnnaBridge 189:f392fc9709a3 296 /* clear ORERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 297 USART_DATA(usart_periph);
AnnaBridge 189:f392fc9709a3 298 }
AnnaBridge 189:f392fc9709a3 299
AnnaBridge 189:f392fc9709a3 300 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_NERR) != RESET) {
AnnaBridge 189:f392fc9709a3 301 /* clear NERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 302 USART_DATA(usart_periph);
AnnaBridge 189:f392fc9709a3 303 }
AnnaBridge 189:f392fc9709a3 304
AnnaBridge 189:f392fc9709a3 305 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_FERR) != RESET) {
AnnaBridge 189:f392fc9709a3 306 /* clear FERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 307 USART_DATA(usart_periph);
AnnaBridge 189:f392fc9709a3 308 }
AnnaBridge 189:f392fc9709a3 309
AnnaBridge 189:f392fc9709a3 310 if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_PERR) != RESET) {
AnnaBridge 189:f392fc9709a3 311 /* clear PERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 312 USART_DATA(usart_periph);
AnnaBridge 189:f392fc9709a3 313 }
AnnaBridge 189:f392fc9709a3 314 }
AnnaBridge 189:f392fc9709a3 315 }
AnnaBridge 189:f392fc9709a3 316
AnnaBridge 189:f392fc9709a3 317 /** This function handles USART0 interrupt handler
AnnaBridge 189:f392fc9709a3 318 *
AnnaBridge 189:f392fc9709a3 319 */
AnnaBridge 189:f392fc9709a3 320 static void usart0_irq(void)
AnnaBridge 189:f392fc9709a3 321 {
AnnaBridge 189:f392fc9709a3 322 usart_irq(0, USART0);
AnnaBridge 189:f392fc9709a3 323 }
AnnaBridge 189:f392fc9709a3 324
AnnaBridge 189:f392fc9709a3 325 /** This function handles USART1 interrupt handler
AnnaBridge 189:f392fc9709a3 326 *
AnnaBridge 189:f392fc9709a3 327 */
AnnaBridge 189:f392fc9709a3 328 static void usart1_irq(void)
AnnaBridge 189:f392fc9709a3 329 {
AnnaBridge 189:f392fc9709a3 330 usart_irq(1, USART1);
AnnaBridge 189:f392fc9709a3 331 }
AnnaBridge 189:f392fc9709a3 332
AnnaBridge 189:f392fc9709a3 333 /** This function handles USART2 interrupt handler
AnnaBridge 189:f392fc9709a3 334 *
AnnaBridge 189:f392fc9709a3 335 */
AnnaBridge 189:f392fc9709a3 336 static void usart2_irq(void)
AnnaBridge 189:f392fc9709a3 337 {
AnnaBridge 189:f392fc9709a3 338 usart_irq(2, USART2);
AnnaBridge 189:f392fc9709a3 339 }
AnnaBridge 189:f392fc9709a3 340
AnnaBridge 189:f392fc9709a3 341 /** This function handles USART3 interrupt handler
AnnaBridge 189:f392fc9709a3 342 *
AnnaBridge 189:f392fc9709a3 343 */
AnnaBridge 189:f392fc9709a3 344 static void uart3_irq(void)
AnnaBridge 189:f392fc9709a3 345 {
AnnaBridge 189:f392fc9709a3 346 usart_irq(3, UART3);
AnnaBridge 189:f392fc9709a3 347 }
AnnaBridge 189:f392fc9709a3 348
AnnaBridge 189:f392fc9709a3 349 /** This function handles USART4 interrupt handler
AnnaBridge 189:f392fc9709a3 350 *
AnnaBridge 189:f392fc9709a3 351 */
AnnaBridge 189:f392fc9709a3 352 static void uart4_irq(void)
AnnaBridge 189:f392fc9709a3 353 {
AnnaBridge 189:f392fc9709a3 354 usart_irq(4, UART4);
AnnaBridge 189:f392fc9709a3 355 }
AnnaBridge 189:f392fc9709a3 356
AnnaBridge 189:f392fc9709a3 357 /** Configure serial interrupt. This function is used for word-approach
AnnaBridge 189:f392fc9709a3 358 *
AnnaBridge 189:f392fc9709a3 359 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 360 * @param irq The serial IRQ type (RX or TX)
AnnaBridge 189:f392fc9709a3 361 * @param enable Set to non-zero to enable events, or zero to disable them
AnnaBridge 189:f392fc9709a3 362 */
AnnaBridge 189:f392fc9709a3 363 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
AnnaBridge 189:f392fc9709a3 364 {
AnnaBridge 189:f392fc9709a3 365 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 366 IRQn_Type irq_n = (IRQn_Type)0;
AnnaBridge 189:f392fc9709a3 367 uint32_t vector = 0;
AnnaBridge 189:f392fc9709a3 368
AnnaBridge 189:f392fc9709a3 369 if (p_obj->uart == USART0) {
AnnaBridge 189:f392fc9709a3 370 irq_n = USART0_IRQn;
AnnaBridge 189:f392fc9709a3 371 vector = (uint32_t)&usart0_irq;
AnnaBridge 189:f392fc9709a3 372 } else if (p_obj->uart == USART1) {
AnnaBridge 189:f392fc9709a3 373 irq_n = USART1_IRQn;
AnnaBridge 189:f392fc9709a3 374 vector = (uint32_t)&usart1_irq;
AnnaBridge 189:f392fc9709a3 375 } else if (p_obj->uart == USART2) {
AnnaBridge 189:f392fc9709a3 376 irq_n = USART2_IRQn;
AnnaBridge 189:f392fc9709a3 377 vector = (uint32_t)&usart2_irq;
AnnaBridge 189:f392fc9709a3 378 } else if (p_obj->uart == UART3) {
AnnaBridge 189:f392fc9709a3 379 irq_n = UART3_IRQn;
AnnaBridge 189:f392fc9709a3 380 vector = (uint32_t)&uart3_irq;
AnnaBridge 189:f392fc9709a3 381 } else if (p_obj->uart == UART4) {
AnnaBridge 189:f392fc9709a3 382 irq_n = UART4_IRQn;
AnnaBridge 189:f392fc9709a3 383 vector = (uint32_t)&uart4_irq;
AnnaBridge 189:f392fc9709a3 384 }
AnnaBridge 189:f392fc9709a3 385
AnnaBridge 189:f392fc9709a3 386 if (enable) {
AnnaBridge 189:f392fc9709a3 387 if (irq == RxIrq) {
AnnaBridge 189:f392fc9709a3 388 /* Rx IRQ */
AnnaBridge 189:f392fc9709a3 389 usart_interrupt_enable(p_obj->uart, USART_INT_RBNE);
AnnaBridge 189:f392fc9709a3 390 } else {
AnnaBridge 189:f392fc9709a3 391 /* Tx IRQ */
AnnaBridge 189:f392fc9709a3 392 usart_interrupt_enable(p_obj->uart, USART_INT_TBE);
AnnaBridge 189:f392fc9709a3 393 }
AnnaBridge 189:f392fc9709a3 394
AnnaBridge 189:f392fc9709a3 395 NVIC_SetVector(irq_n, vector);
AnnaBridge 189:f392fc9709a3 396 NVIC_EnableIRQ(irq_n);
AnnaBridge 189:f392fc9709a3 397 } else {
AnnaBridge 189:f392fc9709a3 398 if (irq == RxIrq) {
AnnaBridge 189:f392fc9709a3 399 /* Rx IRQ */
AnnaBridge 189:f392fc9709a3 400 usart_interrupt_disable(p_obj->uart, USART_INT_RBNE);
AnnaBridge 189:f392fc9709a3 401 } else {
AnnaBridge 189:f392fc9709a3 402 /* Tx IRQ */
AnnaBridge 189:f392fc9709a3 403 usart_interrupt_disable(p_obj->uart, USART_INT_TBE);
AnnaBridge 189:f392fc9709a3 404 }
AnnaBridge 189:f392fc9709a3 405 }
AnnaBridge 189:f392fc9709a3 406 }
AnnaBridge 189:f392fc9709a3 407
AnnaBridge 189:f392fc9709a3 408 /** Get character. This is a blocking call, waiting for a character
AnnaBridge 189:f392fc9709a3 409 *
AnnaBridge 189:f392fc9709a3 410 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 411 */
AnnaBridge 189:f392fc9709a3 412 int serial_getc(serial_t *obj)
AnnaBridge 189:f392fc9709a3 413 {
AnnaBridge 189:f392fc9709a3 414 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 415
AnnaBridge 189:f392fc9709a3 416 while (!serial_readable(obj));
AnnaBridge 189:f392fc9709a3 417 return (int)(usart_data_receive(p_obj->uart) & BITS(0, 7 + (p_obj->databits >> 12)));
AnnaBridge 189:f392fc9709a3 418 }
AnnaBridge 189:f392fc9709a3 419
AnnaBridge 189:f392fc9709a3 420 /** Send a character. This is a blocking call, waiting for a peripheral to be available
AnnaBridge 189:f392fc9709a3 421 * for writing
AnnaBridge 189:f392fc9709a3 422 *
AnnaBridge 189:f392fc9709a3 423 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 424 * @param c The character to be sent
AnnaBridge 189:f392fc9709a3 425 */
AnnaBridge 189:f392fc9709a3 426 void serial_putc(serial_t *obj, int c)
AnnaBridge 189:f392fc9709a3 427 {
AnnaBridge 189:f392fc9709a3 428 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 429
AnnaBridge 189:f392fc9709a3 430 while (!serial_writable(obj));
AnnaBridge 189:f392fc9709a3 431 usart_data_transmit(p_obj->uart, (int)((c) & BITS(0, 7 + (p_obj->databits >> 12))));
AnnaBridge 189:f392fc9709a3 432 }
AnnaBridge 189:f392fc9709a3 433
AnnaBridge 189:f392fc9709a3 434 /** Check if the serial peripheral is readable
AnnaBridge 189:f392fc9709a3 435 *
AnnaBridge 189:f392fc9709a3 436 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 437 * @return Non-zero value if a character can be read, 0 if nothing to read
AnnaBridge 189:f392fc9709a3 438 */
AnnaBridge 189:f392fc9709a3 439 int serial_readable(serial_t *obj)
AnnaBridge 189:f392fc9709a3 440 {
AnnaBridge 189:f392fc9709a3 441 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 442
AnnaBridge 189:f392fc9709a3 443 return (usart_flag_get(p_obj->uart, USART_FLAG_RBNE) != RESET) ? 1 : 0;
AnnaBridge 189:f392fc9709a3 444 }
AnnaBridge 189:f392fc9709a3 445
AnnaBridge 189:f392fc9709a3 446 /** Check if the serial peripheral is writable
AnnaBridge 189:f392fc9709a3 447 *
AnnaBridge 189:f392fc9709a3 448 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 449 * @return Non-zero value if a character can be written, 0 otherwise.
AnnaBridge 189:f392fc9709a3 450 */
AnnaBridge 189:f392fc9709a3 451 int serial_writable(serial_t *obj)
AnnaBridge 189:f392fc9709a3 452 {
AnnaBridge 189:f392fc9709a3 453 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 454
AnnaBridge 189:f392fc9709a3 455 return (usart_flag_get(p_obj->uart, USART_FLAG_TBE) != RESET) ? 1 : 0;
AnnaBridge 189:f392fc9709a3 456 }
AnnaBridge 189:f392fc9709a3 457
AnnaBridge 189:f392fc9709a3 458 /** Clear the serial peripheral
AnnaBridge 189:f392fc9709a3 459 *
AnnaBridge 189:f392fc9709a3 460 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 461 */
AnnaBridge 189:f392fc9709a3 462 void serial_clear(serial_t *obj)
AnnaBridge 189:f392fc9709a3 463 {
AnnaBridge 189:f392fc9709a3 464 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 465
AnnaBridge 189:f392fc9709a3 466 p_obj->tx_count = 0U;
AnnaBridge 189:f392fc9709a3 467 p_obj->rx_count = 0U;
AnnaBridge 189:f392fc9709a3 468 }
AnnaBridge 189:f392fc9709a3 469
AnnaBridge 189:f392fc9709a3 470 /** Set the break
AnnaBridge 189:f392fc9709a3 471 *
AnnaBridge 189:f392fc9709a3 472 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 473 */
AnnaBridge 189:f392fc9709a3 474 void serial_break_set(serial_t *obj)
AnnaBridge 189:f392fc9709a3 475 {
AnnaBridge 189:f392fc9709a3 476 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 477
AnnaBridge 189:f392fc9709a3 478 usart_send_break(p_obj->uart);
AnnaBridge 189:f392fc9709a3 479 }
AnnaBridge 189:f392fc9709a3 480
AnnaBridge 189:f392fc9709a3 481 /** Clear the break
AnnaBridge 189:f392fc9709a3 482 *
AnnaBridge 189:f392fc9709a3 483 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 484 */
AnnaBridge 189:f392fc9709a3 485 void serial_break_clear(serial_t *obj)
AnnaBridge 189:f392fc9709a3 486 {
AnnaBridge 189:f392fc9709a3 487 /* do nothing */
AnnaBridge 189:f392fc9709a3 488 }
AnnaBridge 189:f392fc9709a3 489
AnnaBridge 189:f392fc9709a3 490 /** Configure the TX pin for UART function.
AnnaBridge 189:f392fc9709a3 491 *
AnnaBridge 189:f392fc9709a3 492 * @param tx The pin name used for TX
AnnaBridge 189:f392fc9709a3 493 */
AnnaBridge 189:f392fc9709a3 494 void serial_pinout_tx(PinName tx)
AnnaBridge 189:f392fc9709a3 495 {
AnnaBridge 189:f392fc9709a3 496 pinmap_pinout(tx, PinMap_UART_TX);
AnnaBridge 189:f392fc9709a3 497 }
AnnaBridge 189:f392fc9709a3 498
AnnaBridge 189:f392fc9709a3 499 #if DEVICE_SERIAL_ASYNCH
AnnaBridge 189:f392fc9709a3 500 /**
AnnaBridge 189:f392fc9709a3 501 * Enable the serial events
AnnaBridge 189:f392fc9709a3 502 *
AnnaBridge 189:f392fc9709a3 503 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 504 * @param event The events to be configured
AnnaBridge 189:f392fc9709a3 505 */
AnnaBridge 189:f392fc9709a3 506 static void serial_event_enable(serial_t *obj, int event)
AnnaBridge 189:f392fc9709a3 507 {
AnnaBridge 189:f392fc9709a3 508 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 509
AnnaBridge 189:f392fc9709a3 510 p_obj->events |= event;
AnnaBridge 189:f392fc9709a3 511
AnnaBridge 189:f392fc9709a3 512 }
AnnaBridge 189:f392fc9709a3 513
AnnaBridge 189:f392fc9709a3 514 /**
AnnaBridge 189:f392fc9709a3 515 * Disable the serial events
AnnaBridge 189:f392fc9709a3 516 *
AnnaBridge 189:f392fc9709a3 517 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 518 * @param event The events to be configured
AnnaBridge 189:f392fc9709a3 519 */
AnnaBridge 189:f392fc9709a3 520 static void serial_event_disable(serial_t *obj, int event)
AnnaBridge 189:f392fc9709a3 521 {
AnnaBridge 189:f392fc9709a3 522 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 523
AnnaBridge 189:f392fc9709a3 524 p_obj->events &= ~event;
AnnaBridge 189:f392fc9709a3 525 }
AnnaBridge 189:f392fc9709a3 526
AnnaBridge 189:f392fc9709a3 527 /**
AnnaBridge 189:f392fc9709a3 528 * Preprocess the USART tx interrupt
AnnaBridge 189:f392fc9709a3 529 *
AnnaBridge 189:f392fc9709a3 530 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 531 * @param pData Pointer to tx buffer
AnnaBridge 189:f392fc9709a3 532 * @param Size Size of tx buffer
AnnaBridge 189:f392fc9709a3 533 * @return Returns the status
AnnaBridge 189:f392fc9709a3 534 */
AnnaBridge 189:f392fc9709a3 535 static gd_status_enum usart_tx_interrupt_preprocess(struct serial_s *obj_s, uint8_t *pData, uint16_t Size)
AnnaBridge 189:f392fc9709a3 536 {
AnnaBridge 189:f392fc9709a3 537 if (obj_s->tx_state == OP_STATE_READY) {
AnnaBridge 189:f392fc9709a3 538 if ((pData == NULL) || (Size == 0U)) {
AnnaBridge 189:f392fc9709a3 539 return GD_ERROR;
AnnaBridge 189:f392fc9709a3 540 }
AnnaBridge 189:f392fc9709a3 541
AnnaBridge 189:f392fc9709a3 542 obj_s->tx_buffer_ptr = pData;
AnnaBridge 189:f392fc9709a3 543 obj_s->tx_count = Size;
AnnaBridge 189:f392fc9709a3 544 obj_s->error_code = USART_ERROR_CODE_NONE;
AnnaBridge 189:f392fc9709a3 545 obj_s->tx_state = OP_STATE_BUSY_TX;
AnnaBridge 189:f392fc9709a3 546
AnnaBridge 189:f392fc9709a3 547 usart_interrupt_enable(obj_s->uart, USART_INT_TBE);
AnnaBridge 189:f392fc9709a3 548
AnnaBridge 189:f392fc9709a3 549 return GD_OK;
AnnaBridge 189:f392fc9709a3 550 } else {
AnnaBridge 189:f392fc9709a3 551 return GD_BUSY;
AnnaBridge 189:f392fc9709a3 552 }
AnnaBridge 189:f392fc9709a3 553 }
AnnaBridge 189:f392fc9709a3 554
AnnaBridge 189:f392fc9709a3 555 /**
AnnaBridge 189:f392fc9709a3 556 * Preprocess the USART rx interrupt
AnnaBridge 189:f392fc9709a3 557 *
AnnaBridge 189:f392fc9709a3 558 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 559 * @param pData Pointer to rx buffer
AnnaBridge 189:f392fc9709a3 560 * @param Size Size of rx buffer
AnnaBridge 189:f392fc9709a3 561 * @return Returns the status
AnnaBridge 189:f392fc9709a3 562 */
AnnaBridge 189:f392fc9709a3 563 static gd_status_enum usart_rx_interrupt_preprocess(struct serial_s *obj_s, uint8_t *pData, uint16_t Size)
AnnaBridge 189:f392fc9709a3 564 {
AnnaBridge 189:f392fc9709a3 565 if (obj_s->rx_state == OP_STATE_READY) {
AnnaBridge 189:f392fc9709a3 566 if ((pData == NULL) || (Size == 0U)) {
AnnaBridge 189:f392fc9709a3 567 return GD_ERROR;
AnnaBridge 189:f392fc9709a3 568 }
AnnaBridge 189:f392fc9709a3 569
AnnaBridge 189:f392fc9709a3 570 obj_s->rx_buffer_ptr = pData;
AnnaBridge 189:f392fc9709a3 571 obj_s->rx_size = Size;
AnnaBridge 189:f392fc9709a3 572 obj_s->rx_count = Size;
AnnaBridge 189:f392fc9709a3 573 obj_s->error_code = USART_ERROR_CODE_NONE;
AnnaBridge 189:f392fc9709a3 574 obj_s->rx_state = OP_STATE_BUSY_RX;
AnnaBridge 189:f392fc9709a3 575
AnnaBridge 189:f392fc9709a3 576 usart_interrupt_enable(obj_s->uart, USART_INT_PERR);
AnnaBridge 189:f392fc9709a3 577 usart_interrupt_enable(obj_s->uart, USART_INT_ERR);
AnnaBridge 189:f392fc9709a3 578 usart_interrupt_enable(obj_s->uart, USART_INT_RBNE);
AnnaBridge 189:f392fc9709a3 579
AnnaBridge 189:f392fc9709a3 580 return GD_OK;
AnnaBridge 189:f392fc9709a3 581 } else {
AnnaBridge 189:f392fc9709a3 582 return GD_BUSY;
AnnaBridge 189:f392fc9709a3 583 }
AnnaBridge 189:f392fc9709a3 584 }
AnnaBridge 189:f392fc9709a3 585
AnnaBridge 189:f392fc9709a3 586 /** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
AnnaBridge 189:f392fc9709a3 587 * tx_buff
AnnaBridge 189:f392fc9709a3 588 *
AnnaBridge 189:f392fc9709a3 589 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 590 * @param tx The transmit buffer
AnnaBridge 189:f392fc9709a3 591 * @param tx_length The number of bytes to transmit
AnnaBridge 189:f392fc9709a3 592 * @param tx_width Deprecated argument
AnnaBridge 189:f392fc9709a3 593 * @param handler The serial handler
AnnaBridge 189:f392fc9709a3 594 * @param event The logical OR of events to be registered
AnnaBridge 189:f392fc9709a3 595 * @param hint A suggestion for how to use DMA with this transfer
AnnaBridge 189:f392fc9709a3 596 * @return Returns number of data transfered, otherwise returns 0
AnnaBridge 189:f392fc9709a3 597 */
AnnaBridge 189:f392fc9709a3 598 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)
AnnaBridge 189:f392fc9709a3 599 {
AnnaBridge 189:f392fc9709a3 600 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 601 IRQn_Type irq = usart_irq_n[p_obj->index];
AnnaBridge 189:f392fc9709a3 602
AnnaBridge 189:f392fc9709a3 603 if ((tx_length == 0) || (tx_width != 8)) {
AnnaBridge 189:f392fc9709a3 604 return 0;
AnnaBridge 189:f392fc9709a3 605 }
AnnaBridge 189:f392fc9709a3 606
AnnaBridge 189:f392fc9709a3 607 if (serial_tx_active(obj)) {
AnnaBridge 189:f392fc9709a3 608 /* some transmit is in progress */
AnnaBridge 189:f392fc9709a3 609 return 0;
AnnaBridge 189:f392fc9709a3 610 }
AnnaBridge 189:f392fc9709a3 611
AnnaBridge 189:f392fc9709a3 612 obj->tx_buff.buffer = (void *)tx;
AnnaBridge 189:f392fc9709a3 613 obj->tx_buff.length = tx_length;
AnnaBridge 189:f392fc9709a3 614 obj->tx_buff.pos = 0;
AnnaBridge 189:f392fc9709a3 615
AnnaBridge 189:f392fc9709a3 616 /* disable all events first */
AnnaBridge 189:f392fc9709a3 617 serial_event_disable(obj, SERIAL_EVENT_TX_ALL);
AnnaBridge 189:f392fc9709a3 618 /* enable the specific event */
AnnaBridge 189:f392fc9709a3 619 serial_event_enable(obj, event);
AnnaBridge 189:f392fc9709a3 620
AnnaBridge 189:f392fc9709a3 621 /* enable interrupt */
AnnaBridge 189:f392fc9709a3 622 /* clear pending IRQ */
AnnaBridge 189:f392fc9709a3 623 NVIC_ClearPendingIRQ(irq);
AnnaBridge 189:f392fc9709a3 624 /* disable the IRQ first */
AnnaBridge 189:f392fc9709a3 625 NVIC_DisableIRQ(irq);
AnnaBridge 189:f392fc9709a3 626 /* set the priority and vector */
AnnaBridge 189:f392fc9709a3 627 NVIC_SetPriority(irq, 1);
AnnaBridge 189:f392fc9709a3 628 NVIC_SetVector(irq, (uint32_t)handler);
AnnaBridge 189:f392fc9709a3 629 /* enable IRQ */
AnnaBridge 189:f392fc9709a3 630 NVIC_EnableIRQ(irq);
AnnaBridge 189:f392fc9709a3 631
AnnaBridge 189:f392fc9709a3 632 if (usart_tx_interrupt_preprocess(p_obj, (uint8_t *)tx, tx_length) != GD_OK) {
AnnaBridge 189:f392fc9709a3 633 return 0;
AnnaBridge 189:f392fc9709a3 634 }
AnnaBridge 189:f392fc9709a3 635
AnnaBridge 189:f392fc9709a3 636 return tx_length;
AnnaBridge 189:f392fc9709a3 637 }
AnnaBridge 189:f392fc9709a3 638
AnnaBridge 189:f392fc9709a3 639 /** Begin asynchronous RX transfer (enable interrupt for data collecting)
AnnaBridge 189:f392fc9709a3 640 * The used buffer is specified in the serial object - rx_buff
AnnaBridge 189:f392fc9709a3 641 *
AnnaBridge 189:f392fc9709a3 642 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 643 * @param rx The receive buffer
AnnaBridge 189:f392fc9709a3 644 * @param rx_length The number of bytes to receive
AnnaBridge 189:f392fc9709a3 645 * @param rx_width Deprecated argument
AnnaBridge 189:f392fc9709a3 646 * @param handler The serial handler
AnnaBridge 189:f392fc9709a3 647 * @param event The logical OR of events to be registered
AnnaBridge 189:f392fc9709a3 648 * @param handler The serial handler
AnnaBridge 189:f392fc9709a3 649 * @param char_match A character in range 0-254 to be matched
AnnaBridge 189:f392fc9709a3 650 * @param hint A suggestion for how to use DMA with this transfer
AnnaBridge 189:f392fc9709a3 651 */
AnnaBridge 189:f392fc9709a3 652 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)
AnnaBridge 189:f392fc9709a3 653 {
AnnaBridge 189:f392fc9709a3 654 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 655 IRQn_Type irq = usart_irq_n[p_obj->index];
AnnaBridge 189:f392fc9709a3 656
AnnaBridge 189:f392fc9709a3 657 if ((rx_length == 0) || (rx_width != 8)) {
AnnaBridge 189:f392fc9709a3 658 return;
AnnaBridge 189:f392fc9709a3 659 }
AnnaBridge 189:f392fc9709a3 660
AnnaBridge 189:f392fc9709a3 661 /* disable all events first */
AnnaBridge 189:f392fc9709a3 662 serial_event_disable(obj, SERIAL_EVENT_RX_ALL);
AnnaBridge 189:f392fc9709a3 663 /* enable the specific event */
AnnaBridge 189:f392fc9709a3 664 serial_event_enable(obj, event);
AnnaBridge 189:f392fc9709a3 665
AnnaBridge 189:f392fc9709a3 666 obj->char_match = char_match;
AnnaBridge 189:f392fc9709a3 667
AnnaBridge 189:f392fc9709a3 668 if (serial_rx_active(obj)) {
AnnaBridge 189:f392fc9709a3 669 /* some reception is in progress */
AnnaBridge 189:f392fc9709a3 670 return;
AnnaBridge 189:f392fc9709a3 671 }
AnnaBridge 189:f392fc9709a3 672
AnnaBridge 189:f392fc9709a3 673 obj->rx_buff.buffer = rx;
AnnaBridge 189:f392fc9709a3 674 obj->rx_buff.length = rx_length;
AnnaBridge 189:f392fc9709a3 675 obj->rx_buff.pos = 0;
AnnaBridge 189:f392fc9709a3 676
AnnaBridge 189:f392fc9709a3 677 /* enable interrupt */
AnnaBridge 189:f392fc9709a3 678 /* clear pending IRQ */
AnnaBridge 189:f392fc9709a3 679 NVIC_ClearPendingIRQ(irq);
AnnaBridge 189:f392fc9709a3 680 /* disable the IRQ first */
AnnaBridge 189:f392fc9709a3 681 NVIC_DisableIRQ(irq);
AnnaBridge 189:f392fc9709a3 682 /* set the priority(higher than Tx) and vector */
AnnaBridge 189:f392fc9709a3 683 NVIC_SetPriority(irq, 0);
AnnaBridge 189:f392fc9709a3 684 NVIC_SetVector(irq, (uint32_t)handler);
AnnaBridge 189:f392fc9709a3 685 /* enable IRQ */
AnnaBridge 189:f392fc9709a3 686 NVIC_EnableIRQ(irq);
AnnaBridge 189:f392fc9709a3 687
AnnaBridge 189:f392fc9709a3 688 usart_rx_interrupt_preprocess(p_obj, (uint8_t *)rx, rx_length);
AnnaBridge 189:f392fc9709a3 689 }
AnnaBridge 189:f392fc9709a3 690
AnnaBridge 189:f392fc9709a3 691 /** Attempts to determine if the serial peripheral is already in use for TX
AnnaBridge 189:f392fc9709a3 692 *
AnnaBridge 189:f392fc9709a3 693 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 694 * @return Non-zero if the RX transaction is ongoing, 0 otherwise
AnnaBridge 189:f392fc9709a3 695 */
AnnaBridge 189:f392fc9709a3 696 uint8_t serial_tx_active(serial_t *obj)
AnnaBridge 189:f392fc9709a3 697 {
AnnaBridge 189:f392fc9709a3 698 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 699
AnnaBridge 189:f392fc9709a3 700 return ((p_obj->tx_state == OP_STATE_BUSY_TX) ? 1 : 0);
AnnaBridge 189:f392fc9709a3 701 }
AnnaBridge 189:f392fc9709a3 702
AnnaBridge 189:f392fc9709a3 703 /** Attempts to determine if the serial peripheral is already in use for RX
AnnaBridge 189:f392fc9709a3 704 *
AnnaBridge 189:f392fc9709a3 705 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 706 * @return Non-zero if the RX transaction is ongoing, 0 otherwise
AnnaBridge 189:f392fc9709a3 707 */
AnnaBridge 189:f392fc9709a3 708 uint8_t serial_rx_active(serial_t *obj)
AnnaBridge 189:f392fc9709a3 709 {
AnnaBridge 189:f392fc9709a3 710 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 711
AnnaBridge 189:f392fc9709a3 712 return ((p_obj->rx_state == OP_STATE_BUSY_RX) ? 1 : 0);
AnnaBridge 189:f392fc9709a3 713 }
AnnaBridge 189:f392fc9709a3 714
AnnaBridge 189:f392fc9709a3 715 /** Handle the serial rx interrupt
AnnaBridge 189:f392fc9709a3 716 *
AnnaBridge 189:f392fc9709a3 717 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 718 * @return Returns the status
AnnaBridge 189:f392fc9709a3 719 */
AnnaBridge 189:f392fc9709a3 720 static gd_status_enum usart_rx_interrupt(struct serial_s *obj_s)
AnnaBridge 189:f392fc9709a3 721 {
AnnaBridge 189:f392fc9709a3 722 uint16_t *temp;
AnnaBridge 189:f392fc9709a3 723
AnnaBridge 189:f392fc9709a3 724 if (obj_s->rx_state == OP_STATE_BUSY_RX) {
AnnaBridge 189:f392fc9709a3 725 if (obj_s->databits == USART_WL_9BIT) {
AnnaBridge 189:f392fc9709a3 726 temp = (uint16_t *) obj_s->rx_buffer_ptr;
AnnaBridge 189:f392fc9709a3 727 if (obj_s->parity == USART_PM_NONE) {
AnnaBridge 189:f392fc9709a3 728 /* 9-bit data, none parity bit */
AnnaBridge 189:f392fc9709a3 729 *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x01FF);
AnnaBridge 189:f392fc9709a3 730 obj_s->rx_buffer_ptr += 2U;
AnnaBridge 189:f392fc9709a3 731 } else {
AnnaBridge 189:f392fc9709a3 732 /* 9-bit data, with parity bit */
AnnaBridge 189:f392fc9709a3 733 *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x00FF);
AnnaBridge 189:f392fc9709a3 734 obj_s->rx_buffer_ptr += 1U;
AnnaBridge 189:f392fc9709a3 735 }
AnnaBridge 189:f392fc9709a3 736 } else {
AnnaBridge 189:f392fc9709a3 737 if (obj_s->parity == USART_PM_NONE) {
AnnaBridge 189:f392fc9709a3 738 /* 8-bit data, none parity bit */
AnnaBridge 189:f392fc9709a3 739 *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x00FF);
AnnaBridge 189:f392fc9709a3 740 } else {
AnnaBridge 189:f392fc9709a3 741 /* 8-bit data, with parity bit */
AnnaBridge 189:f392fc9709a3 742 *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x007F);
AnnaBridge 189:f392fc9709a3 743 }
AnnaBridge 189:f392fc9709a3 744 }
AnnaBridge 189:f392fc9709a3 745
AnnaBridge 189:f392fc9709a3 746 if (--obj_s->rx_count == 0U) {
AnnaBridge 189:f392fc9709a3 747 usart_interrupt_disable(obj_s->uart, USART_INT_RBNE);
AnnaBridge 189:f392fc9709a3 748 usart_interrupt_disable(obj_s->uart, USART_INT_PERR);
AnnaBridge 189:f392fc9709a3 749 usart_interrupt_disable(obj_s->uart, USART_INT_ERR);
AnnaBridge 189:f392fc9709a3 750
AnnaBridge 189:f392fc9709a3 751 obj_s->rx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 752 }
AnnaBridge 189:f392fc9709a3 753
AnnaBridge 189:f392fc9709a3 754 return GD_OK;
AnnaBridge 189:f392fc9709a3 755 } else {
AnnaBridge 189:f392fc9709a3 756 return GD_BUSY;
AnnaBridge 189:f392fc9709a3 757 }
AnnaBridge 189:f392fc9709a3 758 }
AnnaBridge 189:f392fc9709a3 759
AnnaBridge 189:f392fc9709a3 760 /** Handle the serial tx interrupt
AnnaBridge 189:f392fc9709a3 761 *
AnnaBridge 189:f392fc9709a3 762 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 763 * @return Returns the status
AnnaBridge 189:f392fc9709a3 764 */
AnnaBridge 189:f392fc9709a3 765 static gd_status_enum usart_tx_interrupt(struct serial_s *obj_s)
AnnaBridge 189:f392fc9709a3 766 {
AnnaBridge 189:f392fc9709a3 767 uint16_t *temp;
AnnaBridge 189:f392fc9709a3 768
AnnaBridge 189:f392fc9709a3 769 if (obj_s->tx_state == OP_STATE_BUSY_TX) {
AnnaBridge 189:f392fc9709a3 770 if (obj_s->databits == USART_WL_9BIT) {
AnnaBridge 189:f392fc9709a3 771 temp = (uint16_t *) obj_s->tx_buffer_ptr;
AnnaBridge 189:f392fc9709a3 772 USART_DATA(obj_s->uart) = (uint16_t)(*temp & (uint16_t)0x01FF);
AnnaBridge 189:f392fc9709a3 773 if (obj_s->parity == USART_PM_NONE) {
AnnaBridge 189:f392fc9709a3 774 obj_s->tx_buffer_ptr += 2U;
AnnaBridge 189:f392fc9709a3 775 } else {
AnnaBridge 189:f392fc9709a3 776 obj_s->tx_buffer_ptr += 1U;
AnnaBridge 189:f392fc9709a3 777 }
AnnaBridge 189:f392fc9709a3 778 } else {
AnnaBridge 189:f392fc9709a3 779 USART_DATA(obj_s->uart) = (uint8_t)(*obj_s->tx_buffer_ptr++ & (uint8_t)0x00FF);
AnnaBridge 189:f392fc9709a3 780 }
AnnaBridge 189:f392fc9709a3 781
AnnaBridge 189:f392fc9709a3 782 if (--obj_s->tx_count == 0U) {
AnnaBridge 189:f392fc9709a3 783 /* disable USART_INT_TBE interrupt */
AnnaBridge 189:f392fc9709a3 784 usart_interrupt_disable(obj_s->uart, USART_INT_TBE);
AnnaBridge 189:f392fc9709a3 785
AnnaBridge 189:f392fc9709a3 786 /* enable USART_INT_TC interrupt */
AnnaBridge 189:f392fc9709a3 787 usart_interrupt_enable(obj_s->uart, USART_INT_TC);
AnnaBridge 189:f392fc9709a3 788 }
AnnaBridge 189:f392fc9709a3 789
AnnaBridge 189:f392fc9709a3 790 return GD_OK;
AnnaBridge 189:f392fc9709a3 791 } else {
AnnaBridge 189:f392fc9709a3 792 return GD_BUSY;
AnnaBridge 189:f392fc9709a3 793 }
AnnaBridge 189:f392fc9709a3 794 }
AnnaBridge 189:f392fc9709a3 795
AnnaBridge 189:f392fc9709a3 796 /** Handle the serial tx complete interrupt
AnnaBridge 189:f392fc9709a3 797 *
AnnaBridge 189:f392fc9709a3 798 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 799 */
AnnaBridge 189:f392fc9709a3 800 static void usart_tx_complete_interrupt(struct serial_s *obj_s)
AnnaBridge 189:f392fc9709a3 801 {
AnnaBridge 189:f392fc9709a3 802 usart_interrupt_disable(obj_s->uart, USART_INT_TC);
AnnaBridge 189:f392fc9709a3 803
AnnaBridge 189:f392fc9709a3 804 obj_s->tx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 805 }
AnnaBridge 189:f392fc9709a3 806
AnnaBridge 189:f392fc9709a3 807 /** Handle all the serial interrupt request
AnnaBridge 189:f392fc9709a3 808 *
AnnaBridge 189:f392fc9709a3 809 * @param obj_s The serial object
AnnaBridge 189:f392fc9709a3 810 */
AnnaBridge 189:f392fc9709a3 811 static void usart_irq_handler(struct serial_s *obj_s)
AnnaBridge 189:f392fc9709a3 812 {
AnnaBridge 189:f392fc9709a3 813 uint32_t err_flags = 0U;
AnnaBridge 189:f392fc9709a3 814
AnnaBridge 189:f392fc9709a3 815 /* no error occurs */
AnnaBridge 189:f392fc9709a3 816 err_flags = (USART_STAT0(obj_s->uart) & (uint32_t)(USART_FLAG_PERR | USART_FLAG_FERR | USART_FLAG_ORERR | USART_FLAG_NERR));
AnnaBridge 189:f392fc9709a3 817 if (err_flags == RESET) {
AnnaBridge 189:f392fc9709a3 818 /* check whether USART is in receiver mode or not */
AnnaBridge 189:f392fc9709a3 819 if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_RBNE) != RESET) {
AnnaBridge 189:f392fc9709a3 820 usart_rx_interrupt(obj_s);
AnnaBridge 189:f392fc9709a3 821
AnnaBridge 189:f392fc9709a3 822 return;
AnnaBridge 189:f392fc9709a3 823 }
AnnaBridge 189:f392fc9709a3 824 }
AnnaBridge 189:f392fc9709a3 825
AnnaBridge 189:f392fc9709a3 826 if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TBE) != RESET) {
AnnaBridge 189:f392fc9709a3 827 usart_tx_interrupt(obj_s);
AnnaBridge 189:f392fc9709a3 828 return;
AnnaBridge 189:f392fc9709a3 829 }
AnnaBridge 189:f392fc9709a3 830
AnnaBridge 189:f392fc9709a3 831 if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TC) != RESET) {
AnnaBridge 189:f392fc9709a3 832 usart_tx_complete_interrupt(obj_s);
AnnaBridge 189:f392fc9709a3 833 return;
AnnaBridge 189:f392fc9709a3 834 }
AnnaBridge 189:f392fc9709a3 835 }
AnnaBridge 189:f392fc9709a3 836
AnnaBridge 189:f392fc9709a3 837 /** The asynchronous TX and RX handler.
AnnaBridge 189:f392fc9709a3 838 *
AnnaBridge 189:f392fc9709a3 839 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 840 * @return Returns event flags if an RX transfer termination condition was met; otherwise returns 0
AnnaBridge 189:f392fc9709a3 841 */
AnnaBridge 189:f392fc9709a3 842 int serial_irq_handler_asynch(serial_t *obj)
AnnaBridge 189:f392fc9709a3 843 {
AnnaBridge 189:f392fc9709a3 844 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 845 volatile uint8_t i = 0;
AnnaBridge 189:f392fc9709a3 846 volatile int return_val = 0;
AnnaBridge 189:f392fc9709a3 847 uint8_t *p_buf = (uint8_t *)(obj->rx_buff.buffer);
AnnaBridge 189:f392fc9709a3 848
AnnaBridge 189:f392fc9709a3 849 if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_PERR) != RESET) {
AnnaBridge 189:f392fc9709a3 850 /* clear PERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 851 USART_DATA(p_obj->uart);
AnnaBridge 189:f392fc9709a3 852
AnnaBridge 189:f392fc9709a3 853 return_val |= (SERIAL_EVENT_RX_PARITY_ERROR & p_obj->events);
AnnaBridge 189:f392fc9709a3 854 p_obj->error_code |= USART_ERROR_CODE_PERR;
AnnaBridge 189:f392fc9709a3 855 }
AnnaBridge 189:f392fc9709a3 856
AnnaBridge 189:f392fc9709a3 857 if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_FERR) != RESET) {
AnnaBridge 189:f392fc9709a3 858 /* clear FERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 859 USART_DATA(p_obj->uart);
AnnaBridge 189:f392fc9709a3 860
AnnaBridge 189:f392fc9709a3 861 return_val |= (SERIAL_EVENT_RX_FRAMING_ERROR & p_obj->events);
AnnaBridge 189:f392fc9709a3 862 p_obj->error_code |= USART_ERROR_CODE_FERR;
AnnaBridge 189:f392fc9709a3 863 }
AnnaBridge 189:f392fc9709a3 864
AnnaBridge 189:f392fc9709a3 865 if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_ORERR) != RESET) {
AnnaBridge 189:f392fc9709a3 866 /* clear ORERR error flag by reading USART DATA register */
AnnaBridge 189:f392fc9709a3 867 USART_DATA(p_obj->uart);
AnnaBridge 189:f392fc9709a3 868
AnnaBridge 189:f392fc9709a3 869 return_val |= (SERIAL_EVENT_RX_OVERRUN_ERROR & p_obj->events);
AnnaBridge 189:f392fc9709a3 870 p_obj->error_code |= USART_ERROR_CODE_ORERR;
AnnaBridge 189:f392fc9709a3 871 }
AnnaBridge 189:f392fc9709a3 872
AnnaBridge 189:f392fc9709a3 873 if (return_val & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR |
AnnaBridge 189:f392fc9709a3 874 SERIAL_EVENT_RX_OVERRUN_ERROR)) {
AnnaBridge 189:f392fc9709a3 875 return return_val;
AnnaBridge 189:f392fc9709a3 876 }
AnnaBridge 189:f392fc9709a3 877
AnnaBridge 189:f392fc9709a3 878 if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_TC) != RESET) {
AnnaBridge 189:f392fc9709a3 879 if ((p_obj->events & SERIAL_EVENT_TX_COMPLETE) != 0) {
AnnaBridge 189:f392fc9709a3 880 return_val |= (SERIAL_EVENT_TX_COMPLETE & p_obj->events);
AnnaBridge 189:f392fc9709a3 881 }
AnnaBridge 189:f392fc9709a3 882 }
AnnaBridge 189:f392fc9709a3 883
AnnaBridge 189:f392fc9709a3 884 usart_irq_handler(p_obj);
AnnaBridge 189:f392fc9709a3 885
AnnaBridge 189:f392fc9709a3 886 if (p_obj->rx_size != 0) {
AnnaBridge 189:f392fc9709a3 887 obj->rx_buff.pos = p_obj->rx_size - p_obj->rx_count;
AnnaBridge 189:f392fc9709a3 888 }
AnnaBridge 189:f392fc9709a3 889
AnnaBridge 189:f392fc9709a3 890 if ((p_obj->rx_count == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
AnnaBridge 189:f392fc9709a3 891 return_val |= (SERIAL_EVENT_RX_COMPLETE & p_obj->events);
AnnaBridge 189:f392fc9709a3 892 }
AnnaBridge 189:f392fc9709a3 893
AnnaBridge 189:f392fc9709a3 894 if (p_obj->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
AnnaBridge 189:f392fc9709a3 895 if (p_buf != NULL) {
AnnaBridge 189:f392fc9709a3 896 for (i = 0; i < obj->rx_buff.pos; i++) {
AnnaBridge 189:f392fc9709a3 897 if (p_buf[i] == obj->char_match) {
AnnaBridge 189:f392fc9709a3 898 obj->rx_buff.pos = i;
AnnaBridge 189:f392fc9709a3 899 return_val |= (SERIAL_EVENT_RX_CHARACTER_MATCH & p_obj->events);
AnnaBridge 189:f392fc9709a3 900 serial_rx_abort_asynch(obj);
AnnaBridge 189:f392fc9709a3 901 break;
AnnaBridge 189:f392fc9709a3 902 }
AnnaBridge 189:f392fc9709a3 903 }
AnnaBridge 189:f392fc9709a3 904 }
AnnaBridge 189:f392fc9709a3 905 }
AnnaBridge 189:f392fc9709a3 906
AnnaBridge 189:f392fc9709a3 907 return return_val;
AnnaBridge 189:f392fc9709a3 908 }
AnnaBridge 189:f392fc9709a3 909
AnnaBridge 189:f392fc9709a3 910 /** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
AnnaBridge 189:f392fc9709a3 911 * flushes the TX hardware buffer if TX FIFO is used
AnnaBridge 189:f392fc9709a3 912 *
AnnaBridge 189:f392fc9709a3 913 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 914 */
AnnaBridge 189:f392fc9709a3 915 void serial_tx_abort_asynch(serial_t *obj)
AnnaBridge 189:f392fc9709a3 916 {
AnnaBridge 189:f392fc9709a3 917 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 918
AnnaBridge 189:f392fc9709a3 919 usart_interrupt_disable(p_obj->uart, USART_INT_TC);
AnnaBridge 189:f392fc9709a3 920 usart_interrupt_disable(p_obj->uart, USART_INT_TBE);
AnnaBridge 189:f392fc9709a3 921
AnnaBridge 189:f392fc9709a3 922 usart_flag_clear(p_obj->uart, USART_FLAG_TC);
AnnaBridge 189:f392fc9709a3 923
AnnaBridge 189:f392fc9709a3 924 p_obj->tx_count = 0;
AnnaBridge 189:f392fc9709a3 925 p_obj->tx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 926 }
AnnaBridge 189:f392fc9709a3 927
AnnaBridge 189:f392fc9709a3 928 /** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and
AnnaBridge 189:f392fc9709a3 929 * flushes the RX hardware buffer if RX FIFO is used
AnnaBridge 189:f392fc9709a3 930 *
AnnaBridge 189:f392fc9709a3 931 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 932 */
AnnaBridge 189:f392fc9709a3 933 void serial_rx_abort_asynch(serial_t *obj)
AnnaBridge 189:f392fc9709a3 934 {
AnnaBridge 189:f392fc9709a3 935 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 936
AnnaBridge 189:f392fc9709a3 937 /* disable interrupts */
AnnaBridge 189:f392fc9709a3 938 usart_interrupt_disable(p_obj->uart, USART_INT_RBNE);
AnnaBridge 189:f392fc9709a3 939 usart_interrupt_disable(p_obj->uart, USART_INT_PERR);
AnnaBridge 189:f392fc9709a3 940 usart_interrupt_disable(p_obj->uart, USART_INT_ERR);
AnnaBridge 189:f392fc9709a3 941
AnnaBridge 189:f392fc9709a3 942 /* clear USART_FLAG_RBNE flag */
AnnaBridge 189:f392fc9709a3 943 usart_flag_clear(p_obj->uart, USART_FLAG_RBNE);
AnnaBridge 189:f392fc9709a3 944
AnnaBridge 189:f392fc9709a3 945 /* clear errors flag by reading USART STATx register and then USART DATA register */
AnnaBridge 189:f392fc9709a3 946 usart_flag_get(p_obj->uart, USART_FLAG_PERR);
AnnaBridge 189:f392fc9709a3 947 usart_flag_get(p_obj->uart, USART_FLAG_FERR);
AnnaBridge 189:f392fc9709a3 948 usart_flag_get(p_obj->uart, USART_FLAG_ORERR);
AnnaBridge 189:f392fc9709a3 949 USART_DATA(p_obj->uart);
AnnaBridge 189:f392fc9709a3 950
AnnaBridge 189:f392fc9709a3 951 /* reset rx transfer count */
AnnaBridge 189:f392fc9709a3 952 p_obj->rx_count = 0;
AnnaBridge 189:f392fc9709a3 953
AnnaBridge 189:f392fc9709a3 954 /* reset rx state */
AnnaBridge 189:f392fc9709a3 955 p_obj->rx_state = OP_STATE_READY;
AnnaBridge 189:f392fc9709a3 956 }
AnnaBridge 189:f392fc9709a3 957
AnnaBridge 189:f392fc9709a3 958 #endif /* DEVICE_SERIAL_ASYNCH */
AnnaBridge 189:f392fc9709a3 959
AnnaBridge 189:f392fc9709a3 960 #if DEVICE_SERIAL_FC
AnnaBridge 189:f392fc9709a3 961 /** Configure the serial for the flow control. It sets flow control in the hardware
AnnaBridge 189:f392fc9709a3 962 * if a serial peripheral supports it, otherwise software emulation is used.
AnnaBridge 189:f392fc9709a3 963 *
AnnaBridge 189:f392fc9709a3 964 * @param obj The serial object
AnnaBridge 189:f392fc9709a3 965 * @param type The type of the flow control. Look at the available FlowControl types.
AnnaBridge 189:f392fc9709a3 966 * @param rxflow The TX pin name
AnnaBridge 189:f392fc9709a3 967 * @param txflow The RX pin name
AnnaBridge 189:f392fc9709a3 968 */
AnnaBridge 189:f392fc9709a3 969 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
AnnaBridge 189:f392fc9709a3 970 {
AnnaBridge 189:f392fc9709a3 971 uint16_t uen_flag = 0U;
AnnaBridge 189:f392fc9709a3 972 struct serial_s *p_obj = GET_SERIAL_S(obj);
AnnaBridge 189:f392fc9709a3 973
AnnaBridge 189:f392fc9709a3 974 /* store the UEN flag */
AnnaBridge 189:f392fc9709a3 975 uen_flag = USART_CTL0(p_obj->uart) & USART_CTL0_UEN;
AnnaBridge 189:f392fc9709a3 976
AnnaBridge 189:f392fc9709a3 977 UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
AnnaBridge 189:f392fc9709a3 978 UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
AnnaBridge 189:f392fc9709a3 979
AnnaBridge 189:f392fc9709a3 980 p_obj->uart = (UARTName)pinmap_merge(uart_cts, uart_rts);
AnnaBridge 189:f392fc9709a3 981 MBED_ASSERT(p_obj->uart != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 982
AnnaBridge 189:f392fc9709a3 983 /* disable USART to modify CTS/RTS configuration */
AnnaBridge 189:f392fc9709a3 984 usart_disable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 985
AnnaBridge 189:f392fc9709a3 986 if (type == FlowControlNone) {
AnnaBridge 189:f392fc9709a3 987 p_obj->hw_flow_ctl = USART_HWCONTROL_NONE;
AnnaBridge 189:f392fc9709a3 988 usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_DISABLE);
AnnaBridge 189:f392fc9709a3 989 usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_DISABLE);
AnnaBridge 189:f392fc9709a3 990 }
AnnaBridge 189:f392fc9709a3 991
AnnaBridge 189:f392fc9709a3 992 if (type == FlowControlRTS) {
AnnaBridge 189:f392fc9709a3 993 MBED_ASSERT(uart_rts != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 994 p_obj->hw_flow_ctl = USART_HWCONTROL_RTS;
AnnaBridge 189:f392fc9709a3 995 p_obj->pin_rts = rxflow;
AnnaBridge 189:f392fc9709a3 996 pinmap_pinout(rxflow, PinMap_UART_RTS);
AnnaBridge 189:f392fc9709a3 997 usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_DISABLE);
AnnaBridge 189:f392fc9709a3 998 usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_ENABLE);
AnnaBridge 189:f392fc9709a3 999 }
AnnaBridge 189:f392fc9709a3 1000
AnnaBridge 189:f392fc9709a3 1001 if (type == FlowControlCTS) {
AnnaBridge 189:f392fc9709a3 1002 MBED_ASSERT(uart_cts != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 1003 p_obj->hw_flow_ctl = USART_HWCONTROL_CTS;
AnnaBridge 189:f392fc9709a3 1004 p_obj->pin_cts = txflow;
AnnaBridge 189:f392fc9709a3 1005 pinmap_pinout(txflow, PinMap_UART_CTS);
AnnaBridge 189:f392fc9709a3 1006 usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_DISABLE);
AnnaBridge 189:f392fc9709a3 1007 usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_ENABLE);
AnnaBridge 189:f392fc9709a3 1008 }
AnnaBridge 189:f392fc9709a3 1009
AnnaBridge 189:f392fc9709a3 1010 if (type == FlowControlRTSCTS) {
AnnaBridge 189:f392fc9709a3 1011 MBED_ASSERT(uart_rts != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 1012 MBED_ASSERT(uart_cts != (UARTName)NC);
AnnaBridge 189:f392fc9709a3 1013 p_obj->hw_flow_ctl = USART_HWCONTROL_RTS_CTS;
AnnaBridge 189:f392fc9709a3 1014 p_obj->pin_rts = rxflow;
AnnaBridge 189:f392fc9709a3 1015 p_obj->pin_cts = txflow;
AnnaBridge 189:f392fc9709a3 1016 pinmap_pinout(txflow, PinMap_UART_CTS);
AnnaBridge 189:f392fc9709a3 1017 pinmap_pinout(rxflow, PinMap_UART_RTS);
AnnaBridge 189:f392fc9709a3 1018 usart_hardware_flow_cts_config(p_obj->uart, USART_CTS_ENABLE);
AnnaBridge 189:f392fc9709a3 1019 usart_hardware_flow_rts_config(p_obj->uart, USART_RTS_ENABLE);
AnnaBridge 189:f392fc9709a3 1020 }
AnnaBridge 189:f392fc9709a3 1021
AnnaBridge 189:f392fc9709a3 1022 /* restore the UEN flag */
AnnaBridge 189:f392fc9709a3 1023 if (RESET != uen_flag) {
AnnaBridge 189:f392fc9709a3 1024 usart_enable(p_obj->uart);
AnnaBridge 189:f392fc9709a3 1025 }
AnnaBridge 189:f392fc9709a3 1026 }
AnnaBridge 189:f392fc9709a3 1027
AnnaBridge 189:f392fc9709a3 1028 #endif /* DEVICE_SERIAL_FC */
AnnaBridge 189:f392fc9709a3 1029
AnnaBridge 189:f392fc9709a3 1030 #if DEVICE_SLEEP
AnnaBridge 189:f392fc9709a3 1031 /** Check whether the serial is in busy state
AnnaBridge 189:f392fc9709a3 1032 *
AnnaBridge 189:f392fc9709a3 1033 * @return 0: all the serial is free to use, 1: some serial is in busy in transfer
AnnaBridge 189:f392fc9709a3 1034 */
AnnaBridge 189:f392fc9709a3 1035 int serial_busy_state_check(void)
AnnaBridge 189:f392fc9709a3 1036 {
AnnaBridge 189:f392fc9709a3 1037 #if defined(USART0)
AnnaBridge 189:f392fc9709a3 1038 if ((USART_CTL0(USART0) & USART_CTL0_UEN) && !(USART_STAT0(USART0) & USART_STAT0_TC)) {
AnnaBridge 189:f392fc9709a3 1039 return 1;
AnnaBridge 189:f392fc9709a3 1040 }
AnnaBridge 189:f392fc9709a3 1041 #endif
AnnaBridge 189:f392fc9709a3 1042
AnnaBridge 189:f392fc9709a3 1043 #if defined(USART1)
AnnaBridge 189:f392fc9709a3 1044 if ((USART_CTL0(USART1) & USART_CTL0_UEN) && !(USART_STAT0(USART1) & USART_STAT0_TC)) {
AnnaBridge 189:f392fc9709a3 1045 return 1;
AnnaBridge 189:f392fc9709a3 1046 }
AnnaBridge 189:f392fc9709a3 1047 #endif
AnnaBridge 189:f392fc9709a3 1048
AnnaBridge 189:f392fc9709a3 1049 #if defined(USART2)
AnnaBridge 189:f392fc9709a3 1050 if ((USART_CTL0(USART2) & USART_CTL0_UEN) && !(USART_STAT0(USART2) & USART_STAT0_TC)) {
AnnaBridge 189:f392fc9709a3 1051 return 1;
AnnaBridge 189:f392fc9709a3 1052 }
AnnaBridge 189:f392fc9709a3 1053 #endif
AnnaBridge 189:f392fc9709a3 1054
AnnaBridge 189:f392fc9709a3 1055 #if defined(UART3)
AnnaBridge 189:f392fc9709a3 1056 if ((USART_CTL0(UART3) & USART_CTL0_UEN) && !(USART_STAT0(UART3) & USART_STAT0_TC)) {
AnnaBridge 189:f392fc9709a3 1057 return 1;
AnnaBridge 189:f392fc9709a3 1058 }
AnnaBridge 189:f392fc9709a3 1059 #endif
AnnaBridge 189:f392fc9709a3 1060
AnnaBridge 189:f392fc9709a3 1061 #if defined(UART4)
AnnaBridge 189:f392fc9709a3 1062 if ((USART_CTL0(UART4) & USART_CTL0_UEN) && !(USART_STAT0(UART4) & USART_STAT0_TC)) {
AnnaBridge 189:f392fc9709a3 1063 return 1;
AnnaBridge 189:f392fc9709a3 1064 }
AnnaBridge 189:f392fc9709a3 1065 #endif
AnnaBridge 189:f392fc9709a3 1066
AnnaBridge 189:f392fc9709a3 1067 /* no serial is in busy state */
AnnaBridge 189:f392fc9709a3 1068 return 0;
AnnaBridge 189:f392fc9709a3 1069 }
AnnaBridge 189:f392fc9709a3 1070 #endif /* DEVICE_SLEEP */
AnnaBridge 189:f392fc9709a3 1071
AnnaBridge 189:f392fc9709a3 1072 #endif /* DEVICE_SERIAL */