billroy / bitlash

Bitlash: a programmable command shell for arduino
http://bitlash.net
MIT License
341 stars 73 forks source link

Support for a Microchip 24xx32A EEPROM module attached to the I2C bus, like the DigiX has #19

Closed remcoder closed 10 years ago

remcoder commented 10 years ago

Hi there!

I would very much like to use Bitlash on my DigiX so I added some basic EEPROM support for it. The DigiX comes with a Microchip 24LC32AT-I EEPROM module onboard, attached to the I2C bus on address 0x50. This is a nice addition since the AT91SAM3X8E doesn't come with this functionality.

Since I'm fairly new to writing Arduino libraries, I'm sure some things can be done in a better way. The most obvious thing is that EEPROM access is actually quite slow. This is due to the I2C bus but also because I went for a simple implementation of eeread() and eewrite(). Doing reads/writes in blocks instead of individually and/or keeping a copy in RAM would probably help.

Anyway, I'm awaiting your feadback and I hope we can get this change merged in master eventually ;-)

cheers, Remco

billroy commented 10 years ago

Hello and thanks for your interesting contribution.

I don't see anyplace where STARTDB and ENDDB are set; these control the size of the eeprom. How big is the eeprom on the DigiX? I couldn't find a reference on the Kickstarter page.

Also, I'd like to get a handle on the performance. How long does it take for a function defined in the i2c eeprom to count to 10000?

function count {if (++i > 10000) {print "time:", millis-t; stop}}
i=0; t=millis; run count

-br

remcoder commented 10 years ago

The eeprom is 4k. I somehow forgot about STARTDB and ENDDB totally. Looking at this, I'm wondering wether if it would be better to put the #defines for EEPROM_MICROCHIP_24XX32A and EEPROM_ADDRESS in bitlash.h, putting them all together.

hmm, I ran the loop but I wasn't patient enough to let it run to 10000, so I let it run to 1000, which took 29s. No very good I guess :-/ In fact, everything that interacts with the eeprom feels sluggish. Just saving a function takes something like 4s.

billroy commented 10 years ago

Those performance numbers are in the Ouch range. I think it bears investigation whether the I2C bus can be run at a higher clock rate on this board, perhaps?

-br

On Jan 2, 2014, at 3:47 PM, Remco Veldkamp notifications@github.com wrote:

The eeprom is 4k. I somehow forgot about STARTDB and ENDDB totally. Looking at this, I'm wondering wether if it would be better to put the #defines for EEPROM_MICROCHIP_24XX32A and EEPROM_ADDRESS in bitlash.h, putting them all together.

hmm, I ran the loop but I wasn't patient enough to let it run to 10000, so I let it run to 1000, which took 29s. No very good I guess :-/ In fact, everything that interacts with the eeprom feels sluggish. Just saving a function takes something like 4s.

— Reply to this email directly or view it on GitHub.

remcoder commented 10 years ago

Yes, according to the datasheet the chip supports 400kHz. I'll give it a try.

remcoder commented 10 years ago

Increasing the clock rate from 100,000kHz to 400,000kHz results in 7.6s to count to 1000. I tested this by modifying Wire.h directly b/c TWI_CLOCK is private. Not sure how this setting could end up as part of the pr. Including a modified copy of the Wire lib is not really pretty and there are different versions for different MCUs.

The 4x increase in responsiveness does seem to get us back into the "slow but usable" zone tho. Saving and calling functions feels much less sluggish now. So yeah, adjusting the clock speed definitely is a step in the right direction. Any ideas on how to get this fix in?

What other functionality relies heavily on the eeprom? I could do some more testing.

remcoder commented 10 years ago

At this point there are a few simple options that would improve the situation:

Please let me know in what direction you'd like this to go.

billroy commented 10 years ago

It might be worth exploring the RAM option. If you look in src/bitlash-unix.c at line 221 there’s a ‘fake eeprom’ implementation you could start with. You’d need to handle loading the ram from eeprom at startup and wriring through to the I2C eeprom, too — but the read speed should be very fast.

-br

On Jan 5, 2014, at 1:04 PM, Remco Veldkamp notifications@github.com wrote:

At this point there are a few simple options that would improve the situation:

increase I2C frequency by letting the user manually set TWI_CLOCK in Wire.h increase I2C frequency via including a modified version of Wire or another I2C lib. reduce the accessible part of the eeprom to reduce lookup time. keep a copy of the data in ram to read from. Writing to eeprom could either be implicitly done after each individual write or writing could be explicitly done with a new flush function. Please let me know in what direction you'd like this to go.

— Reply to this email directly or view it on GitHub.

remcoder commented 10 years ago

thx, I'll try to give it a go before the weekend is over.

billroy commented 10 years ago

Just remembered: Take a look in src/eeprom.c, where the fake eeprom is already integrated for the Due. You could include your initial load and writethrough in something similar to that.

-br

On Jan 11, 2014, at 9:24 AM, Remco Veldkamp notifications@github.com wrote:

thx, I'll try to give it a go before the weekend is over.

— Reply to this email directly or view it on GitHub.

remcoder commented 10 years ago

Between work and being a dad I finally I had/took some time to implement the cache ;-)

Since most time was spent in reading from the eeprom, the cache really speeds things up. (The count loop you wrote now takes 2.3s to go to 10.000 since it stays in ram). Saving a function also feels instant now.

billroy commented 10 years ago

Nice work. The speed is impressive.

remcoder commented 10 years ago

Cool ;-)