mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri May 22 09:45:08 2015 +0100
Revision:
547:88c982c8f758
Parent:
527:74d34ce5a2b5
Child:
548:1abac31e188e
Synchronized with git revision 61deb3e97c669a7c9bc99d3941d8f4c28c463f24

Full URL: https://github.com/mbedmicro/mbed/commit/61deb3e97c669a7c9bc99d3941d8f4c28c463f24/

Timer/Ticker - fix constness of the data argument/member

Who changed what in which revision?

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