I2C Routines (Spin2/Inline PASM2)

JonnyMacJonnyMac Posts: 6,595
edited 2020-03-19 - 22:03:36 in Propeller 2
I translated my jm_i2c.spin to Spin2 and found that it worked, but actually ran faster that 400kHz which is not good with some devices. Where I knew I was going to go, anyway, was converting the routines to inline PASM2 so that the bus clock speed could be controlled. It works. That said, it's version 1, so if you find something wrong please let me know.

I've attached a little demo that is a bus scanner. You can see it found two devices. The device at $AE is a 24C32N EEPROM. The device at $D0 is a DS3231 RTC. Both devices are on a little module that I picked up on Amazon. I tested the I2C methods by setting the clock and reading it back, watching the time change every second.

The updated (March 18) version allows you to specify the internal pull-up strength or none at all (e.g., external pull-ups are used). Block methods have been added, too.

March 19: Updated to use new constants for pin modes in PNut v34o.

Comments

  • I learned more about I2C, P2ASM and the P2 in ten minutes of reading your code than days spent otherwise!

    Thanks, JonnyMac!

    dgately
  • Thanks, Dennis, I'm glad you found the code useful. I am adding block routines at the moment which will speed things along when more than one sequential byte needs writing or reading. The .write() and .read() methods can be used in a loop, but there's a time penalty for shuttling the PASM2 code into the interpreter cog for execution -- it should only take a few more bytes of PASM2 for block moves.
  • RaymanRayman Posts: 10,485
    edited 2020-03-18 - 18:19:50
    I was playing round with the resistor values the other day...
    I think there was a downside to 1.5k, trying to remember what it was...

    Maybe it was the response of the device being slower with a lower value resistance...
    It's probably the best choice though.
  • That's interesting. Even with the P1, I always found that stiff pull-ups (3.3k or 2.2k) were best for the devices I worked with.
  • There is also a 1mA mode, which corresponds roughly to a 3.3k resistor.
  • I didn't think of that... 3.3k would be better...

    There are potential issues when mixing high speed and low speed devices on the same bus...
    15k is probably better for low speed, 1.5k for high speed...
  • Thanks for the reminder, Andy. I'm going to add the pull-up strength as a configuration parameter.
  • I'm trying to wrap my head around 1 mA mode...
    Will that work with multiple devices on the same bus?
  • RaymanRayman Posts: 10,485
    edited 2020-03-18 - 19:42:24
    I wonder if it might be better to leave the I2C code in Spin...

    bytecode would be more compact and I2C does't really need assembly.
    My driver only has 3 lines of ASM to set the pullup strength...
    I just left the rest as Spin. You don't save anything with Fastspin, but didn't seem worth the bother to switch to assembly...

    Here's an example of what I'm using for comparison.
  • JonnyMacJonnyMac Posts: 6,595
    edited 2020-03-18 - 19:45:26
    I understand what you're saying, Ray. I found at 200MHz that the clock speed was greater than 400kHz which may bother some older devices. For large block moves with high speed devices, inline PASM will be faster, IMO (especially with block read and write methods). Yes, there is a bit of cost in terms of code space, but I think the trade is worth it.

    My Spin2 code -- where I started -- is attached. I'll have a look at your code, too.

    I am only using PNut; none of my code has tested with FastSpin.
  • Actually, now that I think about it... Spin in Pnut is probably much slower than Spin in Fastspin.
    So, maybe you do need assembly...
  • Spin2 is roughly 16x as fast as Spin1, but not as fast as assembly.
  • cgraceycgracey Posts: 12,677
    edited 2020-03-18 - 23:12:19
    JonnyMac wrote: »
    Spin2 is roughly 16x as fast as Spin1, but not as fast as assembly.

    Is that at the same clock rate? I haven't done any measurements, myself, yet.
  • Yes. Granted, it was a very quick test; same generic (bit twiddling) code running at 80MHz. I suspect programs that use multiply and divide will improve even more.
  • I2C driver updated (attached to first post)
    -- added pull-up configuration
    -- added wr_block() and rd_block() methods
  • JonnyMac wrote: »
    Yes. Granted, it was a very quick test; same generic (bit twiddling) code running at 80MHz. I suspect programs that use multiply and divide will improve even more.

    Thanks, John. Considering we have a 2x improvement at the PASM level, that means the XBYTE is yielding an 8x improvement.
  • kg1kg1 Posts: 70
    edited 2020-03-19 - 02:55:40
    Attached file at top: version 1 was 10461, version 2 is 10988 bytes. No name change. If file has disappeared click date as in photo attached below:
    456 x 142 - 15K
  • jmgjmg Posts: 14,289
    Rayman wrote: »
    I'm trying to wrap my head around 1 mA mode...
    Will that work with multiple devices on the same bus?

    Yes, it is only slightly different from a 3.3k pullup.
    The resistor has dropped to 0.5mA at 50% Vcc, so you get the classic exponential rise, whilst a current source will still be 1mA at 50%.
    That means a constant current pin will have a bit faster rise time for the same power drain.

    A current source will tail off very close to Vcc.
    Does anyone have the knee voltage of the P2 in current mode (guess ~ 500~700mV below Vcc?) or any curve tracer plots ?
  • JonnyMacJonnyMac Posts: 6,595
    edited 2020-03-20 - 02:24:41
    This makes me smile a little bit. It's an update of a P1 program that was an update of a BS2 program that was an update of BS1 program that I wrote in 1994. I'm having as much fun with the P2 and Spin2 as I did when I first got the BS1 26 years ago.

    This is an LCD demo for a PCF8574 LCD backpack and 2x16 LCD. Tested with PNut v34o.
  • Perfect timing. This was exactly what I needed today. Thanks, @JonnyMac
  • That code's a week old -- I should probably review it! I hope you find it helpful.
Sign In or Register to comment.