-/*----------------------------------------------------------------------------\r
- * Name: serial.c\r
- * Purpose: serial port handling for LPC17xx\r
- * Version: V1.20\r
- *----------------------------------------------------------------------------\r
- * This software is supplied "AS IS" without any warranties, express,\r
- * implied or statutory, including but not limited to the implied\r
- * warranties of fitness for purpose, satisfactory quality and\r
- * noninfringement. Keil extends you a royalty-free right to reproduce\r
- * and distribute executable files created using this software for use\r
- * on NXP Semiconductors LPC microcontroller devices only. Nothing else\r
- * gives you the right to use this software.\r
- *\r
- * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.\r
- *---------------------------------------------------------------------------*/\r
-#include "../LPC17xx.h" // LPC17xx definitions\r
-#include "lpc_types.h"\r
-#include "serial.h"\r
-\r
-\r
-/*----------------------------------------------------------------------------\r
- Defines for ring buffers\r
- *---------------------------------------------------------------------------*/\r
-#define SER_BUF_SIZE (128) // serial buffer in bytes (power 2)\r
-#define SER_BUF_MASK (SER_BUF_SIZE-1ul) // buffer size mask\r
-\r
-/* Buffer read / write macros */\r
-#define SER_BUF_RESET(serBuf) (serBuf.rdIdx = serBuf.wrIdx = 0)\r
-#define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn))\r
-#define SER_BUF_RD(serBuf) (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++])\r
-#define SER_BUF_EMPTY(serBuf) (serBuf.rdIdx == serBuf.wrIdx)\r
-#define SER_BUF_FULL(serBuf) (serBuf.rdIdx == serBuf.wrIdx+1)\r
-#define SER_BUF_COUNT(serBuf) (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx))\r
-\r
-// buffer type\r
-typedef struct __SER_BUF_T {\r
- unsigned char data[SER_BUF_SIZE];\r
- unsigned int wrIdx;\r
- unsigned int rdIdx;\r
-} SER_BUF_T;\r
-\r
-unsigned long ser_txRestart; // NZ if TX restart is required\r
-unsigned short ser_lineState; // ((msr << 8) | (lsr))\r
-SER_BUF_T ser_out; // Serial data buffers\r
-SER_BUF_T ser_in;\r
-\r
-/*----------------------------------------------------------------------------\r
- open the serial port\r
- *---------------------------------------------------------------------------*/\r
-void ser_OpenPort (char portNum) {\r
-\r
- if ( portNum == 0 )\r
- {\r
- /* Port 0 */\r
- NVIC_DisableIRQ(UART0_IRQn);\r
- PINCON->PINSEL0 &= ~0x000000F0;\r
- PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */\r
- }\r
- else\r
- {\r
- /* Port 1 */\r
- NVIC_DisableIRQ(UART1_IRQn);\r
- PINCON->PINSEL4 &= ~0x0000000F;\r
- PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */\r
- }\r
- return;\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- close the serial port\r
- *---------------------------------------------------------------------------*/\r
-void ser_ClosePort (char portNum ) {\r
- if ( portNum == 0 )\r
- {\r
- /* POrt 0 */\r
- PINCON->PINSEL0 &= ~0x000000F0;\r
- /* Disable the interrupt in the VIC and UART controllers */\r
- UART0->IER = 0;\r
- NVIC_DisableIRQ(UART0_IRQn);\r
- }\r
- else\r
- {\r
- /* Port 1 */\r
- PINCON->PINSEL4 &= ~0x0000000F;\r
- /* Disable the interrupt in the VIC and UART controllers */\r
- UART1->IER = 0;\r
- NVIC_DisableIRQ(UART1_IRQn);\r
- }\r
- return;\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- initialize the serial port\r
- *---------------------------------------------------------------------------*/\r
-void ser_InitPort0 (unsigned long baudrate, unsigned int databits,\r
- unsigned int parity, unsigned int stopbits) {\r
-\r
- unsigned char lcr_p, lcr_s, lcr_d;\r
- unsigned int dll;\r
- unsigned int pclkdiv, pclk;\r
-\r
- switch (databits) {\r
- case 5: // 5 Data bits\r
- lcr_d = 0x00;\r
- break;\r
- case 6: // 6 Data bits\r
- lcr_d = 0x01;\r
- break;\r
- case 7: // 7 Data bits\r
- lcr_d = 0x02;\r
- break;\r
- case 8: // 8 Data bits\r
- default:\r
- lcr_d = 0x03;\r
- break;\r
- }\r
-\r
- switch (stopbits) {\r
- case 1: // 1,5 Stop bits\r
- case 2: // 2 Stop bits\r
- lcr_s = 0x04;\r
- break;\r
- case 0: // 1 Stop bit\r
- default:\r
- lcr_s = 0x00;\r
- break;\r
- }\r
-\r
- switch (parity) {\r
- case 1: // Parity Odd\r
- lcr_p = 0x08;\r
- break;\r
- case 2: // Parity Even\r
- lcr_p = 0x18;\r
- break;\r
- case 3: // Parity Mark\r
- lcr_p = 0x28;\r
- break;\r
- case 4: // Parity Space\r
- lcr_p = 0x38;\r
- break;\r
- case 0: // Parity None\r
- default:\r
- lcr_p = 0x00;\r
- break;\r
- }\r
-\r
- SER_BUF_RESET(ser_out); // reset out buffer\r
- SER_BUF_RESET(ser_in); // reset in buffer\r
-\r
- /* Bit 6~7 is for UART0 */\r
- pclkdiv = (SC->PCLKSEL0 >> 6) & 0x03;\r
-\r
- switch ( pclkdiv )\r
- {\r
- case 0x00:\r
- default:\r
- pclk = SystemFrequency/4;\r
- break;\r
- case 0x01:\r
- pclk = SystemFrequency;\r
- break;\r
- case 0x02:\r
- pclk = SystemFrequency/2;\r
- break;\r
- case 0x03:\r
- pclk = SystemFrequency/8;\r
- break;\r
- }\r
-\r
- dll = (pclk/16)/baudrate ; /*baud rate */\r
- UART0->FDR = 0; // Fractional divider not used\r
- UART0->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit\r
- UART0->DLL = dll; // Baud Rate depending on PCLK\r
- UART0->DLM = (dll >> 8); // High divisor latch\r
- UART0->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0\r
- UART0->IER = 0x03; // Enable TX/RX interrupts\r
-\r
- UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */\r
- ser_txRestart = 1; // TX fifo is empty\r
-\r
- /* Enable the UART Interrupt */\r
- NVIC_EnableIRQ(UART0_IRQn);\r
- return;\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- initialize the serial port\r
- *---------------------------------------------------------------------------*/\r
-void ser_InitPort1 (unsigned long baudrate, unsigned int databits,\r
- unsigned int parity, unsigned int stopbits) {\r
-\r
- unsigned char lcr_p, lcr_s, lcr_d;\r
- unsigned int dll;\r
- unsigned int pclkdiv, pclk;\r
-\r
- switch (databits) {\r
- case 5: // 5 Data bits\r
- lcr_d = 0x00;\r
- break;\r
- case 6: // 6 Data bits\r
- lcr_d = 0x01;\r
- break;\r
- case 7: // 7 Data bits\r
- lcr_d = 0x02;\r
- break;\r
- case 8: // 8 Data bits\r
- default:\r
- lcr_d = 0x03;\r
- break;\r
- }\r
-\r
- switch (stopbits) {\r
- case 1: // 1,5 Stop bits\r
- case 2: // 2 Stop bits\r
- lcr_s = 0x04;\r
- break;\r
- case 0: // 1 Stop bit\r
- default:\r
- lcr_s = 0x00;\r
- break;\r
- }\r
-\r
- switch (parity) {\r
- case 1: // Parity Odd\r
- lcr_p = 0x08;\r
- break;\r
- case 2: // Parity Even\r
- lcr_p = 0x18;\r
- break;\r
- case 3: // Parity Mark\r
- lcr_p = 0x28;\r
- break;\r
- case 4: // Parity Space\r
- lcr_p = 0x38;\r
- break;\r
- case 0: // Parity None\r
- default:\r
- lcr_p = 0x00;\r
- break;\r
- }\r
-\r
- SER_BUF_RESET(ser_out); // reset out buffer\r
- SER_BUF_RESET(ser_in); // reset in buffer\r
-\r
- /* Bit 8,9 are for UART1 */\r
- pclkdiv = (SC->PCLKSEL0 >> 8) & 0x03;\r
-\r
- switch ( pclkdiv )\r
- {\r
- case 0x00:\r
- default:\r
- pclk = SystemFrequency/4;\r
- break;\r
- case 0x01:\r
- pclk = SystemFrequency;\r
- break;\r
- case 0x02:\r
- pclk = SystemFrequency/2;\r
- break;\r
- case 0x03:\r
- pclk = SystemFrequency/8;\r
- break;\r
- }\r
-\r
- dll = (pclk/16)/baudrate ; /*baud rate */\r
- UART1->FDR = 0; // Fractional divider not used\r
- UART1->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit\r
- UART1->DLL = dll; // Baud Rate depending on PCLK\r
- UART1->DLM = (dll >> 8); // High divisor latch\r
- UART1->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0\r
- UART1->IER = 0x03; // Enable TX/RX interrupts\r
-\r
- UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */\r
- ser_txRestart = 1; // TX fifo is empty\r
-\r
- /* Enable the UART Interrupt */\r
- NVIC_EnableIRQ(UART1_IRQn);\r
- return;\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- read data from serial port\r
- *---------------------------------------------------------------------------*/\r
-int ser_Read (char *buffer, const int *length) {\r
- int bytesToRead, bytesRead;\r
-\r
- /* Read *length bytes, block if *bytes are not avaialable */\r
- bytesToRead = *length;\r
- bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);\r
- bytesRead = bytesToRead;\r
-\r
- while (bytesToRead--) {\r
- while (SER_BUF_EMPTY(ser_in)); // Block until data is available if none\r
- *buffer++ = SER_BUF_RD(ser_in);\r
- }\r
- return (bytesRead);\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- write data to the serial port\r
- *---------------------------------------------------------------------------*/\r
-int ser_Write (char portNum, const char *buffer, int *length) {\r
- int bytesToWrite, bytesWritten;\r
-\r
- // Write *length bytes\r
- bytesToWrite = *length;\r
- bytesWritten = bytesToWrite;\r
-\r
- while (!SER_BUF_EMPTY(ser_out)); // Block until space is available if none\r
- while (bytesToWrite) {\r
- SER_BUF_WR(ser_out, *buffer++); // Read Rx FIFO to buffer\r
- bytesToWrite--;\r
- }\r
-\r
- if (ser_txRestart) {\r
- ser_txRestart = 0;\r
- if ( portNum == 0 )\r
- {\r
- UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx Register\r
- }\r
- else\r
- {\r
- UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx Register\r
- }\r
- }\r
-\r
- return (bytesWritten);\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- check if character(s) are available at the serial interface\r
- *---------------------------------------------------------------------------*/\r
-void ser_AvailChar (int *availChar) {\r
-\r
- *availChar = SER_BUF_COUNT(ser_in);\r
-\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- read the line state of the serial port\r
- *---------------------------------------------------------------------------*/\r
-void ser_LineState (unsigned short *lineState) {\r
-\r
- *lineState = ser_lineState;\r
- ser_lineState = 0;\r
-\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- serial port 0 interrupt\r
- *---------------------------------------------------------------------------*/\r
-void UART0_IRQHandler(void)\r
-{\r
- volatile unsigned long iir;\r
-\r
- iir = UART0->IIR;\r
-\r
- if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending\r
- while (UART0->LSR & 0x01) { // Rx FIFO is not empty\r
- SER_BUF_WR(ser_in, UART0->RBR); // Read Rx FIFO to buffer\r
- }\r
- }\r
- if ((iir & 0x2)) { // TXMIS pending\r
- if (SER_BUF_COUNT(ser_out) != 0) {\r
- UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO\r
- ser_txRestart = 0;\r
- }\r
- else {\r
- ser_txRestart = 1;\r
- }\r
- }\r
- ser_lineState = UART0->LSR & 0x1E; // update linestate\r
- return;\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- serial port 1 interrupt\r
- *---------------------------------------------------------------------------*/\r
-void UART1_IRQHandler(void)\r
-{\r
- volatile unsigned long iir;\r
-\r
- iir = UART1->IIR;\r
-\r
- if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending\r
- while (UART1->LSR & 0x01) { // Rx FIFO is not empty\r
- SER_BUF_WR(ser_in, UART1->RBR); // Read Rx FIFO to buffer\r
- }\r
- }\r
- if ((iir & 0x2)) { // TXMIS pending\r
- if (SER_BUF_COUNT(ser_out) != 0) {\r
- UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO\r
- ser_txRestart = 0;\r
- }\r
- else {\r
- ser_txRestart = 1;\r
- }\r
- }\r
- ser_lineState = ((UART1->MSR<<8)|UART1->LSR) & 0xE01E; // update linestate\r
- return;\r
-}\r
-\r
-\r
+/*----------------------------------------------------------------------------
+ * Name: serial.c
+ * Purpose: serial port handling for LPC17xx
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+#include <board.h> // LPC17xx definitions
+#include "lpc_types.h"
+#include "serial.h"
+
+
+/*----------------------------------------------------------------------------
+ Defines for ring buffers
+ *---------------------------------------------------------------------------*/
+#define SER_BUF_SIZE (128) // serial buffer in bytes (power 2)
+#define SER_BUF_MASK (SER_BUF_SIZE-1ul) // buffer size mask
+
+/* Buffer read / write macros */
+#define SER_BUF_RESET(serBuf) (serBuf.rdIdx = serBuf.wrIdx = 0)
+#define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn))
+#define SER_BUF_RD(serBuf) (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++])
+#define SER_BUF_EMPTY(serBuf) (serBuf.rdIdx == serBuf.wrIdx)
+#define SER_BUF_FULL(serBuf) (serBuf.rdIdx == serBuf.wrIdx+1)
+#define SER_BUF_COUNT(serBuf) (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx))
+
+// buffer type
+typedef struct __SER_BUF_T {
+ unsigned char data[SER_BUF_SIZE];
+ unsigned int wrIdx;
+ unsigned int rdIdx;
+} SER_BUF_T;
+
+unsigned long ser_txRestart; // NZ if TX restart is required
+unsigned short ser_lineState; // ((msr << 8) | (lsr))
+SER_BUF_T ser_out; // Serial data buffers
+SER_BUF_T ser_in;
+
+/*----------------------------------------------------------------------------
+ open the serial port
+ *---------------------------------------------------------------------------*/
+void ser_OpenPort (char portNum) {
+
+ if ( portNum == 0 )
+ {
+ /* Port 0 */
+ NVIC_DisableIRQ(UART0_IRQn);
+ PINCON->PINSEL0 &= ~0x000000F0;
+ PINCON->PINSEL0 |= 0x00000050; /* RxD0 is P0.3 and TxD0 is P0.2 */
+ }
+ else
+ {
+ /* Port 1 */
+ NVIC_DisableIRQ(UART1_IRQn);
+ PINCON->PINSEL4 &= ~0x0000000F;
+ PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */
+ }
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ close the serial port
+ *---------------------------------------------------------------------------*/
+void ser_ClosePort (char portNum ) {
+ if ( portNum == 0 )
+ {
+ /* POrt 0 */
+ PINCON->PINSEL0 &= ~0x000000F0;
+ /* Disable the interrupt in the VIC and UART controllers */
+ UART0->IER = 0;
+ NVIC_DisableIRQ(UART0_IRQn);
+ }
+ else
+ {
+ /* Port 1 */
+ PINCON->PINSEL4 &= ~0x0000000F;
+ /* Disable the interrupt in the VIC and UART controllers */
+ UART1->IER = 0;
+ NVIC_DisableIRQ(UART1_IRQn);
+ }
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ initialize the serial port
+ *---------------------------------------------------------------------------*/
+void ser_InitPort0 (unsigned long baudrate, unsigned int databits,
+ unsigned int parity, unsigned int stopbits) {
+
+ unsigned char lcr_p, lcr_s, lcr_d;
+ unsigned int dll;
+ unsigned int pclkdiv, pclk;
+
+ switch (databits) {
+ case 5: // 5 Data bits
+ lcr_d = 0x00;
+ break;
+ case 6: // 6 Data bits
+ lcr_d = 0x01;
+ break;
+ case 7: // 7 Data bits
+ lcr_d = 0x02;
+ break;
+ case 8: // 8 Data bits
+ default:
+ lcr_d = 0x03;
+ break;
+ }
+
+ switch (stopbits) {
+ case 1: // 1,5 Stop bits
+ case 2: // 2 Stop bits
+ lcr_s = 0x04;
+ break;
+ case 0: // 1 Stop bit
+ default:
+ lcr_s = 0x00;
+ break;
+ }
+
+ switch (parity) {
+ case 1: // Parity Odd
+ lcr_p = 0x08;
+ break;
+ case 2: // Parity Even
+ lcr_p = 0x18;
+ break;
+ case 3: // Parity Mark
+ lcr_p = 0x28;
+ break;
+ case 4: // Parity Space
+ lcr_p = 0x38;
+ break;
+ case 0: // Parity None
+ default:
+ lcr_p = 0x00;
+ break;
+ }
+
+ SER_BUF_RESET(ser_out); // reset out buffer
+ SER_BUF_RESET(ser_in); // reset in buffer
+
+ /* Bit 6~7 is for UART0 */
+ pclkdiv = (SC->PCLKSEL0 >> 6) & 0x03;
+
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemFrequency/4;
+ break;
+ case 0x01:
+ pclk = SystemFrequency;
+ break;
+ case 0x02:
+ pclk = SystemFrequency/2;
+ break;
+ case 0x03:
+ pclk = SystemFrequency/8;
+ break;
+ }
+
+ dll = (pclk/16)/baudrate ; /*baud rate */
+ UART0->FDR = 0; // Fractional divider not used
+ UART0->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit
+ UART0->DLL = dll; // Baud Rate depending on PCLK
+ UART0->DLM = (dll >> 8); // High divisor latch
+ UART0->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0
+ UART0->IER = 0x03; // Enable TX/RX interrupts
+
+ UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
+ ser_txRestart = 1; // TX fifo is empty
+
+ /* Enable the UART Interrupt */
+ NVIC_EnableIRQ(UART0_IRQn);
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ initialize the serial port
+ *---------------------------------------------------------------------------*/
+void ser_InitPort1 (unsigned long baudrate, unsigned int databits,
+ unsigned int parity, unsigned int stopbits) {
+
+ unsigned char lcr_p, lcr_s, lcr_d;
+ unsigned int dll;
+ unsigned int pclkdiv, pclk;
+
+ switch (databits) {
+ case 5: // 5 Data bits
+ lcr_d = 0x00;
+ break;
+ case 6: // 6 Data bits
+ lcr_d = 0x01;
+ break;
+ case 7: // 7 Data bits
+ lcr_d = 0x02;
+ break;
+ case 8: // 8 Data bits
+ default:
+ lcr_d = 0x03;
+ break;
+ }
+
+ switch (stopbits) {
+ case 1: // 1,5 Stop bits
+ case 2: // 2 Stop bits
+ lcr_s = 0x04;
+ break;
+ case 0: // 1 Stop bit
+ default:
+ lcr_s = 0x00;
+ break;
+ }
+
+ switch (parity) {
+ case 1: // Parity Odd
+ lcr_p = 0x08;
+ break;
+ case 2: // Parity Even
+ lcr_p = 0x18;
+ break;
+ case 3: // Parity Mark
+ lcr_p = 0x28;
+ break;
+ case 4: // Parity Space
+ lcr_p = 0x38;
+ break;
+ case 0: // Parity None
+ default:
+ lcr_p = 0x00;
+ break;
+ }
+
+ SER_BUF_RESET(ser_out); // reset out buffer
+ SER_BUF_RESET(ser_in); // reset in buffer
+
+ /* Bit 8,9 are for UART1 */
+ pclkdiv = (SC->PCLKSEL0 >> 8) & 0x03;
+
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemFrequency/4;
+ break;
+ case 0x01:
+ pclk = SystemFrequency;
+ break;
+ case 0x02:
+ pclk = SystemFrequency/2;
+ break;
+ case 0x03:
+ pclk = SystemFrequency/8;
+ break;
+ }
+
+ dll = (pclk/16)/baudrate ; /*baud rate */
+ UART1->FDR = 0; // Fractional divider not used
+ UART1->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit
+ UART1->DLL = dll; // Baud Rate depending on PCLK
+ UART1->DLM = (dll >> 8); // High divisor latch
+ UART1->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0
+ UART1->IER = 0x03; // Enable TX/RX interrupts
+
+ UART1->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
+ ser_txRestart = 1; // TX fifo is empty
+
+ /* Enable the UART Interrupt */
+ NVIC_EnableIRQ(UART1_IRQn);
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ read data from serial port
+ *---------------------------------------------------------------------------*/
+int ser_Read (char *buffer, const int *length) {
+ int bytesToRead, bytesRead;
+
+ /* Read *length bytes, block if *bytes are not avaialable */
+ bytesToRead = *length;
+ bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
+ bytesRead = bytesToRead;
+
+ while (bytesToRead--) {
+ while (SER_BUF_EMPTY(ser_in)); // Block until data is available if none
+ *buffer++ = SER_BUF_RD(ser_in);
+ }
+ return (bytesRead);
+}
+
+/*----------------------------------------------------------------------------
+ write data to the serial port
+ *---------------------------------------------------------------------------*/
+int ser_Write (char portNum, const char *buffer, int *length) {
+ int bytesToWrite, bytesWritten;
+
+ // Write *length bytes
+ bytesToWrite = *length;
+ bytesWritten = bytesToWrite;
+
+ while (!SER_BUF_EMPTY(ser_out)); // Block until space is available if none
+ while (bytesToWrite) {
+ SER_BUF_WR(ser_out, *buffer++); // Read Rx FIFO to buffer
+ bytesToWrite--;
+ }
+
+ if (ser_txRestart) {
+ ser_txRestart = 0;
+ if ( portNum == 0 )
+ {
+ UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx Register
+ }
+ else
+ {
+ UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx Register
+ }
+ }
+
+ return (bytesWritten);
+}
+
+/*----------------------------------------------------------------------------
+ check if character(s) are available at the serial interface
+ *---------------------------------------------------------------------------*/
+void ser_AvailChar (int *availChar) {
+
+ *availChar = SER_BUF_COUNT(ser_in);
+
+}
+
+/*----------------------------------------------------------------------------
+ read the line state of the serial port
+ *---------------------------------------------------------------------------*/
+void ser_LineState (unsigned short *lineState) {
+
+ *lineState = ser_lineState;
+ ser_lineState = 0;
+
+}
+
+/*----------------------------------------------------------------------------
+ serial port 0 interrupt
+ *---------------------------------------------------------------------------*/
+void UART0_IRQHandler(void)
+{
+ volatile unsigned long iir;
+
+ iir = UART0->IIR;
+
+ if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending
+ while (UART0->LSR & 0x01) { // Rx FIFO is not empty
+ SER_BUF_WR(ser_in, UART0->RBR); // Read Rx FIFO to buffer
+ }
+ }
+ if ((iir & 0x2)) { // TXMIS pending
+ if (SER_BUF_COUNT(ser_out) != 0) {
+ UART0->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO
+ ser_txRestart = 0;
+ }
+ else {
+ ser_txRestart = 1;
+ }
+ }
+ ser_lineState = UART0->LSR & 0x1E; // update linestate
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ serial port 1 interrupt
+ *---------------------------------------------------------------------------*/
+void UART1_IRQHandler(void)
+{
+ volatile unsigned long iir;
+
+ iir = UART1->IIR;
+
+ if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending
+ while (UART1->LSR & 0x01) { // Rx FIFO is not empty
+ SER_BUF_WR(ser_in, UART1->RBR); // Read Rx FIFO to buffer
+ }
+ }
+ if ((iir & 0x2)) { // TXMIS pending
+ if (SER_BUF_COUNT(ser_out) != 0) {
+ UART1->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO
+ ser_txRestart = 0;
+ }
+ else {
+ ser_txRestart = 1;
+ }
+ }
+ ser_lineState = ((UART1->MSR<<8)|UART1->LSR) & 0xE01E; // update linestate
+ return;
+}
+
+