parent
4e643baf5f
commit
1b2b9182e0
@ -1,4 +1,4 @@ |
|||||||
idf_component_register( |
idf_component_register( |
||||||
SRCS "gay-ipod-fw.cpp" "dac.cpp" "gpio-expander.cpp" "battery.cpp" "storage.cpp" |
SRCS "gay-ipod-fw.cpp" "dac.cpp" "gpio-expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp" |
||||||
INCLUDE_DIRS "." |
INCLUDE_DIRS "." |
||||||
REQUIRES "esp_adc_cal" "fatfs") |
REQUIRES "esp_adc_cal" "fatfs") |
||||||
|
@ -0,0 +1,44 @@ |
|||||||
|
#include "i2c.h" |
||||||
|
#include "assert.h" |
||||||
|
|
||||||
|
namespace gay_ipod { |
||||||
|
|
||||||
|
I2CTransaction::I2CTransaction() { |
||||||
|
handle_ = i2c_cmd_link_create(); |
||||||
|
assert(handle_ != NULL && "failed to create command link"); |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction::~I2CTransaction() { |
||||||
|
i2c_cmd_link_delete(handle_); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t I2CTransaction::Execute() { |
||||||
|
return i2c_master_cmd_begin(I2C_NUM_0, handle_, kI2CTimeout); |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction& I2CTransaction::start() { |
||||||
|
ESP_ERROR_CHECK(i2c_master_start(handle_)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction& I2CTransaction::stop() { |
||||||
|
ESP_ERROR_CHECK(i2c_master_stop(handle_)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction& I2CTransaction::write_addr(uint8_t addr, uint8_t op) { |
||||||
|
write_ack(addr << 1 | op); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction& I2CTransaction::write_ack(uint8_t data) { |
||||||
|
ESP_ERROR_CHECK(i2c_master_write_byte(handle_, data, true)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
I2CTransaction& I2CTransaction::read(uint8_t *dest, i2c_ack_type_t ack) { |
||||||
|
ESP_ERROR_CHECK(i2c_master_read_byte(handle_, dest, ack)); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace gay_ipod
|
@ -0,0 +1,80 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "driver/i2c.h" |
||||||
|
#include "hal/i2c_types.h" |
||||||
|
#include <cstdint> |
||||||
|
|
||||||
|
namespace gay_ipod { |
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience wrapper for performing an I2C transaction with a reasonable |
||||||
|
* preconfigured timeout, automatic management of a heap-based command buffer, |
||||||
|
* and a terser API for enqueuing bytes. |
||||||
|
* |
||||||
|
* Any error codes from the underlying ESP IDF are treated as fatal, since they |
||||||
|
* typically represent invalid arguments or OOMs. |
||||||
|
*/ |
||||||
|
class I2CTransaction { |
||||||
|
public: |
||||||
|
static const uint8_t kI2CTimeout = 100 / portTICK_RATE_MS; |
||||||
|
|
||||||
|
I2CTransaction(); |
||||||
|
~I2CTransaction(); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Executes all enqueued commands, returning the result code. Possible error |
||||||
|
* codes, per the ESP-IDF docs: |
||||||
|
* |
||||||
|
* ESP_OK Success |
||||||
|
* ESP_ERR_INVALID_ARG Parameter error |
||||||
|
* ESP_FAIL Sending command error, slave doesn’t ACK the transfer. |
||||||
|
* ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode. |
||||||
|
* ESP_ERR_TIMEOUT Operation timeout because the bus is busy. |
||||||
|
*/ |
||||||
|
esp_err_t Execute(); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Enqueues a start condition. May also be used for repeated start conditions. |
||||||
|
*/ |
||||||
|
I2CTransaction& start(); |
||||||
|
/* Enqueues a stop condition. */ |
||||||
|
I2CTransaction& stop(); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Enqueues writing the given 7 bit address, followed by one bit indicating |
||||||
|
* whether this is a read or write request. |
||||||
|
* |
||||||
|
* This command will expect an ACK before continuing. |
||||||
|
*/ |
||||||
|
I2CTransaction& write_addr(uint8_t addr, uint8_t op); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Enqueues one or more bytes to be written. The transaction will wait for |
||||||
|
* an ACK to be returned before writing the next byte. |
||||||
|
*/ |
||||||
|
I2CTransaction& write_ack(uint8_t data); |
||||||
|
template <typename ...More> |
||||||
|
I2CTransaction& write_ack(uint8_t data, More... more) { |
||||||
|
write_ack(data); |
||||||
|
write_ack(more...); |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Enqueues a read of one byte into the given uint8. Responds with the given |
||||||
|
* ACK/NACK type. |
||||||
|
*/ |
||||||
|
I2CTransaction& read(uint8_t *dest, i2c_ack_type_t ack); |
||||||
|
|
||||||
|
/* Returns the underlying command buffer. */ |
||||||
|
i2c_cmd_handle_t handle() { return handle_; } |
||||||
|
|
||||||
|
// Cannot be moved or copied, since doing so is probably an error. Pass a
|
||||||
|
// reference instead.
|
||||||
|
I2CTransaction(const I2CTransaction&) = delete; |
||||||
|
I2CTransaction& operator=(const I2CTransaction&) = delete; |
||||||
|
private: |
||||||
|
i2c_cmd_handle_t handle_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace gay_ipod
|
Loading…
Reference in new issue