'--------------------------------------------------------------------------------------------
' BasicX I2C subroutines  
' A great deal of this code was created and posted to the basicx yahoo group
' If someone recognizes some of this code email me and i will credit you
' Email me with suggestions, questions and improvement : damon@homepagesetc.com
' This code was tested only with an MD05 Motor controller
' Check manufactures i2c implementation as they can differ
'
'Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte)
'Sends a byte (I2cData) out to a register (I2cReg) and address (I2cAddr) via i2c
'
'Function I2CByteRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As Byte
'Reads a byte (function return) from register (I2cReg) and Address (I2cAddr) via i2c
'
'Function I2CWordRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As UnsignedInteger
'Reads a word or 2 bytes (function return) from register (I2cReg) and Address (I2cAddr) via i2c
'
'Sub I2cOutByte(I2cData As Byte)
'Actual byte send routine
'
'Function I2cInByte() As Byte
'Actual byte read routine
'
'Sub I2cStart()
'I2C start bit sequence
'
'Sub I2cStop()
'I2C stop bit sequence

'--------------------------------------------------------------------------------------------
Option Explicit
Dim I2cAck As Boolean                            ' Acknowledge flag
Const SCL As Byte = 5                           ' I2C clock - choose any pins you wish for SCL and SDA
Const SDA As Byte = 6                           ' I2C data

Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte)
    Call I2cStart()
    Call I2cOutByte(I2cAddr)                  ' send device address
    Call I2cOutByte(I2cReg)                   ' send register address
    Call I2cOutByte(I2cData)                  ' send the data
    Call I2cStop()
End Sub

Function I2CByteRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As Byte
    Call I2cStart()
    Call I2cOutByte(I2cAddr)                  ' send device address
    Call I2cOutByte(I2cReg)                   ' send register address
    Call I2cStart()                           ' repeated start
    I2cAddr = I2cAddr+1
    Call I2cOutByte(I2cAddr)                  ' send device address with read set
    I2cAck = False                            ' setup to send Nak
    I2cByteRead = I2cInByte()                 ' get data byte with Nak
    Call I2cStop()
End Function

Function I2CWordRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As UnsignedInteger
    Set I2CWordRead = New UnsignedInteger
    Call I2cStart()
    Call I2cOutByte(I2cAddr)                  ' send device address
    Call I2cOutByte(I2cReg)                   ' send register address
    Call I2cStart()                           ' repeated start
    I2cAddr = I2cAddr+1
    Call I2cOutByte(I2cAddr)                  ' send device address with read set
    I2cAck = True                             ' setup to send Ack
    I2cWordRead = CuInt(I2cInByte()*256)
    I2cAck = False                            ' setup to send Nak
    I2cWordRead = I2cWordRead + CuInt(I2cInByte())
    Call I2cStop()
End Function

Sub I2cOutByte(I2cData As Byte)
    Call ShiftOut(SDA, SCL, 8, I2cData)       ' shift data out
    Call PutPin(SDA, bxInputTristate)         ' turn SDA around
    Call PutPin(SCL, bxOutputHigh)            ' and clock in the ack' bit
    Call PutPin(SCL, bxOutputLow)
End Sub

Function I2cInByte() As Byte
    I2cInByte = ShiftIn(SDA, SCL, 8)
    If I2cAck=True Then
        Call PutPin(SDA, bxOutputLow)
    Else
        Call PutPin(SDA, bxOutputHigh)
    End If
    Call PutPin(SCL, bxOutputHigh)            ' clock out the ack' bit
    Call PutPin(SCL, bxOutputLow)
End Function

Sub I2cStart()                                ' I2C start bit sequence
    Call PutPin(SDA, bxOutputHigh)
    Call PutPin(SCL, bxOutputHigh)
    Call PutPin(SDA, bxOutputLow)
    Call PutPin(SCL, bxOutputLow)
End Sub

Sub I2cStop()                                 ' I2C stop bit sequence
    Call PutPin(SDA, bxOutputLow)
    Call PutPin(SCL, bxOutputHigh)
    Call PutPin(SDA, bxOutputHigh)
End Sub

 
