SPI or I2C to UART Bridge

Dependents:   SC16IS750_Test mbed_SC16IS750 Xadow_SC16IS750_Test Xadow_MPU9150AHRS

Revision:
3:9783b6bde958
Parent:
2:76cb93b511f2
Child:
4:12446ee9f9c8
--- a/SC16IS750.h	Thu Feb 13 17:12:02 2014 +0000
+++ b/SC16IS750.h	Thu Feb 20 19:37:55 2014 +0000
@@ -1,5 +1,6 @@
-/* SC16IS750 interface 
- *   v0.1 WH, Nov 2013, Sparkfun Libs used as example. Added I2C I/F and many more methods 
+/* SC16IS750 I2C or SPI to UART bridge 
+ *   v0.1 WH, Nov 2013, Sparkfun WiFly Shield code library alpha 0 used as example, Added I2C I/F and many more methods.
+ *                      https://forum.sparkfun.com/viewtopic.php?f=13&t=21846
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  * and associated documentation files (the "Software"), to deal in the Software without restriction,
@@ -19,6 +20,10 @@
 #ifndef _SC16IS750_H
 #define _SC16IS750_H
 
+
+#include "Stream.h"
+//#include <SerialBase.h>
+
 //I2C Slaveaddresses                     A1  A0 
 #define SC16IS750_SA0            0x90  /* VDD VDD */
 #define SC16IS750_SA1            0x92  /* VDD VSS */
@@ -51,7 +56,7 @@
 #define SC16IS750_BAUDRATE_DIVISOR(baud)       ((SC16IS750_XTAL_FREQ/SC16IS750_PRESCALER)/(baud*16UL))
 
 //Default baudrate
-#define SC16IS750_DEFAULT_BAUDRATE     9600
+#define SC16IS750_DEFAULT_BAUDRATE           9600
 
 
 /** See section 8.3 of the datasheet for definitions
@@ -67,8 +72,8 @@
 #define FCR_TX_IRQ_16                 (1 << 4)
 #define FCR_TX_IRQ_8                  (0 << 4)
 //#define FCR_RESERVED                  (1 << 3)
-#define FCR_TXFIFO_RST                (1 << 2)
-#define FCR_RXFIFO_RST                (1 << 1)
+#define FCR_TX_FIFO_RST               (1 << 2)
+#define FCR_RX_FIFO_RST               (1 << 1)
 #define FCR_ENABLE_FIFO               (1 << 0)
 
 //FIFO size
@@ -105,7 +110,7 @@
 /** See section 8.5 of the datasheet for definitions
   * of bits in the Line status register (LSR)
   */
-#define LSR_DR   (0x01) /* Data ready                                  */
+#define LSR_DR   (0x01) /* Data ready in RX FIFO                       */
 #define LSR_OE   (0x02) /* Overrun error                               */
 #define LSR_PE   (0x04) /* Parity error                                */
 #define LSR_FE   (0x08) /* Framing error                               */
@@ -120,8 +125,10 @@
   */
 #define MCR_MDTR                      (1 << 0) /* Data Terminal Ready pin control. */
 #define MCR_MRTS                      (1 << 1) /* Request to Send pin control when not in Auto RTS mode.*/
+//MCR[2] only accessible when EFR[4] is set
 #define MCR_ENABLE_TCR_TLR            (1 << 2)
 #define MCR_ENABLE_LOOPBACK           (1 << 4)
+//MCR[7:5] only accessible when EFR[4] is set
 #define MCR_ENABLE_XON_ANY_CHAR       (1 << 5)
 #define MCR_ENABLE_IRDA               (1 << 6)
 #define MCR_PRESCALE_1                (0 << 7)
@@ -131,28 +138,46 @@
 /** See section 8.7 of the datasheet for definitions
   * of bits in the Modem status register (MSR)
   */
