master 9e67e3732d1a cached
17 files
35.6 KB
9.5k tokens
3 symbols
1 requests
Download .txt
Repository: adafruit/Adafruit-MCP23017-Arduino-Library
Branch: master
Commit: 9e67e3732d1a
Files: 17
Total size: 35.6 KB

Directory structure:
gitextract_3qygkpm0/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       └── githubci.yml
├── README.md
├── examples/
│   ├── mcp23xxx_blink/
│   │   └── mcp23xxx_blink.ino
│   ├── mcp23xxx_button/
│   │   └── mcp23xxx_button.ino
│   ├── mcp23xxx_combo/
│   │   └── mcp23xxx_combo.ino
│   └── mcp23xxx_interrupt/
│       └── mcp23xxx_interrupt.ino
├── keywords.txt
├── library.properties
├── license.txt
└── src/
    ├── Adafruit_MCP23X08.cpp
    ├── Adafruit_MCP23X08.h
    ├── Adafruit_MCP23X17.cpp
    ├── Adafruit_MCP23X17.h
    ├── Adafruit_MCP23XXX.cpp
    └── Adafruit_MCP23XXX.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
Thank you for opening an issue on an Adafruit Arduino library repository.  To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:

- **Do not use GitHub issues for troubleshooting projects and issues.**  Instead use
  the forums at http://forums.adafruit.com to ask questions and troubleshoot why
  something isn't working as expected.  In many cases the problem is a common issue
  that you will more quickly receive help from the forum community.  GitHub issues
  are meant for known defects in the code.  If you don't know if there is a defect
  in the code then start with troubleshooting on the forum first.

- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
  check all of the steps and commands to run have been followed.  Consult the
  forum if you're unsure or have questions about steps in a guide/tutorial.

- **For Arduino projects check these very common issues to ensure they don't apply**:

  - For uploading sketches or communicating with the board make sure you're using
    a **USB data cable** and **not** a **USB charge-only cable**.  It is sometimes
    very hard to tell the difference between a data and charge cable!  Try using the
    cable with other devices or swapping to another cable to confirm it is not
    the problem.

  - **Be sure you are supplying adequate power to the board.**  Check the specs of
    your board and plug in an external power supply.  In many cases just
    plugging a board into your computer is not enough to power it and other
    peripherals.

  - **Double check all soldering joints and connections.**  Flakey connections
    cause many mysterious problems.  See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.

  - **Ensure you are using an official Arduino or Adafruit board.** We can't
    guarantee a clone board will have the same functionality and work as expected
    with this code and don't support them.

If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:

- Arduino board:  **INSERT ARDUINO BOARD NAME/TYPE HERE**

- Arduino IDE version (found in Arduino -> About Arduino menu):  **INSERT ARDUINO
  VERSION HERE**

- List the steps to reproduce the problem below (if possible attach a sketch or
  copy the sketch code in too): **LIST REPRO STEPS BELOW**


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
Before you open the request please review the following guidelines and tips to
help it be more easily integrated:

- **Describe the scope of your change--i.e. what the change does and what parts
  of the code were modified.**  This will help us understand any risks of integrating
  the code.

- **Describe any known limitations with your change.**  For example if the change
  doesn't apply to a supported platform of the library please mention it.

- **Please run any tests or examples that can exercise your modified code.**  We
  strive to not break users of the code and running tests/examples helps with this
  process.

Thank you again for contributing!  We will try to test and integrate the change
as soon as we can, but be aware we have many GitHub repositories to manage and
can't immediately respond to every request.  There is no need to bump or check in
on a pull request (it will clutter the discussion of the request).

Also don't be worried if the request is closed or not integrated--sometimes the
priorities of Adafruit's GitHub code (education, ease of use) might not match the
priorities of the pull request.  Don't fret, the open source community thrives on
forks and GitHub makes it easy to keep your changes in a forked repo.

After reviewing the guidelines above you can delete this text from the pull request.


================================================
FILE: .github/workflows/githubci.yml
================================================
name: Arduino Library CI

