Skip to content

Commit

Permalink
Only use a single SPI device for CMT
Browse files Browse the repository at this point in the history
  • Loading branch information
LennartF22 committed Sep 24, 2024
1 parent 36da830 commit 31cf756
Showing 1 changed file with 70 additions and 63 deletions.
133 changes: 70 additions & 63 deletions lib/CMT2300a/cmt_spi3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ SemaphoreHandle_t paramLock = NULL;
} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)

spi_device_handle_t spi_reg, spi_fifo;
static void IRAM_ATTR pre_cb(spi_transaction_t *trans) {
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 0);
}

static void IRAM_ATTR post_cb(spi_transaction_t *trans) {
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 1);
}

spi_device_handle_t spi;
gpio_num_t cs_reg, cs_fifo;

void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int32_t spi_speed)
{
Expand All @@ -21,128 +30,126 @@ void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin
static_cast<gpio_num_t>(pin_clk)
);

spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
spi_device_interface_config_t device_config {
.command_bits = 0, // set by transactions individually
.address_bits = 0, // set by transactions individually
.dummy_bits = 0,
.mode = 0, // SPI mode 0
.duty_cycle_pos = 0,
.cs_ena_pretrans = 1,
.cs_ena_posttrans = 1,
.cs_ena_pretrans = 2, // only 1 pre and post cycle would be required for register access
.cs_ena_posttrans = static_cast<uint8_t>(2 * spi_speed / 1000000), // >2 us
.clock_speed_hz = spi_speed,
.input_delay_ns = 0,
.spics_io_num = pin_cs,
.spics_io_num = -1, // CS handled by callbacks
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
.queue_size = 1,
.pre_cb = nullptr,
.post_cb = nullptr,
.pre_cb = pre_cb,
.post_cb = post_cb,
};

spi_reg = SpiManagerInst.alloc_device("", bus_config, devcfg);
if (!spi_reg)
spi = SpiManagerInst.alloc_device("", bus_config, device_config);
if (!spi)
ESP_ERROR_CHECK(ESP_FAIL);

// FiFo
spi_device_interface_config_t devcfg2 = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.mode = 0, // SPI mode 0
.duty_cycle_pos = 0,
.cs_ena_pretrans = 2,
.cs_ena_posttrans = static_cast<uint8_t>(2 * spi_speed / 1000000), // >2 us
.clock_speed_hz = spi_speed,
.input_delay_ns = 0,
.spics_io_num = pin_fcs,
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
.queue_size = 1,
.pre_cb = nullptr,
.post_cb = nullptr,
};
cs_reg = static_cast<gpio_num_t>(pin_cs);
ESP_ERROR_CHECK(gpio_reset_pin(cs_reg));
ESP_ERROR_CHECK(gpio_set_level(cs_reg, 1));
ESP_ERROR_CHECK(gpio_set_direction(cs_reg, GPIO_MODE_OUTPUT));

spi_fifo = SpiManagerInst.alloc_device("", bus_config, devcfg2);
if (!spi_fifo)
ESP_ERROR_CHECK(ESP_ERR_NOT_SUPPORTED);
cs_fifo = static_cast<gpio_num_t>(pin_fcs);
ESP_ERROR_CHECK(gpio_reset_pin(cs_fifo));
ESP_ERROR_CHECK(gpio_set_level(cs_fifo, 1));
ESP_ERROR_CHECK(gpio_set_direction(cs_fifo, GPIO_MODE_OUTPUT));
}

void cmt_spi3_write(const uint8_t addr, const uint8_t data)
{
spi_transaction_t t = {
.flags = 0,
.cmd = 0,
.addr = addr,
.length = 8,
.rxlength = 0,
.user = nullptr,
.tx_buffer = &data,
.rx_buffer = nullptr,
spi_transaction_ext_t trans {
.base {
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
.cmd = 0,
.addr = addr,
.length = 8,
.rxlength = 0,
.user = &cs_reg, // CS for register access
.tx_buffer = &data,
.rx_buffer = nullptr,
},
.command_bits = 1,
.address_bits = 7,
.dummy_bits = 0,
};
SPI_PARAM_LOCK();
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
SPI_PARAM_UNLOCK();
}

uint8_t cmt_spi3_read(const uint8_t addr)
{
uint8_t data;
spi_transaction_t t = {
.flags = 0,
.cmd = 1,
.addr = addr,
.length = 0,
.rxlength = 8,
.user = nullptr,
.tx_buffer = nullptr,
.rx_buffer = &data,
spi_transaction_ext_t trans {
.base {
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
.cmd = 1,
.addr = addr,
.length = 0,
.rxlength = 8,
.user = &cs_reg, // CS for register access
.tx_buffer = nullptr,
.rx_buffer = &data,
},
.command_bits = 1,
.address_bits = 7,
.dummy_bits = 0,
};
SPI_PARAM_LOCK();
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
SPI_PARAM_UNLOCK();
return data;
}

void cmt_spi3_write_fifo(const uint8_t* buf, const uint16_t len)
{
spi_transaction_t t = {
spi_transaction_t trans {
.flags = 0,
.cmd = 0,
.addr = 0,
.length = 8,
.rxlength = 0,
.user = nullptr,
.user = &cs_fifo, // CS for FIFO access
.tx_buffer = nullptr,
.rx_buffer = nullptr,
};

SPI_PARAM_LOCK();
spi_device_acquire_bus(spi_fifo, portMAX_DELAY);
spi_device_acquire_bus(spi, portMAX_DELAY);
for (uint8_t i = 0; i < len; i++) {
t.tx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
trans.tx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
}
spi_device_release_bus(spi_fifo);
spi_device_release_bus(spi);
SPI_PARAM_UNLOCK();
}

void cmt_spi3_read_fifo(uint8_t* buf, const uint16_t len)
{
spi_transaction_t t = {
spi_transaction_t trans {
.flags = 0,
.cmd = 0,
.addr = 0,
.length = 0,
.rxlength = 8,
.user = nullptr,
.user = &cs_fifo, // CS for FIFO access
.tx_buffer = nullptr,
.rx_buffer = nullptr,
};

SPI_PARAM_LOCK();
spi_device_acquire_bus(spi_fifo, portMAX_DELAY);
spi_device_acquire_bus(spi, portMAX_DELAY);
for (uint8_t i = 0; i < len; i++) {
t.rx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
trans.rx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
}
spi_device_release_bus(spi_fifo);
spi_device_release_bus(spi);
SPI_PARAM_UNLOCK();
}

0 comments on commit 31cf756

Please sign in to comment.