Swordfish Module: Microchip MCP23008 I2C 8-Bit I/O Expander

MCP23008_-_smThe MCP23008 is an 8-bit I2C I/O expander.  Think of it as adding an 8-bit port to the microcontroller using just 2 wires for an I2C interface which can be shared with many devices.  It's a handy way to add some extra port pins and a way to add extra interrupt capability to an already-busy microcontroller.  Up to 8 MCP23008s may be added to the system by giving each chip a unique address.

The Swordfish driver makes accessing individual pins or the entire port similar to using the microcontroller's port pins in Swordfish, and isolates the complexity of using the I2C interface.  There are a few configuration commands and commands for using individual port pins or addressing the entire port at once.

Unlike the driver for the MCP9800, which has a few specific functions dictated by the functions of the chip, the interface for the MCP23008 is both more flexible and more complex because of the nature of the chip.  For the most part, the commands are similar to those found in Swordfish although the syntax will be slightly different.

The register descriptions and interrupt configuration are included at the start of the driver module to help clarify how to use the chip's features.  Don't worry, the verbose comments don't add to the compiled program's size.

Address and Configuration

Command
Comment
I2CDevice = $40  
 Default MCP23008 address
Function CheckAddress ()
Returns 0 if address invalid, 1 if address present
Function Config_InterruptOutput (Port1 As Byte)
0 = Open drain output
 1 = Active Low
  2 = Active High 

Functions by Pin

Command
Comment
Function OutputPin(Port1 As Byte)
Set specified pin to output, IODIR register is returned
Function InputPin (Port1 As Byte)
'Set specified pin to input, IODIR register is returned
Function LowPin (Port1 As Byte)
Sets specified pin to output and low, OLAT register is returned
Function HighPin (Port1 As Byte)
Sets specified pin to output and high, OLAT register is returned
Function EnablePullupPin (Port1 As Byte)
'Enables pullup resistor on specified pin, returns GPPU register
Function DisablePullupPin (Port1 As Byte)
Disables pullup resistor on specified pin, returns GPPU register
Function ReadPin (Port1 As Byte)
Reads specified pin, returns 0 or 1
Function InvertInputPin (Port1 As Byte)
Changes the sense of the input pin, returns IPOL register
Function NormalInputPin (Port1 As Byte)
Normal sense of the input pin, returns IPOL register
Function IntEnablePin (Port1 As Byte)
Enable interrupt on pin
Function IntDisablePin (Port1 As Byte)
Disable interrupt on pin
Function IntCompareValuePin (Port1 As Byte, Value2 As Bit)
Value to compare pin to if in compare mode
Function IntModePin (Port1 As Byte, Value2 As Bit)
Compare to value if 1, compare to previous if 0
Function IntFlagPin (Port1 As Byte)
1 if pin caused interrupt

Functions by Port

Command
Comment
Function IODirPort (Port1 As Byte)
Set IO Direction, 1 = in, 0 = out.  Returns IODIR reg
Function OutputPort (Port1 As Byte)
Sets OLAT to specifed value.  Returns OLAT reg.  Does not change IODIR reg
Function InputPort ()
Reads GPIO.  Does not change IODIR reg
Function PullupPort (Port1 As Byte)
Sets GPPU to specifed value. Returns GPPU reg.  Does not change IODIR reg
Function InputPolarityPort (Port1 As Byte)
Inverts sense of input levels. Returns IPOL reg.  Does not change IODIR reg
Function IntEnPort (Port1 As Byte)
Enables interrupt on each port pin
Function IntCompareValuePort (Port1 As Byte)
Set Interrupt Comparison Values
Function IntModePort (Port1 As Byte)
Compare to value if 1, compare to previous if 0
Function IntFlagPort (Port1 As Byte)
1 if pin caused interrupt
Function IntCapPort (Port1 As Byte)
Indicates the port state at the time of an interrupt.

Sample Program

