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:
Mon Nov 11 13:30:09 2013 +0000
Revision:
46:bebbbd80dd87
Child:
64:7b352733b00a
Synchronized with git revision b2733e9b9af906952b295cd6abcf916bf79780ab

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 46:bebbbd80dd87 1 /* mbed Microcontroller Library
mbed_official 46:bebbbd80dd87 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 46:bebbbd80dd87 3 *
mbed_official 46:bebbbd80dd87 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 46:bebbbd80dd87 5 * you may not use this file except in compliance with the License.
mbed_official 46:bebbbd80dd87 6 * You may obtain a copy of the License at
mbed_official 46:bebbbd80dd87 7 *
mbed_official 46:bebbbd80dd87 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 46:bebbbd80dd87 9 *
mbed_official 46:bebbbd80dd87 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 46:bebbbd80dd87 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 46:bebbbd80dd87 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 46:bebbbd80dd87 13 * See the License for the specific language governing permissions and
mbed_official 46:bebbbd80dd87 14 * limitations under the License.
mbed_official 46:bebbbd80dd87 15 */
mbed_official 46:bebbbd80dd87 16 // math.h required for floating point operations for baud rate calculation
mbed_official 46:bebbbd80dd87 17 #include <math.h>
mbed_official 46:bebbbd80dd87 18 #include <string.h>
mbed_official 46:bebbbd80dd87 19
mbed_official 46:bebbbd80dd87 20 #include "serial_api.h"
mbed_official 46:bebbbd80dd87 21 #include "cmsis.h"
mbed_official 46:bebbbd80dd87 22 #include "pinmap.h"
mbed_official 46:bebbbd80dd87 23 #include "error.h"
mbed_official 46:bebbbd80dd87 24
mbed_official 46:bebbbd80dd87 25 /******************************************************************************
mbed_official 46:bebbbd80dd87 26 * INITIALIZATION
mbed_official 46:bebbbd80dd87 27 ******************************************************************************/
mbed_official 46:bebbbd80dd87 28 #define UART_NUM 3
mbed_official 46:bebbbd80dd87 29
mbed_official 46:bebbbd80dd87 30 static const SWM_Map SWM_UART_TX[] = {
mbed_official 46:bebbbd80dd87 31 {0, 0},
mbed_official 46:bebbbd80dd87 32 {1, 8},
mbed_official 46:bebbbd80dd87 33 {2, 16},
mbed_official 46:bebbbd80dd87 34 };
mbed_official 46:bebbbd80dd87 35
mbed_official 46:bebbbd80dd87 36 static const SWM_Map SWM_UART_RX[] = {
mbed_official 46:bebbbd80dd87 37 {0, 8},
mbed_official 46:bebbbd80dd87 38 {1, 16},
mbed_official 46:bebbbd80dd87 39 {2, 24},
mbed_official 46:bebbbd80dd87 40 };
mbed_official 46:bebbbd80dd87 41
mbed_official 46:bebbbd80dd87 42 // bit flags for used UARTs
mbed_official 46:bebbbd80dd87 43 static unsigned char uart_used = 0;
mbed_official 46:bebbbd80dd87 44 static int get_available_uart(void) {
mbed_official 46:bebbbd80dd87 45 int i;
mbed_official 46:bebbbd80dd87 46 for (i=0; i<3; i++) {
mbed_official 46:bebbbd80dd87 47 if ((uart_used & (1 << i)) == 0)
mbed_official 46:bebbbd80dd87 48 return i;
mbed_official 46:bebbbd80dd87 49 }
mbed_official 46:bebbbd80dd87 50 return -1;
mbed_official 46:bebbbd80dd87 51 }
mbed_official 46:bebbbd80dd87 52
mbed_official 46:bebbbd80dd87 53 #define UART_EN (0x01<<0)
mbed_official 46:bebbbd80dd87 54
mbed_official 46:bebbbd80dd87 55 #define CTS_DELTA (0x01<<5)
mbed_official 46:bebbbd80dd87 56 #define RXBRK (0x01<<10)
mbed_official 46:bebbbd80dd87 57 #define DELTA_RXBRK (0x01<<11)
mbed_official 46:bebbbd80dd87 58
mbed_official 46:bebbbd80dd87 59 #define RXRDY (0x01<<0)
mbed_official 46:bebbbd80dd87 60 #define TXRDY (0x01<<2)
mbed_official 46:bebbbd80dd87 61
mbed_official 46:bebbbd80dd87 62 #define TXBRKEN (0x01<<1)
mbed_official 46:bebbbd80dd87 63
mbed_official 46:bebbbd80dd87 64 static uint32_t UARTSysClk;
mbed_official 46:bebbbd80dd87 65
mbed_official 46:bebbbd80dd87 66 static uint32_t serial_irq_ids[UART_NUM] = {0};
mbed_official 46:bebbbd80dd87 67 static uart_irq_handler irq_handler;
mbed_official 46:bebbbd80dd87 68
mbed_official 46:bebbbd80dd87 69 int stdio_uart_inited = 0;
mbed_official 46:bebbbd80dd87 70 serial_t stdio_uart;
mbed_official 46:bebbbd80dd87 71
mbed_official 46:bebbbd80dd87 72 void serial_init(serial_t *obj, PinName tx, PinName rx) {
mbed_official 46:bebbbd80dd87 73 int is_stdio_uart = 0;
mbed_official 46:bebbbd80dd87 74
mbed_official 46:bebbbd80dd87 75 int uart_n = get_available_uart();
mbed_official 46:bebbbd80dd87 76 if (uart_n == -1) {
mbed_official 46:bebbbd80dd87 77 error("No available UART");
mbed_official 46:bebbbd80dd87 78 }
mbed_official 46:bebbbd80dd87 79 obj->index = uart_n;
mbed_official 46:bebbbd80dd87 80 obj->uart = (LPC_USART_TypeDef *)(LPC_USART0_BASE + (0x4000 * uart_n));
mbed_official 46:bebbbd80dd87 81 uart_used |= (1 << uart_n);
mbed_official 46:bebbbd80dd87 82
mbed_official 46:bebbbd80dd87 83 const SWM_Map *swm;
mbed_official 46:bebbbd80dd87 84 uint32_t regVal;
mbed_official 46:bebbbd80dd87 85
mbed_official 46:bebbbd80dd87 86 swm = &SWM_UART_TX[uart_n];
mbed_official 46:bebbbd80dd87 87 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 46:bebbbd80dd87 88 LPC_SWM->PINASSIGN[swm->n] = regVal | (tx << swm->offset);
mbed_official 46:bebbbd80dd87 89
mbed_official 46:bebbbd80dd87 90 swm = &SWM_UART_RX[uart_n];
mbed_official 46:bebbbd80dd87 91 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 46:bebbbd80dd87 92 LPC_SWM->PINASSIGN[swm->n] = regVal | (rx << swm->offset);
mbed_official 46:bebbbd80dd87 93
mbed_official 46:bebbbd80dd87 94 /* uart clock divided by 1 */
mbed_official 46:bebbbd80dd87 95 LPC_SYSCON->UARTCLKDIV = 1;
mbed_official 46:bebbbd80dd87 96
mbed_official 46:bebbbd80dd87 97 /* disable uart interrupts */
mbed_official 46:bebbbd80dd87 98 NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + uart_n));
mbed_official 46:bebbbd80dd87 99
mbed_official 46:bebbbd80dd87 100 /* Enable UART clock */
mbed_official 46:bebbbd80dd87 101 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (14 + uart_n));
mbed_official 46:bebbbd80dd87 102
mbed_official 46:bebbbd80dd87 103 /* Peripheral reset control to UART, a "1" bring it out of reset. */
mbed_official 46:bebbbd80dd87 104 LPC_SYSCON->PRESETCTRL &= ~(0x1 << (3 + uart_n));
mbed_official 46:bebbbd80dd87 105 LPC_SYSCON->PRESETCTRL |= (0x1 << (3 + uart_n));
mbed_official 46:bebbbd80dd87 106
mbed_official 46:bebbbd80dd87 107 UARTSysClk = SystemCoreClock / LPC_SYSCON->UARTCLKDIV;
mbed_official 46:bebbbd80dd87 108
mbed_official 46:bebbbd80dd87 109 // set default baud rate and format
mbed_official 46:bebbbd80dd87 110 serial_baud (obj, 9600);
mbed_official 46:bebbbd80dd87 111 serial_format(obj, 8, ParityNone, 1);
mbed_official 46:bebbbd80dd87 112
mbed_official 46:bebbbd80dd87 113 /* Clear all status bits. */
mbed_official 46:bebbbd80dd87 114 obj->uart->STAT = CTS_DELTA | DELTA_RXBRK;
mbed_official 46:bebbbd80dd87 115
mbed_official 46:bebbbd80dd87 116 /* enable uart interrupts */
mbed_official 46:bebbbd80dd87 117 NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + uart_n));
mbed_official 46:bebbbd80dd87 118
mbed_official 46:bebbbd80dd87 119 /* Enable UART interrupt */
mbed_official 46:bebbbd80dd87 120 // obj->uart->INTENSET = RXRDY | TXRDY | DELTA_RXBRK;
mbed_official 46:bebbbd80dd87 121
mbed_official 46:bebbbd80dd87 122 /* Enable UART */
mbed_official 46:bebbbd80dd87 123 obj->uart->CFG |= UART_EN;
mbed_official 46:bebbbd80dd87 124
mbed_official 46:bebbbd80dd87 125 is_stdio_uart = ((tx == USBTX) && (rx == USBRX));
mbed_official 46:bebbbd80dd87 126
mbed_official 46:bebbbd80dd87 127 if (is_stdio_uart) {
mbed_official 46:bebbbd80dd87 128 stdio_uart_inited = 1;
mbed_official 46:bebbbd80dd87 129 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 46:bebbbd80dd87 130 }
mbed_official 46:bebbbd80dd87 131 }
mbed_official 46:bebbbd80dd87 132
mbed_official 46:bebbbd80dd87 133 void serial_free(serial_t *obj) {
mbed_official 46:bebbbd80dd87 134 uart_used &= ~(1 << obj->index);
mbed_official 46:bebbbd80dd87 135 serial_irq_ids[obj->index] = 0;
mbed_official 46:bebbbd80dd87 136 }
mbed_official 46:bebbbd80dd87 137
mbed_official 46:bebbbd80dd87 138 // serial_baud
mbed_official 46:bebbbd80dd87 139 // set the baud rate, taking in to account the current SystemFrequency
mbed_official 46:bebbbd80dd87 140 void serial_baud(serial_t *obj, int baudrate) {
mbed_official 46:bebbbd80dd87 141 /* Integer divider:
mbed_official 46:bebbbd80dd87 142 BRG = UARTSysClk/(Baudrate * 16) - 1
mbed_official 46:bebbbd80dd87 143
mbed_official 46:bebbbd80dd87 144 Frational divider:
mbed_official 46:bebbbd80dd87 145 FRG = ((UARTSysClk / (Baudrate * 16 * (BRG + 1))) - 1)
mbed_official 46:bebbbd80dd87 146
mbed_official 46:bebbbd80dd87 147 where
mbed_official 46:bebbbd80dd87 148 FRG = (LPC_SYSCON->UARTFRDADD + 1) / (LPC_SYSCON->UARTFRDSUB + 1)
mbed_official 46:bebbbd80dd87 149
mbed_official 46:bebbbd80dd87 150 (1) The easiest way is set SUB value to 256, -1 encoded, thus SUB
mbed_official 46:bebbbd80dd87 151 register is 0xFF.
mbed_official 46:bebbbd80dd87 152 (2) In ADD register value, depending on the value of UartSysClk,
mbed_official 46:bebbbd80dd87 153 baudrate, BRG register value, and SUB register value, be careful
mbed_official 46:bebbbd80dd87 154 about the order of multiplier and divider and make sure any
mbed_official 46:bebbbd80dd87 155 multiplier doesn't exceed 32-bit boundary and any divider doesn't get
mbed_official 46:bebbbd80dd87 156 down below one(integer 0).
mbed_official 46:bebbbd80dd87 157 (3) ADD should be always less than SUB.
mbed_official 46:bebbbd80dd87 158 */
mbed_official 46:bebbbd80dd87 159 obj->uart->BRG = UARTSysClk / 16 / baudrate - 1;
mbed_official 46:bebbbd80dd87 160
mbed_official 46:bebbbd80dd87 161 LPC_SYSCON->UARTFRGDIV = 0xFF;
mbed_official 46:bebbbd80dd87 162 LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) /
mbed_official 46:bebbbd80dd87 163 (baudrate * (obj->uart->BRG + 1))
mbed_official 46:bebbbd80dd87 164 ) - (LPC_SYSCON->UARTFRGDIV + 1);
mbed_official 46:bebbbd80dd87 165
mbed_official 46:bebbbd80dd87 166 }
mbed_official 46:bebbbd80dd87 167
mbed_official 46:bebbbd80dd87 168 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
mbed_official 46:bebbbd80dd87 169 // 0: 1 stop bits, 1: 2 stop bits
mbed_official 46:bebbbd80dd87 170 if (stop_bits != 1 && stop_bits != 2) {
mbed_official 46:bebbbd80dd87 171 error("Invalid stop bits specified");
mbed_official 46:bebbbd80dd87 172 }
mbed_official 46:bebbbd80dd87 173 stop_bits -= 1;
mbed_official 46:bebbbd80dd87 174
mbed_official 46:bebbbd80dd87 175 // 0: 7 data bits ... 2: 9 data bits
mbed_official 46:bebbbd80dd87 176 if (data_bits < 7 || data_bits > 9) {
mbed_official 46:bebbbd80dd87 177 error("Invalid number of bits (%d) in serial format, should be 7..9", data_bits);
mbed_official 46:bebbbd80dd87 178 }
mbed_official 46:bebbbd80dd87 179 data_bits -= 7;
mbed_official 46:bebbbd80dd87 180
mbed_official 46:bebbbd80dd87 181 int paritysel;
mbed_official 46:bebbbd80dd87 182 switch (parity) {
mbed_official 46:bebbbd80dd87 183 case ParityNone: paritysel = 0; break;
mbed_official 46:bebbbd80dd87 184 case ParityEven: paritysel = 2; break;
mbed_official 46:bebbbd80dd87 185 case ParityOdd : paritysel = 3; break;
mbed_official 46:bebbbd80dd87 186 default:
mbed_official 46:bebbbd80dd87 187 error("Invalid serial parity setting");
mbed_official 46:bebbbd80dd87 188 return;
mbed_official 46:bebbbd80dd87 189 }
mbed_official 46:bebbbd80dd87 190
mbed_official 46:bebbbd80dd87 191 obj->uart->CFG = (data_bits << 2)
mbed_official 46:bebbbd80dd87 192 | (paritysel << 4)
mbed_official 46:bebbbd80dd87 193 | (stop_bits << 6);
mbed_official 46:bebbbd80dd87 194 }
mbed_official 46:bebbbd80dd87 195
mbed_official 46:bebbbd80dd87 196 /******************************************************************************
mbed_official 46:bebbbd80dd87 197 * INTERRUPTS HANDLING
mbed_official 46:bebbbd80dd87 198 ******************************************************************************/
mbed_official 46:bebbbd80dd87 199 static inline void uart_irq(uint32_t iir, uint32_t index) {
mbed_official 46:bebbbd80dd87 200 // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
mbed_official 46:bebbbd80dd87 201 SerialIrq irq_type;
mbed_official 46:bebbbd80dd87 202 switch (iir) {
mbed_official 46:bebbbd80dd87 203 case 1: irq_type = TxIrq; break;
mbed_official 46:bebbbd80dd87 204 case 2: irq_type = RxIrq; break;
mbed_official 46:bebbbd80dd87 205 default: return;
mbed_official 46:bebbbd80dd87 206 }
mbed_official 46:bebbbd80dd87 207
mbed_official 46:bebbbd80dd87 208 if (serial_irq_ids[index] != 0)
mbed_official 46:bebbbd80dd87 209 irq_handler(serial_irq_ids[index], irq_type);
mbed_official 46:bebbbd80dd87 210 }
mbed_official 46:bebbbd80dd87 211
mbed_official 46:bebbbd80dd87 212 void uart0_irq() {uart_irq((LPC_USART0->STAT & (1 << 2)) ? 2 : 1, 0);}
mbed_official 46:bebbbd80dd87 213 void uart1_irq() {uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 1);}
mbed_official 46:bebbbd80dd87 214 void uart2_irq() {uart_irq((LPC_USART2->STAT & (1 << 2)) ? 2 : 1, 2);}
mbed_official 46:bebbbd80dd87 215
mbed_official 46:bebbbd80dd87 216 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
mbed_official 46:bebbbd80dd87 217 irq_handler = handler;
mbed_official 46:bebbbd80dd87 218 serial_irq_ids[obj->index] = id;
mbed_official 46:bebbbd80dd87 219 }
mbed_official 46:bebbbd80dd87 220
mbed_official 46:bebbbd80dd87 221 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
mbed_official 46:bebbbd80dd87 222 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 46:bebbbd80dd87 223 uint32_t vector = 0;
mbed_official 46:bebbbd80dd87 224 switch ((int)obj->uart) {
mbed_official 46:bebbbd80dd87 225 case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
mbed_official 46:bebbbd80dd87 226 case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
mbed_official 46:bebbbd80dd87 227 case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
mbed_official 46:bebbbd80dd87 228 }
mbed_official 46:bebbbd80dd87 229
mbed_official 46:bebbbd80dd87 230 if (enable) {
mbed_official 46:bebbbd80dd87 231 obj->uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2));
mbed_official 46:bebbbd80dd87 232 NVIC_SetVector(irq_n, vector);
mbed_official 46:bebbbd80dd87 233 NVIC_EnableIRQ(irq_n);
mbed_official 46:bebbbd80dd87 234 } else { // disable
mbed_official 46:bebbbd80dd87 235 int all_disabled = 0;
mbed_official 46:bebbbd80dd87 236 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
mbed_official 46:bebbbd80dd87 237 obj->uart->INTENSET &= ~(1 << ((irq == RxIrq) ? 0 : 2));
mbed_official 46:bebbbd80dd87 238 all_disabled = (obj->uart->INTENSET & (1 << ((other_irq == RxIrq) ? 0 : 2))) == 0;
mbed_official 46:bebbbd80dd87 239 if (all_disabled)
mbed_official 46:bebbbd80dd87 240 NVIC_DisableIRQ(irq_n);
mbed_official 46:bebbbd80dd87 241 }
mbed_official 46:bebbbd80dd87 242 }
mbed_official 46:bebbbd80dd87 243
mbed_official 46:bebbbd80dd87 244 /******************************************************************************
mbed_official 46:bebbbd80dd87 245 * READ/WRITE
mbed_official 46:bebbbd80dd87 246 ******************************************************************************/
mbed_official 46:bebbbd80dd87 247 int serial_getc(serial_t *obj) {
mbed_official 46:bebbbd80dd87 248 while (!serial_readable(obj));
mbed_official 46:bebbbd80dd87 249 return obj->uart->RXDATA;
mbed_official 46:bebbbd80dd87 250 }
mbed_official 46:bebbbd80dd87 251
mbed_official 46:bebbbd80dd87 252 void serial_putc(serial_t *obj, int c) {
mbed_official 46:bebbbd80dd87 253 while (!serial_writable(obj));
mbed_official 46:bebbbd80dd87 254 obj->uart->TXDATA = c;
mbed_official 46:bebbbd80dd87 255 }
mbed_official 46:bebbbd80dd87 256
mbed_official 46:bebbbd80dd87 257 int serial_readable(serial_t *obj) {
mbed_official 46:bebbbd80dd87 258 return obj->uart->STAT & RXRDY;
mbed_official 46:bebbbd80dd87 259 }
mbed_official 46:bebbbd80dd87 260
mbed_official 46:bebbbd80dd87 261 int serial_writable(serial_t *obj) {
mbed_official 46:bebbbd80dd87 262 return obj->uart->STAT & TXRDY;
mbed_official 46:bebbbd80dd87 263 }
mbed_official 46:bebbbd80dd87 264
mbed_official 46:bebbbd80dd87 265 void serial_clear(serial_t *obj) {
mbed_official 46:bebbbd80dd87 266 // [TODO]
mbed_official 46:bebbbd80dd87 267 }
mbed_official 46:bebbbd80dd87 268
mbed_official 46:bebbbd80dd87 269 void serial_pinout_tx(PinName tx) {
mbed_official 46:bebbbd80dd87 270
mbed_official 46:bebbbd80dd87 271 }
mbed_official 46:bebbbd80dd87 272
mbed_official 46:bebbbd80dd87 273 void serial_break_set(serial_t *obj) {
mbed_official 46:bebbbd80dd87 274 obj->uart->CTRL |= TXBRKEN;
mbed_official 46:bebbbd80dd87 275 }
mbed_official 46:bebbbd80dd87 276
mbed_official 46:bebbbd80dd87 277 void serial_break_clear(serial_t *obj) {
mbed_official 46:bebbbd80dd87 278 obj->uart->CTRL &= ~TXBRKEN;
mbed_official 46:bebbbd80dd87 279 }
mbed_official 46:bebbbd80dd87 280