;; I²C Protocol Routines. .module I2C .enum LineMasks None = %00000000, Sda = %00010000, Scl = %00100000 ;; === SdaSclHigh === ;; Releases both SDA and SCL lines. ;; Post: ;; Both SDA and SCL are released and will float high unless held low by ;; another I²C device. ;; ;; All registers are preserved. SdaSclHigh push af push de ld de,LineMasks.None jr ChangeBusLine ;; === SdaLow === ;; Pulls the SDA line low. ;; Post: ;; The SDA line on the I²C-bus is held low. ;; ;; All registers are preserved. SdaLow push af push de ld de,(LineMasks.None|LineMasks.Sda) + (LineMasks.Scl<<8) jr ChangeBusLine ;; === SdaHigh === ;; Releases the SDA line. ;; Post: ;; The SDA line on the I²C-bus is released and floats high unless held ;; low by another I²C device. ;; ;; All registers are preserved. SdaHigh push af push de ld de,(LineMasks.None) + (LineMasks.Scl<<8) jr ChangeBusLine ;; === SclLow === ;; Pulls the SCL line low. ;; Post: ;; The SCL line on the I²C-bus is held low. ;; ;; All registers are preserved. SclLow push af push de ld de,(LineMasks.None|LineMasks.Scl) + (LineMasks.Sda<<8) jr ChangeBusLine ;; === SclHigh === ;; Releases the SCL line. ;; Post: ;; The SCL line on the I²C-bus is released and floats high unless held ;; low by another I²C device. ;; ;; All registers are preserved. SclHigh push af push de ld de,(LineMasks.None) + (LineMasks.Sda<<8) ; Pre: ; af and de pushed to stack (in that order). ; d = bus line mask to ignore. ; e = data to output to link port. ; Post: ; The link port status is modified to hold low or release the I²C bus data ; lines. This routine also provides the short delay required by slow I²C ; devices. ChangeBusLine ld a,(State.IO) and d or e ld (State.IO),a out (Ports.IO),a pop de pop af ret ;; === WriteStart === ;; Writes a start condition to the I²C-bus. ;; Post: ;; All registers are preserved. WriteStart call SdaLow call SclLow ret ;; === WriteStop === ;; Writes a stop condition to the I²C-bus. ;; Post: ;; All registers are preserved. WriteStop call SclHigh call SdaHigh ret ;; === WriteAcknowledge === ;; Writes an acknowledgement to the currently address device. ;; Post: ;; All registers are preserved. WriteAcknowledge call SdaLow call SclHigh call SclLow call SdaHigh ret ;; === WriteBit === ;; Writes a single data bit to the I²C-bus. ;; Pre: ;; Carry = bit to send (set for a 1, reset for a 0). ;; Post: ;; All registers are preserved. WriteBit jr c,BitHigh BitLow call SdaLow jr + BitHigh call SdaHigh + call SclHigh call SclLow call SdaLow ret ;; === WriteByte === ;; Writes a byte to the I²C-bus. ;; Pre: ;; A = byte to send. ;; Post: ;; All registers are preserved. WriteByte push af push bc ld b,8 - rlca call WriteBit djnz - pop bc pop af ret ;; === WriteAndAcknowledge === ;; Writes a byte to the I²C-bus and reads an acknowledgement. ;; Pre: ;; A = byte to send. ;; Post: ;; Carry = set if acknowledgement received, reset otherwise. ;; Other flags are undefined. WriteAndAcknowledge call WriteByte ;; === ReadAcknowledge === ;; Reads an acknowledgement from the I²C-bus. ;; Post: ;; Carry = set on error. ;; Other flags are undefined. ReadAcknowledge push bc ld c,a call SdaHigh call SclHigh ld b,0 - call ReadBit jr nc,GotAcknowledge djnz - GotAcknowledge call SclLow call SdaLow ld a,c pop bc ret ;; === ReadBit === ;; Reads a single bit from the I²C-bus. ;; Post: ;; Carry = set if bit was 1, reset if bit was 0. ;; A is destroyed and other flags are undefined. ReadBit call SdaSclHigh in a,(Ports.IO) and LineMasks.Sda jp z,SclLow scf jp SclLow ;; === ReadByte === ;; Reads a byte from the I²C-bus. ;; Post: ;; A = byte read from bus. ;; All other registers are preserved. ReadByte push bc push af ld b,8 - call ReadBit rl c djnz - pop af ld a,c pop bc ret .for width = 8 to 16 step 8 ;; === WriteData8 === ;; Writes a block of data to an I²C-bus device that uses 8-bit addressing. ;; Pre: ;; B = Amount of data to write. ;; C = Address of device on I²C bus. ;; E = Address to write data to on device. ;; HL = Pointer to data to write. ;; Post: ;; Carry = set if transfer failed, reset if successful. ;; All other flags are undefined; A is destroyed .if width == 8 WriteData8 .elseif width == 16 WriteData16 .endif call WriteStart ; Device address: ld a,c and %11111110 ; Clear the LSB for writes. call WriteAndAcknowledge jr c,StopWriteData ; Register address: .if width == 16 ld a,d call WriteAndAcknowledge jr c,StopWriteData .endif ld a,e call WriteAndAcknowledge jr c,StopWriteData - ld a,(hl) inc hl call WriteAndAcknowledge jr c,StopWriteData inc de djnz - or a jr StopWriteData .loop StopWriteData call WriteStop ret ;; === ReadData8 === ;; Reads a block of data from an I²C-bus device that uses 8-bit addressing. ;; Pre: ;; B = Amount of data to read. ;; C = Address of device on I²C bus. ;; E = Address to read data from on device. ;; HL = Pointer to location to store received data. ;; Post: ;; Carry = set on error. ;; All other flags are undefined; A is .for width = 8 to 16 step 8 .if width == 8 ReadData8 .elseif width == 16 ReadData16 .endif call WriteStart ; Device address: ld a,c and %11111110 ; Clear the LSB for writes. call WriteAndAcknowledge jr c,StopReadData ; Register address: .if width == 16 ld a,d call WriteAndAcknowledge jr c,StopWriteData .endif ld a,e call WriteAndAcknowledge jr c,StopWriteData call WriteStop call WriteStart ; Device address: ld a,c or %00000001 ; Set the LSB for reads. call WriteAndAcknowledge jr c,StopReadData - call ReadByte inc de ld (hl),a inc hl ld a,b cp 1 call nz,WriteAcknowledge djnz - or a jr StopReadData .loop StopReadData call SclLow call SdaLow call WriteStop ret ReadWord16 call WriteStart ; Device address: ld a,c and %11111110 ; Clear the LSB for writes. call WriteAndAcknowledge jp c,StopReadData ; Register address: ld a,d call WriteAndAcknowledge jp c,StopReadData ld a,e call WriteAndAcknowledge jp c,StopReadData call WriteStop call WriteStart ; Device address: ld a,c or %00000001 ; Set the LSB for reads. call WriteAndAcknowledge jp c,StopReadData call ReadByte jr c,StopReadData ld l,a call WriteAcknowledge call ReadByte jp c,StopReadData ld h,a or a jr StopReadData .endmodule ; =================== ; End of file ; ===================