The sample program below sequentially lights LEDs connected to each port pin using pin commands and then extinguishes all of them simultaneously using a port command.  Notice how simply the port pins are controlled using the Swordfish module.

 

MCP23008 Demonstration Program
{
*****************************************************************************
*  Name    : MCP23008 Module Demonstration                                  *
*  Author  : Jon Chandler                                                   *
*  Notice  : Licensed Under Creative Commons 3.0 SA-BY                      *
*          : All Rights Reserved                                            *
*  Date    : 11/15/2010                                                     *
*  Version : 1.0                                                            *
*  Notes   : Microchip MCP23008 - 8-Bit I/O Expander with Serial Interface  *
*          :                                                                *
*****************************************************************************
}
'Module MCP23008
 
Device =18f2520
Clock = 12
 
Include("MCP23008.bas")
 
 
 
Output(PORTB.3)   'LED2 on TAP-28 board
 
MCP23008.I2CDevice = $40  '$40 is the default for the MCP23008 - no need to specify unless different
 
While 1 = 1
 
MCP23008.CheckAddress               'check I2C device connected each loop.  Turn on LED if no response
If MCP23008.CheckAddress = 0 Then
    Low(PORTB.3)
Else
    High(PORTB.3)
End If
 
MCP23008.HighPin(0)    'make pin an output and set it high
DelayMS(100)
MCP23008.HighPin(1)
DelayMS(100)
MCP23008.HighPin(2)
DelayMS(100)
MCP23008.HighPin(3)
DelayMS(100)
MCP23008.HighPin(4)
DelayMS(100)
MCP23008.HighPin(5)
DelayMS(100)
MCP23008.HighPin(6)
DelayMS(100)
MCP23008.HighPin(7)
DelayMS(100)
 
MCP23008.OutputPort(%00000000) 'set all bits low
 
DelayMS(200)
 
Wend

 

 

 

MCP23008 Swordfish Module
{
*****************************************************************************
*  Name    : MCP23008Module                                                 *
*  Author  : Jon Chandler                                                   *
*  Notice  : Licensed Under Creative Commons 3.0 SA-BY                      *
*          : All Rights Reserved                                            *
*  Date    : 11/15/2010                                                     *
*  Version : 1.0                                                            *
*  Notes   : Microchip MCP23008 - 8-Bit I/O Expander with Serial Interface  *
*          :                                                                *
*****************************************************************************
} 
 
