Fork of Tangara with customizations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
tangara-fw/main/gpio-expander.cpp

86 lines
1.9 KiB

#include "gpio-expander.hpp"
#include "i2c.hpp"
#include <cstdint>
namespace gay_ipod {
GpioExpander::GpioExpander() {
ports_ = pack(kPortADefault, kPortBDefault);
// Read and write initial values on initialisation so that we do not have a
// strange partially-initialised state.
// TODO: log or abort if these error; it's really bad!
Write();
Read();
}
GpioExpander::~GpioExpander() {}
void GpioExpander::with(std::function<void(GpioExpander&)> f) {
f(*this);
Write();
}
esp_err_t GpioExpander::Write() {
i2c_cmd_handle_t handle = i2c_cmd_link_create();
if (handle == NULL) {
return ESP_ERR_NO_MEM;
}
std::pair<uint8_t, uint8_t> ports_ab = unpack(ports());
I2CTransaction transaction;
transaction.start()
.write_addr(kPca8575Address, I2C_MASTER_WRITE)
.write_ack(ports_ab.first, ports_ab.second)
.stop();
return transaction.Execute();
}
esp_err_t GpioExpander::Read() {
uint8_t input_a, input_b;
I2CTransaction transaction;
transaction.start()
.write_addr(kPca8575Address, I2C_MASTER_READ)
.read(&input_a, I2C_MASTER_ACK)
.read(&input_b, I2C_MASTER_LAST_NACK)
.stop();
esp_err_t ret = transaction.Execute();
inputs_ = pack(input_a, input_b);
return ret;
}
void GpioExpander::set_pin(ChipSelect cs, bool value) {
set_pin((Pin)cs, value);
}
void GpioExpander::set_pin(Pin pin, bool value) {
if (value) {
ports_ |= (1 << pin);
} else {
ports_ &= ~(1 << pin);
}
}
bool GpioExpander::get_input(Pin pin) const {
return (inputs_ & (1 << pin)) > 0;
}
GpioExpander::SpiLock GpioExpander::AcquireSpiBus(ChipSelect cs) {
return SpiLock(*this, cs);
}
GpioExpander::SpiLock::SpiLock(GpioExpander& gpio, ChipSelect cs)
: lock_(gpio.cs_mutex_), gpio_(gpio), cs_(cs) {
gpio_.with([&](auto& gpio) { gpio.set_pin(cs_, 0); });
}
GpioExpander::SpiLock::~SpiLock() {
gpio_.with([&](auto& gpio) { gpio.set_pin(cs_, 1); });
}
} // namespace gay_ipod