mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

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

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

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

Import librarymbed

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

Committer:
mbed_official
Date:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
554:edd95c0879f8
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 554:edd95c0879f8 1 /* mbed Microcontroller Library
mbed_official 554:edd95c0879f8 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 554:edd95c0879f8 3 *
mbed_official 554:edd95c0879f8 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 554:edd95c0879f8 5 * you may not use this file except in compliance with the License.
mbed_official 554:edd95c0879f8 6 * You may obtain a copy of the License at
mbed_official 554:edd95c0879f8 7 *
mbed_official 554:edd95c0879f8 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 554:edd95c0879f8 9 *
mbed_official 554:edd95c0879f8 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 554:edd95c0879f8 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 554:edd95c0879f8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 554:edd95c0879f8 13 * See the License for the specific language governing permissions and
mbed_official 554:edd95c0879f8 14 * limitations under the License.
mbed_official 554:edd95c0879f8 15 */
mbed_official 554:edd95c0879f8 16 // math.h required for floating point operations for baud rate calculation
mbed_official 554:edd95c0879f8 17 #include "mbed_assert.h"
mbed_official 554:edd95c0879f8 18 #include <math.h>
mbed_official 554:edd95c0879f8 19 #include <string.h>
mbed_official 554:edd95c0879f8 20 #include <stdlib.h>
mbed_official 554:edd95c0879f8 21
mbed_official 554:edd95c0879f8 22 #include "serial_api.h"
mbed_official 554:edd95c0879f8 23 #include "cmsis.h"
mbed_official 554:edd95c0879f8 24 #include "pinmap.h"
mbed_official 554:edd95c0879f8 25
mbed_official 554:edd95c0879f8 26 /******************************************************************************
mbed_official 554:edd95c0879f8 27 * INITIALIZATION
mbed_official 554:edd95c0879f8 28 ******************************************************************************/
mbed_official 554:edd95c0879f8 29 #define UART_NUM 4
mbed_official 554:edd95c0879f8 30
mbed_official 554:edd95c0879f8 31 static const PinMap PinMap_UART_TX[] = {
mbed_official 554:edd95c0879f8 32 {P0_0, UART_3, 2},
mbed_official 554:edd95c0879f8 33 {P0_2, UART_0, 1},
mbed_official 554:edd95c0879f8 34 {P0_10, UART_2, 1},
mbed_official 554:edd95c0879f8 35 {P0_15, UART_1, 1},
mbed_official 554:edd95c0879f8 36 {P0_25, UART_3, 3},
mbed_official 554:edd95c0879f8 37 {P2_0 , UART_1, 2},
mbed_official 554:edd95c0879f8 38 {P2_8 , UART_2, 2},
mbed_official 554:edd95c0879f8 39 {P4_28, UART_3, 3},
mbed_official 554:edd95c0879f8 40 {NC , NC , 0}
mbed_official 554:edd95c0879f8 41 };
mbed_official 554:edd95c0879f8 42
mbed_official 554:edd95c0879f8 43 static const PinMap PinMap_UART_RX[] = {
mbed_official 554:edd95c0879f8 44 {P0_1 , UART_3, 2},
mbed_official 554:edd95c0879f8 45 {P0_3 , UART_0, 1},
mbed_official 554:edd95c0879f8 46 {P0_11, UART_2, 1},
mbed_official 554:edd95c0879f8 47 {P0_16, UART_1, 1},
mbed_official 554:edd95c0879f8 48 {P0_26, UART_3, 3},
mbed_official 554:edd95c0879f8 49 {P2_1 , UART_1, 2},
mbed_official 554:edd95c0879f8 50 {P2_9 , UART_2, 2},
mbed_official 554:edd95c0879f8 51 {P4_29, UART_3, 3},
mbed_official 554:edd95c0879f8 52 {NC , NC , 0}
mbed_official 554:edd95c0879f8 53 };
mbed_official 554:edd95c0879f8 54
mbed_official 554:edd95c0879f8 55 static uint32_t serial_irq_ids[UART_NUM] = {0};
mbed_official 554:edd95c0879f8 56 static uart_irq_handler irq_handler;
mbed_official 554:edd95c0879f8 57
mbed_official 554:edd95c0879f8 58 int stdio_uart_inited = 0;
mbed_official 554:edd95c0879f8 59 serial_t stdio_uart;
mbed_official 554:edd95c0879f8 60
mbed_official 554:edd95c0879f8 61 void serial_init(serial_t *obj, PinName tx, PinName rx) {
mbed_official 554:edd95c0879f8 62 int is_stdio_uart = 0;
mbed_official 554:edd95c0879f8 63
mbed_official 554:edd95c0879f8 64 // determine the UART to use
mbed_official 554:edd95c0879f8 65 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
mbed_official 554:edd95c0879f8 66 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
mbed_official 554:edd95c0879f8 67 UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
mbed_official 554:edd95c0879f8 68 MBED_ASSERT((int)uart != NC);
mbed_official 554:edd95c0879f8 69
mbed_official 554:edd95c0879f8 70 obj->uart = (LPC_UART_TypeDef *)uart;
mbed_official 554:edd95c0879f8 71 // enable power
mbed_official 554:edd95c0879f8 72 switch (uart) {
mbed_official 554:edd95c0879f8 73 case UART_0: LPC_SC->PCONP |= 1 << 3; break;
mbed_official 554:edd95c0879f8 74 case UART_1: LPC_SC->PCONP |= 1 << 4; break;
mbed_official 554:edd95c0879f8 75 case UART_2: LPC_SC->PCONP |= 1 << 24; break;
mbed_official 554:edd95c0879f8 76 case UART_3: LPC_SC->PCONP |= 1 << 25; break;
mbed_official 554:edd95c0879f8 77 }
mbed_official 554:edd95c0879f8 78
mbed_official 554:edd95c0879f8 79 // enable fifos and default rx trigger level
mbed_official 554:edd95c0879f8 80 obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
mbed_official 554:edd95c0879f8 81 | 0 << 1 // Rx Fifo Reset
mbed_official 554:edd95c0879f8 82 | 0 << 2 // Tx Fifo Reset
mbed_official 554:edd95c0879f8 83 | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
mbed_official 554:edd95c0879f8 84
mbed_official 554:edd95c0879f8 85 // disable irqs
mbed_official 554:edd95c0879f8 86 obj->uart->IER = 0 << 0 // Rx Data available irq enable
mbed_official 554:edd95c0879f8 87 | 0 << 1 // Tx Fifo empty irq enable
mbed_official 554:edd95c0879f8 88 | 0 << 2; // Rx Line Status irq enable
mbed_official 554:edd95c0879f8 89
mbed_official 554:edd95c0879f8 90 // set default baud rate and format
mbed_official 554:edd95c0879f8 91 serial_baud (obj, 9600);
mbed_official 554:edd95c0879f8 92 serial_format(obj, 8, ParityNone, 1);
mbed_official 554:edd95c0879f8 93
mbed_official 554:edd95c0879f8 94 // pinout the chosen uart
mbed_official 554:edd95c0879f8 95 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 554:edd95c0879f8 96 pinmap_pinout(rx, PinMap_UART_RX);
mbed_official 554:edd95c0879f8 97
mbed_official 554:edd95c0879f8 98 // set rx/tx pins in PullUp mode
mbed_official 554:edd95c0879f8 99 if (tx != NC) {
mbed_official 554:edd95c0879f8 100 pin_mode(tx, PullUp);
mbed_official 554:edd95c0879f8 101 }
mbed_official 554:edd95c0879f8 102 if (rx != NC) {
mbed_official 554:edd95c0879f8 103 pin_mode(rx, PullUp);
mbed_official 554:edd95c0879f8 104 }
mbed_official 554:edd95c0879f8 105
mbed_official 554:edd95c0879f8 106 switch (uart) {
mbed_official 554:edd95c0879f8 107 case UART_0: obj->index = 0; break;
mbed_official 554:edd95c0879f8 108 case UART_1: obj->index = 1; break;
mbed_official 554:edd95c0879f8 109 case UART_2: obj->index = 2; break;
mbed_official 554:edd95c0879f8 110 case UART_3: obj->index = 3; break;
mbed_official 554:edd95c0879f8 111 }
mbed_official 554:edd95c0879f8 112
mbed_official 554:edd95c0879f8 113 is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
mbed_official 554:edd95c0879f8 114
mbed_official 554:edd95c0879f8 115 if (is_stdio_uart) {
mbed_official 554:edd95c0879f8 116 stdio_uart_inited = 1;
mbed_official 554:edd95c0879f8 117 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 554:edd95c0879f8 118 }
mbed_official 554:edd95c0879f8 119 }
mbed_official 554:edd95c0879f8 120
mbed_official 554:edd95c0879f8 121 void serial_free(serial_t *obj) {
mbed_official 554:edd95c0879f8 122 serial_irq_ids[obj->index] = 0;
mbed_official 554:edd95c0879f8 123 }
mbed_official 554:edd95c0879f8 124
mbed_official 554:edd95c0879f8 125 // serial_baud
mbed_official 554:edd95c0879f8 126 // set the baud rate, taking in to account the current SystemFrequency
mbed_official 554:edd95c0879f8 127 void serial_baud(serial_t *obj, int baudrate) {
mbed_official 554:edd95c0879f8 128 MBED_ASSERT((int)obj->uart <= UART_3);
mbed_official 554:edd95c0879f8 129 // The LPC2300 and LPC1700 have a divider and a fractional divider to control the
mbed_official 554:edd95c0879f8 130 // baud rate. The formula is:
mbed_official 554:edd95c0879f8 131 //
mbed_official 554:edd95c0879f8 132 // Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal)
mbed_official 554:edd95c0879f8 133 // where:
mbed_official 554:edd95c0879f8 134 // 1 < MulVal <= 15
mbed_official 554:edd95c0879f8 135 // 0 <= DivAddVal < 14
mbed_official 554:edd95c0879f8 136 // DivAddVal < MulVal
mbed_official 554:edd95c0879f8 137 //
mbed_official 554:edd95c0879f8 138 // set pclk to /1
mbed_official 554:edd95c0879f8 139 switch ((int)obj->uart) {
mbed_official 554:edd95c0879f8 140 case UART_0: LPC_SC->PCLKSEL0 &= ~(0x3 << 6); LPC_SC->PCLKSEL0 |= (0x1 << 6); break;
mbed_official 554:edd95c0879f8 141 case UART_1: LPC_SC->PCLKSEL0 &= ~(0x3 << 8); LPC_SC->PCLKSEL0 |= (0x1 << 8); break;
mbed_official 554:edd95c0879f8 142 case UART_2: LPC_SC->PCLKSEL1 &= ~(0x3 << 16); LPC_SC->PCLKSEL1 |= (0x1 << 16); break;
mbed_official 554:edd95c0879f8 143 case UART_3: LPC_SC->PCLKSEL1 &= ~(0x3 << 18); LPC_SC->PCLKSEL1 |= (0x1 << 18); break;
mbed_official 554:edd95c0879f8 144 default: break;
mbed_official 554:edd95c0879f8 145 }
mbed_official 554:edd95c0879f8 146
mbed_official 554:edd95c0879f8 147 uint32_t PCLK = SystemCoreClock;
mbed_official 554:edd95c0879f8 148
mbed_official 554:edd95c0879f8 149 // First we check to see if the basic divide with no DivAddVal/MulVal
mbed_official 554:edd95c0879f8 150 // ratio gives us an integer result. If it does, we set DivAddVal = 0,
mbed_official 554:edd95c0879f8 151 // MulVal = 1. Otherwise, we search the valid ratio value range to find
mbed_official 554:edd95c0879f8 152 // the closest match. This could be more elegant, using search methods
mbed_official 554:edd95c0879f8 153 // and/or lookup tables, but the brute force method is not that much
mbed_official 554:edd95c0879f8 154 // slower, and is more maintainable.
mbed_official 554:edd95c0879f8 155 uint16_t DL = PCLK / (16 * baudrate);
mbed_official 554:edd95c0879f8 156
mbed_official 554:edd95c0879f8 157 uint8_t DivAddVal = 0;
mbed_official 554:edd95c0879f8 158 uint8_t MulVal = 1;
mbed_official 554:edd95c0879f8 159 int hit = 0;
mbed_official 554:edd95c0879f8 160 uint16_t dlv;
mbed_official 554:edd95c0879f8 161 uint8_t mv, dav;
mbed_official 554:edd95c0879f8 162 if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder
mbed_official 554:edd95c0879f8 163 int err_best = baudrate, b;
mbed_official 554:edd95c0879f8 164 for (mv = 1; mv < 16 && !hit; mv++)
mbed_official 554:edd95c0879f8 165 {
mbed_official 554:edd95c0879f8 166 for (dav = 0; dav < mv; dav++)
mbed_official 554:edd95c0879f8 167 {
mbed_official 554:edd95c0879f8 168 // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul))
mbed_official 554:edd95c0879f8 169 // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul))
mbed_official 554:edd95c0879f8 170 // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding
mbed_official 554:edd95c0879f8 171 // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision
mbed_official 554:edd95c0879f8 172 // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding
mbed_official 554:edd95c0879f8 173
mbed_official 554:edd95c0879f8 174 if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom
mbed_official 554:edd95c0879f8 175 dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2;
mbed_official 554:edd95c0879f8 176 else // 2 bits headroom, use more precision
mbed_official 554:edd95c0879f8 177 dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2;
mbed_official 554:edd95c0879f8 178
mbed_official 554:edd95c0879f8 179 // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood
mbed_official 554:edd95c0879f8 180 if (dlv == 0)
mbed_official 554:edd95c0879f8 181 dlv = 1;
mbed_official 554:edd95c0879f8 182
mbed_official 554:edd95c0879f8 183 // datasheet says if dav > 0 then DL must be >= 2
mbed_official 554:edd95c0879f8 184 if ((dav > 0) && (dlv < 2))
mbed_official 554:edd95c0879f8 185 dlv = 2;
mbed_official 554:edd95c0879f8 186
mbed_official 554:edd95c0879f8 187 // integer rearrangement of the baudrate equation (with rounding)
mbed_official 554:edd95c0879f8 188 b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2;
mbed_official 554:edd95c0879f8 189
mbed_official 554:edd95c0879f8 190 // check to see how we went
mbed_official 554:edd95c0879f8 191 b = abs(b - baudrate);
mbed_official 554:edd95c0879f8 192 if (b < err_best)
mbed_official 554:edd95c0879f8 193 {
mbed_official 554:edd95c0879f8 194 err_best = b;
mbed_official 554:edd95c0879f8 195
mbed_official 554:edd95c0879f8 196 DL = dlv;
mbed_official 554:edd95c0879f8 197 MulVal = mv;
mbed_official 554:edd95c0879f8 198 DivAddVal = dav;
mbed_official 554:edd95c0879f8 199
mbed_official 554:edd95c0879f8 200 if (b == baudrate)
mbed_official 554:edd95c0879f8 201 {
mbed_official 554:edd95c0879f8 202 hit = 1;
mbed_official 554:edd95c0879f8 203 break;
mbed_official 554:edd95c0879f8 204 }
mbed_official 554:edd95c0879f8 205 }
mbed_official 554:edd95c0879f8 206 }
mbed_official 554:edd95c0879f8 207 }
mbed_official 554:edd95c0879f8 208 }
mbed_official 554:edd95c0879f8 209
mbed_official 554:edd95c0879f8 210 // set LCR[DLAB] to enable writing to divider registers
mbed_official 554:edd95c0879f8 211 obj->uart->LCR |= (1 << 7);
mbed_official 554:edd95c0879f8 212
mbed_official 554:edd95c0879f8 213 // set divider values
mbed_official 554:edd95c0879f8 214 obj->uart->DLM = (DL >> 8) & 0xFF;
mbed_official 554:edd95c0879f8 215 obj->uart->DLL = (DL >> 0) & 0xFF;
mbed_official 554:edd95c0879f8 216 obj->uart->FDR = (uint32_t) DivAddVal << 0
mbed_official 554:edd95c0879f8 217 | (uint32_t) MulVal << 4;
mbed_official 554:edd95c0879f8 218
mbed_official 554:edd95c0879f8 219 // clear LCR[DLAB]
mbed_official 554:edd95c0879f8 220 obj->uart->LCR &= ~(1 << 7);
mbed_official 554:edd95c0879f8 221 }
mbed_official 554:edd95c0879f8 222
mbed_official 554:edd95c0879f8 223 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
mbed_official 554:edd95c0879f8 224 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
mbed_official 554:edd95c0879f8 225 MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
mbed_official 554:edd95c0879f8 226 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
mbed_official 554:edd95c0879f8 227 (parity == ParityForced1) || (parity == ParityForced0));
mbed_official 554:edd95c0879f8 228
mbed_official 554:edd95c0879f8 229 stop_bits -= 1;
mbed_official 554:edd95c0879f8 230 data_bits -= 5;
mbed_official 554:edd95c0879f8 231
mbed_official 554:edd95c0879f8 232 int parity_enable = 0, parity_select = 0;
mbed_official 554:edd95c0879f8 233 switch (parity) {
mbed_official 554:edd95c0879f8 234 case ParityNone: parity_enable = 0; parity_select = 0; break;
mbed_official 554:edd95c0879f8 235 case ParityOdd : parity_enable = 1; parity_select = 0; break;
mbed_official 554:edd95c0879f8 236 case ParityEven: parity_enable = 1; parity_select = 1; break;
mbed_official 554:edd95c0879f8 237 case ParityForced1: parity_enable = 1; parity_select = 2; break;
mbed_official 554:edd95c0879f8 238 case ParityForced0: parity_enable = 1; parity_select = 3; break;
mbed_official 554:edd95c0879f8 239 default:
mbed_official 554:edd95c0879f8 240 break;
mbed_official 554:edd95c0879f8 241 }
mbed_official 554:edd95c0879f8 242
mbed_official 554:edd95c0879f8 243 obj->uart->LCR = data_bits << 0
mbed_official 554:edd95c0879f8 244 | stop_bits << 2
mbed_official 554:edd95c0879f8 245 | parity_enable << 3
mbed_official 554:edd95c0879f8 246 | parity_select << 4;
mbed_official 554:edd95c0879f8 247 }
mbed_official 554:edd95c0879f8 248
mbed_official 554:edd95c0879f8 249 /******************************************************************************
mbed_official 554:edd95c0879f8 250 * INTERRUPTS HANDLING
mbed_official 554:edd95c0879f8 251 ******************************************************************************/
mbed_official 554:edd95c0879f8 252 static inline void uart_irq(uint32_t iir, uint32_t index) {
mbed_official 554:edd95c0879f8 253 // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
mbed_official 554:edd95c0879f8 254 SerialIrq irq_type;
mbed_official 554:edd95c0879f8 255 switch (iir) {
mbed_official 554:edd95c0879f8 256 case 1: irq_type = TxIrq; break;
mbed_official 554:edd95c0879f8 257 case 2: irq_type = RxIrq; break;
mbed_official 554:edd95c0879f8 258 default: return;
mbed_official 554:edd95c0879f8 259 }
mbed_official 554:edd95c0879f8 260
mbed_official 554:edd95c0879f8 261 if (serial_irq_ids[index] != 0){
mbed_official 554:edd95c0879f8 262 irq_handler(serial_irq_ids[index], irq_type);
mbed_official 554:edd95c0879f8 263 }
mbed_official 554:edd95c0879f8 264 }
mbed_official 554:edd95c0879f8 265
mbed_official 554:edd95c0879f8 266 void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);}
mbed_official 554:edd95c0879f8 267 void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);}
mbed_official 554:edd95c0879f8 268 void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);}
mbed_official 554:edd95c0879f8 269 void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);}
mbed_official 554:edd95c0879f8 270
mbed_official 554:edd95c0879f8 271 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
mbed_official 554:edd95c0879f8 272 irq_handler = handler;
mbed_official 554:edd95c0879f8 273 serial_irq_ids[obj->index] = id;
mbed_official 554:edd95c0879f8 274 }
mbed_official 554:edd95c0879f8 275
mbed_official 554:edd95c0879f8 276 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
mbed_official 554:edd95c0879f8 277 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 554:edd95c0879f8 278 uint32_t vector = 0;
mbed_official 554:edd95c0879f8 279 switch ((int)obj->uart) {
mbed_official 554:edd95c0879f8 280 case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
mbed_official 554:edd95c0879f8 281 case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
mbed_official 554:edd95c0879f8 282 case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
mbed_official 554:edd95c0879f8 283 case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break;
mbed_official 554:edd95c0879f8 284 }
mbed_official 554:edd95c0879f8 285
mbed_official 554:edd95c0879f8 286 if (enable) {
mbed_official 554:edd95c0879f8 287 obj->uart->IER |= 1 << irq;
mbed_official 554:edd95c0879f8 288 NVIC_SetVector(irq_n, vector);
mbed_official 554:edd95c0879f8 289 NVIC_EnableIRQ(irq_n);
mbed_official 554:edd95c0879f8 290 } else { // disable
mbed_official 554:edd95c0879f8 291 int all_disabled = 0;
mbed_official 554:edd95c0879f8 292 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
mbed_official 554:edd95c0879f8 293 obj->uart->IER &= ~(1 << irq);
mbed_official 554:edd95c0879f8 294 all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
mbed_official 554:edd95c0879f8 295 if (all_disabled)
mbed_official 554:edd95c0879f8 296 NVIC_DisableIRQ(irq_n);
mbed_official 554:edd95c0879f8 297 }
mbed_official 554:edd95c0879f8 298 }
mbed_official 554:edd95c0879f8 299
mbed_official 554:edd95c0879f8 300 /******************************************************************************
mbed_official 554:edd95c0879f8 301 * READ/WRITE
mbed_official 554:edd95c0879f8 302 ******************************************************************************/
mbed_official 554:edd95c0879f8 303 int serial_getc(serial_t *obj) {
mbed_official 554:edd95c0879f8 304 while (!serial_readable(obj));
mbed_official 554:edd95c0879f8 305 return obj->uart->RBR;
mbed_official 554:edd95c0879f8 306 }
mbed_official 554:edd95c0879f8 307
mbed_official 554:edd95c0879f8 308 void serial_putc(serial_t *obj, int c) {
mbed_official 554:edd95c0879f8 309 while (!serial_writable(obj));
mbed_official 554:edd95c0879f8 310 obj->uart->THR = c;
mbed_official 554:edd95c0879f8 311 }
mbed_official 554:edd95c0879f8 312
mbed_official 554:edd95c0879f8 313 int serial_readable(serial_t *obj) {
mbed_official 554:edd95c0879f8 314 return obj->uart->LSR & 0x01;
mbed_official 554:edd95c0879f8 315 }
mbed_official 554:edd95c0879f8 316
mbed_official 554:edd95c0879f8 317 int serial_writable(serial_t *obj) {
mbed_official 554:edd95c0879f8 318 return obj->uart->LSR & 0x20;
mbed_official 554:edd95c0879f8 319 }
mbed_official 554:edd95c0879f8 320
mbed_official 554:edd95c0879f8 321 void serial_clear(serial_t *obj) {
mbed_official 554:edd95c0879f8 322 obj->uart->FCR = 1 << 1 // rx FIFO reset
mbed_official 554:edd95c0879f8 323 | 1 << 2 // tx FIFO reset
mbed_official 554:edd95c0879f8 324 | 0 << 6; // interrupt depth
mbed_official 554:edd95c0879f8 325 }
mbed_official 554:edd95c0879f8 326
mbed_official 554:edd95c0879f8 327 void serial_pinout_tx(PinName tx) {
mbed_official 554:edd95c0879f8 328 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 554:edd95c0879f8 329 }
mbed_official 554:edd95c0879f8 330
mbed_official 554:edd95c0879f8 331 void serial_break_set(serial_t *obj) {
mbed_official 554:edd95c0879f8 332 obj->uart->LCR |= (1 << 6);
mbed_official 554:edd95c0879f8 333 }
mbed_official 554:edd95c0879f8 334
mbed_official 554:edd95c0879f8 335 void serial_break_clear(serial_t *obj) {
mbed_official 554:edd95c0879f8 336 obj->uart->LCR &= ~(1 << 6);
mbed_official 554:edd95c0879f8 337 }
mbed_official 554:edd95c0879f8 338