mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

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

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

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

Import librarymbed

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

Committer:
mbed_official
Date:
Wed Sep 02 09:00:41 2015 +0100
Revision:
615:0a3cd1b87e2a
Parent:
339:40bd4701f3e2
Synchronized with git revision cfb59496c59d468dacee9fc74c9f834a3027b8f1

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 174:8bb9f3a33240 1 /* mbed Microcontroller Library
mbed_official 174:8bb9f3a33240 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 174:8bb9f3a33240 3 *
mbed_official 174:8bb9f3a33240 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 174:8bb9f3a33240 5 * you may not use this file except in compliance with the License.
mbed_official 174:8bb9f3a33240 6 * You may obtain a copy of the License at
mbed_official 174:8bb9f3a33240 7 *
mbed_official 174:8bb9f3a33240 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 174:8bb9f3a33240 9 *
mbed_official 174:8bb9f3a33240 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 174:8bb9f3a33240 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 174:8bb9f3a33240 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 174:8bb9f3a33240 13 * See the License for the specific language governing permissions and
mbed_official 174:8bb9f3a33240 14 * limitations under the License.
mbed_official 174:8bb9f3a33240 15 */
mbed_official 220:aa774fb95d17 16
mbed_official 174:8bb9f3a33240 17 // math.h required for floating point operations for baud rate calculation
mbed_official 227:7bd0639b8911 18 #include "mbed_assert.h"
mbed_official 174:8bb9f3a33240 19 #include <math.h>
mbed_official 174:8bb9f3a33240 20 #include <string.h>
mbed_official 174:8bb9f3a33240 21 #include <stdlib.h>
mbed_official 174:8bb9f3a33240 22
mbed_official 174:8bb9f3a33240 23 #include "serial_api.h"
mbed_official 174:8bb9f3a33240 24 #include "cmsis.h"
mbed_official 174:8bb9f3a33240 25 #include "pinmap.h"
mbed_official 174:8bb9f3a33240 26
mbed_official 174:8bb9f3a33240 27 #if DEVICE_SERIAL
mbed_official 220:aa774fb95d17 28
mbed_official 174:8bb9f3a33240 29 /******************************************************************************
mbed_official 174:8bb9f3a33240 30 * INITIALIZATION
mbed_official 174:8bb9f3a33240 31 ******************************************************************************/
mbed_official 174:8bb9f3a33240 32
mbed_official 220:aa774fb95d17 33 #define UART_NUM 5
mbed_official 220:aa774fb95d17 34
mbed_official 220:aa774fb95d17 35 // CFG
mbed_official 220:aa774fb95d17 36 #define UART_EN (0x01<<0)
mbed_official 220:aa774fb95d17 37
mbed_official 220:aa774fb95d17 38 // CTL
mbed_official 220:aa774fb95d17 39 #define TXBRKEN (0x01<<1)
mbed_official 220:aa774fb95d17 40
mbed_official 220:aa774fb95d17 41 // STAT
mbed_official 220:aa774fb95d17 42 #define RXRDY (0x01<<0)
mbed_official 220:aa774fb95d17 43 #define TXRDY (0x01<<2)
mbed_official 220:aa774fb95d17 44 #define DELTACTS (0x01<<5)
mbed_official 220:aa774fb95d17 45 #define RXBRK (0x01<<10)
mbed_official 220:aa774fb95d17 46 #define DELTARXBRK (0x01<<11)
mbed_official 174:8bb9f3a33240 47
mbed_official 174:8bb9f3a33240 48 static const PinMap PinMap_UART_TX[] = {
mbed_official 174:8bb9f3a33240 49 {P0_19, UART_0, 1},
mbed_official 174:8bb9f3a33240 50 {P1_18, UART_0, 2},
mbed_official 174:8bb9f3a33240 51 {P1_27, UART_0, 2},
mbed_official 220:aa774fb95d17 52 {P1_8 , UART_1, 2},
mbed_official 615:0a3cd1b87e2a 53 {P0_14, UART_1, 4},
mbed_official 220:aa774fb95d17 54 {P1_0 , UART_2, 3},
mbed_official 220:aa774fb95d17 55 {P1_23, UART_2, 3},
mbed_official 220:aa774fb95d17 56 {P2_4 , UART_3, 1},
mbed_official 220:aa774fb95d17 57 {P2_12, UART_4, 1},
mbed_official 174:8bb9f3a33240 58 { NC , NC , 0}
mbed_official 174:8bb9f3a33240 59 };
mbed_official 174:8bb9f3a33240 60
mbed_official 174:8bb9f3a33240 61 static const PinMap PinMap_UART_RX[] = {
mbed_official 174:8bb9f3a33240 62 {P0_18, UART_0, 1},
mbed_official 174:8bb9f3a33240 63 {P1_17, UART_0, 2},
mbed_official 174:8bb9f3a33240 64 {P1_26, UART_0, 2},
mbed_official 220:aa774fb95d17 65 {P1_2 , UART_1, 3},
mbed_official 615:0a3cd1b87e2a 66 {P0_13, UART_1, 4},
mbed_official 220:aa774fb95d17 67 {P0_20, UART_2, 2},
mbed_official 220:aa774fb95d17 68 {P1_6 , UART_2, 2},
mbed_official 220:aa774fb95d17 69 {P2_3 , UART_3, 1},
mbed_official 220:aa774fb95d17 70 {P2_11, UART_4, 1},
mbed_official 174:8bb9f3a33240 71 {NC , NC , 0}
mbed_official 174:8bb9f3a33240 72 };
mbed_official 174:8bb9f3a33240 73
mbed_official 174:8bb9f3a33240 74 static uint32_t serial_irq_ids[UART_NUM] = {0};
mbed_official 174:8bb9f3a33240 75 static uart_irq_handler irq_handler;
mbed_official 174:8bb9f3a33240 76
mbed_official 174:8bb9f3a33240 77 int stdio_uart_inited = 0;
mbed_official 174:8bb9f3a33240 78 serial_t stdio_uart;
mbed_official 174:8bb9f3a33240 79
mbed_official 174:8bb9f3a33240 80 void serial_init(serial_t *obj, PinName tx, PinName rx) {
mbed_official 174:8bb9f3a33240 81 int is_stdio_uart = 0;
mbed_official 174:8bb9f3a33240 82
mbed_official 174:8bb9f3a33240 83 // determine the UART to use
mbed_official 174:8bb9f3a33240 84 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
mbed_official 174:8bb9f3a33240 85 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
mbed_official 174:8bb9f3a33240 86 UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
mbed_official 227:7bd0639b8911 87 MBED_ASSERT((int)uart != NC);
mbed_official 174:8bb9f3a33240 88
mbed_official 220:aa774fb95d17 89 switch (uart) {
mbed_official 220:aa774fb95d17 90 case UART_0:
mbed_official 220:aa774fb95d17 91 obj->index = 0;
mbed_official 220:aa774fb95d17 92 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
mbed_official 220:aa774fb95d17 93 break;
mbed_official 220:aa774fb95d17 94 case UART_1:
mbed_official 220:aa774fb95d17 95 obj->index = 1;
mbed_official 220:aa774fb95d17 96 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 20);
mbed_official 220:aa774fb95d17 97 LPC_SYSCON->PRESETCTRL |= (1 << 5);
mbed_official 220:aa774fb95d17 98 break;
mbed_official 220:aa774fb95d17 99 case UART_2:
mbed_official 220:aa774fb95d17 100 obj->index = 2;
mbed_official 220:aa774fb95d17 101 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 21);
mbed_official 220:aa774fb95d17 102 LPC_SYSCON->PRESETCTRL |= (1 << 6);
mbed_official 220:aa774fb95d17 103 break;
mbed_official 220:aa774fb95d17 104 case UART_3:
mbed_official 220:aa774fb95d17 105 obj->index = 3;
mbed_official 220:aa774fb95d17 106 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 22);
mbed_official 220:aa774fb95d17 107 LPC_SYSCON->PRESETCTRL |= (1 << 7);
mbed_official 220:aa774fb95d17 108 break;
mbed_official 220:aa774fb95d17 109 case UART_4:
mbed_official 220:aa774fb95d17 110 obj->index = 4;
mbed_official 220:aa774fb95d17 111 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 22);
mbed_official 220:aa774fb95d17 112 LPC_SYSCON->PRESETCTRL |= (1 << 8);
mbed_official 220:aa774fb95d17 113 break;
mbed_official 220:aa774fb95d17 114 }
mbed_official 174:8bb9f3a33240 115
mbed_official 220:aa774fb95d17 116 if (obj->index == 0)
mbed_official 220:aa774fb95d17 117 obj->uart = (LPC_USART0_Type *)uart;
mbed_official 220:aa774fb95d17 118 else
mbed_official 220:aa774fb95d17 119 obj->mini_uart = (LPC_USART4_Type *)uart;
mbed_official 174:8bb9f3a33240 120
mbed_official 220:aa774fb95d17 121 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 122 // enable fifos and default rx trigger level
mbed_official 220:aa774fb95d17 123 obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
mbed_official 220:aa774fb95d17 124 | 0 << 1 // Rx Fifo Clear
mbed_official 220:aa774fb95d17 125 | 0 << 2 // Tx Fifo Clear
mbed_official 220:aa774fb95d17 126 | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
mbed_official 220:aa774fb95d17 127 // disable irqs
mbed_official 220:aa774fb95d17 128 obj->uart->IER = 0 << 0 // Rx Data available irq enable
mbed_official 220:aa774fb95d17 129 | 0 << 1 // Tx Fifo empty irq enable
mbed_official 220:aa774fb95d17 130 | 0 << 2; // Rx Line Status irq enable
mbed_official 220:aa774fb95d17 131 }
mbed_official 220:aa774fb95d17 132 else {
mbed_official 220:aa774fb95d17 133 // Clear all status bits
mbed_official 220:aa774fb95d17 134 obj->mini_uart->STAT = (DELTACTS | DELTARXBRK);
mbed_official 220:aa774fb95d17 135 // Enable UART
mbed_official 220:aa774fb95d17 136 obj->mini_uart->CFG |= UART_EN;
mbed_official 220:aa774fb95d17 137 }
mbed_official 174:8bb9f3a33240 138 // set default baud rate and format
mbed_official 174:8bb9f3a33240 139 serial_baud (obj, 9600);
mbed_official 174:8bb9f3a33240 140 serial_format(obj, 8, ParityNone, 1);
mbed_official 174:8bb9f3a33240 141
mbed_official 174:8bb9f3a33240 142 // pinout the chosen uart
mbed_official 174:8bb9f3a33240 143 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 174:8bb9f3a33240 144 pinmap_pinout(rx, PinMap_UART_RX);
mbed_official 174:8bb9f3a33240 145
mbed_official 174:8bb9f3a33240 146 // set rx/tx pins in PullUp mode
mbed_official 339:40bd4701f3e2 147 if (tx != NC) {
mbed_official 339:40bd4701f3e2 148 pin_mode(tx, PullUp);
mbed_official 339:40bd4701f3e2 149 }
mbed_official 339:40bd4701f3e2 150 if (rx != NC) {
mbed_official 339:40bd4701f3e2 151 pin_mode(rx, PullUp);
mbed_official 339:40bd4701f3e2 152 }
mbed_official 174:8bb9f3a33240 153
mbed_official 174:8bb9f3a33240 154 is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
mbed_official 174:8bb9f3a33240 155
mbed_official 220:aa774fb95d17 156 if (is_stdio_uart && (obj->index == 0)) {
mbed_official 174:8bb9f3a33240 157 stdio_uart_inited = 1;
mbed_official 174:8bb9f3a33240 158 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 174:8bb9f3a33240 159 }
mbed_official 174:8bb9f3a33240 160 }
mbed_official 174:8bb9f3a33240 161
mbed_official 174:8bb9f3a33240 162 void serial_free(serial_t *obj) {
mbed_official 174:8bb9f3a33240 163 serial_irq_ids[obj->index] = 0;
mbed_official 174:8bb9f3a33240 164 }
mbed_official 174:8bb9f3a33240 165
mbed_official 174:8bb9f3a33240 166 // serial_baud
mbed_official 174:8bb9f3a33240 167 // set the baud rate, taking in to account the current SystemFrequency
mbed_official 174:8bb9f3a33240 168 void serial_baud(serial_t *obj, int baudrate) {
mbed_official 220:aa774fb95d17 169 LPC_SYSCON->USART0CLKDIV = 1;
mbed_official 220:aa774fb95d17 170 LPC_SYSCON->FRGCLKDIV = 1;
mbed_official 220:aa774fb95d17 171
mbed_official 220:aa774fb95d17 172 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 173 uint32_t PCLK = SystemCoreClock;
mbed_official 220:aa774fb95d17 174 // First we check to see if the basic divide with no DivAddVal/MulVal
mbed_official 220:aa774fb95d17 175 // ratio gives us an integer result. If it does, we set DivAddVal = 0,
mbed_official 220:aa774fb95d17 176 // MulVal = 1. Otherwise, we search the valid ratio value range to find
mbed_official 220:aa774fb95d17 177 // the closest match. This could be more elegant, using search methods
mbed_official 220:aa774fb95d17 178 // and/or lookup tables, but the brute force method is not that much
mbed_official 220:aa774fb95d17 179 // slower, and is more maintainable.
mbed_official 220:aa774fb95d17 180 uint16_t DL = PCLK / (16 * baudrate);
mbed_official 220:aa774fb95d17 181
mbed_official 220:aa774fb95d17 182 uint8_t DivAddVal = 0;
mbed_official 220:aa774fb95d17 183 uint8_t MulVal = 1;
mbed_official 220:aa774fb95d17 184 int hit = 0;
mbed_official 220:aa774fb95d17 185 uint16_t dlv;
mbed_official 220:aa774fb95d17 186 uint8_t mv, dav;
mbed_official 220:aa774fb95d17 187 if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder
mbed_official 220:aa774fb95d17 188 int err_best = baudrate, b;
mbed_official 220:aa774fb95d17 189 for (mv = 1; mv < 16 && !hit; mv++)
mbed_official 174:8bb9f3a33240 190 {
mbed_official 220:aa774fb95d17 191 for (dav = 0; dav < mv; dav++)
mbed_official 220:aa774fb95d17 192 {
mbed_official 220:aa774fb95d17 193 // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul))
mbed_official 220:aa774fb95d17 194 // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul))
mbed_official 220:aa774fb95d17 195 // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding
mbed_official 220:aa774fb95d17 196 // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision
mbed_official 220:aa774fb95d17 197 // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding
mbed_official 174:8bb9f3a33240 198
mbed_official 220:aa774fb95d17 199 if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom
mbed_official 220:aa774fb95d17 200 dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2;
mbed_official 220:aa774fb95d17 201 else // 2 bits headroom, use more precision
mbed_official 220:aa774fb95d17 202 dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2;
mbed_official 174:8bb9f3a33240 203
mbed_official 220:aa774fb95d17 204 // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood
mbed_official 220:aa774fb95d17 205 if (dlv == 0)
mbed_official 220:aa774fb95d17 206 dlv = 1;
mbed_official 174:8bb9f3a33240 207
mbed_official 220:aa774fb95d17 208 // datasheet says if dav > 0 then DL must be >= 2
mbed_official 220:aa774fb95d17 209 if ((dav > 0) && (dlv < 2))
mbed_official 220:aa774fb95d17 210 dlv = 2;
mbed_official 220:aa774fb95d17 211
mbed_official 220:aa774fb95d17 212 // integer rearrangement of the baudrate equation (with rounding)
mbed_official 220:aa774fb95d17 213 b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2;
mbed_official 174:8bb9f3a33240 214
mbed_official 220:aa774fb95d17 215 // check to see how we went
mbed_official 220:aa774fb95d17 216 b = abs(b - baudrate);
mbed_official 220:aa774fb95d17 217 if (b < err_best)
mbed_official 220:aa774fb95d17 218 {
mbed_official 220:aa774fb95d17 219 err_best = b;
mbed_official 174:8bb9f3a33240 220
mbed_official 220:aa774fb95d17 221 DL = dlv;
mbed_official 220:aa774fb95d17 222 MulVal = mv;
mbed_official 220:aa774fb95d17 223 DivAddVal = dav;
mbed_official 174:8bb9f3a33240 224
mbed_official 220:aa774fb95d17 225 if (b == baudrate)
mbed_official 220:aa774fb95d17 226 {
mbed_official 220:aa774fb95d17 227 hit = 1;
mbed_official 220:aa774fb95d17 228 break;
mbed_official 220:aa774fb95d17 229 }
mbed_official 174:8bb9f3a33240 230 }
mbed_official 174:8bb9f3a33240 231 }
mbed_official 174:8bb9f3a33240 232 }
mbed_official 174:8bb9f3a33240 233 }
mbed_official 220:aa774fb95d17 234
mbed_official 220:aa774fb95d17 235 // set LCR[DLAB] to enable writing to divider registers
mbed_official 220:aa774fb95d17 236 obj->uart->LCR |= (1 << 7);
mbed_official 220:aa774fb95d17 237
mbed_official 220:aa774fb95d17 238 // set divider values
mbed_official 220:aa774fb95d17 239 obj->uart->DLM = (DL >> 8) & 0xFF;
mbed_official 220:aa774fb95d17 240 obj->uart->DLL = (DL >> 0) & 0xFF;
mbed_official 220:aa774fb95d17 241 obj->uart->FDR = (uint32_t) DivAddVal << 0
mbed_official 220:aa774fb95d17 242 | (uint32_t) MulVal << 4;
mbed_official 220:aa774fb95d17 243
mbed_official 220:aa774fb95d17 244 // clear LCR[DLAB]
mbed_official 220:aa774fb95d17 245 obj->uart->LCR &= ~(1 << 7);
mbed_official 174:8bb9f3a33240 246 }
mbed_official 220:aa774fb95d17 247 else {
mbed_official 220:aa774fb95d17 248 uint32_t UARTSysClk = SystemCoreClock / LPC_SYSCON->FRGCLKDIV;
mbed_official 220:aa774fb95d17 249 obj->mini_uart->BRG = UARTSysClk / 16 / baudrate - 1;
mbed_official 220:aa774fb95d17 250
mbed_official 220:aa774fb95d17 251 LPC_SYSCON->UARTFRGDIV = 0xFF;
mbed_official 220:aa774fb95d17 252 LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) /
mbed_official 220:aa774fb95d17 253 (baudrate * (obj->mini_uart->BRG + 1))
mbed_official 220:aa774fb95d17 254 ) - (LPC_SYSCON->UARTFRGDIV + 1);
mbed_official 220:aa774fb95d17 255 }
mbed_official 174:8bb9f3a33240 256 }
mbed_official 174:8bb9f3a33240 257
mbed_official 174:8bb9f3a33240 258 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
mbed_official 227:7bd0639b8911 259 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
mbed_official 227:7bd0639b8911 260
mbed_official 174:8bb9f3a33240 261 stop_bits -= 1;
mbed_official 227:7bd0639b8911 262
mbed_official 220:aa774fb95d17 263 if (obj->index == 0) {
mbed_official 227:7bd0639b8911 264 MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
mbed_official 227:7bd0639b8911 265 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
mbed_official 227:7bd0639b8911 266 (parity == ParityForced1) || (parity == ParityForced0));
mbed_official 220:aa774fb95d17 267 data_bits -= 5;
mbed_official 220:aa774fb95d17 268
mbed_official 220:aa774fb95d17 269 int parity_enable, parity_select;
mbed_official 220:aa774fb95d17 270 switch (parity) {
mbed_official 220:aa774fb95d17 271 case ParityNone: parity_enable = 0; parity_select = 0; break;
mbed_official 220:aa774fb95d17 272 case ParityOdd : parity_enable = 1; parity_select = 0; break;
mbed_official 220:aa774fb95d17 273 case ParityEven: parity_enable = 1; parity_select = 1; break;
mbed_official 220:aa774fb95d17 274 case ParityForced1: parity_enable = 1; parity_select = 2; break;
mbed_official 220:aa774fb95d17 275 case ParityForced0: parity_enable = 1; parity_select = 3; break;
mbed_official 220:aa774fb95d17 276 default:
mbed_official 220:aa774fb95d17 277 return;
mbed_official 220:aa774fb95d17 278 }
mbed_official 220:aa774fb95d17 279
mbed_official 220:aa774fb95d17 280 obj->uart->LCR = data_bits << 0
mbed_official 220:aa774fb95d17 281 | stop_bits << 2
mbed_official 220:aa774fb95d17 282 | parity_enable << 3
mbed_official 220:aa774fb95d17 283 | parity_select << 4;
mbed_official 174:8bb9f3a33240 284 }
mbed_official 220:aa774fb95d17 285 else {
mbed_official 220:aa774fb95d17 286 // 0: 7 data bits ... 2: 9 data bits
mbed_official 227:7bd0639b8911 287 MBED_ASSERT((data_bits > 6) && (data_bits < 10));
mbed_official 227:7bd0639b8911 288 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven));
mbed_official 220:aa774fb95d17 289 data_bits -= 7;
mbed_official 227:7bd0639b8911 290
mbed_official 220:aa774fb95d17 291 int paritysel;
mbed_official 220:aa774fb95d17 292 switch (parity) {
mbed_official 220:aa774fb95d17 293 case ParityNone: paritysel = 0; break;
mbed_official 220:aa774fb95d17 294 case ParityEven: paritysel = 2; break;
mbed_official 220:aa774fb95d17 295 case ParityOdd : paritysel = 3; break;
mbed_official 220:aa774fb95d17 296 default:
mbed_official 220:aa774fb95d17 297 return;
mbed_official 220:aa774fb95d17 298 }
mbed_official 220:aa774fb95d17 299 obj->mini_uart->CFG = (data_bits << 2)
mbed_official 220:aa774fb95d17 300 | (paritysel << 4)
mbed_official 220:aa774fb95d17 301 | (stop_bits << 6)
mbed_official 220:aa774fb95d17 302 | UART_EN;
mbed_official 174:8bb9f3a33240 303 }
mbed_official 174:8bb9f3a33240 304 }
mbed_official 174:8bb9f3a33240 305
mbed_official 174:8bb9f3a33240 306 /******************************************************************************
mbed_official 174:8bb9f3a33240 307 * INTERRUPTS HANDLING
mbed_official 174:8bb9f3a33240 308 ******************************************************************************/
mbed_official 174:8bb9f3a33240 309 static inline void uart_irq(uint32_t iir, uint32_t index) {
mbed_official 174:8bb9f3a33240 310 SerialIrq irq_type;
mbed_official 174:8bb9f3a33240 311 switch (iir) {
mbed_official 174:8bb9f3a33240 312 case 1: irq_type = TxIrq; break;
mbed_official 174:8bb9f3a33240 313 case 2: irq_type = RxIrq; break;
mbed_official 174:8bb9f3a33240 314 default: return;
mbed_official 174:8bb9f3a33240 315 }
mbed_official 174:8bb9f3a33240 316
mbed_official 174:8bb9f3a33240 317 if (serial_irq_ids[index] != 0)
mbed_official 174:8bb9f3a33240 318 irq_handler(serial_irq_ids[index], irq_type);
mbed_official 174:8bb9f3a33240 319 }
mbed_official 174:8bb9f3a33240 320
mbed_official 174:8bb9f3a33240 321 void uart0_irq()
mbed_official 174:8bb9f3a33240 322 {
mbed_official 174:8bb9f3a33240 323 uart_irq((LPC_USART0->IIR >> 1) & 0x7, 0);
mbed_official 174:8bb9f3a33240 324 }
mbed_official 174:8bb9f3a33240 325
mbed_official 174:8bb9f3a33240 326 void uart1_irq()
mbed_official 174:8bb9f3a33240 327 {
mbed_official 615:0a3cd1b87e2a 328 if(LPC_USART1->STAT & (1 << 2)){
mbed_official 615:0a3cd1b87e2a 329 uart_irq(1, 1);
mbed_official 615:0a3cd1b87e2a 330 }
mbed_official 615:0a3cd1b87e2a 331 if(LPC_USART1->STAT & (1 << 0)){
mbed_official 615:0a3cd1b87e2a 332 uart_irq(2, 1);
mbed_official 615:0a3cd1b87e2a 333 }
mbed_official 174:8bb9f3a33240 334 }
mbed_official 174:8bb9f3a33240 335
mbed_official 174:8bb9f3a33240 336 void uart2_irq()
mbed_official 174:8bb9f3a33240 337 {
mbed_official 615:0a3cd1b87e2a 338 if(LPC_USART2->STAT & (1 << 2)){
mbed_official 615:0a3cd1b87e2a 339 uart_irq(1, 2);
mbed_official 615:0a3cd1b87e2a 340 }
mbed_official 615:0a3cd1b87e2a 341 if(LPC_USART2->STAT & (1 << 0)){
mbed_official 615:0a3cd1b87e2a 342 uart_irq(2, 2);
mbed_official 615:0a3cd1b87e2a 343 }
mbed_official 174:8bb9f3a33240 344 }
mbed_official 174:8bb9f3a33240 345
mbed_official 174:8bb9f3a33240 346 void uart3_irq()
mbed_official 174:8bb9f3a33240 347 {
mbed_official 615:0a3cd1b87e2a 348 if(LPC_USART3->STAT & (1 << 2)){
mbed_official 615:0a3cd1b87e2a 349 uart_irq(1, 3);
mbed_official 615:0a3cd1b87e2a 350 }
mbed_official 615:0a3cd1b87e2a 351 if(LPC_USART3->STAT & (1 << 0)){
mbed_official 615:0a3cd1b87e2a 352 uart_irq(2, 3);
mbed_official 615:0a3cd1b87e2a 353 }
mbed_official 174:8bb9f3a33240 354 }
mbed_official 174:8bb9f3a33240 355
mbed_official 174:8bb9f3a33240 356 void uart4_irq()
mbed_official 174:8bb9f3a33240 357 {
mbed_official 615:0a3cd1b87e2a 358 if(LPC_USART4->STAT & (1 << 2)){
mbed_official 615:0a3cd1b87e2a 359 uart_irq(1, 4);
mbed_official 615:0a3cd1b87e2a 360 }
mbed_official 615:0a3cd1b87e2a 361 if(LPC_USART4->STAT & (1 << 0)){
mbed_official 615:0a3cd1b87e2a 362 uart_irq(2, 4);
mbed_official 615:0a3cd1b87e2a 363 }
mbed_official 174:8bb9f3a33240 364 }
mbed_official 174:8bb9f3a33240 365
mbed_official 174:8bb9f3a33240 366 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
mbed_official 174:8bb9f3a33240 367 irq_handler = handler;
mbed_official 174:8bb9f3a33240 368 serial_irq_ids[obj->index] = id;
mbed_official 174:8bb9f3a33240 369 }
mbed_official 174:8bb9f3a33240 370
mbed_official 174:8bb9f3a33240 371 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
mbed_official 174:8bb9f3a33240 372 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 174:8bb9f3a33240 373 uint32_t vector = 0;
mbed_official 615:0a3cd1b87e2a 374 if(obj->index == 0){
mbed_official 615:0a3cd1b87e2a 375 irq_n = USART0_IRQn; vector = (uint32_t)&uart0_irq;
mbed_official 615:0a3cd1b87e2a 376 }
mbed_official 615:0a3cd1b87e2a 377 else{
mbed_official 615:0a3cd1b87e2a 378 switch ((int)obj->mini_uart) {
mbed_official 615:0a3cd1b87e2a 379 case UART_0: irq_n = USART0_IRQn; vector = (uint32_t)&uart0_irq; break;
mbed_official 615:0a3cd1b87e2a 380 case UART_1: irq_n = USART1_4_IRQn; vector = (uint32_t)&uart1_irq; break;
mbed_official 615:0a3cd1b87e2a 381 case UART_2: irq_n = USART2_3_IRQn; vector = (uint32_t)&uart2_irq; break;
mbed_official 615:0a3cd1b87e2a 382 case UART_3: irq_n = USART2_3_IRQn; vector = (uint32_t)&uart3_irq; break;
mbed_official 615:0a3cd1b87e2a 383 case UART_4: irq_n = USART1_4_IRQn; vector = (uint32_t)&uart4_irq; break;
mbed_official 615:0a3cd1b87e2a 384 }
mbed_official 174:8bb9f3a33240 385 }
mbed_official 174:8bb9f3a33240 386
mbed_official 174:8bb9f3a33240 387 if (enable) {
mbed_official 220:aa774fb95d17 388 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 389 obj->uart->IER |= (1 << irq);
mbed_official 220:aa774fb95d17 390 }
mbed_official 220:aa774fb95d17 391 else {
mbed_official 220:aa774fb95d17 392 obj->mini_uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2));
mbed_official 220:aa774fb95d17 393 }
mbed_official 174:8bb9f3a33240 394 NVIC_SetVector(irq_n, vector);
mbed_official 174:8bb9f3a33240 395 NVIC_EnableIRQ(irq_n);
mbed_official 174:8bb9f3a33240 396 } else { // disable
mbed_official 174:8bb9f3a33240 397 int all_disabled = 0;
mbed_official 615:0a3cd1b87e2a 398 SerialIrq other_irq = (irq == RxIrq) ? (RxIrq) : (TxIrq);
mbed_official 174:8bb9f3a33240 399
mbed_official 220:aa774fb95d17 400 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 401 obj->uart->IER &= ~(1 << irq);
mbed_official 220:aa774fb95d17 402 all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
mbed_official 220:aa774fb95d17 403 }
mbed_official 220:aa774fb95d17 404 else {
mbed_official 615:0a3cd1b87e2a 405 obj->mini_uart->INTENCLR = (1 << ((irq == RxIrq) ? 0 : 2));
mbed_official 615:0a3cd1b87e2a 406 all_disabled = (obj->mini_uart->INTENSET) == 0;
mbed_official 220:aa774fb95d17 407 }
mbed_official 220:aa774fb95d17 408
mbed_official 174:8bb9f3a33240 409 if (all_disabled)
mbed_official 174:8bb9f3a33240 410 NVIC_DisableIRQ(irq_n);
mbed_official 174:8bb9f3a33240 411 }
mbed_official 174:8bb9f3a33240 412 }
mbed_official 174:8bb9f3a33240 413
mbed_official 174:8bb9f3a33240 414 /******************************************************************************
mbed_official 174:8bb9f3a33240 415 * READ/WRITE
mbed_official 174:8bb9f3a33240 416 ******************************************************************************/
mbed_official 174:8bb9f3a33240 417 int serial_getc(serial_t *obj) {
mbed_official 174:8bb9f3a33240 418 while (!serial_readable(obj));
mbed_official 220:aa774fb95d17 419 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 420 return obj->uart->RBR;
mbed_official 220:aa774fb95d17 421 }
mbed_official 220:aa774fb95d17 422 else {
mbed_official 220:aa774fb95d17 423 return obj->mini_uart->RXDAT;
mbed_official 220:aa774fb95d17 424 }
mbed_official 174:8bb9f3a33240 425 }
mbed_official 174:8bb9f3a33240 426
mbed_official 174:8bb9f3a33240 427 void serial_putc(serial_t *obj, int c) {
mbed_official 174:8bb9f3a33240 428 while (!serial_writable(obj));
mbed_official 220:aa774fb95d17 429 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 430 obj->uart->THR = c;
mbed_official 220:aa774fb95d17 431 }
mbed_official 220:aa774fb95d17 432 else {
mbed_official 220:aa774fb95d17 433 obj->mini_uart->TXDAT = c;
mbed_official 220:aa774fb95d17 434 }
mbed_official 174:8bb9f3a33240 435 }
mbed_official 174:8bb9f3a33240 436
mbed_official 174:8bb9f3a33240 437 int serial_readable(serial_t *obj) {
mbed_official 220:aa774fb95d17 438 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 439 return obj->uart->LSR & 0x01;
mbed_official 220:aa774fb95d17 440 }
mbed_official 220:aa774fb95d17 441 else {
mbed_official 220:aa774fb95d17 442 return obj->mini_uart->STAT & RXRDY;
mbed_official 220:aa774fb95d17 443 }
mbed_official 174:8bb9f3a33240 444 }
mbed_official 174:8bb9f3a33240 445
mbed_official 174:8bb9f3a33240 446 int serial_writable(serial_t *obj) {
mbed_official 220:aa774fb95d17 447 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 448 return obj->uart->LSR & 0x20;
mbed_official 220:aa774fb95d17 449 }
mbed_official 220:aa774fb95d17 450 else {
mbed_official 220:aa774fb95d17 451 return obj->mini_uart->STAT & TXRDY;
mbed_official 220:aa774fb95d17 452 }
mbed_official 174:8bb9f3a33240 453 }
mbed_official 174:8bb9f3a33240 454
mbed_official 174:8bb9f3a33240 455 void serial_clear(serial_t *obj) {
mbed_official 220:aa774fb95d17 456 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 457 obj->uart->FCR = 1 << 1 // rx FIFO reset
mbed_official 220:aa774fb95d17 458 | 1 << 2 // tx FIFO reset
mbed_official 220:aa774fb95d17 459 | 0 << 6; // interrupt depth
mbed_official 220:aa774fb95d17 460 }
mbed_official 220:aa774fb95d17 461 else {
mbed_official 220:aa774fb95d17 462 obj->mini_uart->STAT = 0;
mbed_official 220:aa774fb95d17 463 }
mbed_official 174:8bb9f3a33240 464 }
mbed_official 174:8bb9f3a33240 465
mbed_official 174:8bb9f3a33240 466 void serial_pinout_tx(PinName tx) {
mbed_official 174:8bb9f3a33240 467 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 174:8bb9f3a33240 468 }
mbed_official 174:8bb9f3a33240 469
mbed_official 174:8bb9f3a33240 470 void serial_break_set(serial_t *obj) {
mbed_official 220:aa774fb95d17 471 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 472 obj->uart->LCR |= (1 << 6);
mbed_official 220:aa774fb95d17 473 }
mbed_official 220:aa774fb95d17 474 else {
mbed_official 220:aa774fb95d17 475 obj->mini_uart->CTL |= TXBRKEN;
mbed_official 220:aa774fb95d17 476 }
mbed_official 174:8bb9f3a33240 477 }
mbed_official 174:8bb9f3a33240 478
mbed_official 174:8bb9f3a33240 479 void serial_break_clear(serial_t *obj) {
mbed_official 220:aa774fb95d17 480 if (obj->index == 0) {
mbed_official 220:aa774fb95d17 481 obj->uart->LCR &= ~(1 << 6);
mbed_official 220:aa774fb95d17 482 }
mbed_official 220:aa774fb95d17 483 else {
mbed_official 220:aa774fb95d17 484 obj->mini_uart->CTL &= ~TXBRKEN;
mbed_official 220:aa774fb95d17 485 }
mbed_official 174:8bb9f3a33240 486 }
mbed_official 174:8bb9f3a33240 487
mbed_official 174:8bb9f3a33240 488
mbed_official 174:8bb9f3a33240 489 #endif