Cliff Hacks Things.

Thursday, December 27, 2007

PropellerForth I2C EEPROM driver

This afternoon, I curled up with the datasheets for Atmel's I2C EEPROMs, like the one the Propeller uses to boot. I haven't written any I2C code in a while, so I had to relearn the protocol.

Then, I went out for phở. The place down the street is quite tolerant of me sitting for half an hour drawing state diagrams.

Noodles completed, I set to work interfacing PropellerForth to the boot EEPROM. It's been a resounding success. The sources are below; they should work on the old 20061124 image, if anyone still has a copy. Otherwise, they'll work on the 20080101 image once I make it available.

Executive summary: these words implement a hardcoded interface to an EEPROM on pins 29:28. This lets you access data stored in EEPROM (using ee@ and ee!). For the first time, you can save a bootable image of your current PropellerForth system to EEPROM, using the saveforth word.

The emphasis there shows how excited I am about this. Bootstrapping my NTSC display driver requires me to carefully type in Forth code for several minutes, each time I reboot! The words are factored so I can test as I go, but it's still painful. This is about as revolutionary as when I got cassette storage working with my TRS-80 Model 100 and no longer had to type in BASIC listings.

The interface is not spectacularly fast; page reads can stream data at about 20kbps, and page writes aren't implemented yet. saveforth can take a minute or two. It is, however, pretty simple and readable, assuming you read Forth.

If you don't read Forth, it's worth taking a glance at the code anyway. It's not the best Forth code -- I'm rusty -- but casual observers may notice that code toward the top of the listing tends to be low-level (written in terms of machine registers like OUTA). As you progress through the listing, the language changes: first to a physical-level description of I2C, then to a layer-2 description of how to talk to the EEPROM. In my day job we refer to this as a domain-specific language. Forth programmers didn't coin this term, because they didn't need one: it's the natural way to build systems in Forth.

So: the code! I've hand-escaped this, and may have introduced errors in the process.

Update: sneaky bug fixed by addition of mkboot word. Details below the source listing for anyone who doesn't want to figure it out for themselves. :-)


hex \ my dad will surely rib me for not using octal

\ Sets the value of an output pin (identified by 'mask').
\ Output is 0 if 'f' is false, 1 otherwise.
: pin! ( f mask -- )
swap if
OUTA L@ or
else
OUTA L@ swap -and
then OUTA L! ;

\ Sets a pin (identified by 'mask') to output.
: pin> ( mask -- )
DIRA L@ or DIRA L! ;

\ Sets a pin (identified by 'mask') to input.
: <pin ( mask -- )
dira L@ -and dira L! ;

\ I2C pin masks. Workaround for CONSTANT bug (CONSTANTs are 16-bit).
: eesdamask 20000000 ; \ pin 29
: eesclmask 10000000 ; \ pin 28

\ Words for working with the EEPROM SDA line.
: eesda! ( f -- ) eesdamask pin! ;
: eesda@ ( -- f ) INA L@ eesdamask and ;
: eesda> eesdamask pin> ;
: <eesda eesdamask <pin ;

\ Words for working with the EEPROM SCL line.
: eescl! ( f -- ) eesclmask pin! ;
: eescl> eesclmask pin> ;
: <eescl eesclmask <pin ;

\ Initializes the bus; useful for resetting a b0rked chip
: eeinit
\ SCL high/output, SDA input
1 eescl! eescl> <eesda

\ Drain the device until we get an ACK, or we try 9 times
9 0 do
0 eescl! 1 eescl!
eesda@ if unloop exit then
loop ;

\ I2C start condition
: eestart
1 eescl! eescl>
1 eesda! eesda> 0 eesda!
0 eescl! ;

\ I2C stop condition
: eestop
1 eescl!
1 eesda!
<eescl
<eesda ;

: eerxbit ( -- bit ) 1 eescl! eesda@ 0 eescl! ;

\ Transmits a byte, MSB first. Returns ack bit.
: eetx ( byte -- ackbit )
8 0 do
dup 80 and eesda!
1 lshift
1 eescl! 0 eescl!
loop drop
\ Read ack bit
<eesda eerxbit
0 eesda! eesda> ;

