I2C Slave
hippy
Posts: 1,981
Something which has been on the To Do list for a while ... Propeller as an I2C Slave.
Entirely Spin ( the PASM version won't play ball ) so needs to have the I2C bus speed wound down low. The demonstration emulates a 512 x 8 Eeprom connected to the Propeller SDA/SCLK lines so runs without needing any hardware mods. Nothing fancy, just the basics, and probably doesn't conform to whatever the official I2C spec says a slave should.
Entirely Spin ( the PASM version won't play ball ) so needs to have the I2C bus speed wound down low. The demonstration emulates a 512 x 8 Eeprom connected to the Propeller SDA/SCLK lines so runs without needing any hardware mods. Nothing fancy, just the basics, and probably doesn't conform to whatever the official I2C spec says a slave should.
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
Nice work
Knowing you, the PASM version's probably coded too well and is too fast for I2C LOL (I'm sure you'll get it working tho').
Thanks for sharing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheers,
Simon
www.norfolkhelicopterclub.co.uk
You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
BTW: I type as I'm thinking, so please don't take any offense at my writing style
There's also some odd bug I haven't located yet which means running two concurrent I2C Slaves ( Spin versions ) with different Device ID's fails the tests.
If anyone wants to take a cursory look at the code ...
I'm working on a serial/i2c console for the prop at the moment to use in testing another project and this would be really useful.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheers,
Simon
www.norfolkhelicopterclub.co.uk
You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
BTW: I type as I'm thinking, so please don't take any offense at my writing style
Funny you should mention that; exactly how I set about debugging the PASM code. This grabs the raw bit stream and also identifies start, stop and data bits for on-screen reporting. It's easy enough to add logging to I2cSlave_Slave_XXX.spin in the same way if you want to add higher level captures. This is a simple fill and stop buffer but a ring buffer should work as well.
Currently shows the results of a writebyte then readbyte.
I'll probably produce a later version which handles high-level processing while also looking for dodgy conditions on the bus to try and find why I get problems with two I2C Slaves running. Just listing the bit stream triplets which are invalid may show where problems are.
Opening the same object twice is of course not the same as opening a second object
In this case it simply changed the Device Id of the single I2C Slave so of course the bus was left floating when trying to read from the first used Device Id; the slave said, "not for me" and went to sleep until the next start bit.
Doing it properly and everything tested so far works fine. I cannot believe how many hours I've spent on this having done something so fundamentally stupid !
Once I've done some more comprehensive testing and added some better documentation, I'll probably have my first object suitable for Obex.
Supports 7-bit and 10-bit device addressing. 1Kx8 Ram in Cog, up to 32Kx8 in Hub ( only 16Kx8 tested ).
Doesn't support clock stretching ( incompatible with ProtoBoard hardware ). Not tested over physical wires, only used INA/OUTA/DIR loop-back on same chip.
I2cSlave_Demo : Proves it all works
I2cSlave_Slave : The actual I2C Slave handler ( PASM )
I2cSlave_Master : I2C Master routines ( Spin )
I2cSlave_16Kx8Ram : Test of 16Kx8 Ram
I2cSlave_32Kx8Ram : Theoretical 32Kx8 Ram
I2cLogger_Demo : Demonstrates I2C capture / logging
Enjoy ! Bug reports welcome.
@stevenmess2004 : I've updated the I2C logging which you might like to take a look at.
I've been waiting for this. Tried out the demo programs with VGA (I've never managed to get TV to work on PAL) using the Proto Board. Works fine.
I then tried to read/write to the slave with a wired I2C interface but with little luck. My issue is that I'm still bashing my way around Propeller Spin. So just waiting for your documentation / Obex version. ETA?
Cheers
Cheers
I haven't tried any properly wired I2C scenarios but I'm going to give that a go. Apart from any tweaks needed to make that work the I2C Slave software should be "as is", near finalised.
I've got a much better I2C bus monitor written - Not sure if it's in the above package, but if not, it captures much faster, works with a TV or terminal emulator / HyperTerm and suited for use with a simple VB/Other front-end for filtering what info's wanted. Mainly lacking documentation.
I don't have a scope so if there's any hardware issues with a properly wired I2C slave which I cannot fix by guessing or analysing in software that will have to be a job for someone who has the right tools.
That's as close as I can get it to 'real application use' as I don't have another Propeller setup to run separate Master and Slave.
I have been using a modified version of your i2c slave driver - modified in that it uses hub memory only, etc.
I believe I have found a problem with the I2C state machine. When the master writes a byte to the slave, it will release the SDA to float (so the slave can drive it for the ack) when it takes the SCL low. If SDA is pulled high before the slave pulls SDA low for the ack then you get the sequence 00_10_01 (i.e. SDA goes from 0 to 1 when SCL goes from 1 to 0 on the 8th clock of a write). This is an error in your state machine.
I have been seeing this happen a lot, > 50% of the transfers to the prop I2c slave have been failing with no ack.
I changed 2 places in the state machine - the above and 10_01_00 which is entered after the ack is sent. With these 2 changes I get the correct behaviour.
I have attached my modified driver that contains these state changes.
Thanks Tim
Thanks - great job as usual. This code together with the code from Beau gives me high-quality routines that are ideal for SPI and I2C interfaces.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH
The two fixes are for glitches / oversights which I never encountered when testing, but then I never had the tools to do exhaustive real world testing.
You can use Tim's code 'as is' if that's suitable or take the two changes made to the State Table and apply them to any of the code I produced earlier.
Many thanks Tim, for putting the effort in to fix the problem and for sharing. In some ways I'm glad you got so many errors, just a few occasional ones could have been very hard to track down and quite frustrating.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH
Post Edited (photomankc) : 9/8/2009 5:40:43 AM GMT
I don't know if any progress has been made on the i2c slave front, using separate Propellor chips. This is the latest forum item I could find.I have been trying to find the example of Hippy's modified code with 2 processors (http://forums.parallax.com/forums/default.aspx?f=25&m=355505) . But since the Forum has been migrated, I can't locate it. Do you know where it currently resides?
I have been attempting to use either Hippy's or your modified 12cslave_info object with separate processors, accessing hub ram at a pointer with little success. I have the master i2c on pins 6 & 7 of a prop demo board and the slave i2c on pins 28 & 29 of a Education kit proto board. While I have had no luck at all with Hippy's master and slave objects, your object using Hippy's AiChip_I2cSlave_Master_DemoBoard_006.spin or Basic_I2C_Driver has had erratic results. Reading or Writing, the data seems to slop over into adjacent memory locations, to and from the slave.
Any guidence would be greatly appreciated. Thanks
What do you mean by slop over? The save auto increments the address when reading/writing or are you reading from one location and seeing different address locations? The way I was using it was I had the prop reading sensors and storing the output in a range of addresses and the Crio reading them, I would set the memory location at the being of the sensor memory range and let it auto increment through it to the end. The only issues I saw was the sensor values changing while I was reading but thats expected with the way I was updating the memory.
And here is link on NEW forum
I2C-slave-example
Tim, first of all, Thank You for getting back to me. I want to do some more investigation before holding to what I said about slop over. Just wondering, is the i2cslave_info object capable of writing as well as reading hub memory on the slave prop? My aim is to have the i2cslave_info object point to @myarray, size 64, on the slave prop. Where the array contains 32 16bit words that hold data values for my slave prop board's front panel controls. From the master prop, I want to either interogate, by reading data at any location in @myarray, or make changes on the slave by writing data at any location in @myarray.
I suppose for the reading I can call (from the modified Basic_i2C_driver I found in the fsensor archive):
Where a register value of 0 would equal the first 8 bit byte byte in @myarray, 1 the second 8 bit byte, 2 the third 8 bit byte or 2nd 16 bit word, and so on.