I2CX - software I2C master

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
Jerry Messina
Swordfish Developer
Posts: 1487
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

I2CX - software I2C master

Post by Jerry Messina » Thu Feb 23, 2023 4:04 pm

Many new devices no longer have an MSSP I2C peripheral (including the xv18 core devices), and the I2C peripheral in those devices is not compatible with the hdw I2C/I2C2 modules.

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
I2CX will be included in the next update.
Attachments
I2CX.zip
(4.49 KiB) Downloaded 267 times

Post Reply