on: [pull_request, push, repository_dispatch]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/setup-python@v4
      with:
        python-version: '3.x'
    - uses: actions/checkout@v3
    - uses: actions/checkout@v3
      with:
         repository: adafruit/ci-arduino
         path: ci
    
    - name: pre-install
      run: bash ci/actions_install.sh

    - name: test platforms
      run: python3 ci/build_platform.py main_platforms
  clang-format:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/setup-python@v4
      with:
        python-version: '3.x'
    - uses: actions/checkout@v3
    - uses: actions/checkout@v3
      with:
         repository: adafruit/ci-arduino
         path: ci
    
    - name: pre-install
      run: bash ci/actions_install.sh

    - name: clang
      run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 
  doxygen:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    - uses: actions/checkout@v3
      with:
         repository: adafruit/ci-arduino
         path: ci
    
    # The Adafruit doxygen setup is configured to only look for files in the root directory
    - name: move src contents to root
      run: mv -v src/* .

    - name: doxygen
      env:
        GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
        PRETTYNAME : "Adafruit MCP23017 Library"
      run: bash ci/doxy_gen_and_deploy.sh



================================================
FILE: README.md
================================================
# Adafruit MCP23017 Arduino Library [![Build Status](https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-MCP23017-Arduino-Library/html/index.html)

This is a library for the MCP23008/17 I2C and MCP23S08/17 SPI Port Expanders.

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Carter Nelson for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution

To install, use the Arduino IDE Library Manager.

# Pin Addressing

When using single pin operations such as _pinMode(pinId, dir)_ or _digitalRead(pinId)_  or _digitalWrite(pinId, val)_ then the pins are addressed using the ID's below. For example, for set the mode of _GPB0_ then use _pinMode(8, ...)_. **NOTE** The MCP23008 and MCP23S08 only have _GPAx_ pins.

| MCP23x08 Pin # | MCP23x17 Pin # | Pin Name | Pin ID |
| :------------: | :------------: | :------: | :----: |
|       10       |       21       |   GPA0   |   0    |
|       11       |       22       |   GPA1   |   1    |
|       12       |       23       |   GPA2   |   2    |
|       13       |       24       |   GPA3   |   3    |
|       14       |       25       |   GPA4   |   4    |
|       15       |       26       |   GPA5   |   5    |
|       16       |       27       |   GPA6   |   6    |
|       17       |       28       |   GPA7   |   7    |
|       --       |       1        |   GPB0   |   8    |
|       --       |       2        |   GPB1   |   9    |
|       --       |       3        |   GPB2   |   10   |
|       --       |       4        |   GPB3   |   11   |
|       --       |       5        |   GPB4   |   12   |
|       --       |       6        |   GPB5   |   13   |
|       --       |       7        |   GPB6   |   14   |
|       --       |       8        |   GPB7   |   15   |

# Use of HW address pins for SPI device

Library supports MCP23Sxx HW pin addressing (A2, A1, A0 for S17 and A1, A0 for S08)
To use it provide HW address to begin_SPI(CS, SPI, HW_ADDR) function, and as a result each SPI message will contain correct chip address.

Example:
mcp.begin_SPI(10, &SPI, 0b101);

HW Address recognition must be enabled by enableAddrPins() function. **NOTE** Calling enableAddrPins() will enable IOCON.HAEN bit for all active (CS low) devices on SPI bus.
**NOTE**
There is hardware bug in the MCP23S17 chip, see "MCP23S17 Rev. A Silicon Errata".
As a result, if using device with A2 = high, and not using addressing, hw address must be set to 0b1XX
In such case, even if not using addressing, initalize your MCP23S17 chip with 0b1XX address, eg: mcp.begin_SPI(10, &SPI, 0b100);.

# Warning

Some people have reported an undocumented bug that can potentially corrupt the I2C bus.
It occurs if an MCP230XX input pin state changes during I2C readout. **This should be very rare.** For more information, see this [forum post](https://www.microchip.com/forums/m646539.aspx) and this [knowledge base article](https://microchipsupport.force.com/s/article/On-MCP23008-MCP23017-SDA-line-change-when-GPIO7-input-change>).


================================================
FILE: examples/mcp23xxx_blink/mcp23xxx_blink.ino
================================================
// Blinks an LED attached to a MCP23XXX pin.

// ok to include only the one needed
// both included here to make things simple for example
#include <Adafruit_MCP23X08.h>
#include <Adafruit_MCP23X17.h>

#define LED_PIN 0     // MCP23XXX pin LED is attached to

// only used for SPI
#define CS_PIN 6

// uncomment appropriate line
Adafruit_MCP23X08 mcp;
//Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  Serial.println("MCP23xxx Blink Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }

  // configure pin for output
  mcp.pinMode(LED_PIN, OUTPUT);

  Serial.println("Looping...");
}

void loop() {
  mcp.digitalWrite(LED_PIN, HIGH);
  delay(500);
  mcp.digitalWrite(LED_PIN, LOW);
  delay(500);
}

================================================
FILE: examples/mcp23xxx_button/mcp23xxx_button.ino
================================================
// Reads a button attached to a MCP23XXX pin.

// ok to include only the one needed
// both included here to make things simple for example
#include <Adafruit_MCP23X08.h>
#include <Adafruit_MCP23X17.h>

#define BUTTON_PIN 1  // MCP23XXX pin button is attached to

// only used for SPI
#define CS_PIN 6

// uncomment appropriate line
Adafruit_MCP23X08 mcp;
//Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  Serial.println("MCP23xxx Button Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }

  // configure pin for input with pull up
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Looping...");
}

void loop() {
  // LOW = pressed, HIGH = not pressed
  if (!mcp.digitalRead(BUTTON_PIN)) {
    Serial.println("Button Pressed!");
    delay(250);
  }
}

================================================
FILE: examples/mcp23xxx_combo/mcp23xxx_combo.ino
================================================
// Controls an LED via an attached button.

// ok to include only the one needed
// both included here to make things simple for example
#include <Adafruit_MCP23X08.h>
#include <Adafruit_MCP23X17.h>

#define LED_PIN 0     // MCP23XXX pin LED is attached to
#define BUTTON_PIN 1  // MCP23XXX pin button is attached to

// only used for SPI
#define CS_PIN 6

// uncomment appropriate line
Adafruit_MCP23X08 mcp;
//Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  Serial.println("MCP23xxx Combo Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }

  // configure LED pin for output
  mcp.pinMode(LED_PIN, OUTPUT);

  // configure button pin for input with pull up
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Looping...");
}

void loop() {
  mcp.digitalWrite(LED_PIN, !mcp.digitalRead(BUTTON_PIN));
}

================================================
FILE: examples/mcp23xxx_interrupt/mcp23xxx_interrupt.ino
================================================
// NOTE: This is a simple example that only reads the INTA or INTB pin
//       state. No actual interrupts are used on the host microcontroller.
//       MCP23XXX supports the following interrupt modes:
//           * CHANGE - interrupt occurs if pin changes to opposite state
//           * LOW - interrupt occurs while pin state is LOW
//           * HIGH - interrupt occurs while pin state is HIGH

// ok to include only the one needed
// both included here to make things simple for example
#include <Adafruit_MCP23X08.h>
#include <Adafruit_MCP23X17.h>

#define BUTTON_PIN 1   // MCP23XXX pin used for interrupt

#define INT_PIN 7      // microcontroller pin attached to INTA/B

// only used for SPI
#define CS_PIN 6

// uncomment appropriate line
Adafruit_MCP23X08 mcp;
//Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  Serial.println("MCP23xxx Interrupt Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }

  // configure MCU pin that will read INTA/B state
  pinMode(INT_PIN, INPUT);

  // OPTIONAL - call this to override defaults
  // mirror INTA/B so only one wire required
  // active drive so INTA/B will not be floating
  // INTA/B will be signaled with a LOW
  mcp.setupInterrupts(true, false, LOW);

  // configure button pin for input with pull up
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);

  // enable interrupt on button_pin
  mcp.setupInterruptPin(BUTTON_PIN, LOW);

  Serial.println("Looping...");
}

void loop() {
  if (!digitalRead(INT_PIN)) {
    Serial.print("Interrupt detected on pin: ");
    Serial.println(mcp.getLastInterruptPin());
    Serial.print("Pin states at time of interrupt: 0b");
    Serial.println(mcp.getCapturedInterrupt(), 2);
    delay(250);  // debounce
    // NOTE: If using DEFVAL, INT clears only if interrupt
    // condition does not exist.
    // See Fig 1-7 in datasheet.
    mcp.clearInterrupts();  // clear
  }
}

================================================
FILE: keywords.txt
================================================
#######################################
# Syntax Coloring Map for MCP23017
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

Adafruit_MCP23X08	KEYWORD1
Adafruit_MCP23X17	KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin_I2C	KEYWORD2
begin_SPI	KEYWORD2
configureInterrupt	KEYWORD2
enableInterrupt	KEYWORD2
disableInterrupt	KEYWORD2
getLastInterruptPin	KEYWORD2
writeGPIO	KEYWORD2
readGPIO	KEYWORD2
writeGPIOA	KEYWORD2
readGPIOA	KEYWORD2
writeGPIOB	KEYWORD2
readGPIOB	KEYWORD2
writeGPIOAB	KEYWORD2
readGPIOAB	KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################


================================================
FILE: library.properties
================================================
name=Adafruit MCP23017 Arduino Library
version=2.3.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Arduino Library for MCP23XXX I2C and SPI GPIO port expanders
paragraph=Arduino Library for MCP23008, MCP23S08, MCP23017, and MCP23S17 I2C and SPI GPIO port expanders
category=Signal Input/Output
url=https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
architectures=*
depends=Adafruit BusIO


================================================
FILE: license.txt
================================================
Software License Agreement (BSD License)

Copyright (c) 2012, Adafruit Industries
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: src/Adafruit_MCP23X08.cpp
================================================
/*!
 * @file Adafruit_MCP23X08.cpp
 */