{
---------------------------------------------------------------------------------------------------
 
Register and Interrupt Information from the data sheet
---------------------------------------------------------------------------------------------------
 
I/O DIRECTION (IODIR) REGISTER
 
Controls the direction of the data I/O.  When a bit is set, the corresponding pin becomes an
input. When a bit is clear, the corresponding pin becomes an output.
 
These bits control the direction of data I/O <7:0>
1 = Pin is configured as an input.
0 = Pin is configured as an output.
---------------------------------------------------------------------------------------------------
 
INPUT POLARITY (IPOL) REGISTER
 
The IPOL register allows the user to configure the polarity on the corresponding GPIO port bits.
If a bit is set, the corresponding GPIO register bit will reflect the inverted value on the pin.
 
These bits control the polarity inversion of the input pins <7:0>
1 = GPIO register bit will reflect the opposite logic state of the input pin.
0 = GPIO register bit will reflect the same logic state of the input pin.
---------------------------------------------------------------------------------------------------
 
INTERRUPT-ON-CHANGE CONTROL (GPINTEN) REGISTER
 
The GPINTEN register controls the interrupt-onchange feature for each pin. If a bit is set, the 
corresponding pin is enabled for interrupt-on-change. The DEFVAL and INTCON registers must also 
be configured if any pins are enabled for interrupt-on-change.
 
General purpose I/O interrupt-on-change bits <7:0>
1 = Enable GPIO input pin for interrupt-on-change event.
0 = Disable GPIO input pin for interrupt-on-change event.
---------------------------------------------------------------------------------------------------
 
DEFAULT COMPARE (DEFVAL) REGISTER FOR INTERRUPT-ONCHANGE
 
The default comparison value is configured in the DEFVAL register. If enabled (via GPINTEN and
INTCON) to compare against the DEFVAL register, an opposite value on the associated pin will cause
an interrupt to occur.
---------------------------------------------------------------------------------------------------
 
INTERRUPT CONTROL (INTCON) REGISTER
 
The INTCON register controls how the associated pin value is compared for the interrupt-on-change feature.
If a bit is set, the corresponding I/O pin is compared against the associated bit in the DEFVAL register. 
If a bit value is clear, the corresponding I/O pin is compared against the previous value.
 
These bits set the compare value for pins configured for interrupt-on-change from defaults <7:0>. 
Refer to INTCON and GPINTEN.
1 = Controls how the associated pin value is compared for interrupt-on-change.
0 = Pin value is compared against the previous pin value.
---------------------------------------------------------------------------------------------------
 
CONFIGURATION (IOCON) REGISTER
 
The IOCON register contains several bits for configuring the device:
• The Sequential Operation (SEQOP) controls the incrementing function of the address pointer. If the
address pointer is disabled, the address pointer does not automatically increment after each byte
is clocked during a serial transfer. This feature is useful when it is desired to continuously poll
(read) or modify (write) a register.
 
• The Slew Rate (DISSLW) bit controls the slew rate function on the SDA pin. If enabled, the SDA
slew rate will be controlled when driving from a high to a low.
 
 
• The Open-Drain (ODR) control bit enables/disables the INT pin for open-drain configuration.
 
• The Interrupt Polarity (INTPOL) control bit sets the polarity of the INT pin. This bit is functional
only when the ODR bit is cleared, configuring the INT pin as active push-pull.
 
bit 7-6 Unimplemented: Read as ‘0’.
bit 5 SEQOP: Sequential Operation mode bit.
    1 = Sequential operation disabled, address pointer does not increment.
    0 = Sequential operation enabled, address pointer increments.
bit 4 DISSLW: Slew Rate control bit for SDA output.
    1 = Slew rate disabled.
    0 = Slew rate enabled.
bit 3 HAEN: N/A - Address pins are always enabled on MCP23008.
bit 2 ODR: This bit configures the INT pin as an open-drain output.
    1 = Open-drain output (overrides the INTPOL bit).
    0 = Active driver output (INTPOL bit sets the polarity).
bit 1 INTPOL: This bit sets the polarity of the INT output pin.
    1 = Active-high.
    0 = Active-low.
bit 0 Unimplemented: Read as ‘0’.
---------------------------------------------------------------------------------------------------
 
PULL-UP RESISTOR CONFIGURATION (GPPU) REGISTER
The GPPU register controls the pull-up resistors for the port pins. If a bit is set and the corresponding 
pin is configured as an input, the corresponding port pin is internally pulled up with a 100 kO resistor.
 
These bits control the weak pull-up resistors on each pin (when configured as an input)
1 = Pull-up enabled.
0 = Pull-up disabled.
---------------------------------------------------------------------------------------------------
 
INTERRUPT FLAG (INTF) REGISTER
 
The INTF register reflects the interrupt condition on the port pins of any pin that is enabled for interrupts 
via the GPINTEN register. A ‘set’ bit indicates that the associated pin caused the interrupt.
 
This register is ‘read-only’. Writes to this register will be ignored.
 
Note: INTF will always reflect the pin(s) that have an interrupt condition. For example, one pin causes an 
interrupt to occur and is captured in INTCAP and INF. If before clearing the interrupt another pin changes,
which would normally cause an interrupt, it will be reflected in INTF, but not INTCAP
 
These bits reflect the interrupt condition on the port. Will reflect the change only if interrupts
are enabled (GPINTEN) <7:0>.
1 = Pin caused interrupt.
0 = Interrupt not pending
---------------------------------------------------------------------------------------------------
 
INTERRUPT CAPTURE (INTCAP) REGISTER
 
The INTCAP register captures the GPIO port value at the time the interrupt occurred. The register is ‘readonly’
and is updated only when an interrupt occurs. The register will remain unchanged until the interrupt is
cleared via a read of INTCAP or GPIO.
 
These bits reflect the logic level on the port pins at the time of interrupt due to pin change <7:0>
1 = Logic-high.
0 = Logic-low.
---------------------------------------------------------------------------------------------------
 
PORT (GPIO) REGISTER
 
The GPIO register reflects the value on the port. Reading from this register reads the port. Writing to this
register modifies the Output Latch (OLAT) register.
 
These bits reflect the logic level on the pins <7:0>
1 = Logic-high.
0 = Logic-low.
---------------------------------------------------------------------------------------------------
 
OUTPUT LATCH REGISTER (OLAT)
 
The OLAT register provides access to the output latches. A read from this register results in a read of the
OLAT and not the port itself. A write to this register modifies the output latches that modify the pins
configured as outputs.
 
These bits reflect the logic level on the output latch <7:0>
1 = Logic-high.
0 = Logic-low.
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
 
Interrupt Logic
 
The interrupt output pin will activate if an internal interrupt occurs. The interrupt block is configured by
the following registers:
 
• GPINTEN – enables the individual inputs
 
• DEFVAL – holds the values that are compared against the associated input port values
 
• INTCON – controls if the input values are compared against DEFVAL or the previous values on the port
 
• IOCON (ODR and INPOL) – configures the INT pin as push-pull, open-drain and active-level
 
Only pins configured as inputs can cause interrupts. Pins configured as outputs have no affect on INT.
Interrupt activity on the port will cause the port value to be captured and copied into INTCAP. The interrupt will
remain active until the INTCAP or GPIO register is read. Writing to these registers will not affect the interrupt.
 
The first interrupt event will cause the port contents to be copied into the INTCAP register. Subsequent
interrupt conditions on the port will not cause an interrupt to occur as long as the interrupt is not cleared
by a read of INTCAP or GPIO.
 
INTERRUPT CONDITIONS
 
There are two possible configurations to cause interrupts (configured via INTCON):
 
1. Pins configured for interrupt-on-pin-change will cause an interrupt to occur if a pin changes
to the opposite state. The default state is reset after an interrupt occurs. For example, an
interrupt occurs by an input changing from 1 to 0. The new initial state for the pin is a logic 0.
 
2. Pins configured for interrupt-on-change from register value will cause an interrupt to occur if
the corresponding input pin differs from the register bit. The interrupt condition will remain as
long as the condition exists, regardless if the INTAP or GPIO is read.
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
 
}
 
