mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 25 14:15:10 2015 +0100
Revision:
627:4fa1328d9c60
Parent:
563:536c9fb088a0
Synchronized with git revision fe238a91ab7a4d1d72c4cab9da04967c619d54ad

Full URL: https://github.com/mbedmicro/mbed/commit/fe238a91ab7a4d1d72c4cab9da04967c619d54ad/

Silicon Labs - Add support for low-power async Serial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 627:4fa1328d9c60 1 /***************************************************************************//**
mbed_official 627:4fa1328d9c60 2 * @file serial_api.c
mbed_official 627:4fa1328d9c60 3 *******************************************************************************
mbed_official 627:4fa1328d9c60 4 * @section License
mbed_official 627:4fa1328d9c60 5 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
mbed_official 627:4fa1328d9c60 6 *******************************************************************************
mbed_official 525:c320967f86b9 7 *
mbed_official 627:4fa1328d9c60 8 * Permission is granted to anyone to use this software for any purpose,
mbed_official 627:4fa1328d9c60 9 * including commercial applications, and to alter it and redistribute it
mbed_official 627:4fa1328d9c60 10 * freely, subject to the following restrictions:
mbed_official 525:c320967f86b9 11 *
mbed_official 627:4fa1328d9c60 12 * 1. The origin of this software must not be misrepresented; you must not
mbed_official 627:4fa1328d9c60 13 * claim that you wrote the original software.
mbed_official 627:4fa1328d9c60 14 * 2. Altered source versions must be plainly marked as such, and must not be
mbed_official 627:4fa1328d9c60 15 * misrepresented as being the original software.
mbed_official 627:4fa1328d9c60 16 * 3. This notice may not be removed or altered from any source distribution.
mbed_official 525:c320967f86b9 17 *
mbed_official 627:4fa1328d9c60 18 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
mbed_official 627:4fa1328d9c60 19 * obligation to support this Software. Silicon Labs is providing the
mbed_official 627:4fa1328d9c60 20 * Software "AS IS", with no express or implied warranties of any kind,
mbed_official 627:4fa1328d9c60 21 * including, but not limited to, any implied warranties of merchantability
mbed_official 627:4fa1328d9c60 22 * or fitness for any particular purpose or warranties against infringement
mbed_official 627:4fa1328d9c60 23 * of any proprietary rights of a third party.
mbed_official 627:4fa1328d9c60 24 *
mbed_official 627:4fa1328d9c60 25 * Silicon Labs will not be liable for any consequential, incidental, or
mbed_official 627:4fa1328d9c60 26 * special damages, or any other relief, or for any claim by any third party,
mbed_official 627:4fa1328d9c60 27 * arising from your use of this Software.
mbed_official 627:4fa1328d9c60 28 *
mbed_official 627:4fa1328d9c60 29 ******************************************************************************/
mbed_official 525:c320967f86b9 30
mbed_official 525:c320967f86b9 31 #include "device.h"
mbed_official 525:c320967f86b9 32 #include "clocking.h"
mbed_official 525:c320967f86b9 33 #if DEVICE_SERIAL
mbed_official 525:c320967f86b9 34
mbed_official 525:c320967f86b9 35 #include "mbed_assert.h"
mbed_official 525:c320967f86b9 36 #include "serial_api.h"
mbed_official 525:c320967f86b9 37 #include <string.h>
mbed_official 525:c320967f86b9 38 #include <stdbool.h>
mbed_official 525:c320967f86b9 39
mbed_official 525:c320967f86b9 40 #include "pinmap.h"
mbed_official 525:c320967f86b9 41 #include "pinmap_function.h"
mbed_official 525:c320967f86b9 42 #include "PeripheralPins.h"
mbed_official 525:c320967f86b9 43 #include "PeripheralNames.h"
mbed_official 525:c320967f86b9 44
mbed_official 525:c320967f86b9 45 #include "em_usart.h"
mbed_official 525:c320967f86b9 46 #include "em_leuart.h"
mbed_official 525:c320967f86b9 47 #include "em_cmu.h"
mbed_official 525:c320967f86b9 48 #include "em_dma.h"
mbed_official 525:c320967f86b9 49 #include "dma_api_HAL.h"
mbed_official 525:c320967f86b9 50 #include "dma_api.h"
mbed_official 525:c320967f86b9 51 #include "sleep_api.h"
mbed_official 525:c320967f86b9 52 #include "buffer.h"
mbed_official 526:7c4bdfe6a168 53 #include "sleepmodes.h"
mbed_official 525:c320967f86b9 54
mbed_official 525:c320967f86b9 55 #define SERIAL_LEAST_ACTIVE_SLEEPMODE EM1
mbed_official 525:c320967f86b9 56 #define SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART EM2
mbed_official 525:c320967f86b9 57
mbed_official 525:c320967f86b9 58 /** Validation of LEUART register block pointer reference
mbed_official 525:c320967f86b9 59 * for assert statements. */
mbed_official 525:c320967f86b9 60 #if !defined(LEUART_COUNT)
mbed_official 525:c320967f86b9 61 #define LEUART_REF_VALID(ref) (0)
mbed_official 525:c320967f86b9 62 #elif (LEUART_COUNT == 1)
mbed_official 525:c320967f86b9 63 #define LEUART_REF_VALID(ref) ((ref) == LEUART0)
mbed_official 525:c320967f86b9 64 #elif (LEUART_COUNT == 2)
mbed_official 525:c320967f86b9 65 #define LEUART_REF_VALID(ref) (((ref) == LEUART0) || ((ref) == LEUART1))
mbed_official 525:c320967f86b9 66 #else
mbed_official 525:c320967f86b9 67 #error Undefined number of low energy UARTs (LEUART).
mbed_official 525:c320967f86b9 68 #endif
mbed_official 525:c320967f86b9 69
mbed_official 525:c320967f86b9 70 /* Store IRQ id for each UART */
mbed_official 525:c320967f86b9 71 static uint32_t serial_irq_ids[SERIAL_NUM_UARTS] = { 0 };
mbed_official 525:c320967f86b9 72 /* Interrupt handler from mbed common */
mbed_official 525:c320967f86b9 73 static uart_irq_handler irq_handler;
mbed_official 525:c320967f86b9 74 /* Keep track of incoming DMA IRQ's */
mbed_official 525:c320967f86b9 75 static bool serial_dma_irq_fired[DMACTRL_CH_CNT] = { false };
mbed_official 525:c320967f86b9 76
mbed_official 525:c320967f86b9 77 /* Serial interface on USBTX/USBRX retargets stdio */
mbed_official 525:c320967f86b9 78 int stdio_uart_inited = 0;
mbed_official 525:c320967f86b9 79 serial_t stdio_uart;
mbed_official 525:c320967f86b9 80
mbed_official 525:c320967f86b9 81 static void uart_irq(UARTName, int, SerialIrq);
mbed_official 525:c320967f86b9 82 uint8_t serial_get_index(serial_t *obj);
mbed_official 547:88c982c8f758 83 void serial_enable(serial_t *obj, uint8_t enable);
mbed_official 547:88c982c8f758 84 void serial_enable_pins(serial_t *obj, uint8_t enable);
mbed_official 525:c320967f86b9 85 IRQn_Type serial_get_rx_irq_index(serial_t *obj);
mbed_official 525:c320967f86b9 86 IRQn_Type serial_get_tx_irq_index(serial_t *obj);
mbed_official 525:c320967f86b9 87 CMU_Clock_TypeDef serial_get_clock(serial_t *obj);
mbed_official 525:c320967f86b9 88
mbed_official 525:c320967f86b9 89 /* ISRs for RX and TX events */
mbed_official 525:c320967f86b9 90 #ifdef UART0
mbed_official 525:c320967f86b9 91 static void uart0_rx_irq() { uart_irq(UART_0, 0, RxIrq); }
mbed_official 525:c320967f86b9 92 static void uart0_tx_irq() { uart_irq(UART_0, 0, TxIrq); USART_IntClear((USART_TypeDef*)UART_0, USART_IFC_TXC);}
mbed_official 525:c320967f86b9 93 #endif
mbed_official 525:c320967f86b9 94 #ifdef UART1
mbed_official 525:c320967f86b9 95 static void uart1_rx_irq() { uart_irq(UART_1, 1, RxIrq); }
mbed_official 525:c320967f86b9 96 static void uart1_tx_irq() { uart_irq(UART_1, 1, TxIrq); USART_IntClear((USART_TypeDef*)UART_1, USART_IFC_TXC);}
mbed_official 525:c320967f86b9 97 #endif
mbed_official 525:c320967f86b9 98 #ifdef USART0
mbed_official 525:c320967f86b9 99 static void usart0_rx_irq() { uart_irq(USART_0, 2, RxIrq); }
mbed_official 525:c320967f86b9 100 static void usart0_tx_irq() { uart_irq(USART_0, 2, TxIrq); USART_IntClear((USART_TypeDef*)USART_0, USART_IFC_TXC);}
mbed_official 525:c320967f86b9 101 #endif
mbed_official 525:c320967f86b9 102 #ifdef USART1
mbed_official 525:c320967f86b9 103 static void usart1_rx_irq() { uart_irq(USART_1, 3, RxIrq); }
mbed_official 525:c320967f86b9 104 static void usart1_tx_irq() { uart_irq(USART_1, 3, TxIrq); USART_IntClear((USART_TypeDef*)USART_1, USART_IFC_TXC);}
mbed_official 525:c320967f86b9 105 #endif
mbed_official 525:c320967f86b9 106 #ifdef USART2
mbed_official 525:c320967f86b9 107 static void usart2_rx_irq() { uart_irq(USART_2, 4, RxIrq); }
mbed_official 525:c320967f86b9 108 static void usart2_tx_irq() { uart_irq(USART_2, 4, TxIrq); USART_IntClear((USART_TypeDef*)USART_2, USART_IFC_TXC);}
mbed_official 525:c320967f86b9 109 #endif
mbed_official 525:c320967f86b9 110 #ifdef LEUART0
mbed_official 548:1abac31e188e 111 static void leuart0_irq()
mbed_official 548:1abac31e188e 112 {
mbed_official 525:c320967f86b9 113 if(LEUART_IntGetEnabled(LEUART0) && (LEUART_IF_RXDATAV | LEUART_IF_FERR | LEUART_IFC_PERR | LEUART_IF_RXOF)) {
mbed_official 548:1abac31e188e 114 uart_irq(LEUART_0, 5, RxIrq);
mbed_official 525:c320967f86b9 115 } else {
mbed_official 525:c320967f86b9 116 uart_irq(LEUART_0, 5, TxIrq);
mbed_official 525:c320967f86b9 117 }
mbed_official 525:c320967f86b9 118 }
mbed_official 525:c320967f86b9 119 #endif
mbed_official 525:c320967f86b9 120 #ifdef LEUART1
mbed_official 548:1abac31e188e 121 static void leuart1_irq()
mbed_official 548:1abac31e188e 122 {
mbed_official 525:c320967f86b9 123 if(LEUART_IntGetEnabled(LEUART1) && (LEUART_IF_RXDATAV | LEUART_IF_FERR | LEUART_IFC_PERR | LEUART_IF_RXOF)) {
mbed_official 548:1abac31e188e 124 uart_irq(LEUART_1, 6, RxIrq);
mbed_official 525:c320967f86b9 125 } else {
mbed_official 525:c320967f86b9 126 uart_irq(LEUART_1, 6, TxIrq);
mbed_official 525:c320967f86b9 127 }
mbed_official 525:c320967f86b9 128 }
mbed_official 525:c320967f86b9 129 #endif
mbed_official 525:c320967f86b9 130
mbed_official 525:c320967f86b9 131 /**
mbed_official 525:c320967f86b9 132 * Initialize the UART using default settings, overridden by settings from serial object
mbed_official 525:c320967f86b9 133 *
mbed_official 525:c320967f86b9 134 * @param obj pointer to serial object
mbed_official 525:c320967f86b9 135 */
mbed_official 525:c320967f86b9 136 static void uart_init(serial_t *obj)
mbed_official 525:c320967f86b9 137 {
mbed_official 525:c320967f86b9 138 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 139 LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
mbed_official 525:c320967f86b9 140
mbed_official 525:c320967f86b9 141 init.enable = leuartDisable;
mbed_official 525:c320967f86b9 142 init.baudrate = 9600;
mbed_official 525:c320967f86b9 143 init.databits = leuartDatabits8;
mbed_official 525:c320967f86b9 144 init.parity = leuartNoParity;
mbed_official 525:c320967f86b9 145 init.stopbits = leuartStopbits1;
mbed_official 627:4fa1328d9c60 146 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 147 init.refFreq = LEUART_LF_REF_FREQ;
mbed_official 627:4fa1328d9c60 148 #else
mbed_official 525:c320967f86b9 149 init.refFreq = LEUART_REF_FREQ;
mbed_official 627:4fa1328d9c60 150 #endif
mbed_official 525:c320967f86b9 151 LEUART_Init(obj->serial.periph.leuart, &init);
mbed_official 525:c320967f86b9 152 } else {
mbed_official 525:c320967f86b9 153 USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
mbed_official 525:c320967f86b9 154
mbed_official 525:c320967f86b9 155 init.enable = usartDisable;
mbed_official 525:c320967f86b9 156 init.baudrate = 9600;
mbed_official 525:c320967f86b9 157 init.oversampling = usartOVS16;
mbed_official 525:c320967f86b9 158 init.databits = usartDatabits8;
mbed_official 525:c320967f86b9 159 init.parity = usartNoParity;
mbed_official 525:c320967f86b9 160 init.stopbits = usartStopbits1;
mbed_official 525:c320967f86b9 161
mbed_official 525:c320967f86b9 162 /* Determine the reference clock, because the correct clock is not set up at init time */
mbed_official 525:c320967f86b9 163 init.refFreq = REFERENCE_FREQUENCY;
mbed_official 525:c320967f86b9 164
mbed_official 525:c320967f86b9 165 USART_InitAsync(obj->serial.periph.uart, &init);
mbed_official 525:c320967f86b9 166 }
mbed_official 525:c320967f86b9 167 }
mbed_official 525:c320967f86b9 168
mbed_official 525:c320967f86b9 169 /**
mbed_official 525:c320967f86b9 170 * Get index of serial object, relating it to the physical peripheral.
mbed_official 525:c320967f86b9 171 *
mbed_official 525:c320967f86b9 172 * @param obj pointer to serial object
mbed_official 525:c320967f86b9 173 * @return internal index of U(S)ART peripheral
mbed_official 525:c320967f86b9 174 */
mbed_official 525:c320967f86b9 175 inline uint8_t serial_get_index(serial_t *obj)
mbed_official 525:c320967f86b9 176 {
mbed_official 525:c320967f86b9 177 switch ((uint32_t)obj->serial.periph.uart) {
mbed_official 525:c320967f86b9 178 #ifdef UART0
mbed_official 525:c320967f86b9 179 case UART_0:
mbed_official 525:c320967f86b9 180 return 0;
mbed_official 525:c320967f86b9 181 #endif
mbed_official 525:c320967f86b9 182 #ifdef UART1
mbed_official 525:c320967f86b9 183 case UART_1:
mbed_official 525:c320967f86b9 184 return 1;
mbed_official 525:c320967f86b9 185 #endif
mbed_official 525:c320967f86b9 186 #ifdef USART0
mbed_official 525:c320967f86b9 187 case USART_0:
mbed_official 525:c320967f86b9 188 return 2;
mbed_official 525:c320967f86b9 189 #endif
mbed_official 525:c320967f86b9 190 #ifdef USART1
mbed_official 525:c320967f86b9 191 case USART_1:
mbed_official 525:c320967f86b9 192 return 3;
mbed_official 525:c320967f86b9 193 #endif
mbed_official 525:c320967f86b9 194 #ifdef USART2
mbed_official 525:c320967f86b9 195 case USART_2:
mbed_official 525:c320967f86b9 196 return 4;
mbed_official 525:c320967f86b9 197 #endif
mbed_official 525:c320967f86b9 198 #ifdef LEUART0
mbed_official 525:c320967f86b9 199 case LEUART_0:
mbed_official 525:c320967f86b9 200 return 5;
mbed_official 525:c320967f86b9 201 #endif
mbed_official 525:c320967f86b9 202 #ifdef LEUART1
mbed_official 525:c320967f86b9 203 case LEUART_1:
mbed_official 525:c320967f86b9 204 return 6;
mbed_official 525:c320967f86b9 205 #endif
mbed_official 525:c320967f86b9 206 }
mbed_official 525:c320967f86b9 207 return 0;
mbed_official 525:c320967f86b9 208 }
mbed_official 525:c320967f86b9 209
mbed_official 525:c320967f86b9 210 /**
mbed_official 525:c320967f86b9 211 * Get index of serial object RX IRQ, relating it to the physical peripheral.
mbed_official 525:c320967f86b9 212 *
mbed_official 525:c320967f86b9 213 * @param obj pointer to serial object
mbed_official 525:c320967f86b9 214 * @return internal NVIC RX IRQ index of U(S)ART peripheral
mbed_official 525:c320967f86b9 215 */
mbed_official 525:c320967f86b9 216 inline IRQn_Type serial_get_rx_irq_index(serial_t *obj)
mbed_official 525:c320967f86b9 217 {
mbed_official 525:c320967f86b9 218 switch ((uint32_t)obj->serial.periph.uart) {
mbed_official 525:c320967f86b9 219 #ifdef UART0
mbed_official 525:c320967f86b9 220 case UART_0:
mbed_official 525:c320967f86b9 221 return UART0_RX_IRQn;
mbed_official 525:c320967f86b9 222 #endif
mbed_official 525:c320967f86b9 223 #ifdef UART1
mbed_official 525:c320967f86b9 224 case UART_1:
mbed_official 525:c320967f86b9 225 return UART1_RX_IRQn;
mbed_official 525:c320967f86b9 226 #endif
mbed_official 525:c320967f86b9 227 #ifdef USART0
mbed_official 525:c320967f86b9 228 case USART_0:
mbed_official 525:c320967f86b9 229 return USART0_RX_IRQn;
mbed_official 525:c320967f86b9 230 #endif
mbed_official 525:c320967f86b9 231 #ifdef USART1
mbed_official 525:c320967f86b9 232 case USART_1:
mbed_official 525:c320967f86b9 233 return USART1_RX_IRQn;
mbed_official 525:c320967f86b9 234 #endif
mbed_official 525:c320967f86b9 235 #ifdef USART2
mbed_official 525:c320967f86b9 236 case USART_2:
mbed_official 525:c320967f86b9 237 return USART2_RX_IRQn;
mbed_official 525:c320967f86b9 238 #endif
mbed_official 525:c320967f86b9 239 #ifdef LEUART0
mbed_official 525:c320967f86b9 240 case LEUART_0:
mbed_official 525:c320967f86b9 241 return LEUART0_IRQn;
mbed_official 525:c320967f86b9 242 #endif
mbed_official 525:c320967f86b9 243 #ifdef LEUART1
mbed_official 525:c320967f86b9 244 case LEUART_1:
mbed_official 525:c320967f86b9 245 return LEUART1_IRQn;
mbed_official 525:c320967f86b9 246 #endif
mbed_official 525:c320967f86b9 247 default:
mbed_official 525:c320967f86b9 248 MBED_ASSERT(0);
mbed_official 525:c320967f86b9 249 }
mbed_official 526:7c4bdfe6a168 250 return (IRQn_Type)0;
mbed_official 525:c320967f86b9 251 }
mbed_official 525:c320967f86b9 252
mbed_official 525:c320967f86b9 253 /**
mbed_official 525:c320967f86b9 254 * Get index of serial object TX IRQ, relating it to the physical peripheral.
mbed_official 525:c320967f86b9 255 *
mbed_official 525:c320967f86b9 256 * @param obj pointer to serial object
mbed_official 525:c320967f86b9 257 * @return internal NVIC TX IRQ index of U(S)ART peripheral
mbed_official 525:c320967f86b9 258 */
mbed_official 525:c320967f86b9 259 inline IRQn_Type serial_get_tx_irq_index(serial_t *obj)
mbed_official 525:c320967f86b9 260 {
mbed_official 525:c320967f86b9 261 switch ((uint32_t)obj->serial.periph.uart) {
mbed_official 525:c320967f86b9 262 #ifdef UART0
mbed_official 525:c320967f86b9 263 case UART_0:
mbed_official 525:c320967f86b9 264 return UART0_TX_IRQn;
mbed_official 525:c320967f86b9 265 #endif
mbed_official 525:c320967f86b9 266 #ifdef UART1
mbed_official 525:c320967f86b9 267 case UART_1:
mbed_official 525:c320967f86b9 268 return UART1_TX_IRQn;
mbed_official 525:c320967f86b9 269 #endif
mbed_official 525:c320967f86b9 270 #ifdef USART0
mbed_official 525:c320967f86b9 271 case USART_0:
mbed_official 525:c320967f86b9 272 return USART0_TX_IRQn;
mbed_official 525:c320967f86b9 273 #endif
mbed_official 525:c320967f86b9 274 #ifdef USART1
mbed_official 525:c320967f86b9 275 case USART_1:
mbed_official 525:c320967f86b9 276 return USART1_TX_IRQn;
mbed_official 525:c320967f86b9 277 #endif
mbed_official 525:c320967f86b9 278 #ifdef USART2
mbed_official 525:c320967f86b9 279 case USART_2:
mbed_official 525:c320967f86b9 280 return USART2_TX_IRQn;
mbed_official 525:c320967f86b9 281 #endif
mbed_official 525:c320967f86b9 282 #ifdef LEUART0
mbed_official 525:c320967f86b9 283 case LEUART_0:
mbed_official 525:c320967f86b9 284 return LEUART0_IRQn;
mbed_official 525:c320967f86b9 285 #endif
mbed_official 525:c320967f86b9 286 #ifdef LEUART1
mbed_official 525:c320967f86b9 287 case LEUART_1:
mbed_official 525:c320967f86b9 288 return LEUART1_IRQn;
mbed_official 525:c320967f86b9 289 #endif
mbed_official 525:c320967f86b9 290 default:
mbed_official 525:c320967f86b9 291 MBED_ASSERT(0);
mbed_official 525:c320967f86b9 292 }
mbed_official 526:7c4bdfe6a168 293 return (IRQn_Type)0;
mbed_official 525:c320967f86b9 294 }
mbed_official 525:c320967f86b9 295
mbed_official 525:c320967f86b9 296 /**
mbed_official 525:c320967f86b9 297 * Get clock tree for serial peripheral pointed to by obj.
mbed_official 548:1abac31e188e 298 *
mbed_official 525:c320967f86b9 299 * @param obj pointer to serial object
mbed_official 525:c320967f86b9 300 * @return CMU_Clock_TypeDef for U(S)ART
mbed_official 525:c320967f86b9 301 */
mbed_official 525:c320967f86b9 302 inline CMU_Clock_TypeDef serial_get_clock(serial_t *obj)
mbed_official 525:c320967f86b9 303 {
mbed_official 525:c320967f86b9 304 switch ((uint32_t)obj->serial.periph.uart) {
mbed_official 525:c320967f86b9 305 #ifdef UART0
mbed_official 525:c320967f86b9 306 case UART_0:
mbed_official 525:c320967f86b9 307 return cmuClock_UART0;
mbed_official 525:c320967f86b9 308 #endif
mbed_official 525:c320967f86b9 309 #ifdef UART1
mbed_official 525:c320967f86b9 310 case UART_1:
mbed_official 525:c320967f86b9 311 return cmuClock_UART1;
mbed_official 525:c320967f86b9 312 #endif
mbed_official 525:c320967f86b9 313 #ifdef USART0
mbed_official 525:c320967f86b9 314 case USART_0:
mbed_official 525:c320967f86b9 315 return cmuClock_USART0;
mbed_official 525:c320967f86b9 316 #endif
mbed_official 525:c320967f86b9 317 #ifdef USART1
mbed_official 525:c320967f86b9 318 case USART_1:
mbed_official 525:c320967f86b9 319 return cmuClock_USART1;
mbed_official 525:c320967f86b9 320 #endif
mbed_official 525:c320967f86b9 321 #ifdef USART2
mbed_official 525:c320967f86b9 322 case USART_2:
mbed_official 525:c320967f86b9 323 return cmuClock_USART2;
mbed_official 525:c320967f86b9 324 #endif
mbed_official 525:c320967f86b9 325 #ifdef LEUART0
mbed_official 525:c320967f86b9 326 case LEUART_0:
mbed_official 525:c320967f86b9 327 return cmuClock_LEUART0;
mbed_official 525:c320967f86b9 328 #endif
mbed_official 525:c320967f86b9 329 #ifdef LEUART1
mbed_official 525:c320967f86b9 330 case LEUART_1:
mbed_official 525:c320967f86b9 331 return cmuClock_LEUART1;
mbed_official 525:c320967f86b9 332 #endif
mbed_official 525:c320967f86b9 333 default:
mbed_official 525:c320967f86b9 334 return cmuClock_HFPER;
mbed_official 525:c320967f86b9 335 }
mbed_official 525:c320967f86b9 336 }
mbed_official 525:c320967f86b9 337
mbed_official 525:c320967f86b9 338 void serial_preinit(serial_t *obj, PinName tx, PinName rx)
mbed_official 525:c320967f86b9 339 {
mbed_official 525:c320967f86b9 340 /* Get UART object connected to the given pins */
mbed_official 525:c320967f86b9 341 UARTName uart_tx = (UARTName) pinmap_peripheral(tx, PinMap_UART_TX);
mbed_official 525:c320967f86b9 342 UARTName uart_rx = (UARTName) pinmap_peripheral(rx, PinMap_UART_RX);
mbed_official 525:c320967f86b9 343 /* Check that pins are connected to same UART */
mbed_official 525:c320967f86b9 344 UARTName uart = (UARTName) pinmap_merge(uart_tx, uart_rx);
mbed_official 525:c320967f86b9 345 MBED_ASSERT((int) uart != NC);
mbed_official 525:c320967f86b9 346
mbed_official 525:c320967f86b9 347 obj->serial.periph.uart = (USART_TypeDef *) uart;
mbed_official 525:c320967f86b9 348
mbed_official 525:c320967f86b9 349 /* Get location */
mbed_official 525:c320967f86b9 350 uint32_t uart_tx_loc = pin_location(tx, PinMap_UART_TX);
mbed_official 525:c320967f86b9 351 uint32_t uart_rx_loc = pin_location(rx, PinMap_UART_RX);
mbed_official 525:c320967f86b9 352 /* Check that pins are used by same location for the given UART */
mbed_official 525:c320967f86b9 353 obj->serial.location = pinmap_merge(uart_tx_loc, uart_rx_loc);
mbed_official 525:c320967f86b9 354 MBED_ASSERT(obj->serial.location != (uint32_t)NC);
mbed_official 525:c320967f86b9 355
mbed_official 525:c320967f86b9 356 /* Store pins in object for easy disabling in serial_free() */
mbed_official 525:c320967f86b9 357 obj->serial.rx_pin = rx;
mbed_official 525:c320967f86b9 358 obj->serial.tx_pin = tx;
mbed_official 525:c320967f86b9 359
mbed_official 525:c320967f86b9 360 /* Select interrupt */
mbed_official 525:c320967f86b9 361 switch ((uint32_t)obj->serial.periph.uart) {
mbed_official 525:c320967f86b9 362 #ifdef UART0
mbed_official 525:c320967f86b9 363 case UART_0:
mbed_official 525:c320967f86b9 364 NVIC_SetVector(UART0_RX_IRQn, (uint32_t) &uart0_rx_irq);
mbed_official 525:c320967f86b9 365 NVIC_SetVector(UART0_TX_IRQn, (uint32_t) &uart0_tx_irq);
mbed_official 525:c320967f86b9 366 NVIC_SetPriority(UART0_TX_IRQn, 1);
mbed_official 525:c320967f86b9 367 break;
mbed_official 525:c320967f86b9 368 #endif
mbed_official 525:c320967f86b9 369 #ifdef UART1
mbed_official 525:c320967f86b9 370 case UART_1:
mbed_official 525:c320967f86b9 371 NVIC_SetVector(UART1_RX_IRQn, (uint32_t) &uart1_rx_irq);
mbed_official 525:c320967f86b9 372 NVIC_SetVector(UART1_TX_IRQn, (uint32_t) &uart1_tx_irq);
mbed_official 525:c320967f86b9 373 NVIC_SetPriority(UART1_TX_IRQn, 1);
mbed_official 525:c320967f86b9 374 break;
mbed_official 525:c320967f86b9 375 #endif
mbed_official 525:c320967f86b9 376 #ifdef USART0
mbed_official 525:c320967f86b9 377 case USART_0:
mbed_official 525:c320967f86b9 378 NVIC_SetVector(USART0_RX_IRQn, (uint32_t) &usart0_rx_irq);
mbed_official 525:c320967f86b9 379 NVIC_SetVector(USART0_TX_IRQn, (uint32_t) &usart0_tx_irq);
mbed_official 525:c320967f86b9 380 NVIC_SetPriority(USART0_TX_IRQn, 1);
mbed_official 525:c320967f86b9 381 break;
mbed_official 525:c320967f86b9 382 #endif
mbed_official 525:c320967f86b9 383 #ifdef USART1
mbed_official 525:c320967f86b9 384 case USART_1:
mbed_official 525:c320967f86b9 385 NVIC_SetVector(USART1_RX_IRQn, (uint32_t) &usart1_rx_irq);
mbed_official 525:c320967f86b9 386 NVIC_SetVector(USART1_TX_IRQn, (uint32_t) &usart1_tx_irq);
mbed_official 525:c320967f86b9 387 NVIC_SetPriority(USART1_TX_IRQn, 1);
mbed_official 525:c320967f86b9 388 break;
mbed_official 525:c320967f86b9 389 #endif
mbed_official 525:c320967f86b9 390 #ifdef USART2
mbed_official 525:c320967f86b9 391 case USART_2:
mbed_official 525:c320967f86b9 392 NVIC_SetVector(USART2_RX_IRQn, (uint32_t) &usart2_rx_irq);
mbed_official 525:c320967f86b9 393 NVIC_SetVector(USART2_TX_IRQn, (uint32_t) &usart2_tx_irq);
mbed_official 525:c320967f86b9 394 NVIC_SetPriority(USART2_TX_IRQn, 1);
mbed_official 525:c320967f86b9 395 break;
mbed_official 525:c320967f86b9 396 #endif
mbed_official 525:c320967f86b9 397 #ifdef LEUART0
mbed_official 525:c320967f86b9 398 case LEUART_0:
mbed_official 525:c320967f86b9 399 NVIC_SetVector(LEUART0_IRQn, (uint32_t) &leuart0_irq);
mbed_official 525:c320967f86b9 400 break;
mbed_official 525:c320967f86b9 401 #endif
mbed_official 525:c320967f86b9 402 #ifdef LEUART1
mbed_official 525:c320967f86b9 403 case LEUART_1:
mbed_official 525:c320967f86b9 404 NVIC_SetVector(LEUART1_IRQn, (uint32_t) &leuart1_irq);
mbed_official 525:c320967f86b9 405 break;
mbed_official 525:c320967f86b9 406 #endif
mbed_official 525:c320967f86b9 407 }
mbed_official 525:c320967f86b9 408 }
mbed_official 525:c320967f86b9 409
mbed_official 525:c320967f86b9 410 void serial_enable_pins(serial_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 411 {
mbed_official 525:c320967f86b9 412 if (enable) {
mbed_official 525:c320967f86b9 413 /* Configure GPIO pins*/
mbed_official 525:c320967f86b9 414 pin_mode(obj->serial.rx_pin, Input);
mbed_official 525:c320967f86b9 415 /* 0x10 sets DOUT. Prevents false start. */
mbed_official 525:c320967f86b9 416 pin_mode(obj->serial.tx_pin, PushPull | 0x10);
mbed_official 525:c320967f86b9 417 } else {
mbed_official 525:c320967f86b9 418 pin_mode(obj->serial.rx_pin, Disabled);
mbed_official 525:c320967f86b9 419 pin_mode(obj->serial.tx_pin, Disabled);
mbed_official 525:c320967f86b9 420 }
mbed_official 525:c320967f86b9 421 }
mbed_official 525:c320967f86b9 422
mbed_official 525:c320967f86b9 423 void serial_init(serial_t *obj, PinName tx, PinName rx)
mbed_official 525:c320967f86b9 424 {
mbed_official 548:1abac31e188e 425 serial_preinit(obj, tx, rx);
mbed_official 548:1abac31e188e 426
mbed_official 525:c320967f86b9 427 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 428 // Set up LEUART clock tree
mbed_official 627:4fa1328d9c60 429 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 430 //set to use LFXO
mbed_official 627:4fa1328d9c60 431 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
mbed_official 627:4fa1328d9c60 432 CMU_ClockEnable(cmuClock_CORELE, true);
mbed_official 627:4fa1328d9c60 433 #else
mbed_official 627:4fa1328d9c60 434 //set to use high-speed clock
mbed_official 525:c320967f86b9 435 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
mbed_official 627:4fa1328d9c60 436 #endif
mbed_official 525:c320967f86b9 437 }
mbed_official 548:1abac31e188e 438
mbed_official 525:c320967f86b9 439 CMU_ClockEnable(serial_get_clock(obj), true);
mbed_official 548:1abac31e188e 440
mbed_official 525:c320967f86b9 441 /* Configure UART for async operation */
mbed_official 525:c320967f86b9 442 uart_init(obj);
mbed_official 525:c320967f86b9 443
mbed_official 525:c320967f86b9 444 /* Limitations of board controller: CDC port only supports 115kbaud */
mbed_official 525:c320967f86b9 445 if((tx == STDIO_UART_TX) && (rx == STDIO_UART_RX) && (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART )) {
mbed_official 525:c320967f86b9 446 serial_baud(obj, 115200);
mbed_official 525:c320967f86b9 447 }
mbed_official 548:1abac31e188e 448
mbed_official 525:c320967f86b9 449 /* Enable pins for UART at correct location */
mbed_official 525:c320967f86b9 450 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 451 obj->serial.periph.leuart->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT);
mbed_official 525:c320967f86b9 452 obj->serial.periph.leuart->IFC = LEUART_IFC_TXC;
mbed_official 627:4fa1328d9c60 453 obj->serial.periph.leuart->CTRL |= LEUART_CTRL_RXDMAWU | LEUART_CTRL_TXDMAWU;
mbed_official 525:c320967f86b9 454 } else {
mbed_official 525:c320967f86b9 455 obj->serial.periph.uart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (obj->serial.location << _USART_ROUTE_LOCATION_SHIFT);
mbed_official 525:c320967f86b9 456 obj->serial.periph.uart->IFC = USART_IFC_TXC;
mbed_official 525:c320967f86b9 457 }
mbed_official 548:1abac31e188e 458
mbed_official 525:c320967f86b9 459 /* If this is the UART to be used for stdio, copy it to the stdio_uart struct */
mbed_official 525:c320967f86b9 460 if (obj->serial.periph.uart == (USART_TypeDef*)STDIO_UART ) {
mbed_official 525:c320967f86b9 461 stdio_uart_inited = 1;
mbed_official 525:c320967f86b9 462 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 525:c320967f86b9 463 }
mbed_official 525:c320967f86b9 464
mbed_official 525:c320967f86b9 465 serial_enable_pins(obj, true);
mbed_official 547:88c982c8f758 466 serial_enable(obj, true);
mbed_official 548:1abac31e188e 467
mbed_official 525:c320967f86b9 468
mbed_official 525:c320967f86b9 469 obj->serial.dmaOptionsTX.dmaChannel = -1;
mbed_official 525:c320967f86b9 470 obj->serial.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
mbed_official 525:c320967f86b9 471
mbed_official 548:1abac31e188e 472 obj->serial.dmaOptionsRX.dmaChannel = -1;
mbed_official 548:1abac31e188e 473 obj->serial.dmaOptionsRX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
mbed_official 525:c320967f86b9 474
mbed_official 525:c320967f86b9 475 }
mbed_official 525:c320967f86b9 476
mbed_official 525:c320967f86b9 477 void serial_enable(serial_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 478 {
mbed_official 525:c320967f86b9 479 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 480 if (enable) {
mbed_official 525:c320967f86b9 481 LEUART_Enable(obj->serial.periph.leuart, leuartEnable);
mbed_official 525:c320967f86b9 482 } else {
mbed_official 525:c320967f86b9 483 LEUART_Enable(obj->serial.periph.leuart, leuartDisable);
mbed_official 525:c320967f86b9 484 }
mbed_official 525:c320967f86b9 485 } else {
mbed_official 525:c320967f86b9 486 if (enable) {
mbed_official 525:c320967f86b9 487 USART_Enable(obj->serial.periph.uart, usartEnable);
mbed_official 525:c320967f86b9 488 } else {
mbed_official 525:c320967f86b9 489 USART_Enable(obj->serial.periph.uart, usartDisable);
mbed_official 525:c320967f86b9 490 }
mbed_official 525:c320967f86b9 491 }
mbed_official 525:c320967f86b9 492 serial_irq_ids[serial_get_index(obj)] = 0;
mbed_official 525:c320967f86b9 493 }
mbed_official 525:c320967f86b9 494
mbed_official 525:c320967f86b9 495 /**
mbed_official 525:c320967f86b9 496 * Set UART baud rate
mbed_official 525:c320967f86b9 497 */
mbed_official 525:c320967f86b9 498 void serial_baud(serial_t *obj, int baudrate)
mbed_official 525:c320967f86b9 499 {
mbed_official 525:c320967f86b9 500 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 501 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 502
mbed_official 627:4fa1328d9c60 503 /* check if baudrate is within allowed range */
mbed_official 627:4fa1328d9c60 504 MBED_ASSERT(baudrate >= (LEUART_LF_REF_FREQ >> 7));
mbed_official 627:4fa1328d9c60 505
mbed_official 627:4fa1328d9c60 506 if(baudrate > (LEUART_LF_REF_FREQ >> 1)){
mbed_official 627:4fa1328d9c60 507 /* check if baudrate is within allowed range */
mbed_official 627:4fa1328d9c60 508 MBED_ASSERT((baudrate <= (LEUART_HF_REF_FREQ >> 1)) && (baudrate > (LEUART_HF_REF_FREQ >> 10)));
mbed_official 627:4fa1328d9c60 509
mbed_official 627:4fa1328d9c60 510 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_CORELEDIV2);
mbed_official 627:4fa1328d9c60 511 uint8_t divisor = 1;
mbed_official 627:4fa1328d9c60 512
mbed_official 627:4fa1328d9c60 513 if(baudrate > (LEUART_HF_REF_FREQ >> 7)){
mbed_official 627:4fa1328d9c60 514 divisor = 1;
mbed_official 627:4fa1328d9c60 515 }else if(baudrate > (LEUART_HF_REF_FREQ >> 8)){
mbed_official 627:4fa1328d9c60 516 divisor = 2;
mbed_official 627:4fa1328d9c60 517 }else if(baudrate > (LEUART_HF_REF_FREQ >> 9)){
mbed_official 627:4fa1328d9c60 518 divisor = 4;
mbed_official 627:4fa1328d9c60 519 }else{
mbed_official 627:4fa1328d9c60 520 divisor = 8;
mbed_official 627:4fa1328d9c60 521 }
mbed_official 627:4fa1328d9c60 522 CMU_ClockDivSet(serial_get_clock(obj), divisor);
mbed_official 627:4fa1328d9c60 523 LEUART_BaudrateSet(obj->serial.periph.leuart, LEUART_HF_REF_FREQ/divisor, (uint32_t)baudrate);
mbed_official 627:4fa1328d9c60 524 }else{
mbed_official 627:4fa1328d9c60 525 CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
mbed_official 627:4fa1328d9c60 526 CMU_ClockDivSet(serial_get_clock(obj), 1);
mbed_official 627:4fa1328d9c60 527 LEUART_BaudrateSet(obj->serial.periph.leuart, LEUART_LF_REF_FREQ, (uint32_t)baudrate);
mbed_official 627:4fa1328d9c60 528 }
mbed_official 627:4fa1328d9c60 529 #else
mbed_official 627:4fa1328d9c60 530 /* check if baudrate is within allowed range */
mbed_official 627:4fa1328d9c60 531 MBED_ASSERT((baudrate > (LEUART_REF_FREQ >> 10)) && (baudrate <= (LEUART_REF_FREQ >> 1)));
mbed_official 627:4fa1328d9c60 532 uint8_t divisor = 1;
mbed_official 627:4fa1328d9c60 533 if(baudrate > (LEUART_REF_FREQ >> 7)){
mbed_official 627:4fa1328d9c60 534 divisor = 1;
mbed_official 627:4fa1328d9c60 535 }else if(baudrate > (LEUART_REF_FREQ >> 8)){
mbed_official 627:4fa1328d9c60 536 divisor = 2;
mbed_official 627:4fa1328d9c60 537 }else if(baudrate > (LEUART_REF_FREQ >> 9)){
mbed_official 627:4fa1328d9c60 538 divisor = 4;
mbed_official 627:4fa1328d9c60 539 }else{
mbed_official 627:4fa1328d9c60 540 divisor = 8;
mbed_official 627:4fa1328d9c60 541 }
mbed_official 627:4fa1328d9c60 542 CMU_ClockDivSet(serial_get_clock(obj), divisor);
mbed_official 627:4fa1328d9c60 543 LEUART_BaudrateSet(obj->serial.periph.leuart, LEUART_REF_FREQ/divisor, (uint32_t)baudrate);
mbed_official 627:4fa1328d9c60 544 #endif
mbed_official 525:c320967f86b9 545 } else {
mbed_official 525:c320967f86b9 546 USART_BaudrateAsyncSet(obj->serial.periph.uart, REFERENCE_FREQUENCY, (uint32_t)baudrate, usartOVS16);
mbed_official 525:c320967f86b9 547 }
mbed_official 525:c320967f86b9 548 }
mbed_official 525:c320967f86b9 549
mbed_official 525:c320967f86b9 550 /**
mbed_official 525:c320967f86b9 551 * Set UART format by re-initializing the peripheral.
mbed_official 525:c320967f86b9 552 */
mbed_official 525:c320967f86b9 553 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
mbed_official 525:c320967f86b9 554 {
mbed_official 525:c320967f86b9 555 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 556 /* Save the serial state */
mbed_official 525:c320967f86b9 557 uint8_t was_enabled = LEUART_StatusGet(obj->serial.periph.leuart) & (LEUART_STATUS_TXENS | LEUART_STATUS_RXENS);
mbed_official 525:c320967f86b9 558 uint32_t enabled_interrupts = obj->serial.periph.leuart->IEN;
mbed_official 548:1abac31e188e 559
mbed_official 525:c320967f86b9 560 LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
mbed_official 548:1abac31e188e 561
mbed_official 525:c320967f86b9 562 /* We support 8 data bits ONLY on LEUART*/
mbed_official 525:c320967f86b9 563 MBED_ASSERT(data_bits == 8);
mbed_official 548:1abac31e188e 564
mbed_official 525:c320967f86b9 565 /* Re-init the UART */
mbed_official 525:c320967f86b9 566 init.enable = (was_enabled == 0 ? leuartDisable : leuartEnable);
mbed_official 525:c320967f86b9 567 init.baudrate = LEUART_BaudrateGet(obj->serial.periph.leuart);
mbed_official 525:c320967f86b9 568 if (stop_bits == 2) {
mbed_official 525:c320967f86b9 569 init.stopbits = leuartStopbits2;
mbed_official 525:c320967f86b9 570 } else {
mbed_official 525:c320967f86b9 571 init.stopbits = leuartStopbits1;
mbed_official 525:c320967f86b9 572 }
mbed_official 525:c320967f86b9 573 switch (parity) {
mbed_official 525:c320967f86b9 574 case ParityOdd:
mbed_official 525:c320967f86b9 575 case ParityForced0:
mbed_official 525:c320967f86b9 576 init.parity = leuartOddParity;
mbed_official 525:c320967f86b9 577 break;
mbed_official 525:c320967f86b9 578 case ParityEven:
mbed_official 525:c320967f86b9 579 case ParityForced1:
mbed_official 525:c320967f86b9 580 init.parity = leuartEvenParity;
mbed_official 525:c320967f86b9 581 break;
mbed_official 525:c320967f86b9 582 default: /* ParityNone */
mbed_official 525:c320967f86b9 583 init.parity = leuartNoParity;
mbed_official 525:c320967f86b9 584 break;
mbed_official 525:c320967f86b9 585 }
mbed_official 525:c320967f86b9 586
mbed_official 525:c320967f86b9 587 LEUART_Init(obj->serial.periph.leuart, &init);
mbed_official 525:c320967f86b9 588
mbed_official 525:c320967f86b9 589 /* Re-enable pins for UART at correct location */
mbed_official 525:c320967f86b9 590 obj->serial.periph.leuart->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | (obj->serial.location << _LEUART_ROUTE_LOCATION_SHIFT);
mbed_official 548:1abac31e188e 591
mbed_official 525:c320967f86b9 592 /* Re-enable interrupts */
mbed_official 525:c320967f86b9 593 if(was_enabled != 0) {
mbed_official 525:c320967f86b9 594 obj->serial.periph.leuart->IFC = LEUART_IFC_TXC;
mbed_official 525:c320967f86b9 595 obj->serial.periph.leuart->IEN = enabled_interrupts;
mbed_official 525:c320967f86b9 596 }
mbed_official 525:c320967f86b9 597 } else {
mbed_official 525:c320967f86b9 598 /* Save the serial state */
mbed_official 525:c320967f86b9 599 uint8_t was_enabled = USART_StatusGet(obj->serial.periph.uart) & (USART_STATUS_TXENS | USART_STATUS_RXENS);
mbed_official 525:c320967f86b9 600 uint32_t enabled_interrupts = obj->serial.periph.uart->IEN;
mbed_official 548:1abac31e188e 601
mbed_official 525:c320967f86b9 602
mbed_official 525:c320967f86b9 603 USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
mbed_official 548:1abac31e188e 604
mbed_official 525:c320967f86b9 605 /* We support 4 to 8 data bits */
mbed_official 525:c320967f86b9 606 MBED_ASSERT(data_bits >= 4 && data_bits <= 8);
mbed_official 548:1abac31e188e 607
mbed_official 525:c320967f86b9 608 /* Re-init the UART */
mbed_official 525:c320967f86b9 609 init.enable = (was_enabled == 0 ? usartDisable : usartEnable);
mbed_official 525:c320967f86b9 610 init.baudrate = USART_BaudrateGet(obj->serial.periph.uart);
mbed_official 525:c320967f86b9 611 init.oversampling = usartOVS16;
mbed_official 525:c320967f86b9 612 init.databits = (USART_Databits_TypeDef)((data_bits - 3) << _USART_FRAME_DATABITS_SHIFT);
mbed_official 525:c320967f86b9 613 if (stop_bits == 2) {
mbed_official 525:c320967f86b9 614 init.stopbits = usartStopbits2;
mbed_official 525:c320967f86b9 615 } else {
mbed_official 525:c320967f86b9 616 init.stopbits = usartStopbits1;
mbed_official 525:c320967f86b9 617 }
mbed_official 525:c320967f86b9 618 switch (parity) {
mbed_official 525:c320967f86b9 619 case ParityOdd:
mbed_official 525:c320967f86b9 620 case ParityForced0:
mbed_official 525:c320967f86b9 621 init.parity = usartOddParity;
mbed_official 525:c320967f86b9 622 break;
mbed_official 525:c320967f86b9 623 case ParityEven:
mbed_official 525:c320967f86b9 624 case ParityForced1:
mbed_official 525:c320967f86b9 625 init.parity = usartEvenParity;
mbed_official 525:c320967f86b9 626 break;
mbed_official 525:c320967f86b9 627 default: /* ParityNone */
mbed_official 525:c320967f86b9 628 init.parity = usartNoParity;
mbed_official 525:c320967f86b9 629 break;
mbed_official 525:c320967f86b9 630 }
mbed_official 525:c320967f86b9 631
mbed_official 525:c320967f86b9 632 USART_InitAsync(obj->serial.periph.uart, &init);
mbed_official 525:c320967f86b9 633
mbed_official 525:c320967f86b9 634 /* Re-enable pins for UART at correct location */
mbed_official 525:c320967f86b9 635 obj->serial.periph.uart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (obj->serial.location << _USART_ROUTE_LOCATION_SHIFT);
mbed_official 548:1abac31e188e 636
mbed_official 525:c320967f86b9 637 /* Re-enable interrupts */
mbed_official 525:c320967f86b9 638 if(was_enabled != 0) {
mbed_official 525:c320967f86b9 639 obj->serial.periph.uart->IFC = USART_IFC_TXC;
mbed_official 525:c320967f86b9 640 obj->serial.periph.uart->IEN = enabled_interrupts;
mbed_official 525:c320967f86b9 641 }
mbed_official 525:c320967f86b9 642 }
mbed_official 525:c320967f86b9 643 }
mbed_official 525:c320967f86b9 644
mbed_official 525:c320967f86b9 645 /******************************************************************************
mbed_official 525:c320967f86b9 646 * INTERRUPTS *
mbed_official 525:c320967f86b9 647 ******************************************************************************/
mbed_official 525:c320967f86b9 648 uint8_t serial_tx_ready(serial_t *obj)
mbed_official 525:c320967f86b9 649 {
mbed_official 525:c320967f86b9 650 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 651 return (obj->serial.periph.leuart->STATUS & LEUART_STATUS_TXBL) ? true : false;
mbed_official 525:c320967f86b9 652 } else {
mbed_official 525:c320967f86b9 653 return (obj->serial.periph.uart->STATUS & USART_STATUS_TXBL) ? true : false;
mbed_official 525:c320967f86b9 654 }
mbed_official 525:c320967f86b9 655 }
mbed_official 525:c320967f86b9 656
mbed_official 525:c320967f86b9 657 uint8_t serial_rx_ready(serial_t *obj)
mbed_official 525:c320967f86b9 658 {
mbed_official 525:c320967f86b9 659 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 660 return (obj->serial.periph.leuart->STATUS & LEUART_STATUS_RXDATAV) ? true : false;
mbed_official 525:c320967f86b9 661 } else {
mbed_official 525:c320967f86b9 662 return (obj->serial.periph.uart->STATUS & USART_STATUS_RXDATAV) ? true : false;
mbed_official 525:c320967f86b9 663 }
mbed_official 525:c320967f86b9 664 }
mbed_official 525:c320967f86b9 665
mbed_official 525:c320967f86b9 666 void serial_write_asynch(serial_t *obj, int data)
mbed_official 525:c320967f86b9 667 {
mbed_official 525:c320967f86b9 668 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 669 obj->serial.periph.leuart->TXDATA = (uint32_t)data;
mbed_official 525:c320967f86b9 670 } else {
mbed_official 525:c320967f86b9 671 obj->serial.periph.uart->TXDATA = (uint32_t)data;
mbed_official 525:c320967f86b9 672 }
mbed_official 525:c320967f86b9 673 }
mbed_official 525:c320967f86b9 674
mbed_official 525:c320967f86b9 675 int serial_read_asynch(serial_t *obj)
mbed_official 525:c320967f86b9 676 {
mbed_official 525:c320967f86b9 677 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 678 return (int)obj->serial.periph.leuart->RXDATA;
mbed_official 525:c320967f86b9 679 } else {
mbed_official 525:c320967f86b9 680 return (int)obj->serial.periph.uart->RXDATA;
mbed_official 548:1abac31e188e 681 }
mbed_official 525:c320967f86b9 682 }
mbed_official 525:c320967f86b9 683
mbed_official 525:c320967f86b9 684 uint8_t serial_tx_int_flag(serial_t *obj)
mbed_official 525:c320967f86b9 685 {
mbed_official 525:c320967f86b9 686 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 687 return (obj->serial.periph.leuart->IF & LEUART_IF_TXBL) ? true : false;
mbed_official 525:c320967f86b9 688 } else {
mbed_official 525:c320967f86b9 689 return (obj->serial.periph.uart->IF & USART_IF_TXBL) ? true : false;
mbed_official 548:1abac31e188e 690 }
mbed_official 525:c320967f86b9 691 }
mbed_official 525:c320967f86b9 692
mbed_official 525:c320967f86b9 693 uint8_t serial_rx_int_flag(serial_t *obj)
mbed_official 525:c320967f86b9 694 {
mbed_official 525:c320967f86b9 695 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 696 return (obj->serial.periph.leuart->IF & LEUART_IF_RXDATAV) ? true : false;
mbed_official 525:c320967f86b9 697 } else {
mbed_official 525:c320967f86b9 698 return (obj->serial.periph.uart->IF & USART_IF_RXDATAV) ? true : false;
mbed_official 548:1abac31e188e 699 }
mbed_official 525:c320967f86b9 700 }
mbed_official 525:c320967f86b9 701
mbed_official 525:c320967f86b9 702 void serial_read_asynch_complete(serial_t *obj)
mbed_official 525:c320967f86b9 703 {
mbed_official 525:c320967f86b9 704 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 705 obj->serial.periph.leuart->IFC |= LEUART_IFC_RXOF; // in case it got full
mbed_official 525:c320967f86b9 706 } else {
mbed_official 525:c320967f86b9 707 obj->serial.periph.uart->IFC |= USART_IFC_RXFULL; // in case it got full
mbed_official 525:c320967f86b9 708 }
mbed_official 525:c320967f86b9 709 }
mbed_official 525:c320967f86b9 710
mbed_official 525:c320967f86b9 711 void serial_write_asynch_complete(serial_t *obj)
mbed_official 525:c320967f86b9 712 {
mbed_official 525:c320967f86b9 713 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 714 obj->serial.periph.leuart->IFC |= LEUART_IFC_TXC;
mbed_official 525:c320967f86b9 715 } else {
mbed_official 525:c320967f86b9 716 obj->serial.periph.uart->IFC |= USART_IFC_TXC;
mbed_official 525:c320967f86b9 717 }
mbed_official 525:c320967f86b9 718 }
mbed_official 525:c320967f86b9 719
mbed_official 525:c320967f86b9 720 /** Enable and set the interrupt handler for write (TX)
mbed_official 525:c320967f86b9 721 *
mbed_official 525:c320967f86b9 722 * @param obj The serial object
mbed_official 525:c320967f86b9 723 * @param address The address of TX handler
mbed_official 525:c320967f86b9 724 * @param enable Set to non-zero to enable or zero to disable
mbed_official 525:c320967f86b9 725 */
mbed_official 525:c320967f86b9 726 void serial_write_enable_interrupt(serial_t *obj, uint32_t address, uint8_t enable)
mbed_official 525:c320967f86b9 727 {
mbed_official 525:c320967f86b9 728 NVIC_SetVector(serial_get_tx_irq_index(obj), address);
mbed_official 525:c320967f86b9 729 serial_irq_set(obj, (SerialIrq)1, enable);
mbed_official 525:c320967f86b9 730 }
mbed_official 525:c320967f86b9 731
mbed_official 525:c320967f86b9 732 /** Enable and set the interrupt handler for read (RX)
mbed_official 525:c320967f86b9 733 *
mbed_official 525:c320967f86b9 734 * @param obj The serial object
mbed_official 525:c320967f86b9 735 * @param address The address of RX handler
mbed_official 525:c320967f86b9 736 * @param enable Set to non-zero to enable or zero to disable
mbed_official 525:c320967f86b9 737 */
mbed_official 525:c320967f86b9 738 void serial_read_enable_interrupt(serial_t *obj, uint32_t address, uint8_t enable)
mbed_official 525:c320967f86b9 739 {
mbed_official 525:c320967f86b9 740 NVIC_SetVector(serial_get_rx_irq_index(obj), address);
mbed_official 525:c320967f86b9 741 serial_irq_set(obj, (SerialIrq)0, enable);
mbed_official 525:c320967f86b9 742 }
mbed_official 525:c320967f86b9 743
mbed_official 525:c320967f86b9 744 uint8_t serial_interrupt_enabled(serial_t *obj)
mbed_official 525:c320967f86b9 745 {
mbed_official 525:c320967f86b9 746 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 747 return (obj->serial.periph.leuart->IEN & (LEUART_IEN_RXDATAV | LEUART_IEN_TXBL)) ? true : false;
mbed_official 525:c320967f86b9 748 } else {
mbed_official 525:c320967f86b9 749 return (obj->serial.periph.uart->IEN & (USART_IEN_RXDATAV | USART_IEN_TXBL)) ? true : false;
mbed_official 525:c320967f86b9 750 }
mbed_official 525:c320967f86b9 751 }
mbed_official 525:c320967f86b9 752
mbed_official 525:c320967f86b9 753 /**
mbed_official 525:c320967f86b9 754 * Set handler for all serial interrupts (is probably SerialBase::_handler())
mbed_official 525:c320967f86b9 755 * and store IRQ ID to be returned to the handler upon interrupt. ID is
mbed_official 525:c320967f86b9 756 * probably a pointer to the calling Serial object.
mbed_official 525:c320967f86b9 757 */
mbed_official 525:c320967f86b9 758 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
mbed_official 525:c320967f86b9 759 {
mbed_official 525:c320967f86b9 760 irq_handler = handler;
mbed_official 525:c320967f86b9 761 serial_irq_ids[serial_get_index(obj)] = id;
mbed_official 525:c320967f86b9 762 }
mbed_official 525:c320967f86b9 763
mbed_official 525:c320967f86b9 764 /**
mbed_official 525:c320967f86b9 765 * Generic ISR for all UARTs, both TX and RX
mbed_official 525:c320967f86b9 766 */
mbed_official 525:c320967f86b9 767 static void uart_irq(UARTName name, int index, SerialIrq irq)
mbed_official 525:c320967f86b9 768 {
mbed_official 525:c320967f86b9 769 if (serial_irq_ids[index] != 0) {
mbed_official 525:c320967f86b9 770 /* Pass interrupt on to mbed common handler */
mbed_official 525:c320967f86b9 771 irq_handler(serial_irq_ids[index], irq);
mbed_official 525:c320967f86b9 772 /* Clearing interrupt not necessary */
mbed_official 525:c320967f86b9 773 }
mbed_official 525:c320967f86b9 774 }
mbed_official 525:c320967f86b9 775
mbed_official 525:c320967f86b9 776 /**
mbed_official 525:c320967f86b9 777 * Set ISR for a given UART and interrupt event (TX or RX)
mbed_official 525:c320967f86b9 778 */
mbed_official 525:c320967f86b9 779 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
mbed_official 525:c320967f86b9 780 {
mbed_official 525:c320967f86b9 781 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 782 /* Enable or disable interrupt */
mbed_official 525:c320967f86b9 783 if (enable) {
mbed_official 525:c320967f86b9 784 if (irq == RxIrq) { /* RX */
mbed_official 525:c320967f86b9 785 obj->serial.periph.leuart->IEN |= LEUART_IEN_RXDATAV;
mbed_official 525:c320967f86b9 786 NVIC_ClearPendingIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 787 NVIC_EnableIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 788 } else { /* TX */
mbed_official 525:c320967f86b9 789 obj->serial.periph.leuart->IEN |= LEUART_IEN_TXC;
mbed_official 525:c320967f86b9 790 NVIC_ClearPendingIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 791 NVIC_SetPriority(serial_get_tx_irq_index(obj), 1);
mbed_official 525:c320967f86b9 792 NVIC_EnableIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 793 }
mbed_official 525:c320967f86b9 794 } else {
mbed_official 525:c320967f86b9 795 if (irq == RxIrq) { /* RX */
mbed_official 525:c320967f86b9 796 obj->serial.periph.leuart->IEN &= ~LEUART_IEN_RXDATAV;
mbed_official 525:c320967f86b9 797 NVIC_DisableIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 798 } else { /* TX */
mbed_official 525:c320967f86b9 799 obj->serial.periph.leuart->IEN &= ~LEUART_IEN_TXC;
mbed_official 525:c320967f86b9 800 NVIC_DisableIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 801 }
mbed_official 525:c320967f86b9 802 }
mbed_official 525:c320967f86b9 803 } else {
mbed_official 525:c320967f86b9 804 /* Enable or disable interrupt */
mbed_official 525:c320967f86b9 805 if (enable) {
mbed_official 525:c320967f86b9 806 if (irq == RxIrq) { /* RX */
mbed_official 525:c320967f86b9 807 obj->serial.periph.uart->IEN |= USART_IEN_RXDATAV;
mbed_official 525:c320967f86b9 808 NVIC_ClearPendingIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 809 NVIC_EnableIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 810 } else { /* TX */
mbed_official 525:c320967f86b9 811 obj->serial.periph.uart->IEN |= USART_IEN_TXC;
mbed_official 525:c320967f86b9 812 NVIC_ClearPendingIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 813 NVIC_SetPriority(serial_get_tx_irq_index(obj), 1);
mbed_official 525:c320967f86b9 814 NVIC_EnableIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 815 }
mbed_official 525:c320967f86b9 816 } else {
mbed_official 525:c320967f86b9 817 if (irq == RxIrq) { /* RX */
mbed_official 525:c320967f86b9 818 obj->serial.periph.uart->IEN &= ~USART_IEN_RXDATAV;
mbed_official 525:c320967f86b9 819 NVIC_DisableIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 820 } else { /* TX */
mbed_official 525:c320967f86b9 821 obj->serial.periph.uart->IEN &= ~USART_IEN_TXC;
mbed_official 525:c320967f86b9 822 NVIC_DisableIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 823 }
mbed_official 525:c320967f86b9 824 }
mbed_official 525:c320967f86b9 825 }
mbed_official 525:c320967f86b9 826 }
mbed_official 525:c320967f86b9 827
mbed_official 525:c320967f86b9 828 /******************************************************************************
mbed_official 525:c320967f86b9 829 * READ/WRITE *
mbed_official 525:c320967f86b9 830 ******************************************************************************/
mbed_official 525:c320967f86b9 831
mbed_official 525:c320967f86b9 832 /**
mbed_official 525:c320967f86b9 833 * Get one char from serial link
mbed_official 525:c320967f86b9 834 */
mbed_official 525:c320967f86b9 835 int serial_getc(serial_t *obj)
mbed_official 525:c320967f86b9 836 {
mbed_official 525:c320967f86b9 837 /* Emlib USART_Rx blocks until data is available, so we don't need to use
mbed_official 525:c320967f86b9 838 * serial_readable(). Use USART_RxDataGet() to read register directly. */
mbed_official 525:c320967f86b9 839 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 840 return LEUART_Rx(obj->serial.periph.leuart);
mbed_official 525:c320967f86b9 841 } else {
mbed_official 525:c320967f86b9 842 return USART_Rx(obj->serial.periph.uart);
mbed_official 525:c320967f86b9 843 }
mbed_official 525:c320967f86b9 844 }
mbed_official 525:c320967f86b9 845
mbed_official 525:c320967f86b9 846 /*
mbed_official 525:c320967f86b9 847 * Send one char over serial link
mbed_official 525:c320967f86b9 848 */
mbed_official 525:c320967f86b9 849 void serial_putc(serial_t *obj, int c)
mbed_official 525:c320967f86b9 850 {
mbed_official 525:c320967f86b9 851 /* Emlib USART_Tx blocks until buffer is writable (non-full), so we don't
mbed_official 525:c320967f86b9 852 * need to use serial_writable(). */
mbed_official 525:c320967f86b9 853 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 854 LEUART_Tx(obj->serial.periph.leuart, (uint8_t)(c));
mbed_official 525:c320967f86b9 855 } else {
mbed_official 525:c320967f86b9 856 USART_Tx(obj->serial.periph.uart, (uint8_t)(c));
mbed_official 525:c320967f86b9 857 }
mbed_official 525:c320967f86b9 858 }
mbed_official 525:c320967f86b9 859
mbed_official 525:c320967f86b9 860 /**
mbed_official 525:c320967f86b9 861 * Check if data is available in RX data vector
mbed_official 525:c320967f86b9 862 */
mbed_official 525:c320967f86b9 863 int serial_readable(serial_t *obj)
mbed_official 525:c320967f86b9 864 {
mbed_official 525:c320967f86b9 865 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 866 return obj->serial.periph.leuart->STATUS & LEUART_STATUS_RXDATAV;
mbed_official 525:c320967f86b9 867 } else {
mbed_official 525:c320967f86b9 868 return obj->serial.periph.uart->STATUS & USART_STATUS_RXDATAV;
mbed_official 548:1abac31e188e 869 }
mbed_official 525:c320967f86b9 870 }
mbed_official 525:c320967f86b9 871
mbed_official 525:c320967f86b9 872 /**
mbed_official 525:c320967f86b9 873 * Check if TX buffer is empty
mbed_official 525:c320967f86b9 874 */
mbed_official 525:c320967f86b9 875 int serial_writable(serial_t *obj)
mbed_official 525:c320967f86b9 876 {
mbed_official 525:c320967f86b9 877 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 878 return obj->serial.periph.leuart->STATUS & LEUART_STATUS_TXBL;
mbed_official 525:c320967f86b9 879 } else {
mbed_official 525:c320967f86b9 880 return obj->serial.periph.uart->STATUS & USART_STATUS_TXBL;
mbed_official 525:c320967f86b9 881 }
mbed_official 525:c320967f86b9 882 }
mbed_official 525:c320967f86b9 883
mbed_official 525:c320967f86b9 884 /**
mbed_official 525:c320967f86b9 885 * Clear UART interrupts
mbed_official 525:c320967f86b9 886 */
mbed_official 525:c320967f86b9 887 void serial_clear(serial_t *obj)
mbed_official 525:c320967f86b9 888 {
mbed_official 525:c320967f86b9 889 /* Interrupts automatically clear when condition is not met anymore */
mbed_official 525:c320967f86b9 890 }
mbed_official 525:c320967f86b9 891
mbed_official 525:c320967f86b9 892 void serial_break_set(serial_t *obj)
mbed_official 525:c320967f86b9 893 {
mbed_official 525:c320967f86b9 894 /* Send transmission break */
mbed_official 525:c320967f86b9 895 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 896 obj->serial.periph.leuart->TXDATAX = LEUART_TXDATAX_TXBREAK;
mbed_official 525:c320967f86b9 897 } else {
mbed_official 525:c320967f86b9 898 obj->serial.periph.uart->TXDATAX = USART_TXDATAX_TXBREAK;
mbed_official 525:c320967f86b9 899 }
mbed_official 525:c320967f86b9 900 }
mbed_official 525:c320967f86b9 901
mbed_official 525:c320967f86b9 902 void serial_break_clear(serial_t *obj)
mbed_official 525:c320967f86b9 903 {
mbed_official 525:c320967f86b9 904 /* No need to clear break, it is automatically cleared after one frame.
mbed_official 525:c320967f86b9 905 * From the reference manual:
mbed_official 525:c320967f86b9 906 *
mbed_official 525:c320967f86b9 907 * By setting TXBREAK, the output will be held low during the stop-bit
mbed_official 525:c320967f86b9 908 * period to generate a framing error. A receiver that supports break
mbed_official 525:c320967f86b9 909 * detection detects this state, allowing it to be used e.g. for framing
mbed_official 525:c320967f86b9 910 * of larger data packets. The line is driven high before the next frame
mbed_official 525:c320967f86b9 911 * is transmitted so the next start condition can be identified correctly
mbed_official 525:c320967f86b9 912 * by the recipient. Continuous breaks lasting longer than a USART frame
mbed_official 525:c320967f86b9 913 * are thus not supported by the USART. GPIO can be used for this.
mbed_official 525:c320967f86b9 914 */
mbed_official 525:c320967f86b9 915 }
mbed_official 525:c320967f86b9 916
mbed_official 525:c320967f86b9 917 void serial_pinout_tx(PinName tx)
mbed_official 525:c320967f86b9 918 {
mbed_official 525:c320967f86b9 919 /* 0x10 sets DOUT high. Prevents false start. */
mbed_official 525:c320967f86b9 920 pin_mode(tx, PushPull | 0x10);
mbed_official 525:c320967f86b9 921 }
mbed_official 525:c320967f86b9 922
mbed_official 525:c320967f86b9 923 /************************************************************************************
mbed_official 627:4fa1328d9c60 924 * DMA helper functions *
mbed_official 525:c320967f86b9 925 ************************************************************************************/
mbed_official 525:c320967f86b9 926 /******************************************
mbed_official 525:c320967f86b9 927 * static void serial_dmaTransferComplete(uint channel, bool primary, void* user)
mbed_official 525:c320967f86b9 928 *
mbed_official 525:c320967f86b9 929 * Callback function which gets called upon DMA transfer completion
mbed_official 525:c320967f86b9 930 * the user-defined pointer is pointing to the CPP-land thunk
mbed_official 525:c320967f86b9 931 ******************************************/
mbed_official 525:c320967f86b9 932 static void serial_dmaTransferComplete(unsigned int channel, bool primary, void *user)
mbed_official 525:c320967f86b9 933 {
mbed_official 548:1abac31e188e 934 /* Store information about which channel triggered because CPP doesn't take arguments */
mbed_official 548:1abac31e188e 935 serial_dma_irq_fired[channel] = true;
mbed_official 525:c320967f86b9 936
mbed_official 525:c320967f86b9 937 /* User pointer should be a thunk to CPP land */
mbed_official 525:c320967f86b9 938 if (user != NULL) {
mbed_official 525:c320967f86b9 939 ((DMACallback)user)();
mbed_official 525:c320967f86b9 940 }
mbed_official 525:c320967f86b9 941 }
mbed_official 525:c320967f86b9 942
mbed_official 525:c320967f86b9 943 /******************************************
mbed_official 525:c320967f86b9 944 * static void serial_setupDmaChannel(serial_t *obj, bool tx_nrx)
mbed_official 525:c320967f86b9 945 *
mbed_official 525:c320967f86b9 946 * Sets up the DMA configuration block for the assigned channel
mbed_official 525:c320967f86b9 947 * tx_nrx: true if configuring TX, false if configuring RX.
mbed_official 525:c320967f86b9 948 ******************************************/
mbed_official 548:1abac31e188e 949 static void serial_dmaSetupChannel(serial_t *obj, bool tx_nrx)
mbed_official 548:1abac31e188e 950 {
mbed_official 548:1abac31e188e 951 DMA_CfgChannel_TypeDef channelConfig;
mbed_official 525:c320967f86b9 952
mbed_official 548:1abac31e188e 953 if(tx_nrx) {
mbed_official 548:1abac31e188e 954 //setup TX channel
mbed_official 548:1abac31e188e 955 channelConfig.highPri = false;
mbed_official 548:1abac31e188e 956 channelConfig.enableInt = true;
mbed_official 548:1abac31e188e 957 channelConfig.cb = &(obj->serial.dmaOptionsTX.dmaCallback);
mbed_official 525:c320967f86b9 958
mbed_official 548:1abac31e188e 959 switch((uint32_t)(obj->serial.periph.uart)) {
mbed_official 525:c320967f86b9 960 #ifdef UART0
mbed_official 548:1abac31e188e 961 case UART_0:
mbed_official 548:1abac31e188e 962 channelConfig.select = DMAREQ_UART0_TXBL;
mbed_official 548:1abac31e188e 963 break;
mbed_official 525:c320967f86b9 964 #endif
mbed_official 525:c320967f86b9 965 #ifdef UART1
mbed_official 548:1abac31e188e 966 case UART_1:
mbed_official 548:1abac31e188e 967 channelConfig.select = DMAREQ_UART1_TXBL;
mbed_official 548:1abac31e188e 968 break;
mbed_official 525:c320967f86b9 969 #endif
mbed_official 525:c320967f86b9 970 #ifdef USART0
mbed_official 548:1abac31e188e 971 case USART_0:
mbed_official 548:1abac31e188e 972 channelConfig.select = DMAREQ_USART0_TXBL;
mbed_official 548:1abac31e188e 973 break;
mbed_official 525:c320967f86b9 974 #endif
mbed_official 525:c320967f86b9 975 #ifdef USART1
mbed_official 548:1abac31e188e 976 case USART_1:
mbed_official 548:1abac31e188e 977 channelConfig.select = DMAREQ_USART1_TXBL;
mbed_official 548:1abac31e188e 978 break;
mbed_official 525:c320967f86b9 979 #endif
mbed_official 525:c320967f86b9 980 #ifdef USART2
mbed_official 548:1abac31e188e 981 case USART_2:
mbed_official 548:1abac31e188e 982 channelConfig.select = DMAREQ_USART2_TXBL;
mbed_official 548:1abac31e188e 983 break;
mbed_official 525:c320967f86b9 984 #endif
mbed_official 525:c320967f86b9 985 #ifdef LEUART0
mbed_official 548:1abac31e188e 986 case LEUART_0:
mbed_official 548:1abac31e188e 987 channelConfig.select = DMAREQ_LEUART0_TXBL;
mbed_official 548:1abac31e188e 988 break;
mbed_official 525:c320967f86b9 989 #endif
mbed_official 525:c320967f86b9 990 #ifdef LEUART1
mbed_official 548:1abac31e188e 991 case LEUART_1:
mbed_official 548:1abac31e188e 992 channelConfig.select = DMAREQ_LEUART1_TXBL;
mbed_official 548:1abac31e188e 993 break;
mbed_official 525:c320967f86b9 994 #endif
mbed_official 548:1abac31e188e 995 }
mbed_official 525:c320967f86b9 996
mbed_official 548:1abac31e188e 997 DMA_CfgChannel(obj->serial.dmaOptionsTX.dmaChannel, &channelConfig);
mbed_official 548:1abac31e188e 998 } else {
mbed_official 548:1abac31e188e 999 //setup RX channel
mbed_official 548:1abac31e188e 1000 channelConfig.highPri = true;
mbed_official 548:1abac31e188e 1001 channelConfig.enableInt = true;
mbed_official 548:1abac31e188e 1002 channelConfig.cb = &(obj->serial.dmaOptionsRX.dmaCallback);
mbed_official 525:c320967f86b9 1003
mbed_official 548:1abac31e188e 1004 switch((uint32_t)(obj->serial.periph.uart)) {
mbed_official 525:c320967f86b9 1005 #ifdef UART0
mbed_official 548:1abac31e188e 1006 case UART_0:
mbed_official 548:1abac31e188e 1007 channelConfig.select = DMAREQ_UART0_RXDATAV;
mbed_official 548:1abac31e188e 1008 break;
mbed_official 525:c320967f86b9 1009 #endif
mbed_official 525:c320967f86b9 1010 #ifdef UART1
mbed_official 548:1abac31e188e 1011 case UART_1:
mbed_official 548:1abac31e188e 1012 channelConfig.select = DMAREQ_UART1_RXDATAV;
mbed_official 548:1abac31e188e 1013 break;
mbed_official 525:c320967f86b9 1014 #endif
mbed_official 525:c320967f86b9 1015 #ifdef USART0
mbed_official 548:1abac31e188e 1016 case USART_0:
mbed_official 548:1abac31e188e 1017 channelConfig.select = DMAREQ_USART0_RXDATAV;
mbed_official 548:1abac31e188e 1018 break;
mbed_official 525:c320967f86b9 1019 #endif
mbed_official 525:c320967f86b9 1020 #ifdef USART1
mbed_official 548:1abac31e188e 1021 case USART_1:
mbed_official 548:1abac31e188e 1022 channelConfig.select = DMAREQ_USART1_RXDATAV;
mbed_official 548:1abac31e188e 1023 break;
mbed_official 525:c320967f86b9 1024 #endif
mbed_official 525:c320967f86b9 1025 #ifdef USART2
mbed_official 548:1abac31e188e 1026 case USART_2:
mbed_official 548:1abac31e188e 1027 channelConfig.select = DMAREQ_USART2_RXDATAV;
mbed_official 548:1abac31e188e 1028 break;
mbed_official 525:c320967f86b9 1029 #endif
mbed_official 525:c320967f86b9 1030 #ifdef LEUART0
mbed_official 548:1abac31e188e 1031 case LEUART_0:
mbed_official 548:1abac31e188e 1032 channelConfig.select = DMAREQ_LEUART0_RXDATAV;
mbed_official 548:1abac31e188e 1033 break;
mbed_official 525:c320967f86b9 1034 #endif
mbed_official 525:c320967f86b9 1035 #ifdef LEUART1
mbed_official 548:1abac31e188e 1036 case LEUART_1:
mbed_official 548:1abac31e188e 1037 channelConfig.select = DMAREQ_LEUART1_RXDATAV;
mbed_official 548:1abac31e188e 1038 break;
mbed_official 525:c320967f86b9 1039 #endif
mbed_official 548:1abac31e188e 1040 }
mbed_official 525:c320967f86b9 1041
mbed_official 548:1abac31e188e 1042 DMA_CfgChannel(obj->serial.dmaOptionsRX.dmaChannel, &channelConfig);
mbed_official 548:1abac31e188e 1043 }
mbed_official 525:c320967f86b9 1044
mbed_official 525:c320967f86b9 1045
mbed_official 525:c320967f86b9 1046 }
mbed_official 525:c320967f86b9 1047
mbed_official 525:c320967f86b9 1048 /******************************************
mbed_official 525:c320967f86b9 1049 * static void serial_dmaTrySetState(DMA_OPTIONS_t *obj, DMAUsage requestedState)
mbed_official 525:c320967f86b9 1050 *
mbed_official 525:c320967f86b9 1051 * Tries to set the passed DMA state to the requested state.
mbed_official 525:c320967f86b9 1052 *
mbed_official 525:c320967f86b9 1053 * requested state possibilities:
mbed_official 627:4fa1328d9c60 1054 * * NEVER:
mbed_official 627:4fa1328d9c60 1055 * if the previous state was always, will deallocate the channel
mbed_official 627:4fa1328d9c60 1056 * * OPPORTUNISTIC:
mbed_official 627:4fa1328d9c60 1057 * If the previous state was always, will reuse that channel but free upon next completion.
mbed_official 627:4fa1328d9c60 1058 * If not, will try to acquire a channel.
mbed_official 627:4fa1328d9c60 1059 * When allocated, state changes to DMA_USAGE_TEMPORARY_ALLOCATED.
mbed_official 627:4fa1328d9c60 1060 * * ALWAYS:
mbed_official 627:4fa1328d9c60 1061 * Will try to allocate a channel and keep it.
mbed_official 627:4fa1328d9c60 1062 * If succesfully allocated, state changes to DMA_USAGE_ALLOCATED.
mbed_official 525:c320967f86b9 1063 ******************************************/
mbed_official 548:1abac31e188e 1064 static void serial_dmaTrySetState(DMA_OPTIONS_t *obj, DMAUsage requestedState, serial_t *serialPtr, bool tx_nrx)
mbed_official 548:1abac31e188e 1065 {
mbed_official 548:1abac31e188e 1066 DMAUsage currentState = obj->dmaUsageState;
mbed_official 548:1abac31e188e 1067 int tempDMAChannel = -1;
mbed_official 525:c320967f86b9 1068
mbed_official 548:1abac31e188e 1069 if ((requestedState == DMA_USAGE_ALWAYS) && (currentState != DMA_USAGE_ALLOCATED)) {
mbed_official 548:1abac31e188e 1070 /* Try to allocate channel */
mbed_official 548:1abac31e188e 1071 tempDMAChannel = dma_channel_allocate(DMA_CAP_NONE);
mbed_official 548:1abac31e188e 1072 if(tempDMAChannel >= 0) {
mbed_official 548:1abac31e188e 1073 obj->dmaChannel = tempDMAChannel;
mbed_official 548:1abac31e188e 1074 obj->dmaUsageState = DMA_USAGE_ALLOCATED;
mbed_official 548:1abac31e188e 1075 dma_init();
mbed_official 548:1abac31e188e 1076 serial_dmaSetupChannel(serialPtr, tx_nrx);
mbed_official 548:1abac31e188e 1077 }
mbed_official 548:1abac31e188e 1078 } else if (requestedState == DMA_USAGE_OPPORTUNISTIC) {
mbed_official 548:1abac31e188e 1079 if (currentState == DMA_USAGE_ALLOCATED) {
mbed_official 548:1abac31e188e 1080 /* Channels have already been allocated previously by an ALWAYS state, so after this transfer, we will release them */
mbed_official 548:1abac31e188e 1081 obj->dmaUsageState = DMA_USAGE_TEMPORARY_ALLOCATED;
mbed_official 548:1abac31e188e 1082 } else {
mbed_official 548:1abac31e188e 1083 /* Try to allocate channel */
mbed_official 548:1abac31e188e 1084 tempDMAChannel = dma_channel_allocate(DMA_CAP_NONE);
mbed_official 548:1abac31e188e 1085 if(tempDMAChannel >= 0) {
mbed_official 548:1abac31e188e 1086 obj->dmaChannel = tempDMAChannel;
mbed_official 548:1abac31e188e 1087 obj->dmaUsageState = DMA_USAGE_TEMPORARY_ALLOCATED;
mbed_official 548:1abac31e188e 1088 dma_init();
mbed_official 548:1abac31e188e 1089 serial_dmaSetupChannel(serialPtr, tx_nrx);
mbed_official 548:1abac31e188e 1090 }
mbed_official 548:1abac31e188e 1091 }
mbed_official 548:1abac31e188e 1092 } else if (requestedState == DMA_USAGE_NEVER) {
mbed_official 548:1abac31e188e 1093 /* If channel is allocated, get rid of it */
mbed_official 548:1abac31e188e 1094 dma_channel_free(obj->dmaChannel);
mbed_official 548:1abac31e188e 1095 obj->dmaChannel = -1;
mbed_official 548:1abac31e188e 1096 obj->dmaUsageState = DMA_USAGE_NEVER;
mbed_official 548:1abac31e188e 1097 }
mbed_official 525:c320967f86b9 1098 }
mbed_official 525:c320967f86b9 1099
mbed_official 548:1abac31e188e 1100 static void serial_dmaActivate(serial_t *obj, void* cb, void* buffer, int length, bool tx_nrx)
mbed_official 548:1abac31e188e 1101 {
mbed_official 548:1abac31e188e 1102 DMA_CfgDescr_TypeDef channelConfig;
mbed_official 525:c320967f86b9 1103
mbed_official 548:1abac31e188e 1104 if(tx_nrx) {
mbed_official 548:1abac31e188e 1105 // Set DMA callback
mbed_official 548:1abac31e188e 1106 obj->serial.dmaOptionsTX.dmaCallback.cbFunc = serial_dmaTransferComplete;
mbed_official 548:1abac31e188e 1107 obj->serial.dmaOptionsTX.dmaCallback.userPtr = cb;
mbed_official 525:c320967f86b9 1108
mbed_official 548:1abac31e188e 1109 // Set up configuration structure
mbed_official 548:1abac31e188e 1110 channelConfig.dstInc = dmaDataIncNone;
mbed_official 548:1abac31e188e 1111 channelConfig.srcInc = dmaDataInc1;
mbed_official 548:1abac31e188e 1112 channelConfig.size = dmaDataSize1;
mbed_official 548:1abac31e188e 1113 channelConfig.arbRate = dmaArbitrate1;
mbed_official 548:1abac31e188e 1114 channelConfig.hprot = 0;
mbed_official 525:c320967f86b9 1115
mbed_official 548:1abac31e188e 1116 DMA_CfgDescr(obj->serial.dmaOptionsTX.dmaChannel, true, &channelConfig);
mbed_official 525:c320967f86b9 1117 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1118 // Activate TX
mbed_official 525:c320967f86b9 1119 obj->serial.periph.leuart->CMD = LEUART_CMD_TXEN;
mbed_official 627:4fa1328d9c60 1120 while(obj->serial.periph.leuart->SYNCBUSY & LEUART_SYNCBUSY_CMD);
mbed_official 548:1abac31e188e 1121
mbed_official 525:c320967f86b9 1122 // Kick off TX DMA
mbed_official 525:c320967f86b9 1123 DMA_ActivateBasic(obj->serial.dmaOptionsTX.dmaChannel, true, false, (void*) &(obj->serial.periph.leuart->TXDATA), buffer, length - 1);
mbed_official 525:c320967f86b9 1124 } else {
mbed_official 627:4fa1328d9c60 1125 // Activate TX amd clear TX buffer
mbed_official 627:4fa1328d9c60 1126 obj->serial.periph.uart->CMD = USART_CMD_TXEN | USART_CMD_CLEARTX;
mbed_official 548:1abac31e188e 1127
mbed_official 525:c320967f86b9 1128 // Kick off TX DMA
mbed_official 525:c320967f86b9 1129 DMA_ActivateBasic(obj->serial.dmaOptionsTX.dmaChannel, true, false, (void*) &(obj->serial.periph.uart->TXDATA), buffer, length - 1);
mbed_official 525:c320967f86b9 1130 }
mbed_official 548:1abac31e188e 1131 } else {
mbed_official 548:1abac31e188e 1132 // Set DMA callback
mbed_official 548:1abac31e188e 1133 obj->serial.dmaOptionsRX.dmaCallback.cbFunc = serial_dmaTransferComplete;
mbed_official 548:1abac31e188e 1134 obj->serial.dmaOptionsRX.dmaCallback.userPtr = cb;
mbed_official 525:c320967f86b9 1135
mbed_official 548:1abac31e188e 1136 // Set up configuration structure
mbed_official 548:1abac31e188e 1137 channelConfig.dstInc = dmaDataInc1;
mbed_official 548:1abac31e188e 1138 channelConfig.srcInc = dmaDataIncNone;
mbed_official 548:1abac31e188e 1139 channelConfig.size = dmaDataSize1;
mbed_official 548:1abac31e188e 1140 channelConfig.arbRate = dmaArbitrate1;
mbed_official 548:1abac31e188e 1141 channelConfig.hprot = 0;
mbed_official 525:c320967f86b9 1142
mbed_official 548:1abac31e188e 1143 DMA_CfgDescr(obj->serial.dmaOptionsRX.dmaChannel, true, &channelConfig);
mbed_official 548:1abac31e188e 1144
mbed_official 525:c320967f86b9 1145 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1146 // Activate RX and clear RX buffer
mbed_official 627:4fa1328d9c60 1147 obj->serial.periph.leuart->CMD = LEUART_CMD_RXEN | LEUART_CMD_CLEARRX;
mbed_official 627:4fa1328d9c60 1148 while(obj->serial.periph.leuart->SYNCBUSY & LEUART_SYNCBUSY_CMD);
mbed_official 525:c320967f86b9 1149
mbed_official 525:c320967f86b9 1150 // Kick off RX DMA
mbed_official 525:c320967f86b9 1151 DMA_ActivateBasic(obj->serial.dmaOptionsRX.dmaChannel, true, false, buffer, (void*) &(obj->serial.periph.leuart->RXDATA), length - 1);
mbed_official 525:c320967f86b9 1152 } else {
mbed_official 627:4fa1328d9c60 1153 // Activate RX and clear RX buffer
mbed_official 627:4fa1328d9c60 1154 obj->serial.periph.uart->CMD = USART_CMD_RXEN | USART_CMD_CLEARRX;
mbed_official 525:c320967f86b9 1155
mbed_official 525:c320967f86b9 1156 // Kick off RX DMA
mbed_official 525:c320967f86b9 1157 DMA_ActivateBasic(obj->serial.dmaOptionsRX.dmaChannel, true, false, buffer, (void*) &(obj->serial.periph.uart->RXDATA), length - 1);
mbed_official 525:c320967f86b9 1158 }
mbed_official 548:1abac31e188e 1159 }
mbed_official 525:c320967f86b9 1160 }
mbed_official 525:c320967f86b9 1161
mbed_official 525:c320967f86b9 1162 /************************************************************************************
mbed_official 627:4fa1328d9c60 1163 * ASYNCHRONOUS HAL *
mbed_official 525:c320967f86b9 1164 ************************************************************************************/
mbed_official 525:c320967f86b9 1165
mbed_official 525:c320967f86b9 1166 #if DEVICE_SERIAL_ASYNCH
mbed_official 525:c320967f86b9 1167
mbed_official 525:c320967f86b9 1168 /************************************
mbed_official 627:4fa1328d9c60 1169 * HELPER FUNCTIONS *
mbed_official 525:c320967f86b9 1170 ***********************************/
mbed_official 525:c320967f86b9 1171
mbed_official 525:c320967f86b9 1172 /** Configure TX events
mbed_official 525:c320967f86b9 1173 *
mbed_official 525:c320967f86b9 1174 * @param obj The serial object
mbed_official 525:c320967f86b9 1175 * @param event The logical OR of the TX events to configure
mbed_official 525:c320967f86b9 1176 * @param enable Set to non-zero to enable events, or zero to disable them
mbed_official 525:c320967f86b9 1177 */
mbed_official 548:1abac31e188e 1178 void serial_tx_enable_event(serial_t *obj, int event, uint8_t enable)
mbed_official 548:1abac31e188e 1179 {
mbed_official 548:1abac31e188e 1180 // Shouldn't have to enable TX interrupt here, just need to keep track of the requested events.
mbed_official 548:1abac31e188e 1181 if(enable) obj->serial.events |= event;
mbed_official 548:1abac31e188e 1182 else obj->serial.events &= ~event;
mbed_official 525:c320967f86b9 1183 }
mbed_official 525:c320967f86b9 1184
mbed_official 525:c320967f86b9 1185 /**
mbed_official 525:c320967f86b9 1186 * @param obj The serial object.
mbed_official 525:c320967f86b9 1187 * @param event The logical OR of the RX events to configure
mbed_official 525:c320967f86b9 1188 * @param enable Set to non-zero to enable events, or zero to disable them
mbed_official 525:c320967f86b9 1189 */
mbed_official 548:1abac31e188e 1190 void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable)
mbed_official 548:1abac31e188e 1191 {
mbed_official 548:1abac31e188e 1192 if(enable) {
mbed_official 548:1abac31e188e 1193 obj->serial.events |= event;
mbed_official 548:1abac31e188e 1194 } else {
mbed_official 548:1abac31e188e 1195 obj->serial.events &= ~event;
mbed_official 548:1abac31e188e 1196 }
mbed_official 525:c320967f86b9 1197 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1198 if(event & SERIAL_EVENT_RX_FRAMING_ERROR) {
mbed_official 525:c320967f86b9 1199 //FERR interrupt source
mbed_official 525:c320967f86b9 1200 if(enable) obj->serial.periph.leuart->IEN |= LEUART_IEN_FERR;
mbed_official 525:c320967f86b9 1201 else obj->serial.periph.leuart->IEN &= ~LEUART_IEN_FERR;
mbed_official 525:c320967f86b9 1202 }
mbed_official 525:c320967f86b9 1203 if(event & SERIAL_EVENT_RX_PARITY_ERROR) {
mbed_official 525:c320967f86b9 1204 //PERR interrupt source
mbed_official 525:c320967f86b9 1205 if(enable) obj->serial.periph.leuart->IEN |= LEUART_IEN_PERR;
mbed_official 525:c320967f86b9 1206 else obj->serial.periph.leuart->IEN &= ~LEUART_IEN_PERR;
mbed_official 525:c320967f86b9 1207 }
mbed_official 525:c320967f86b9 1208 if(event & SERIAL_EVENT_RX_OVERFLOW) {
mbed_official 525:c320967f86b9 1209 //RXOF interrupt source
mbed_official 525:c320967f86b9 1210 if(enable) obj->serial.periph.leuart->IEN |= LEUART_IEN_RXOF;
mbed_official 525:c320967f86b9 1211 else obj->serial.periph.leuart->IEN &= ~LEUART_IEN_RXOF;
mbed_official 525:c320967f86b9 1212 }
mbed_official 525:c320967f86b9 1213 } else {
mbed_official 525:c320967f86b9 1214 if(event & SERIAL_EVENT_RX_FRAMING_ERROR) {
mbed_official 525:c320967f86b9 1215 //FERR interrupt source
mbed_official 525:c320967f86b9 1216 if(enable) obj->serial.periph.uart->IEN |= USART_IEN_FERR;
mbed_official 525:c320967f86b9 1217 else obj->serial.periph.uart->IEN &= ~USART_IEN_FERR;
mbed_official 525:c320967f86b9 1218 }
mbed_official 525:c320967f86b9 1219 if(event & SERIAL_EVENT_RX_PARITY_ERROR) {
mbed_official 525:c320967f86b9 1220 //PERR interrupt source
mbed_official 525:c320967f86b9 1221 if(enable) obj->serial.periph.uart->IEN |= USART_IEN_PERR;
mbed_official 525:c320967f86b9 1222 else obj->serial.periph.uart->IEN &= ~USART_IEN_PERR;
mbed_official 525:c320967f86b9 1223 }
mbed_official 525:c320967f86b9 1224 if(event & SERIAL_EVENT_RX_OVERFLOW) {
mbed_official 525:c320967f86b9 1225 //RXOF interrupt source
mbed_official 525:c320967f86b9 1226 if(enable) obj->serial.periph.uart->IEN |= USART_IEN_RXOF;
mbed_official 525:c320967f86b9 1227 else obj->serial.periph.uart->IEN &= ~USART_IEN_RXOF;
mbed_official 525:c320967f86b9 1228 }
mbed_official 525:c320967f86b9 1229 }
mbed_official 525:c320967f86b9 1230 }
mbed_official 525:c320967f86b9 1231
mbed_official 525:c320967f86b9 1232 /** Configure the TX buffer for an asynchronous write serial transaction
mbed_official 525:c320967f86b9 1233 *
mbed_official 525:c320967f86b9 1234 * @param obj The serial object.
mbed_official 525:c320967f86b9 1235 * @param tx The buffer for sending.
mbed_official 525:c320967f86b9 1236 * @param tx_length The number of words to transmit.
mbed_official 525:c320967f86b9 1237 */
mbed_official 548:1abac31e188e 1238 void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
mbed_official 548:1abac31e188e 1239 {
mbed_official 548:1abac31e188e 1240 // We only support byte buffers for now
mbed_official 548:1abac31e188e 1241 MBED_ASSERT(width == 8);
mbed_official 525:c320967f86b9 1242
mbed_official 548:1abac31e188e 1243 if(serial_tx_active(obj)) return;
mbed_official 525:c320967f86b9 1244
mbed_official 548:1abac31e188e 1245 obj->tx_buff.buffer = tx;
mbed_official 548:1abac31e188e 1246 obj->tx_buff.length = tx_length;
mbed_official 548:1abac31e188e 1247 obj->tx_buff.pos = 0;
mbed_official 548:1abac31e188e 1248
mbed_official 548:1abac31e188e 1249 return;
mbed_official 525:c320967f86b9 1250 }
mbed_official 525:c320967f86b9 1251
mbed_official 525:c320967f86b9 1252 /** Configure the TX buffer for an asynchronous read serial transaction
mbed_official 525:c320967f86b9 1253 *
mbed_official 525:c320967f86b9 1254 * @param obj The serial object.
mbed_official 525:c320967f86b9 1255 * @param rx The buffer for receiving.
mbed_official 525:c320967f86b9 1256 * @param rx_length The number of words to read.
mbed_official 525:c320967f86b9 1257 */
mbed_official 548:1abac31e188e 1258 void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
mbed_official 548:1abac31e188e 1259 {
mbed_official 548:1abac31e188e 1260 // We only support byte buffers for now
mbed_official 548:1abac31e188e 1261 MBED_ASSERT(width == 8);
mbed_official 525:c320967f86b9 1262
mbed_official 548:1abac31e188e 1263 if(serial_rx_active(obj)) return;
mbed_official 525:c320967f86b9 1264
mbed_official 548:1abac31e188e 1265 obj->rx_buff.buffer = rx;
mbed_official 548:1abac31e188e 1266 obj->rx_buff.length = rx_length;
mbed_official 548:1abac31e188e 1267 obj->rx_buff.pos = 0;
mbed_official 548:1abac31e188e 1268
mbed_official 548:1abac31e188e 1269 return;
mbed_official 525:c320967f86b9 1270 }
mbed_official 525:c320967f86b9 1271
mbed_official 525:c320967f86b9 1272 /************************************
mbed_official 627:4fa1328d9c60 1273 * TRANSFER FUNCTIONS *
mbed_official 525:c320967f86b9 1274 ***********************************/
mbed_official 525:c320967f86b9 1275
mbed_official 525:c320967f86b9 1276 /** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
mbed_official 525:c320967f86b9 1277 * tx_buff
mbed_official 525:c320967f86b9 1278 *
mbed_official 525:c320967f86b9 1279 * @param obj The serial object
mbed_official 525:c320967f86b9 1280 * @param cb The function to call when an event occurs
mbed_official 525:c320967f86b9 1281 * @param hint A suggestion for how to use DMA with this transfer
mbed_official 525:c320967f86b9 1282 * @return Returns number of data transfered, or 0 otherwise
mbed_official 525:c320967f86b9 1283 */
mbed_official 563:536c9fb088a0 1284 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)
mbed_official 548:1abac31e188e 1285 {
mbed_official 548:1abac31e188e 1286 // Check that a buffer has indeed been set up
mbed_official 548:1abac31e188e 1287 MBED_ASSERT(tx != (void*)0);
mbed_official 548:1abac31e188e 1288 if(tx_length == 0) return 0;
mbed_official 525:c320967f86b9 1289
mbed_official 548:1abac31e188e 1290 // Set up buffer
mbed_official 563:536c9fb088a0 1291 serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
mbed_official 525:c320967f86b9 1292
mbed_official 548:1abac31e188e 1293 // Set up events
mbed_official 548:1abac31e188e 1294 serial_tx_enable_event(obj, SERIAL_EVENT_TX_ALL, false);
mbed_official 548:1abac31e188e 1295 serial_tx_enable_event(obj, event, true);
mbed_official 525:c320967f86b9 1296
mbed_official 548:1abac31e188e 1297 // Set up sleepmode
mbed_official 627:4fa1328d9c60 1298 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 1299 if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
mbed_official 627:4fa1328d9c60 1300 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
mbed_official 627:4fa1328d9c60 1301 }else{
mbed_official 627:4fa1328d9c60 1302 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1303 }
mbed_official 627:4fa1328d9c60 1304 #else
mbed_official 548:1abac31e188e 1305 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1306 #endif
mbed_official 525:c320967f86b9 1307
mbed_official 548:1abac31e188e 1308 // Determine DMA strategy
mbed_official 548:1abac31e188e 1309 serial_dmaTrySetState(&(obj->serial.dmaOptionsTX), hint, obj, true);
mbed_official 525:c320967f86b9 1310
mbed_official 548:1abac31e188e 1311 // If DMA, kick off DMA transfer
mbed_official 548:1abac31e188e 1312 if(obj->serial.dmaOptionsTX.dmaChannel >= 0) {
mbed_official 548:1abac31e188e 1313 serial_dmaActivate(obj, (void*)handler, obj->tx_buff.buffer, obj->tx_buff.length, true);
mbed_official 548:1abac31e188e 1314 }
mbed_official 548:1abac31e188e 1315 // Else, activate interrupt. TXBL will take care of buffer filling through ISR.
mbed_official 548:1abac31e188e 1316 else {
mbed_official 548:1abac31e188e 1317 // Store callback
mbed_official 548:1abac31e188e 1318 NVIC_ClearPendingIRQ(serial_get_tx_irq_index(obj));
mbed_official 548:1abac31e188e 1319 NVIC_DisableIRQ(serial_get_tx_irq_index(obj));
mbed_official 548:1abac31e188e 1320 NVIC_SetPriority(serial_get_tx_irq_index(obj), 1);
mbed_official 548:1abac31e188e 1321 NVIC_SetVector(serial_get_tx_irq_index(obj), (uint32_t)handler);
mbed_official 548:1abac31e188e 1322 NVIC_EnableIRQ(serial_get_tx_irq_index(obj));
mbed_official 525:c320967f86b9 1323
mbed_official 525:c320967f86b9 1324 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1325 // Activate TX and clear TX buffer
mbed_official 627:4fa1328d9c60 1326 obj->serial.periph.leuart->CMD = LEUART_CMD_TXEN | LEUART_CMD_CLEARTX;
mbed_official 627:4fa1328d9c60 1327 while(obj->serial.periph.leuart->SYNCBUSY & LEUART_SYNCBUSY_CMD);
mbed_official 525:c320967f86b9 1328
mbed_official 525:c320967f86b9 1329 // Enable interrupt
mbed_official 525:c320967f86b9 1330 LEUART_IntEnable(obj->serial.periph.leuart, LEUART_IEN_TXBL);
mbed_official 525:c320967f86b9 1331 } else {
mbed_official 627:4fa1328d9c60 1332 // Activate TX and clear TX buffer
mbed_official 627:4fa1328d9c60 1333 obj->serial.periph.uart->CMD = USART_CMD_TXEN | USART_CMD_CLEARTX;
mbed_official 525:c320967f86b9 1334
mbed_official 525:c320967f86b9 1335 // Enable interrupt
mbed_official 525:c320967f86b9 1336 USART_IntEnable(obj->serial.periph.uart, USART_IEN_TXBL);
mbed_official 525:c320967f86b9 1337 }
mbed_official 548:1abac31e188e 1338 }
mbed_official 525:c320967f86b9 1339
mbed_official 548:1abac31e188e 1340 return 0;
mbed_official 525:c320967f86b9 1341 }
mbed_official 525:c320967f86b9 1342
mbed_official 525:c320967f86b9 1343 /** Begin asynchronous RX transfer (enable interrupt for data collecting)
mbed_official 525:c320967f86b9 1344 * The used buffer is specified in the serial object - rx_buff
mbed_official 525:c320967f86b9 1345 *
mbed_official 525:c320967f86b9 1346 * @param obj The serial object
mbed_official 525:c320967f86b9 1347 * @param cb The function to call when an event occurs
mbed_official 525:c320967f86b9 1348 * @param hint A suggestion for how to use DMA with this transfer
mbed_official 525:c320967f86b9 1349 */
mbed_official 548:1abac31e188e 1350 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)
mbed_official 548:1abac31e188e 1351 {
mbed_official 548:1abac31e188e 1352 // Check that a buffer has indeed been set up
mbed_official 548:1abac31e188e 1353 MBED_ASSERT(rx != (void*)0);
mbed_official 548:1abac31e188e 1354 if(rx_length == 0) return;
mbed_official 525:c320967f86b9 1355
mbed_official 548:1abac31e188e 1356 // Set up buffer
mbed_official 627:4fa1328d9c60 1357 serial_rx_buffer_set(obj,(void*) rx, rx_length, rx_width);
mbed_official 627:4fa1328d9c60 1358
mbed_official 627:4fa1328d9c60 1359 //disable character match if no character is specified
mbed_official 627:4fa1328d9c60 1360 if(char_match == SERIAL_RESERVED_CHAR_MATCH){
mbed_official 627:4fa1328d9c60 1361 event &= ~SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 627:4fa1328d9c60 1362 }
mbed_official 627:4fa1328d9c60 1363
mbed_official 627:4fa1328d9c60 1364 /*clear all set interrupts*/
mbed_official 627:4fa1328d9c60 1365 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1366 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_PERR | LEUART_IFC_FERR | LEUART_IFC_RXOF);
mbed_official 627:4fa1328d9c60 1367 }else{
mbed_official 627:4fa1328d9c60 1368 USART_IntClear(obj->serial.periph.uart, USART_IFC_PERR | USART_IFC_FERR | USART_IFC_RXOF);
mbed_official 627:4fa1328d9c60 1369 }
mbed_official 525:c320967f86b9 1370
mbed_official 548:1abac31e188e 1371 // Set up events
mbed_official 548:1abac31e188e 1372 serial_rx_enable_event(obj, SERIAL_EVENT_RX_ALL, false);
mbed_official 548:1abac31e188e 1373 serial_rx_enable_event(obj, event, true);
mbed_official 627:4fa1328d9c60 1374 obj->char_match = char_match;
mbed_official 548:1abac31e188e 1375
mbed_official 548:1abac31e188e 1376 // Set up sleepmode
mbed_official 627:4fa1328d9c60 1377 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 1378 if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
mbed_official 627:4fa1328d9c60 1379 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
mbed_official 627:4fa1328d9c60 1380 }else{
mbed_official 627:4fa1328d9c60 1381 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1382 }
mbed_official 627:4fa1328d9c60 1383 #else
mbed_official 548:1abac31e188e 1384 blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1385 #endif
mbed_official 525:c320967f86b9 1386
mbed_official 548:1abac31e188e 1387 // Determine DMA strategy
mbed_official 548:1abac31e188e 1388 // If character match is enabled, we can't use DMA, sadly. We could when using LEUART though, but that support is not in here yet.
mbed_official 627:4fa1328d9c60 1389 // TODO: add DMA support for character matching with leuart
mbed_official 548:1abac31e188e 1390 if(!(event & SERIAL_EVENT_RX_CHARACTER_MATCH)) {
mbed_official 548:1abac31e188e 1391 serial_dmaTrySetState(&(obj->serial.dmaOptionsRX), hint, obj, false);
mbed_official 627:4fa1328d9c60 1392 }else{
mbed_official 627:4fa1328d9c60 1393 serial_dmaTrySetState(&(obj->serial.dmaOptionsRX), DMA_USAGE_NEVER, obj, false);
mbed_official 548:1abac31e188e 1394 }
mbed_official 525:c320967f86b9 1395
mbed_official 548:1abac31e188e 1396 // If DMA, kick off DMA
mbed_official 548:1abac31e188e 1397 if(obj->serial.dmaOptionsRX.dmaChannel >= 0) {
mbed_official 548:1abac31e188e 1398 serial_dmaActivate(obj, (void*)handler, obj->rx_buff.buffer, obj->rx_buff.length, false);
mbed_official 548:1abac31e188e 1399 }
mbed_official 548:1abac31e188e 1400 // Else, activate interrupt. RXDATAV is responsible for incoming data notification.
mbed_official 548:1abac31e188e 1401 else {
mbed_official 548:1abac31e188e 1402 // Store callback
mbed_official 548:1abac31e188e 1403 NVIC_ClearPendingIRQ(serial_get_rx_irq_index(obj));
mbed_official 548:1abac31e188e 1404 NVIC_SetVector(serial_get_rx_irq_index(obj), (uint32_t)handler);
mbed_official 548:1abac31e188e 1405 NVIC_EnableIRQ(serial_get_rx_irq_index(obj));
mbed_official 525:c320967f86b9 1406
mbed_official 525:c320967f86b9 1407 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1408 // Activate RX and clear RX buffer
mbed_official 627:4fa1328d9c60 1409 obj->serial.periph.leuart->CMD = LEUART_CMD_RXEN | LEUART_CMD_CLEARRX;
mbed_official 627:4fa1328d9c60 1410 while(obj->serial.periph.leuart->SYNCBUSY & LEUART_SYNCBUSY_CMD);
mbed_official 525:c320967f86b9 1411
mbed_official 525:c320967f86b9 1412 // Enable interrupt
mbed_official 525:c320967f86b9 1413 LEUART_IntEnable(obj->serial.periph.leuart, LEUART_IEN_RXDATAV);
mbed_official 525:c320967f86b9 1414 } else {
mbed_official 627:4fa1328d9c60 1415 // Activate RX and clear RX buffer
mbed_official 627:4fa1328d9c60 1416 obj->serial.periph.uart->CMD = USART_CMD_RXEN | USART_CMD_CLEARRX;
mbed_official 525:c320967f86b9 1417
mbed_official 525:c320967f86b9 1418 // Clear RXFULL
mbed_official 525:c320967f86b9 1419 USART_IntClear(obj->serial.periph.uart, USART_IFC_RXFULL);
mbed_official 525:c320967f86b9 1420
mbed_official 525:c320967f86b9 1421 // Enable interrupt
mbed_official 525:c320967f86b9 1422 USART_IntEnable(obj->serial.periph.uart, USART_IEN_RXDATAV);
mbed_official 525:c320967f86b9 1423 }
mbed_official 548:1abac31e188e 1424 }
mbed_official 525:c320967f86b9 1425
mbed_official 548:1abac31e188e 1426 return;
mbed_official 525:c320967f86b9 1427 }
mbed_official 525:c320967f86b9 1428
mbed_official 525:c320967f86b9 1429 /** Attempts to determine if the serial peripheral is already in use for TX
mbed_official 525:c320967f86b9 1430 *
mbed_official 525:c320967f86b9 1431 * @param obj The serial object
mbed_official 525:c320967f86b9 1432 * @return Non-zero if the TX transaction is ongoing, 0 otherwise
mbed_official 525:c320967f86b9 1433 */
mbed_official 548:1abac31e188e 1434 uint8_t serial_tx_active(serial_t *obj)
mbed_official 548:1abac31e188e 1435 {
mbed_official 548:1abac31e188e 1436 switch(obj->serial.dmaOptionsTX.dmaUsageState) {
mbed_official 548:1abac31e188e 1437 case DMA_USAGE_TEMPORARY_ALLOCATED:
mbed_official 548:1abac31e188e 1438 /* Temporary allocation always means its active, as this state gets cleared afterwards */
mbed_official 548:1abac31e188e 1439 return 1;
mbed_official 548:1abac31e188e 1440 case DMA_USAGE_ALLOCATED:
mbed_official 548:1abac31e188e 1441 /* Check whether the allocated DMA channel is active by checking the DMA transfer */
mbed_official 548:1abac31e188e 1442 return(DMA_ChannelEnabled(obj->serial.dmaOptionsTX.dmaChannel));
mbed_official 548:1abac31e188e 1443 default:
mbed_official 548:1abac31e188e 1444 /* Check whether interrupt for serial TX is enabled */
mbed_official 525:c320967f86b9 1445 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1446 return (obj->serial.periph.leuart->IEN & (LEUART_IEN_TXBL)) ? true : false;
mbed_official 525:c320967f86b9 1447 } else {
mbed_official 525:c320967f86b9 1448 return (obj->serial.periph.uart->IEN & (USART_IEN_TXBL)) ? true : false;
mbed_official 525:c320967f86b9 1449 }
mbed_official 548:1abac31e188e 1450 }
mbed_official 525:c320967f86b9 1451 }
mbed_official 525:c320967f86b9 1452
mbed_official 525:c320967f86b9 1453 /** Attempts to determine if the serial peripheral is already in use for RX
mbed_official 525:c320967f86b9 1454 *
mbed_official 525:c320967f86b9 1455 * @param obj The serial object
mbed_official 525:c320967f86b9 1456 * @return Non-zero if the RX transaction is ongoing, 0 otherwise
mbed_official 525:c320967f86b9 1457 */
mbed_official 548:1abac31e188e 1458 uint8_t serial_rx_active(serial_t *obj)
mbed_official 548:1abac31e188e 1459 {
mbed_official 548:1abac31e188e 1460 switch(obj->serial.dmaOptionsRX.dmaUsageState) {
mbed_official 548:1abac31e188e 1461 case DMA_USAGE_TEMPORARY_ALLOCATED:
mbed_official 548:1abac31e188e 1462 /* Temporary allocation always means its active, as this state gets cleared afterwards */
mbed_official 548:1abac31e188e 1463 return 1;
mbed_official 548:1abac31e188e 1464 case DMA_USAGE_ALLOCATED:
mbed_official 548:1abac31e188e 1465 /* Check whether the allocated DMA channel is active by checking the DMA transfer */
mbed_official 548:1abac31e188e 1466 return(DMA_ChannelEnabled(obj->serial.dmaOptionsRX.dmaChannel));
mbed_official 548:1abac31e188e 1467 default:
mbed_official 548:1abac31e188e 1468 /* Check whether interrupt for serial TX is enabled */
mbed_official 525:c320967f86b9 1469 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1470 return (obj->serial.periph.leuart->IEN & (LEUART_IEN_RXDATAV)) ? true : false;
mbed_official 525:c320967f86b9 1471 } else {
mbed_official 525:c320967f86b9 1472 return (obj->serial.periph.uart->IEN & (USART_IEN_RXDATAV)) ? true : false;
mbed_official 525:c320967f86b9 1473 }
mbed_official 548:1abac31e188e 1474 }
mbed_official 525:c320967f86b9 1475 }
mbed_official 525:c320967f86b9 1476
mbed_official 525:c320967f86b9 1477 /** The asynchronous TX handler. Writes to the TX FIFO and checks for events.
mbed_official 525:c320967f86b9 1478 * If any TX event has occured, the TX abort function is called.
mbed_official 525:c320967f86b9 1479 *
mbed_official 525:c320967f86b9 1480 * @param obj The serial object
mbed_official 525:c320967f86b9 1481 * @return Returns event flags if a TX transfer termination condition was met or 0 otherwise
mbed_official 525:c320967f86b9 1482 */
mbed_official 548:1abac31e188e 1483 int serial_tx_irq_handler_asynch(serial_t *obj)
mbed_official 548:1abac31e188e 1484 {
mbed_official 548:1abac31e188e 1485 /* This interrupt handler is called from USART irq */
mbed_official 548:1abac31e188e 1486 uint8_t *buf = obj->tx_buff.buffer;
mbed_official 525:c320967f86b9 1487
mbed_official 627:4fa1328d9c60 1488 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1489 if(obj->serial.periph.leuart->IEN & LEUART_IEN_TXBL){
mbed_official 627:4fa1328d9c60 1490 /* There is still data to send */
mbed_official 525:c320967f86b9 1491 while((LEUART_StatusGet(obj->serial.periph.leuart) & LEUART_STATUS_TXBL) && (obj->tx_buff.pos <= (obj->tx_buff.length - 1))) {
mbed_official 627:4fa1328d9c60 1492 while (obj->serial.periph.leuart->SYNCBUSY);
mbed_official 525:c320967f86b9 1493 LEUART_Tx(obj->serial.periph.leuart, buf[obj->tx_buff.pos]);
mbed_official 525:c320967f86b9 1494 obj->tx_buff.pos++;
mbed_official 525:c320967f86b9 1495 }
mbed_official 627:4fa1328d9c60 1496 if(obj->tx_buff.pos >= obj->tx_buff.length){
mbed_official 627:4fa1328d9c60 1497 /* Last byte has been put in TX, set up TXC interrupt */
mbed_official 627:4fa1328d9c60 1498 LEUART_IntDisable(obj->serial.periph.leuart, LEUART_IEN_TXBL);
mbed_official 627:4fa1328d9c60 1499 LEUART_IntEnable(obj->serial.periph.leuart, LEUART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1500 }
mbed_official 627:4fa1328d9c60 1501 }else if (obj->serial.periph.leuart->IF & LEUART_IF_TXC){
mbed_official 627:4fa1328d9c60 1502 /* Last byte has been successfully transmitted. Stop the procedure */
mbed_official 627:4fa1328d9c60 1503 serial_tx_abort_asynch(obj);
mbed_official 627:4fa1328d9c60 1504 return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
mbed_official 627:4fa1328d9c60 1505 }
mbed_official 627:4fa1328d9c60 1506 } else {
mbed_official 627:4fa1328d9c60 1507 if(obj->serial.periph.uart->IEN & USART_IEN_TXBL){
mbed_official 627:4fa1328d9c60 1508 /* There is still data to send */
mbed_official 525:c320967f86b9 1509 while((USART_StatusGet(obj->serial.periph.uart) & USART_STATUS_TXBL) && (obj->tx_buff.pos <= (obj->tx_buff.length - 1))) {
mbed_official 525:c320967f86b9 1510 USART_Tx(obj->serial.periph.uart, buf[obj->tx_buff.pos]);
mbed_official 525:c320967f86b9 1511 obj->tx_buff.pos++;
mbed_official 525:c320967f86b9 1512 }
mbed_official 627:4fa1328d9c60 1513 if(obj->tx_buff.pos >= obj->tx_buff.length){
mbed_official 627:4fa1328d9c60 1514 /* Last byte has been put in TX, set up TXC interrupt */
mbed_official 627:4fa1328d9c60 1515 USART_IntDisable(obj->serial.periph.uart, USART_IEN_TXBL);
mbed_official 627:4fa1328d9c60 1516 USART_IntEnable(obj->serial.periph.uart, USART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1517 }
mbed_official 627:4fa1328d9c60 1518 } else if (obj->serial.periph.uart->IF & USART_IF_TXC) {
mbed_official 627:4fa1328d9c60 1519 /* Last byte has been successfully transmitted. Stop the procedure */
mbed_official 627:4fa1328d9c60 1520 serial_tx_abort_asynch(obj);
mbed_official 627:4fa1328d9c60 1521 return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
mbed_official 525:c320967f86b9 1522 }
mbed_official 548:1abac31e188e 1523 }
mbed_official 548:1abac31e188e 1524 return 0;
mbed_official 525:c320967f86b9 1525 }
mbed_official 525:c320967f86b9 1526
mbed_official 525:c320967f86b9 1527 /** The asynchronous RX handler. Reads from the RX FIFOF and checks for events.
mbed_official 525:c320967f86b9 1528 * If any RX event has occured, the RX abort function is called.
mbed_official 525:c320967f86b9 1529 *
mbed_official 525:c320967f86b9 1530 * @param obj The serial object
mbed_official 525:c320967f86b9 1531 * @return Returns event flags if a RX transfer termination condition was met or 0 otherwise
mbed_official 525:c320967f86b9 1532 */
mbed_official 548:1abac31e188e 1533 int serial_rx_irq_handler_asynch(serial_t *obj)
mbed_official 548:1abac31e188e 1534 {
mbed_official 548:1abac31e188e 1535 int event = 0;
mbed_official 525:c320967f86b9 1536
mbed_official 548:1abac31e188e 1537 /* This interrupt handler is called from USART irq */
mbed_official 548:1abac31e188e 1538 uint8_t *buf = (uint8_t*)obj->rx_buff.buffer;
mbed_official 525:c320967f86b9 1539
mbed_official 525:c320967f86b9 1540 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1541 /* Determine the source of the interrupt */
mbed_official 525:c320967f86b9 1542 if(LEUART_IntGetEnabled(obj->serial.periph.leuart) & LEUART_IF_PERR) {
mbed_official 525:c320967f86b9 1543 /* Parity error has occurred, and we are notifying. */
mbed_official 525:c320967f86b9 1544 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_PERR);
mbed_official 525:c320967f86b9 1545 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1546 return SERIAL_EVENT_RX_PARITY_ERROR;
mbed_official 525:c320967f86b9 1547 }
mbed_official 525:c320967f86b9 1548
mbed_official 525:c320967f86b9 1549 if(LEUART_IntGetEnabled(obj->serial.periph.leuart) & LEUART_IF_FERR) {
mbed_official 525:c320967f86b9 1550 /* Framing error has occurred, and we are notifying */
mbed_official 525:c320967f86b9 1551 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_FERR);
mbed_official 525:c320967f86b9 1552 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1553 return SERIAL_EVENT_RX_FRAMING_ERROR;
mbed_official 525:c320967f86b9 1554 }
mbed_official 525:c320967f86b9 1555
mbed_official 525:c320967f86b9 1556 if(LEUART_IntGetEnabled(obj->serial.periph.leuart) & LEUART_IF_RXOF) {
mbed_official 525:c320967f86b9 1557 /* RX buffer overflow has occurred, and we are notifying */
mbed_official 525:c320967f86b9 1558 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_RXOF);
mbed_official 525:c320967f86b9 1559 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1560 return SERIAL_EVENT_RX_OVERFLOW;
mbed_official 525:c320967f86b9 1561 }
mbed_official 548:1abac31e188e 1562
mbed_official 525:c320967f86b9 1563 if((LEUART_IntGetEnabled(obj->serial.periph.leuart) & LEUART_IF_RXDATAV) || (LEUART_StatusGet(obj->serial.periph.leuart) & LEUART_STATUS_RXDATAV)) {
mbed_official 525:c320967f86b9 1564 /* Valid data in buffer. Determine course of action: continue receiving or interrupt */
mbed_official 525:c320967f86b9 1565 if(obj->rx_buff.pos >= (obj->rx_buff.length - 1)) {
mbed_official 525:c320967f86b9 1566 /* Last char, transfer complete. Switch off interrupt and return event. */
mbed_official 525:c320967f86b9 1567 buf[obj->rx_buff.pos] = LEUART_RxDataGet(obj->serial.periph.leuart);
mbed_official 525:c320967f86b9 1568
mbed_official 525:c320967f86b9 1569 event |= SERIAL_EVENT_RX_COMPLETE;
mbed_official 525:c320967f86b9 1570
mbed_official 525:c320967f86b9 1571 if((buf[obj->rx_buff.pos] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 525:c320967f86b9 1572
mbed_official 525:c320967f86b9 1573 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1574 return event & obj->serial.events;
mbed_official 525:c320967f86b9 1575 } else {
mbed_official 525:c320967f86b9 1576 /* There's still space in the receive buffer */
mbed_official 525:c320967f86b9 1577 while((LEUART_StatusGet(obj->serial.periph.leuart) & LEUART_STATUS_RXDATAV) && (obj->rx_buff.pos <= (obj->rx_buff.length - 1))) {
mbed_official 627:4fa1328d9c60 1578 bool aborting = false;
mbed_official 525:c320967f86b9 1579 buf[obj->rx_buff.pos] = LEUART_RxDataGet(obj->serial.periph.leuart);
mbed_official 525:c320967f86b9 1580 obj->rx_buff.pos++;
mbed_official 525:c320967f86b9 1581
mbed_official 525:c320967f86b9 1582 /* Check for character match event */
mbed_official 525:c320967f86b9 1583 if((buf[obj->rx_buff.pos - 1] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) {
mbed_official 627:4fa1328d9c60 1584 aborting = true;
mbed_official 525:c320967f86b9 1585 event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 525:c320967f86b9 1586 }
mbed_official 525:c320967f86b9 1587
mbed_official 525:c320967f86b9 1588 /* Check for final char event */
mbed_official 525:c320967f86b9 1589 if(obj->rx_buff.pos >= (obj->rx_buff.length)) {
mbed_official 627:4fa1328d9c60 1590 aborting = true;
mbed_official 525:c320967f86b9 1591 event |= SERIAL_EVENT_RX_COMPLETE & obj->serial.events;
mbed_official 525:c320967f86b9 1592 }
mbed_official 525:c320967f86b9 1593
mbed_official 627:4fa1328d9c60 1594 if(aborting) {
mbed_official 525:c320967f86b9 1595 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1596 return event & obj->serial.events;
mbed_official 525:c320967f86b9 1597 }
mbed_official 525:c320967f86b9 1598 }
mbed_official 525:c320967f86b9 1599 }
mbed_official 525:c320967f86b9 1600 }
mbed_official 525:c320967f86b9 1601 } else {
mbed_official 525:c320967f86b9 1602 /* Determine the source of the interrupt */
mbed_official 525:c320967f86b9 1603 if(USART_IntGetEnabled(obj->serial.periph.uart) & USART_IF_PERR) {
mbed_official 525:c320967f86b9 1604 /* Parity error has occurred, and we are notifying. */
mbed_official 525:c320967f86b9 1605 USART_IntClear(obj->serial.periph.uart, USART_IFC_PERR);
mbed_official 525:c320967f86b9 1606 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1607 return SERIAL_EVENT_RX_PARITY_ERROR;
mbed_official 525:c320967f86b9 1608 }
mbed_official 525:c320967f86b9 1609
mbed_official 525:c320967f86b9 1610 if(USART_IntGetEnabled(obj->serial.periph.uart) & USART_IF_FERR) {
mbed_official 525:c320967f86b9 1611 /* Framing error has occurred, and we are notifying */
mbed_official 525:c320967f86b9 1612 USART_IntClear(obj->serial.periph.uart, USART_IFC_FERR);
mbed_official 525:c320967f86b9 1613 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1614 return SERIAL_EVENT_RX_FRAMING_ERROR;
mbed_official 525:c320967f86b9 1615 }
mbed_official 525:c320967f86b9 1616
mbed_official 525:c320967f86b9 1617 if(USART_IntGetEnabled(obj->serial.periph.uart) & USART_IF_RXOF) {
mbed_official 525:c320967f86b9 1618 /* RX buffer overflow has occurred, and we are notifying */
mbed_official 525:c320967f86b9 1619 USART_IntClear(obj->serial.periph.uart, USART_IFC_RXOF);
mbed_official 525:c320967f86b9 1620 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1621 return SERIAL_EVENT_RX_OVERFLOW;
mbed_official 525:c320967f86b9 1622 }
mbed_official 525:c320967f86b9 1623
mbed_official 525:c320967f86b9 1624 if((USART_IntGetEnabled(obj->serial.periph.uart) & USART_IF_RXDATAV) || (USART_StatusGet(obj->serial.periph.uart) & USART_STATUS_RXFULL)) {
mbed_official 525:c320967f86b9 1625 /* Valid data in buffer. Determine course of action: continue receiving or interrupt */
mbed_official 525:c320967f86b9 1626 if(obj->rx_buff.pos >= (obj->rx_buff.length - 1)) {
mbed_official 525:c320967f86b9 1627 /* Last char, transfer complete. Switch off interrupt and return event. */
mbed_official 525:c320967f86b9 1628 buf[obj->rx_buff.pos] = USART_RxDataGet(obj->serial.periph.uart);
mbed_official 525:c320967f86b9 1629
mbed_official 525:c320967f86b9 1630 event |= SERIAL_EVENT_RX_COMPLETE;
mbed_official 525:c320967f86b9 1631
mbed_official 525:c320967f86b9 1632 if((buf[obj->rx_buff.pos] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 525:c320967f86b9 1633
mbed_official 525:c320967f86b9 1634 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1635 return event & obj->serial.events;
mbed_official 525:c320967f86b9 1636 } else {
mbed_official 525:c320967f86b9 1637 /* There's still space in the receive buffer */
mbed_official 525:c320967f86b9 1638 while(((USART_StatusGet(obj->serial.periph.uart) & USART_STATUS_RXDATAV) || (USART_StatusGet(obj->serial.periph.uart) & USART_IF_RXFULL)) && (obj->rx_buff.pos <= (obj->rx_buff.length - 1))) {
mbed_official 627:4fa1328d9c60 1639 bool aborting = false;
mbed_official 525:c320967f86b9 1640 buf[obj->rx_buff.pos] = USART_RxDataGet(obj->serial.periph.uart);
mbed_official 525:c320967f86b9 1641 obj->rx_buff.pos++;
mbed_official 525:c320967f86b9 1642
mbed_official 525:c320967f86b9 1643 /* Check for character match event */
mbed_official 525:c320967f86b9 1644 if((buf[obj->rx_buff.pos - 1] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) {
mbed_official 627:4fa1328d9c60 1645 aborting = true;
mbed_official 525:c320967f86b9 1646 event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 525:c320967f86b9 1647 }
mbed_official 525:c320967f86b9 1648
mbed_official 525:c320967f86b9 1649 /* Check for final char event */
mbed_official 525:c320967f86b9 1650 if(obj->rx_buff.pos >= (obj->rx_buff.length)) {
mbed_official 627:4fa1328d9c60 1651 aborting = true;
mbed_official 525:c320967f86b9 1652 event |= SERIAL_EVENT_RX_COMPLETE & obj->serial.events;
mbed_official 525:c320967f86b9 1653 }
mbed_official 525:c320967f86b9 1654
mbed_official 627:4fa1328d9c60 1655 if(aborting) {
mbed_official 525:c320967f86b9 1656 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1657 return event & obj->serial.events;
mbed_official 525:c320967f86b9 1658 }
mbed_official 525:c320967f86b9 1659 }
mbed_official 525:c320967f86b9 1660 }
mbed_official 525:c320967f86b9 1661 }
mbed_official 525:c320967f86b9 1662 }
mbed_official 548:1abac31e188e 1663
mbed_official 548:1abac31e188e 1664 /* All events should have generated a return, if no return has happened, no event has been caught */
mbed_official 548:1abac31e188e 1665 return 0;
mbed_official 525:c320967f86b9 1666 }
mbed_official 525:c320967f86b9 1667
mbed_official 525:c320967f86b9 1668 /** Unified IRQ handler. Determines the appropriate handler to execute and returns the flags.
mbed_official 525:c320967f86b9 1669 *
mbed_official 525:c320967f86b9 1670 * WARNING: this code should be stateless, as re-entrancy is very possible in interrupt-based mode.
mbed_official 525:c320967f86b9 1671 */
mbed_official 548:1abac31e188e 1672 int serial_irq_handler_asynch(serial_t *obj)
mbed_official 548:1abac31e188e 1673 {
mbed_official 548:1abac31e188e 1674 /* First, check if we're running in DMA mode */
mbed_official 548:1abac31e188e 1675 if(serial_dma_irq_fired[obj->serial.dmaOptionsRX.dmaChannel]) {
mbed_official 548:1abac31e188e 1676 /* Clean up */
mbed_official 548:1abac31e188e 1677 serial_dma_irq_fired[obj->serial.dmaOptionsRX.dmaChannel] = false;
mbed_official 548:1abac31e188e 1678 serial_rx_abort_asynch(obj);
mbed_official 525:c320967f86b9 1679
mbed_official 548:1abac31e188e 1680 /* Notify CPP land of RX completion */
mbed_official 548:1abac31e188e 1681 return SERIAL_EVENT_RX_COMPLETE & obj->serial.events;
mbed_official 548:1abac31e188e 1682 } else if (serial_dma_irq_fired[obj->serial.dmaOptionsTX.dmaChannel]) {
mbed_official 627:4fa1328d9c60 1683 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1684 if(obj->serial.periph.leuart->IEN & LEUART_IEN_TXC){
mbed_official 627:4fa1328d9c60 1685 LEUART_IntDisable(obj->serial.periph.leuart,LEUART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1686 /* Clean up */
mbed_official 627:4fa1328d9c60 1687 serial_dma_irq_fired[obj->serial.dmaOptionsTX.dmaChannel] = false;
mbed_official 627:4fa1328d9c60 1688 serial_tx_abort_asynch(obj);
mbed_official 627:4fa1328d9c60 1689 /* Notify CPP land of completion */
mbed_official 627:4fa1328d9c60 1690 return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
mbed_official 627:4fa1328d9c60 1691 }else{
mbed_official 627:4fa1328d9c60 1692 LEUART_IntEnable(obj->serial.periph.leuart,LEUART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1693 }
mbed_official 627:4fa1328d9c60 1694 }else{
mbed_official 627:4fa1328d9c60 1695 if(obj->serial.periph.uart->IEN & USART_IEN_TXC){
mbed_official 627:4fa1328d9c60 1696 USART_IntDisable(obj->serial.periph.leuart,USART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1697 /* Clean up */
mbed_official 627:4fa1328d9c60 1698 serial_dma_irq_fired[obj->serial.dmaOptionsTX.dmaChannel] = false;
mbed_official 627:4fa1328d9c60 1699 serial_tx_abort_asynch(obj);
mbed_official 627:4fa1328d9c60 1700 /* Notify CPP land of completion */
mbed_official 627:4fa1328d9c60 1701 return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
mbed_official 627:4fa1328d9c60 1702 }else{
mbed_official 627:4fa1328d9c60 1703 USART_IntEnable(obj->serial.periph.leuart,USART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1704 }
mbed_official 627:4fa1328d9c60 1705 }
mbed_official 548:1abac31e188e 1706 } else {
mbed_official 548:1abac31e188e 1707 /* Check the NVIC to see which interrupt we're running from
mbed_official 548:1abac31e188e 1708 * Also make sure to prioritize RX */
mbed_official 525:c320967f86b9 1709 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 525:c320967f86b9 1710 //Different method of checking tx vs rx for LEUART
mbed_official 627:4fa1328d9c60 1711 if(LEUART_IntGetEnabled(obj->serial.periph.leuart) & (LEUART_IF_RXDATAV | LEUART_IF_FERR | LEUART_IF_PERR | LEUART_IF_RXOF)) {
mbed_official 525:c320967f86b9 1712 return serial_rx_irq_handler_asynch(obj);
mbed_official 627:4fa1328d9c60 1713 } else if(LEUART_StatusGet(obj->serial.periph.leuart) & (LEUART_STATUS_TXBL | LEUART_STATUS_TXC)) {
mbed_official 525:c320967f86b9 1714 return serial_tx_irq_handler_asynch(obj);
mbed_official 525:c320967f86b9 1715 }
mbed_official 525:c320967f86b9 1716 } else {
mbed_official 525:c320967f86b9 1717 if(USART_IntGetEnabled(obj->serial.periph.uart) & (USART_IF_RXDATAV | USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR)) {
mbed_official 525:c320967f86b9 1718 return serial_rx_irq_handler_asynch(obj);
mbed_official 627:4fa1328d9c60 1719 } else if(USART_StatusGet(obj->serial.periph.uart) & (USART_STATUS_TXBL | USART_STATUS_TXC)){
mbed_official 525:c320967f86b9 1720 return serial_tx_irq_handler_asynch(obj);
mbed_official 525:c320967f86b9 1721 }
mbed_official 525:c320967f86b9 1722 }
mbed_official 548:1abac31e188e 1723 }
mbed_official 525:c320967f86b9 1724
mbed_official 548:1abac31e188e 1725 // All should be done now
mbed_official 548:1abac31e188e 1726 return 0;
mbed_official 525:c320967f86b9 1727 }
mbed_official 525:c320967f86b9 1728
mbed_official 525:c320967f86b9 1729 /** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
mbed_official 525:c320967f86b9 1730 * flush TX hardware buffer if TX FIFO is used
mbed_official 525:c320967f86b9 1731 *
mbed_official 525:c320967f86b9 1732 * @param obj The serial object
mbed_official 525:c320967f86b9 1733 */
mbed_official 548:1abac31e188e 1734 void serial_tx_abort_asynch(serial_t *obj)
mbed_official 548:1abac31e188e 1735 {
mbed_official 548:1abac31e188e 1736 /* Stop transmitter */
mbed_official 548:1abac31e188e 1737 //obj->serial.periph.uart->CMD |= USART_CMD_TXDIS;
mbed_official 525:c320967f86b9 1738
mbed_official 548:1abac31e188e 1739 /* Clean up */
mbed_official 548:1abac31e188e 1740 switch(obj->serial.dmaOptionsTX.dmaUsageState) {
mbed_official 548:1abac31e188e 1741 case DMA_USAGE_ALLOCATED:
mbed_official 548:1abac31e188e 1742 /* stop DMA transfer */
mbed_official 548:1abac31e188e 1743 DMA_ChannelEnable(obj->serial.dmaOptionsTX.dmaChannel, false);
mbed_official 548:1abac31e188e 1744 break;
mbed_official 548:1abac31e188e 1745 case DMA_USAGE_TEMPORARY_ALLOCATED:
mbed_official 548:1abac31e188e 1746 /* stop DMA transfer and release channel */
mbed_official 548:1abac31e188e 1747 DMA_ChannelEnable(obj->serial.dmaOptionsTX.dmaChannel, false);
mbed_official 548:1abac31e188e 1748 dma_channel_free(obj->serial.dmaOptionsTX.dmaChannel);
mbed_official 548:1abac31e188e 1749 obj->serial.dmaOptionsTX.dmaChannel = -1;
mbed_official 548:1abac31e188e 1750 obj->serial.dmaOptionsTX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
mbed_official 548:1abac31e188e 1751 break;
mbed_official 548:1abac31e188e 1752 default:
mbed_official 548:1abac31e188e 1753 /* stop interrupting */
mbed_official 548:1abac31e188e 1754 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1755 LEUART_IntDisable(obj->serial.periph.leuart, LEUART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1756 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_TXC);
mbed_official 548:1abac31e188e 1757 } else {
mbed_official 627:4fa1328d9c60 1758 USART_IntDisable(obj->serial.periph.uart, USART_IEN_TXC);
mbed_official 627:4fa1328d9c60 1759 USART_IntClear(obj->serial.periph.uart, USART_IFC_TXC);
mbed_official 548:1abac31e188e 1760 }
mbed_official 548:1abac31e188e 1761 break;
mbed_official 548:1abac31e188e 1762 }
mbed_official 525:c320967f86b9 1763
mbed_official 627:4fa1328d9c60 1764 /* Say that we can stop using this emode */
mbed_official 627:4fa1328d9c60 1765 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 1766 if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
mbed_official 627:4fa1328d9c60 1767 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
mbed_official 627:4fa1328d9c60 1768 }else{
mbed_official 627:4fa1328d9c60 1769 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1770 }
mbed_official 627:4fa1328d9c60 1771 #else
mbed_official 548:1abac31e188e 1772 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1773 #endif
mbed_official 525:c320967f86b9 1774 }
mbed_official 525:c320967f86b9 1775
mbed_official 525:c320967f86b9 1776 /** Abort the ongoing RX transaction It disables the enabled interrupt for RX and
mbed_official 525:c320967f86b9 1777 * flush RX hardware buffer if RX FIFO is used
mbed_official 525:c320967f86b9 1778 *
mbed_official 525:c320967f86b9 1779 * @param obj The serial object
mbed_official 525:c320967f86b9 1780 */
mbed_official 548:1abac31e188e 1781 void serial_rx_abort_asynch(serial_t *obj)
mbed_official 548:1abac31e188e 1782 {
mbed_official 548:1abac31e188e 1783 /* Stop receiver */
mbed_official 548:1abac31e188e 1784 obj->serial.periph.uart->CMD |= USART_CMD_RXDIS;
mbed_official 525:c320967f86b9 1785
mbed_official 548:1abac31e188e 1786 /* Clean up */
mbed_official 548:1abac31e188e 1787 switch(obj->serial.dmaOptionsRX.dmaUsageState) {
mbed_official 548:1abac31e188e 1788 case DMA_USAGE_ALLOCATED:
mbed_official 548:1abac31e188e 1789 /* stop DMA transfer */
mbed_official 548:1abac31e188e 1790 DMA_ChannelEnable(obj->serial.dmaOptionsRX.dmaChannel, false);
mbed_official 548:1abac31e188e 1791 break;
mbed_official 548:1abac31e188e 1792 case DMA_USAGE_TEMPORARY_ALLOCATED:
mbed_official 548:1abac31e188e 1793 /* stop DMA transfer and release channel */
mbed_official 548:1abac31e188e 1794 DMA_ChannelEnable(obj->serial.dmaOptionsRX.dmaChannel, false);
mbed_official 548:1abac31e188e 1795 dma_channel_free(obj->serial.dmaOptionsRX.dmaChannel);
mbed_official 548:1abac31e188e 1796 obj->serial.dmaOptionsRX.dmaChannel = -1;
mbed_official 548:1abac31e188e 1797 obj->serial.dmaOptionsRX.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
mbed_official 548:1abac31e188e 1798 break;
mbed_official 548:1abac31e188e 1799 default:
mbed_official 548:1abac31e188e 1800 /* stop interrupting */
mbed_official 548:1abac31e188e 1801 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1802 LEUART_IntDisable(obj->serial.periph.leuart, LEUART_IEN_RXDATAV | LEUART_IEN_PERR | LEUART_IEN_FERR | LEUART_IEN_RXOF);
mbed_official 548:1abac31e188e 1803 } else {
mbed_official 548:1abac31e188e 1804 USART_IntDisable(obj->serial.periph.uart, USART_IEN_RXDATAV | USART_IEN_PERR | USART_IEN_FERR | USART_IEN_RXOF);
mbed_official 548:1abac31e188e 1805 }
mbed_official 548:1abac31e188e 1806 break;
mbed_official 548:1abac31e188e 1807 }
mbed_official 525:c320967f86b9 1808
mbed_official 627:4fa1328d9c60 1809 /*clear all set interrupts*/
mbed_official 627:4fa1328d9c60 1810 if(LEUART_REF_VALID(obj->serial.periph.leuart)) {
mbed_official 627:4fa1328d9c60 1811 LEUART_IntClear(obj->serial.periph.leuart, LEUART_IFC_PERR | LEUART_IFC_FERR | LEUART_IFC_RXOF);
mbed_official 627:4fa1328d9c60 1812 }else{
mbed_official 627:4fa1328d9c60 1813 USART_IntClear(obj->serial.periph.uart, USART_IFC_PERR | USART_IFC_FERR | USART_IFC_RXOF);
mbed_official 627:4fa1328d9c60 1814 }
mbed_official 627:4fa1328d9c60 1815
mbed_official 548:1abac31e188e 1816 /* Say that we can stop using this emode */
mbed_official 627:4fa1328d9c60 1817 #ifdef LEUART_USING_LFXO
mbed_official 627:4fa1328d9c60 1818 if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
mbed_official 627:4fa1328d9c60 1819 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
mbed_official 627:4fa1328d9c60 1820 }else{
mbed_official 627:4fa1328d9c60 1821 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1822 }
mbed_official 627:4fa1328d9c60 1823 #else
mbed_official 548:1abac31e188e 1824 unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
mbed_official 627:4fa1328d9c60 1825 #endif
mbed_official 525:c320967f86b9 1826 }
mbed_official 525:c320967f86b9 1827
mbed_official 525:c320967f86b9 1828 #endif //DEVICE_SERIAL_ASYNCH
mbed_official 525:c320967f86b9 1829 #endif //DEVICE_SERIAL