mbed SDK library sources

Fork of mbed-src by mbed official

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:
Thu Dec 26 13:00:06 2013 +0000
Revision:
68:41613245dfd7
Child:
73:299c67215126
Synchronized with git revision fba199a9c4445231b0f38e1e113c118182635546

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

target K20D5M

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 68:41613245dfd7 1 /* mbed Microcontroller Library
mbed_official 68:41613245dfd7 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 68:41613245dfd7 3 *
mbed_official 68:41613245dfd7 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 68:41613245dfd7 5 * you may not use this file except in compliance with the License.
mbed_official 68:41613245dfd7 6 * You may obtain a copy of the License at
mbed_official 68:41613245dfd7 7 *
mbed_official 68:41613245dfd7 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 68:41613245dfd7 9 *
mbed_official 68:41613245dfd7 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 68:41613245dfd7 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 68:41613245dfd7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 68:41613245dfd7 13 * See the License for the specific language governing permissions and
mbed_official 68:41613245dfd7 14 * limitations under the License.
mbed_official 68:41613245dfd7 15 */
mbed_official 68:41613245dfd7 16 #include "serial_api.h"
mbed_official 68:41613245dfd7 17
mbed_official 68:41613245dfd7 18 // math.h required for floating point operations for baud rate calculation
mbed_official 68:41613245dfd7 19 #include <math.h>
mbed_official 68:41613245dfd7 20
mbed_official 68:41613245dfd7 21 #include <string.h>
mbed_official 68:41613245dfd7 22
mbed_official 68:41613245dfd7 23 #include "cmsis.h"
mbed_official 68:41613245dfd7 24 #include "pinmap.h"
mbed_official 68:41613245dfd7 25 #include "error.h"
mbed_official 68:41613245dfd7 26
mbed_official 68:41613245dfd7 27 static const PinMap PinMap_UART_TX[] = {
mbed_official 68:41613245dfd7 28 {PTB17, UART_0, 3},
mbed_official 68:41613245dfd7 29 {NC , NC , 0}
mbed_official 68:41613245dfd7 30 };
mbed_official 68:41613245dfd7 31
mbed_official 68:41613245dfd7 32 static const PinMap PinMap_UART_RX[] = {
mbed_official 68:41613245dfd7 33 {PTB16, UART_0, 3},
mbed_official 68:41613245dfd7 34 {NC , NC , 0}
mbed_official 68:41613245dfd7 35 };
mbed_official 68:41613245dfd7 36
mbed_official 68:41613245dfd7 37 #define UART_NUM 3
mbed_official 68:41613245dfd7 38
mbed_official 68:41613245dfd7 39 static uint32_t serial_irq_ids[UART_NUM] = {0};
mbed_official 68:41613245dfd7 40 static uart_irq_handler irq_handler;
mbed_official 68:41613245dfd7 41
mbed_official 68:41613245dfd7 42 int stdio_uart_inited = 0;
mbed_official 68:41613245dfd7 43 serial_t stdio_uart;
mbed_official 68:41613245dfd7 44
mbed_official 68:41613245dfd7 45 void serial_init(serial_t *obj, PinName tx, PinName rx) {
mbed_official 68:41613245dfd7 46 // determine the UART to use
mbed_official 68:41613245dfd7 47 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
mbed_official 68:41613245dfd7 48 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
mbed_official 68:41613245dfd7 49 UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
mbed_official 68:41613245dfd7 50 if ((int)uart == NC)
mbed_official 68:41613245dfd7 51 error("Serial pinout mapping failed");
mbed_official 68:41613245dfd7 52
mbed_official 68:41613245dfd7 53 obj->uart = (UART_Type *)uart;
mbed_official 68:41613245dfd7 54 // enable clk
mbed_official 68:41613245dfd7 55 switch (uart) {
mbed_official 68:41613245dfd7 56 case UART_0: SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | (1<<SIM_SOPT5_UART0TXSRC_SHIFT);
mbed_official 68:41613245dfd7 57 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
mbed_official 68:41613245dfd7 58 case UART_1: SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; break;
mbed_official 68:41613245dfd7 59 case UART_2: SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; break;
mbed_official 68:41613245dfd7 60 }
mbed_official 68:41613245dfd7 61 // Disable UART before changing registers
mbed_official 68:41613245dfd7 62 obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
mbed_official 68:41613245dfd7 63
mbed_official 68:41613245dfd7 64 switch (uart) {
mbed_official 68:41613245dfd7 65 case UART_0: obj->index = 0; break;
mbed_official 68:41613245dfd7 66 case UART_1: obj->index = 1; break;
mbed_official 68:41613245dfd7 67 case UART_2: obj->index = 2; break;
mbed_official 68:41613245dfd7 68 }
mbed_official 68:41613245dfd7 69
mbed_official 68:41613245dfd7 70 // set default baud rate and format
mbed_official 68:41613245dfd7 71 serial_baud (obj, 9600);
mbed_official 68:41613245dfd7 72 serial_format(obj, 8, ParityNone, 1);
mbed_official 68:41613245dfd7 73
mbed_official 68:41613245dfd7 74 // pinout the chosen uart
mbed_official 68:41613245dfd7 75 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 68:41613245dfd7 76 pinmap_pinout(rx, PinMap_UART_RX);
mbed_official 68:41613245dfd7 77
mbed_official 68:41613245dfd7 78 // set rx/tx pins in PullUp mode
mbed_official 68:41613245dfd7 79 pin_mode(tx, PullUp);
mbed_official 68:41613245dfd7 80 pin_mode(rx, PullUp);
mbed_official 68:41613245dfd7 81
mbed_official 68:41613245dfd7 82 obj->uart->C2 |= (UART_C2_RE_MASK | UART_C2_TE_MASK);
mbed_official 68:41613245dfd7 83
mbed_official 68:41613245dfd7 84 if (uart == STDIO_UART) {
mbed_official 68:41613245dfd7 85 stdio_uart_inited = 1;
mbed_official 68:41613245dfd7 86 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 68:41613245dfd7 87 }
mbed_official 68:41613245dfd7 88 }
mbed_official 68:41613245dfd7 89
mbed_official 68:41613245dfd7 90 void serial_free(serial_t *obj) {
mbed_official 68:41613245dfd7 91 serial_irq_ids[obj->index] = 0;
mbed_official 68:41613245dfd7 92 }
mbed_official 68:41613245dfd7 93
mbed_official 68:41613245dfd7 94 void serial_baud(serial_t *obj, int baudrate) {
mbed_official 68:41613245dfd7 95 // save C2 state
mbed_official 68:41613245dfd7 96 uint32_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
mbed_official 68:41613245dfd7 97
mbed_official 68:41613245dfd7 98 // Disable UART before changing registers
mbed_official 68:41613245dfd7 99 obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
mbed_official 68:41613245dfd7 100
mbed_official 68:41613245dfd7 101 // [TODO] not hardcode this value
mbed_official 68:41613245dfd7 102 uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u;
mbed_official 68:41613245dfd7 103
mbed_official 68:41613245dfd7 104 // First we check to see if the basic divide with no DivAddVal/MulVal
mbed_official 68:41613245dfd7 105 // ratio gives us an integer result. If it does, we set DivAddVal = 0,
mbed_official 68:41613245dfd7 106 // MulVal = 1. Otherwise, we search the valid ratio value range to find
mbed_official 68:41613245dfd7 107 // the closest match. This could be more elegant, using search methods
mbed_official 68:41613245dfd7 108 // and/or lookup tables, but the brute force method is not that much
mbed_official 68:41613245dfd7 109 // slower, and is more maintainable.
mbed_official 68:41613245dfd7 110 uint16_t DL = PCLK / (16 * baudrate);
mbed_official 68:41613245dfd7 111
mbed_official 68:41613245dfd7 112 // set BDH and BDL
mbed_official 68:41613245dfd7 113 obj->uart->BDH = (obj->uart->BDH & ~(0x1f)) | ((DL >> 8) & 0x1f);
mbed_official 68:41613245dfd7 114 obj->uart->BDL = (obj->uart->BDL & ~(0xff)) | ((DL >> 0) & 0xff);
mbed_official 68:41613245dfd7 115
mbed_official 68:41613245dfd7 116 // restore C2 state
mbed_official 68:41613245dfd7 117 obj->uart->C2 |= c2_state;
mbed_official 68:41613245dfd7 118 }
mbed_official 68:41613245dfd7 119
mbed_official 68:41613245dfd7 120 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
mbed_official 68:41613245dfd7 121
mbed_official 68:41613245dfd7 122 // save C2 state
mbed_official 68:41613245dfd7 123 uint32_t c2_state = (obj->uart->C2 & (UART_C2_RE_MASK | UART_C2_TE_MASK));
mbed_official 68:41613245dfd7 124
mbed_official 68:41613245dfd7 125 // Disable UART before changing registers
mbed_official 68:41613245dfd7 126 obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
mbed_official 68:41613245dfd7 127
mbed_official 68:41613245dfd7 128 // 8 data bits = 0 ... 9 data bits = 1
mbed_official 68:41613245dfd7 129 if ((data_bits < 8) || (data_bits > 9))
mbed_official 68:41613245dfd7 130 error("Invalid number of bits (%d) in serial format, should be 8..9\r\n", data_bits);
mbed_official 68:41613245dfd7 131
mbed_official 68:41613245dfd7 132 data_bits -= 8;
mbed_official 68:41613245dfd7 133
mbed_official 68:41613245dfd7 134 uint32_t parity_enable, parity_select;
mbed_official 68:41613245dfd7 135 switch (parity) {
mbed_official 68:41613245dfd7 136 case ParityNone: parity_enable = 0; parity_select = 0; break;
mbed_official 68:41613245dfd7 137 case ParityOdd : parity_enable = 1; parity_select = 1; data_bits++; break;
mbed_official 68:41613245dfd7 138 case ParityEven: parity_enable = 1; parity_select = 0; data_bits++; break;
mbed_official 68:41613245dfd7 139 default:
mbed_official 68:41613245dfd7 140 error("Invalid serial parity setting\r\n");
mbed_official 68:41613245dfd7 141 return;
mbed_official 68:41613245dfd7 142 }
mbed_official 68:41613245dfd7 143
mbed_official 68:41613245dfd7 144 // 1 stop bits = 0, 2 stop bits = 1
mbed_official 68:41613245dfd7 145 if ((stop_bits != 1) && (stop_bits != 2))
mbed_official 68:41613245dfd7 146 error("Invalid stop bits specified\r\n");
mbed_official 68:41613245dfd7 147 stop_bits -= 1;
mbed_official 68:41613245dfd7 148
mbed_official 68:41613245dfd7 149 uint32_t m10 = 0;
mbed_official 68:41613245dfd7 150
mbed_official 68:41613245dfd7 151 // 9 data bits + parity
mbed_official 68:41613245dfd7 152 if (data_bits == 2) {
mbed_official 68:41613245dfd7 153 // only uart0 supports 10 bit communication
mbed_official 68:41613245dfd7 154 if (obj->index != 0)
mbed_official 68:41613245dfd7 155 error("Invalid number of bits (9) to be used with parity\r\n");
mbed_official 68:41613245dfd7 156 data_bits = 0;
mbed_official 68:41613245dfd7 157 m10 = 1;
mbed_official 68:41613245dfd7 158 }
mbed_official 68:41613245dfd7 159
mbed_official 68:41613245dfd7 160 // data bits, parity and parity mode
mbed_official 68:41613245dfd7 161 obj->uart->C1 = ((data_bits << 4)
mbed_official 68:41613245dfd7 162 | (parity_enable << 1)
mbed_official 68:41613245dfd7 163 | (parity_select << 0));
mbed_official 68:41613245dfd7 164
mbed_official 68:41613245dfd7 165 //enable 10bit mode if needed
mbed_official 68:41613245dfd7 166 if (obj->index == 0) {
mbed_official 68:41613245dfd7 167 obj->uart->C4 &= ~UART_C4_M10_MASK;
mbed_official 68:41613245dfd7 168 obj->uart->C4 |= (m10 << UART_C4_M10_SHIFT);
mbed_official 68:41613245dfd7 169 }
mbed_official 68:41613245dfd7 170
mbed_official 68:41613245dfd7 171 // stop bits
mbed_official 68:41613245dfd7 172 obj->uart->BDH &= ~UART_BDH_SBR_MASK;
mbed_official 68:41613245dfd7 173 obj->uart->BDH |= (stop_bits << UART_BDH_SBR_SHIFT);
mbed_official 68:41613245dfd7 174
mbed_official 68:41613245dfd7 175 // restore C2 state
mbed_official 68:41613245dfd7 176 obj->uart->C2 |= c2_state;
mbed_official 68:41613245dfd7 177 }
mbed_official 68:41613245dfd7 178
mbed_official 68:41613245dfd7 179 /******************************************************************************
mbed_official 68:41613245dfd7 180 * INTERRUPTS HANDLING
mbed_official 68:41613245dfd7 181 ******************************************************************************/
mbed_official 68:41613245dfd7 182 static inline void uart_irq(uint8_t status, uint32_t index) {
mbed_official 68:41613245dfd7 183 if (serial_irq_ids[index] != 0) {
mbed_official 68:41613245dfd7 184 if (status & UART_S1_TDRE_MASK)
mbed_official 68:41613245dfd7 185 irq_handler(serial_irq_ids[index], TxIrq);
mbed_official 68:41613245dfd7 186
mbed_official 68:41613245dfd7 187 if (status & UART_S1_RDRF_MASK)
mbed_official 68:41613245dfd7 188 irq_handler(serial_irq_ids[index], RxIrq);
mbed_official 68:41613245dfd7 189 }
mbed_official 68:41613245dfd7 190 }
mbed_official 68:41613245dfd7 191
mbed_official 68:41613245dfd7 192 void uart0_irq() {uart_irq(UART0->S1, 0);}
mbed_official 68:41613245dfd7 193 void uart1_irq() {uart_irq(UART1->S1, 1);}
mbed_official 68:41613245dfd7 194 void uart2_irq() {uart_irq(UART2->S1, 2);}
mbed_official 68:41613245dfd7 195
mbed_official 68:41613245dfd7 196 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
mbed_official 68:41613245dfd7 197 irq_handler = handler;
mbed_official 68:41613245dfd7 198 serial_irq_ids[obj->index] = id;
mbed_official 68:41613245dfd7 199 }
mbed_official 68:41613245dfd7 200
mbed_official 68:41613245dfd7 201 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
mbed_official 68:41613245dfd7 202 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 68:41613245dfd7 203 uint32_t vector = 0;
mbed_official 68:41613245dfd7 204 switch ((int)obj->uart) {
mbed_official 68:41613245dfd7 205 case UART_0:
mbed_official 68:41613245dfd7 206 irq_n=UART0_RX_TX_IRQn;
mbed_official 68:41613245dfd7 207 vector = (uint32_t)&uart0_irq;
mbed_official 68:41613245dfd7 208 break;
mbed_official 68:41613245dfd7 209 case UART_1:
mbed_official 68:41613245dfd7 210 irq_n=UART1_RX_TX_IRQn;
mbed_official 68:41613245dfd7 211 vector = (uint32_t)&uart1_irq;
mbed_official 68:41613245dfd7 212 break;
mbed_official 68:41613245dfd7 213 case UART_2:
mbed_official 68:41613245dfd7 214 irq_n=UART2_RX_TX_IRQn;
mbed_official 68:41613245dfd7 215 vector = (uint32_t)&uart2_irq;
mbed_official 68:41613245dfd7 216 break;
mbed_official 68:41613245dfd7 217 }
mbed_official 68:41613245dfd7 218
mbed_official 68:41613245dfd7 219 if (enable) {
mbed_official 68:41613245dfd7 220 switch (irq) {
mbed_official 68:41613245dfd7 221 case RxIrq:
mbed_official 68:41613245dfd7 222 obj->uart->C2 |= (UART_C2_RIE_MASK);
mbed_official 68:41613245dfd7 223 break;
mbed_official 68:41613245dfd7 224 case TxIrq:
mbed_official 68:41613245dfd7 225 obj->uart->C2 |= (UART_C2_TIE_MASK);
mbed_official 68:41613245dfd7 226 break;
mbed_official 68:41613245dfd7 227 }
mbed_official 68:41613245dfd7 228 NVIC_SetVector(irq_n, vector);
mbed_official 68:41613245dfd7 229 NVIC_EnableIRQ(irq_n);
mbed_official 68:41613245dfd7 230
mbed_official 68:41613245dfd7 231 } else { // disable
mbed_official 68:41613245dfd7 232 int all_disabled = 0;
mbed_official 68:41613245dfd7 233 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
mbed_official 68:41613245dfd7 234 switch (irq) {
mbed_official 68:41613245dfd7 235 case RxIrq:
mbed_official 68:41613245dfd7 236 obj->uart->C2 &= ~(UART_C2_RIE_MASK);
mbed_official 68:41613245dfd7 237 break;
mbed_official 68:41613245dfd7 238 case TxIrq:
mbed_official 68:41613245dfd7 239 obj->uart->C2 &= ~(UART_C2_TIE_MASK);
mbed_official 68:41613245dfd7 240 break;
mbed_official 68:41613245dfd7 241 }
mbed_official 68:41613245dfd7 242 switch (other_irq) {
mbed_official 68:41613245dfd7 243 case RxIrq:
mbed_official 68:41613245dfd7 244 all_disabled = (obj->uart->C2 & (UART_C2_RIE_MASK)) == 0;
mbed_official 68:41613245dfd7 245 break;
mbed_official 68:41613245dfd7 246 case TxIrq:
mbed_official 68:41613245dfd7 247 all_disabled = (obj->uart->C2 & (UART_C2_TIE_MASK)) == 0;
mbed_official 68:41613245dfd7 248 break;
mbed_official 68:41613245dfd7 249 }
mbed_official 68:41613245dfd7 250 if (all_disabled)
mbed_official 68:41613245dfd7 251 NVIC_DisableIRQ(irq_n);
mbed_official 68:41613245dfd7 252 }
mbed_official 68:41613245dfd7 253 }
mbed_official 68:41613245dfd7 254
mbed_official 68:41613245dfd7 255 int serial_getc(serial_t *obj) {
mbed_official 68:41613245dfd7 256 while (!serial_readable(obj));
mbed_official 68:41613245dfd7 257 return obj->uart->D;
mbed_official 68:41613245dfd7 258 }
mbed_official 68:41613245dfd7 259
mbed_official 68:41613245dfd7 260 void serial_putc(serial_t *obj, int c) {
mbed_official 68:41613245dfd7 261 while (!serial_writable(obj));
mbed_official 68:41613245dfd7 262 obj->uart->D = c;
mbed_official 68:41613245dfd7 263 }
mbed_official 68:41613245dfd7 264
mbed_official 68:41613245dfd7 265 int serial_readable(serial_t *obj) {
mbed_official 68:41613245dfd7 266
mbed_official 68:41613245dfd7 267 return (obj->uart->S1 & UART_S1_RDRF_MASK);
mbed_official 68:41613245dfd7 268 }
mbed_official 68:41613245dfd7 269
mbed_official 68:41613245dfd7 270 int serial_writable(serial_t *obj) {
mbed_official 68:41613245dfd7 271
mbed_official 68:41613245dfd7 272 return (obj->uart->S1 & UART_S1_TDRE_MASK);
mbed_official 68:41613245dfd7 273 }
mbed_official 68:41613245dfd7 274
mbed_official 68:41613245dfd7 275 void serial_clear(serial_t *obj) {
mbed_official 68:41613245dfd7 276 }
mbed_official 68:41613245dfd7 277
mbed_official 68:41613245dfd7 278 void serial_pinout_tx(PinName tx) {
mbed_official 68:41613245dfd7 279 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 68:41613245dfd7 280 }
mbed_official 68:41613245dfd7 281
mbed_official 68:41613245dfd7 282 void serial_break_set(serial_t *obj) {
mbed_official 68:41613245dfd7 283 obj->uart->C2 |= UART_C2_SBK_MASK;
mbed_official 68:41613245dfd7 284 }
mbed_official 68:41613245dfd7 285
mbed_official 68:41613245dfd7 286 void serial_break_clear(serial_t *obj) {
mbed_official 68:41613245dfd7 287 obj->uart->C2 &= ~UART_C2_SBK_MASK;
mbed_official 68:41613245dfd7 288 }
mbed_official 68:41613245dfd7 289