mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-21 21:43:26 +02:00
5c26f95a4b
* Checkpoint * Checkpoint * Checkpoint * Revert hal change * Checkpoint * Checkpoint * Checkpoint * Checkpoint * ESP-IDF working * clang-format * use bus_list * Add spi_device; fix 16 bit transfer. * Enable multi_conf; Fix LSB 16 bit transactions * Formatting fixes * Clang-format, codeowners * Add test * Formatting * clang tidy * clang-format * clang-tidy * clang-format * Checkpoint * Checkpoint * Checkpoint * Revert hal change * Checkpoint * Checkpoint * Checkpoint * Checkpoint * ESP-IDF working * clang-format * use bus_list * Add spi_device; fix 16 bit transfer. * Enable multi_conf; Fix LSB 16 bit transactions * Formatting fixes * Clang-format, codeowners * Add test * Formatting * clang tidy * clang-format * clang-tidy * clang-format * Clang-tidy * Clang-format * clang-tidy * clang-tidy * Fix ESP8266 * RP2040 * RP2040 * Avoid use of spi1 as id * Refactor SPI code. Add support for ESP-IDF hardware SPI * Force SW only for RP2040 * Break up large transfers * Add interface: option for spi. validate pins in python. * Can't use match/case with Python 3.9. Check for inverted pins. * Work around target_platform issue with * Remove debug code * Optimize write_array16 * Show errors in hex * Only one spi on ESP32Cx variants * Ensure bus is claimed before asserting /CS. * Check on init/deinit * Allow maximum rate write only SPI on GPIO MUXed pins. * Clang-format * Clang-tidy * Fix issue with reads. * Finger trouble... * Make comment about missing SPI on Cx variants * Pacify CI clang-format. Did not complain locally?? * Restore 8266 to its former SPI glory * Fix per clang-format * Move validation and choice of SPI into Python code. * Add test for interface: config * Fix issues found on self-review. --------- Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
90 lines
2.9 KiB
C++
90 lines
2.9 KiB
C++
#include "spi.h"
|
|
#include <vector>
|
|
|
|
namespace esphome {
|
|
namespace spi {
|
|
|
|
#ifdef USE_ARDUINO
|
|
|
|
static const char *const TAG = "spi-esp-arduino";
|
|
class SPIDelegateHw : public SPIDelegate {
|
|
public:
|
|
SPIDelegateHw(SPIInterface channel, uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
|
|
: SPIDelegate(data_rate, bit_order, mode, cs_pin), channel_(channel) {}
|
|
|
|
void begin_transaction() override {
|
|
#ifdef USE_RP2040
|
|
SPISettings const settings(this->data_rate_, static_cast<BitOrder>(this->bit_order_), this->mode_);
|
|
#else
|
|
SPISettings const settings(this->data_rate_, this->bit_order_, this->mode_);
|
|
#endif
|
|
this->channel_->beginTransaction(settings);
|
|
SPIDelegate::begin_transaction();
|
|
}
|
|
|
|
void transfer(uint8_t *ptr, size_t length) override { this->channel_->transfer(ptr, length); }
|
|
|
|
void end_transaction() override {
|
|
this->channel_->endTransaction();
|
|
SPIDelegate::end_transaction();
|
|
}
|
|
|
|
uint8_t transfer(uint8_t data) override { return this->channel_->transfer(data); }
|
|
|
|
void write16(uint16_t data) override { this->channel_->transfer16(data); }
|
|
|
|
#ifdef USE_RP2040
|
|
void write_array(const uint8_t *ptr, size_t length) override {
|
|
// avoid overwriting the supplied buffer
|
|
uint8_t *rxbuf = new uint8_t[length]; // NOLINT(cppcoreguidelines-owning-memory)
|
|
memcpy(rxbuf, ptr, length);
|
|
this->channel_->transfer((void *) rxbuf, length);
|
|
delete[] rxbuf; // NOLINT(cppcoreguidelines-owning-memory)
|
|
}
|
|
#else
|
|
void write_array(const uint8_t *ptr, size_t length) override { this->channel_->writeBytes(ptr, length); }
|
|
#endif
|
|
|
|
void read_array(uint8_t *ptr, size_t length) override { this->channel_->transfer(ptr, length); }
|
|
|
|
protected:
|
|
SPIInterface channel_{};
|
|
};
|
|
|
|
class SPIBusHw : public SPIBus {
|
|
public:
|
|
SPIBusHw(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi, SPIInterface channel) : SPIBus(clk, sdo, sdi), channel_(channel) {
|
|
#ifdef USE_ESP8266
|
|
channel->pins(Utility::get_pin_no(clk), Utility::get_pin_no(sdi), Utility::get_pin_no(sdo), -1);
|
|
channel->begin();
|
|
#endif // USE_ESP8266
|
|
#ifdef USE_ESP32
|
|
channel->begin(Utility::get_pin_no(clk), Utility::get_pin_no(sdi), Utility::get_pin_no(sdo), -1);
|
|
#endif
|
|
#ifdef USE_RP2040
|
|
if (Utility::get_pin_no(sdi) != -1)
|
|
channel->setRX(Utility::get_pin_no(sdi));
|
|
if (Utility::get_pin_no(sdo) != -1)
|
|
channel->setTX(Utility::get_pin_no(sdo));
|
|
channel->setSCK(Utility::get_pin_no(clk));
|
|
channel->begin();
|
|
#endif
|
|
}
|
|
|
|
SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin) override {
|
|
return new SPIDelegateHw(this->channel_, data_rate, bit_order, mode, cs_pin);
|
|
}
|
|
|
|
protected:
|
|
SPIInterface channel_{};
|
|
bool is_hw() override { return true; }
|
|
};
|
|
|
|
SPIBus *SPIComponent::get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi) {
|
|
return new SPIBusHw(clk, sdo, sdi, interface);
|
|
}
|
|
|
|
#endif // USE_ARDUINO
|
|
} // namespace spi
|
|
} // namespace esphome
|