#include "Adafruit_MCP23X08.h"

/**************************************************************************/
/*!
  @brief default ctor.
*/
/**************************************************************************/
Adafruit_MCP23X08::Adafruit_MCP23X08() { pinCount = 8; }

/**************************************************************************/
/*!
  @brief Enable usage of HW address pins (A0, A1) on MCP23S08

  Send this message as first message after chip init.

  By default HW address pins are disabled.
  (Register IOCON, bit HAEN = 0 on chip reset)
*/
/**************************************************************************/
void Adafruit_MCP23X08::enableAddrPins() {
  if (!spi_dev) // I2C dev always use addr, only makes sense for SPI dev
    return;

  Adafruit_BusIO_Register GPIOAddr(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                   getRegister(MCP23XXX_IOCON, 0), 2);

  GPIOAddr.write((1 << 3), 1);
}

================================================
FILE: src/Adafruit_MCP23X08.h
================================================
/*!
 * @file Adafruit_MCP23X08.h
 */

#ifndef __ADAFRUIT_MCP23X08_H__
#define __ADAFRUIT_MCP23X08_H__

#include "Adafruit_MCP23XXX.h"

/**************************************************************************/
/*!
    @brief  Class for MCP23008 I2C and MCP23S08 SPI variants.
*/
/**************************************************************************/
class Adafruit_MCP23X08 : public Adafruit_MCP23XXX {
public:
  Adafruit_MCP23X08();

