SPI or I2C to UART Bridge

Dependents:   SC16IS750_Test mbed_SC16IS750 Xadow_SC16IS750_Test Xadow_MPU9150AHRS

Revision:
2:76cb93b511f2
Parent:
1:0440152c5387
Child:
3:9783b6bde958
--- a/SC16IS750.h	Sun Feb 09 14:58:06 2014 +0000
+++ b/SC16IS750.h	Thu Feb 13 17:12:02 2014 +0000
@@ -1,5 +1,5 @@
 /* SC16IS750 interface 
- *   v0.1 WH, Nov 2013, Ported to mbed, Sparkfun Libs used as example. Added I2C and SPI I/F and more methods 
+ *   v0.1 WH, Nov 2013, Sparkfun Libs used as example. Added I2C I/F and many more methods 
  *
  * 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,
@@ -20,106 +20,91 @@
 #define _SC16IS750_H
 
 //I2C Slaveaddresses                     A1  A0 
-#define SC16IS750_SA0           0x90  /* VDD VDD */
-#define SC16IS750_SA1           0x92  /* VDD VSS */
-#define SC16IS750_SA2           0x94  /* VDD SCL */
-#define SC16IS750_SA3           0x95  /* VDD SDA */
-#define SC16IS750_SA4           0x98  /* VSS VDD */
-#define SC16IS750_SA5           0x9A  /* VSS VSS */
-#define SC16IS750_SA6           0x9C  /* VSS SCL */
-#define SC16IS750_SA7           0x9E  /* VSS SDA */
-#define SC16IS750_SA8           0xA0  /* SCL VDD */
-#define SC16IS750_SA9           0xA2  /* SCL VSS */
-#define SC16IS750_SA10          0xA4  /* SCL SCL */
-#define SC16IS750_SA11          0xA6  /* SCL SDA */
-#define SC16IS750_SA12          0xA8  /* SDA VDD */
-#define SC16IS750_SA13          0xAA  /* SDA VSS */
-#define SC16IS750_SA14          0xAC  /* SDA SCL */
-#define SC16IS750_SA15          0xAE  /* SDA SDA */
+#define SC16IS750_SA0            0x90  /* VDD VDD */
+#define SC16IS750_SA1            0x92  /* VDD VSS */
+#define SC16IS750_SA2            0x94  /* VDD SCL */
+#define SC16IS750_SA3            0x95  /* VDD SDA */
+#define SC16IS750_SA4            0x98  /* VSS VDD */
+#define SC16IS750_SA5            0x9A  /* VSS VSS */
+#define SC16IS750_SA6            0x9C  /* VSS SCL */
+#define SC16IS750_SA7            0x9E  /* VSS SDA */
+#define SC16IS750_SA8            0xA0  /* SCL VDD */
+#define SC16IS750_SA9            0xA2  /* SCL VSS */
+#define SC16IS750_SA10           0xA4  /* SCL SCL */
+#define SC16IS750_SA11           0xA6  /* SCL SDA */
+#define SC16IS750_SA12           0xA8  /* SDA VDD */
+#define SC16IS750_SA13           0xAA  /* SDA VSS */
+#define SC16IS750_SA14           0xAC  /* SDA SCL */
+#define SC16IS750_SA15           0xAE  /* SDA SDA */
 
 //Default I2C Slaveaddress
-#define DEFAULT_SC16IS750_ADDR  SC16IS750_SA0
+#define SC16IS750_DEFAULT_ADDR   SC16IS750_SA0
+
+
+/** See datasheet section 7.8 for configuring the
+  * "Programmable baud rate generator"
+  */
+#define SC16IS750_XTAL_FREQ              14745600UL /* On-board crystal (New mid-2010 Version) */
+#define SC16IS750_PRESCALER_1                   1   /* Default prescaler after reset           */
+#define SC16IS750_PRESCALER_4                   4   /* Selectable by setting MCR[7]            */
+#define SC16IS750_PRESCALER                      SC16IS750_PRESCALER_1  
+#define SC16IS750_BAUDRATE_DIVISOR(baud)       ((SC16IS750_XTAL_FREQ/SC16IS750_PRESCALER)/(baud*16UL))
 
 //Default baudrate
