RETRO ROBOT E
Dependents: RETRO_ROBOT_SC16IS750E
Fork of SC16IS750 by
Revision 1:0440152c5387, committed 2014-02-09
- Comitter:
- wim
- Date:
- Sun Feb 09 14:58:06 2014 +0000
- Parent:
- 0:d64854a60f95
- Child:
- 2:76cb93b511f2
- Commit message:
- working proto, tested on BOB
Changed in this revision
SC16IS750.cpp | Show annotated file Show diff for this revision Revisions of this file |
SC16IS750.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/SC16IS750.cpp Wed Jan 22 16:39:37 2014 +0000 +++ b/SC16IS750.cpp Sun Feb 09 14:58:06 2014 +0000 @@ -1,6 +1,5 @@ /* SC16IS750 interface - * /////////////////////v1.0 Tedd OKANO, 18 Jul 2012, I2C I/F only, MIT License - * v1.1 WH, Nov 2013, Added SPI I/F and more methods, MIT License + * v0.1 WH, Nov 2013, Ported to mbed, Sparkfun Libs used as example. Added I2C and SPI I/F and 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, @@ -22,7 +21,7 @@ /** Abstract class SC16IS750 for converter between either SPI or I2C and a Serial port - * + * Constructor for this Abstract Class is protected * Supports both SPI and I2C interfaces through derived classes * * @code @@ -31,7 +30,8 @@ */ //SC16IS750::SC16IS750() : Serial(NC, NC) { //Fout ??? SC16IS750::SC16IS750() { - init(); // initialise UART registers +// Dont call _init() here since the SPI or I2C port have not yet been configured... + //_init(); // initialise UART registers } @@ -46,10 +46,11 @@ _config.baudrate = baudrate; // Save baudrate lcr_tmp = this->readRegister(LCR); // Read current LCR register - this->writeRegister(LCR, lcr_tmp | LCR_DIV_ENA); // Enable Divisor registers + this->writeRegister(LCR, lcr_tmp | LCR_ENABLE_DIV); // Enable Divisor registers this->writeRegister(DLL, ( divisor & 0xFF)); // write divisor LSB this->writeRegister(DLH, ((divisor >> 8) & 0xFF)); // write divisor MSB this->writeRegister(LCR, lcr_tmp); // Restore LCR register, activate regular RBR, THR and IER registers + } @@ -101,54 +102,164 @@ }; +/** Generate a break condition on the serial line + */ +void SC16IS750::send_break() { + // Wait for 1.5 frames before clearing the break condition + // This will have different effects on our platforms, but should + // ensure that we keep the break active for at least one frame. + // We consider a full frame (1 start bit + 8 data bits bits + + // 1 parity bit + 2 stop bits = 12 bits) for computation. + // One bit time (in us) = 1000000/_baud + // Twelve bits: 12000000/baud delay + // 1.5 frames: 18000000/baud delay + set_break(true); + wait_us(18000000/_config.baudrate); + set_break(false); +}; + +/** Set a break condition on the serial line + * @param enable break condition + */ +void SC16IS750::set_break(bool enable) { -/** - * Initialise the UART. + if (enable) { + _config.dataformat |= LCR_BRK_ENA; // Save dataformat + } + else { + _config.dataformat &= ~LCR_BRK_ENA; // Save dataformat + } + + this->writeRegister(LCR, _config.dataformat); // Set LCR register +} + +/** Set the flow control type on the serial port + * Added for compatibility with Serial Class. + * SC16IS750 supports only Flow, Pins can not be selected. * - * If initialisation fails this method does not return. + * @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) */ -void SC16IS750::init() { +void SC16IS750::set_flow_control(Flow type, PinName flow1, PinName flow2) { + char lcr_tmp; + char efr_tmp = 0x00; + + // We need to enable flow control to prevent overflow of buffers and + // lose data when used with fast devices like the WiFly. + + switch (type) { + case Disabled : + break; + case RTS: efr_tmp = EFR_ENABLE_RTS; + break; + case CTS: efr_tmp = EFR_ENABLE_CTS; + break; + case RTSCTS: efr_tmp = EFR_ENABLE_RTS | EFR_ENABLE_CTS; + break; + default: ; + + } + + //Save flowcontrol state + //enable enhanced functions + _config.flowctrl = efr_tmp | EFR_ENABLE_ENHANCED_FUNCTIONS, + + lcr_tmp = this->readRegister(LCR); // save LRC register + this->writeRegister(LCR, LCR_ENABLE_ENHANCED_FUNCTIONS); // write magic number 0xBF to enable access to EFR register + this->writeRegister(EFR, _config.flowctrl); // set flow and enable enhanced functions + this->writeRegister(LCR, lcr_tmp); // restore LCR register +} + + +/** Initialise internal registers + * Should be in protection section. Public for testing purposes + * If initialisation fails this method does not return. + * @param none + * @return none + */ +void SC16IS750::_init() { // Initialise SC16IS750 + // Software reset, assuming there is no access to the HW Reset pin + swReset(); + // Set default baudrate and save in _config + // LCR, DLL/DLH baud(); // Set dataflow and save in _config - // We need to enable flow control or we overflow buffers and - // lose data when used with the WiFly. Note that flow control - // needs to be enabled on the WiFly for this to work but it's - // possible to do that with flow control enabled here but not there. - // TODO: Make this able to be configured externally? - _config.flowctrl = EFR_ENABLE_CTS | EFR_ENABLE_RTS | EFR_ENABLE_ENHANCED_FUNCTIONS, - - this->writeRegister(LCR, 0xBF); // access EFR register - this->writeRegister(EFR, _config.flowctrl); // enable enhanced registers + // LCR, EFR + set_flow_control(); // Set default dataformat and save in _config + // LCR format(); + // Set default break condition and save in _config + // LCR + //set_break(); + // Set default fifoformat and save in _config - this->writeRegister(FCR, 0x06); // reset TXFIFO, reset RXFIFO, non FIFO mode - this->writeRegister(FCR, 0x01); // enable FIFO mode + // FCR + _config.fifoenable = true; + _config.fifoformat = FCR_RX_IRQ_NONE | FCR_ENA_FIFO_64; + flush(); // The UART bridge should now be successfully initialised. - // Test if UART bridge is present and initialised if(!connected()){ #if(0) // Lock up if we fail to initialise UART bridge. - while(1) { - }; + while(1) {}; #else printf("Failed to initialise UART bridge\r\n"); +#endif + } + else { + printf("Initialised UART bridge!\r\n"); + } + +} + +/** + * Flush the UART FIFOs while maintaining current FIFO mode. + * @param none + * @return none + */ +void SC16IS750::flush() { + + // reset TXFIFO, reset RXFIFO, non FIFO mode + this->writeRegister(FCR, FCR_TXFIFO_RST | FCR_RXFIFO_RST); + + if (_config.fifoenable) + // enable FIFO mode and set FIFO control values + this->writeRegister(FCR, _config.fifoformat | FCR_ENABLE_FIFO); + else + // disable FIFO mode and set FIFO control values + this->writeRegister(FCR, _config.fifoformat); + +#if(0) +//original + /* + * Flush characters from SC16IS750 receive buffer. + */ + + // Note: This may not be the most appropriate flush approach. + // It might be better to just flush the UART's buffer + // rather than the buffer of the connected device + // which is essentially what this does. + while(readable() > 0) { + getc(); } #endif } + /** * Check that UART is connected and operational. * @param none @@ -169,18 +280,10 @@ * @return 1 if there is a character available to read, 0 otherwise */ int SC16IS750::readable() { - /** - * Get the number of chars (characters) available for reading. - * - * This is data that's already arrived and stored in the receive - * buffer (which holds 64 chars). - * This alternative just checks if there's data but doesn't - * return how many characters are in the buffer: - */ return (this->readRegister(LSR) & 0x01); } -/** Determine if how many characters available to read. +/** Determine how many characters are available to read. * @return int Characters available to read */ int SC16IS750::readableCount() { @@ -201,12 +304,12 @@ return (this->writableCount() > 0); // Check datasheet for faster version } -/** Determine if how many characters available to write. - * @return int Characters available to write +/** Determine how much space available for writing characters. + * @return int character space available to write */ int SC16IS750::writableCount() { /* - * Get the number of chars (characters) available for reading. + * Get the available space for writing characters. * * This is data that's already stored in the transmit * buffer (which holds 64 chars). @@ -217,15 +320,13 @@ } - -char SC16IS750::getc() { - /* - * Read char from UART. - * - * Returns char read or or -1 if no data available. - * - * Acts in the same manner as 'Serial.read()'. - */ +/** + * Read char from UART Bridge. + * Acts in the same manner as 'Serial.read()'. + * @param none + * @return char read or -1 if no data available. + */ +int SC16IS750::getc() { if (!readable()) { return -1; @@ -234,16 +335,19 @@ return this->readRegister(RHR); } - -void SC16IS750::putc(char value) { - /* - * Write char to UART. - */ - +/** + * Write char to UART Bridge. Blocking when no free space in FIFO + * @param value char to be written + * @return value written + */ +int SC16IS750::putc(int value) { while (this->readRegister(TXLVL) == 0) { // Wait for space in TX buffer + wait_us(10); }; this->writeRegister(THR, value); + + return value; } @@ -254,6 +358,7 @@ write((const uint8_t *) str, strlen(str)); while (this->readRegister(TXLVL) < 64) { // Wait for empty TX buffer (slow) + wait_us(10); // (But apparently still not slow enough to ensure delivery.) }; } @@ -279,89 +384,108 @@ } #endif -void SC16IS750::flush() { - /* - * Flush characters from SC16IS750 receive buffer. - */ - - // Note: This may not be the most appropriate flush approach. - // It might be better to just flush the UART's buffer - // rather than the buffer of the connected device - // which is essentially what this does. - while(readable() > 0) { - getc(); - } -} - - +/** Set direction of I/O port pins. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param bits Bitpattern for I/O (1=output, 0=input) + * @return none + */ void SC16IS750::ioSetDirection(unsigned char bits) { this->writeRegister(IODIR, bits); } - +/** Set bits of I/O port pins. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param bits Bitpattern for I/O (1= set output bit, 0 = clear output bit) + * @return none + */ void SC16IS750::ioSetState(unsigned char bits) { this->writeRegister(IOSTATE, bits); } +/** Get bits of I/O port pins. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param none + * @return bits Bitpattern for I/O (1= bit set, 0 = bit cleared) + */ +unsigned char SC16IS750::ioGetState() { + return this->readRegister(IOSTATE) ; +} -// Begin SPI Implementation +/** Software Reset SC16IS750 device. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param none + * @return none + */ +void SC16IS750::swReset() { + this->writeRegister(IOCTRL, IOC_SW_RST); +} + + +// +// End Abstract Class Implementation // + + /** Class SC16IS750_SPI for a converter between SPI and a Serial port * + * @code + * + * @endcode + * */ SC16IS750_SPI::SC16IS750_SPI (SPI *spi, PinName cs) : _spi(spi), _cs(cs) { _cs = 1; // deselect _spi->format(8, 0); _spi->frequency(1000000); - +// _spi->frequency(100000); //test + + // Dont call _init() until SPI port has been configured. + // That is why _init() is not called in parent Constructor + _init(); + }; /** Write value to internal register. * Pure virtual, must be declared in derived class. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @param data The 8bit value to write * @return none */ void SC16IS750_SPI::writeRegister(RegisterName registerAddress, char data) { - /* - * Write <data> char to the SC16IS750 register <registerAddress> - */ _cs = 0; // select; _spi->write(registerAddress); _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 } /** Read value from internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @return char The 8bit value read from the register */ char SC16IS750_SPI::readRegister(RegisterName registerAddress) { - /* - * Read char from SC16IS750 register at <registerAddress>. - */ // Used in SPI read operations to flush slave's shift register - const char SPI_DUMMY_char = 0xFF; + const char SPI_DUMMY_CHAR = 0xFF; char result; _cs = 0; // select; _spi->write(SPI_READ_MODE_FLAG | registerAddress); - result = _spi->write(SPI_DUMMY_char); + result = _spi->write(SPI_DUMMY_CHAR); _cs = 1; // deselect; return result; @@ -369,23 +493,28 @@ // // End SPI Implementation +// -// Begin I2C Implementation -// - /** Class SC16IS750_I2C for a converter between I2C and a Serial port * + * @code + * + * @endcode + * */ SC16IS750_I2C::SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c), _slaveAddress(deviceAddress) { - _i2c->frequency(400000); + _i2c->frequency(400000); + // Dont call _init() until I2C port has been configured. + // That is why _init() is not called in parent Constructor + _init(); } /** Write value to internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @param data The 8bit value to write * @return none */ @@ -400,7 +529,7 @@ /** Read value from internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @return char The 8bit value read from the register */ char SC16IS750_I2C::readRegister(RegisterName registerAddress) { @@ -420,4 +549,5 @@ // -// End I2C Implementation \ No newline at end of file +// End I2C Implementation +// \ No newline at end of file
--- a/SC16IS750.h Wed Jan 22 16:39:37 2014 +0000 +++ b/SC16IS750.h Sun Feb 09 14:58:06 2014 +0000 @@ -1,6 +1,5 @@ /* SC16IS750 interface - * /////////////////////v1.0 Tedd OKANO, 18 Jul 2012, I2C I/F only, MIT License - * v1.1 WH, Nov 2013, Added SPI I/F and more methods, MIT License + * v0.1 WH, Nov 2013, Ported to mbed, Sparkfun Libs used as example. Added I2C and SPI I/F and 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,16 +19,32 @@ #ifndef _SC16IS750_H #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 */ + //Default I2C Slaveaddress -#define DEFAULT_SC16IS750_ADDR 0x9A +#define DEFAULT_SC16IS750_ADDR SC16IS750_SA0 //Default baudrate #define DEFAULT_BAUD_RATE 9600 #define ENABLE_BULK_TRANSFERS 0x01 -//#include "Configuration.h" - #define XTAL_FREQUENCY 14745600UL // On-board crystal (New mid-2010 Version) // See datasheet section 7.8 for configuring the @@ -56,9 +71,10 @@ #define LCR_BRK_ENA 0x40 #define LCR_BRK_DIS 0x00 -#define LCR_DIV_ENA 0x80 -#define LCR_DIV_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) @@ -66,6 +82,77 @@ #define EFR_ENABLE_RTS (1 << 6) #define EFR_ENABLE_ENHANCED_FUNCTIONS (1 << 4) + +// 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) +#define FCR_TXFIFO_RST (1 << 2) +#define FCR_RXFIFO_RST (1 << 1) +#define FCR_ENABLE_FIFO (1 << 0) + + + +/* + * Interrupt enable register. + */ + +#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 */ + +/* + * Modem control register. + */ + +#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) + +/* + * Line status register. + */ + +#define LSR_DR (0x01) /* Data ready */ +#define LSR_OE (0x02) /* Overrun error */ +#define LSR_PE (0x04) /* Parity error */ +#define LSR_FE (0x08) /* Framing error */ +#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) */ + +/* + * Interrupt identification register. + * 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) + + +/* + * 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 Chapter 11 of datasheet #define SPI_READ_MODE_FLAG 0x80 @@ -85,87 +172,192 @@ // SC16IS750 Register definitions (shifted to align) enum RegisterName { - RHR = 0x00 << 3, - THR = 0x00 << 3, - IER = 0x01 << 3, - FCR = 0x02 << 3, - IIR = 0x02 << 3, - LCR = 0x03 << 3, - MCR = 0x04 << 3, - LSR = 0x05 << 3, - MSR = 0x06 << 3, - SPR = 0x07 << 3, - TCR = 0x06 << 3, - TLR = 0x07 << 3, - TXLVL = 0x08 << 3, - RXLVL = 0x09 << 3, - IODIR = 0x0A << 3, - IOSTATE = 0x0B << 3, - IOINTMSK = 0x0C << 3, - reserved = 0x0D << 3, - IOCTRL = 0x0E << 3, - EFCR = 0x0F << 3, - DLL = 0x00 << 3, - DLH = 0x01 << 3, - EFR = 0x02 << 3, - XON1 = 0x04 << 3, - XON2 = 0x05 << 3, - XOFF1 = 0x06 << 3, - XOFF2 = 0x07 << 3, +/* + * 16750 addresses. Registers accessed when LCR[7] = 0. + */ + RHR = 0x00 << 3, /* Rx buffer register - Read access */ + THR = 0x00 << 3, /* Tx holding register - Write access */ + IER = 0x01 << 3, /* Interrupt enable reg - RD/WR access */ + +/* + * 16750 addresses. Registers accessed when LCR[7] = 1. + */ + DLL = 0x00 << 3, /* Divisor latch (LSB) - RD/WR access */ + DLH = 0x01 << 3, /* Divisor latch (MSB) - RD/WR access */ + +/* + * 16750 addresses. IIR/FCR is accessed when LCR[7:0] <> 0xBF. + * Bit 5 of the FCR register is accessed when LCR[7] = 1. + */ + IIR = 0x02 << 3, /* Interrupt id. register - Read only */ + FCR = 0x02 << 3, /* FIFO control register - Write only */ +/* + * 16750 addresses. EFR is accessed when LCR[7:0] = 0xBF. + */ + EFR = 0x02 << 3, /* Enhanced features reg - RD/WR access */ + +/* + * 16750 addresses. + */ + LCR = 0x03 << 3, /* Line control register - RD/WR access */ +/* + * 16750 addresses. MCR/LSR is accessed when LCR[7:0] <> 0xBF. + * Bit 7 of the MCR register is accessed when EFR[4] = 1. + */ + MCR = 0x04 << 3, /* Modem control register - RD/WR access */ + LSR = 0x05 << 3, /* Line status register - Read only */ + +/* + * 16750 addresses. MSR/SPR is accessed when LCR[7:0] <> 0xBF. + * MSR, SPR register is accessed when EFR[1]=0 and MCR[2]=0. + */ + MSR = 0x06 << 3, /* Modem status register - Read only */ + SPR = 0x07 << 3, /* Scratchpad register - RD/WR access */ +/* + * 16750 addresses. TCR/TLR is accessed when LCR[7:0] <> 0xBF. + * TCR, TLR register is accessed when EFR[1]=1 and MCR[2]=1. + */ + TCR = 0x06 << 3, /* Transmission control register - RD/WR access */ + TLR = 0x07 << 3, /* Trigger level register - RD/WR access */ + +/* + * 16750 addresses. XON, XOFF is accessed when LCR[7:0] = 0xBF. + */ + XON1 = 0x04 << 3, /* XON1 register - RD/WR access */ + XON2 = 0x05 << 3, /* XON2 register - RD/WR access */ + XOFF1 = 0x06 << 3, /* XOFF1 register - RD/WR access */ + XOFF2 = 0x07 << 3, /* XOFF2 register - RD/WR access */ + +/* + * 16750 addresses. + */ + TXLVL = 0x08 << 3, /* TX FIFO Level register - Read only */ + RXLVL = 0x09 << 3, /* RX FIFO Level register - Read only */ + IODIR = 0x0A << 3, /* IO Pin Direction reg - RD/WR access */ + IOSTATE = 0x0B << 3, /* IO Pin State reg - Read only */ + IOINTENA = 0x0C << 3, /* IO Interrupt Enable - RD/WR access */ +// reserved = 0x0D << 3, + IOCTRL = 0x0E << 3, /* IO Control register - RD/WR access */ + EFCR = 0x0F << 3, /* Extra features reg - RD/WR access */ + } ; + // This enum used to be part of SerialBase class (access via SerialBase.h). + // It seems not be supported anymore. The enums for Parity have moved to Serial now.. + enum Flow { + Disabled = 0, + RTS, + CTS, + RTSCTS + }; + + // SC16IS750 configuration register values +// Several configuration registers are write-only. Need to save values to allow restoring. struct SC16IS750_cfg { char baudrate; char dataformat; char flowctrl; - char fifoformat; + char fifoformat; + bool fifoenable; }; -/** Constructor - * - */ - SC16IS750(); /** Determine if there is a character available to read. * @return 1 if there is a character available to read, 0 otherwise */ - int readable(); + int readable(); -/** Determine if how many characters available to read. +/** Determine how many characters available for reading. * @return int Characters available to read */ - int readableCount(); + int readableCount(); /** Determine if there is space available to write a character. * @return 1 if there is a space for a character to write, 0 otherwise */ - int writable(); + int writable(); -/** Determine if how much space is available to write characters. - * @return int Characterspace available for writing +/** Determine how much space available for writing characters. + * @return int character space available to write */ - int writableCount(); - - char getc(); - void putc(char value); + int writableCount(); + - void write(const char *str); +/** + * Read char from UART Bridge. + * Acts in the same manner as 'Serial.read()'. + * @param none + * @return char read or -1 if no data available. + */ + int getc(); + +/** + * Write char to UART Bridge. Blocking when no free space in FIFO + * @param value char to be written + * @return value written + */ + int putc(int value); + + 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 = DEFAULT_BAUD_RATE); /** 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) */ - void format(int bits=8, Serial::Parity parity=Serial::None, int stop_bits=1); + 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 + * + * @param fptr A pointer to a void function, or 0 to set as none + * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) + */ + void attach(void (*fptr)(void), IrqType type=RxIrq); + +/** Attach a member function to call whenever a serial interrupt is generated + * + * @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) + */ + template<typename T> + void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) { + if((mptr != NULL) && (tptr != NULL)) { + _irq[type].attach(tptr, mptr); + serial_irq_set(&_serial, (SerialIrq)type, 1); + } + } +#endif + +/** Generate a break condition on the serial line + */ + void send_break(); + +/** Set a break condition on the serial line + * @param enable break condition + */ + 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. + * + * @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) + */ + void set_flow_control(Flow type=Disabled, PinName flow1=NC, PinName flow2=NC); + /** * Check that UART is connected and operational. * @param none @@ -179,38 +371,85 @@ #else // using Print::write; #endif - void flush(); + +/** Flush the UART FIFOs while maintaining current FIFO mode. + * @param none + * @return none + */ + void flush(); //required for Stream - int peek() {return 0;}; + 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 + * @param bits Bitpattern for I/O (1=output, 0=input) + * @return none + */ + void ioSetDirection(unsigned char bits); - // These are specific to the SPI UART - void ioSetDirection(unsigned char bits); - void ioSetState(unsigned char bits); +/** Set bits of I/O port pins. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param bits Bitpattern for I/O (1= set output bit, 0 = clear output bit) + * @return none + */ + void ioSetState(unsigned char bits); + +/** Get bits of I/O port pins. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param none + * @return bits Bitpattern for I/O (1= bit set, 0 = bit cleared) + */ + unsigned char ioGetState(); + + +/** Software Reset SC16IS750 device. + * This method is specific to the SPI-I2C UART and not found on the 16750 + * @param none + * @return none + */ + void swReset(); + /** Write value to internal register. * Pure virtual, must be declared in derived class. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @param data The 8bit value to write * @return none */ - virtual void writeRegister (RegisterName register_address, char data ) =0; + virtual void writeRegister (RegisterName register_address, char data ) =0; /** Read value from internal register. * Pure virtual, must be declared in derived class. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @return char The 8bit value read from the register */ - virtual char readRegister (RegisterName register_address ) =0; + virtual char readRegister (RegisterName register_address ) =0; + +/** Initialise internal registers + * Should be in protection section. Public for testing purposes + * If initialisation fails this method does not return. + * @param none + * @return none + */ + void _init(); + protected: //protected is accessible to derived classes, but not to external users +/** Constructor for this Abstract Class is protected + * + */ + SC16IS750(); + + SC16IS750_cfg _config; private: //private is not accessible to derived classes, nor external users - void init(); + }; @@ -249,14 +488,14 @@ SC16IS750_SPI(SPI *spi, PinName cs); /** Write value to internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @param data The 8bit value to write * @return none */ virtual void writeRegister(SC16IS750::RegisterName registerAddress, char data); /** Read value from internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @return char The 8bit value read from the register */ virtual char readRegister(SC16IS750::RegisterName registerAddress); @@ -307,14 +546,14 @@ SC16IS750_I2C(I2C *i2c, uint8_t deviceAddress = DEFAULT_SC16IS750_ADDR); /** Write value to internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @param data The 8bit value to write * @return none */ virtual void writeRegister(SC16IS750::RegisterName register_address, char data ); /** Read value from internal register. - * @param register_address The address of the Register (enum RegisterName) + * @param registerAddress The address of the Register (enum RegisterName) * @return char The 8bit value read from the register */ virtual char readRegister(SC16IS750::RegisterName register_address );