; I2C (TWI) master interface.
; This is part of the Z80-CP/M emulator written by Sprite_tm.
;
; Copyright (C) 2013 Leo C.
;
; This file is part of avrcpm.
;
; avrcpm is free software: you can redistribute it and/or modify it
; under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; avrcpm is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with avrcpm. If not, see .
;
; $Id$
;
#if I2C_SUPPORT
/* General TWI Master status codes */
#define TWI_START 0x08 /* START has been transmitted */
#define TWI_REP_START 0x10 /* Repeated START has been transmitted */
#define TWI_ARB_LOST 0x38 /* Arbitration lost */
/* TWI Master Transmitter status codes */
#define TWI_MTX_ADR_ACK 0x18 /* SLA+W has been transmitted and ACK received */
#define TWI_MTX_ADR_NACK 0x20 /* SLA+W has been transmitted and NACK received */
#define TWI_MTX_DATA_ACK 0x28 /* Data byte has been transmitted and ACK received */
#define TWI_MTX_DATA_NACK 0x30 /* Data byte has been transmitted and NACK received */
/* TWI Master Receiver status codes */
#define TWI_MRX_ADR_ACK 0x40 /* SLA+R has been transmitted and ACK received */
#define TWI_MRX_ADR_NACK 0x48 /* SLA+R has been transmitted and NACK received */
#define TWI_MRX_DATA_ACK 0x50 /* Data byte has been received and ACK transmitted */
#define TWI_MRX_DATA_NACK 0x58 /* Data byte has been received and NACK transmitted */
/* TWI Miscellaneous status codes */
#define TWI_NO_STATE 0xF8 /* No relevant state information available */
#define TWI_BUS_ERROR 0x00 /* Bus error due to an illegal START or STOP condition */
#define I2C_BR ((F_CPU / (2 * I2C_CLOCK)) - 8) /* I2C Bit Rate */
;----------------------------------------------------------------------
;
; TWINT: TWI Interrupt Flag
; TWEA: TWI Enable Acknowledge Bit
; TWSTA: TWI START Condition Bit
; TWSTO: TWI STOP Condition Bit
; TWEN: TWI Enable Bit
; TWIE: TWI Interrupt Enable
;
; (1<= 0 No error
; > 0 status tbd.
;
;----------------------------------------------------------------------
.dseg
i2c_var:
i2ci_idx:
.byte 1
i2c_result:
.byte 1
i2c_bufcnt:
.byte 1
i2c_buf:
.byte I2C_BUFSIZE
.equ oi2ci_idx = 0
.equ oi2c_result = 1
.equ oi2c_bufcnt = 2
.equ oi2c_buf = 3
;------------------------------------------------------------------
.cseg
INTERRUPT TWIaddr
push temp
in temp,sreg
push temp
push temp2
push zh
push zl
ldiw z,i2c_var
ldd temp2,z+oi2ci_idx
inm8 temp,TWSR
cpi temp,TWI_START
breq i2ci_START
cpi temp,TWI_REP_START
breq i2ci_REP_START
cpi temp,TWI_MTX_ADR_ACK
breq i2ci_MTX_ADR_ACK
cpi temp,TWI_MTX_DATA_ACK
breq i2ci_MTX_DATA_ACK
cpi temp,TWI_MRX_ADR_ACK
breq i2ci_MRX_ADR_ACK
cpi temp,TWI_MRX_DATA_ACK
breq i2ci_MRX_DATA_ACK
cpi temp,TWI_MRX_DATA_NACK
breq i2ci_MRX_DATA_NACK
rjmp i2ci_default
i2ci_START:
i2ci_REP_START:
clr temp2 ;reset buffer pointer
i2ci_MTX_ADR_ACK:
i2ci_MTX_DATA_ACK:
ldd temp,z+oi2c_bufcnt
cp temp2,temp ;all bytes tranmited?
brsh i2ci_12 ; yes
add zl,temp2
adc zh,_0
inc temp2
ldd temp,z+oi2c_buf ;next byte
outm8 TWDR,temp
ldi temp,(1<