-#define DEFAULT_BAUD_RATE       9600
-
-#define ENABLE_BULK_TRANSFERS   0x01
-
-#define XTAL_FREQUENCY 14745600UL // On-board crystal (New mid-2010 Version)
-
-// See datasheet section 7.8 for configuring the
-// "Programmable baud rate generator"
-#define PRESCALER                  1 // Default prescaler after reset
-#define BAUD_RATE_DIVISOR(baud) ((XTAL_FREQUENCY/PRESCALER)/(baud*16UL))
-
-// See section 8.4 of the datasheet for definitions
-// of bits in the Line Control Register (LCR)
-#define LCR_BITS5                0x00
-#define LCR_BITS6                0x01
-#define LCR_BITS7                0x02
-#define LCR_BITS8                0x03
-
-#define LCR_BITS1                0x00
-#define LCR_BITS2                0x04
-
-#define LCR_NONE                 0x00
-#define LCR_ODD                  0x08
-#define LCR_EVEN                 0x18
-#define LCR_FORCED1              0x28
-#define LCR_FORCED0              0x38
-
-#define LCR_BRK_ENA              0x40
-#define LCR_BRK_DIS              0x00
-
-#define LCR_ENABLE_DIV           0x80
-#define LCR_DISABLE_DIV          0x00
-
-#define LCR_ENABLE_ENHANCED_FUNCTIONS (0xBF)
-
-// See section 8.10 of the datasheet for definitions
-// of bits in the Enhanced Features Register (EFR)
-#define EFR_ENABLE_CTS                (1 << 7)
-#define EFR_ENABLE_RTS                (1 << 6)
-#define EFR_ENABLE_ENHANCED_FUNCTIONS (1 << 4)
+#define SC16IS750_DEFAULT_BAUDRATE     9600
 
 
-// See section 8.xx of the datasheet for definitions
-// of bits in the Flow Control Register (FCR)
-#define FCR_RX_IRQ_14                 (3 << 6)
-#define FCR_RX_IRQ_8                  (2 << 6)
-#define FCR_RX_IRQ_4                  (1 << 6)
-#define FCR_RX_IRQ_1                  (0 << 6)
-#define FCR_RX_IRQ_NONE               (0 << 6)
-#define FCR_ENA_FIFO_64               (1 << 5)
+/** See section 8.3 of the datasheet for definitions
+  * of bits in the FIFO Control Register (FCR)
+  */
+#define FCR_RX_IRQ_60                 (3 << 6)
+#define FCR_RX_IRQ_56                 (2 << 6)
+#define FCR_RX_IRQ_16                 (1 << 6)
+#define FCR_RX_IRQ_8                  (0 << 6)
+//TX Level only accessible when EFR[4] is set
+#define FCR_TX_IRQ_56                 (3 << 4)
+#define FCR_TX_IRQ_32                 (2 << 4)
+#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_ENABLE_FIFO               (1 << 0)
 
+//FIFO size
+#define SC16IS750_FIFO_RX                  64
+#define SC16IS750_FIFO_TX                  64
 
 
-/*
- * Interrupt enable register.
- */
+/** See section 8.4 of the datasheet for definitions
+  * of bits in the Line Control Register (LCR)
+  */
+#define LCR_BITS5                      0x00
+#define LCR_BITS6                      0x01
+#define LCR_BITS7                      0x02
+#define LCR_BITS8                      0x03
 
-#define IER_ERBI  (0x01) /* Enable received data available interrupt            */
-#define IER_ETBEI (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_SLEEP (0x10) /* Enable sleep mode                                   */
+#define LCR_BITS1                      0x00
+#define LCR_BITS2                      0x04
 
-/*
- * Modem control register.
- */
+#define LCR_NONE                       0x00
+#define LCR_ODD                        0x08
+#define LCR_EVEN                       0x18
+#define LCR_FORCED1                    0x28
+#define LCR_FORCED0                    0x38
+
+#define LCR_BRK_ENA                    0x40
+#define LCR_BRK_DIS                    0x00
 
-#define MCR_MDTR (0x01) /* Data terminal ready. */
-#define MCR_MRTS (0x02) /* Request to send.     */
-//#define MCR_TCR_TLR_BIT (6)
-#define MCR_ENABLE_TCR_TLR (1 << 2)
+#define LCR_ENABLE_DIV                 0x80
+#define LCR_DISABLE_DIV                0x00
+
+#define LCR_ENABLE_ENHANCED_FUNCTIONS (0xBF)
 
-/*
- * Line status register.
- */
 
+/** 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_OE   (0x02) /* Overrun error                               */
 #define LSR_PE   (0x04) /* Parity error                                */
@@ -127,34 +112,107 @@
 #define LSR_BI   (0x10) /* Break interrupt                             */
 #define LSR_THRE (0x20) /* Transmitter holding register (FIFO empty)   */
 #define LSR_TEMT (0x40) /* Transmitter empty (FIFO and TSR both empty) */
+#define LSR_FFE  (0x80) /* At least one PE, FE or BI in FIFO           */
 
