Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sat Jun 03 00:22:44 2017 +0000
Revision:
46:b156ef445742
Parent:
18:6a4db94011d3
Final code for internal battlebot competition.

Who changed what in which revision?

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