\ 2006-07-09 EW \ speaking to i2c bus as master \ \ N O E R R O R C H E C KI N G \ W H A T S O E V E R ! \ \ expects: \ PinSDA PinSCL \ PortI2C PddrI2C \ \ provides: \ NB>i2c ( xN .. x1.msB N addr -- ) \ send N bytes to i2c device at addr \ \ NB<i2c ( N addr -- X1.msB .. xN ) \ read N bytes from i2c device at addr \ expects previously sent addr/controlbyte \ since REPEATED START condition is used : sda0 PinSDA PortI2C bclr ; : sda1 PinSDA PortI2C bset ; : scl0 PinSCL PortI2C bclr ; : scl1 PinSCL PortI2C bset ; \ get Bit Nr. i from Byte x : getBit ( x i -- b ) rshift 1 and ; : sdaInput ( -- ) PinSDA PddrI2C bclr ; : sdaOutput ( -- ) PinSDA PddrI2C bset ; : readSDA ( -- f ) PinSDA PortI2C btst IF 1 ELSE 0 ENDIF ; : i2c_tick 2 us ; : 2i2c_tick i2c_tick i2c_tick ; \ send START : i2c_start ( -- ) i2c_tick sda0 2i2c_tick scl0 i2c_tick ; \ send STOP : i2c_stop ( -- ) i2c_tick scl1 2i2c_tick sda1 i2c_tick ; \ send REPEATED START : i2c_rstart sda1 i2c_tick scl1 i2c_tick sda0 i2c_tick scl0 i2c_tick ; \ clock out 1 Bit : bit>i2c ( f -- ) IF sda1 ELSE sda0 ENDIF i2c_tick scl1 2i2c_tick scl0 i2c_tick ; \ send 1 Byte, 8 Bit, msb first : >i2c ( x -- ) 8 0 DO dup 8 I 1+ - getBit bit>i2c LOOP drop ; \ read 1 Byte, 8 Bit, msb first : <i2c ( -- x ) sdaInput 0 8 0 DO 1 lshift i2c_tick scl1 i2c_tick readSDA i2c_tick scl0 i2c_tick + LOOP sdaOutput ; \ read ACK|NACK from device : ack<i2c ( -- f ) sdaInput i2c_tick scl1 i2c_tick readSDA i2c_tick scl0 i2c_tick sdaOutput ; \ send n bytes from stack to device : NB>i2c ( x1 .. xN.msB N addr -- ) i2c_start >i2c ack<i2c drop \ send address 0 DO >i2c ack<i2c drop \ send next byte LOOP i2c_stop ; \ read n Bytes from device to stack, assume \ address and opt. controlbytes were sent : NB<i2c ( N addr -- xN.msB .. x1 ) i2c_rstart 1+ >i2c ack<i2c drop \ send addr 1- dup 0 > IF 0 DO \ loop N-1 times <i2c 0 bit>i2c \ read byte, send ACK LOOP ENDIF <i2c 1 bit>i2c \ read last byte, send NACK i2c_stop ;