-/*
- * Interrupt identification register.
- * Bit 0 is set to 0 if an IT is pending.
- * Bits 1 and 2 are used to identify the IT.
- */
+
+/** See section 8.6 of the datasheet for definitions
+  * of bits in the Modem control register (MCR)
+  */
+#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.*/
+#define MCR_ENABLE_TCR_TLR            (1 << 2)
+#define MCR_ENABLE_LOOPBACK           (1 << 4)
+#define MCR_ENABLE_XON_ANY_CHAR       (1 << 5)
+#define MCR_ENABLE_IRDA               (1 << 6)
+#define MCR_PRESCALE_1                (0 << 7)
+#define MCR_PRESCALE_4                (1 << 7)
+
 
-#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.7 of the datasheet for definitions
+  * of bits in the Modem status register (MSR)
+  */
+
+
+/** 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_ELSI  (0x04) /* Enable receiver line status interrupt               */
+#define IER_EDSSI (0x08) /* Enable modem status interrupt                       */
+#define IER_SLEEP (0x10) /* Enable sleep mode                                   */
 
 
-/*
- * IO Control register.
- * Bit 0 is set to 0 to enable latch of IO inputs.
- * Bit 1 is set to enable GPIO[7-4] as /RI, /CD, /DTR, /DST.
- * Bit 2 is set to enable software reset.
- */
-#define IOC_ENA_LATCH      (0x01)
-#define IOC_ENA_MODEM      (0x02)
-#define IOC_SW_RST         (0x04)
+/** 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.
+  */
+#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
+  * of bits in the Enhanced Features Register (EFR)
+  */
+#define EFR_ENABLE_CTS                  (1 << 7)
+#define EFR_ENABLE_RTS                  (1 << 6)
+#define EFR_ENABLE_XOFF2_CHAR_DETECT    (1 << 5)
+#define EFR_ENABLE_ENHANCED_FUNCTIONS   (1 << 4)
+// EFR[3:0] are used to define Software Flow Control mode
+// See section 7.3
+#define EFR_DISABLE_TX_FLOW_CTRL        (0x0 << 2)
+#define EFR_TX_XON2_XOFF2               (0x1 << 2)
+#define EFR_TX_XON1_XOFF1               (0x2 << 2)
+#define EFR_TX_XON2_1_XOFF2_1           (0x3 << 2)
+
+#define EFR_DISABLE_RX_FLOW_CTRL        (0x0 << 0)
+#define EFR_RX_XON2_XOFF2               (0x1 << 0)
+#define EFR_RX_XON1_XOFF1               (0x2 << 0)
+#define EFR_RX_XON2_1_XOFF2_1           (0x3 << 0)
+
+#define EFR_TX_XON2_XOFF2_RX_FLOW       (0x1 << 2) | (0x3 << 0)
+#define EFR_TX_XON1_XOFF1_RX_FLOW       (0x2 << 2) | (0x3 << 0)
+#define EFR_TX_XON2_1_XOFF2_1_RX_FLOW   (0x3 << 2) | (0x3 << 0)
 
 
 
+/** 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) 
+  */
+#define TCR_HALT_DEFAULT                (0x0E)
+#define TCR_RESUME_DEFAULT              (0x04)  
+
+  
+/** See section 8.13 of the datasheet for definitions
+  * of bits in the Trigger Level Register (TLR)
+  *   Trigger level for TX interrupt: 0..15 (meaning 0-60 with a granularity of 4) 
+  *   Trigger level for RX interrupt: 0..15 (meaning 0-60 with a granularity of 4) 
+  */
+#define TLR_TX_DEFAULT                  (0x0E)
+#define TLR_RX_DEFAULT                  (0x04)  
+
+
+/**
+  * See section 8.19 of the datasheet for definitions
+  * of bits in the IO Control register (IOC)
+  * 
+  * Bit 0 is set to 0 to enable latch of IO inputs.
+  * Bit 1 is set to enable GPIO[7-4] as /RI, /CD, /DTR, /DST.
+  * Bit 2 is set to enable software reset.
+  */
+#define IOC_ENA_LATCH                   (0x01)
+#define IOC_ENA_MODEM                   (0x02)
+#define IOC_SW_RST                      (0x04)
+
+
 // See Chapter 11 of datasheet
-#define SPI_READ_MODE_FLAG      0x80
+#define SPI_READ_MODE_FLAG              (0x80)
 
 
 /** Abstract class SC16IS750 for a converter between either SPI or I2C and a Serial port
@@ -265,13 +323,19 @@
 
 
 /** Determine if there is a character available to read.
+  * This is data that's already arrived and stored in the receive
+  * buffer (which holds 64 chars).
+  *
   *   @return 1 if there is a character available to read, 0 otherwise
   */
   int readable();
 
-/** Determine how many characters available for reading.
+/** Determine how many characters are available to read.
+  * This is data that's already arrived and stored in the receive
+  * buffer (which holds 64 chars).
+  *
   *   @return int Characters available to read
-  */
+  */ 
   int readableCount();
 
 /** Determine if there is space available to write a character.    
@@ -279,9 +343,13 @@
   */
   int writable();
 