  void enableAddrPins();
};

#endif

================================================
FILE: src/Adafruit_MCP23X17.cpp
================================================
/*!
 * @file Adafruit_MCP23X17.cpp
 */

#include "Adafruit_MCP23X17.h"

/**************************************************************************/
/*!
  @brief default ctor.
*/
/**************************************************************************/
Adafruit_MCP23X17::Adafruit_MCP23X17() { pinCount = 16; }

/**************************************************************************/
/*!
  @brief Bulk read all pins on Port A.
  @returns current pin states of port as a uint8_t.
*/
/**************************************************************************/
uint8_t Adafruit_MCP23X17::readGPIOA() { return readGPIO(0); }

/**************************************************************************/
/*!
  @brief Bulk write all pins on Port A.
  @param value pin states to write as uint8_t.
*/
/**************************************************************************/
void Adafruit_MCP23X17::writeGPIOA(uint8_t value) { writeGPIO(value, 0); }

/**************************************************************************/
/*!
  @brief Bulk read all pins on Port B.
  @returns current pin states of port as a uint8_t.
*/
/**************************************************************************/
uint8_t Adafruit_MCP23X17::readGPIOB() { return readGPIO(1); }

/**************************************************************************/
/*!
  @brief Bulk write all pins on Port B.
  @param value pin states to write as uint8_t.
*/
/**************************************************************************/
void Adafruit_MCP23X17::writeGPIOB(uint8_t value) { writeGPIO(value, 1); }

/**************************************************************************/
/*!
  @brief Bulk read all pins on Port A and B.
  @returns current pin states of ports as a uint16_t.
*/
/**************************************************************************/
uint16_t Adafruit_MCP23X17::readGPIOAB() {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, 0), 2);
  return GPIO.read();
}

/**************************************************************************/
/*!
  @brief Bulk write all pins on Port A and Port B.
  @param value pin states to write as uint16_t.
*/
/**************************************************************************/
void Adafruit_MCP23X17::writeGPIOAB(uint16_t value) {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, 0), 2);
  GPIO.write(value, 2);
}

/**************************************************************************/
/*!
  @brief Enable usage of HW address pins (A0, A1, A2) on MCP23S17

  Send this message as first message after chip init, as it will
  set bits in IOCON register to default (except HAEN)
  By default pins are not used and disabled (see README for details)
  This message is sent to all devices on bus (no hw_addr is added to msg
  as it's not enabled yet)
  Due to HW bug in the chip message must be sent twice (to addr 0b000 and
  0b1xx)
*/
/**************************************************************************/
void Adafruit_MCP23X17::enableAddrPins() {
  if (!spi_dev) // I2C dev always use addr, only makes sense for SPI dev
    return;

  Adafruit_BusIO_Register GPIOAddr(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                   getRegister(MCP23XXX_IOCON, 0), 2);

  // Send message to address 0b000 regardless of chip addr,
  // Because addressing is not yet enabled
  uint8_t tmp = this->hw_addr;
  this->hw_addr = 0; // Temporary set hw addr to 0
  Adafruit_BusIO_Register GPIONoAddr(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                     getRegister(MCP23XXX_IOCON, 0), 2);
  this->hw_addr = tmp;

  GPIONoAddr.write((1 << 3), 1); // Bit3: HAEN, devices with A2 = 0
  GPIOAddr.write((1 << 3), 1);   // Devices with A2 = 1 (if any)
}

================================================
FILE: src/Adafruit_MCP23X17.h
================================================
/*!
 * @file Adafruit_MCP23X17.h
 */

#ifndef __ADAFRUIT_MCP23X17_H__
#define __ADAFRUIT_MCP23X17_H__

#include "Adafruit_MCP23XXX.h"

/**************************************************************************/
/*!
    @brief  Class for MCP23017 I2C and MCP23S17 SPI variants.
*/
/**************************************************************************/
class Adafruit_MCP23X17 : public Adafruit_MCP23XXX {
public:
  Adafruit_MCP23X17();

  uint8_t readGPIOA();
  void writeGPIOA(uint8_t value);
  uint8_t readGPIOB();
  void writeGPIOB(uint8_t value);
  uint16_t readGPIOAB();
  void writeGPIOAB(uint16_t value);
  void enableAddrPins();
};

#endif

