147 lines
4.2 KiB
C
147 lines
4.2 KiB
C
#include "cmt_spi3.h"
|
|
#include <Arduino.h>
|
|
#include <driver/spi_master.h>
|
|
#include <esp_rom_gpio.h> // 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 = {
|
|
.flags = SPI_TRANS_MODE_OCT,
|
|
.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();
|
|
}
|