\ Receives 8 bits, sending 'ackbit' in response
: eerx ( ackbit -- byte )
<eesda
0 8 0 do
1 lshift
eerxbit if 1 or then
loop
swap eesda! eesda>
1 eescl! 0 eescl! ;

\ Like eetx, but throws file error if not acked.
: eetx? ( byte -- )
eetx if -25 throw then ;

\ Sends a two-byte big-endian address.
: eetxaddr? ( addr -- )
dup 8 rshift FF and eetx?
FF and eetx? ;

\ Reads a byte out of EEPROM. Throws on failure.
\ If you're feeling cryptic you could rename this
\ eec@.
: eeread ( addr -- byte )
eestart A0 eetx? eetxaddr?
eestart A1 eetx? 1 eerx
eestop ;

\ Writes a byte to EEPROM. Throws on failure.
: eewrite ( byte addr -- )
eestart A0 eetx? eetxaddr? eetx? eestop ;

\ Reads a little-endian 32-bit integer from EEPROM.
\ Throws on failure.
\ Eventually this should use page read.
: ee@ ( addr -- x )
0 4 0 do
8 rshift
over eeread 18 ( hex ) lshift or
swap 1+ swap
loop nip ;

\ Waits for the EEPROM to become available. Required
\ after a write operation unless you're damn sure you're
\ going to be busy for a while.
: eewait begin eestart A0 eetx eestop 0= until ;

\ Writes a little-endian 32-bit integer into EEPROM.
\ Throws on failure.
: ee! ( x addr -- )
4 0 do
2dup eewrite
1+ swap 8 rshift swap
eewait
loop 2drop ;

\ Reads 'count' bytes from the EEPROM starting at 'addr'
\ into a buffer at 'dest'.
: eereadpage ( dest count addr -- )
over 0= if drop drop drop exit then
eestart A0 eetx? eetxaddr?
eestart A1 eetx?
( count ) 1- 0 do
0 eerx over c!
1+
loop
1 eerx swap c!
eestop ;

\ Updates fields in the image preamble to allow
\ us to boot properly.
: mkboot
here 08 H!
here 08 + 0A H!
here 0C + 0E H!
here 10 - 10 H! ;

\ The word that made my evening: saves the
\ current dictionary, kernel, and bootloader
\ as a bootable image in EEPROM. Takes a
\ while, but prints cute little status updates.
\ The resulting image will boot to the interpreter
\ running the standard startup vector.
\
\ CAVEAT HACKER: this will erase whatever's in
\ EEPROM, in case that wasn't apparent.
: saveforth
." Saving 0 to " here aligned . cr
mkboot
here aligned 0 do
i @ i ee!
i FF and 0= if
." ..." i . cr
then
4 +loop
." Done." ;


Update about mkboot: the original listing I posted contained a subtle bug. When booting the saved EEPROM image, 12 bytes in the middle of your first user-added colon definition were destroyed. I didn't notice this because my first def was some test word that I didn't use after boot.

As described in my article on reverse-engineering the Propeller's image format, the SPIN interpreter needs some RAM to start. My image preamble (as used in propasm, and by extension PropellerForth) uses 12 bytes of RAM for the initial SPIN stack before the machine code is loaded.

The preamble tells SPIN where to put its stack; propasm indicates that it should go right after the end of the code. But if you've added code at runtime and saved Forth, the preamble needs to be updated -- otherwise SPIN will clobber an area just past the end of the original image, which is probably in the middle of a definition.

So, mkboot updates the preamble.

Labels:

