RETRO ROBOT E
Dependents: RETRO_ROBOT_SC16IS750E
Fork of SC16IS750 by
Diff: SC16IS750.cpp
- Revision:
- 3:9783b6bde958
- Parent:
- 2:76cb93b511f2
- Child:
- 4:12446ee9f9c8
--- a/SC16IS750.cpp Thu Feb 13 17:12:02 2014 +0000 +++ b/SC16IS750.cpp 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,7 +20,8 @@ #include "mbed.h" #include "SC16IS750.h" -#define ENABLE_BULK_TRANSFERS 0x01 +#define ENABLE_BULK_TRANSFERS 1 +#define BULK_BLOCK_LEN 16 /** Abstract class SC16IS750 for converter between either SPI or I2C and a Serial port * Constructor for this Abstract Class is protected @@ -29,8 +31,9 @@ * * @endcode */ -//SC16IS750::SC16IS750() : Serial(NC, NC) { //Fout ??? -SC16IS750::SC16IS750() { +SC16IS750::SC16IS750() { +//SC16IS750::SC16IS750() : Serial(NC, NC) { //Fout, mag geen NC zijn +//SC16IS750::SC16IS750() : SerialBase(NC, NC) { //Fout, mag geen NC zijn // Dont call _init() here since the SPI or I2C port have not yet been configured... //_init(); // initialise UART registers } @@ -140,7 +143,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. 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) - NOT USED @@ -177,7 +180,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) @@ -245,7 +248,7 @@ set_flow_control(); - // 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] only accessible when EFR[4] is set (enhanced functions enable) // FCR, TLR set_fifo_control(); @@ -325,7 +328,7 @@ // FCR is Write Only, use saved _config // reset TXFIFO, reset RXFIFO, non FIFO mode - this->writeRegister(FCR, FCR_TXFIFO_RST | FCR_RXFIFO_RST); + this->writeRegister(FCR, FCR_TX_FIFO_RST | FCR_RX_FIFO_RST); if (_config.fifoenable) // enable FIFO mode and set FIFO control values @@ -439,6 +442,7 @@ return this->readRegister(RHR); } + /** * Write char to UART Bridge. Blocking when no free space in FIFO * @param value char to be written @@ -455,16 +459,15 @@ return value; } + /** * Write char string to UART Bridge. Blocking when no free space in FIFO * @param *str char string to be written * @return none */ -void SC16IS750::write(const char *str) { +void SC16IS750::writeString(const char *str) { #if ENABLE_BULK_TRANSFERS - - #define BULK_BLOCK_LEN 16 int len, idx; len = strlen(str); @@ -477,16 +480,22 @@ }; // Write a block of BULK_BLOCK_LEN bytes - // Note: can be optimized by writing registeraddress once and then repeatedsly write the bytes. +#if (0) + // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes. for (idx=0; idx<BULK_BLOCK_LEN; idx++) { this->writeRegister(THR, str[idx]); }; - +#else + // optimized + this->writeDataBlock(str, BULK_BLOCK_LEN); +#endif + len -= BULK_BLOCK_LEN; str += BULK_BLOCK_LEN; } // Write remaining bytes + // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes. for (idx=0; idx<len; idx++) { while (this->readRegister(TXLVL) == 0) { // Wait for space in TX buffer @@ -497,6 +506,7 @@ #else + // Single writes instead of bulktransfer int len, idx; len = strlen(str); @@ -511,6 +521,66 @@ } +/** + * 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 SC16IS750::writeBytes(const char *data, int len) { + +#if ENABLE_BULK_TRANSFERS + int idx; + + // Write blocks of BULK_BLOCK_LEN + while (len > BULK_BLOCK_LEN) { + while(this->readRegister(TXLVL) < BULK_BLOCK_LEN) { + // Wait for space in TX buffer + wait_us(10); + }; + + // Write a block of BULK_BLOCK_LEN bytes +#if (0) + // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes. + for (idx=0; idx<BULK_BLOCK_LEN; idx++) { + this->writeRegister(THR, data[idx]); + }; +#else + // optimized + this->writeDataBlock(data, BULK_BLOCK_LEN); +#endif + + len -= BULK_BLOCK_LEN; + data += BULK_BLOCK_LEN; + } + + // Write remaining bytes + // Note: can be optimized by writing registeraddress once and then repeatedly write the bytes. + for (idx=0; idx<len; idx++) { + while (this->readRegister(TXLVL) == 0) { + // Wait for space in TX buffer + wait_us(10); + }; + this->writeRegister(THR, data[idx]); + } + + +#else + // Single writes instead of bulktransfer + int idx; + + for (idx=0; idx<len; idx++) { + while (this->readRegister(TXLVL) == 0) { + // Wait for space in TX buffer + wait_us(10); + }; + this->writeRegister(THR, str[idx]); + } +#endif +} + + + /** Set direction of I/O port pins. * This method is specific to the SPI-I2C UART and not found on the 16750 @@ -589,14 +659,7 @@ _spi->write(data); _cs = 1; // deselect; -#if(0) -//Test only - DigitalOut myled2(LED_GREEN); - myled2 = 0; //LED On - wait(0.2); - myled2 = 1; //LED Off - wait(0.6); -#endif + } @@ -619,6 +682,30 @@ return result; } + +/** 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 + */ +void SC16IS750_SPI::writeDataBlock (const char *data, int len) { + int i; + + _cs = 0; // select; + + // Select the Transmit Holding Register + // Assume that previous check confirmed that the FIFO has sufficient free space to store the data + _spi->write(THR); + + for (i=0; i<len; i++, data++) + _spi->write(*data); + + _cs = 1; // deselect; +} + // // End SPI Implementation // @@ -631,7 +718,7 @@ * @endcode * */ -SC16IS750_I2C::SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c), _slaveAddress(deviceAddress) { +SC16IS750_I2C::SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c), _slaveAddress(deviceAddress & 0xFE) { _i2c->frequency(400000); @@ -676,6 +763,48 @@ } +/** 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 + */ +void SC16IS750_I2C::writeDataBlock (const char *data, int len) { + +#if(0) + int i; + char w[BULK_BLOCK_LEN]; + + // Select the Transmit Holding Register + // Assume that previous check confirmed that the FIFO has sufficient free space to store the data + w[0] = THR; + + // copy the data.. + for (i=0; i<len; i++) + w[i+1] = data[i]; + + _i2c->write( _slaveAddress, w, len + 1); +#else + int i; + + _i2c->start(); + _i2c->write(_slaveAddress); + + // Select the Transmit Holding Register + // Assume that previous check confirmed that the FIFO has sufficient free space to store the data + _i2c->write(THR); + + // send the data.. + for (i=0; i<len; i++) + _i2c->write(data[i]); + + _i2c->stop(); +#endif +} + + // // End I2C Implementation // \ No newline at end of file