ESPHome  2024.4.1
spi_arduino.cpp
Go to the documentation of this file.
1 #include "spi.h"
2 #include <vector>
3 
4 namespace esphome {
5 namespace spi {
6 
7 #ifdef USE_ARDUINO
8 
9 static const char *const TAG = "spi-esp-arduino";
10 class SPIDelegateHw : public SPIDelegate {
11  public:
12  SPIDelegateHw(SPIInterface channel, uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
13  : SPIDelegate(data_rate, bit_order, mode, cs_pin), channel_(channel) {}
14 
15  void begin_transaction() override {
16 #ifdef USE_RP2040
17  SPISettings const settings(this->data_rate_, static_cast<BitOrder>(this->bit_order_), this->mode_);
18 #elif defined(ESP8266)
19  // Arduino ESP8266 library has mangled values for SPI modes :-(
20  auto mode = (this->mode_ & 0x01) + ((this->mode_ & 0x02) << 3);
21  ESP_LOGVV(TAG, "8266 mangled SPI mode 0x%X", mode);
22  SPISettings const settings(this->data_rate_, this->bit_order_, mode);
23 #else
24  SPISettings const settings(this->data_rate_, this->bit_order_, this->mode_);
25 #endif
26  this->channel_->beginTransaction(settings);
28  }
29 
30  void transfer(uint8_t *ptr, size_t length) override { this->channel_->transfer(ptr, length); }
31 
32  void end_transaction() override {
33  this->channel_->endTransaction();
35  }
36 
37  uint8_t transfer(uint8_t data) override { return this->channel_->transfer(data); }
38 
39  void write16(uint16_t data) override { this->channel_->transfer16(data); }
40 
41 #ifdef USE_RP2040
42  void write_array(const uint8_t *ptr, size_t length) override {
43  // avoid overwriting the supplied buffer
44  uint8_t *rxbuf = new uint8_t[length]; // NOLINT(cppcoreguidelines-owning-memory)
45  memcpy(rxbuf, ptr, length);
46  this->channel_->transfer((void *) rxbuf, length);
47  delete[] rxbuf; // NOLINT(cppcoreguidelines-owning-memory)
48  }
49 #else
50  void write_array(const uint8_t *ptr, size_t length) override { this->channel_->writeBytes(ptr, length); }
51 #endif
52 
53  void read_array(uint8_t *ptr, size_t length) override { this->channel_->transfer(ptr, length); }
54 
55  protected:
56  SPIInterface channel_{};
57 };
58 
59 class SPIBusHw : public SPIBus {
60  public:
61  SPIBusHw(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi, SPIInterface channel) : SPIBus(clk, sdo, sdi), channel_(channel) {
62 #ifdef USE_ESP8266
63  channel->pins(Utility::get_pin_no(clk), Utility::get_pin_no(sdi), Utility::get_pin_no(sdo), -1);
64  channel->begin();
65 #endif // USE_ESP8266
66 #ifdef USE_ESP32
67  channel->begin(Utility::get_pin_no(clk), Utility::get_pin_no(sdi), Utility::get_pin_no(sdo), -1);
68 #endif
69 #ifdef USE_RP2040
70  if (Utility::get_pin_no(sdi) != -1)
71  channel->setRX(Utility::get_pin_no(sdi));
72  if (Utility::get_pin_no(sdo) != -1)
73  channel->setTX(Utility::get_pin_no(sdo));
74  channel->setSCK(Utility::get_pin_no(clk));
75  channel->begin();
76 #endif
77  }
78 
79  SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin) override {
80  return new SPIDelegateHw(this->channel_, data_rate, bit_order, mode, cs_pin);
81  }
82 
83  protected:
84  SPIInterface channel_{};
85  bool is_hw() override { return true; }
86 };
87 
89  const std::vector<uint8_t> &data_pins) {
90  return new SPIBusHw(clk, sdo, sdi, interface);
91 }
92 
93 #endif // USE_ARDUINO
94 } // namespace spi
95 } // namespace esphome
SPIClassRP2040 * SPIInterface
Definition: spi.h:16
static int get_pin_no(GPIOPin *pin)
Definition: spi.h:130
const char *const TAG
Definition: spi.cpp:8
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
SPIMode
Modes mapping to clock phase and polarity.
Definition: spi.h:76
virtual void end_transaction()
Definition: spi.h:190
virtual void begin_transaction()
Definition: spi.h:187
static SPIBus * get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi, const std::vector< uint8_t > &data_pins)
Definition: spi_arduino.cpp:88
SPIBitOrder
The bit-order for SPI devices. This defines how the data read from and written to the device is inter...
Definition: spi.h:38
uint16_t length
Definition: tt21100.cpp:12
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7