Module MCP23008
 
Include ("i2c.bas")
 
'Registers
 
Public Const REG_IODIR = $00
Public Const REG_IPOL = $01 
Public Const REG_GPINTEN = $02
Public Const REG_DEFVAL = $03
Public Const REG_INTCON = $04
Public Const REG_IOCON = $05
Public Const REG_GPPU = $06
Public Const REG_INTF = $07
Public Const REG_INTCAP = $08
Public Const REG_GPIO = $09
Public Const REG_OLAT = $0A
 
'Configuration Bits
 
Public Const ConstConfig_SREAD = 5
Public Const ConstConfig_DISSLW = 4
Public Const ConstConfig_HAEN = 3
Public Const ConstConfig_ODR = 2
Public Const ConstConfig_INTPOL = 1
 
Public Dim I2CDevice As Byte
 
Public Dim I2CPointer As Byte
Public Dim Port1 As Byte
Public Dim Port2 As Byte
Dim Value1 As Byte
Dim Value2 As Byte
 
Public Sub Read_REG(Pointer As Byte, ByRef Val1 As Byte)
        I2C.Start
        I2C.WriteByte(I2CDevice)
        I2C.WriteByte(Pointer)
        I2C.Stop
 
        I2C.Restart
        I2C.WriteByte(I2CDevice+1)
        Val1 = I2C.ReadByte
 
        I2C.Acknowledge(I2C_NOT_ACKNOWLEDGE)
        I2C.Stop
 
