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:
humlet
Date:
Sun Jun 30 16:34:50 2013 +0000
Revision:
11:f9e72c209510
Parent:
10:3bc89ef62ce7
fix for mbed lib issue 1 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/1

Who changed what in which revision?

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