19#include "driver/gpio.h"
20#include "driver/spi_master.h"
83 void transfer(
const uint8_t *tx, uint8_t *rx, std::size_t len) {
84 if (!initialized_ || spi_device_ ==
nullptr) {
85 ESP_LOGE(TAG,
"SPI bus not initialized");
89 spi_transaction_t trans = {};
90 trans.length = len * 8;
94 esp_err_t ret = spi_device_transmit(spi_device_, &trans);
96 ESP_LOGE(TAG,
"SPI transfer failed: %s", esp_err_to_name(ret));
99#if ESP32_AS5047U_ENABLE_DETAILED_SPI_LOGGING
101 if (len > 0 && len <= 8) {
104 n += snprintf(buf + n,
sizeof(buf) - n,
"SPI[%zu] TX:", len);
105 for (std::size_t i = 0; i < len && n < (int)(
sizeof(buf) - 4); ++i) {
106 n += snprintf(buf + n,
sizeof(buf) - n,
" %02X", tx ? tx[i] : 0u);
109 n += snprintf(buf + n,
sizeof(buf) - n,
" RX:");
110 for (std::size_t i = 0; i < len && n < (int)(
sizeof(buf) - 4); ++i) {
111 n += snprintf(buf + n,
sizeof(buf) - n,
" %02X", rx[i]);
114 n += snprintf(buf + n,
sizeof(buf) - n,
" RX: (none)");
116 ESP_LOGI(TAG,
"%s", buf);
127 ESP_LOGW(TAG,
"SPI bus already initialized");
131 if (!initializeSPI()) {
132 ESP_LOGE(TAG,
"Failed to initialize SPI bus");
136 if (!addSPIDevice()) {
137 ESP_LOGE(TAG,
"Failed to add SPI device");
143 ESP_LOGI(TAG,
"SPI bus initialized successfully");
155 if (spi_device_ !=
nullptr) {
156 spi_bus_remove_device(spi_device_);
157 spi_device_ =
nullptr;
160 spi_bus_free(config_.
host);
162 initialized_ =
false;
163 ESP_LOGI(TAG,
"SPI bus deinitialized");
180 spi_device_handle_t spi_device_ =
nullptr;
181 bool initialized_ =
false;
182 static constexpr const char *TAG =
"Esp32As5047uSpiBus";
188 bool initializeSPI() {
190 if (config_.sclk_pin < 0 || config_.sclk_pin > 48) {
191 ESP_LOGE(TAG,
"Invalid SCLK pin: %d", config_.sclk_pin);
194 if (config_.mosi_pin < 0 || config_.mosi_pin > 48) {
195 ESP_LOGE(TAG,
"Invalid MOSI pin: %d", config_.mosi_pin);
198 if (config_.miso_pin < 0 || config_.miso_pin > 48) {
199 ESP_LOGE(TAG,
"Invalid MISO pin: %d", config_.miso_pin);
203 spi_bus_config_t buscfg = {};
204 buscfg.mosi_io_num = config_.mosi_pin;
205 buscfg.miso_io_num = config_.miso_pin;
206 buscfg.sclk_io_num = config_.sclk_pin;
207 buscfg.quadwp_io_num = -1;
208 buscfg.quadhd_io_num = -1;
209 buscfg.max_transfer_sz = 64;
210 buscfg.flags = SPICOMMON_BUSFLAG_MASTER;
213 ESP_LOGI(TAG,
"Initializing SPI bus: MISO=GPIO%d, MOSI=GPIO%d, SCLK=GPIO%d, Host=SPI%d",
214 config_.miso_pin, config_.mosi_pin, config_.sclk_pin, config_.host + 1);
216 esp_err_t ret = spi_bus_initialize(config_.host, &buscfg, SPI_DMA_CH_AUTO);
218 ESP_LOGE(TAG,
"Failed to initialize SPI bus: %s", esp_err_to_name(ret));
219 ESP_LOGE(TAG,
"Check: SCLK pin GPIO%d is not used by another peripheral", config_.sclk_pin);
223 ESP_LOGI(TAG,
"SPI bus initialized successfully: MISO=GPIO%d, MOSI=GPIO%d, SCLK=GPIO%d",
224 config_.miso_pin, config_.mosi_pin, config_.sclk_pin);
231 ESP_LOGI(TAG,
"SCLK pin GPIO%d is driven by SPI%d; freq=%lu Hz",
232 config_.sclk_pin, config_.host + 1, (
unsigned long)config_.frequency);
241 bool addSPIDevice() {
242 if (config_.frequency == 0) {
243 ESP_LOGE(TAG,
"SPI frequency is 0 - SCLK will not run. Set SPIParams::FREQUENCY > 0 (e.g. 4000000)");
246 spi_device_interface_config_t devcfg = {};
247 devcfg.command_bits = 0;
248 devcfg.address_bits = 0;
249 devcfg.dummy_bits = 0;
250 devcfg.clock_speed_hz = config_.frequency;
251 devcfg.mode = config_.mode;
252 devcfg.duty_cycle_pos = 128;
253 devcfg.spics_io_num = config_.cs_pin;
254 devcfg.queue_size = config_.queue_size;
255 devcfg.cs_ena_pretrans = config_.cs_ena_pretrans;
256 devcfg.cs_ena_posttrans = config_.cs_ena_posttrans;
258 devcfg.input_delay_ns = 0;
259 devcfg.pre_cb =
nullptr;
260 devcfg.post_cb =
nullptr;
262 ESP_LOGI(TAG,
"Adding SPI device: CS=GPIO%d, Freq=%lu Hz, Mode=%d, SCLK=GPIO%d",
263 config_.cs_pin, config_.frequency, config_.mode, config_.sclk_pin);
265 esp_err_t ret = spi_bus_add_device(config_.host, &devcfg, &spi_device_);
267 ESP_LOGE(TAG,
"Failed to add SPI device: %s", esp_err_to_name(ret));
268 ESP_LOGE(TAG,
"Check: CS pin GPIO%d and SCLK pin GPIO%d are not used elsewhere",
269 config_.cs_pin, config_.sclk_pin);
273 ESP_LOGI(TAG,
"SPI device added successfully: CS=GPIO%d, Freq=%lu Hz, Mode=%d",
274 config_.cs_pin, config_.frequency, config_.mode);
294 config.
host = (SPIParams::SPI_HOST_ID == 3) ? SPI3_HOST : SPI2_HOST;
295 config.
miso_pin =
static_cast<gpio_num_t
>(SPIPins::MISO);
296 config.
mosi_pin =
static_cast<gpio_num_t
>(SPIPins::MOSI);
297 config.
sclk_pin =
static_cast<gpio_num_t
>(SPIPins::SCLK);
298 config.
cs_pin =
static_cast<gpio_num_t
>(SPIPins::CS);
302 config.
mode = SPIParams::MODE;
307 return std::make_unique<Esp32As5047uSpiBus>(config);
CRTP-based SPI bus interface for AS5047U driver.
ESP32 SPI transport implementation for AS5047U driver.
Definition esp32_as5047u_bus.hpp:35
Esp32As5047uSpiBus(const SPIConfig &config)
Constructor with SPI configuration.
Definition esp32_as5047u_bus.hpp:68
const SPIConfig & getConfig() const noexcept
Get the current SPI configuration.
Definition esp32_as5047u_bus.hpp:170
~Esp32As5047uSpiBus()
Destructor - cleans up SPI resources.
Definition esp32_as5047u_bus.hpp:73
bool isInitialized() const noexcept
Check if SPI bus is initialized.
Definition esp32_as5047u_bus.hpp:176
bool initialize()
Initialize the SPI bus (must be called before use)
Definition esp32_as5047u_bus.hpp:125
void deinitialize()
Deinitialize the SPI bus.
Definition esp32_as5047u_bus.hpp:150
void transfer(const uint8_t *tx, uint8_t *rx, std::size_t len)
Perform a full-duplex SPI data transfer.
Definition esp32_as5047u_bus.hpp:83
CRTP-based template interface for SPI bus operations.
Definition as5047u_spi_interface.hpp:36
auto CreateEsp32As5047uSpiBus() noexcept -> std::unique_ptr< Esp32As5047uSpiBus >
Factory function to create a configured Esp32As5047uSpiBus instance.
Definition esp32_as5047u_bus.hpp:288
Hardware configuration for AS5047U driver on ESP32-C6.
Definition esp32_as5047u_test_config.hpp:39
SPI configuration structure.
Definition esp32_as5047u_bus.hpp:47
uint8_t cs_ena_posttrans
CS held N clock cycles after transaction.
Definition esp32_as5047u_bus.hpp:57
gpio_num_t sclk_pin
SCLK pin (SPI Clock)
Definition esp32_as5047u_bus.hpp:51
uint8_t cs_ena_pretrans
CS asserted N clock cycles before transaction.
Definition esp32_as5047u_bus.hpp:56
uint8_t queue_size
Transaction queue size.
Definition esp32_as5047u_bus.hpp:55
uint32_t frequency
SPI frequency in Hz (max 10MHz for AS5047U)
Definition esp32_as5047u_bus.hpp:53
gpio_num_t cs_pin
CS pin (Chip Select, active low)
Definition esp32_as5047u_bus.hpp:52
gpio_num_t mosi_pin
MOSI pin (Master Out Slave In)
Definition esp32_as5047u_bus.hpp:50
uint8_t mode
SPI mode (must be 1: CPOL=0, CPHA=1 for AS5047U)
Definition esp32_as5047u_bus.hpp:54
spi_host_device_t host
SPI host (e.g., SPI2_HOST for ESP32-S3)
Definition esp32_as5047u_bus.hpp:48
gpio_num_t miso_pin
MISO pin (Master In Slave Out)
Definition esp32_as5047u_bus.hpp:49