This new module (I2CX.bas) is a software I2C master that adds support for clock-stretching, which is useful for those slaves that require it (the existing SI2C module drives the SCL in push-pull fashion so it's not 100% I2C compliant). It has a few new features such as an event callback to let you setup IO pins (digital mode, slew rate, pullups, etc).
Here's an example... it's very similar to the existing modules
Code: Select all
program I2CX_example
device = 18F26Q71
clock = 64
include "intosc.bas"
#option I2CX_SCL = PORTC.3 // SCL
#option I2CX_SDA = PORTC.4 // SDA
#option I2CX_BAUD = 400 // 400KHz
#option I2CX_INIT_EVENT = true // use init event for IO pin setup
include "I2CX.bas"
// setup 18FxxQ71 pins used for I2C (called by I2CX.Open/Initialize)
// most devices have weak pullups (WPU)
// _xv18 devices have addtl RxyI2C PAD controls for certain pins
#option WPU = true
event IOinit()
// RxyI2C PAD control present in _xv18 devices
// [SLEW1] [SLEW0] [PU1] [PU0] [--] [--] [TH1] [TH0]
'const RXYI2C = (%11<<6) + (%10<<4) + %10 // slew=fast mode, pu=10x, th=SMBUS2.0
const RXYI2C = 0 // set default to not used
// set IO pin modes
#if (I2CX_SCL = PORTC) and (I2CX_SCL@ = 3) // check for PORTC.3
ANSELC.bits(3) = 0 // 0=digital, 1=analog mode
SLRCONC.bits(3) = 0 // 0=max rate, 1=limited slewrate (RxyI2C SLEW=00)
INLVLC.bits(3) = 0 // 0=TTL, 1=ST (RxyI2C TH=00)
#if (WPU)
WPUC.bits(3) = 1 // enable weak pullup (if supported and RxyI2C PU=00)
#endif
RC3I2C = RXYI2C
#endif
#if (I2CX_SDA = PORTC) and (I2CX_SDA@ = 4) // check for PORTC.4
ANSELC.bits(4) = 0 // 0=digital, 1=analog mode
SLRCONC.bits(4) = 0 // 0=max rate, 1=limited slewrate (RxyI2C SLEW=00)
INLVLC.bits(4) = 0 // 0=TTL, 1=ST (RxyI2C TH=00)
#if (WPU)
WPUC.bits(4) = 1 // enable weak pullup (if supported and RxyI2C PU=00)
#endif
RC4I2C = RXYI2C
#endif
end event
dim st as boolean
dim b as byte
// initialize I2C using the IOinit event to setup pins
I2CX.open(IOinit) // requires 'I2CX_INIT_EVENT = true'
// check if bus ok
st = I2CX.CheckBus()
// see if slave device addr $02 responds (ACK/NACK)
st = I2CX.IsPresent($02)
// write $55 to addr $02
I2CX.Start()
I2CX.WriteByte($02)
I2CX.WriteByte($55)
I2CX.Stop()
// read two bytes from addr $02
I2CX.Start()
I2CX.WriteByte($02)
I2CX.Restart()
b = I2CX.ReadByte(I2C_ACK)
b = I2CX.ReadByte(I2C_NACK)
I2CX.Stop()
I2CX.Close()
end program