Shop OBEX P1 Docs P2 Docs Learn Events
I2C Slave — Parallax Forums

I2C Slave

hippyhippy Posts: 1,981
edited 2012-09-28 12:53 in Propeller 1
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.
«1

Comments

  • Ken PetersonKen Peterson Posts: 806
    edited 2008-04-11 20:42
    You say the PASM version won't play ball. What do you mean by that?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    The more I know, the more I know I don't know.· Is this what they call Wisdom?
  • simonlsimonl Posts: 866
    edited 2008-04-11 23:09
    Hi hippy,

    Nice work smile.gif

    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 smile.gif
  • hippyhippy Posts: 1,981
    edited 2008-04-12 02:08
    "Won't play ball" ... just being the usual PITA to debug. It's almost a direct line-for-line translation of the Spin, so what could go wrong smile.gif

    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 ...
  • hippyhippy Posts: 1,981
    edited 2008-04-12 13:12
    PASM version fixed, so now fastest-speed operation. Still haven't found the problem when two I2C Slaves are opened at the same time. Emulates a 256 byte I2C Ram held in Cog.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-04-12 13:18
    hippy, would it be possible to do a version of this that just monitors the bus like a sniffer and dumps everything received into a buffer in the hub?

    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.
  • simonlsimonl Posts: 866
    edited 2008-04-12 13:35
    See - I knew you'd do it [noparse]:grin:[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    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 smile.gif
  • hippyhippy Posts: 1,981
    edited 2008-04-12 16:34
    stevenmess2004 said...
    hippy, would it be possible to do a version of this that just monitors the bus like a sniffer and dumps everything received into a buffer in the hub?

    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.
  • hippyhippy Posts: 1,981
    edited 2008-04-12 17:09
    D'oh !

    Opening the same object twice is of course not the same as opening a second object rolleyes.gif

    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.
  • hippyhippy Posts: 1,981
    edited 2008-04-13 15:12
    Final Version for now.

    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.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-04-14 11:09
    Thanks hippy, I'll have a look at it this week. I seem to be getting more and more stuff to do...
  • EricGarlicEricGarlic Posts: 41
    edited 2008-04-17 21:25
    Hippy,

    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
  • EricGarlicEricGarlic Posts: 41
    edited 2008-05-05 08:09
    Hi Hippy, any plans to work up your I2C slave object. I'm keen to test it.

    Cheers
  • hippyhippy Posts: 1,981
    edited 2008-05-05 13:32
    Sorry, I missed your earlier post (4/17).

    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.
  • hippyhippy Posts: 1,981
    edited 2008-05-10 22:55
    I've had a further chance to test this. With P28(SCL) and P29(SDA) wired straight to other pins, using P28/P29 for Master I2C and the others as Slave I2C it all works okay on the same Propeller ( and fails if I specify the wrong pins, just as a double-check ).

    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.
  • hippyhippy Posts: 1,981
    edited 2008-05-11 10:30
    Slightly off-topic ? You'd be far better off starting a new thread. It saves annoying those who are interested in I2C Slaves and don't want to be distracted by other discussion, and those not interested but have the answers you need, or would benefit from the replies, may not even see the post.
  • hippyhippy Posts: 1,981
    edited 2008-09-26 19:28
    Some enhancements I forgot to release earlier. Main change AFAIR is that there are now hard and soft I2C Master Drivers for DemoBoard and ProtoBoard respectively, no SCL pull-up and with SCL pull-up.
  • TimmooreTimmoore Posts: 1,031
    edited 2009-05-16 01:18
    Hippy,

    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
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-16 03:39
    Hippy & 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
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-29 13:00
    So, which is it: Hippy's or Tim Moore's method?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH
  • hippyhippy Posts: 1,981
    edited 2009-05-29 16:45
    I suppose it's my method plus Tim's fixes.

    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.
  • TimmooreTimmoore Posts: 1,031
    edited 2009-05-29 17:01
    So I am [noparse]:)[/noparse], I will post my I2C slave example to a different thread. Rather than a memory slave, it is a slave that controls a number of I2C slaves, GPS, etc and exposes those on its I2C slave interface. I was testing the I2C implementation on the First NI CRio controller. I found some limitations with the I2C implementation and some devices just wouldn't work so I ended up putting those devices on a propeller and connecting that to the CRio I2C interface. Then I had fun connecting anything that was around either to the CRio or the prop.
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-29 18:02
    I'll merge Tim's code in the State Table and test exhaustively. Many thanks!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH
  • photomankcphotomankc Posts: 943
    edited 2009-09-08 04:56
    Is there a final version out there? I'm trying to make something out of this but I fear I'm making a giant mess.· Hippie's version runs great on a single prop over a real buss but I get failures at various points using two props.· The file from Tim Moore I can't get to cooperate with the test code for AiChip.· Is there a simple example out there to start from?

    Post Edited (photomankc) : 9/8/2009 5:40:43 AM GMT
  • TimmooreTimmoore Posts: 1,031
    edited 2009-09-08 05:00
    http://forums.parallax.com/forums/default.aspx?f=25&m=355505 is a I2C slave example using a modified version of hippys code. This code works as a I2C slave with a different processor as the I2C master.
  • photomankcphotomankc Posts: 943
    edited 2009-09-08 06:14
    I may be better off to put this on the back table and go with simple RS232 for now. Thanks for the link to the code though. Lots of examples to wade through.
  • MarcGMarcG Posts: 14
    edited 2011-01-14 08:56
    Tim or any helping hand,

    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
  • TimmooreTimmoore Posts: 1,031
    edited 2011-01-15 11:11
    My version of I2cslave I used with another processor as the master, the FRC Crio controller though it acts very similar to the lego nxt system.
    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.
  • Cluso99Cluso99 Posts: 18,069
    edited 2011-01-15 12:14
    Here's the link http://forums.parallaxinc.com/forums/default.aspx?f=25&m=355505 Just add "inc" to parallax.com
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 12:22
    Hi.

    And here is link on NEW forum

    I2C-slave-example
  • MarcGMarcG Posts: 14
    edited 2011-01-15 15:25
    Cluso, thanks for showing me about adding inc to forums.parallax.com, in order to access the old forum. That is going to be a great help. And thanks Sapieha for the link in the new forum.

    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):
    PUB readLocation16(SCL,device_address, register) : value
      start(SCL)
      write(SCL,device_address | 0)
      write(SCL,register)
      start(SCL)
      write(SCL,device_address | 1)  
      value := read(SCL,ACK)
      value <<= 8
      value |= (read(SCL,NAK) & $ff)
      stop(SCL)
      return value
    

    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.
Sign In or Register to comment.