End Sub
 
Public Sub Write_REG(Pointer As Byte, ByRef Val1 As Byte)
        I2C.Start
        I2C.WriteByte(I2CDevice)
        I2C.WriteByte(Pointer)
        I2C.WriteByte(val1)
        I2C.Stop
 
End Sub
 
Public Function CheckAddress () As Bit  'Returns 0 if address invalid, 1 if address present
    Read_REG(REG_GPIO, Value1)
    If I2C.NotAcknowledged = true Then
        result = 0
    Else
        result = 1
    End If
    I2C.Stop
End Function
 
'****************************************************************************
'* Pin Functions - Agrument is pin number, returned value is register value *
'****************************************************************************
 
Public Function OutputPin(Port1 As Byte) As Byte 'Set specified pin to output, IODIR register is returned
    Read_REG(REG_IODIR, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_IODIR, Value1)
    result = Value1
End Function
 
Public Function InputPin (Port1 As Byte) As Byte 'Set specified pin to input, IODIR register is returned
    Read_REG(REG_IODIR, Value1)
    Select Port1
        Case = 0
            Value1.0 = 1
        Case = 1
            Value1.1 = 1
        Case = 2
            Value1.2 = 1
        Case = 3
            Value1.3 = 1
        Case = 4
            Value1.4 = 1
        Case = 5
            Value1.5 = 1
        Case = 6
            Value1.6 = 1
        Case = 7
            Value1.7 = 1
    End Select
    Write_REG(REG_IODIR, Value1)
    result = Value1
End Function
 
Public Function LowPin (Port1 As Byte) As Byte 'Sets specified pin to output and low, OLAT register is returned
    Read_REG(REG_IODIR, Value1) ' set bit for output
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    result = Value1
    End Select
    Write_REG(REG_IODIR, Value1)
 
    Read_REG(REG_OLAT, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_OLAT, Value1)
    result = Value1
End Function
 
Public Function HighPin (Port1 As Byte) As Byte 'Sets specified pin to output and high, OLAT register is returned
    Read_REG(REG_IODIR, Value1) ' set bit for output
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    result = Value1
    End Select
    Write_REG(REG_IODIR, Value1)
 
    Read_REG(REG_OLAT, Value1)
    Select Port1
        Case = 0
            Value1.0 = 1
        Case = 1
            Value1.1 = 1
        Case = 2
            Value1.2 = 1
        Case = 3
            Value1.3 = 1
        Case = 4
            Value1.4 = 1
        Case = 5
            Value1.5 = 1
        Case = 6
            Value1.6 = 1
        Case = 7
            Value1.7 = 1
    result = Value1
    End Select
    Write_REG(REG_OLAT, Value1)
End Function
 
Public Function EnablePullupPin (Port1 As Byte) As Byte 'Enables pullup resistor on specified pin, returns GPPU register
    Read_REG(REG_GPPU, Value1)
    Select Port1
        Case = 0
            Value1.0 = 1
        Case = 1
            Value1.1 = 1
        Case = 2
            Value1.2 = 1
        Case = 3
            Value1.3 = 1
        Case = 4
            Value1.4 = 1
        Case = 5
            Value1.5 = 1
        Case = 6
            Value1.6 = 1
        Case = 7
            Value1.7 = 1
    End Select
    Write_REG(REG_GPPU, Value1)
    result = Value1
End Function
 
