Shop OBEX P1 Docs P2 Docs Learn Events
I2C Issue.... WARNING involes math — Parallax Forums

I2C Issue.... WARNING involes math

RavenkallenRavenkallen Posts: 1,057
edited 2010-05-02 19:33 in Propeller 1
So i have played around with i2c eeprom interfaced to the propeller. I have had some issues regarding speed. Tell me if i am wrong. I am assuming the objects use i2c fast mode, and i am reading one byte at a time. The i2c fast mode is 400 khz, if that means that is takes one cycle to clock in a bit and there are 8 bits in a byte, we should have a theoretical read time of 50 kilobytes a second. If there are four bytes(Slave Address and w/r bit, Memory address, data byte to be received)·needed to complete a·read cycle that would leave 12.5 kilobytes a second. Plus if you add a little time for the propeller to process, i would·say we·have a speed of roughly 10 kilobytes a second. Problem is,·all the objects·i tried·only gave me roughly 500 bytes a second, which is way to slow for my application. I know that you can read from the eeprom sequentially to save·even more time, but still, i don't get it. Even if the object was using i2c·slow mode it would still·yield about 2.5 kilobytes a second. IF I am doing something wrong, please let me know. I·Know the propeller is fast enough, but maybe the objects are·just to slow...Calling anybody with knowledge of i2c and the propeller...·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-02 04:00
    It all depends on what I2C driver you're using. A byte does require 10 clocks, so your throughput calculations are a little off. In addition, the usual byte transfer does require a select byte and two address bytes in addition to the byte being transferred. You can transfer multiple bytes and that does spread out the overhead cost, but you have to transfer multiple bytes explicitly.

    If you're using Basic_I2C_Driver, this is written in Spin so that will slow down the transfer rates. If you use sdspiFemto, the default speed is 100KHz. You have to override the default to get a 400KHz speed.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-05-02 04:19
    wow, thanks for the quick answer Mike. I have tried two different i2c objects, one called ''i2c'' and the other called ''romengine1'' or something. even if it took 10 cycles per byte that wouldn't change the speed so much that it could only transfer 500 bytes a second. i know spin is pretty slow. i wonder if someone made a pasm i2c driver?
  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-02 04:31
    sdspiFemto.spin is a PASM I2C driver. It's part of FemtoBasic, but can be used by itself. See the comments at the beginning of the object for details.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-05-02 04:37
    i will try that and see how it goes.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-05-02 14:53
    I ran some tests on the EEProm file system I'm developing, and the read speed is about 2,300 bytes/second.· I used Mike's Basic_I2C_Driver, which is written in Spin.· I also used page mode, which reads 64 bytes at a time.· At some point I'll try a PASM driver, which should speed things up considerably.

    BTW, I measured a write speed of 250 bytes/second.· I also used page mode for this.· I basically wrote 400-byte chunks of memory, which were broken up into seperate 64-byte pages.· This means the boundary pages were written twice in my test, so the optimal write speed would be somewhat higher than 250 bytes/second.· However, an assembly driver won't help this much.

    Dave
  • BradCBradC Posts: 2,601
    edited 2010-05-02 15:42
    Dave Hein said...
    This means the boundary pages were written twice in my test, so the optimal write speed would be somewhat higher than 250 bytes/second. However, an assembly driver won't help this much.

    Something is very wrong there. That would suggest 32k in ~131 seconds. I've never seen the propeller bootloader take that long to write an eeprom.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-05-02 16:00
    Thanks dave, but i don't need to read 64 bytes at a time. I only need to read one. Bradc you do have a point, 250 bytes a second is really slow, even with the 5ms delay time.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-05-02 16:13
    Well, i looked at sdspifemto and it looked really weird. Its like i2c, spi and sd all in one. I don't know if i could figure it out. I know other devices(Like the basic stamp) read the whole program from a i2c eeprom. The bs2 has a speed of like 2,000 instructions/ s. I know the prop is capable of faster speed, even in spin.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-02 16:40
    Yes, sdspiFemto combines an I2C driver with a low level SD card SPI driver, but the operations are separate. You can ignore the SPI stuff completely if you're only interested in I2C. The Spin routines "start", "readEEPROM", and "writeEEPROM" are the only ones you have to understand. If you want to use variable timing for writes rather than a fixed 5ms delay after a write, you'd need to use "writeWait" as well.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-05-02 17:36
    I saw the "writewait" routine and the "start" one, but i can't find the "readeeprom" and "writeeeprom" one's. I must me overlooking it, but it is like not there. You said it was a spin routine right.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-02 17:45
    These routines begin with:

    PUB readEEPROM(addr,buffer,count) | t '' Read a block from EEPROM to RAM
    PUB writeEEPROM(addr,buffer,count) | t '' Write a block to EEPROM from RAM
    PUB writeWait(addr) | t '' Wait for EEPROM to complete write
    PUB start(ctrlBlk) | t '' Start the I2C I/O driver (standalone)

    For readEEPROM, writeEEPROM, and writeWait, "addr" is the EEPROM address (including the I/O pin numbers as described in the comments). "buffer" is the address of the data to be read or written, and "count" is the number of bytes to be transferred in a single transfer. For reads, the data must lie completely within a single EEPROM. For writes, the data must fit within a single EEPROM page (typically 64 or 128 bytes). For start, "ctrlBlk" is the address of a two long work area used to communicate with the PASM routine.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-05-02 19:33
    BradC said...

    Something is very wrong there. That would suggest 32k in ~131 seconds. I've never seen the propeller bootloader take that long to write an eeprom.
    I tried it again after formatting the EEProm, and it took half the time to write my test file.· So it appears my block allocation method is taking a significant amount of time.··Everytime I·add a new block to a file I·start from the beginning of the file system and step through the blocks looking for an unsed one.· I need to modify that algorithm so it remembers where the last free block was.· Or I could create a free-block table when I first mount the file system.

    Edit: I modified my code to keep track of the last allocated block, and it now writes about 1,260 byte/second.· It's still about 10x slower than the theoretical max of 12,800 bytes/second, but it's getting better.· There's a few more things I can do to speed it up, and then I'll have to go to a PASM driver to get any more gain.

    Dave

    Post Edited (Dave Hein) : 5/2/2010 8:04:08 PM GMT
Sign In or Register to comment.