mbed library sources

Dependents:   FRDM-KL46Z_LCD_Test FRDM-KL46Z_LCD_Test FRDM-KL46Z_Plantilla FRDM-KL46Z_Plantilla ... more

Committer:
ebrus
Date:
Thu Jul 28 15:56:34 2016 +0000
Revision:
0:6bc4ac881c8e
1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ebrus 0:6bc4ac881c8e 1 /* mbed Microcontroller Library
ebrus 0:6bc4ac881c8e 2 * Copyright (c) 2006-2013 ARM Limited
ebrus 0:6bc4ac881c8e 3 *
ebrus 0:6bc4ac881c8e 4 * Licensed under the Apache License, Version 2.0 (the "License");
ebrus 0:6bc4ac881c8e 5 * you may not use this file except in compliance with the License.
ebrus 0:6bc4ac881c8e 6 * You may obtain a copy of the License at
ebrus 0:6bc4ac881c8e 7 *
ebrus 0:6bc4ac881c8e 8 * http://www.apache.org/licenses/LICENSE-2.0
ebrus 0:6bc4ac881c8e 9 *
ebrus 0:6bc4ac881c8e 10 * Unless required by applicable law or agreed to in writing, software
ebrus 0:6bc4ac881c8e 11 * distributed under the License is distributed on an "AS IS" BASIS,
ebrus 0:6bc4ac881c8e 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ebrus 0:6bc4ac881c8e 13 * See the License for the specific language governing permissions and
ebrus 0:6bc4ac881c8e 14 * limitations under the License.
ebrus 0:6bc4ac881c8e 15 */
ebrus 0:6bc4ac881c8e 16 #include "serial_api.h"
ebrus 0:6bc4ac881c8e 17
ebrus 0:6bc4ac881c8e 18 #if DEVICE_SERIAL
ebrus 0:6bc4ac881c8e 19
ebrus 0:6bc4ac881c8e 20 // math.h required for floating point operations for baud rate calculation
ebrus 0:6bc4ac881c8e 21 #include <math.h>
ebrus 0:6bc4ac881c8e 22 #include "mbed_assert.h"
ebrus 0:6bc4ac881c8e 23
ebrus 0:6bc4ac881c8e 24 #include <string.h>
ebrus 0:6bc4ac881c8e 25
ebrus 0:6bc4ac881c8e 26 #include "cmsis.h"
ebrus 0:6bc4ac881c8e 27 #include "pinmap.h"
ebrus 0:6bc4ac881c8e 28 #include "fsl_uart_hal.h"
ebrus 0:6bc4ac881c8e 29 #include "fsl_clock_manager.h"
ebrus 0:6bc4ac881c8e 30 #include "fsl_uart_features.h"
ebrus 0:6bc4ac881c8e 31 #include "PeripheralPins.h"
ebrus 0:6bc4ac881c8e 32
ebrus 0:6bc4ac881c8e 33 /* TODO:
ebrus 0:6bc4ac881c8e 34 putchar/getchar 9 and 10 bits support
ebrus 0:6bc4ac881c8e 35 */
ebrus 0:6bc4ac881c8e 36 #ifndef UART3_BASE
ebrus 0:6bc4ac881c8e 37 #define UART_NUM 3
ebrus 0:6bc4ac881c8e 38 #else
ebrus 0:6bc4ac881c8e 39 #define UART_NUM 5
ebrus 0:6bc4ac881c8e 40 #endif
ebrus 0:6bc4ac881c8e 41
ebrus 0:6bc4ac881c8e 42 static uint32_t serial_irq_ids[UART_NUM] = {0};
ebrus 0:6bc4ac881c8e 43 static uart_irq_handler irq_handler;
ebrus 0:6bc4ac881c8e 44
ebrus 0:6bc4ac881c8e 45 int stdio_uart_inited = 0;
ebrus 0:6bc4ac881c8e 46 serial_t stdio_uart;
ebrus 0:6bc4ac881c8e 47
ebrus 0:6bc4ac881c8e 48 void serial_init(serial_t *obj, PinName tx, PinName rx) {
ebrus 0:6bc4ac881c8e 49 uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
ebrus 0:6bc4ac881c8e 50 uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
ebrus 0:6bc4ac881c8e 51 obj->index = pinmap_merge(uart_tx, uart_rx);
ebrus 0:6bc4ac881c8e 52 MBED_ASSERT((int)obj->index != NC);
ebrus 0:6bc4ac881c8e 53
ebrus 0:6bc4ac881c8e 54 uint32_t uartSourceClock = CLOCK_SYS_GetUartFreq(obj->index);
ebrus 0:6bc4ac881c8e 55
ebrus 0:6bc4ac881c8e 56 CLOCK_SYS_EnableUartClock(obj->index);
ebrus 0:6bc4ac881c8e 57 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 58 UART_HAL_Init(uart_addrs[obj->index]);
ebrus 0:6bc4ac881c8e 59 UART_HAL_SetBaudRate(uart_addrs[obj->index], uartSourceClock, 9600);
ebrus 0:6bc4ac881c8e 60 UART_HAL_SetParityMode(uart_addrs[obj->index], kUartParityDisabled);
ebrus 0:6bc4ac881c8e 61 #if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
ebrus 0:6bc4ac881c8e 62 UART_HAL_SetStopBitCount(uart_addrs[obj->index], kUartOneStopBit);
ebrus 0:6bc4ac881c8e 63 #endif
ebrus 0:6bc4ac881c8e 64 UART_HAL_SetBitCountPerChar(uart_addrs[obj->index], kUart8BitsPerChar);
ebrus 0:6bc4ac881c8e 65 UART_HAL_EnableTransmitter(uart_addrs[obj->index]);
ebrus 0:6bc4ac881c8e 66 UART_HAL_EnableReceiver(uart_addrs[obj->index]);
ebrus 0:6bc4ac881c8e 67
ebrus 0:6bc4ac881c8e 68 pinmap_pinout(tx, PinMap_UART_TX);
ebrus 0:6bc4ac881c8e 69 pinmap_pinout(rx, PinMap_UART_RX);
ebrus 0:6bc4ac881c8e 70
ebrus 0:6bc4ac881c8e 71 pin_mode(tx, PullUp);
ebrus 0:6bc4ac881c8e 72 pin_mode(rx, PullUp);
ebrus 0:6bc4ac881c8e 73
ebrus 0:6bc4ac881c8e 74 if (obj->index == STDIO_UART) {
ebrus 0:6bc4ac881c8e 75 stdio_uart_inited = 1;
ebrus 0:6bc4ac881c8e 76 memcpy(&stdio_uart, obj, sizeof(serial_t));
ebrus 0:6bc4ac881c8e 77 }
ebrus 0:6bc4ac881c8e 78 }
ebrus 0:6bc4ac881c8e 79
ebrus 0:6bc4ac881c8e 80 void serial_free(serial_t *obj) {
ebrus 0:6bc4ac881c8e 81 serial_irq_ids[obj->index] = 0;
ebrus 0:6bc4ac881c8e 82 }
ebrus 0:6bc4ac881c8e 83
ebrus 0:6bc4ac881c8e 84 void serial_baud(serial_t *obj, int baudrate) {
ebrus 0:6bc4ac881c8e 85 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 86 UART_HAL_SetBaudRate(uart_addrs[obj->index], CLOCK_SYS_GetUartFreq(obj->index), (uint32_t)baudrate);
ebrus 0:6bc4ac881c8e 87 }
ebrus 0:6bc4ac881c8e 88
ebrus 0:6bc4ac881c8e 89 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
ebrus 0:6bc4ac881c8e 90 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 91 UART_HAL_SetBitCountPerChar(uart_addrs[obj->index], (uart_bit_count_per_char_t)data_bits);
ebrus 0:6bc4ac881c8e 92 UART_HAL_SetParityMode(uart_addrs[obj->index], (uart_parity_mode_t)parity);
ebrus 0:6bc4ac881c8e 93 #if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
ebrus 0:6bc4ac881c8e 94 UART_HAL_SetStopBitCount(uart_addrs[obj->index], (uart_stop_bit_count_t)stop_bits);
ebrus 0:6bc4ac881c8e 95 #endif
ebrus 0:6bc4ac881c8e 96 }
ebrus 0:6bc4ac881c8e 97
ebrus 0:6bc4ac881c8e 98 /******************************************************************************
ebrus 0:6bc4ac881c8e 99 * INTERRUPTS HANDLING
ebrus 0:6bc4ac881c8e 100 ******************************************************************************/
ebrus 0:6bc4ac881c8e 101 static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index) {
ebrus 0:6bc4ac881c8e 102 if (serial_irq_ids[index] != 0) {
ebrus 0:6bc4ac881c8e 103 if (transmit_empty)
ebrus 0:6bc4ac881c8e 104 irq_handler(serial_irq_ids[index], TxIrq);
ebrus 0:6bc4ac881c8e 105
ebrus 0:6bc4ac881c8e 106 if (receive_full)
ebrus 0:6bc4ac881c8e 107 irq_handler(serial_irq_ids[index], RxIrq);
ebrus 0:6bc4ac881c8e 108 }
ebrus 0:6bc4ac881c8e 109 }
ebrus 0:6bc4ac881c8e 110
ebrus 0:6bc4ac881c8e 111 void uart0_irq() {
ebrus 0:6bc4ac881c8e 112 uart_irq(UART_HAL_IsTxDataRegEmpty(UART0_BASE), UART_HAL_IsRxDataRegFull(UART0_BASE), 0);
ebrus 0:6bc4ac881c8e 113 if (UART_HAL_GetStatusFlag(UART0_BASE, kUartRxOverrun))
ebrus 0:6bc4ac881c8e 114 UART_HAL_ClearStatusFlag(UART0_BASE, kUartRxOverrun);
ebrus 0:6bc4ac881c8e 115 }
ebrus 0:6bc4ac881c8e 116 void uart1_irq() {
ebrus 0:6bc4ac881c8e 117 uart_irq(UART_HAL_IsTxDataRegEmpty(UART1_BASE), UART_HAL_IsRxDataRegFull(UART1_BASE), 1);
ebrus 0:6bc4ac881c8e 118 }
ebrus 0:6bc4ac881c8e 119
ebrus 0:6bc4ac881c8e 120 void uart2_irq() {
ebrus 0:6bc4ac881c8e 121 uart_irq(UART_HAL_IsTxDataRegEmpty(UART2_BASE), UART_HAL_IsRxDataRegFull(UART2_BASE), 2);
ebrus 0:6bc4ac881c8e 122 }
ebrus 0:6bc4ac881c8e 123
ebrus 0:6bc4ac881c8e 124 #if (UART_NUM > 3)
ebrus 0:6bc4ac881c8e 125
ebrus 0:6bc4ac881c8e 126 void uart3_irq() {
ebrus 0:6bc4ac881c8e 127 uart_irq(UART_HAL_IsTxDataRegEmpty(UART3_BASE), UART_HAL_IsRxDataRegFull(UART3_BASE), 3);
ebrus 0:6bc4ac881c8e 128 }
ebrus 0:6bc4ac881c8e 129
ebrus 0:6bc4ac881c8e 130 void uart4_irq() {
ebrus 0:6bc4ac881c8e 131 uart_irq(UART_HAL_IsTxDataRegEmpty(UART4_BASE), UART_HAL_IsRxDataRegFull(UART4_BASE), 4);
ebrus 0:6bc4ac881c8e 132 }
ebrus 0:6bc4ac881c8e 133 #endif
ebrus 0:6bc4ac881c8e 134
ebrus 0:6bc4ac881c8e 135 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
ebrus 0:6bc4ac881c8e 136 irq_handler = handler;
ebrus 0:6bc4ac881c8e 137 serial_irq_ids[obj->index] = id;
ebrus 0:6bc4ac881c8e 138 }
ebrus 0:6bc4ac881c8e 139
ebrus 0:6bc4ac881c8e 140 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
ebrus 0:6bc4ac881c8e 141 IRQn_Type irq_n = (IRQn_Type)0;
ebrus 0:6bc4ac881c8e 142 uint32_t vector = 0;
ebrus 0:6bc4ac881c8e 143
ebrus 0:6bc4ac881c8e 144 switch (obj->index) {
ebrus 0:6bc4ac881c8e 145 case 0: irq_n=UART0_RX_TX_IRQn; vector = (uint32_t)&uart0_irq; break;
ebrus 0:6bc4ac881c8e 146 case 1: irq_n=UART1_RX_TX_IRQn; vector = (uint32_t)&uart1_irq; break;
ebrus 0:6bc4ac881c8e 147 case 2: irq_n=UART2_RX_TX_IRQn; vector = (uint32_t)&uart2_irq; break;
ebrus 0:6bc4ac881c8e 148 #if (NUM_UART > 3)
ebrus 0:6bc4ac881c8e 149 case 3: irq_n=UART3_RX_TX_IRQn; vector = (uint32_t)&uart3_irq; break;
ebrus 0:6bc4ac881c8e 150 case 4: irq_n=UART4_RX_TX_IRQn; vector = (uint32_t)&uart4_irq; break;
ebrus 0:6bc4ac881c8e 151 #endif
ebrus 0:6bc4ac881c8e 152 }
ebrus 0:6bc4ac881c8e 153 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 154 if (enable) {
ebrus 0:6bc4ac881c8e 155 switch (irq) {
ebrus 0:6bc4ac881c8e 156 case RxIrq: UART_HAL_SetRxDataRegFullIntCmd(uart_addrs[obj->index], true); break;
ebrus 0:6bc4ac881c8e 157 case TxIrq: UART_HAL_SetTxDataRegEmptyIntCmd(uart_addrs[obj->index], true); break;
ebrus 0:6bc4ac881c8e 158 }
ebrus 0:6bc4ac881c8e 159 NVIC_SetVector(irq_n, vector);
ebrus 0:6bc4ac881c8e 160 NVIC_EnableIRQ(irq_n);
ebrus 0:6bc4ac881c8e 161
ebrus 0:6bc4ac881c8e 162 } else { // disable
ebrus 0:6bc4ac881c8e 163 int all_disabled = 0;
ebrus 0:6bc4ac881c8e 164 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
ebrus 0:6bc4ac881c8e 165 switch (irq) {
ebrus 0:6bc4ac881c8e 166 case RxIrq: UART_HAL_SetRxDataRegFullIntCmd(uart_addrs[obj->index], false); break;
ebrus 0:6bc4ac881c8e 167 case TxIrq: UART_HAL_SetTxDataRegEmptyIntCmd(uart_addrs[obj->index], false); break;
ebrus 0:6bc4ac881c8e 168 }
ebrus 0:6bc4ac881c8e 169 switch (other_irq) {
ebrus 0:6bc4ac881c8e 170 case RxIrq: all_disabled = UART_HAL_GetRxDataRegFullIntCmd(uart_addrs[obj->index]) == 0; break;
ebrus 0:6bc4ac881c8e 171 case TxIrq: all_disabled = UART_HAL_GetTxDataRegEmptyIntCmd(uart_addrs[obj->index]) == 0; break;
ebrus 0:6bc4ac881c8e 172 }
ebrus 0:6bc4ac881c8e 173 if (all_disabled)
ebrus 0:6bc4ac881c8e 174 NVIC_DisableIRQ(irq_n);
ebrus 0:6bc4ac881c8e 175 }
ebrus 0:6bc4ac881c8e 176 }
ebrus 0:6bc4ac881c8e 177
ebrus 0:6bc4ac881c8e 178 int serial_getc(serial_t *obj) {
ebrus 0:6bc4ac881c8e 179 while (!serial_readable(obj));
ebrus 0:6bc4ac881c8e 180 uint8_t data;
ebrus 0:6bc4ac881c8e 181 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 182 UART_HAL_Getchar(uart_addrs[obj->index], &data);
ebrus 0:6bc4ac881c8e 183
ebrus 0:6bc4ac881c8e 184 return data;
ebrus 0:6bc4ac881c8e 185 }
ebrus 0:6bc4ac881c8e 186
ebrus 0:6bc4ac881c8e 187 void serial_putc(serial_t *obj, int c) {
ebrus 0:6bc4ac881c8e 188 while (!serial_writable(obj));
ebrus 0:6bc4ac881c8e 189 uint32_t uart_addrs[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 190 UART_HAL_Putchar(uart_addrs[obj->index], (uint8_t)c);
ebrus 0:6bc4ac881c8e 191 }
ebrus 0:6bc4ac881c8e 192
ebrus 0:6bc4ac881c8e 193 int serial_readable(serial_t *obj) {
ebrus 0:6bc4ac881c8e 194 uint32_t uart_address[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 195 if (UART_HAL_GetStatusFlag(uart_address[obj->index], kUartRxOverrun))
ebrus 0:6bc4ac881c8e 196 UART_HAL_ClearStatusFlag(uart_address[obj->index], kUartRxOverrun);
ebrus 0:6bc4ac881c8e 197 return UART_HAL_IsRxDataRegFull(uart_address[obj->index]);
ebrus 0:6bc4ac881c8e 198 }
ebrus 0:6bc4ac881c8e 199
ebrus 0:6bc4ac881c8e 200 int serial_writable(serial_t *obj) {
ebrus 0:6bc4ac881c8e 201 uint32_t uart_address[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 202 if (UART_HAL_GetStatusFlag(uart_address[obj->index], kUartRxOverrun))
ebrus 0:6bc4ac881c8e 203 UART_HAL_ClearStatusFlag(uart_address[obj->index], kUartRxOverrun);
ebrus 0:6bc4ac881c8e 204
ebrus 0:6bc4ac881c8e 205 return UART_HAL_IsTxDataRegEmpty(uart_address[obj->index]);
ebrus 0:6bc4ac881c8e 206 }
ebrus 0:6bc4ac881c8e 207
ebrus 0:6bc4ac881c8e 208 void serial_clear(serial_t *obj) {
ebrus 0:6bc4ac881c8e 209 }
ebrus 0:6bc4ac881c8e 210
ebrus 0:6bc4ac881c8e 211 void serial_pinout_tx(PinName tx) {
ebrus 0:6bc4ac881c8e 212 pinmap_pinout(tx, PinMap_UART_TX);
ebrus 0:6bc4ac881c8e 213 }
ebrus 0:6bc4ac881c8e 214
ebrus 0:6bc4ac881c8e 215 void serial_break_set(serial_t *obj) {
ebrus 0:6bc4ac881c8e 216 uint32_t uart_address[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 217 UART_HAL_SetBreakCharCmd(uart_address[obj->index], true);
ebrus 0:6bc4ac881c8e 218 }
ebrus 0:6bc4ac881c8e 219
ebrus 0:6bc4ac881c8e 220 void serial_break_clear(serial_t *obj) {
ebrus 0:6bc4ac881c8e 221 uint32_t uart_address[] = UART_BASE_ADDRS;
ebrus 0:6bc4ac881c8e 222 UART_HAL_SetBreakCharCmd(uart_address[obj->index], false);
ebrus 0:6bc4ac881c8e 223 }
ebrus 0:6bc4ac881c8e 224
ebrus 0:6bc4ac881c8e 225 #endif