Public Function DisablePullupPin (Port1 As Byte) As Byte 'Disables pullup resistor on specified pin, returns GPPU register
    Read_REG(REG_GPPU, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_GPPU, Value1)
    result = Value1
End Function
 
Public Function ReadPin (Port1 As Byte) As Bit 'Reads specified pin, returns 0 or 1
    Read_REG(REG_GPIO, Value1)
        Select Port1
        Case = 0
            result = Value1.0
        Case = 1
            result = Value1.1
        Case = 2
            result = Value1.2
        Case = 3
            result = Value1.3
        Case = 4
            result = Value1.4
        Case = 5
            result = Value1.5
        Case = 6
            result = Value1.6
        Case = 7
            result = Value1.7
    End Select
End Function
 
Public Function InvertInputPin (Port1 As Byte) As Byte 'Changes the sense of the input pin, returns IPOL register
    Read_REG(REG_IPOL, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_IPOL, Value1)
    result = Value1
End Function
 
Public Function NormalInputPin (Port1 As Byte) As Byte 'Normal sense of the input pin, returns IPOL register
    Read_REG(REG_IPOL, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_IPOL, Value1)
    result = Value1
End Function
 
'****************************************************************************
'* Interrupt Functions by Pin                                               *
'****************************************************************************
 
Public Function IntEnablePin (Port1 As Byte) As Byte  'enable interrupt on pin
    Read_REG(REG_GPINTEN, Value1)
    Select Port1
        Case = 0
            Value1.0 = 1
        Case = 1
            Value1.1 = 1
        Case = 2
            Value1.2 = 1
        Case = 3
            Value1.3 = 1
        Case = 4
            Value1.4 = 1
        Case = 5
            Value1.5 = 1
        Case = 6
            Value1.6 = 1
        Case = 7
            Value1.7 = 1
    End Select
    Write_REG(REG_GPINTEN, Value1)
    result = Value1
 
End Function
 
Public Function IntDisablePin (Port1 As Byte) As Byte   'disable interrupt on pin
Read_REG(REG_GPINTEN, Value1)
    Select Port1
        Case = 0
            Value1.0 = 0
        Case = 1
            Value1.1 = 0
        Case = 2
            Value1.2 = 0
        Case = 3
            Value1.3 = 0
        Case = 4
            Value1.4 = 0
        Case = 5
            Value1.5 = 0
        Case = 6
            Value1.6 = 0
        Case = 7
            Value1.7 = 0
    End Select
    Write_REG(REG_GPINTEN, Value1)
    result = Value1
 
End Function
 
 
Public Function IntCompareValuePin (Port1 As Byte, Value2 As Bit) As Byte   'value to compare pin to if in compare mode
Read_REG(REG_DEFVAL, Value1)
    Select Port1
        Case = 0
            Value1.0 = Value2
        Case = 1
            Value1.1 = Value2
        Case = 2
            Value1.2 = Value2
        Case = 3
            Value1.3 = Value2
        Case = 4
            Value1.4 = Value2
        Case = 5
            Value1.5 = Value2
        Case = 6
            Value1.6 = Value2
        Case = 7
            Value1.7 = Value2
    End Select
    Write_REG(REG_GPINTEN, Value1)
    result = Value1
 
End Function
 
Public Function IntModePin (Port1 As Byte, Value2 As Bit) As Byte      'compare to value if 1, compare to previous if 0
Read_REG(REG_INTCON, Value1)
    Select Port1
        Case = 0
            Value1.0 = Value2
        Case = 1
            Value1.1 = Value2
        Case = 2
            Value1.2 = Value2
        Case = 3
            Value1.3 = Value2
        Case = 4
            Value1.4 = Value2
        Case = 5
            Value1.5 = Value2
        Case = 6
            Value1.6 = Value2
        Case = 7
            Value1.7 = Value2
    End Select
    Write_REG(REG_INTCON, Value1)
    result = Value1
 
End Function
 
