section ".data" include "OS.H" xdef i2clib@0000 xdef i2clib@0001 xdef i2clib@0002 xdef i2clib@0003 xdef i2clib@0004 xdef i2clib@0005 ;**************************************************** ;* SDA is mapped to bit 1 and SCL to bit 0 * ;* D1 and D2 are volatile, D0 is parameter * ;**************************************************** ;**************************************************** ; Macro definitions Rel_SDA MACRO bclr.b #1,$60000E ENDM Rel_SCL MACRO bclr.b #0,$60000E ENDM Pull_SDA MACRO bset.b #1,$60000E ENDM Pull_SCL MACRO bset.b #0,$60000E ENDM Get_SDA MACRO move.b $60000E,D2 not D2 btst.b #3,D2 ENDM Get_SCL MACRO ; Not used move.b $60000E,D2 not D2 btst.b #2,D2 ENDM Wait_2us: ; Small delay ; move.w #1,D2 ; I think these loops aren't needed : the ; bra loopw5us ; tests i made with rts only showed a speed of Wait_5us: ; ~45kbps, while the specifications are 100kbps max. ; move.w #2,D2 ; the delay should be around 5µs between the ; edges of the SCL signal. loopw5us: ; for more info about timing, see i2clib.txt ; dbra D2,loopw5us rts ;***************************************************** ; Generate a START condition i2clib@0000: Start: ; move.w #$700,D0 ; Disable (maskable) interrupts ; trap #1 ; Beware if you use keyboard or auto-ints (used for greyscale)! bclr.b #6,$60000E ; Enable direct link port access move.w $60000C,D0 ; (dunno exactly what these bits are for, but move.b #$E0,$60000C ; strange things happen if they're not set ...) Rel_SDA ; Start condition definition : Rel_SCL bsr Wait_5us ; __ ; SDA : \__ Pull_SDA ; _____ bsr Wait_5us ; SCL : Pull_SCL bsr Wait_5us rts ;***************************************************** ; Generate a STOP condition i2clib@0001: Stop: Pull_SDA ; Stop condition definition : Rel_SCL bsr Wait_5us ; __ ; SDA : __/ Rel_SDA ; _____ bsr Wait_5us ; SCL : bset.b #6,$60000E ; Disable direct link access jsr OSLinkReset ; To be sure everything's in order ; move.w #0,D0 ; Enable interrupts ; trap #1 rts ;***************************************************** ; Send ADRESS or DATA Byte i2clib@0002: Adress: i2clib@0003: Send_byte: move.w #7,D1 ; MSB first loopsd: btst.b D1,D0 beq sd0 Rel_SDA bra sd1 sd0: Pull_SDA sd1: bsr Wait_2us Rel_SCL bsr Wait_5us Pull_SCL bsr Wait_2us dbra D1,loopsd Rel_SDA ; Get the Acknowledge bit bsr Wait_2us Rel_SCL bsr Wait_2us Get_SDA bne sdak0 move.l #1,D0 ; D0=1 : Ack not set (byte not received) bra sdak1 sdak0: move.l #0,D0 ; D0=0 : Ack Set (OK) sdak1: bsr Wait_2us Pull_SCL ; Pull_SDA bsr Wait_2us rts ;***************************************************** ; Get DATA Byte and acknowledge i2clib@0004: Get_byte_a: bsr Get_b Pull_SDA ; Send an Acknowledge bit bsr Wait_2us Rel_SCL bsr Wait_5us Pull_SCL bsr Wait_2us Rel_SDA rts ;***************************************************** ; Get DATA Byte and do not acknowledge i2clib@0005: Get_byte_na: bsr Get_b Rel_SDA ; Send a Not Acknowledge bit bsr Wait_2us Rel_SCL bsr Wait_5us Pull_SCL bsr Wait_2us rts ;***************************************************** ; Get byte subroutine Get_b: clr.l D0 move.w #7,D1 ; MSB first loopgt: bsr Wait_2us Rel_SCL bsr Wait_2us Get_SDA beq gt0 bset.b D1,D0 gt0: bsr Wait_2us Pull_SCL bsr Wait_2us dbra D1,loopgt rts ;***************************************************** end