+  
 /** Determine how much space available for writing characters.
+  * This considers data that's already stored in the transmit
+  * buffer (which holds 64 chars).
+  *
   *   @return int character space available to write
-  */
+  */  
   int writableCount();
 
 
@@ -300,20 +368,28 @@
   */
   int putc(int value);    
 
+
+/**
+  * Write char string to UART Bridge. Blocking when no free space in FIFO
+  *   @param *str char string to be written    
+  *   @return none  
+  */
   void write(const char *str);
     
 /** Set baudrate of the serial port.    
   *  @param  baud integer baudrate (4800, 9600 etc)
   *  @return none
   */
-  void baud(int baudrate = DEFAULT_BAUD_RATE);   
+  void baud(int baudrate = SC16IS750_DEFAULT_BAUDRATE);   
 
 /** Set the transmission format used by the serial port.   
   *   @param bits      The number of bits in a word (5-8; default = 8)
   *   @param parity    The parity used (Serial::None, Serial::Odd, Serial::Even, Serial::Forced1, Serial::Forced0; default = Serial::None)
   *   @param stop_bits The number of stop bits (1 or 2; default = 1) 
+  *   @return none   
   */
   void format(int bits=8, Serial::Parity parity=Serial::None, int stop_bits=1);
+  
 #if(0)
 /** Attach a function to call whenever a serial interrupt is generated
   *
@@ -327,6 +403,7 @@
   *  @param tptr pointer to the object to call the member function on
   *  @param mptr pointer to the member function to be called
   *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+  *  @return none   
   */
   template<typename T>
     void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
@@ -338,25 +415,51 @@
 #endif
  
 /** Generate a break condition on the serial line
+  *  @param none
+  *  @return none 
   */
   void send_break();
 
 
 /** Set a break condition on the serial line
   *  @param enable  break condition
+  *  @return none   
   */
   void set_break(bool enable=false);
     
 
 /** Set the flow control type on the serial port
   *  Added for compatibility with Serial Class.
-  *  SC16IS750 supports only Flow, Pins can not be selected.  
+  *  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.   
   *
   *  @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)
   *  @param flow2 the second flow control pin (CTS for RTSCTS)
+  *  @return none   
   */
   void set_flow_control(Flow type=Disabled, PinName flow1=NC, PinName flow2=NC);
+
+
+/** Set the RX FIFO flow control levels
+  *  This method sets only 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)     
+  *  @param halt trigger level to resume transmission (0..15, meaning 0-60 with granularity of 4)           
+  *  @return none   
+  */
+  void set_flow_triggers(int resume = TCR_RESUME_DEFAULT, int halt = TCR_HALT_DEFAULT);
+
+
+/** Set the Modem Control register
+  *  This method sets prescaler, enables TCR and TLR
+  *
+  *  @param none 
+  *  @return none 
+  */
+  void set_modem_control();
+
  
 /**
   * Check that UART is connected and operational.
@@ -366,11 +469,15 @@
   bool connected();
 
          
-#if ENABLE_BULK_TRANSFERS
-    void write(const uint8_t *buffer, size_t size);
-#else
- //   using Print::write;
-#endif
+
+/** FIFO control, sets TX and RX 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
+  *   @return none
+  */
+  void set_fifo_control();
+
 
 /** Flush the UART FIFOs while maintaining current FIFO mode.
   *   @param  none
@@ -439,12 +546,13 @@
 protected:
 //protected is accessible to derived classes, but not to external users
 
-/** Constructor for this Abstract Class is protected
+
+/** Constructor is protected for this abstract Class
   *  
   */
   SC16IS750();  
 
-
+// Save config settings
 SC16IS750_cfg _config;
 
 private:
@@ -471,6 +579,9 @@
  *   while(1) { 
  *     serial_spi.ioSetState(0x00);
  *     wait(0.5);
+ *     serial_spi.ioSetState(0xFF); 
+ *     wait(0.5); 
+ *     serial_spi.putc('*');  
  *     pc.putc('*');                
  *   }
  * }
@@ -529,6 +640,9 @@
  *   while(1) { 
  *     serial_i2c.ioSetState(0x00);
  *     wait(0.5);
+ *     serial_i2c.ioSetState(0xFF); 
+ *     wait(0.5); 
+ *     serial_i2c.putc('*');   
  *     pc.putc('*');                
  *   }
  * }
@@ -543,7 +657,7 @@
   * @param I2C &i2c the I2C port to connect to 
   * @param char deviceAddress the address of the SC16IS750
   */  
-  SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress = DEFAULT_SC16IS750_ADDR);
+  SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress = SC16IS750_DEFAULT_ADDR);
 
 /** Write value to internal register.
   *   @param registerAddress   The address of the Register (enum RegisterName)