#raspberry-pi #spi-driver #spi-interface #rppal #16-bit #hardware-interface #mcp23s17

rppal-mcp23s17

MCP23S17 driver An experimental driver for the MCP23S17 16 bit I/O expander chip addressed over the SPI bus on Raspbery Pi peripherals, such as the PiFace Digital HAT. Requires RPPAL for the SPI interface.

5 releases

0.1.0 Aug 19, 2024
0.0.4 Aug 6, 2024
0.0.3 Jan 19, 2023
0.0.2 Nov 14, 2022
0.0.1 Nov 11, 2022

#175 in Hardware support

Download history 2/week @ 2024-07-24 79/week @ 2024-07-31 56/week @ 2024-08-07 137/week @ 2024-08-14 67/week @ 2024-08-21 10/week @ 2024-08-28 32/week @ 2024-09-11 17/week @ 2024-09-18 19/week @ 2024-09-25 20/week @ 2024-10-02 37/week @ 2024-10-23

62 downloads per month
Used in rppal-pfd

MIT license

87KB
2K SLoC

MCP23S17 driver

Crates.io Crates.io Crates.io GitHub Workflow Status

A driver for the MCP23S17 I/O expander which is accessed over an SPI bus. Note that this driver depends on RPPAL and is therefore specific to the Raspberry Pi.

Example usage

use rppal_mcp23s17::{ChipSelect, HardwareAddress, Level, Mcp23s17, Port, RegisterAddress, SpiBus, SpiMode};

// Create an instance of the driver for the device with the hardware address
// (A2, A1, A0) of 0b000.
let mcp23s17 = Mcp23s17::new(
    HardwareAddress::new(0).expect("Invalid hardware address"),
    SpiBus::Spi0,
    ChipSelect::Cs0,
    100_000,
    SpiMode::Mode0,
)
.expect("Failed to create MCP23S17");

// Take ownership of the pin on bit 4 of GPIOA and then convert it into an
// OutputPin. Initialisation of the OutputPin ensures that the MCP23S17
// registers (e.g. IODIRA) are set accordingly.
let pin = mcp23s17
    .get(Port::GpioA, 4)
    .expect("Failed to get Pin")
    .into_output_pin()
    .expect("Failed to convert to OutputPin");

// Set the pin to logic-level low.
pin.write(Level::Low).expect("Bad pin write");

Concurrency Warning

Note that the rppal::spi::Spi contained in the Mcp23s17 is !Send so that the device can only be used within the context of a single thread. However, there is nothing to stop separate instances on separate threads accessing the same MCP23S17. We could possibly do something smarter to enforce uniqueness of [Pin]s between threads but currently it is down to the user to ensure if multiple instances are in use they don't tread on each other's toes!

Indeed, there is nothing to stop separate processes accessing the MCP23S17 over the SPI bus at the same time and given that many bit-flipping operations are implemented as a read-modify-write on the relevant registers there are huge windows for race hazards between processes/threads. Clearly much more reliable for everyone if a single process "owns" the MCP23S17 device and a single thread within that process instantiates a singleton Mcp23s17 object.

Acknowledgements

Many of the documentation comments in this library are taken direct from the MCP23S17 datasheet and are © 2005-2022 Microchip Technology Inc. and its subsidiaries.

This library not only uses, but has also taken a lot of inspiration from, the RPPAL crate.

Dependencies

~0.7–1.3MB
~28K SLoC