mbed library sources

Fork of mbed-src by mbed official

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