Bit of history: I have designed and build a series of add-on boards based on the DAC8574 16-Bit I2C DAC. They work very well, and I can drive them no problem from a Pi using C/PIGPIO I2C commands at 400KHz. So far so good.
The DAC8574 has a 'base' I2C address of 0x4C and a user-selectable 4-Bit address (A0-A3). A0,A1 are 'Physical' address selection bits, and A2,A3 are so-called 'Extended' address selection bits.
By setting A0,A1 the device appears on Physical I2C addresses 0x4C - 0x4F to talk to 16 devices you then set A2,A3 via a control register. Obviously there is duplication of the 'Physical' addresses - A device set to 0x0000 will be on the same Physical address as those set 0x0100, 0x1000 and 0x1100.
I can write to these overlapping devices separately with no problems. The write sequence being:
[P][Addr][w][CTRL][MSB][LSB][P]
Where MSB & LSB are the output level, and the [CTRL] byte contains A2,A3 and bits to select which of the 4 output channels you are writing to. Etc., standard stuff. IOt all works very well, and my add-on boards have DIP switches to select the address and can be daisy-chained together to provide up to 16x4 = 48 Analogue outputs.
So, if my software knows what boards to expect, I can write to them without a problem. Then, I thought: what happens if a user just has, say, 2 boards, and sets them to Eg. 0x0100 and 0x0000 - is there a way I can tell what hardware is present.
From the DAC8574's perspective, yes you can. You can write a value to an output channel, then read it back. If you get back what you wrote, the device is there. Great, I thought, I'll write a simple start-up routine that scans the 16 possible addresses and notes which address(es) have devices sitting on them.
However, the read sequence requires the dreaded Repeated Start bit. The sequence being as follows:
where Sr is a repeated start bit.
PIGPIO cannot send the Sr bit as it's not supported by the underlying SMB driver so I thought I'd try bit-banging the I2C connection instead.
First question: My hardware has already been built to use the normal Pi I2C bus connection on pins 3 & 5 (GPIO2 & 3), and I'd rather not change this. So, can I bit-bang the DACs over GPIO2 & 3 to find out what's physically there, and then switch to 'normal' I2C operation. ie:
bbI2COpen
bbI2CZip -- muiltiple commands to query the devices etc
bbI2CClose
then carry on as before:
i2cOpen
i2cWriteWordData -- normal operation of the software
i2cClose
My issue is that I am getting -82 errors (i2c write failed) when I call bbI2CZip, so I just wanted to check that bit banging over the normal I2C pins is OK, and/or do I need to take any particular precautions?
Also, I'd like to check the syntax of the of the Byte String I am passing to bbI2CZip. Specifically:
1) Do I need to include a Start bit? Joan's example on the PIGPIO library doesn't include one, so is it prepended automatically?
2) when I re-issue the Address, does it also need to be pre-pended by the Address identifier 0x04?
My byte sequence is currently:
0x02 0x04 0x4C 0x07 0x01 0x90 0x02 0x04, 0x4C 0x06 0x06 0x03
which reads as:
Start, Set Addr, 0x4C, Write, 1 Byte, 0x90, ReStart, Set Addr, 0x4C, Read, 2 Bytes, Stop
Assume my Address and Control register bytes are correct.
Do I need the first 0x02 (start) and the second 0x04 (Set Address)?
Sorry for the long post, but I needed to include sufficient detail.
Morph