================================================
FILE: src/Adafruit_MCP23XXX.cpp
================================================
/*!
 * @file Adafruit_MCP23XXX.cpp
 *
 * @mainpage Adafruit MCP23X08/17 Library
 *
 * @section intro_sec Introduction
 *
 * This is a library for the MCP23008/17 I2C and MCP23S08/17 SPI port
 * expanders.
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 * @section author Author
 *
 * Written by Carter Nelson for Adafruit Industries.
 *
 * @section license License
 *
 * BSD license, all text above must be included in any redistribution
 */

#include "Adafruit_MCP23XXX.h"

/**************************************************************************/
/*!
  @brief Initialize MCP using I2C.
  @param i2c_addr I2C address
  @param wire Pointer to Wire instance
  @return true if initialization successful, otherwise false.
*/
/**************************************************************************/
bool Adafruit_MCP23XXX::begin_I2C(uint8_t i2c_addr, TwoWire *wire) {
  i2c_dev = new Adafruit_I2CDevice(i2c_addr, wire);
  return i2c_dev->begin();
}

/**************************************************************************/
/*!
  @brief Initialize MCP using hardware SPI.
  @param cs_pin Pin to use for SPI chip select
  @param theSPI Pointer to SPI instance
  @param _hw_addr Hardware address (pins A2, A1, A0)
  @return true if initialization successful, otherwise false.
*/
/**************************************************************************/
bool Adafruit_MCP23XXX::begin_SPI(uint8_t cs_pin, SPIClass *theSPI,
                                  uint8_t _hw_addr) {
  this->hw_addr = _hw_addr;
  spi_dev = new Adafruit_SPIDevice(cs_pin, 1000000, SPI_BITORDER_MSBFIRST,
                                   SPI_MODE0, theSPI);
  return spi_dev->begin();
}

/**************************************************************************/
/*!
  @brief Initialize MCP using software SPI.
  @param cs_pin Pin to use for SPI chip select
  @param sck_pin Pin to use for SPI clock
  @param miso_pin Pin to use for SPI MISO
  @param mosi_pin Pin to use for SPI MOSI
  @param _hw_addr Hardware address (pins A2, A1, A0)
  @return true if initialization successful, otherwise false.
*/
/**************************************************************************/
bool Adafruit_MCP23XXX::begin_SPI(int8_t cs_pin, int8_t sck_pin,
                                  int8_t miso_pin, int8_t mosi_pin,
                                  uint8_t _hw_addr) {
  this->hw_addr = _hw_addr;
  spi_dev = new Adafruit_SPIDevice(cs_pin, sck_pin, miso_pin, mosi_pin);
  return spi_dev->begin();
}

/**************************************************************************/
/*!
  @brief Configures the specified pin to behave either as an input or an
  output.
  @param pin the Arduino pin number to set the mode of
  @param mode INPUT, OUTPUT, or INPUT_PULLUP
*/
/**************************************************************************/
void Adafruit_MCP23XXX::pinMode(uint8_t pin, uint8_t mode) {
  Adafruit_BusIO_Register IODIR(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                getRegister(MCP23XXX_IODIR, MCP_PORT(pin)));
  Adafruit_BusIO_Register GPPU(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPPU, MCP_PORT(pin)));
  Adafruit_BusIO_RegisterBits dir_bit(&IODIR, 1, pin % 8);
  Adafruit_BusIO_RegisterBits pullup_bit(&GPPU, 1, pin % 8);

  dir_bit.write((mode == OUTPUT) ? 0 : 1);
  pullup_bit.write((mode == INPUT_PULLUP) ? 1 : 0);
}

/**************************************************************************/
/*!
  @brief Reads the value from a specified digital pin, either HIGH or LOW.
  @param pin the Arduino pin number you want to read
  @returns HIGH or LOW
*/
/**************************************************************************/
uint8_t Adafruit_MCP23XXX::digitalRead(uint8_t pin) {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, MCP_PORT(pin)));
  Adafruit_BusIO_RegisterBits pin_bit(&GPIO, 1, pin % 8);

  return ((pin_bit.read() == 0) ? LOW : HIGH);
}

/**************************************************************************/
/*!
  @brief Write a HIGH or a LOW value to a digital pin.
  @param pin the Arduino pin number
  @param value HIGH or LOW
*/
/**************************************************************************/
void Adafruit_MCP23XXX::digitalWrite(uint8_t pin, uint8_t value) {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, MCP_PORT(pin)));
  Adafruit_BusIO_RegisterBits pin_bit(&GPIO, 1, pin % 8);

  pin_bit.write((value == LOW) ? 0 : 1);
}

/**************************************************************************/
/*!
  @brief Bulk read all pins on a port.
  @param port 0 for Port A, 1 for Port B (MCP23X17 only).
  @returns current pin states of port as a uint8_t.
*/
/**************************************************************************/
uint8_t Adafruit_MCP23XXX::readGPIO(uint8_t port) {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, port));
  return GPIO.read() & 0xFF;
}