+#define MSR_DCTS                      (1 << 0) /* Delta CTS - CTS Changed State      */
+#define MSR_DDSR                      (1 << 1) /* Delta DSR - DSR Changed State      */
+#define MSR_DDI                       (1 << 2) /* Delta DI  - DI  Changed State      */
+#define MSR_DCD                       (1 << 3) /* Delta CD  - CD  Changed State      */
+#define MSR_CTS                       (1 << 4) /* CTS State - Complement of NCTS pin */
+//MSR[7:5] only accessible when GPIO[7:4] are set as modem pin
+#define MSR_DSR                       (1 << 5) /* DSR State - Complement of NDSR pin */
+#define MSR_RI                        (1 << 6) /* RI State  - Complement of  NRI pin */
+#define MSR_CD                        (1 << 7) /* CD State  - Complement of  NCD pin */
 
 
 /** See section 8.8 of the datasheet for definitions
   * of bits in the Interrupt enable register (IER)
   */
-#define IER_ERBI  (0x01) /* Enable received data available interrupt            */
-#define IER_ETBEI (0x02) /* Enable transmitter holding register empty interrupt */
+#define IER_ERHRI (0x01) /* Enable received data available interrupt            */
+#define IER_ETHRI (0x02) /* Enable transmitter holding register empty interrupt */
 #define IER_ELSI  (0x04) /* Enable receiver line status interrupt               */
-#define IER_EDSSI (0x08) /* Enable modem status interrupt                       */
+#define IER_EMSI  (0x08) /* Enable modem status interrupt                       */
+//IER[7:5] only accessible when EFR[4] is set
 #define IER_SLEEP (0x10) /* Enable sleep mode                                   */
+#define IER_XOFFI (0x20) /* Enable XOFF interrupt                               */
+#define IER_RTSI  (0x40) /* Enable RTS interrupt                                */
+#define IER_CTSI  (0x80) /* Enable CTS interrupt                                */
 
 
 /** See section 8.9 of the datasheet for definitions
   * of bits in the Interrupt identification register (IIR)
-  * Bit 0 is set to 0 if an IT is pending.
-  * Bits 1 and 2 are used to identify the IT.
+  * Bit 0 is set to 0 if an IRQ is pending.
+  * Bits 1..5 are used to identify the IRQ source.
   */
+#define IIR_IRQ_NOT_PENDING             (0x01)  /* IRQ Not Pending              */
+#define IIR_TX_EMPTY                    (0x02)  /* THR Interrupt                */
+#define IIR_RX_DATA                     (0x04)  /* RHR Interrupt                */
+#define IIR_RX_ERROR                    (0x06)  /* Line Status Error Interrupt  */
+#define IIR_RX_TIMEOUT                  (0x0B)  /* RX Timeout Interrupt         */
+#define IIR_RX_XOFF                     (0x10)  /* RX XOff Interrupt            */
+#define IIR_DCTS_DRTS                   (0x20)  /* Delta CTS or RTS Interrupt   */
+#define IIR_DIO                         (0x30)  /* Delta GPIO pin Interrupt     */
+
 #define IIR_BITS_USED                   (0x07)
-#define IIR_IT_NOT_PENDING              (0x01)
-#define IIR_RX_DATA                     (0x04)
-#define IIR_TX_EMPTY                    (0x02)
-#define IIR_MODEM_STATUS                (0x00)
 
 
 /** See section 8.10 of the datasheet for definitions
@@ -182,23 +207,41 @@
 
 /** See section 8.12 of the datasheet for definitions
   * of bits in the Transmission Control Register (TCR)
-  *   Trigger level to halt transmission: 0..15 (meaning 0-60 with a granularity of 4) 
-  *   Trigger level to resume transmission: 0..15 (meaning 0-60 with a granularity of 4) 
+  * These levels control when RTS is asserted or de-asserted and auto RTS is enabled. Note that XON/XOFF is not supported in this lib.
+  *   Trigger level to halt transmission to the device   : 0..15 (meaning 0-60 with a granularity of 4) 
+  *     RTS is de-asserted when RX FIFO is above the set trigger level (i.e. buffer is getting full)  
+  *   Trigger level to resume transmission to the device : 0..15 (meaning 0-60 with a granularity of 4) 
+  *     RTS is asserted again when RX FIFO drops below the set trigger level (i.e. buffer has room again)    
   */
 #define TCR_HALT_DEFAULT                (0x0E)
