SC18IS604 SPI to I2C bridge - is anyone using it? - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: October 13, 2025, 03:55:02 pm
content: It is a weird chip and the NXP documentation is basically crap.The first thing I tested doesn't work per the manualYou have to do this (found on google on some NXP forum)and there is a minimum time between the two register accesses, of several microseconds. The NXP guy says he will check it but he never came back.There is also no need to send it all those 0xFF bytes... very few SPI devices need specific input data when reading output data (ADS1118 is one exception).And the ID string returned is offset by two bytes:Code:// Write the buffer, length numbytes, to the SC18IS604.// Returned data goes back into the buffer. Buffer must not be in CCM.// Returns true unless SPI3_DMA_TransmitReceive() returned false.static bool spi2i2c_write_read(uint8_t *buffer, uint16_t numBytes){SPI3_Lock();bool retcode;spi2i2c_cs(0);retcode = SPI3_DMA_TransmitReceive(buffer, buffer, numBytes, false, false, false);spi2i2c_cs(1);SPI3_Unlock();return (retcode);}// Check for presence of SC18IS604 chip - used for touch screen LCD. This also sets g_lcd_touch.void spi2i2c_init(void){g_lcd_touch=false;static uint8_t buf = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};// 1+16 actually needed, and must not be in CCM// Apply hardware reset pulse to SC18IS604HAL_GPIO_WritePin(STLED316S_DISPLAY_CURRENT_GPIO_PORT, STLED316S_DISPLAY_CURRENT_PIN, GPIO_PIN_RESET);hang_around_us(1);// min 125nsHAL_GPIO_WritePin(STLED316S_DISPLAY_CURRENT_GPIO_PORT, STLED316S_DISPLAY_CURRENT_PIN, GPIO_PIN_SET);osDelay(10);// 10ms just in case (data sheet says nothing about this)// Issue Read version function ID and get the ID string into the bufferbuf = 0xFE;// read function ID commandspi2i2c_write_read(buf, 1);osDelay(2);// actually measured: 10us is enoughbuf = 0x06;// read function ID commandspi2i2c_write_read(buf, 16);if (strncmp((char*)&buf,"SC18IS604",9)==0){g_lcd_touch=true;}}Next, I am trying to read the five GPIO pinsand this is the timingso you would think that writing 0x21 0x01 and a dummy byte would do it, in the usual SPI way. But no... what actually works, in extensive testing of different combinations and command bytes, is thisIt has the usual hallmarks of a monkey written DSThere is some code on Github for the 602 which has similar functions but it doesn't work, which could be because 50% of Github is junk, or any other reason.Code:// Read GPIO. Returns 1 byte.// 5 bits, 4 of them are push buttons and 5th is LCD /IRQ// This differs from the crappy NXP DS which contains this// https://peter-ftp.co.uk/screenshots/20251013517655316.jpg// but actually it is this// https://peter-ftp.co.uk/screenshots/202510131619335819.jpguint8_t spi2i2c_read_gpio(void){uint8_t buf;buf = 0x21;// read regbuf = 0x01;// reg 1buf = 0xFF;// dummy valuebuf = 0xFF;// dummy value - gets replaced with the GPIO bytespi2i2c_cs(0);hang_around_us(5); // 1us tested ok so we make it 5 (DS is not clear)SPI3_DMA_TransmitReceive(buf, buf, 4, false, false, false);hang_around_us(5);spi2i2c_cs(1);return buf;}So far I am just doing internal regs; not yet started on the SPI-I2C flow-through, which is likely to be more fun. I have not found any appnotes on this chip.

author: peter-h
author_rank: Super Contributor
timestamp: October 13, 2025, 09:39:48 pm
content: I wonder if this chip needs some undocumented delay after writing config registers? I find this code works:Code:// Configure the five GPIOs. Set all four to inputs (power-up default)buf = 0x20;// write regbuf = 0x00;// reg 0buf = 0x00;// value 0buf = 0xff;spi2i2c_write_read(buf, 4);// Configure bus clock rates register (I2CClk) - 375kHzbuf = 0x20;// write regbuf = 0x02;// reg 2buf = 0x05;// value 5 (max freq)buf = 0xff;spi2i2c_write_read(buf, 4);i.e. buf, a dummy byte, has to be sent, to get buf, the actual config value, to go in.EDIT: indeed a delay is needed. If you omit buf and send out 3 bytes instead of 4, and add adelayafter each write, some tens of us, it works.