Public Function IntFlagPin (Port1 As Byte) As Bit      '1 if pin caused interrupt
    Read_REG(REG_INTF, Value1)
        Select Port1
        Case = 0
            result = Value1.0
        Case = 1
            result = Value1.1
        Case = 2
            result = Value1.2
        Case = 3
            result = Value1.3
        Case = 4
            result = Value1.4
        Case = 5
            result = Value1.5
        Case = 6
            result = Value1.6
        Case = 7
            result = Value1.7
    End Select
End Function
 
'******************************************************************************
'* Port Functions - Agrument is byte to set, returned value is register value *
'******************************************************************************
 
Public Function IODirPort (Port1 As Byte) As Byte   'set IO Direction, 1 = in, 0 = out.  Returns IODIR reg
    Write_REG(REG_IODIR, Port1)
    Read_REG(REG_IODIR, Port1)
    result = Port1
End Function
 
Public Function OutputPort (Port1 As Byte) As Byte   'sets OLAT to specifed value. Returns OLAT reg Does not change IODIR reg 
    Write_REG(REG_OLAT, Port1)
    Read_REG(REG_OLAT, Port1)
    result = Port1
End Function
 
Public Function InputPort () As Byte   'Reads GPIO.  Does not change IODIR reg 
    Read_REG(REG_GPIO, Port1)
    result = Port1
End Function
 
Public Function PullupPort (Port1 As Byte) As Byte   'sets GPPU to specifed value. Returns GPPU reg. Does not change IODIR reg 
    Write_REG(REG_GPPU, Port1)
    Read_REG(REG_GPPU, Port1)
    result = Port1
End Function
 
Public Function InputPolarityPort (Port1 As Byte) As Byte   'Inverts sense of input levels. Returns IPOL reg.  Does not change IODIR reg 
    Write_REG(REG_IPOL, Port1)
    Read_REG(REG_IPOL, Port1)
    result = Port1
End Function
 
'****************************************************************************
'* Interrupt Functions by Port                                              *
'****************************************************************************
Public Function IntEnPort (Port1 As Byte) As Byte   'Enables interrupt on each port pin 
    Write_REG(REG_GPINTEN, Port1)
    Read_REG(REG_GPINTEN, Port1)
    result = Port1
End Function
 
Public Function IntCompareValuePort (Port1 As Byte) As Byte   'Set Interrupt Comparison Values
    Write_REG(REG_DEFVAL, Port1)
    Read_REG(REG_GPINTEN, Port1)
    result = Port1
End Function
 
Public Function IntModePort (Port1 As Byte) As Byte      'compare to value if 1, compare to previous if 0
    Write_REG(REG_INTCON, Port1)
    Read_REG(REG_INTCON, Port1)
    result = Port1
End Function
 
Public Function IntFlagPort (Port1 As Byte) As Byte      '1 if pin caused interrupt
   Read_REG(REG_INTF, Port1)
   result = Port1
End Function
 
Public Function IntCapPort (Port1 As Byte) As Byte      'Indicates the port state at the time of an interrupt.  
   Read_REG(REG_INTCAP, Port1)
   result = Port1
End Function
 
'******************************************************************************
'* Configuration Options                                                      *
'******************************************************************************
 
Public Function Config_InterruptOutput (Port1 As Byte) As Byte 
Read_REG(REG_IOCON, Value1)
Select Port1
    Case = 0    'Open drain output
        Value1.2 = 1   
    Case = 1    'Active Low
        Value1.2 = 0
        Value1.1 = 0    
    Case = 2    'Active High
        Value1.2 = 0
        Value1.1 = 1
End Select
Write_REG(REG_IOCON, Value1)
result = Value1
End Function            
 
 
 
 
 
 
 
I2CDevice = $40     'default address 
I2CPointer = $00
 
I2C.Initialize
I2C.Start
I2C.Stop 

 

 

Forum Activity

Member Access