-#define TCR_RESUME_DEFAULT              (0x04)  
+#define TCR_RESUME_DEFAULT              (0x08)  
 
+/** See section 8.12 of the datasheet for definitions
+  * Note: The device will stop transmissions from the TX FIFO when CTS is de-asserted by external receiver and 
+  *       auto CTS is enabled. Note that XON/XOFF is not supported in this lib.
+  */
   
-/** See section 8.13 of the datasheet for definitions
-  * of bits in the Trigger Level Register (TLR)
+    
+/** See section 7.5 and 8.13 of the datasheet for definitions
+  * of bits in the Trigger Level Register (TLR) control when an IRQ is generated.
   *   Trigger level for TX interrupt: 0..15 (meaning 0-60 with a granularity of 4) 
+  *     IRQ when TX FIFO is above the set trigger level (i.e. buffer is getting full)
   *   Trigger level for RX interrupt: 0..15 (meaning 0-60 with a granularity of 4) 
+  *     IRQ when RX FIFO is above the set trigger level (i.e. data is waiting to be read)
   */
 #define TLR_TX_DEFAULT                  (0x0E)
 #define TLR_RX_DEFAULT                  (0x04)  
 
 
 /**
+  * See section 8.16, 8.17, 8.18 of the datasheet for definitions
+  * of bits in the IO Direction (IODIR), IO State (IOSTATE) and IO Interrupt Enable register (IOINTENA)
+  * 
+  * Basically a direct mapping of register bits to GPIO pin.
+  */
+
+
+/**
   * See section 8.19 of the datasheet for definitions
   * of bits in the IO Control register (IOC)
   * 
@@ -207,9 +250,21 @@
   * Bit 2 is set to enable software reset.
   */
 #define IOC_ENA_LATCH                   (0x01)
-#define IOC_ENA_MODEM                   (0x02)
-#define IOC_SW_RST                      (0x04)
+#define IOC_ENA_MODEM                   (0x02) /* Set GPIO[7:4] pins to modem functions */
+#define IOC_SW_RST                      (0x04) 
+
 
+/**
+  * See section 8.20 of the datasheet for definitions
+  * of bits in the Extra Features Control register (EFCR)
+  * 
+  */
+#define EFCR_ENA_RS485                  (0x01)  
+#define EFCR_DIS_RX                     (0x02)    
+#define EFCR_DIS_TX                     (0x04)    
+#define EFCR_ENA_TX_RTS                 (0x10)    
+#define EFCR_INV_RTS_RS485              (0x20)    
+#define EFCR_ENA_IRDA                   (0x80)    
 
 // See Chapter 11 of datasheet
 #define SPI_READ_MODE_FLAG              (0x80)
@@ -223,9 +278,9 @@
   *
   * @endcode
   */