/**************************************************************************/
/*!
  @brief Bulk write all pins on a port.
  @param value pin states to write as a uint8_t.
  @param port 0 for Port A, 1 for Port B (MCP23X17 only).
*/
/**************************************************************************/
void Adafruit_MCP23XXX::writeGPIO(uint8_t value, uint8_t port) {
  Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                               getRegister(MCP23XXX_GPIO, port));
  GPIO.write(value);
}

/**************************************************************************/
/*!
  @brief Configure the interrupt system.
  @param mirroring true to OR both INTA and INTB pins.
  @param openDrain true for open drain output, false for active drive output.
  @param polarity HIGH or LOW
*/
/**************************************************************************/
void Adafruit_MCP23XXX::setupInterrupts(bool mirroring, bool openDrain,
                                        uint8_t polarity) {
  Adafruit_BusIO_Register IOCON(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                getRegister(MCP23XXX_IOCON));
  Adafruit_BusIO_RegisterBits mirror_bit(&IOCON, 1, 6);
  Adafruit_BusIO_RegisterBits openDrain_bit(&IOCON, 1, 2);
  Adafruit_BusIO_RegisterBits polarity_bit(&IOCON, 1, 1);

  mirror_bit.write(mirroring ? 1 : 0);
  openDrain_bit.write(openDrain ? 1 : 0);
  polarity_bit.write((polarity == HIGH) ? 1 : 0);
}

/**************************************************************************/
/*!
  @brief Enable interrupt and set mode for given pin.
  @param pin Pin to enable.
  @param mode CHANGE, LOW, HIGH
*/
/**************************************************************************/
void Adafruit_MCP23XXX::setupInterruptPin(uint8_t pin, uint8_t mode) {
  Adafruit_BusIO_Register GPINTEN(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                  getRegister(MCP23XXX_GPINTEN, MCP_PORT(pin)));
  Adafruit_BusIO_Register INTCON(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                 getRegister(MCP23XXX_INTCON, MCP_PORT(pin)));
  Adafruit_BusIO_Register DEFVAL(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                 getRegister(MCP23XXX_DEFVAL, MCP_PORT(pin)));
  Adafruit_BusIO_RegisterBits enable_bit(&GPINTEN, 1, pin % 8);
  Adafruit_BusIO_RegisterBits config_bit(&INTCON, 1, pin % 8);
  Adafruit_BusIO_RegisterBits defval_bit(&DEFVAL, 1, pin % 8);

  enable_bit.write(1);                        // enable it
  config_bit.write((mode == CHANGE) ? 0 : 1); // set mode
  defval_bit.write((mode == LOW) ? 1 : 0);    // set defval
}

/**************************************************************************/
/*!
  @brief Disable interrupt for given pin.
  @param pin Pin to disable.
*/
/**************************************************************************/
void Adafruit_MCP23XXX::disableInterruptPin(uint8_t pin) {
  Adafruit_BusIO_Register GPINTEN(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                  getRegister(MCP23XXX_GPINTEN, MCP_PORT(pin)));
  Adafruit_BusIO_RegisterBits enable_bit(&GPINTEN, 1, pin % 8);

  enable_bit.write(0);
}

/**************************************************************************/
/*!
  @brief Clear interrupts. NOTE:If using DEFVAL, INT clears only if interrupt
  condition does not exist. See Fig 1-7 in datasheet.
*/
/**************************************************************************/
void Adafruit_MCP23XXX::clearInterrupts() {
  // reading INTCAP register(s) clears interrupts
  // just call this and ignore return
  getCapturedInterrupt();
}

/**************************************************************************/
/*!
  @brief Gets the pin that caused the latest interrupt, from INTF, without
  clearing any interrupt flags.
  @returns Pin that caused lastest interrupt.
*/
/**************************************************************************/
uint8_t Adafruit_MCP23XXX::getLastInterruptPin() {
  uint8_t intf;

  // Port A
  Adafruit_BusIO_Register INTFA(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                getRegister(MCP23XXX_INTF, 0));
  INTFA.read(&intf);
  for (uint8_t pin = 0; pin < 8; pin++) {
    if (intf & (1 << pin)) {
      return pin;
    }
  }

  // Port B ?
  if (pinCount > 8) {
    Adafruit_BusIO_Register INTFB(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                  getRegister(MCP23XXX_INTF, 1));
    INTFB.read(&intf);
    for (uint8_t pin = 0; pin < 8; pin++) {
      if (intf & (1 << pin)) {
        return pin + 8;
      }
    }
  }

  return MCP23XXX_INT_ERR;
}

/**************************************************************************/
/*!
  @brief Get pin states captured at time of interrupt.
  @returns Mutli-bit value representing pin states.
*/
/**************************************************************************/
uint16_t Adafruit_MCP23XXX::getCapturedInterrupt() {
  uint16_t intcap;
  uint8_t intf;

  // Port A
  Adafruit_BusIO_Register INTCAPA(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                  getRegister(MCP23XXX_INTCAP, 0));
  INTCAPA.read(&intf);
  intcap = intf;

  // Port B ?
  if (pinCount > 8) {
    Adafruit_BusIO_Register INTCAPB(i2c_dev, spi_dev, MCP23XXX_SPIREG,
                                    getRegister(MCP23XXX_INTCAP, 1));
    INTCAPB.read(&intf);
    intcap |= (uint16_t)intf << 8;
  }

  return intcap;
}

