Mateusz Kowalik / Application_danix

Fork of Application by Daniel Sygut

Committer:
Zaitsev
Date:
Thu Feb 15 14:29:23 2018 +0000
Revision:
15:2a20c3d2616e
Parent:
10:41552d038a69
j

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Zaitsev 10:41552d038a69 1 /**
Zaitsev 10:41552d038a69 2 ******************************************************************************
Zaitsev 10:41552d038a69 3 * @file Serial.c
Zaitsev 10:41552d038a69 4 * @brief Implementation of a 16C550 UART driver
Zaitsev 10:41552d038a69 5 * @internal
Zaitsev 10:41552d038a69 6 * @author ON Semiconductor
Zaitsev 10:41552d038a69 7 * $Rev: 0.1 $
Zaitsev 10:41552d038a69 8 * $Date: 2015-11-04 05:30:00 +0530 (Wed, 04 Nov 2015) $
Zaitsev 10:41552d038a69 9 ******************************************************************************
Zaitsev 10:41552d038a69 10 * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
Zaitsev 10:41552d038a69 11 * All rights reserved. This software and/or documentation is licensed by ON Semiconductor
Zaitsev 10:41552d038a69 12 * under limited terms and conditions. The terms and conditions pertaining to the software
Zaitsev 10:41552d038a69 13 * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
Zaitsev 10:41552d038a69 14 * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
Zaitsev 10:41552d038a69 15 * if applicable the software license agreement. Do not use this software and/or
Zaitsev 10:41552d038a69 16 * documentation unless you have carefully read and you agree to the limited terms and
Zaitsev 10:41552d038a69 17 * conditions. By using this software and/or documentation, you agree to the limited
Zaitsev 10:41552d038a69 18 * terms and conditions.
Zaitsev 10:41552d038a69 19 *
Zaitsev 10:41552d038a69 20 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
Zaitsev 10:41552d038a69 21 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
Zaitsev 10:41552d038a69 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
Zaitsev 10:41552d038a69 23 * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
Zaitsev 10:41552d038a69 24 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
Zaitsev 10:41552d038a69 25 * @endinternal
Zaitsev 10:41552d038a69 26 *
Zaitsev 10:41552d038a69 27 * @ingroup uart_16c550
Zaitsev 10:41552d038a69 28 *
Zaitsev 10:41552d038a69 29 */
Zaitsev 10:41552d038a69 30 #if DEVICE_SERIAL
Zaitsev 10:41552d038a69 31
Zaitsev 10:41552d038a69 32 #include "serial_api.h"
Zaitsev 10:41552d038a69 33
Zaitsev 10:41552d038a69 34 #include "cmsis.h"
Zaitsev 10:41552d038a69 35 #include "pinmap.h"
Zaitsev 10:41552d038a69 36 #include "PeripheralPins.h"
Zaitsev 10:41552d038a69 37
Zaitsev 10:41552d038a69 38 #include "mbed_assert.h"
Zaitsev 10:41552d038a69 39 #include <string.h>
Zaitsev 10:41552d038a69 40 #include "uart_16c550.h"
Zaitsev 10:41552d038a69 41 #include "cmsis_nvic.h"
Zaitsev 10:41552d038a69 42
Zaitsev 10:41552d038a69 43 static IRQn_Type Irq;
Zaitsev 10:41552d038a69 44
Zaitsev 10:41552d038a69 45 uint32_t stdio_uart_inited = 0;
Zaitsev 10:41552d038a69 46 serial_t stdio_uart;
Zaitsev 10:41552d038a69 47
Zaitsev 10:41552d038a69 48 static uint32_t serial_irq_ids[UART_NUM] = {0};
Zaitsev 10:41552d038a69 49 static uart_irq_handler irq_handler;
Zaitsev 10:41552d038a69 50 static inline void uart_irq(uint8_t status, uint32_t index);
Zaitsev 10:41552d038a69 51
Zaitsev 10:41552d038a69 52
Zaitsev 10:41552d038a69 53 /** Opens UART device.
Zaitsev 10:41552d038a69 54 * @details
Zaitsev 10:41552d038a69 55 * Sets the necessary registers. Set to default Baud rate 115200, 8 bit, parity None and stop bit 1.
Zaitsev 10:41552d038a69 56 * The UART interrupt is enabled.
Zaitsev 10:41552d038a69 57 *
Zaitsev 10:41552d038a69 58 * @note The UART transmit interrupt is not enabled, because sending is controlled
Zaitsev 10:41552d038a69 59 * by the task.
Zaitsev 10:41552d038a69 60 *
Zaitsev 10:41552d038a69 61 * @param UartNum A UART device instance.
Zaitsev 10:41552d038a69 62 * @param options The options parameter containing the baud rate.
Zaitsev 10:41552d038a69 63 * @return True if opening was successful.
Zaitsev 10:41552d038a69 64 */
Zaitsev 10:41552d038a69 65
Zaitsev 10:41552d038a69 66 void serial_init(serial_t *obj, PinName tx, PinName rx)
Zaitsev 10:41552d038a69 67 {
Zaitsev 10:41552d038a69 68 uint16_t clockDivisor;
Zaitsev 10:41552d038a69 69
Zaitsev 10:41552d038a69 70 CrossbReg_t *CbRegOffSet;
Zaitsev 10:41552d038a69 71 PadReg_t *PadRegOffset;
Zaitsev 10:41552d038a69 72
Zaitsev 10:41552d038a69 73 //find which peripheral is associated with the rx and tx pins
Zaitsev 10:41552d038a69 74 uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
Zaitsev 10:41552d038a69 75 uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
Zaitsev 10:41552d038a69 76 //check if the peripherals for each pin are the same or not
Zaitsev 10:41552d038a69 77 //returns the enum associated with the peripheral
Zaitsev 10:41552d038a69 78 //in the case of this target, the enum is the base address of the peripheral
Zaitsev 10:41552d038a69 79 obj->UARTREG = (Uart16C550Reg_pt) pinmap_merge(uart_tx, uart_rx);
Zaitsev 10:41552d038a69 80 MBED_ASSERT(obj->UARTREG != (Uart16C550Reg_pt) NC);
Zaitsev 10:41552d038a69 81
Zaitsev 10:41552d038a69 82 pinmap_pinout(tx, PinMap_UART_TX);
Zaitsev 10:41552d038a69 83 pinmap_pinout(rx, PinMap_UART_RX);
Zaitsev 10:41552d038a69 84
Zaitsev 10:41552d038a69 85 /*TODO: Mac Lobdell - we should recommend using the instance method and not using base addresses as index */
Zaitsev 10:41552d038a69 86
Zaitsev 10:41552d038a69 87 if (obj->UARTREG == (Uart16C550Reg_pt)STDIO_UART) {
Zaitsev 10:41552d038a69 88 stdio_uart_inited = 1;
Zaitsev 10:41552d038a69 89 memcpy(&stdio_uart, obj, sizeof(serial_t));
Zaitsev 10:41552d038a69 90 }
Zaitsev 10:41552d038a69 91 /*TODO: determine if pullups are needed/recommended */
Zaitsev 10:41552d038a69 92 /* if (tx != NC) {
Zaitsev 10:41552d038a69 93 pin_mode(tx, PullUp);
Zaitsev 10:41552d038a69 94 }
Zaitsev 10:41552d038a69 95 if (rx != NC) {
Zaitsev 10:41552d038a69 96 pin_mode(rx, PullUp);
Zaitsev 10:41552d038a69 97 }
Zaitsev 10:41552d038a69 98 */
Zaitsev 10:41552d038a69 99 /* Configure IOs to UART using cross bar, pad and GPIO settings */
Zaitsev 10:41552d038a69 100
Zaitsev 10:41552d038a69 101 if(obj->UARTREG == UART2REG) {
Zaitsev 10:41552d038a69 102 /* UART 2 */
Zaitsev 10:41552d038a69 103 CLOCK_ENABLE(CLOCK_UART2);
Zaitsev 10:41552d038a69 104 Irq = Uart2_IRQn;
Zaitsev 10:41552d038a69 105 } else if(obj->UARTREG == UART1REG) {
Zaitsev 10:41552d038a69 106 /* UART 1 */
Zaitsev 10:41552d038a69 107 CLOCK_ENABLE(CLOCK_UART1);
Zaitsev 10:41552d038a69 108
Zaitsev 10:41552d038a69 109 Irq = Uart1_IRQn;
Zaitsev 10:41552d038a69 110 } else {
Zaitsev 10:41552d038a69 111 MBED_ASSERT(False);
Zaitsev 10:41552d038a69 112 }
Zaitsev 10:41552d038a69 113
Zaitsev 10:41552d038a69 114 CLOCK_ENABLE(CLOCK_GPIO);
Zaitsev 10:41552d038a69 115 CLOCK_ENABLE(CLOCK_CROSSB);
Zaitsev 10:41552d038a69 116 CLOCK_ENABLE(CLOCK_PAD);
Zaitsev 10:41552d038a69 117
Zaitsev 10:41552d038a69 118 /*TODO: determine if tx and rx are used correctly in this case - this depends on the pin enum matching the position in the crossbar*/
Zaitsev 10:41552d038a69 119
Zaitsev 10:41552d038a69 120 /* Configure tx pin as UART */
Zaitsev 10:41552d038a69 121 CbRegOffSet = (CrossbReg_t*)(CROSSBREG_BASE + (tx * CROSS_REG_ADRS_BYTE_SIZE));
Zaitsev 10:41552d038a69 122 CbRegOffSet->DIOCTRL0 = CONFIGURE_AS_UART; /* tx pin as UART */
Zaitsev 10:41552d038a69 123
Zaitsev 10:41552d038a69 124 /* Configure rx pin as UART */
Zaitsev 10:41552d038a69 125 CbRegOffSet = (CrossbReg_t*)(CROSSBREG_BASE + (rx * CROSS_REG_ADRS_BYTE_SIZE));
Zaitsev 10:41552d038a69 126 CbRegOffSet->DIOCTRL0 = CONFIGURE_AS_UART; /* rx pin as UART */
Zaitsev 10:41552d038a69 127
Zaitsev 10:41552d038a69 128 /** - Set pad parameters, output drive strength, pull piece control, output drive type */
Zaitsev 10:41552d038a69 129 PadRegOffset = (PadReg_t*)(PADREG_BASE + (tx * PAD_REG_ADRS_BYTE_SIZE));
Zaitsev 10:41552d038a69 130 PadRegOffset->PADIO0.WORD = PAD_UART_TX; /* Pad setting for UART Tx */
Zaitsev 10:41552d038a69 131
Zaitsev 10:41552d038a69 132 PadRegOffset = (PadReg_t*)(PADREG_BASE + (rx * PAD_REG_ADRS_BYTE_SIZE));
Zaitsev 10:41552d038a69 133 PadRegOffset->PADIO0.WORD = PAD_UART_RX; /* Pad settings for UART Rx */
Zaitsev 10:41552d038a69 134
Zaitsev 10:41552d038a69 135 GPIOREG->W_OUT = (0x1 << tx); /* tx as OUT direction */
Zaitsev 10:41552d038a69 136 GPIOREG->W_IN = (0x1 << rx); /* rx as IN directon */
Zaitsev 10:41552d038a69 137
Zaitsev 10:41552d038a69 138 CLOCK_DISABLE(CLOCK_PAD);
Zaitsev 10:41552d038a69 139 CLOCK_DISABLE(CLOCK_CROSSB);
Zaitsev 10:41552d038a69 140 CLOCK_DISABLE(CLOCK_GPIO);
Zaitsev 10:41552d038a69 141
Zaitsev 10:41552d038a69 142 /* Set the divisor value. To do so, LCR[7] needs to be set to 1 in order to access the divisor registers.
Zaitsev 10:41552d038a69 143 * The right-shift of 4 is a division of 16, representing the oversampling rate. */
Zaitsev 10:41552d038a69 144 clockDivisor = (fClockGetPeriphClockfrequency() / UART_DEFAULT_BAUD) >> 4;
Zaitsev 10:41552d038a69 145 obj->UARTREG->LCR.WORD = 0x80;
Zaitsev 10:41552d038a69 146 obj->UARTREG->DLL = clockDivisor & 0xFF;
Zaitsev 10:41552d038a69 147 obj->UARTREG->DLM = clockDivisor >> 8;
Zaitsev 10:41552d038a69 148
Zaitsev 10:41552d038a69 149 /* Set the character width to 8 data bits, no parity, 1 stop bit. Write the entire line control register,
Zaitsev 10:41552d038a69 150 * effectively disabling the divisor latch. */
Zaitsev 10:41552d038a69 151 obj->UARTREG->LCR.WORD = 0x03;
Zaitsev 10:41552d038a69 152
Zaitsev 10:41552d038a69 153 /* Enable the FIFOs, reset the Tx and Rx FIFOs, set the Rx FIFO trigger level to 8 bytes, and set DMA Mode
Zaitsev 10:41552d038a69 154 to 1. */
Zaitsev 10:41552d038a69 155 obj->UARTREG->FCR.WORD = (FCR_RXFIFOTRIGGERLEVEL_8 | FCR_DMA_MODE_1 |
Zaitsev 10:41552d038a69 156 FCR_TXFIFO_RESET | FCR_RXFIFO_RESET | FCR_FIFO_ENABLE);
Zaitsev 10:41552d038a69 157
Zaitsev 10:41552d038a69 158 /* Make a copy of the current MSR to the SCR register. This is used from task space to determine the
Zaitsev 10:41552d038a69 159 * flow control state. */
Zaitsev 10:41552d038a69 160 obj->UARTREG->SCR = obj->UARTREG->MSR.WORD;
Zaitsev 10:41552d038a69 161
Zaitsev 10:41552d038a69 162 if((int)obj->UARTREG == STDIO_UART) {
Zaitsev 10:41552d038a69 163 stdio_uart_inited = 1;
Zaitsev 10:41552d038a69 164 memcpy(&stdio_uart, obj, sizeof(serial_t));
Zaitsev 10:41552d038a69 165 }
Zaitsev 10:41552d038a69 166
Zaitsev 10:41552d038a69 167 NVIC_ClearPendingIRQ(Irq);
Zaitsev 10:41552d038a69 168
Zaitsev 10:41552d038a69 169 return;
Zaitsev 10:41552d038a69 170 }
Zaitsev 10:41552d038a69 171
Zaitsev 10:41552d038a69 172 /** Closes a UART device.
Zaitsev 10:41552d038a69 173 * @details
Zaitsev 10:41552d038a69 174 * Disables the UART interrupt.
Zaitsev 10:41552d038a69 175 *
Zaitsev 10:41552d038a69 176 * @param device The UART device to close.
Zaitsev 10:41552d038a69 177 */
Zaitsev 10:41552d038a69 178 void serial_free(serial_t *obj)
Zaitsev 10:41552d038a69 179 {
Zaitsev 10:41552d038a69 180 NVIC_DisableIRQ(obj->IRQType);
Zaitsev 10:41552d038a69 181 }
Zaitsev 10:41552d038a69 182
Zaitsev 10:41552d038a69 183 void serial_baud(serial_t *obj, int baudrate)
Zaitsev 10:41552d038a69 184 {
Zaitsev 10:41552d038a69 185 /* Set the divisor value. To do so, LCR[7] needs to be set to 1 in order to access the divisor registers.
Zaitsev 10:41552d038a69 186 * The right-shift of 4 is a division of 16, representing the oversampling rate. */
Zaitsev 10:41552d038a69 187 uint16_t clockDivisor = (fClockGetPeriphClockfrequency() / baudrate) >> 4;
Zaitsev 10:41552d038a69 188
Zaitsev 10:41552d038a69 189 obj->UARTREG->LCR.BITS.DLAB = True;
Zaitsev 10:41552d038a69 190 obj->UARTREG->DLL = clockDivisor & 0xFF;
Zaitsev 10:41552d038a69 191 obj->UARTREG->DLM = clockDivisor >> 8;
Zaitsev 10:41552d038a69 192 obj->UARTREG->LCR.BITS.DLAB = False;
Zaitsev 10:41552d038a69 193 }
Zaitsev 10:41552d038a69 194
Zaitsev 10:41552d038a69 195 /*
Zaitsev 10:41552d038a69 196 Parity XX0 – Parity disabled; 001 – Odd Parity; 011 – Even Parity; 101 – Stick Parity, checked as 1; 111 – Stick Parity, checked as 0.
Zaitsev 10:41552d038a69 197 StopBit 0 – 1 stop bit; 1 – 2 stop bits.
Zaitsev 10:41552d038a69 198 DataLen 00 – 5 bits; 01 – 6 bits; 10 – 7 bits; 11 – 8 bits
Zaitsev 10:41552d038a69 199 */
Zaitsev 10:41552d038a69 200 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
Zaitsev 10:41552d038a69 201 {
Zaitsev 10:41552d038a69 202 if(data_bits >= 5 && data_bits <= 8 && parity <= 7 && stop_bits >= 1 && stop_bits <= 2) {
Zaitsev 10:41552d038a69 203 if(parity == (SerialParity)0) {
Zaitsev 10:41552d038a69 204 parity = (SerialParity)0;
Zaitsev 10:41552d038a69 205 } else {
Zaitsev 10:41552d038a69 206 parity = (SerialParity)(parity + parity - 1) ;
Zaitsev 10:41552d038a69 207 }
Zaitsev 10:41552d038a69 208
Zaitsev 10:41552d038a69 209 obj->UARTREG->LCR.WORD |= ((((data_bits - 5) << UART_LCR_DATALEN_BIT_POS) |
Zaitsev 10:41552d038a69 210 (parity << UART_LCR_PARITY_BIT_POS) |
Zaitsev 10:41552d038a69 211 ((stop_bits - 1) << UART_LCR_STPBIT_BIT_POS)) & 0x3F);
Zaitsev 10:41552d038a69 212 } else {
Zaitsev 10:41552d038a69 213 MBED_ASSERT(False);
Zaitsev 10:41552d038a69 214 }
Zaitsev 10:41552d038a69 215 }
Zaitsev 10:41552d038a69 216
Zaitsev 10:41552d038a69 217 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
Zaitsev 10:41552d038a69 218 {
Zaitsev 10:41552d038a69 219 irq_handler = handler;
Zaitsev 10:41552d038a69 220 serial_irq_ids[obj->index] = id;
Zaitsev 10:41552d038a69 221 }
Zaitsev 10:41552d038a69 222
Zaitsev 10:41552d038a69 223 /******************************************************
Zaitsev 10:41552d038a69 224 ************* Internal IRQ functions ******************
Zaitsev 10:41552d038a69 225 *******************************************************/
Zaitsev 10:41552d038a69 226 void Uart1_Irq()
Zaitsev 10:41552d038a69 227 {
Zaitsev 10:41552d038a69 228 uint8_t active_irq = (uint8_t)(UART1REG->LSR.WORD) & 0xFF;
Zaitsev 10:41552d038a69 229 uint8_t irq_mask = 0;
Zaitsev 10:41552d038a69 230
Zaitsev 10:41552d038a69 231 if(UART1REG->IER.WORD & UART_IER_TX_EMPTY_MASK) { /*check if TX interrupt is enabled*/
Zaitsev 10:41552d038a69 232 irq_mask |= active_irq & UART_LSR_TX_EMPTY_MASK;
Zaitsev 10:41552d038a69 233 }
Zaitsev 10:41552d038a69 234
Zaitsev 10:41552d038a69 235 if(UART1REG->IER.WORD & UART_IER_RX_DATA_READY_MASK) { /*check if RX interrupt is enabled*/
Zaitsev 10:41552d038a69 236 irq_mask |= active_irq & UART_LSR_RX_DATA_READY_MASK;
Zaitsev 10:41552d038a69 237 }
Zaitsev 10:41552d038a69 238
Zaitsev 10:41552d038a69 239 //uart_irq((uint8_t)(UART1REG->LSR.WORD & 0xFF), 0);
Zaitsev 10:41552d038a69 240 uart_irq(active_irq & irq_mask, 0);
Zaitsev 10:41552d038a69 241 }
Zaitsev 10:41552d038a69 242
Zaitsev 10:41552d038a69 243 void Uart2_Irq()
Zaitsev 10:41552d038a69 244 {
Zaitsev 10:41552d038a69 245 uint8_t active_irq = (uint8_t)(UART2REG->LSR.WORD) & 0xFF;
Zaitsev 10:41552d038a69 246 uint8_t irq_mask = 0;
Zaitsev 10:41552d038a69 247
Zaitsev 10:41552d038a69 248 if(UART2REG->IER.WORD & UART_IER_TX_EMPTY_MASK) { /*check if TX interrupt is enabled*/
Zaitsev 10:41552d038a69 249 irq_mask |= active_irq & UART_LSR_TX_EMPTY_MASK;
Zaitsev 10:41552d038a69 250 }
Zaitsev 10:41552d038a69 251
Zaitsev 10:41552d038a69 252 if(UART2REG->IER.WORD & UART_IER_RX_DATA_READY_MASK) { /*check if RX interrupt is enabled*/
Zaitsev 10:41552d038a69 253 irq_mask |= active_irq & UART_LSR_RX_DATA_READY_MASK;
Zaitsev 10:41552d038a69 254 }
Zaitsev 10:41552d038a69 255
Zaitsev 10:41552d038a69 256 //uart_irq((uint8_t)(UART2REG->LSR.WORD & 0xFF), 1);
Zaitsev 10:41552d038a69 257 uart_irq(active_irq & irq_mask, 1);
Zaitsev 10:41552d038a69 258
Zaitsev 10:41552d038a69 259 }
Zaitsev 10:41552d038a69 260
Zaitsev 10:41552d038a69 261 static inline void uart_irq(uint8_t status, uint32_t index)
Zaitsev 10:41552d038a69 262 {
Zaitsev 10:41552d038a69 263 if (serial_irq_ids[index] != 0) {
Zaitsev 10:41552d038a69 264 if (status & UART_LSR_TX_EMPTY_MASK) {
Zaitsev 10:41552d038a69 265 irq_handler(serial_irq_ids[index], TxIrq);
Zaitsev 10:41552d038a69 266 }
Zaitsev 10:41552d038a69 267 if (status & UART_LSR_RX_DATA_READY_MASK) {
Zaitsev 10:41552d038a69 268 irq_handler(serial_irq_ids[index], RxIrq);
Zaitsev 10:41552d038a69 269 }
Zaitsev 10:41552d038a69 270 }
Zaitsev 10:41552d038a69 271 }
Zaitsev 10:41552d038a69 272 /******************************************************/
Zaitsev 10:41552d038a69 273
Zaitsev 10:41552d038a69 274 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
Zaitsev 10:41552d038a69 275 {
Zaitsev 10:41552d038a69 276 IRQn_Type irq_n = (IRQn_Type)0;
Zaitsev 10:41552d038a69 277 uint32_t Vector = 0;
Zaitsev 10:41552d038a69 278
Zaitsev 10:41552d038a69 279 /* Check UART number & assign irq handler */
Zaitsev 10:41552d038a69 280 if(obj->UARTREG == UART1REG) {
Zaitsev 10:41552d038a69 281 /* UART 2 */
Zaitsev 10:41552d038a69 282 Vector = (uint32_t)&Uart1_Irq;
Zaitsev 10:41552d038a69 283 irq_n = Uart1_IRQn;
Zaitsev 10:41552d038a69 284 } else if(obj->UARTREG == UART2REG) {
Zaitsev 10:41552d038a69 285 /* UART 1 */
Zaitsev 10:41552d038a69 286 Vector = (uint32_t)&Uart2_Irq;
Zaitsev 10:41552d038a69 287 irq_n = Uart2_IRQn;
Zaitsev 10:41552d038a69 288 } else {
Zaitsev 10:41552d038a69 289 MBED_ASSERT(False);
Zaitsev 10:41552d038a69 290 }
Zaitsev 10:41552d038a69 291
Zaitsev 10:41552d038a69 292 /* Check IRQ type & enable/disable accordingly */
Zaitsev 10:41552d038a69 293 if(enable) {
Zaitsev 10:41552d038a69 294 /* Enable */
Zaitsev 10:41552d038a69 295 if(irq == RxIrq) {
Zaitsev 10:41552d038a69 296 /* Rx IRQ */
Zaitsev 10:41552d038a69 297 obj->UARTREG->FCR.BITS.RX_FIFO_TRIG = 0x0;
Zaitsev 10:41552d038a69 298 obj->UARTREG->IER.BITS.RX_DATA_INT = True;
Zaitsev 10:41552d038a69 299 } else if(irq == TxIrq) {
Zaitsev 10:41552d038a69 300 /* Tx IRQ */
Zaitsev 10:41552d038a69 301 obj->UARTREG->IER.BITS.TX_HOLD_INT = True;
Zaitsev 10:41552d038a69 302 } else {
Zaitsev 10:41552d038a69 303 MBED_ASSERT(False);
Zaitsev 10:41552d038a69 304 }
Zaitsev 10:41552d038a69 305 NVIC_SetVector(irq_n, Vector);
Zaitsev 10:41552d038a69 306 NVIC_EnableIRQ(irq_n);
Zaitsev 10:41552d038a69 307 } else {
Zaitsev 10:41552d038a69 308 /* Disable */
Zaitsev 10:41552d038a69 309 NVIC_DisableIRQ(irq_n);
Zaitsev 10:41552d038a69 310 if(irq == RxIrq) {
Zaitsev 10:41552d038a69 311 /* Rx IRQ */
Zaitsev 10:41552d038a69 312 obj->UARTREG->IER.BITS.RX_DATA_INT = False;
Zaitsev 10:41552d038a69 313 } else if(irq == TxIrq) {
Zaitsev 10:41552d038a69 314 /* Tx IRQ */
Zaitsev 10:41552d038a69 315
Zaitsev 10:41552d038a69 316 obj->UARTREG->IER.BITS.TX_HOLD_INT = False;
Zaitsev 10:41552d038a69 317 } else {
Zaitsev 10:41552d038a69 318 MBED_ASSERT(False);
Zaitsev 10:41552d038a69 319 }
Zaitsev 10:41552d038a69 320 }
Zaitsev 10:41552d038a69 321 }
Zaitsev 10:41552d038a69 322
Zaitsev 10:41552d038a69 323 int serial_getc(serial_t *obj)
Zaitsev 10:41552d038a69 324 {
Zaitsev 10:41552d038a69 325 uint8_t c;
Zaitsev 10:41552d038a69 326
Zaitsev 10:41552d038a69 327 while(!obj->UARTREG->LSR.BITS.READY); /* Wait for received data is ready */
Zaitsev 10:41552d038a69 328 c = obj->UARTREG->RBR & 0xFF; /* Get received character */
Zaitsev 10:41552d038a69 329 return c;
Zaitsev 10:41552d038a69 330 }
Zaitsev 10:41552d038a69 331
Zaitsev 10:41552d038a69 332 void serial_putc(serial_t *obj, int c)
Zaitsev 10:41552d038a69 333 {
Zaitsev 10:41552d038a69 334
Zaitsev 10:41552d038a69 335 while(!obj->UARTREG->LSR.BITS.TX_HOLD_EMPTY);/* Wait till THR is empty */
Zaitsev 10:41552d038a69 336 obj->UARTREG->THR = c; /* Transmit byte */
Zaitsev 10:41552d038a69 337
Zaitsev 10:41552d038a69 338 }
Zaitsev 10:41552d038a69 339
Zaitsev 10:41552d038a69 340 int serial_readable(serial_t *obj)
Zaitsev 10:41552d038a69 341 {
Zaitsev 10:41552d038a69 342 return obj->UARTREG->LSR.BITS.READY;
Zaitsev 10:41552d038a69 343 }
Zaitsev 10:41552d038a69 344
Zaitsev 10:41552d038a69 345 int serial_writable(serial_t *obj)
Zaitsev 10:41552d038a69 346 {
Zaitsev 10:41552d038a69 347 return obj->UARTREG->LSR.BITS.TX_HOLD_EMPTY;
Zaitsev 10:41552d038a69 348 }
Zaitsev 10:41552d038a69 349
Zaitsev 10:41552d038a69 350 void serial_clear(serial_t *obj)
Zaitsev 10:41552d038a69 351 {
Zaitsev 10:41552d038a69 352 /* Reset TX & RX FIFO */
Zaitsev 10:41552d038a69 353 obj->UARTREG->FCR.WORD |= ((True << UART_FCS_TX_FIFO_RST_BIT_POS) |
Zaitsev 10:41552d038a69 354 (True << UART_FCS_RX_FIFO_RST_BIT_POS));
Zaitsev 10:41552d038a69 355 }
Zaitsev 10:41552d038a69 356
Zaitsev 10:41552d038a69 357 void serial_break_set(serial_t *obj)
Zaitsev 10:41552d038a69 358 {
Zaitsev 10:41552d038a69 359 obj->UARTREG->LCR.BITS.BREAK = True;
Zaitsev 10:41552d038a69 360 }
Zaitsev 10:41552d038a69 361
Zaitsev 10:41552d038a69 362 void serial_break_clear(serial_t *obj)
Zaitsev 10:41552d038a69 363 {
Zaitsev 10:41552d038a69 364 obj->UARTREG->LCR.BITS.BREAK = False;
Zaitsev 10:41552d038a69 365 }
Zaitsev 10:41552d038a69 366
Zaitsev 10:41552d038a69 367 void serial_pinout_tx(PinName tx)
Zaitsev 10:41552d038a69 368 {
Zaitsev 10:41552d038a69 369 /* COnfigure PinNo to drive strength of 1, Push pull and pull none */
Zaitsev 10:41552d038a69 370 fPadIOCtrl(tx, 1, 0, 1);
Zaitsev 10:41552d038a69 371 }
Zaitsev 10:41552d038a69 372
Zaitsev 10:41552d038a69 373 /** Configure the serial for the flow control. It sets flow control in the hardware
Zaitsev 10:41552d038a69 374 * if a serial peripheral supports it, otherwise software emulation is used.
Zaitsev 10:41552d038a69 375 *
Zaitsev 10:41552d038a69 376 * @param obj The serial object
Zaitsev 10:41552d038a69 377 * @param type The type of the flow control. Look at the available FlowControl types.
Zaitsev 10:41552d038a69 378 * @param rxflow The TX pin name
Zaitsev 10:41552d038a69 379 * @param txflow The RX pin name
Zaitsev 10:41552d038a69 380 */
Zaitsev 10:41552d038a69 381 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
Zaitsev 10:41552d038a69 382 {
Zaitsev 10:41552d038a69 383 /* TODO: This is an empty implementation for now.*/
Zaitsev 10:41552d038a69 384 }
Zaitsev 10:41552d038a69 385
Zaitsev 10:41552d038a69 386 #endif /* DEVICE_SERIAL */