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:
Tue Feb 03 17:00:07 2015 +0000
Revision:
463:5c73c3744533
Parent:
339:40bd4701f3e2
Synchronized with git revision 134a67aab259d410373367cb96b73420b390d385

Full URL: https://github.com/mbedmicro/mbed/commit/134a67aab259d410373367cb96b73420b390d385/

Who changed what in which revision?

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