; ** Find Devices on I2C Bus IDENTIFY-003 Revised by AllyCat April 20 **
#define picaxe20 ; Choose from 08,14,18 or 20 pin chips. Check PWR/GND pin outputs if used
#no_data
#terminal 4800
#ifdef picaxe08
#picaxe 08m2
#define ok
Symbol SCL = C.1 : Symbol pinSCL = pinC.1 ; Leg 6
Symbol SDA = C.2 : Symbol pinSDA = pinC.2 ; Leg 5
;Symbol PWR = C.4 ; Leg 3
;Symbol GND = C.0 ; Leg 7 (SerOut defaults to GND)
Symbol MINVOLTS = 240 ; Tens of mV (for 08M2)
#endif
#ifdef Picaxe14
#Picaxe 14M2
#define ok
Symbol SCL = B.3 : Symbol pinSCL = pinB.7 ; Leg 10
Symbol SDA = B.4 : Symbol pinSDA = pinB.5 ; Leg 9
;Symbol PWR = B.5 ; Leg 8
;Symbol GND = B.2 ; Leg 11
Symbol MINVOLTS = 190
#endif
#ifdef Picaxe18
#Picaxe 18M2
#define ok
Symbol SCL = B.4 : Symbol pinSCL = pinB.4 ; Leg 10
Symbol SDA = B.1 : Symbol pinSDA = pinB.1 ; Leg 7
;Symbol PWR = B.0 ; Leg 6
;Symbol GND = B.7 ; Leg 13
Symbol MINVOLTS = 190
#endif
#ifdef picaxe20
#picaxe 20m2
#define ok
Symbol SCL = B.7 : Symbol pinSCL = pinB.7 ; Leg 11 (Linked to B.4 Leg 14)
Symbol SDA = B.5 : Symbol pinSDA = pinB.5 ; Leg 13
;Symbol PWR = B.6 ; Leg 12
;symbol GND = B.2 ; Leg 16
Symbol MINVOLTS = 190
#endif
#ifNdef ok
sertxd("Sorry,Pinout not available")
Symbol SCL = 0 : Symbol pinSCL = pin0 ; Dummy values to avoid syntax errors
Symbol SDA = 0 : Symbol pinSDA = pin0
Symbol MINVOLTS = 0
stop
#endif
Symbol GND = 0 ; Editor will report error if already defined
Symbol PWR = 0 ; Editor will report error if already defined
Symbol MAXVOLTS = 550 ; Tens of mV
sertxd(cr,lf,"SCL= ",#SCL," SDA= ",#SDA," V+= ",#PWR," GND=",#GND,cr,lf)
; .-----_-----. Typical I2C header
; Vdd ---| V+ 0V |--- 0V .-.
; -| SI C.0 |--+ +------>|O| PWR
; +---| C.4 C.1 |--|-- SCL --|-------|O| SCL
; | -| C.3 C.2 |--|-- SDA --|-------|O| SDA
; | `-----------' +---------|-------|O| 0V
; +----------------------------+ `-'
;
; Some breakout boards include pull-ups for SDA and SCL
; This program uses internal pull-ups if external pull-ups are missing
; ** Main Program **
do
PowerOnReset:
Pause 1000
Gosub VoltCheck
b0 = PWR ; Can't compare constants
if b0 <> GND then
High PWR
Low GND
endif
Gosub BusCheck ; And enable pullups if required
Pause 100
MainLoop:
; Do
SerTxd( CR, LF, "Looking for Devices ...", CR, LF )
Gosub FindDevices
pullup OFF
Pause 4000
Loop
; ** Check PSU Voltage and Bus hardware **
VoltCheck:
Do
#ifdef simulating
w0 = 500
#else
calibadc10 w0
w0 = w0 / 2 + 52378 / w0
calibadc10 w1 ; Oversample to average and for 10mV resolution
w0 = 52378 / w1 + w0
#endif
BinToAscii w0, b13,b13,b13,b12,b11
SerTxd( cr,lf, "Vpsu = ", b13,".",b12,b11, "Volts")
Select Case w0
Case < MINVOLTS : SerTxd( ": Supply too Low", cr, lf )
Case > MAXVOLTS : SerTxd( ": Supply too High", cr, lf )
End Select
Pause 500
Loop Until w0 >= MINVOLTS and w0 =< MAXVOLTS
Return
BusCheck:
pullup OFF
low SDA ; Take Low now to catch a SDA-SCL bridge
low SCL
input SCL ; Float pin
; pause 10 ; Maybe needed for high pullup resistance or bus capacitance
if pinSCL = 0 then
gosub pullups ; PULLUP command cannot use a variable (PE6 can use #define)
if pinSCL = 0 then
sertxd(cr,lf,"SCL held Low")
else
sertxd(cr,lf,"No SCL Pullup")
endif
pullup OFF
endif
input SDA
; pause 10 ; Maybe needed for high pullup resistance or bus capacitance
if pinSDA = 0 then
gosub pullups
if pinSDA = 0 then
sertxd(cr,lf,"SDA held Low")
else
sertxd(cr,lf,"No SDA Pullup")
endif
endif ; Now fall into pullups in case SCL needs a pullup
pullups:
#ifdef picaxe08
pullup %110
#endif
#ifdef picaxe14
pullup %11000
#endif
#ifdef picaxe18
pullup %10010
#endif
#ifdef picaxe20
pullup %10100000
#endif
; pause 10 ; Maybe needed for high pullup resitance or bus capacitance
return
; ** Search For Devices **
FindDevices:
SerTxd( CR, LF, " ")
For b0 = $00 To $1F Step 2
If b0 = $10 Then
SerTxd( " " )
End If
SerTxd( " " ) : Gosub HexLsd
Next
b10 = $00 ; Address to try
b12 = $00 ; Address found
Do
b0 = b10 & $1F
Select Case b0
Case $00
SerTxd( CR, LF )
b0 = b10 / $10 : Gosub HexLsd
Case $10
SerTxd( " " )
b0 = b10 / $10 : Gosub HexLsd
End Select
If b10 < $10 Or b10 >= $F0 Then
SerTxd( " XX" )
Else
Gosub CheckForDevice
End If
b10 = b10 + 2
Loop Until b10 = 0
SerTxd( CR, LF, CR, LF )
b0 = b12 and 254
if b0 = 0 then : SerTxd( "No devices found" )
else
if b0 <> b12 then
SerTxd( "Multiple devices, Last was at " )
else
SerTxd( "Device found at " )
endif
Gosub Hex
Select Case b0
Case $78 : SerTxd ( " SSD1306 OLED" )
Case $A0 to $A7 : SerTxd ( " EEPROM" )
Case $A4 : SerTxd ( " Wii Controller" )
Case $A6 : SerTxd ( " Wii Motion Plus" )
Case $D0 : SerTxd ( " RTC (Maxim)" )
Case $DE : SerTxd ( " RTC (MCP7940)" )
End Select
endif
SerTxd( CR, LF )
Return
CheckForDevice:
; Gosub ResetBus
Gosub SendStart
b0 = b10 Or 1 ; Read bit
Gosub SendByte
Gosub ReadAck
; Gosub SendStop
If b0 = 0 Then
; Ack
If b12 = $00 Then
b12 = b10
Else
b12 = b10 + 1 ; Mark that this is not the first find
End If
SerTxd( " " ) : b0 = b10 : Gosub Hex
Else
; Nak
SerTxd( " --" )
End If
Gosub ReadByte
Gosub SendNack
Gosub SendStop
Return
; ** Low-Level I2C Routines **
SendStart:
Input SCL ; SCL = 1
Gosub Stretch
Input SDA ; SDA = 1
Low SDA ; SDA = 0
Low SCL ; SCL = 0
Return
ResetBus:
Input SDA ; SDA = 1
Low SCL ; SCL = 0
For b1 = 0 To 8
Input SCL ; SCL = 1
Low SCL ; SCL = 0
Next
SendStop:
Low SDA ; SDA = 0
Low SCL ; SCL = 0
Input SCL ; SCL = 1
Gosub Stretch
Input SDA ; SDA = 1
Return
SendByte:
For b1 = 0 To 7
If bit7 = 0 Then
Low SDA ; SDA = 0
Else
Input SDA ; SDA = 1
End If
Input SCL ; SCL = 1
Gosub Stretch
Low SCL ; SCL = 0
b0 = b0 + b0
Next
Return
ReadByte:
Low SCL ; SCL = 0
Input SDA ; SDA = 1
For b1 = 0 To 7
Input SCL ; SCL = 1
Gosub Stretch
b0 = b0 + b0 + pinSDA
Low SCL ; SCL = 0
Next
Return
ReadAck:
Input SDA ; SDA = 1
Input SCL ; SCL = 1
Gosub Stretch
b0 = pinSDA
Low SCL ; SCL = 0
Return
SendAck:
Low SDA ; SDA = 0
Input SCL ; SCL = 1
Gosub Stretch
Low SCL ; SCL = 0
Return
SendNack:
Input SDA ; SDA = 1
Input SCL ; SCL = 1
Gosub Stretch
Low SCL ; SCL = 0
Return
Stretch:
Do : Loop While pinSCL = 0
Return
; ** Display Output Routines **
Hex:
b1 = b0 / $10 : Gosub Nibble
HexLsd:
b1 = b0
Nibble:
b1 = b1 & $0F + "0"
If b1 > "9" Then : b1 = b1 + 7 : End If
SerTxd( b1 )
Return
; ** End Of Program **