SPI or I2C to UART Bridge

Dependents:   SC16IS750_Test mbed_SC16IS750 Xadow_SC16IS750_Test Xadow_MPU9150AHRS

Committer:
wim
Date:
Wed Dec 24 01:05:49 2014 +0000
Revision:
5:ff3e57bebb6a
Parent:
4:12446ee9f9c8
Added Repeated Start for I2C readRegister(). Set I2C clock at 100kb/s. Fixed and added some comments.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 3:9783b6bde958 1 /* SC16IS750 I2C or SPI to UART bridge
wim 3:9783b6bde958 2 * v0.1 WH, Nov 2013, Sparkfun WiFly Shield code library alpha 0 used as example, Added I2C I/F and many more methods.
wim 3:9783b6bde958 3 * https://forum.sparkfun.com/viewtopic.php?f=13&t=21846
wim 4:12446ee9f9c8 4 * v0.2 WH, Feb 2014, Added Doxygen Documentation, Added Hardware Reset pin methods.
wim 4:12446ee9f9c8 5 * v0.3 WH, Dec 2014, Added support for SC16IS752 dual UART.
wim 5:ff3e57bebb6a 6 * v0.4 WH, Dec 2014, Added Repeated Start for I2C readRegister(). Set I2C clock at 100kb/s. Fixed and added some comments.
wim 0:d64854a60f95 7 *
wim 0:d64854a60f95 8 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
wim 0:d64854a60f95 9 * and associated documentation files (the "Software"), to deal in the Software without restriction,
wim 0:d64854a60f95 10 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
wim 0:d64854a60f95 11 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
wim 0:d64854a60f95 12 * furnished to do so, subject to the following conditions:
wim 0:d64854a60f95 13 *
wim 0:d64854a60f95 14 * The above copyright notice and this permission notice shall be included in all copies or
wim 0:d64854a60f95 15 * substantial portions of the Software.
wim 0:d64854a60f95 16 *
wim 0:d64854a60f95 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
wim 0:d64854a60f95 18 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
wim 0:d64854a60f95 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
wim 0:d64854a60f95 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:d64854a60f95 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
wim 0:d64854a60f95 22 */
wim 0:d64854a60f95 23 #include "mbed.h"
wim 0:d64854a60f95 24 #include "SC16IS750.h"
wim 0:d64854a60f95 25
wim 3:9783b6bde958 26 #define ENABLE_BULK_TRANSFERS 1
wim 3:9783b6bde958 27 #define BULK_BLOCK_LEN 16
wim 0:d64854a60f95 28
wim 0:d64854a60f95 29 /** Abstract class SC16IS750 for converter between either SPI or I2C and a Serial port
wim 1:0440152c5387 30 * Constructor for this Abstract Class is protected
wim 0:d64854a60f95 31 * Supports both SPI and I2C interfaces through derived classes
wim 0:d64854a60f95 32 *
wim 0:d64854a60f95 33 * @code
wim 0:d64854a60f95 34 *
wim 0:d64854a60f95 35 * @endcode
wim 0:d64854a60f95 36 */
wim 3:9783b6bde958 37 SC16IS750::SC16IS750() {
wim 3:9783b6bde958 38 //SC16IS750::SC16IS750() : Serial(NC, NC) { //Fout, mag geen NC zijn
wim 3:9783b6bde958 39 //SC16IS750::SC16IS750() : SerialBase(NC, NC) { //Fout, mag geen NC zijn
wim 1:0440152c5387 40 // Dont call _init() here since the SPI or I2C port have not yet been configured...
wim 1:0440152c5387 41 //_init(); // initialise UART registers
wim 0:d64854a60f95 42 }
wim 0:d64854a60f95 43
wim 0:d64854a60f95 44
wim 0:d64854a60f95 45 /** Set baudrate of the serial port.
wim 0:d64854a60f95 46 * @param baud integer baudrate (4800, 9600 etc)
wim 0:d64854a60f95 47 * @return none
wim 0:d64854a60f95 48 */
wim 0:d64854a60f95 49 void SC16IS750::baud(int baudrate) {
wim 2:76cb93b511f2 50 unsigned long divisor = SC16IS750_BAUDRATE_DIVISOR(baudrate);
wim 0:d64854a60f95 51 char lcr_tmp;
wim 0:d64854a60f95 52
wim 0:d64854a60f95 53 _config.baudrate = baudrate; // Save baudrate
wim 0:d64854a60f95 54
wim 0:d64854a60f95 55 lcr_tmp = this->readRegister(LCR); // Read current LCR register
wim 1:0440152c5387 56 this->writeRegister(LCR, lcr_tmp | LCR_ENABLE_DIV); // Enable Divisor registers
wim 0:d64854a60f95 57 this->writeRegister(DLL, ( divisor & 0xFF)); // write divisor LSB
wim 0:d64854a60f95 58 this->writeRegister(DLH, ((divisor >> 8) & 0xFF)); // write divisor MSB
wim 0:d64854a60f95 59 this->writeRegister(LCR, lcr_tmp); // Restore LCR register, activate regular RBR, THR and IER registers
wim 1:0440152c5387 60
wim 0:d64854a60f95 61 }
wim 0:d64854a60f95 62
wim 0:d64854a60f95 63
wim 0:d64854a60f95 64 /** Set the transmission format used by the serial port.
wim 0:d64854a60f95 65 * @param bits The number of bits in a word (5-8; default = 8)
wim 0:d64854a60f95 66 * @param parity The parity used (Serial::None, Serial::Odd, Serial::Even, Serial::Forced1, Serial::Forced0; default = Serial::None)
wim 0:d64854a60f95 67 * @param stop_bits The number of stop bits (1 or 2; default = 1)
wim 2:76cb93b511f2 68 * @return none
wim 0:d64854a60f95 69 */
wim 0:d64854a60f95 70 void SC16IS750::format(int bits, Serial::Parity parity, int stop_bits) {
wim 0:d64854a60f95 71 char lcr_tmp = 0x00;
wim 0:d64854a60f95 72
wim 0:d64854a60f95 73 switch (bits) {
wim 0:d64854a60f95 74 case 5: lcr_tmp |= LCR_BITS5;
wim 0:d64854a60f95 75 break;
wim 0:d64854a60f95 76 case 6: lcr_tmp |= LCR_BITS6;
wim 0:d64854a60f95 77 break;
wim 0:d64854a60f95 78 case 7: lcr_tmp |= LCR_BITS7;
wim 0:d64854a60f95 79 break;
wim 0:d64854a60f95 80 case 8: lcr_tmp |= LCR_BITS8;
wim 0:d64854a60f95 81 break;
wim 0:d64854a60f95 82 default: lcr_tmp |= LCR_BITS8;
wim 0:d64854a60f95 83 }
wim 0:d64854a60f95 84
wim 0:d64854a60f95 85 switch (parity) {
wim 0:d64854a60f95 86 case Serial::None: lcr_tmp |= LCR_NONE;
wim 0:d64854a60f95 87 break;
wim 0:d64854a60f95 88 case Serial::Odd: lcr_tmp |= LCR_ODD;
wim 0:d64854a60f95 89 break;
wim 0:d64854a60f95 90 case Serial::Even: lcr_tmp |= LCR_EVEN;
wim 0:d64854a60f95 91 break;
wim 0:d64854a60f95 92 case Serial::Forced1: lcr_tmp |= LCR_FORCED1;
wim 0:d64854a60f95 93 break;
wim 0:d64854a60f95 94 case Serial::Forced0: lcr_tmp |= LCR_FORCED0;
wim 0:d64854a60f95 95 break;
wim 0:d64854a60f95 96 default: lcr_tmp |= LCR_NONE;
wim 0:d64854a60f95 97 }
wim 0:d64854a60f95 98
wim 0:d64854a60f95 99 switch (stop_bits) {
wim 0:d64854a60f95 100 case 1: lcr_tmp |= LCR_BITS1;
wim 0:d64854a60f95 101 break;
wim 0:d64854a60f95 102 case 2: lcr_tmp |= LCR_BITS2;
wim 0:d64854a60f95 103 break;
wim 0:d64854a60f95 104 default: lcr_tmp |= LCR_BITS1;
wim 0:d64854a60f95 105 }
wim 0:d64854a60f95 106
wim 0:d64854a60f95 107 _config.dataformat = lcr_tmp; // Save dataformat
wim 0:d64854a60f95 108
wim 0:d64854a60f95 109 this->writeRegister(LCR, lcr_tmp); // Set LCR register, activate regular RBR, THR and IER registers
wim 0:d64854a60f95 110
wim 0:d64854a60f95 111 };
wim 0:d64854a60f95 112
wim 1:0440152c5387 113 /** Generate a break condition on the serial line
wim 2:76cb93b511f2 114 * @return none
wim 1:0440152c5387 115 */
wim 1:0440152c5387 116 void SC16IS750::send_break() {
wim 1:0440152c5387 117 // Wait for 1.5 frames before clearing the break condition
wim 1:0440152c5387 118 // This will have different effects on our platforms, but should
wim 1:0440152c5387 119 // ensure that we keep the break active for at least one frame.
wim 1:0440152c5387 120 // We consider a full frame (1 start bit + 8 data bits bits +
wim 1:0440152c5387 121 // 1 parity bit + 2 stop bits = 12 bits) for computation.
wim 1:0440152c5387 122 // One bit time (in us) = 1000000/_baud
wim 1:0440152c5387 123 // Twelve bits: 12000000/baud delay
wim 1:0440152c5387 124 // 1.5 frames: 18000000/baud delay
wim 1:0440152c5387 125 set_break(true);
wim 1:0440152c5387 126 wait_us(18000000/_config.baudrate);
wim 1:0440152c5387 127 set_break(false);
wim 1:0440152c5387 128 };
wim 1:0440152c5387 129
wim 1:0440152c5387 130 /** Set a break condition on the serial line
wim 1:0440152c5387 131 * @param enable break condition
wim 2:76cb93b511f2 132 * @return none
wim 1:0440152c5387 133 */
wim 1:0440152c5387 134 void SC16IS750::set_break(bool enable) {
wim 0:d64854a60f95 135
wim 1:0440152c5387 136 if (enable) {
wim 1:0440152c5387 137 _config.dataformat |= LCR_BRK_ENA; // Save dataformat
wim 1:0440152c5387 138 }
wim 1:0440152c5387 139 else {
wim 1:0440152c5387 140 _config.dataformat &= ~LCR_BRK_ENA; // Save dataformat
wim 1:0440152c5387 141 }
wim 1:0440152c5387 142
wim 1:0440152c5387 143 this->writeRegister(LCR, _config.dataformat); // Set LCR register
wim 1:0440152c5387 144 }
wim 1:0440152c5387 145
wim 1:0440152c5387 146 /** Set the flow control type on the serial port
wim 1:0440152c5387 147 * Added for compatibility with Serial Class.
wim 1:0440152c5387 148 * SC16IS750 supports only Flow, Pins can not be selected.
wim 3:9783b6bde958 149 * This method sets hardware flow control. SC16IS750 supports XON/XOFF, but this is not implemented.
wim 0:d64854a60f95 150 *
wim 1:0440152c5387 151 * @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
wim 2:76cb93b511f2 152 * @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS) - NOT USED
wim 2:76cb93b511f2 153 * @param flow2 the second flow control pin (CTS for RTSCTS) - NOT USED
wim 2:76cb93b511f2 154 * @return none
wim 0:d64854a60f95 155 */
wim 1:0440152c5387 156 void SC16IS750::set_flow_control(Flow type, PinName flow1, PinName flow2) {
wim 1:0440152c5387 157 char lcr_tmp;
wim 1:0440152c5387 158 char efr_tmp = 0x00;
wim 1:0440152c5387 159
wim 1:0440152c5387 160 // We need to enable flow control to prevent overflow of buffers and
wim 1:0440152c5387 161 // lose data when used with fast devices like the WiFly.
wim 1:0440152c5387 162
wim 1:0440152c5387 163 switch (type) {
wim 1:0440152c5387 164 case Disabled :
wim 1:0440152c5387 165 break;
wim 1:0440152c5387 166 case RTS: efr_tmp = EFR_ENABLE_RTS;
wim 1:0440152c5387 167 break;
wim 1:0440152c5387 168 case CTS: efr_tmp = EFR_ENABLE_CTS;
wim 1:0440152c5387 169 break;
wim 1:0440152c5387 170 case RTSCTS: efr_tmp = EFR_ENABLE_RTS | EFR_ENABLE_CTS;
wim 1:0440152c5387 171 break;
wim 1:0440152c5387 172 default: ;
wim 1:0440152c5387 173
wim 1:0440152c5387 174 }
wim 1:0440152c5387 175
wim 2:76cb93b511f2 176 //Save flowcontrol mode and enable enhanced functions
wim 2:76cb93b511f2 177 _config.flowctrl = efr_tmp | EFR_ENABLE_ENHANCED_FUNCTIONS;
wim 1:0440152c5387 178
wim 1:0440152c5387 179 lcr_tmp = this->readRegister(LCR); // save LRC register
wim 1:0440152c5387 180 this->writeRegister(LCR, LCR_ENABLE_ENHANCED_FUNCTIONS); // write magic number 0xBF to enable access to EFR register
wim 1:0440152c5387 181 this->writeRegister(EFR, _config.flowctrl); // set flow and enable enhanced functions
wim 1:0440152c5387 182 this->writeRegister(LCR, lcr_tmp); // restore LCR register
wim 1:0440152c5387 183 }
wim 2:76cb93b511f2 184
wim 2:76cb93b511f2 185 /** Set the RX FIFO flow control levels
wim 3:9783b6bde958 186 * This method sets hardware flow control levels. SC16IS750 supports XON/XOFF, but this is not implemented.
wim 2:76cb93b511f2 187 * Should be called BEFORE Auto RTS is enabled.
wim 2:76cb93b511f2 188 *
wim 2:76cb93b511f2 189 * @param resume trigger level to resume transmission (0..15, meaning 0-60 with a granularity of 4)
wim 2:76cb93b511f2 190 * @param halt trigger level to resume transmission (0..15, meaning 0-60 with granularity of 4)
wim 2:76cb93b511f2 191 * @return none
wim 2:76cb93b511f2 192 */
wim 2:76cb93b511f2 193 void SC16IS750::set_flow_triggers(int resume, int halt) {
wim 2:76cb93b511f2 194
wim 2:76cb93b511f2 195 // sanity checks
wim 2:76cb93b511f2 196 halt = halt & 0x0F;
wim 2:76cb93b511f2 197 resume = resume & 0x0F;
wim 2:76cb93b511f2 198 if (halt <= resume) {
wim 2:76cb93b511f2 199 halt = TCR_HALT_DEFAULT;
wim 2:76cb93b511f2 200 resume = TCR_RESUME_DEFAULT;
wim 2:76cb93b511f2 201 }
wim 2:76cb93b511f2 202
wim 2:76cb93b511f2 203 // Note: TCR accessible only when EFR[4]=1 and MCR[2]=1
wim 2:76cb93b511f2 204 this->writeRegister(TCR, (resume << 4) | halt); // set TCR register
wim 2:76cb93b511f2 205 }
wim 2:76cb93b511f2 206
wim 2:76cb93b511f2 207
wim 2:76cb93b511f2 208 /** Set the Modem Control register
wim 2:76cb93b511f2 209 * This method sets prescaler, enables TCR and TLR
wim 2:76cb93b511f2 210 *
wim 2:76cb93b511f2 211 * @param none
wim 2:76cb93b511f2 212 * @return none
wim 2:76cb93b511f2 213 */
wim 2:76cb93b511f2 214 void SC16IS750::set_modem_control() {
wim 2:76cb93b511f2 215
wim 2:76cb93b511f2 216 //Note MCR[7:4] and MCR[2] only accessible when EFR[4] is set
wim 2:76cb93b511f2 217 if (SC16IS750_PRESCALER == SC16IS750_PRESCALER_1) { // Default prescaler after reset
wim 2:76cb93b511f2 218 this->writeRegister(MCR, MCR_PRESCALE_1 | MCR_ENABLE_TCR_TLR);
wim 2:76cb93b511f2 219 }
wim 2:76cb93b511f2 220 else {
wim 2:76cb93b511f2 221 this->writeRegister(MCR, MCR_PRESCALE_4 | MCR_ENABLE_TCR_TLR);
wim 2:76cb93b511f2 222 }
wim 2:76cb93b511f2 223 }
wim 2:76cb93b511f2 224
wim 1:0440152c5387 225
wim 1:0440152c5387 226
wim 1:0440152c5387 227 /** Initialise internal registers
wim 1:0440152c5387 228 * Should be in protection section. Public for testing purposes
wim 1:0440152c5387 229 * If initialisation fails this method does not return.
wim 1:0440152c5387 230 * @param none
wim 1:0440152c5387 231 * @return none
wim 1:0440152c5387 232 */
wim 1:0440152c5387 233 void SC16IS750::_init() {
wim 0:d64854a60f95 234
wim 0:d64854a60f95 235 // Initialise SC16IS750
wim 0:d64854a60f95 236
wim 4:12446ee9f9c8 237 // Hardware reset, assuming there is a HW Reset pin
wim 4:12446ee9f9c8 238 // this->hwReset();
wim 4:12446ee9f9c8 239
wim 1:0440152c5387 240 // Software reset, assuming there is no access to the HW Reset pin
wim 1:0440152c5387 241 swReset();
wim 4:12446ee9f9c8 242
wim 2:76cb93b511f2 243 // Set default baudrate (depends on prescaler) and save in _config
wim 2:76cb93b511f2 244 // DLL/DLH
wim 0:d64854a60f95 245 baud();
wim 0:d64854a60f95 246
wim 0:d64854a60f95 247 // Set default dataformat and save in _config
wim 1:0440152c5387 248 // LCR
wim 0:d64854a60f95 249 format();
wim 0:d64854a60f95 250
wim 2:76cb93b511f2 251 // Set dataflow mode and Enables enhanced functions
wim 2:76cb93b511f2 252 // Save in _config
wim 2:76cb93b511f2 253 // EFR
wim 2:76cb93b511f2 254 set_flow_control();
wim 2:76cb93b511f2 255
wim 2:76cb93b511f2 256
wim 3:9783b6bde958 257 // FIFO control, sets TX and RX IRQ trigger levels and enables FIFO and save in _config
wim 2:76cb93b511f2 258 // Note FCR[5:4] only accessible when EFR[4] is set (enhanced functions enable)
wim 2:76cb93b511f2 259 // FCR, TLR
wim 2:76cb93b511f2 260 set_fifo_control();
wim 2:76cb93b511f2 261 flush();
wim 2:76cb93b511f2 262
wim 2:76cb93b511f2 263 // Modem control, sets prescaler, enable TCR and TLR
wim 2:76cb93b511f2 264 // Note MCR[7:4] and MCR[2] only accessible when EFR[4] is set (enhanced functions enable)
wim 2:76cb93b511f2 265 set_modem_control();
wim 2:76cb93b511f2 266
wim 2:76cb93b511f2 267 // Set RTS trigger levels
wim 2:76cb93b511f2 268 // Note TCR only accessible when EFR[4] is set (enhanced functions enable) and MCR[2] is set
wim 2:76cb93b511f2 269 set_flow_triggers();
wim 2:76cb93b511f2 270
wim 2:76cb93b511f2 271
wim 1:0440152c5387 272 // Set default break condition and save in _config
wim 1:0440152c5387 273 // LCR
wim 1:0440152c5387 274 //set_break();
wim 2:76cb93b511f2 275
wim 0:d64854a60f95 276 // The UART bridge should now be successfully initialised.
wim 0:d64854a60f95 277
wim 0:d64854a60f95 278 // Test if UART bridge is present and initialised
wim 0:d64854a60f95 279 if(!connected()){
wim 0:d64854a60f95 280 #if(0)
wim 0:d64854a60f95 281 // Lock up if we fail to initialise UART bridge.
wim 1:0440152c5387 282 while(1) {};
wim 0:d64854a60f95 283 #else
wim 0:d64854a60f95 284 printf("Failed to initialise UART bridge\r\n");
wim 1:0440152c5387 285 #endif
wim 1:0440152c5387 286 }
wim 1:0440152c5387 287 else {
wim 1:0440152c5387 288 printf("Initialised UART bridge!\r\n");
wim 1:0440152c5387 289 }
wim 1:0440152c5387 290
wim 1:0440152c5387 291 }
wim 1:0440152c5387 292
wim 2:76cb93b511f2 293
wim 2:76cb93b511f2 294 /** FIFO control, sets TX and RX trigger levels and enables FIFO and save in _config
wim 2:76cb93b511f2 295 * Note FCR[5:4] (=TX_IRQ_LVL) only accessible when EFR[4] is set (enhanced functions enable)
wim 2:76cb93b511f2 296 * Note TLR only accessible when EFR[4] is set (enhanced functions enable) and MCR[2] is set
wim 2:76cb93b511f2 297 * @param none
wim 2:76cb93b511f2 298 * @return none
wim 2:76cb93b511f2 299 */
wim 2:76cb93b511f2 300 void SC16IS750::set_fifo_control() {
wim 2:76cb93b511f2 301
wim 2:76cb93b511f2 302 // Set default fifoformat
wim 2:76cb93b511f2 303 // FCR
wim 2:76cb93b511f2 304 _config.fifoenable = true;
wim 2:76cb93b511f2 305
wim 2:76cb93b511f2 306 // Note FCR[5:4] (=TX_IRQ_LVL) only accessible when EFR[4] is set (enhanced functions enable)
wim 2:76cb93b511f2 307 // _config.fifoformat = FCR_RX_IRQ_8 | FCR_TX_IRQ_56;
wim 2:76cb93b511f2 308 _config.fifoformat = FCR_RX_IRQ_8 | FCR_TX_IRQ_8; //Default
wim 2:76cb93b511f2 309
wim 2:76cb93b511f2 310 if (_config.fifoenable)
wim 2:76cb93b511f2 311 // enable FIFO mode and set FIFO control values
wim 2:76cb93b511f2 312 this->writeRegister(FCR, _config.fifoformat | FCR_ENABLE_FIFO);
wim 2:76cb93b511f2 313 else
wim 2:76cb93b511f2 314 // disable FIFO mode and set FIFO control values
wim 2:76cb93b511f2 315 this->writeRegister(FCR, _config.fifoformat);
wim 2:76cb93b511f2 316
wim 2:76cb93b511f2 317 // Set Trigger level register TLR for RX and TX interrupt generation
wim 2:76cb93b511f2 318 // Note TLR only accessible when EFR[4] is set (enhanced functions enable) and MCR[2] is set
wim 2:76cb93b511f2 319 // TRL Trigger levels for RX and TX are 0..15, meaning 0-60 with a granularity of 4 chars
wim 2:76cb93b511f2 320 // When TLR for RX or TX are 'Zero' the corresponding values in FCR are used. The FCR settings
wim 2:76cb93b511f2 321 // have less resolution (only 4 levels) so TLR is considered an enhanced function.
wim 2:76cb93b511f2 322 this->writeRegister(TLR, 0x00); // Use FCR Levels
wim 2:76cb93b511f2 323 // this->writeRegister(TLR, (TLR_RX_DEFAULT << 4) | TLR_TX_DEFAULT); // Use Default enhanced levels
wim 2:76cb93b511f2 324
wim 2:76cb93b511f2 325 }
wim 2:76cb93b511f2 326
wim 2:76cb93b511f2 327
wim 1:0440152c5387 328 /**
wim 1:0440152c5387 329 * Flush the UART FIFOs while maintaining current FIFO mode.
wim 1:0440152c5387 330 * @param none
wim 1:0440152c5387 331 * @return none
wim 1:0440152c5387 332 */
wim 1:0440152c5387 333 void SC16IS750::flush() {
wim 2:76cb93b511f2 334 // FCR is Write Only, use saved _config
wim 1:0440152c5387 335
wim 1:0440152c5387 336 // reset TXFIFO, reset RXFIFO, non FIFO mode
wim 3:9783b6bde958 337 this->writeRegister(FCR, FCR_TX_FIFO_RST | FCR_RX_FIFO_RST);
wim 1:0440152c5387 338
wim 1:0440152c5387 339 if (_config.fifoenable)
wim 1:0440152c5387 340 // enable FIFO mode and set FIFO control values
wim 1:0440152c5387 341 this->writeRegister(FCR, _config.fifoformat | FCR_ENABLE_FIFO);
wim 1:0440152c5387 342 else
wim 1:0440152c5387 343 // disable FIFO mode and set FIFO control values
wim 1:0440152c5387 344 this->writeRegister(FCR, _config.fifoformat);
wim 1:0440152c5387 345
wim 1:0440152c5387 346 #if(0)
wim 1:0440152c5387 347 //original
wim 1:0440152c5387 348 /*
wim 1:0440152c5387 349 * Flush characters from SC16IS750 receive buffer.
wim 1:0440152c5387 350 */
wim 1:0440152c5387 351
wim 1:0440152c5387 352 // Note: This may not be the most appropriate flush approach.
wim 1:0440152c5387 353 // It might be better to just flush the UART's buffer
wim 1:0440152c5387 354 // rather than the buffer of the connected device
wim 1:0440152c5387 355 // which is essentially what this does.
wim 1:0440152c5387 356 while(readable() > 0) {
wim 1:0440152c5387 357 getc();
wim 0:d64854a60f95 358 }
wim 0:d64854a60f95 359 #endif
wim 0:d64854a60f95 360
wim 0:d64854a60f95 361 }
wim 0:d64854a60f95 362
wim 0:d64854a60f95 363
wim 0:d64854a60f95 364 /**
wim 0:d64854a60f95 365 * Check that UART is connected and operational.
wim 0:d64854a60f95 366 * @param none
wim 0:d64854a60f95 367 * @return bool true when connected, false otherwise
wim 0:d64854a60f95 368 */
wim 0:d64854a60f95 369 bool SC16IS750::connected() {
wim 0:d64854a60f95 370 // Perform read/write test to check if UART is working
wim 0:d64854a60f95 371 const char TEST_CHARACTER = 'H';
wim 0:d64854a60f95 372
wim 0:d64854a60f95 373 this->writeRegister(SPR, TEST_CHARACTER);
wim 0:d64854a60f95 374
wim 0:d64854a60f95 375 return (this->readRegister(SPR) == TEST_CHARACTER);
wim 0:d64854a60f95 376 }
wim 0:d64854a60f95 377
wim 0:d64854a60f95 378
wim 0:d64854a60f95 379 /** Determine if there is a character available to read.
wim 2:76cb93b511f2 380 * This is data that's already arrived and stored in the receive
wim 2:76cb93b511f2 381 * buffer (which holds 64 chars).
wim 2:76cb93b511f2 382 *
wim 0:d64854a60f95 383 * @return 1 if there is a character available to read, 0 otherwise
wim 0:d64854a60f95 384 */
wim 0:d64854a60f95 385 int SC16IS750::readable() {
wim 2:76cb93b511f2 386
wim 2:76cb93b511f2 387 // if (this->readableCount() > 0) { // Check count
wim 2:76cb93b511f2 388 if (this->readRegister(LSR) & LSR_DR) { // Data in Receiver Bit, at least one character waiting
wim 2:76cb93b511f2 389 return 1;
wim 2:76cb93b511f2 390 }
wim 2:76cb93b511f2 391 else {
wim 2:76cb93b511f2 392 return 0;
wim 2:76cb93b511f2 393 }
wim 0:d64854a60f95 394 }
wim 0:d64854a60f95 395
wim 1:0440152c5387 396 /** Determine how many characters are available to read.
wim 2:76cb93b511f2 397 * This is data that's already arrived and stored in the receive
wim 2:76cb93b511f2 398 * buffer (which holds 64 chars).
wim 2:76cb93b511f2 399 *
wim 0:d64854a60f95 400 * @return int Characters available to read
wim 0:d64854a60f95 401 */
wim 0:d64854a60f95 402 int SC16IS750::readableCount() {
wim 0:d64854a60f95 403
wim 0:d64854a60f95 404 return (this->readRegister(RXLVL));
wim 0:d64854a60f95 405 }
wim 0:d64854a60f95 406
wim 0:d64854a60f95 407 /** Determine if there is space available to write a character.
wim 0:d64854a60f95 408 * @return 1 if there is a space for a character to write, 0 otherwise
wim 0:d64854a60f95 409 */
wim 0:d64854a60f95 410 int SC16IS750::writable() {
wim 2:76cb93b511f2 411
wim 2:76cb93b511f2 412 // if ((this->writableCount() > 0) { // Check count
wim 2:76cb93b511f2 413 if (this->readRegister(LSR) & LSR_THRE) { // THR Empty, space for at least one character
wim 2:76cb93b511f2 414 return 1;
wim 2:76cb93b511f2 415 }
wim 2:76cb93b511f2 416 else {
wim 2:76cb93b511f2 417 return 0;
wim 2:76cb93b511f2 418 }
wim 0:d64854a60f95 419 }
wim 0:d64854a60f95 420
wim 1:0440152c5387 421 /** Determine how much space available for writing characters.
wim 2:76cb93b511f2 422 * This considers data that's already stored in the transmit
wim 2:76cb93b511f2 423 * buffer (which holds 64 chars).
wim 2:76cb93b511f2 424 *
wim 1:0440152c5387 425 * @return int character space available to write
wim 0:d64854a60f95 426 */
wim 0:d64854a60f95 427 int SC16IS750::writableCount() {
wim 0:d64854a60f95 428
wim 2:76cb93b511f2 429 return (this->readRegister(TXLVL)); // TX Level
wim 0:d64854a60f95 430 }
wim 0:d64854a60f95 431
wim 0:d64854a60f95 432
wim 1:0440152c5387 433 /**
wim 1:0440152c5387 434 * Read char from UART Bridge.
wim 1:0440152c5387 435 * Acts in the same manner as 'Serial.read()'.
wim 1:0440152c5387 436 * @param none
wim 1:0440152c5387 437 * @return char read or -1 if no data available.
wim 1:0440152c5387 438 */
wim 1:0440152c5387 439 int SC16IS750::getc() {
wim 0:d64854a60f95 440
wim 0:d64854a60f95 441 if (!readable()) {
wim 0:d64854a60f95 442 return -1;
wim 0:d64854a60f95 443 }
wim 0:d64854a60f95 444
wim 0:d64854a60f95 445 return this->readRegister(RHR);
wim 0:d64854a60f95 446 }
wim 0:d64854a60f95 447
wim 3:9783b6bde958 448
wim 1:0440152c5387 449 /**
wim 1:0440152c5387 450 * Write char to UART Bridge. Blocking when no free space in FIFO
wim 1:0440152c5387 451 * @param value char to be written
wim 1:0440152c5387 452 * @return value written
wim 1:0440152c5387 453 */
wim 1:0440152c5387 454 int SC16IS750::putc(int value) {
wim 2:76cb93b511f2 455
wim 0:d64854a60f95 456 while (this->readRegister(TXLVL) == 0) {
wim 0:d64854a60f95 457 // Wait for space in TX buffer
wim 1:0440152c5387 458 wait_us(10);
wim 0:d64854a60f95 459 };
wim 0:d64854a60f95 460 this->writeRegister(THR, value);
wim 1:0440152c5387 461
wim 1:0440152c5387 462 return value;
wim 0:d64854a60f95 463 }
wim 0:d64854a60f95 464
wim 3:9783b6bde958 465
wim 2:76cb93b511f2 466 /**
wim 2:76cb93b511f2 467 * Write char string to UART Bridge. Blocking when no free space in FIFO
wim 2:76cb93b511f2 468 * @param *str char string to be written
wim 2:76cb93b511f2 469 * @return none
wim 2:76cb93b511f2 470 */
wim 3:9783b6bde958 471 void SC16IS750::writeString(const char *str) {
wim 0:d64854a60f95 472
wim 0:d64854a60f95 473 #if ENABLE_BULK_TRANSFERS
wim 2:76cb93b511f2 474 int len, idx;
wim 0:d64854a60f95 475
wim 2:76cb93b511f2 476 len = strlen(str);
wim 0:d64854a60f95 477
wim 2:76cb93b511f2 478 // Write blocks of BULK_BLOCK_LEN
wim 2:76cb93b511f2 479 while (len > BULK_BLOCK_LEN) {
wim 2:76cb93b511f2 480 while(this->readRegister(TXLVL) < BULK_BLOCK_LEN) {
wim 2:76cb93b511f2 481 // Wait for space in TX buffer
wim 2:76cb93b511f2 482 wait_us(10);
wim 2:76cb93b511f2 483 };
wim 2:76cb93b511f2 484
wim 2:76cb93b511f2 485 // Write a block of BULK_BLOCK_LEN bytes
wim 3:9783b6bde958 486 #if (0)
wim 3:9783b6bde958 487 // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes.
wim 2:76cb93b511f2 488 for (idx=0; idx<BULK_BLOCK_LEN; idx++) {
wim 2:76cb93b511f2 489 this->writeRegister(THR, str[idx]);
wim 2:76cb93b511f2 490 };
wim 3:9783b6bde958 491 #else
wim 3:9783b6bde958 492 // optimized
wim 3:9783b6bde958 493 this->writeDataBlock(str, BULK_BLOCK_LEN);
wim 3:9783b6bde958 494 #endif
wim 3:9783b6bde958 495
wim 2:76cb93b511f2 496 len -= BULK_BLOCK_LEN;
wim 2:76cb93b511f2 497 str += BULK_BLOCK_LEN;
wim 0:d64854a60f95 498 }
wim 2:76cb93b511f2 499
wim 2:76cb93b511f2 500 // Write remaining bytes
wim 3:9783b6bde958 501 // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes.
wim 2:76cb93b511f2 502 for (idx=0; idx<len; idx++) {
wim 2:76cb93b511f2 503 while (this->readRegister(TXLVL) == 0) {
wim 2:76cb93b511f2 504 // Wait for space in TX buffer
wim 2:76cb93b511f2 505 wait_us(10);
wim 2:76cb93b511f2 506 };
wim 2:76cb93b511f2 507 this->writeRegister(THR, str[idx]);
wim 2:76cb93b511f2 508 }
wim 2:76cb93b511f2 509
wim 0:d64854a60f95 510
wim 2:76cb93b511f2 511 #else
wim 3:9783b6bde958 512 // Single writes instead of bulktransfer
wim 2:76cb93b511f2 513 int len, idx;
wim 2:76cb93b511f2 514
wim 2:76cb93b511f2 515 len = strlen(str);
wim 2:76cb93b511f2 516 for (idx=0; idx<len; idx++) {
wim 2:76cb93b511f2 517 while (this->readRegister(TXLVL) == 0) {
wim 2:76cb93b511f2 518 // Wait for space in TX buffer
wim 2:76cb93b511f2 519 wait_us(10);
wim 2:76cb93b511f2 520 };
wim 2:76cb93b511f2 521 this->writeRegister(THR, str[idx]);
wim 2:76cb93b511f2 522 }
wim 2:76cb93b511f2 523 #endif
wim 0:d64854a60f95 524 }
wim 2:76cb93b511f2 525
wim 2:76cb93b511f2 526
wim 3:9783b6bde958 527 /**
wim 3:9783b6bde958 528 * Write byte array to UART Bridge. Blocking when no free space in FIFO
wim 3:9783b6bde958 529 * @param *data byte array to be written
wim 3:9783b6bde958 530 * @param len number of bytes to write
wim 3:9783b6bde958 531 * @return none
wim 3:9783b6bde958 532 */
wim 3:9783b6bde958 533 void SC16IS750::writeBytes(const char *data, int len) {
wim 3:9783b6bde958 534
wim 3:9783b6bde958 535 #if ENABLE_BULK_TRANSFERS
wim 3:9783b6bde958 536 int idx;
wim 3:9783b6bde958 537
wim 3:9783b6bde958 538 // Write blocks of BULK_BLOCK_LEN
wim 3:9783b6bde958 539 while (len > BULK_BLOCK_LEN) {
wim 3:9783b6bde958 540 while(this->readRegister(TXLVL) < BULK_BLOCK_LEN) {
wim 3:9783b6bde958 541 // Wait for space in TX buffer
wim 3:9783b6bde958 542 wait_us(10);
wim 3:9783b6bde958 543 };
wim 3:9783b6bde958 544
wim 3:9783b6bde958 545 // Write a block of BULK_BLOCK_LEN bytes
wim 3:9783b6bde958 546 #if (0)
wim 3:9783b6bde958 547 // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes.
wim 3:9783b6bde958 548 for (idx=0; idx<BULK_BLOCK_LEN; idx++) {
wim 3:9783b6bde958 549 this->writeRegister(THR, data[idx]);
wim 3:9783b6bde958 550 };
wim 3:9783b6bde958 551 #else
wim 3:9783b6bde958 552 // optimized
wim 3:9783b6bde958 553 this->writeDataBlock(data, BULK_BLOCK_LEN);
wim 3:9783b6bde958 554 #endif
wim 3:9783b6bde958 555
wim 3:9783b6bde958 556 len -= BULK_BLOCK_LEN;
wim 3:9783b6bde958 557 data += BULK_BLOCK_LEN;
wim 3:9783b6bde958 558 }
wim 3:9783b6bde958 559
wim 3:9783b6bde958 560 // Write remaining bytes
wim 3:9783b6bde958 561 // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes.
wim 3:9783b6bde958 562 for (idx=0; idx<len; idx++) {
wim 3:9783b6bde958 563 while (this->readRegister(TXLVL) == 0) {
wim 3:9783b6bde958 564 // Wait for space in TX buffer
wim 3:9783b6bde958 565 wait_us(10);
wim 3:9783b6bde958 566 };
wim 3:9783b6bde958 567 this->writeRegister(THR, data[idx]);
wim 3:9783b6bde958 568 }
wim 3:9783b6bde958 569
wim 3:9783b6bde958 570
wim 3:9783b6bde958 571 #else
wim 3:9783b6bde958 572 // Single writes instead of bulktransfer
wim 3:9783b6bde958 573 int idx;
wim 3:9783b6bde958 574
wim 3:9783b6bde958 575 for (idx=0; idx<len; idx++) {
wim 3:9783b6bde958 576 while (this->readRegister(TXLVL) == 0) {
wim 3:9783b6bde958 577 // Wait for space in TX buffer
wim 3:9783b6bde958 578 wait_us(10);
wim 3:9783b6bde958 579 };
wim 3:9783b6bde958 580 this->writeRegister(THR, str[idx]);
wim 3:9783b6bde958 581 }
wim 3:9783b6bde958 582 #endif
wim 3:9783b6bde958 583 }
wim 3:9783b6bde958 584
wim 3:9783b6bde958 585
wim 1:0440152c5387 586 /** Set direction of I/O port pins.
wim 1:0440152c5387 587 * This method is specific to the SPI-I2C UART and not found on the 16750
wim 5:ff3e57bebb6a 588 * Note: The SC16IS752 does not have separate GPIOs for Channel_A and Channel_B.
wim 1:0440152c5387 589 * @param bits Bitpattern for I/O (1=output, 0=input)
wim 1:0440152c5387 590 * @return none
wim 1:0440152c5387 591 */
wim 0:d64854a60f95 592 void SC16IS750::ioSetDirection(unsigned char bits) {
wim 0:d64854a60f95 593 this->writeRegister(IODIR, bits);
wim 0:d64854a60f95 594 }
wim 0:d64854a60f95 595
wim 1:0440152c5387 596 /** Set bits of I/O port pins.
wim 1:0440152c5387 597 * This method is specific to the SPI-I2C UART and not found on the 16750
wim 5:ff3e57bebb6a 598 * Note: The SC16IS752 does not have separate GPIOs for Channel_A and Channel_B.
wim 1:0440152c5387 599 * @param bits Bitpattern for I/O (1= set output bit, 0 = clear output bit)
wim 1:0440152c5387 600 * @return none
wim 1:0440152c5387 601 */
wim 0:d64854a60f95 602 void SC16IS750::ioSetState(unsigned char bits) {
wim 0:d64854a60f95 603 this->writeRegister(IOSTATE, bits);
wim 0:d64854a60f95 604 }
wim 0:d64854a60f95 605
wim 1:0440152c5387 606 /** Get bits of I/O port pins.
wim 1:0440152c5387 607 * This method is specific to the SPI-I2C UART and not found on the 16750
wim 5:ff3e57bebb6a 608 * Note: The SC16IS752 does not have separate GPIOs for Channel_A and Channel_B.
wim 1:0440152c5387 609 * @param none
wim 1:0440152c5387 610 * @return bits Bitpattern for I/O (1= bit set, 0 = bit cleared)
wim 1:0440152c5387 611 */
wim 1:0440152c5387 612 unsigned char SC16IS750::ioGetState() {
wim 1:0440152c5387 613 return this->readRegister(IOSTATE) ;
wim 1:0440152c5387 614 }
wim 0:d64854a60f95 615
wim 0:d64854a60f95 616
wim 1:0440152c5387 617 /** Software Reset SC16IS750 device.
wim 1:0440152c5387 618 * This method is specific to the SPI-I2C UART and not found on the 16750
wim 5:ff3e57bebb6a 619 * Note: The SC16IS752 does not have separate Reset for Channel_A and Channel_B.
wim 1:0440152c5387 620 * @param none
wim 1:0440152c5387 621 * @return none
wim 1:0440152c5387 622 */
wim 1:0440152c5387 623 void SC16IS750::swReset() {
wim 1:0440152c5387 624 this->writeRegister(IOCTRL, IOC_SW_RST);
wim 1:0440152c5387 625 }
wim 1:0440152c5387 626
wim 1:0440152c5387 627
wim 1:0440152c5387 628 //
wim 1:0440152c5387 629 // End Abstract Class Implementation
wim 0:d64854a60f95 630 //
wim 0:d64854a60f95 631
wim 1:0440152c5387 632
wim 1:0440152c5387 633
wim 4:12446ee9f9c8 634 //
wim 4:12446ee9f9c8 635 // Begin SPI Class Implementation
wim 4:12446ee9f9c8 636 //
wim 4:12446ee9f9c8 637
wim 4:12446ee9f9c8 638
wim 4:12446ee9f9c8 639 /** Create an SC16IS750_SPI object using a specified SPI bus and CS
wim 1:0440152c5387 640 *
wim 4:12446ee9f9c8 641 * @param SPI &spi the SPI port to connect to
wim 4:12446ee9f9c8 642 * @param cs Pinname of the CS pin (active low)
wim 4:12446ee9f9c8 643 * @param rst Pinname for Reset pin (active low) Optional, Default = NC
wim 4:12446ee9f9c8 644 */
wim 4:12446ee9f9c8 645 SC16IS750_SPI::SC16IS750_SPI (SPI *spi, PinName cs, PinName rst) : _spi(spi), _cs(cs) {
wim 0:d64854a60f95 646 _cs = 1; // deselect
wim 0:d64854a60f95 647
wim 0:d64854a60f95 648 _spi->format(8, 0);
wim 0:d64854a60f95 649 _spi->frequency(1000000);
wim 4:12446ee9f9c8 650
wim 4:12446ee9f9c8 651 // The hardware Reset pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 4:12446ee9f9c8 652 if (rst != NC) {
wim 4:12446ee9f9c8 653 _reset = new DigitalOut(rst); //Construct new pin
wim 4:12446ee9f9c8 654 _reset->write(1); //Deactivate
wim 4:12446ee9f9c8 655 }
wim 4:12446ee9f9c8 656 else {
wim 4:12446ee9f9c8 657 // No Hardware Reset pin
wim 4:12446ee9f9c8 658 _reset = NULL; //Construct dummy pin
wim 4:12446ee9f9c8 659 }
wim 4:12446ee9f9c8 660
wim 1:0440152c5387 661
wim 1:0440152c5387 662 // Dont call _init() until SPI port has been configured.
wim 1:0440152c5387 663 // That is why _init() is not called in parent Constructor
wim 1:0440152c5387 664 _init();
wim 1:0440152c5387 665
wim 0:d64854a60f95 666 };
wim 0:d64854a60f95 667
wim 4:12446ee9f9c8 668
wim 4:12446ee9f9c8 669 /** Destruct SC16IS750_SPI bridge object
wim 4:12446ee9f9c8 670 *
wim 4:12446ee9f9c8 671 * @param none
wim 4:12446ee9f9c8 672 * @return none
wim 4:12446ee9f9c8 673 */
wim 4:12446ee9f9c8 674 SC16IS750_SPI::~SC16IS750_SPI() {
wim 4:12446ee9f9c8 675 if (_reset != NULL) {delete _reset;} // Reset pin
wim 4:12446ee9f9c8 676 }
wim 4:12446ee9f9c8 677
wim 0:d64854a60f95 678 /** Write value to internal register.
wim 0:d64854a60f95 679 * Pure virtual, must be declared in derived class.
wim 1:0440152c5387 680 * @param registerAddress The address of the Register (enum RegisterName)
wim 0:d64854a60f95 681 * @param data The 8bit value to write
wim 0:d64854a60f95 682 * @return none
wim 0:d64854a60f95 683 */
wim 0:d64854a60f95 684 void SC16IS750_SPI::writeRegister(RegisterName registerAddress, char data) {
wim 0:d64854a60f95 685
wim 0:d64854a60f95 686 _cs = 0; // select;
wim 0:d64854a60f95 687 _spi->write(registerAddress);
wim 0:d64854a60f95 688 _spi->write(data);
wim 0:d64854a60f95 689 _cs = 1; // deselect;
wim 1:0440152c5387 690
wim 0:d64854a60f95 691 }
wim 0:d64854a60f95 692
wim 0:d64854a60f95 693
wim 0:d64854a60f95 694 /** Read value from internal register.
wim 1:0440152c5387 695 * @param registerAddress The address of the Register (enum RegisterName)
wim 0:d64854a60f95 696 * @return char The 8bit value read from the register
wim 0:d64854a60f95 697 */
wim 0:d64854a60f95 698 char SC16IS750_SPI::readRegister(RegisterName registerAddress) {
wim 0:d64854a60f95 699
wim 0:d64854a60f95 700 // Used in SPI read operations to flush slave's shift register
wim 1:0440152c5387 701 const char SPI_DUMMY_CHAR = 0xFF;
wim 0:d64854a60f95 702
wim 0:d64854a60f95 703 char result;
wim 0:d64854a60f95 704
wim 0:d64854a60f95 705 _cs = 0; // select;
wim 0:d64854a60f95 706 _spi->write(SPI_READ_MODE_FLAG | registerAddress);
wim 1:0440152c5387 707 result = _spi->write(SPI_DUMMY_CHAR);
wim 0:d64854a60f95 708 _cs = 1; // deselect;
wim 0:d64854a60f95 709
wim 0:d64854a60f95 710 return result;
wim 0:d64854a60f95 711 }
wim 0:d64854a60f95 712
wim 3:9783b6bde958 713
wim 3:9783b6bde958 714 /** Write multiple datavalues to Transmitregister.
wim 3:9783b6bde958 715 * More Efficient implementation than writing individual bytes
wim 3:9783b6bde958 716 * Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 3:9783b6bde958 717 * Pure virtual, must be declared in derived class.
wim 3:9783b6bde958 718 * @param char* databytes The pointer to the block of data
wim 3:9783b6bde958 719 * @param len The number of bytes to write
wim 3:9783b6bde958 720 * @return none
wim 3:9783b6bde958 721 */
wim 3:9783b6bde958 722 void SC16IS750_SPI::writeDataBlock (const char *data, int len) {
wim 3:9783b6bde958 723 int i;
wim 3:9783b6bde958 724
wim 3:9783b6bde958 725 _cs = 0; // select;
wim 3:9783b6bde958 726
wim 3:9783b6bde958 727 // Select the Transmit Holding Register
wim 3:9783b6bde958 728 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 3:9783b6bde958 729 _spi->write(THR);
wim 3:9783b6bde958 730
wim 3:9783b6bde958 731 for (i=0; i<len; i++, data++)
wim 3:9783b6bde958 732 _spi->write(*data);
wim 3:9783b6bde958 733
wim 3:9783b6bde958 734 _cs = 1; // deselect;
wim 3:9783b6bde958 735 }
wim 3:9783b6bde958 736
wim 4:12446ee9f9c8 737
wim 4:12446ee9f9c8 738 /** Hardware Reset SC16IS750 device.
wim 4:12446ee9f9c8 739 * This method is only available when the Reset pin has been declared and is also connected
wim 4:12446ee9f9c8 740 * @param none
wim 4:12446ee9f9c8 741 * @return none
wim 4:12446ee9f9c8 742 */
wim 4:12446ee9f9c8 743 void SC16IS750_SPI::hwReset() {
wim 4:12446ee9f9c8 744
wim 4:12446ee9f9c8 745 if (_reset != NULL){
wim 4:12446ee9f9c8 746 _reset->write(0); //activate
wim 4:12446ee9f9c8 747 // wait_ms(100);
wim 4:12446ee9f9c8 748 wait_ms(1000); //test only
wim 4:12446ee9f9c8 749 _reset->write(1); //deactivate
wim 4:12446ee9f9c8 750 }
wim 4:12446ee9f9c8 751 else {
wim 4:12446ee9f9c8 752 printf("Hardware Reset pin is not available...\n\r");
wim 4:12446ee9f9c8 753 }
wim 4:12446ee9f9c8 754
wim 4:12446ee9f9c8 755 }
wim 4:12446ee9f9c8 756
wim 0:d64854a60f95 757 //
wim 0:d64854a60f95 758 // End SPI Implementation
wim 1:0440152c5387 759 //
wim 0:d64854a60f95 760
wim 0:d64854a60f95 761
wim 4:12446ee9f9c8 762
wim 4:12446ee9f9c8 763 //
wim 4:12446ee9f9c8 764 // Begin I2C Implementation
wim 4:12446ee9f9c8 765 //
wim 4:12446ee9f9c8 766
wim 4:12446ee9f9c8 767 /** Create a SC16IS750_I2C object for a bridge between I2C and a Serial port
wim 1:0440152c5387 768 *
wim 4:12446ee9f9c8 769 * @param I2C &i2c the I2C port to connect to
wim 4:12446ee9f9c8 770 * @param char deviceAddress the I2C slave address of the SC16IS750
wim 4:12446ee9f9c8 771 * @param rst Pinname for Reset pin (active low) Optional, Default = NC
wim 4:12446ee9f9c8 772 *
wim 4:12446ee9f9c8 773 */
wim 4:12446ee9f9c8 774 SC16IS750_I2C::SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress, PinName rst) : _i2c(i2c), _slaveAddress(deviceAddress & 0xFE) {
wim 0:d64854a60f95 775
wim 5:ff3e57bebb6a 776 // _i2c->frequency(400000);
wim 5:ff3e57bebb6a 777 _i2c->frequency(100000);
wim 4:12446ee9f9c8 778
wim 4:12446ee9f9c8 779 // The hardware Reset pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 4:12446ee9f9c8 780 if (rst != NC) {
wim 4:12446ee9f9c8 781 _reset = new DigitalOut(rst); //Construct new pin
wim 4:12446ee9f9c8 782 _reset->write(1); //Deactivate
wim 4:12446ee9f9c8 783 }
wim 4:12446ee9f9c8 784 else {
wim 4:12446ee9f9c8 785 // No Hardware Reset pin
wim 4:12446ee9f9c8 786 _reset = NULL; //Construct dummy pin
wim 4:12446ee9f9c8 787 }
wim 4:12446ee9f9c8 788
wim 1:0440152c5387 789 // Dont call _init() until I2C port has been configured.
wim 1:0440152c5387 790 // That is why _init() is not called in parent Constructor
wim 1:0440152c5387 791 _init();
wim 0:d64854a60f95 792 }
wim 0:d64854a60f95 793
wim 0:d64854a60f95 794
wim 4:12446ee9f9c8 795 /** Destruct SC16IS750_I2C bridge object
wim 4:12446ee9f9c8 796 *
wim 4:12446ee9f9c8 797 * @param none
wim 4:12446ee9f9c8 798 * @return none
wim 4:12446ee9f9c8 799 */
wim 4:12446ee9f9c8 800 SC16IS750_I2C::~SC16IS750_I2C() {
wim 4:12446ee9f9c8 801 if (_reset != NULL) {delete _reset;} // Reset pin
wim 4:12446ee9f9c8 802 }
wim 4:12446ee9f9c8 803
wim 4:12446ee9f9c8 804
wim 0:d64854a60f95 805 /** Write value to internal register.
wim 1:0440152c5387 806 * @param registerAddress The address of the Register (enum RegisterName)
wim 0:d64854a60f95 807 * @param data The 8bit value to write
wim 0:d64854a60f95 808 * @return none
wim 0:d64854a60f95 809 */
wim 0:d64854a60f95 810 void SC16IS750_I2C::writeRegister(RegisterName registerAddress, char data) {
wim 0:d64854a60f95 811 char w[2];
wim 0:d64854a60f95 812
wim 0:d64854a60f95 813 w[0] = registerAddress;
wim 0:d64854a60f95 814 w[1] = data;
wim 0:d64854a60f95 815
wim 0:d64854a60f95 816 _i2c->write( _slaveAddress, w, 2 );
wim 0:d64854a60f95 817 }
wim 0:d64854a60f95 818
wim 0:d64854a60f95 819
wim 0:d64854a60f95 820 /** Read value from internal register.
wim 1:0440152c5387 821 * @param registerAddress The address of the Register (enum RegisterName)
wim 0:d64854a60f95 822 * @return char The 8bit value read from the register
wim 0:d64854a60f95 823 */
wim 0:d64854a60f95 824 char SC16IS750_I2C::readRegister(RegisterName registerAddress) {
wim 0:d64854a60f95 825 /*
wim 0:d64854a60f95 826 * Read char from SC16IS750 register at <registerAddress>.
wim 0:d64854a60f95 827 */
wim 0:d64854a60f95 828 char w[1];
wim 0:d64854a60f95 829 char r[1];
wim 0:d64854a60f95 830
wim 0:d64854a60f95 831 w[0] = registerAddress;
wim 0:d64854a60f95 832
wim 5:ff3e57bebb6a 833 // _i2c->write( _slaveAddress, w, 1 );
wim 5:ff3e57bebb6a 834 _i2c->write(_slaveAddress, w, 1, true); //Repeated Start
wim 0:d64854a60f95 835 _i2c->read( _slaveAddress, r, 1 );
wim 0:d64854a60f95 836
wim 0:d64854a60f95 837 return ( r[0] );
wim 0:d64854a60f95 838 }
wim 0:d64854a60f95 839
wim 0:d64854a60f95 840
wim 3:9783b6bde958 841 /** Write multiple datavalues to Transmitregister.
wim 3:9783b6bde958 842 * More Efficient implementation than writing individual bytes
wim 3:9783b6bde958 843 * Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 3:9783b6bde958 844 * Pure virtual, must be declared in derived class.
wim 3:9783b6bde958 845 * @param char* databytes The pointer to the block of data
wim 3:9783b6bde958 846 * @param len The number of bytes to write
wim 3:9783b6bde958 847 * @return none
wim 3:9783b6bde958 848 */
wim 3:9783b6bde958 849 void SC16IS750_I2C::writeDataBlock (const char *data, int len) {
wim 3:9783b6bde958 850
wim 3:9783b6bde958 851 #if(0)
wim 3:9783b6bde958 852 int i;
wim 3:9783b6bde958 853 char w[BULK_BLOCK_LEN];
wim 3:9783b6bde958 854
wim 3:9783b6bde958 855 // Select the Transmit Holding Register
wim 3:9783b6bde958 856 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 3:9783b6bde958 857 w[0] = THR;
wim 3:9783b6bde958 858
wim 3:9783b6bde958 859 // copy the data..
wim 3:9783b6bde958 860 for (i=0; i<len; i++)
wim 3:9783b6bde958 861 w[i+1] = data[i];
wim 3:9783b6bde958 862
wim 3:9783b6bde958 863 _i2c->write( _slaveAddress, w, len + 1);
wim 3:9783b6bde958 864 #else
wim 3:9783b6bde958 865 int i;
wim 3:9783b6bde958 866
wim 3:9783b6bde958 867 _i2c->start();
wim 3:9783b6bde958 868 _i2c->write(_slaveAddress);
wim 3:9783b6bde958 869
wim 3:9783b6bde958 870 // Select the Transmit Holding Register
wim 3:9783b6bde958 871 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 3:9783b6bde958 872 _i2c->write(THR);
wim 3:9783b6bde958 873
wim 3:9783b6bde958 874 // send the data..
wim 3:9783b6bde958 875 for (i=0; i<len; i++)
wim 3:9783b6bde958 876 _i2c->write(data[i]);
wim 3:9783b6bde958 877
wim 3:9783b6bde958 878 _i2c->stop();
wim 3:9783b6bde958 879 #endif
wim 3:9783b6bde958 880 }
wim 3:9783b6bde958 881
wim 3:9783b6bde958 882
wim 4:12446ee9f9c8 883 /** Hardware Reset SC16IS750 device.
wim 4:12446ee9f9c8 884 * This method is only available when the Reset pin has been declared and is also connected
wim 4:12446ee9f9c8 885 * @param none
wim 4:12446ee9f9c8 886 * @return none
wim 4:12446ee9f9c8 887 */
wim 4:12446ee9f9c8 888 void SC16IS750_I2C::hwReset() {
wim 4:12446ee9f9c8 889
wim 4:12446ee9f9c8 890 if (_reset != NULL){
wim 4:12446ee9f9c8 891 _reset->write(0); //activate
wim 4:12446ee9f9c8 892 // wait_ms(100);
wim 4:12446ee9f9c8 893 wait_ms(1000); //test only
wim 4:12446ee9f9c8 894 _reset->write(1); //deactivate
wim 4:12446ee9f9c8 895 }
wim 4:12446ee9f9c8 896 else {
wim 4:12446ee9f9c8 897 printf("Hardware Reset pin is not available...\n\r");
wim 4:12446ee9f9c8 898 }
wim 4:12446ee9f9c8 899 }
wim 4:12446ee9f9c8 900
wim 4:12446ee9f9c8 901
wim 0:d64854a60f95 902 //
wim 1:0440152c5387 903 // End I2C Implementation
wim 4:12446ee9f9c8 904 //
wim 4:12446ee9f9c8 905
wim 4:12446ee9f9c8 906
wim 4:12446ee9f9c8 907
wim 4:12446ee9f9c8 908 //
wim 4:12446ee9f9c8 909 // Begin SPI Class Implementation for 16SCIS752 dual UART
wim 4:12446ee9f9c8 910 //
wim 4:12446ee9f9c8 911
wim 4:12446ee9f9c8 912
wim 4:12446ee9f9c8 913 /** Create an SC16IS752_SPI object using a specified SPI bus and CS
wim 5:ff3e57bebb6a 914 * Note: The SC16IS752 does not have separate GPIOs for Channel_A and Channel_B.
wim 5:ff3e57bebb6a 915 * Note: The SC16IS752 does not have separate Reset for Channel_A and Channel_B.
wim 4:12446ee9f9c8 916 *
wim 4:12446ee9f9c8 917 * @param SPI &spi the SPI port to connect to
wim 4:12446ee9f9c8 918 * @param cs Pinname of the CS pin (active low)
wim 4:12446ee9f9c8 919 * @param rst Pinname for Reset pin (active low) Optional, Default = NC
wim 4:12446ee9f9c8 920 * @param channel UART ChannelName, Default = Channel_A
wim 4:12446ee9f9c8 921 */
wim 4:12446ee9f9c8 922 SC16IS752_SPI::SC16IS752_SPI (SPI *spi, PinName cs, PinName rst, ChannelName channel) : _spi(spi), _cs(cs), _channel(channel) {
wim 4:12446ee9f9c8 923 _cs = 1; // deselect
wim 4:12446ee9f9c8 924
wim 4:12446ee9f9c8 925 _spi->format(8, 0);
wim 4:12446ee9f9c8 926 _spi->frequency(1000000);
wim 4:12446ee9f9c8 927
wim 4:12446ee9f9c8 928 // The hardware Reset pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 4:12446ee9f9c8 929 if (rst != NC) {
wim 4:12446ee9f9c8 930 _reset = new DigitalOut(rst); //Construct new pin
wim 4:12446ee9f9c8 931 _reset->write(1); //Deactivate
wim 4:12446ee9f9c8 932 }
wim 4:12446ee9f9c8 933 else {
wim 4:12446ee9f9c8 934 // No Hardware Reset pin
wim 4:12446ee9f9c8 935 _reset = NULL; //Construct dummy pin
wim 4:12446ee9f9c8 936 }
wim 4:12446ee9f9c8 937
wim 4:12446ee9f9c8 938
wim 4:12446ee9f9c8 939 // Dont call _init() until SPI port has been configured.
wim 4:12446ee9f9c8 940 // That is why _init() is not called in parent Constructor
wim 4:12446ee9f9c8 941 _init();
wim 4:12446ee9f9c8 942
wim 4:12446ee9f9c8 943 };
wim 4:12446ee9f9c8 944
wim 4:12446ee9f9c8 945
wim 4:12446ee9f9c8 946 /** Destruct SC16IS750_SPI bridge object
wim 4:12446ee9f9c8 947 *
wim 4:12446ee9f9c8 948 * @param none
wim 4:12446ee9f9c8 949 * @return none
wim 4:12446ee9f9c8 950 */
wim 4:12446ee9f9c8 951 SC16IS752_SPI::~SC16IS752_SPI() {
wim 4:12446ee9f9c8 952 if (_reset != NULL) {delete _reset;} // Reset pin
wim 4:12446ee9f9c8 953 }
wim 4:12446ee9f9c8 954
wim 4:12446ee9f9c8 955
wim 4:12446ee9f9c8 956 /** Write value to internal register.
wim 4:12446ee9f9c8 957 * Pure virtual, must be declared in derived class.
wim 4:12446ee9f9c8 958 * @param registerAddress The address of the Register (enum RegisterName)
wim 4:12446ee9f9c8 959 * @param data The 8bit value to write
wim 4:12446ee9f9c8 960 * @return none
wim 4:12446ee9f9c8 961 */
wim 4:12446ee9f9c8 962 void SC16IS752_SPI::writeRegister(RegisterName registerAddress, char data) {
wim 4:12446ee9f9c8 963
wim 4:12446ee9f9c8 964 _cs = 0; // select;
wim 4:12446ee9f9c8 965 _spi->write(registerAddress | _channel);
wim 4:12446ee9f9c8 966 _spi->write(data);
wim 4:12446ee9f9c8 967 _cs = 1; // deselect;
wim 4:12446ee9f9c8 968
wim 4:12446ee9f9c8 969 }
wim 4:12446ee9f9c8 970
wim 4:12446ee9f9c8 971
wim 4:12446ee9f9c8 972 /** Read value from internal register.
wim 4:12446ee9f9c8 973 * @param registerAddress The address of the Register (enum RegisterName)
wim 4:12446ee9f9c8 974 * @return char The 8bit value read from the register
wim 4:12446ee9f9c8 975 */
wim 4:12446ee9f9c8 976 char SC16IS752_SPI::readRegister(RegisterName registerAddress) {
wim 4:12446ee9f9c8 977
wim 4:12446ee9f9c8 978 // Used in SPI read operations to flush slave's shift register
wim 4:12446ee9f9c8 979 const char SPI_DUMMY_CHAR = 0xFF;
wim 4:12446ee9f9c8 980
wim 4:12446ee9f9c8 981 char result;
wim 4:12446ee9f9c8 982
wim 4:12446ee9f9c8 983 _cs = 0; // select;
wim 4:12446ee9f9c8 984 _spi->write(SPI_READ_MODE_FLAG | registerAddress | _channel);
wim 4:12446ee9f9c8 985 result = _spi->write(SPI_DUMMY_CHAR);
wim 4:12446ee9f9c8 986 _cs = 1; // deselect;
wim 4:12446ee9f9c8 987
wim 4:12446ee9f9c8 988 return result;
wim 4:12446ee9f9c8 989 }
wim 4:12446ee9f9c8 990
wim 4:12446ee9f9c8 991
wim 4:12446ee9f9c8 992 /** Write multiple datavalues to Transmitregister.
wim 4:12446ee9f9c8 993 * More Efficient implementation than writing individual bytes
wim 4:12446ee9f9c8 994 * Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 4:12446ee9f9c8 995 * Pure virtual, must be declared in derived class.
wim 4:12446ee9f9c8 996 * @param char* databytes The pointer to the block of data
wim 4:12446ee9f9c8 997 * @param len The number of bytes to write
wim 4:12446ee9f9c8 998 * @return none
wim 4:12446ee9f9c8 999 */
wim 4:12446ee9f9c8 1000 void SC16IS752_SPI::writeDataBlock (const char *data, int len) {
wim 4:12446ee9f9c8 1001 int i;
wim 4:12446ee9f9c8 1002
wim 4:12446ee9f9c8 1003 _cs = 0; // select;
wim 4:12446ee9f9c8 1004
wim 4:12446ee9f9c8 1005 // Select the Transmit Holding Register
wim 4:12446ee9f9c8 1006 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 4:12446ee9f9c8 1007 _spi->write(THR | _channel);
wim 4:12446ee9f9c8 1008
wim 4:12446ee9f9c8 1009 for (i=0; i<len; i++, data++)
wim 4:12446ee9f9c8 1010 _spi->write(*data);
wim 4:12446ee9f9c8 1011
wim 4:12446ee9f9c8 1012 _cs = 1; // deselect;
wim 4:12446ee9f9c8 1013 }
wim 4:12446ee9f9c8 1014
wim 4:12446ee9f9c8 1015
wim 4:12446ee9f9c8 1016 /** Hardware Reset SC16IS752 device.
wim 4:12446ee9f9c8 1017 * This method is only available when the Reset pin has been declared and is also connected
wim 4:12446ee9f9c8 1018 * @param none
wim 4:12446ee9f9c8 1019 * @return none
wim 4:12446ee9f9c8 1020 */
wim 4:12446ee9f9c8 1021 void SC16IS752_SPI::hwReset() {
wim 4:12446ee9f9c8 1022
wim 4:12446ee9f9c8 1023 if (_reset != NULL){
wim 4:12446ee9f9c8 1024 _reset->write(0); //activate
wim 4:12446ee9f9c8 1025 // wait_ms(100);
wim 4:12446ee9f9c8 1026 wait_ms(1000); //test only
wim 4:12446ee9f9c8 1027 _reset->write(1); //deactivate
wim 4:12446ee9f9c8 1028 }
wim 4:12446ee9f9c8 1029 else {
wim 4:12446ee9f9c8 1030 printf("Hardware Reset pin is not available...\n\r");
wim 4:12446ee9f9c8 1031 }
wim 4:12446ee9f9c8 1032
wim 4:12446ee9f9c8 1033 }
wim 4:12446ee9f9c8 1034
wim 4:12446ee9f9c8 1035 //
wim 4:12446ee9f9c8 1036 // End SPI Implementation
wim 4:12446ee9f9c8 1037 //
wim 4:12446ee9f9c8 1038
wim 4:12446ee9f9c8 1039
wim 4:12446ee9f9c8 1040
wim 4:12446ee9f9c8 1041 //
wim 4:12446ee9f9c8 1042 // Begin I2C Implementation for 16SCIS752 dual UART
wim 4:12446ee9f9c8 1043 //
wim 4:12446ee9f9c8 1044
wim 4:12446ee9f9c8 1045 /** Create a SC16IS752_I2C object for a bridge between I2C and a Serial port
wim 5:ff3e57bebb6a 1046 * Note: The SC16IS752 does not have separate GPIOs for Channel_A and Channel_B.
wim 5:ff3e57bebb6a 1047 * Note: The SC16IS752 does not have separate Reset for Channel_A and Channel_B.
wim 4:12446ee9f9c8 1048 *
wim 4:12446ee9f9c8 1049 * @param I2C &i2c the I2C port to connect to
wim 4:12446ee9f9c8 1050 * @param char deviceAddress the I2C slave address of the SC16IS750
wim 4:12446ee9f9c8 1051 * @param rst Pinname for Reset pin (active low) Optional, Default = NC
wim 4:12446ee9f9c8 1052 * @param channel UART Channel, Default = Channel_A
wim 4:12446ee9f9c8 1053 */
wim 4:12446ee9f9c8 1054 SC16IS752_I2C::SC16IS752_I2C(I2C *i2c, uint8_t deviceAddress, PinName rst, ChannelName channel) : _i2c(i2c), _slaveAddress(deviceAddress & 0xFE), _channel(channel) {
wim 4:12446ee9f9c8 1055
wim 5:ff3e57bebb6a 1056 // _i2c->frequency(400000);
wim 5:ff3e57bebb6a 1057 _i2c->frequency(100000);
wim 5:ff3e57bebb6a 1058
wim 4:12446ee9f9c8 1059 // The hardware Reset pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 4:12446ee9f9c8 1060 if (rst != NC) {
wim 4:12446ee9f9c8 1061 _reset = new DigitalOut(rst); //Construct new pin
wim 4:12446ee9f9c8 1062 _reset->write(1); //Deactivate
wim 4:12446ee9f9c8 1063 }
wim 4:12446ee9f9c8 1064 else {
wim 4:12446ee9f9c8 1065 // No Hardware Reset pin
wim 4:12446ee9f9c8 1066 _reset = NULL; //Construct dummy pin
wim 4:12446ee9f9c8 1067 }
wim 4:12446ee9f9c8 1068
wim 4:12446ee9f9c8 1069 // Dont call _init() until I2C port has been configured.
wim 4:12446ee9f9c8 1070 // That is why _init() is not called in parent Constructor
wim 4:12446ee9f9c8 1071 _init();
wim 4:12446ee9f9c8 1072 }
wim 4:12446ee9f9c8 1073
wim 4:12446ee9f9c8 1074
wim 4:12446ee9f9c8 1075 /** Destruct SC16IS752_I2C bridge object
wim 4:12446ee9f9c8 1076 *
wim 4:12446ee9f9c8 1077 * @param none
wim 4:12446ee9f9c8 1078 * @return none
wim 4:12446ee9f9c8 1079 */
wim 4:12446ee9f9c8 1080 SC16IS752_I2C::~SC16IS752_I2C() {
wim 4:12446ee9f9c8 1081 if (_reset != NULL) {delete _reset;} // Reset pin
wim 4:12446ee9f9c8 1082 }
wim 4:12446ee9f9c8 1083
wim 4:12446ee9f9c8 1084
wim 4:12446ee9f9c8 1085 /** Write value to internal register.
wim 4:12446ee9f9c8 1086 * @param registerAddress The address of the Register (enum RegisterName)
wim 4:12446ee9f9c8 1087 * @param data The 8bit value to write
wim 4:12446ee9f9c8 1088 * @return none
wim 4:12446ee9f9c8 1089 */
wim 4:12446ee9f9c8 1090 void SC16IS752_I2C::writeRegister(RegisterName registerAddress, char data) {
wim 4:12446ee9f9c8 1091 char w[2];
wim 4:12446ee9f9c8 1092
wim 4:12446ee9f9c8 1093 w[0] = registerAddress | _channel;
wim 4:12446ee9f9c8 1094 w[1] = data;
wim 4:12446ee9f9c8 1095
wim 4:12446ee9f9c8 1096 _i2c->write( _slaveAddress, w, 2 );
wim 4:12446ee9f9c8 1097 }
wim 4:12446ee9f9c8 1098
wim 4:12446ee9f9c8 1099
wim 4:12446ee9f9c8 1100 /** Read value from internal register.
wim 4:12446ee9f9c8 1101 * @param registerAddress The address of the Register (enum RegisterName)
wim 4:12446ee9f9c8 1102 * @return char The 8bit value read from the register
wim 4:12446ee9f9c8 1103 */
wim 4:12446ee9f9c8 1104 char SC16IS752_I2C::readRegister(RegisterName registerAddress) {
wim 4:12446ee9f9c8 1105 /*
wim 4:12446ee9f9c8 1106 * Read char from SC16IS752 register at <registerAddress>.
wim 4:12446ee9f9c8 1107 */
wim 4:12446ee9f9c8 1108 char w[1];
wim 4:12446ee9f9c8 1109 char r[1];
wim 4:12446ee9f9c8 1110
wim 4:12446ee9f9c8 1111 w[0] = registerAddress | _channel;
wim 4:12446ee9f9c8 1112
wim 5:ff3e57bebb6a 1113 // _i2c->write( _slaveAddress, w, 1 );
wim 5:ff3e57bebb6a 1114 _i2c->write(_slaveAddress, w, 1, true); //Repeated Start
wim 5:ff3e57bebb6a 1115 _i2c->read(_slaveAddress, r, 1 );
wim 4:12446ee9f9c8 1116
wim 4:12446ee9f9c8 1117 return ( r[0] );
wim 4:12446ee9f9c8 1118 }
wim 4:12446ee9f9c8 1119
wim 4:12446ee9f9c8 1120
wim 4:12446ee9f9c8 1121 /** Write multiple datavalues to Transmitregister.
wim 4:12446ee9f9c8 1122 * More Efficient implementation than writing individual bytes
wim 4:12446ee9f9c8 1123 * Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 4:12446ee9f9c8 1124 * Pure virtual, must be declared in derived class.
wim 4:12446ee9f9c8 1125 * @param char* databytes The pointer to the block of data
wim 4:12446ee9f9c8 1126 * @param len The number of bytes to write
wim 4:12446ee9f9c8 1127 * @return none
wim 4:12446ee9f9c8 1128 */
wim 4:12446ee9f9c8 1129 void SC16IS752_I2C::writeDataBlock (const char *data, int len) {
wim 4:12446ee9f9c8 1130
wim 4:12446ee9f9c8 1131 #if(0)
wim 4:12446ee9f9c8 1132 int i;
wim 4:12446ee9f9c8 1133 char w[BULK_BLOCK_LEN];
wim 4:12446ee9f9c8 1134
wim 4:12446ee9f9c8 1135 // Select the Transmit Holding Register
wim 4:12446ee9f9c8 1136 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 4:12446ee9f9c8 1137 w[0] = THR | _channel;
wim 4:12446ee9f9c8 1138
wim 4:12446ee9f9c8 1139 // copy the data..
wim 4:12446ee9f9c8 1140 for (i=0; i<len; i++)
wim 4:12446ee9f9c8 1141 w[i+1] = data[i];
wim 4:12446ee9f9c8 1142
wim 4:12446ee9f9c8 1143 _i2c->write( _slaveAddress, w, len + 1);
wim 4:12446ee9f9c8 1144 #else
wim 4:12446ee9f9c8 1145 int i;
wim 4:12446ee9f9c8 1146
wim 4:12446ee9f9c8 1147 _i2c->start();
wim 4:12446ee9f9c8 1148 _i2c->write(_slaveAddress);
wim 4:12446ee9f9c8 1149
wim 4:12446ee9f9c8 1150 // Select the Transmit Holding Register
wim 4:12446ee9f9c8 1151 // Assume that previous check confirmed that the FIFO has sufficient free space to store the data
wim 4:12446ee9f9c8 1152 _i2c->write(THR | _channel);
wim 4:12446ee9f9c8 1153
wim 4:12446ee9f9c8 1154 // send the data..
wim 4:12446ee9f9c8 1155 for (i=0; i<len; i++)
wim 4:12446ee9f9c8 1156 _i2c->write(data[i]);
wim 4:12446ee9f9c8 1157
wim 4:12446ee9f9c8 1158 _i2c->stop();
wim 4:12446ee9f9c8 1159 #endif
wim 4:12446ee9f9c8 1160 }
wim 4:12446ee9f9c8 1161
wim 4:12446ee9f9c8 1162
wim 4:12446ee9f9c8 1163 /** Hardware Reset SC16IS752 device.
wim 4:12446ee9f9c8 1164 * This method is only available when the Reset pin has been declared and is also connected
wim 4:12446ee9f9c8 1165 * @param none
wim 4:12446ee9f9c8 1166 * @return none
wim 4:12446ee9f9c8 1167 */
wim 4:12446ee9f9c8 1168 void SC16IS752_I2C::hwReset() {
wim 4:12446ee9f9c8 1169
wim 4:12446ee9f9c8 1170 if (_reset != NULL){
wim 4:12446ee9f9c8 1171 _reset->write(0); //activate
wim 4:12446ee9f9c8 1172 // wait_ms(100);
wim 4:12446ee9f9c8 1173 wait_ms(1000); //test only
wim 4:12446ee9f9c8 1174 _reset->write(1); //deactivate
wim 4:12446ee9f9c8 1175 }
wim 4:12446ee9f9c8 1176 else {
wim 4:12446ee9f9c8 1177 printf("Hardware Reset pin is not available...\n\r");
wim 4:12446ee9f9c8 1178 }
wim 4:12446ee9f9c8 1179 }
wim 4:12446ee9f9c8 1180
wim 4:12446ee9f9c8 1181
wim 4:12446ee9f9c8 1182 //
wim 4:12446ee9f9c8 1183 // End I2C Implementation
wim 4:12446ee9f9c8 1184 //
wim 4:12446ee9f9c8 1185
wim 4:12446ee9f9c8 1186
wim 4:12446ee9f9c8 1187