/**************************************************************************/
/*!
  @brief helper to get register address
  @param baseAddress base register address
  @param port 0 for A, 1 for B (MCP23X17 only)
  @returns calculated register address
*/
/**************************************************************************/
uint16_t Adafruit_MCP23XXX::getRegister(uint8_t baseAddress, uint8_t port) {
  // MCP23x08
  uint16_t reg = baseAddress;
  // MCP23x17 BANK=0
  if (pinCount > 8) {
    reg <<= 1;
    reg |= port;
  }
  // for SPI, add opcode as high byte
  return (spi_dev) ? (0x4000 | (hw_addr << 9) | reg) : reg;
}


================================================
FILE: src/Adafruit_MCP23XXX.h
================================================
/*!
 * @file Adafruit_MCP23XXX.h
 */

#ifndef __ADAFRUIT_MCP23XXX_H__
#define __ADAFRUIT_MCP23XXX_H__

#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
#include <Arduino.h>

// registers
#define MCP23XXX_IODIR 0x00   //!< I/O direction register
#define MCP23XXX_IPOL 0x01    //!< Input polarity register
#define MCP23XXX_GPINTEN 0x02 //!< Interrupt-on-change control register
#define MCP23XXX_DEFVAL                                                        \
  0x03 //!< Default compare register for interrupt-on-change
#define MCP23XXX_INTCON 0x04 //!< Interrupt control register
#define MCP23XXX_IOCON 0x05  //!< Configuration register
#define MCP23XXX_GPPU 0x06   //!< Pull-up resistor configuration register
#define MCP23XXX_INTF 0x07   //!< Interrupt flag register
#define MCP23XXX_INTCAP 0x08 //!< Interrupt capture register
#define MCP23XXX_GPIO 0x09   //!< Port register
#define MCP23XXX_OLAT 0x0A   //!< Output latch register

#define MCP23XXX_ADDR 0x20 //!< Default I2C Address
#define MCP23XXX_SPIREG                                                        \
  ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE //!< SPI register type

#define MCP_PORT(pin) ((pin < 8) ? 0 : 1) //!< Determine port from pin number

#define MCP23XXX_INT_ERR 255 //!< Interrupt error

/**************************************************************************/
/*!
    @brief  Base class for all MCP23XXX variants.
*/
/**************************************************************************/
class Adafruit_MCP23XXX {
public:
  // init
  bool begin_I2C(uint8_t i2c_addr = MCP23XXX_ADDR, TwoWire *wire = &Wire);
  bool begin_SPI(uint8_t cs_pin, SPIClass *theSPI = &SPI,
                 uint8_t _hw_addr = 0x00);
  bool begin_SPI(int8_t cs_pin, int8_t sck_pin, int8_t miso_pin,
                 int8_t mosi_pin, uint8_t _hw_addr = 0x00);

  // main Arduino API methods
  void pinMode(uint8_t pin, uint8_t mode);
  uint8_t digitalRead(uint8_t pin);
  void digitalWrite(uint8_t pin, uint8_t value);

  // bulk access
  uint8_t readGPIO(uint8_t port = 0);
  void writeGPIO(uint8_t value, uint8_t port = 0);

  // interrupts
  void setupInterrupts(bool mirroring, bool openDrain, uint8_t polarity);
  void setupInterruptPin(uint8_t pin, uint8_t mode = CHANGE);
  void disableInterruptPin(uint8_t pin);
  void clearInterrupts();
  uint8_t getLastInterruptPin();
  uint16_t getCapturedInterrupt();

protected:
  Adafruit_I2CDevice *i2c_dev = nullptr; ///< Pointer to I2C bus interface
  Adafruit_SPIDevice *spi_dev = nullptr; ///< Pointer to SPI bus interface
  uint8_t pinCount;                      ///< Total number of GPIO pins
  uint8_t hw_addr;                       ///< HW address matching A2/A1/A0 pins
  uint16_t getRegister(uint8_t baseAddress, uint8_t port = 0);

private:
  uint8_t buffer[4];
};

#endif
Download .txt
gitextract_3qygkpm0/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       └── githubci.yml
├── README.md
├── examples/
│   ├── mcp23xxx_blink/
│   │   └── mcp23xxx_blink.ino
│   ├── mcp23xxx_button/
│   │   └── mcp23xxx_button.ino
│   ├── mcp23xxx_combo/
│   │   └── mcp23xxx_combo.ino
│   └── mcp23xxx_interrupt/
│       └── mcp23xxx_interrupt.ino
├── keywords.txt
├── library.properties
├── license.txt
└── src/
    ├── Adafruit_MCP23X08.cpp
    ├── Adafruit_MCP23X08.h
    ├── Adafruit_MCP23X17.cpp
    ├── Adafruit_MCP23X17.h
    ├── Adafruit_MCP23XXX.cpp
    └── Adafruit_MCP23XXX.h
