Fix USB, DOS line endings, integrate and reorganize project
[rapper.git] / new_cmsis / usb / serial.c
index 938ae18..dd23b26 100755 (executable)
-/*----------------------------------------------------------------------------\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;
+}
+
+