FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
mcp23008.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
21#ifndef MCP23008_H
22#define MCP23008_H
23
24#include "mcp230xx.h"
25#include "../functors.h"
26#include "../i2c_device.h"
27#include "../i2c_device_utilities.h"
28
30{
39 template<typename MANAGER>
40 class MCP23008 : public i2c::I2CDevice<MANAGER>
41 {
42 private:
44
45 // Forward declarations needed by compiler
46 template<uint8_t REGISTER, typename T = uint8_t, typename FUNCTOR = functor::Identity<T>>
48 template<uint8_t REGISTER, typename T = uint8_t, typename FUNCTOR = functor::Identity<T>>
50 template<typename T, uint8_t... REGISTERS>
52
53 static constexpr uint8_t compute_address(uint8_t address)
54 {
55 return uint8_t((uint8_t(BASE_ADDRESS) | uint8_t(address & 0x07U)) << 1);
56 }
57
58 // Base address of the device (actual address can be in 0x20-0x27)
59 static constexpr const uint8_t BASE_ADDRESS = 0x20;
60
61 // All registers addresses
62 static constexpr const uint8_t IODIR = 0x00;
63 static constexpr const uint8_t IPOL = 0x01;
64
65 static constexpr const uint8_t GPINTEN = 0x02;
66 static constexpr const uint8_t DEFVAL = 0x03;
67 static constexpr const uint8_t INTCON = 0x04;
68
69 static constexpr const uint8_t IOCON = 0x05;
70
71 static constexpr const uint8_t GPPU = 0x06;
72
73 static constexpr const uint8_t INTF = 0x07;
74 static constexpr const uint8_t INTCAP = 0x08;
75
76 static constexpr const uint8_t GPIO = 0x09;
77 static constexpr const uint8_t OLAT = 0x0A;
78
79 // IOCON bits (not all are used in this implementation)
80 static constexpr const uint8_t IOCON_SEQOP = bits::BV8(5);
81 static constexpr const uint8_t IOCON_DISSLW = bits::BV8(4);
82 static constexpr const uint8_t IOCON_HAEN = bits::BV8(3);
83 static constexpr const uint8_t IOCON_ODR = bits::BV8(2);
84 static constexpr const uint8_t IOCON_INTPOL = bits::BV8(1);
85
86 class IOCONConverter
87 {
88 public:
89 using ARG_TYPE = InterruptPolarity;
90 using RES_TYPE = uint8_t;
91 uint8_t operator()(InterruptPolarity int_polarity) const
92 {
93 return (int_polarity == InterruptPolarity::ACTIVE_HIGH) ? IOCON_INTPOL : 0;
94 }
95 };
96
97 public:
105 MCP23008(MANAGER& manager, uint8_t address)
106 : PARENT{manager, compute_address(address), i2c::I2C_FAST, true} {}
107
108 // Asynchronous API
109 //==================
122
141 {
142 return this->async_write(future);
143 }
144
162 class ConfigureGPIOFuture : public TWriteMultiRegisterFuture<uint8_t, IODIR, IPOL, GPPU>
163 {
165 public:
167 ConfigureGPIOFuture(uint8_t direction, uint8_t pullup = 0, uint8_t polarity = 0)
168 : PARENT{direction, polarity, pullup} {}
170 };
171
190 {
191 return this->async_multi_write(future);
192 }
193
212 class ConfigureInterruptsFuture : public TWriteMultiRegisterFuture<uint8_t, GPINTEN, DEFVAL, INTCON>
213 {
215 public:
217 ConfigureInterruptsFuture(uint8_t int_pins, uint8_t ref = 0, uint8_t compare_ref = 0)
218 : PARENT{int_pins, ref, compare_ref} {}
220 };
221
240 {
241 return this->async_multi_write(future);
242 }
243
256
275 {
276 return this->async_write(future);
277 }
278
288
307 {
308 return this->async_read(future);
309 }
310
321
341 {
342 return this->async_read(future);
343 }
344
355
377 {
378 return this->async_read(future);
379 }
380
381 // Synchronous API
382 //=================
395 {
396 return this->template sync_write<BeginFuture, InterruptPolarity>(interrupt_polarity);
397 }
398
416 bool configure_gpio(uint8_t direction, uint8_t pullup = 0, uint8_t polarity = 0)
417 {
418 ConfigureGPIOFuture future{direction, pullup, polarity};
419 if (configure_gpio(future) != 0) return false;
420 return (future.await() == future::FutureStatus::READY);
421 }
422
440 bool configure_interrupts(uint8_t int_pins, uint8_t ref = 0, uint8_t compare_ref = 0)
441 {
442 ConfigureInterruptsFuture future{int_pins, ref, compare_ref};
443 if (configure_interrupts(future) != 0) return false;
444 return (future.await() == future::FutureStatus::READY);
445 }
446
458 bool values(uint8_t value)
459 {
460 return this->template sync_write<SetValuesFuture>(value);
461 }
462
472 uint8_t values()
473 {
474 return get_value<GetValuesFuture>();
475 }
476
488 {
489 return get_value<InterruptFlagsFuture>();
490 }
491
505 {
506 return get_value<CapturedValuesFuture>();
507 }
508
509 private:
510 template<typename F> uint8_t get_value()
511 {
512 uint8_t value = 0;
513 this->template sync_read<F>(value);
514 return value;
515 }
516
517 i2c::I2CLightCommand write_stop(uint8_t byte_count = 0) const
518 {
519 return this->write(byte_count, false, true);
520 }
521 };
522}
523
524#endif /* MCP23008_H */
Create a future to be used by asynchronous method configure_gpio(ConfigureGPIOFuture&).
Definition: mcp23008.h:163
Create a future to be used by asynchronous method configure_interrupts(ConfigureInterruptsFuture&).
Definition: mcp23008.h:213
I2C device driver for Microchip MCP23008 support.
Definition: mcp23008.h:41
uint8_t interrupt_flags()
Get the pins that generated the latest interrupt on the port of the MCP23008 chip.
Definition: mcp23008.h:487
int values(GetValuesFuture &future)
Get levels of pins on the port of this MCP23008 chip.
Definition: mcp23008.h:306
int configure_interrupts(ConfigureInterruptsFuture &future)
Configure interrupts on the port of this MCP23008 chip.
Definition: mcp23008.h:239
int values(SetValuesFuture &future)
Set output levels of output pins on the port of this MCP23008 chip.
Definition: mcp23008.h:274
bool begin(InterruptPolarity interrupt_polarity=InterruptPolarity::ACTIVE_HIGH)
Initialize the chip before operation.
Definition: mcp23008.h:394
uint8_t values()
Get levels of pins on the port of this MCP23008 chip.
Definition: mcp23008.h:472
int configure_gpio(ConfigureGPIOFuture &future)
Configure GPIO on the port of this MCP23008 chip.
Definition: mcp23008.h:189
MCP23008(MANAGER &manager, uint8_t address)
Create a new device driver for an MCP23008 chip.
Definition: mcp23008.h:105
uint8_t captured_values()
Get captured levels, at the time an interrupt was triggered, of pins on the port of this MCP23008 chi...
Definition: mcp23008.h:504
int interrupt_flags(InterruptFlagsFuture &future)
Get the pins that generated the latest interrupt on the port of the MCP23008 chip.
Definition: mcp23008.h:340
bool values(uint8_t value)
Set output levels of output pins on the port of this MCP23008 chip.
Definition: mcp23008.h:458
bool configure_interrupts(uint8_t int_pins, uint8_t ref=0, uint8_t compare_ref=0)
Configure interrupts on the port of this MCP23008 chip.
Definition: mcp23008.h:440
int begin(BeginFuture &future)
Initialize the chip before operation.
Definition: mcp23008.h:140
int captured_values(CapturedValuesFuture &future)
Get captured levels, at the time an interrupt was triggered, of pins on the port of this MCP23008 chi...
Definition: mcp23008.h:376
bool configure_gpio(uint8_t direction, uint8_t pullup=0, uint8_t polarity=0)
Configure GPIO on the port of this MCP23008 chip.
Definition: mcp23008.h:416
Base class for all I2C devices.
Definition: i2c_device.h:84
static constexpr I2CLightCommand write(uint8_t write_count=0, bool finish_future=false, bool stop=false)
Build a write I2CLightCommand that can be later pushed to the I2C Manager for proper handling.
Definition: i2c_device.h:202
int async_write(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing only one write...
Definition: i2c_device.h:357
int async_multi_write(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing several regist...
Definition: i2c_device.h:379
MANAGER MANAGER
the type of I2C Manager that can handle this device.
Definition: i2c_device.h:87
int async_read(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing one write foll...
Definition: i2c_device.h:309
Light atomic I2C command as prepared by an I2C device.
Generic Future that can be used to read an I2C device register.
Generic Future that can be used to write to several I2C device registers.
Generic Future that can be used to write to an I2C device register.
API to handle the MCP23008/23017 chips (8 & 16-Bit I/O Expanders with I2C interface).
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Definition: bits.h:41
Defines the API for MCP23008/MCP23017 chips support.
Definition: mcp23008.h:30
InterruptPolarity
The polarity of the MCP23008/MCP23017 INT pins.
Definition: mcp230xx.h:44
@ ACTIVE_HIGH
The INT pins shall be active high, ie they are low by default, and changed to high when an interrupt ...
Contains the API around Future implementation.
Definition: future.h:312
@ READY
The status of a Future once its output value has been fully set by a provider.
Define API to define and manage I2C devices.
Definition: i2c.h:51