2 releases
0.1.1 | Jul 20, 2024 |
---|---|
0.1.0 | Jul 19, 2024 |
#348 in Embedded development
95KB
2K
SLoC
mcp23017
16-Bit I/O Expander with Serial Interface
mcp23017 Datasheet
Description
This crate was made for and tested on MCP23017 from Microchip, it is based on I2C from embedded-hal crate. The implementation of this crate is based on #![no_std] but with some minor adjustments it can be used on std environments.
This driver allows you to:
- choose operating mode: (1x16bit), (2x8bit) or (16x1bit)
- configure interrupts
- enable or disable interrupts
- set internall pull resistor
- read or write to pin/port/chip dependiong on the mode choosen
NOTE: When operating in 16bit mode, use LittleEndian formatting (0xbbaa).
Version Revision
0.1.0 - First Version
0.1.1 - Fixed doc generation, fixed async support in traits, improved prelude for feature usage, fixed endianess for interrupt functions
Features
features = ["async"] - enables support for async Rust (Currently embedded_hal_bus does not implement async for I2C, therefore if using more than one pin/port, disable the async feature)
features = ["chipmode"] - The driver operates as a 1x 16bit device set entirely as output or input
features = ["portmode"] - The driver operates as a 2x 8bit port device, each port is configured individually
features = ["pinmode"] - The driver operates as a 16x 1bit pins device, each pin is configured individually
ATTENTION: ENABLE ONLY ONE OF THE MODES OR FACE THE CONSEQUENCES.... ASYNC CAN BE USED ON ANY MODE
Example
To use the driver, you must have a concrete implementation of the embedded-hal traits. This example uses stm32f4xx-hal:
When using chipmode, the driver will operate in 16bit, the code below will set all pins to output:
use core::cell::RefCell;
use embedded_hal_bus::i2c;
use mcp23017_tp::prelude::*;
let mut i2c = dp.I2C1.i2c(
(scl, sda),
Mode::Standard {
frequency: 100.kHz(),
},
&clocks,
);
let i2c_ref_cell = RefCell::new(i2c);
let mut mcp = mcp23017_tp::MCP23017::new(i2c::RefCellDevice::new(&i2c_ref_cell), address)
.set_as_output()
.unwrap();
loop {
mcp.write(0xbbaa).unwrap();
delay.delay_ms(2000);
// u16: 0xbbaa - u8[]: [0]aa [1]bb (LittleEndian)
mcp.write(0x0000).unwrap();
delay.delay_ms(2000);
}
When using portmode, the driver will operate in 2x8bit, the code below will set port A as output and port B as input:
use core::cell::RefCell;
use embedded_hal_bus::i2c;
use mcp23017_tp::prelude::*;
let mut i2c = dp.I2C1.i2c(
(scl, sda),
Mode::Standard {
frequency: 100.kHz(),
},
&clocks,
);
let i2c_ref_cell = RefCell::new(i2c);
let mut porta = mcp23017_tp::PortA::new(i2c::RefCellDevice::new(&i2c_ref_cell), address)
.set_as_output()
.unwrap();
let mut portb = mcp23017_tp::PortB::new(i2c::RefCellDevice::new(&i2c_ref_cell), address)
.set_as_input()
.unwrap()
.set_pull(PinSet::High)
.unwrap()
.ready();
loop {
porta.write(0xff).unwrap();
delay.delay_ms(2000);
porta.write(0x00).unwrap();
delay.delay_ms(2000);
rprintln!("{:#02x}", portb.read().unwrap());
}
When using pinmode, the driver will operate in 16x1bit, the code below will set pin A1 and pin B3 as input:
use core::cell::RefCell;
use embedded_hal_bus::i2c;
use mcp23017_tp::prelude::*;
let mut i2c = dp.I2C1.i2c(
(scl, sda),
Mode::Standard {
frequency: 100.kHz(),
},
&clocks,
);
let i2c_ref_cell = RefCell::new(i2c);
let mut pina1 = mcp23017_tp::Pina1::new(i2c::RefCellDevice::new(&i2c_ref_cell), address)
.set_as_input()
.unwrap()
.set_pull(PinSet::High)
.unwrap()
.ready();
let mut pinb3 = mcp23017_tp::Pinb3::new(i2c::RefCellDevice::new(&i2c_ref_cell), address)
.set_as_input()
.unwrap()
.set_pull(PinSet::High)
.unwrap()
.ready();
loop {
delay.delay_ms(2000);
rprintln!(
"{:#02x} {:#02x}",
pina1.read().unwrap(),
pinb3.read().unwrap()
);
}
License
Licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~2MB
~40K SLoC