diff options
| author | jacqueline <me@jacqueline.id.au> | 2022-09-21 12:10:41 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2022-09-21 12:10:41 +1000 |
| commit | b429f0ddecca1b6cd3ae46a71dc325b35b780465 (patch) | |
| tree | 9e2ebd9cc97a817878c8a55982345afff8122858 /main/gpio-expander.cpp | |
| parent | a303f425308b764265ae852d1f6502cc17707c8c (diff) | |
| download | tangara-fw-b429f0ddecca1b6cd3ae46a71dc325b35b780465.tar.gz | |
Add a basic i2c gpio expander implementation
Diffstat (limited to 'main/gpio-expander.cpp')
| -rw-r--r-- | main/gpio-expander.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/main/gpio-expander.cpp b/main/gpio-expander.cpp new file mode 100644 index 00000000..3aadb63e --- /dev/null +++ b/main/gpio-expander.cpp @@ -0,0 +1,67 @@ +#include "gpio-expander.h" + +namespace gay_ipod { + +GpioExpander::GpioExpander() { +} + +GpioExpander::~GpioExpander() { +} + +esp_err_t GpioExpander::Write() { + i2c_cmd_handle_t handle = i2c_cmd_link_create(); + if (handle == NULL) { + return ESP_ERR_NO_MEM; + } + + // Technically enqueuing these commands could fail, but we don't worry about + // it because that would indicate some really very badly wrong more generally. + i2c_master_start(handle); + i2c_master_write_byte(handle, (PCA8575_ADDRESS << 1 | I2C_MASTER_WRITE), true); + i2c_master_write_byte(handle, port_a_, true); + i2c_master_write_byte(handle, port_b_, true); + i2c_master_stop(handle); + + // TODO: timeout + esp_err_t ret = i2c_master_cmd_begin(0, handle, 0); + + i2c_cmd_link_delete(handle); + return ret; +} + +esp_err_t GpioExpander::Read() { + i2c_cmd_handle_t handle = i2c_cmd_link_create(); + if (handle == NULL) { + return ESP_ERR_NO_MEM; + } + + // Technically enqueuing these commands could fail, but we don't worry about + // it because that would indicate some really very badly wrong more generally. + i2c_master_start(handle); + i2c_master_write_byte(handle, (PCA8575_ADDRESS << 1 | I2C_MASTER_READ), true); + i2c_master_read_byte(handle, &input_a_, I2C_MASTER_ACK); + i2c_master_read_byte(handle, &input_b_, I2C_MASTER_LAST_NACK); + i2c_master_stop(handle); + + // TODO: timeout + esp_err_t ret = i2c_master_cmd_begin(0, handle, 0); + + i2c_cmd_link_delete(handle); + return ret; +} + +bool GpioExpander::charge_power_ok(void) { + // Active-low. + return (input_a_ & (1 << 4)) == 0; +} + +bool GpioExpander::headphone_detect(void) { + // Active-low. + return (input_b_ & (1 << 0)) == 0; // TODO. +} + +uint8_t GpioExpander::key_states(void) { + return input_b_ & 0b00111111; +} + +} // namespace gay_ipod |
