MCP23016 - April 24, '04, Completed development by Kareem Maitland


' MCP23016_1.Bas
'
' Configures MCP23016 Port0, Bit 0 as an output and continually flashes LED on
' GP0.0 (term 21).
'
' PICAXE-18X			MCP23016
'
' Out0 (term 6) --------------- SCL (term 14)
'
' Out1 (term 7) -- 4.7K ------- SDA (term 15)
'                         |
' Input1 (term 18) <------
'
' Clock Rext = 3.9K, Cext = 33 pFd
'
' A2, A1, A0 on MCP23016 strapped to GRD.
'
' copyright, Kareem A.Maitland, Peter H Anderson, Baltimore, MD, April, '04

' Define IO terminals
Symbol  SCL = 0
Symbol  SDAOut = 1
Symbol  SDAIn = Pin1

' Define variables
Symbol N = B0
Symbol OByte = B1

' MCP23016 registers
Symbol GP0 = $00
Symbol GP1 = $01
Symbol OLAT0 = $02
Symbol OLAT1 = $03
Symbol IPOL0 = $04
Symbol IPOL1 = $05
Symbol IODIR0 = $06
Symbol IODIR1 = $07
Symbol INTCAP0 = $08
Symbol INTCAP1 = $09
Symbol IOCON0 = $0a
Symbol IOCON1 = $0b

    Pause 1000	  ' wait for MCP23016 to boot

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = $IODIR0
    GoSub OutByte
    OByte = %11111110	' make least sig bit of Port 0 an output
    GoSub OutByte
    GoSub I2CStop

TOP:
    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = OLAT0
    GoSub OutByte
    OByte = $01		' Port0.0 = 1
    GoSub OutByte
    GoSub I2CStop

    Pause 1000

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = OLAT0
    GoSub OutByte
    OByte = $00		' Port0.0 = 0
    GoSub OutByte
    GoSub I2CStop

    Pause 1000

    GoTo TOP

I2CStart:
    High SDAOut
    High SCL
    Low SDAOut
    Low SCL
    Return

I2CStop:
    High SCL
    High SDAOut
    Return

OutByte:

    For N = 1 to 8

       If OByte > 127 Then OutHigh
       Low SDAOut
       SerTxD ("0")		' for debugging
       GoTo OutByte_1

OutHigh:
       High SDAOut
       SerTxD ("1")		' for debugging
       GoTo OutByte_1

OutByte_1:
       High SCL
       Low SCL
       OByte = OByte * 2
    Next

    High SDAOut
    High SCL
    Low SCL
    Low SDAOut

    SerTxD(13, 10)		' for debugging

    Return


' MCP23016_2.Bas
'
' Continually reads GP1.0 (term 2) on MCP23016.  If at logic one, flashes LED on GP0.0.
'
' PICAXE-18X			MCP23016
'
' Out0 (term 6) --------------- SCL (term 14)
'
' Out1 (term 7) -- 4.7K ------- SDA (term 15)
'                         |
' Input1 (term 18) <------
'
' Clock Rext = 3.9K, Cext = 33 pFd
'
'A2, A1, A0 on MCP23016 strapped to GRD.
'
' copyright, Kareem A.Maitland, Peter H Anderson, Baltimore, MD, April, '04

' Define IO Terminals
Symbol SCL = 0
Symbol SDAIn = Pin1
Symbol SDAOut = 1

' define variables
Symbol N = B0
Symbol OByte = B1
Symbol IByte = B2

' MCP23016 registers
Symbol GP0 = $00
Symbol GP1 = $01
Symbol OLAT0 = $02
Symbol OLAT1 = $03
Symbol IPOL0 = $04
Symbol IPOL1 = $05
Symbol IODIR0 = $06
Symbol IODIR1 = $07
Symbol INTCAP0 = $08
Symbol INTCAP1 = $09
Symbol IOCON0 = $0a
Symbol IOCON1 = $0b

    Pause 1000	 ' wait for MCP23016 to boot

    GoSub I2CStart	' high speed sampling
    OByte = $40
    GoSub OutByte
    OByte = IOCON0
    GoSub OutByte
    OByte = $01
    GoSub OutByte
    GoSub I2CStop

    GoSub I2CStart    ' make GP0.0 an output
    OByte = $40
    GoSub OutByte
    OByte = IODIR0
    GoSub OutByte
    OByte = %11111110
    GoSub OutByte
    GoSub I2CStop