Download .txt
SYMBOL INDEX (3 symbols across 3 files)

FILE: src/Adafruit_MCP23X08.h
  function class (line 15) | class Adafruit_MCP23X08 : public Adafruit_MCP23XXX {

FILE: src/Adafruit_MCP23X17.h
  function class (line 15) | class Adafruit_MCP23X17 : public Adafruit_MCP23XXX {

FILE: src/Adafruit_MCP23XXX.h
  function class (line 40) | class Adafruit_MCP23XXX {
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (38K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 2624,
    "preview": "Thank you for opening an issue on an Adafruit Arduino library repository.  To\nimprove the speed of resolution please rev"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1415,
    "preview": "Thank you for creating a pull request to contribute to Adafruit's GitHub code!\nBefore you open the request please review"
  },
  {
    "path": ".github/workflows/githubci.yml",
    "chars": 1446,
    "preview": "name: Arduino Library CI\n\non: [pull_request, push, repository_dispatch]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    \n"
  },
  {
    "path": "README.md",
    "chars": 3406,
    "preview": "# Adafruit MCP23017 Arduino Library [![Build Status](https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/workf"
  },
  {
    "path": "examples/mcp23xxx_blink/mcp23xxx_blink.ino",
    "chars": 836,
    "preview": "// Blinks an LED attached to a MCP23XXX pin.\n\n// ok to include only the one needed\n// both included here to make things "
  },
  {
    "path": "examples/mcp23xxx_button/mcp23xxx_button.ino",
    "chars": 901,
    "preview": "// Reads a button attached to a MCP23XXX pin.\n\n// ok to include only the one needed\n// both included here to make things"
  },
  {
    "path": "examples/mcp23xxx_combo/mcp23xxx_combo.ino",
    "chars": 951,
    "preview": "// Controls an LED via an attached button.\n\n// ok to include only the one needed\n// both included here to make things si"
  },
  {
    "path": "examples/mcp23xxx_interrupt/mcp23xxx_interrupt.ino",
    "chars": 2006,
    "preview": "// NOTE: This is a simple example that only reads the INTA or INTB pin\n//       state. No actual interrupts are used on "
  },
  {
    "path": "keywords.txt",
    "chars": 797,
    "preview": "#######################################\n# Syntax Coloring Map for MCP23017\n#######################################\n\n####"
  },
  {
    "path": "library.properties",
    "chars": 418,
    "preview": "name=Adafruit MCP23017 Arduino Library\nversion=2.3.2\nauthor=Adafruit\nmaintainer=Adafruit <info@adafruit.com>\nsentence=Ar"
  },
  {
    "path": "license.txt",
    "chars": 1499,
    "preview": "Software License Agreement (BSD License)\n\nCopyright (c) 2012, Adafruit Industries\nAll rights reserved.\n\nRedistribution a"
  },
  {
    "path": "src/Adafruit_MCP23X08.cpp",
    "chars": 986,
    "preview": "/*!\n * @file Adafruit_MCP23X08.cpp\n */\n\n#include \"Adafruit_MCP23X08.h\"\n\n/***********************************************"
  },
  {
    "path": "src/Adafruit_MCP23X08.h",
    "chars": 478,
    "preview": "/*!\n * @file Adafruit_MCP23X08.h\n */\n\n#ifndef __ADAFRUIT_MCP23X08_H__\n#define __ADAFRUIT_MCP23X08_H__\n\n#include \"Adafrui"
  },
  {
    "path": "src/Adafruit_MCP23X17.cpp",
    "chars": 3886,
    "preview": "/*!\n * @file Adafruit_MCP23X17.cpp\n */\n\n#include \"Adafruit_MCP23X17.h\"\n\n/***********************************************"
  },
  {
    "path": "src/Adafruit_MCP23X17.h",
    "chars": 653,
    "preview": "/*!\n * @file Adafruit_MCP23X17.h\n */\n\n#ifndef __ADAFRUIT_MCP23X17_H__\n#define __ADAFRUIT_MCP23X17_H__\n\n#include \"Adafrui"
  },
  {
    "path": "src/Adafruit_MCP23XXX.cpp",
    "chars": 11280,
    "preview": "/*!\n * @file Adafruit_MCP23XXX.cpp\n *\n * @mainpage Adafruit MCP23X08/17 Library\n *\n * @section intro_sec Introduction\n *"
  },
  {
    "path": "src/Adafruit_MCP23XXX.h",
    "chars": 2838,
    "preview": "/*!\n * @file Adafruit_MCP23XXX.h\n */\n\n#ifndef __ADAFRUIT_MCP23XXX_H__\n#define __ADAFRUIT_MCP23XXX_H__\n\n#include <Adafrui"
  }
]

About this extraction

This page contains the full source code of the adafruit/Adafruit-MCP23017-Arduino-Library GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (35.6 KB), approximately 9.5k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!