-//class SC16IS750 : public Serial { //Fout, geen Serial constr met Serial(NC, NC) toegestaan...
-class SC16IS750 {
-    
+//class SC16IS750 {
+//class SC16IS750 : public SerialBase, public Stream {    // Wrong, Serialbase can not be constructed for NC,NC
+class SC16IS750 : public Stream {    
 public:
 
 //  SC16IS750 Register definitions (shifted to align)
@@ -374,7 +429,16 @@
   *   @param *str char string to be written    
   *   @return none  
   */
-  void write(const char *str);
+  void writeString(const char *str);
+
+
+/**
+  * Write byte array to UART Bridge. Blocking when no free space in FIFO
+  *   @param *data byte array to be written    
+  *   @param len   number of bytes to write  
+  *   @return none  
+  */
+  void writeBytes(const char *data, int len);
     
 /** Set baudrate of the serial port.    
   *  @param  baud integer baudrate (4800, 9600 etc)
@@ -431,7 +495,7 @@
 /** Set the flow control type on the serial port
   *  Added for compatibility with Serial Class.
   *  SC16IS750 supports only Flow, Pins can not be selected. 
-  *  This method sets only hardware flow control. SC16IS750 supports XON/XOFF, but this is not implemented.   
+  *  This method sets hardware flow control levels. SC16IS750 supports XON/XOFF, but this is not implemented.  
   *
   *  @param type the flow control type (Disabled, RTS, CTS, RTSCTS)     
   *  @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
@@ -442,7 +506,7 @@
 
 
 /** Set the RX FIFO flow control levels
-  *  This method sets only hardware flow control levels. SC16IS750 supports XON/XOFF, but this is not implemented.   
+  *  This method sets hardware flow control levels. SC16IS750 supports XON/XOFF, but this is not implemented.   
   *  Should be called BEFORE Auto RTS is enabled.    
   *
   *  @param resume trigger level to resume transmission (0..15, meaning 0-60 with a granularity of 4)     
@@ -470,7 +534,7 @@
 
          
 
-/** FIFO control, sets TX and RX trigger levels and enables FIFO and save in _config
+/** FIFO control, sets TX and RX IRQ trigger levels and enables FIFO and save in _config
   *  Note FCR[5:4] (=TX_IRQ_LVL) only accessible when EFR[4] is set (enhanced functions enable)
   *  Note TLR only accessible when EFR[4] is set (enhanced functions enable) and MCR[2] is set 
   *   @param  none
@@ -485,9 +549,6 @@
   */
   void flush();
 
-//required for Stream
-  int peek() {return 0;};
-
 
 /** Set direction of I/O port pins.
   * This method is specific to the SPI-I2C UART and not found on the 16750
@@ -534,6 +595,15 @@
   */
   virtual char readRegister (RegisterName register_address ) =0;
 
+/** Write multiple datavalues to Transmitregister.
+  * More Efficient implementation than writing individual bytes
+  * Pure virtual, must be declared in derived class.   
+  *   @param char* databytes   The pointer to the block of data
+  *   @param len               The number of bytes to write
+  *   @return none 
+  */
+  virtual void writeDataBlock (const char *data, int len ) =0;
+
 
 /** Initialise internal registers
   * Should be in protection section. Public for testing purposes
@@ -552,6 +622,33 @@
   */
   SC16IS750();  
 
+/** Needed to implement Stream
+  *
+  * Read char from UART Bridge.
+  * Acts in the same manner as 'Serial.read()'.  
+  *   @param none    
+  *   @return char read or -1 if no data available. 
+  */  
+  virtual int _getc() {
+    return getc();
+  }
+
+
+/** Needed to implement Stream
+  *
+  * Write char to UART Bridge. Blocking when no free space in FIFO
+  *   @param value char to be written    
+  *   @return value written  
+  */
+  virtual int _putc(int c) {
+    return putc(c); 
+  }
+  
+/** Needed to implement Stream
+  *
+  */
+  virtual int peek() {return 0;};
+
 // Save config settings
 SC16IS750_cfg _config;
 
@@ -611,6 +708,17 @@
   */
   virtual char readRegister(SC16IS750::RegisterName registerAddress);
 
+/** Write multiple datavalues to Transmitregister.
+  * More Efficient implementation than writing individual bytes
+  * Assume that previous check confirmed that the FIFO has sufficient free space to store the data 
+  * Pure virtual, must be declared in derived class.   
+  *   @param char* databytes   The pointer to the block of data
+  *   @param len               The number of bytes to write
+  *   @return none 
+  */
+  virtual void writeDataBlock (const char *data, int len );
+
+
 protected:
 //protected is accessible to derived classes, but not to external users
 
@@ -672,6 +780,17 @@
   */
   virtual char readRegister(SC16IS750::RegisterName register_address );
 
+
+/** Write multiple datavalues to Transmitregister.
+  * More Efficient implementation than writing individual bytes
+  * Assume that previous check confirmed that the FIFO has sufficient free space to store the data 
+  * Pure virtual, must be declared in derived class.   
+  *   @param char* databytes   The pointer to the block of data
+  *   @param len               The number of bytes to write
+  *   @return none 
+  */
+  virtual void writeDataBlock (const char *data, int len );
+
 protected:
 //protected is accessible to derived classes, but not to external users