Top:

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = GP1
    GoSub OutByte

    GoSub I2CStart
    OByte = $41
    GoSub OutByte
    GoSub InByte
    Gosub I2CStop

    SerTxD (#IByte, 13, 10) ' for debugging

    IByte = IByte & $01
    If IByte = 1 Then Flash

    Pause 1000

    GoTo TOP

Flash:
    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = OLAT0
    GoSub OutByte
    OByte = $01
    GoSub OutByte
    GoSub I2CStop

    Pause 1000

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = OLAT0
    GoSub OutByte
    OByte = $00
    GoSub OutByte
    GoSub I2CStop

    Pause 1000
    GoTo TOP

I2CStart:
    High SDAOut
    High SCL
    Low SDAOut
    Low SCL
    Return

I2CStop:
    High SCL
    High SDAOut
    Return

OutByte:

    For N = 1 to 8

       If OByte > 127 Then OutHigh
       Low SDAOut
       SerTxD ("0")	' for debugging
       GoTo OutByte_1

OutHigh:
       High SDAOut
       SerTxD ("1")	' for debugging
       GoTo OutByte_1

OutByte_1:
       High SCL
       Low SCL
       OByte = OByte * 2
    Next

    High SDAOut
    High SCL
    Low SCL
    Low SDAOut

    SerTxD(13, 10)	' for debugging

    Return

InByte:
    High SDAOut
    For N=1 to 8
       High SCL
	   IByte = Ibyte * 2 + SDAIn
	   Low SCL
    Next

    High SDAOut
    High SCL
    Low  SCL
    Low SDAOut

    Return


' MCP23016_3.Bas
'
' Continually flashes LED on MCP23016, GP0.0.  GP1 configured for eight inputs.
' If any input to MCP23016 changes, the PICAXE is interrupted and the int capture
' register INTCAP1 is read and the state of each input is displayed
'
' PICAXE-18X			MCP23016
'
' Out0 (term 6) --------------- SCL (term 14)
'
' Out1 (term 7) -- 4.7K ------- SDA (term 15)
'                         |
' Input1 (term 18) <------
'
' Clock Rext = 3.9K, Cext = 33 pFd
'
' A2, A1, A0 on MCP23016 strapped to GRD.
'
' copyright, Kareem A Maitland, Peter H. Anderson, Baltimore, MD, Apr, '04

' Define IO Terminals
Symbol SCL = 0
Symbol SDAIn = Pin1
Symbol SDAOut = 1

' define variables
Symbol N = B0
Symbol OByte = B1
Symbol IByte = B2

Symbol NDelay = B3

Symbol NN = B4
Symbol MSB = B5


' MCP23016 registers
Symbol GP0 = $00
Symbol GP1 = $01
Symbol OLAT0 = $02
Symbol OLAT1 = $03
Symbol IPOL0 = $04
Symbol IPOL1 = $05
Symbol IODIR0 = $06
Symbol IODIR1 = $07
Symbol INTCAP0 = $08
Symbol INTCAP1 = $09
Symbol IOCON0 = $0a
Symbol IOCON1 = $0b

    Pause 1000	  ' wait for MCP23016 to boot

    GoSub I2CStart	  ' high speed sampling
    OByte = $40
    GoSub OutByte
    OByte = IOCON0
    GoSub OutByte
    OByte = $01
    GoSub OutByte
    GoSub I2CStop

    GoSub I2CStart     ' make GP0 all outputs
    OByte = $40
    GoSub OutByte
    OByte = IODIR0
    GoSub OutByte
    OByte = $00	       ' 0000 0000
    GoSub OutByte
    GoSub I2CStop

    GoSub I2CStart     ' make GP1 all inputs
    OByte = $40
    GoSub OutByte
    OByte = IODIR1
    GoSub OutByte
    OByte = $ff	       ' 1111 1111
    GoSub OutByte
    GoSub I2CStop


Top:

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
   	OByte = OLAT0
    GoSub OutByte
    OByte = $01
    GoSub OutByte
    GoSub I2CStop

    Gosub DelayOneSec

    GoSub I2CStart
    OByte = $40
    GoSub OutByte
    OByte = OLAT0
    GoSub OutByte
    OByte = $00
    GoSub OutByte
    GoSub I2CStop

    GoSub DelayOneSec

    GoTo TOP

DelayOneSec:
    SetInt %00000000, %10000000		' enable polled interrupt on Input 7 of PICAXE
    For NDelay = 1 to 250
       Pause 4
    Next
    SetInt %00000000, %00000000		' disable polled interrupt
    SetInt %00000000, %00000000		' be sure it is disabled
    Return

Interrupt:
    If Pin7 = 0 Then Interrupt

    GoSub I2CStart     ' fetch INTCAP1
    OByte = $40
    GoSub OutByte
    OByte = INTCAP1
    GoSub OutByte

    GoSub I2CStart
    OByte = $41	       ' 1000 0000
    GoSub OutByte
    GoSub InByte
    GoSub I2CStop

    SerTxD (#IByte, 13, 10)

    For NN = 1 to 8
       MSB = IByte / 128
       SerTxD (#MSB, " ")
       IByte = IByte * 2
    Next

    SerTxD (13, 10)

    High 3			' wink an LED
    Pause 100
    Low 3
    SetInt %00000000, %10000000
    Return

I2CStart:
    High SDAOut
    High SCL
    Low SDAOut
    Low SCL
    Return

I2CStop:
    High SCL
    High SDAOut
    Return

OutByte:

    For N = 1 to 8

      If OByte > 127 Then OutHigh
      Low SDAOut
      ' SerTxD ("0")
      GoTo OutByte_1

OutHigh:
      High SDAOut
      'SerTxD ("1")
      GoTo OutByte_1

OutByte_1:
      High SCL
      Low SCL
      OByte = OByte * 2
    Next

    High SDAOut
    High SCL
    Low SCL
    Low SDAOut

    ' SerTxD(13, 10)

    Return

InByte:
    High SDAOut
    For N=1 to 8
       High SCL
       IByte = Ibyte * 2 + SDAIn
       Low SCL
    Next

    High SCL
    Low  SCL
    Low SDAOut

    Return