#include "cmt_spi3.h" #include #include #include // for esp_rom_gpio_connect_out_signal SemaphoreHandle_t paramLock = NULL; #define SPI_PARAM_LOCK() \ do { \ } while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS) #define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock) // as Espressif confused the hell out of everyone we need to swap the selected SPI PHY here // as for newer generations NRF24 is exactly on the other SPI Interface and we get a collision #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #define SPI_CMT SPI3_HOST #else #define SPI_CMT SPI2_HOST #endif spi_device_handle_t spi_reg, spi_fifo; void cmt_spi3_init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, uint32_t spi_speed) { paramLock = xSemaphoreCreateMutex(); spi_bus_config_t buscfg = { .mosi_io_num = pin_sdio, .miso_io_num = -1, // single wire MOSI/MISO .sclk_io_num = pin_clk, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 32, }; spi_device_interface_config_t devcfg = { .command_bits = 1, .address_bits = 7, .dummy_bits = 0, .mode = 0, // SPI mode 0 .cs_ena_pretrans = 1, .cs_ena_posttrans = 1, .clock_speed_hz = spi_speed, .spics_io_num = pin_cs, .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, .queue_size = 1, .pre_cb = NULL, .post_cb = NULL, }; ESP_ERROR_CHECK(spi_bus_initialize(SPI_CMT, &buscfg, SPI_DMA_DISABLED)); ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg, &spi_reg)); // FiFo spi_device_interface_config_t devcfg2 = { .command_bits = 0, .address_bits = 0, .dummy_bits = 0, .mode = 0, // SPI mode 0 .cs_ena_pretrans = 2, .cs_ena_posttrans = (uint8_t)(1 / (spi_speed * 10e6 * 2) + 2), // >2 us .clock_speed_hz = spi_speed, .spics_io_num = pin_fcs, .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, .queue_size = 1, .pre_cb = NULL, .post_cb = NULL, }; ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg2, &spi_fifo)); esp_rom_gpio_connect_out_signal(pin_sdio, spi_periph_signal[SPI_CMT].spid_out, true, false); delay(100); } void cmt_spi3_write(uint8_t addr, uint8_t dat) { uint8_t tx_data; tx_data = ~dat; spi_transaction_t t = { .cmd = 1, .addr = ~addr, .length = 8, .tx_buffer = &tx_data, .rx_buffer = NULL }; SPI_PARAM_LOCK(); ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); SPI_PARAM_UNLOCK(); delayMicroseconds(100); } uint8_t cmt_spi3_read(uint8_t addr) { uint8_t rx_data; spi_transaction_t t = { .cmd = 0, .addr = ~addr, .length = 8, .rxlength = 8, .tx_buffer = NULL, .rx_buffer = &rx_data }; SPI_PARAM_LOCK(); ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); SPI_PARAM_UNLOCK(); delayMicroseconds(100); return rx_data; } void cmt_spi3_write_fifo(const uint8_t* buf, uint16_t len) { uint8_t tx_data; spi_transaction_t t = { .length = 8, .tx_buffer = &tx_data, // reference to write data .rx_buffer = NULL }; SPI_PARAM_LOCK(); for (uint8_t i = 0; i < len; i++) { tx_data = ~buf[i]; // negate buffer contents ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); delayMicroseconds(4); // > 4 us } SPI_PARAM_UNLOCK(); } void cmt_spi3_read_fifo(uint8_t* buf, uint16_t len) { uint8_t rx_data; spi_transaction_t t = { .length = 8, .rxlength = 8, .tx_buffer = NULL, .rx_buffer = &rx_data }; SPI_PARAM_LOCK(); for (uint8_t i = 0; i < len; i++) { ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); delayMicroseconds(4); // > 4 us buf[i] = rx_data; } SPI_PARAM_UNLOCK(); }