;* --------------------------------------------------------------------------------------
;*  Copyright (C) 2004 Dallas Semiconductor Corporation, All Rights Reserved.
;* 
;*  Permission is hereby granted, free of charge, to any person obtaining a
;*  copy of this software and associated documentation files (the "Software"),
;*  to deal in the Software without restriction, including without limitation
;*  the rights to use, copy, modify, merge, publish, distribute, sublicense,
;*  and/or sell copies of the Software, and to permit persons to whom the
;*  Software is furnished to do so, subject to the following conditions:
;* 
;*  The above copyright notice and this permission notice shall be included
;*  in all copies or substantial portions of the Software.
;* 
;*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
;*  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;*  MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;*  IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
;*  OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
;*  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
;*  OTHER DEALINGS IN THE SOFTWARE.
;* 
;*  Except as contained in this notice, the name of Dallas Semiconductor
;*  shall not be used except as stated in the Dallas Semiconductor
;*  Branding Policy.
;*
;*  Module:        i2c
;*  Description:   I2C Library Routines
;*  Filename:      maxq2000_i2c.asm
;*  Date:          October 28, 2004
;*  Version:       1.00
;*
;*  Contains I2C library functions.  On the MAXQ2000, SW.6 and SW.7 must be ON
;*  to communicate with the AT24C32A I2C EEPROM.  Note that this code assumes
;*  16-bit accumulators.  Other than that, this code should be portable to any 
;*  MAXQ20 device.
;*
;* --------------------------------------------------------------------------------------
#include "maxQ2000.inc"

#define SCL_ON   M1[18].0   ; PD6.0
#define SDA_ON   M1[18].1   ; PD6.1
#define SCL      M1[2].0    ; PO6.0
#define SDA      M1[2].1    ; PO6.1
#define SDA_IN   M1[10].1   ; PI6.1

 .code
;********************************************************************
;*
;* Function:    I2C_Init
;*
;* Description: Initialize the I2C lines on the MAXQ2000 Evaluation 
;*              Kit.
;*
;* Input:       None
;*
;* Output:      None
;*
;* Destroys:    None
;*
;********************************************************************
I2C_Init::
   move    SCL, #1
   move    SDA, #1
   move    SCL_ON, #1
   move    SDA_ON, #1
   ret

;********************************************************************
;*
;* Function:    Pause
;*
;* Description: Performs a fixed pause for I2C communications.
;*
;* Input:       None
;*
;* Output:      None
;*
;* Destroys:    LC[0]
;*
;********************************************************************
Pause:
   move    LC[0], #1000
   djnz    LC[0], $
   ret   


;********************************************************************
;*
;* Function:    PauseWrite
;*
;* Description: Performs a fixed pause suitable for an I2C write
;*              delay.
;*
;* Input:       None
;*
;* Output:      None
;*
;* Destroys:    LC[0], LC[1]
;*
;********************************************************************
PauseWrite::
   move    LC[0], #1000
   move    LC[1], #100
PauseWrite_L1:
   djnz    LC[0], $
   djnz    LC[1], PauseWrite_L1
   ret   

;********************************************************************
;*
;* Function:    I2C_Start
;*
;* Description: Performs a START condition on the I2C bus.
;*
;* Input:       None
;*
;* Output:      None
;*
;* Destroys:    LC[0]
;*
;********************************************************************
I2C_Start::
   move    SCL, #1           ; Drive HIGH
   move    SDA, #1           ; Drive HIGH
   call    Pause
   move    SDA, #0           ; Drive LOW
   call    Pause
   move    SCL, #0           ; Drive LOW
   call    Pause
   ret

;********************************************************************
;*
;* Function:    I2C_Stop
;*
;* Description: Performs a STOP condition on the I2C bus.  Assumes 
;*              that SCL/SDA are LOW.
;*
;* Input:       None
;*
;* Output:      None
;*
;* Destroys:    LC[0]
;*
;********************************************************************
I2C_Stop::
   call    Pause
   move    SCL, #1           ; Drive HIGH
   call    Pause
   move    SDA, #1           ; Drive HIGH
   call    Pause
   ret


