Forth i2c words

Given some words for handling the i2c lines:

>SDA    ( f -- )    write f to the SDA line
SDA>    ( -- f )    read the state of the SDA line
SCL-0   ( -- )      drive SCL low
SCL-1   ( -- )      drive SCL high
half    ( -- )      half-cycle delay

In the best Forth tradition, one screen is enough:

( i2c                                        JCB 10:09 08/15/10)
: i2c-start     \ with SCL high, change SDA from 1 to 0
    1 >SDA half SCL-1 half 0 >SDA half SCL-0 ;
: i2c-stop      \ with SCL high, change SDA from 0 to 1
    0 >SDA half SCL-1 half 1 >SDA half ;

: i2c-rx-bit ( -- b )
    1 >SDA half SCL-1 half SDA> SCL-0 ;
: i2c-tx-bit ( f -- )
    0<> >SDA half SCL-1 half SCL-0 ;

: i2c-tx    ( b -- nak )
    8 0 do dup 128 and i2c-tx-bit 2* loop drop i2c-rx-bit ;

: i2c-rx    ( nak -- b )
    0 8 0 do 2* i2c-rx-bit + loop swap i2c-tx-bit ;

And sample use for some 8-bit device at address 40:

( i2c example usage for 8-bit device         JCB 10:09 08/15/10)

: device ( addr -- ) \ common i2c preamble
    i2c-start 40 i2c-tx throw i2c-tx throw ;

: device! ( v addr -- ) \ write v to i2c register addr
    device i2c-tx throw i2c-stop ;

: device@ ( addr -- v ) \ read i2c register addr
    device i2c-start 41 i2c-tx throw 1 i2c-rx i2c-stop ;

This code is used in the WGE100 Ethernet cameras. The source code is in i2c.fs.