author: mtwieg
author_rank: Frequent Contributor
timestamp: October 14, 2025, 01:40:30 pm
content: Microchip was infamous for selling factory-programmed PIC microcontrollers as various logic devices, including things like GPIO expanders and serial bridges. This meant there were lots of odd, undocumented behaviors one could discover, often requiring arbitrary delays to work around. I'm guessing this is a similar scenario.

author: peter-h
author_rank: Super Contributor
timestamp: October 14, 2025, 02:14:31 pm
content: Yes I am further along now, with the added excitement of using the SC18IS604 to talk to a FT6236 LCD touch screen controller.So I have one chip with a total POS datasheet talking through another chip with a total POS datasheet.You are right; these are all microcontrollers. Some of the required delays are impressive e.g. 70ms (70 milliseconds) after writing a config reg on the SC18IS604.Not sure I would go for anything from NXP, given the crap support found out there. The FT6236 is chinese so one expects the DS to be crap, and one is not disappointedAfter some 10hrs I am reading out the 1 byte chip ID (0x11).Code:static uint8_t buf;// Must not be in CCM// Send I2C read commandbuf = 0x02;// I2C write and read commandbuf = 2;// number of write bytesbuf = len;// number of read bytesbuf = i2caddr;buf = reg;buf = 0xff;buf = i2caddr;spi2i2c_cs(0);hang_around_us(5);SPI3_DMA_TransmitReceive(buf, NULL, 7, true, false, false);hang_around_us(5);spi2i2c_cs(1);SPI3_Unlock();// Wait for I2C transaction to complete and for the data to arrive in the SC18IS604.// Min delay required is 200us and that is for 1 byte read back.osDelay(2+((len*500)/1000));// Min 2 tick delay, adding 500us per byte// This part reads the data out of the buffer in the SC18IS604buf = 0x06;// SC18IS604 Read Buffer commandspi2i2c_write_read(buf, len+2);// Since the read-back data is at buf+2 onwards, shuffle it backfor (int i=0; i<len; i++){dst = buf[i+2];}

author: cv007
author_rank: Frequent Contributor
timestamp: October 15, 2025, 06:29:57 am
content: Table 14 in the datasheet says you need a minimum of 8us sck high time between each spi byte. Not sure how one would do that unless the spi clock is at a speed to meet that requirement (unless you are doing single bytes I guess). Seems odd they list a max spi speed of 1.2MHz but then make you wait 8us between bytes.

author: TinLethax
author_rank: Regular Contributor
timestamp: October 15, 2025, 07:17:08 am
content: This chip reminds me one of the on going project at my company, we have customer quote for the power supply. The our old PSU design (which is almost 10 years old) was using the I2C based analog to digital chip along with the digital isolator. Ended up replacing that ADC with just a cheapo ARM-based MCU because it was 3 times cheaper.IMHO the "general"* protocol interface bridge is so niche these day as MCUs are so cheap, already loaded with a bunch of peripheral and you can pretty much do anything with it in your own way with little to no hidden delay needed***General as for I2C, SPI and UART.*Except errata lol

author: peter-h
author_rank: Super Contributor
timestamp: October 15, 2025, 04:00:53 pm
content: I eventually solved ithttps://www.eevblog.com/forum/microcontrollers/looking-for-some-simple-tips-on-resistive-touch-panel-on-an-lcd/msg6069201/#msg6069201QuoteI didn't spot that, although I did spot that Tspilead is missing from the numbers... It might explain why dummy bytes are needed. But only in some places. It clearly is not a blanket requirement. You are probably right in that a much slower I2C clock might also work. It does look like that 8us applies only to SPI transactions intended to generate I2C activity. and I found a dummy byte is needed in one place there.EDIT: I did tests with different SPI clock speeds. Currently it is 650kHz which is ~1/2 of the 1.2MHz max. 650kHz is 12.3us per byte. No gap is needed at 650kHz, or 325kHz. But at 1.3MHz, it still works too, which is a surprise. So I don't know where this 1.8us comes from. I found data online which says max clock is 2MHz but the current DS does not say that, and at 2.6MHz it does not work (even the chip ID does not come back). The need for /CS=1 (Tcsw) implies a specific context, where you transmit data to I2c and probably expect a response; I have only one such, to read back the touch coordinates and that has a delay before retrieving the I2C device responseosDelay(2+((len*500)/1000)); // Min 2 tick delay, adding 500us per byteQuoteMy CPU does have I2C ports but I have no pins left for them