;********************************************************************
;*
;* Function:    I2C_TxBit
;*
;* Description: Transmits a 0/1 data bit on the I2C bus.  Assumes 
;*              that SCL/SDA are LOW.
;*
;* Input:       c - bit to output on the I2C bus
;*
;* Output:      None
;*
;* Destroys:    LC[0]
;*
;********************************************************************
I2C_TxBit::
   jump    C, I2C_TxBitHi
   move    SDA, #0           ; Drive LOW
   jump    I2C_TxBitClk
I2C_TxBitHi:
   move    SDA, #1           ; Drive HIGH
I2C_TxBitClk:
   call    Pause
   move    SCL, #1           ; Raise clock
   call    Pause
   move    SCL, #0           ; Lower clock
   call    Pause
   move    SDA, #0           ; Clear SDA to low
   call    Pause
   ret

;********************************************************************
;*
;* Function:    I2C_RxBit
;*
;* Description: Receives a data bit from the I2C bus.  Assumes that 
;*              SCL/SDA are LOW.
;*
;* Input:       None
;*
;* Output:      c - bit input from the I2C bus
;*
;* Destroys:    LC[0]
;*
;********************************************************************
I2C_RxBit::
   move    SDA_ON, #0        ; Release data line
   move    SDA, #1           ; Weak pullup
   call    Pause
   move    SCL, #1           ; Raise clock
   call    Pause
   move    C, SDA_IN         ; Get bit output from slave
   call    Pause
   move    SCL, #0           ; Lower clock
   call    Pause
   move    SDA, #0           ; Turn off weak pullup
   move    SDA_ON, #1        ; Drive LOW
   call    Pause
   ret

;********************************************************************
;*
;* Function:    I2C_TxByte
;*
;* Description: Transmits a 8-bit byte on the I2C bus.  Assumes that 
;*              SCL/SDA are LOW.
;*
;* Input:       ACC - byte to transmit on I2C
;*
;* Output:      c - bit input from the I2C bus
;*
;* Destroys:    LC[0], PSF
;*
;********************************************************************
I2C_TxByte::
   xch                       ; Move transmit byte to high byte
   rlc
   call    I2C_TxBit         ; Transmit bit 7
   rlc
   call    I2C_TxBit         ; Transmit bit 6
   rlc
   call    I2C_TxBit         ; Transmit bit 5
   rlc
   call    I2C_TxBit         ; Transmit bit 4
   rlc
   call    I2C_TxBit         ; Transmit bit 3
   rlc
   call    I2C_TxBit         ; Transmit bit 2
   rlc
   call    I2C_TxBit         ; Transmit bit 1
   rlc
   call    I2C_TxBit         ; Transmit bit 0
   ret

;********************************************************************
;*
;* Function:    I2C_RxByte
;*
;* Description: Receives an 8-bit byte from a slave on the I2C bus, 
;*              MSB first.
;*              
;* Input:       None
;*
;* Output:      ACC - bbyte received over I2C
;*
;* Destroys:    LC[0], PSF
;*
;********************************************************************
I2C_RxByte::
   move    Acc, #0000h       ; Clear accumulator
   call    I2C_RxBit         ; Receive bit 7
   rlc                       ; Shift bit into Acc
   call    I2C_RxBit         ; Receive bit 6
   rlc
   call    I2C_RxBit         ; Receive bit 5
   rlc
   call    I2C_RxBit         ; Receive bit 4
   rlc
   call    I2C_RxBit         ; Receive bit 3
   rlc
   call    I2C_RxBit         ; Receive bit 2
   rlc
   call    I2C_RxBit         ; Receive bit 1
   rlc
   call    I2C_RxBit         ; Receive bit 0
   rlc
   ret

end
