\ 2006-07-31 SMBus.fs --- SMBus Basiscode \ i2c Bus am R8C \ P1.0 -- SCL \ P1.1 -- SDA \ Konstanten 0 Constant PinSCL 1 Constant PinSDA port1 Constant PortI2C $E3 Constant PddrI2C \ SDA,SCL Pins auf 0 oder 1 setzen : sda0 PinSDA PortI2C bclr ; : sda1 PinSDA PortI2C bset ; : scl0 PinSCL PortI2C bclr ; : scl1 PinSCL PortI2C bset ; \ 1 SCL Zyklus sind im Programm 4 ticks : tick 1 us ; : 2tick tick tick ; \ sende 1 Bit : bit>i2c ( bit -- ) IF sda1 ELSE sda0 ENDIF tick scl1 2tick scl0 tick ; \ erzeuge Bit Nr. i aus Byte x als 0 oder 1 : getBit ( x i -- b ) rshift $01 and ; \ sende 1 Byte, (8 Bit) "most significant bit" zuerst : >i2c ( x -- ) 8 0 DO dup 8 I 1+ - getBit bit>i2c LOOP drop ; \ sende START, STOP, REPEATED_START : i2c_start ( -- ) tick sda0 2tick scl0 tick ; : i2c_stop ( -- ) tick scl1 2tick sda1 tick ; : i2c_rstart sda1 tick scl1 tick sda0 tick scl0 tick ; \ setze SDA zum Lesen / Senden : sdaInput ( -- ) PinSDA PddrI2C bclr ; : sdaOutput ( -- ) PinSDA PddrI2C bset ; \ lies SDA : readSDA ( -- f ) PinSDA PortI2C btst IF 1 ELSE 0 ENDIF ; \ lies 1 Byte (8 Bit), "most significant bit" zuerst : i2c ( x1 .. xN.msB N addr -- ) i2c_start \ START >i2c acki2c acki2c ack IF \ Schleife ueber N-1 Byte 0 DO \ Datenbyte = 0 (initialisieren) i2c \ DATA_BYTE lesen, ACK schicken LOOP \ Ende Schleife ENDIF \ i2c \ letzes Byte lesen, NACK schicken i2c_stop \ STOP ;