I2Cmaster.spin - correct I2C implementation
shimniok
Posts: 177
Wanted to share my I2Cmaster.spin in case it is of benefit to others using I2C. It's Spin/PASM and based off a couple other well known objects BUT it respects I2C open collector design and honors slave clock stretching (the reasons why this matter can be found within the object file). The source includes fairly extensive documentation about hardware, I2C protocol and such stuff, plus example code.
Another convenience, you specify any arbitrary SCL and SDA once at init time.
I'll post on obex with a nice description after I work out EEPROM support and do a bit more testing.
I've tested on LSM303DLH, HMC5843, L3G4200D -- example spin files are included in the zip -- and also my ATtiny-based Sharp Ranger I2C converter boards which was the motivation for writing this.
Thanks, all.
Michael
Another convenience, you specify any arbitrary SCL and SDA once at init time.
I'll post on obex with a nice description after I work out EEPROM support and do a bit more testing.
I've tested on LSM303DLH, HMC5843, L3G4200D -- example spin files are included in the zip -- and also my ATtiny-based Sharp Ranger I2C converter boards which was the motivation for writing this.
Thanks, all.
Michael
zip
10K
Comments
Also... you've got timing and _STACK parameters in your top objects and in your I2C child object. This could confuse newcomers. I try to keep that stuff in the top object. In fact, the manual says that _STACK is ignored if in a child object.
@Jeff - my pleasure
It's a bit minimalist, requiring the user to call the start method, format the device code and call the write method, acks... and as you note that keeps the Spin routine waiting around. I guess I'm a bit lazy and prefer for the I2C driver to handle it all internally while the Spin routine continues about its business. I do like the way you encode the success/fail along with any returned bytes, I might have to borrow that.
Not even a Start wiggle.
Chris's post explains it.
I like the minimalist approach, I can walk thru the datasheet step by step.
I am not against higher level also.
Tom
While I do like having full control over every step of the I2C transaction (mbed provides this option)... there's something to be said for higher level routines (Arduino, mbed). Will dig into that.
With your input I think we can make this thing quite a bit better.
I really appreciate the input, everyone.
I had a PASM object I worked on as well last year. It could get up to 400KHz. I left off at trying to make it multi-cog compatible with locks so that several cogs could be dedicated to their own device on a common I2C bus but that was all handled by SPIN code stringing together primitives and locking until the full transaction was complete. I did succumb to speed envy later and made some combinations in PASM that cut down the gaps induced by slow SPIN code execution between each primitive. Could get some really fast transactions that way.
Mine was a hack of someone else's driver. I'll have to check yours out. It has the possibility to be much cleaner.