17 Comments:

  • Very informative and very thorough at reading. You can identify all the quality spots here and we thank you for this.asian girl

    By Blogger chinese girl, at 10:31 PM  

  • The learning lab is providing the best Maths and English Tutor Sydney and if you are looking for maths tutor for your child contact us now!

    By Blogger steve7876, at 9:00 AM  

  • Females just love doing everything to enhance their personality and elegance. Looking glamorous and elegant in each and every season for every occasion is significant for her. Choosing correct type of hairstyle is as important as getting a unique dress, stunning shoes and constitute.. For new in addition to latest hairstyles visit this excellent website half up half down hairstyles

    By Blogger steve7876, at 9:01 AM  

  • bettys beauty blog has been selling the Best anti aging cream online and Betty has tested all the products on herself. Find out how Bettys has improved her skin and wrinkles on her face!

    By Blogger steve7876, at 1:23 AM  

  • Supplements can help your dreams of having your own product come alive. Intermountain Weight Loss Supplements offers a wide variety of custom formulation services including liquids, capsules, sprays, powders, and more.

    By Blogger steve7876, at 2:39 AM  

  • Supplements can help your dreams of having your own product come alive Private Label Manufacturing. Intermountain Supplements offers a wide variety of custom formulation services including liquids, capsules, sprays, powders, and more.

    By Blogger steve7876, at 4:26 AM  

  • i have read your all the content and i think you should be don more hard work. This type of coding not be easy. In future it is better for you.During the reading your article i found this site soclean2 it provides us good services.
    Thanks

    By Blogger mathscoursesydney, at 2:20 AM  

  • True Healing Self Healing has an extraordinary proprietary formula featuring the richest source of 100% bio-available Humic Fulvic Acid along with micro and marco mineral nutrients. This highly refined product consists of tiny, extremely complex molecules. The unique nanotechnology used in this formula sets it apart from any other product claiming to be similar in nature. It has a pH level of 7.4 to 8.0. Fulvic Acid is an incredible delivery system and is the element that makes nutrients absorbable. It charges, regenerates, regulates, and delivers its energies to living cells. A single Fulvic molecule can individually carry up to 60 different vital activated minerals nutrients to our cells. Simply put if there was one supplement to take then this will be it.
    the truth inhealing

    By Blogger shahbaz, at 4:55 AM  

  • Once in Los Angeles he studied beneath the fabulous Stella Adler plus mood mime Jeff Corey. Hellos initial acting vacancy was active beside Steven Spielberg as the Pizza Human in E.T. Stretch in LA he continued to thing on TV moreover Movie.oven repairs perth

    By Blogger shahbaz, at 1:53 AM  

  • Thanks for this well-written article that helps me a lot! I am grateful to read this I will follow your blog from now on.Mini-size CWDM Module

    By Blogger shahbaz, at 11:19 PM  

  • Several of my classmates voiced their distresss that their monograph closet were calamitous roster oriented comrades, I guileless smiled separate it did minus happened between my ideal coincident you. Instantly I am convinced that there are treatise agencies who gave assures of pardon they can't truckle up. It's exceedingly beginner.tx ecommerce

    By Blogger shahbaz, at 4:45 AM  

  • I find this interesting, thanks for sharing this wonderful idea, I'll try that pressure washers while using my.Fancy Dress

    By Blogger shahbaz, at 4:07 AM  

  • I have read your blog its very attractive and impressive. I like it your blog.

    Java Online Training Java EE Online Training Java EE Online Training Java 8 online training Core Java 8 online training

    Java Online Training from India Java Online Training from India Core Java Training Online Core Java Training Online Java Training InstitutesJava Training Institutes

    By Blogger Naviya Nair, at 9:29 PM  

  • Some may not want to cover the corks with papers or photos, instead using the board as an art piece.ios icon pack

    By Blogger shahbaz, at 9:37 AM  

  • This is the best way to share the great article with everyone one, so that everyone can able to utilize this information.guinea fowl feathers

    By Blogger shahbaz, at 1:10 AM  

  • I just don't understand how can you think so deep in this matter..? Well, now I know why you are called 'The Masters'. Thumbs up!i need to refinance my home with bad credit

    By Blogger shahbaz, at 11:06 PM  

  • Much gratitude to you for not floating perpetually just to fill the page. An obligation of appreciation is all together for sharing the information, continue doing wonderful.get t shirts printed

    By Blogger shahbaz, at 4:14 AM  

Post a Comment

<< Home