mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri May 22 10:45:46 2015 +0100
Revision:
548:1abac31e188e
Parent:
547:88c982c8f758
Child:
563:536c9fb088a0
Synchronized with git revision 88d158e43b54f97c5e94da305ea9a096889cc81b

Full URL: https://github.com/mbedmicro/mbed/commit/88d158e43b54f97c5e94da305ea9a096889cc81b/

Silicon Labs - Cosmetic: apply mbed coding style to HAL

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