#include <SPI.h>
#include <driver/spi_slave.h>
/**************************************************************************************************/
#define SPI_BUS SPI2_HOST
#define SPI_MODE SPI_MODE0
#define SPI_CS 10
#define SPI_CLK 12
#define SPI_MOSI 11
#define SPI_MISO 13
#define QUEUE_SIZE 1
#define MAX_SAMPLES 100
#define BUFFER_SIZE (MAX_SAMPLES * sizeof(uint32_t))
#define MAX_TRANSFER_SIZE BUFFER_SIZE
/**************************************************************************************************/
bool spi_completed_flag;
spi_slave_transaction_t trans;
uint8_t *spi_buf;
/**************************************************************************************************/
extern "C" void spi_completed_cb(struct spi_slave_transaction_t *trans);
void IRAM_ATTR spi_completed_cb(struct spi_slave_transaction_t *trans)
{
Serial.printf("spi_completed_cb()\n");
Serial.printf("trans->tx_buffer:0x%08X\n", (unsigned int)trans->tx_buffer);
Serial.printf("trans->rx_buffer:0x%08X\n", (unsigned int)trans->rx_buffer);
Serial.printf("trans->length:%"PRIu32"\n", (uint32_t)trans->length);
Serial.printf("trans->trans_len:%"PRIu32"\n", (uint32_t)trans->trans_len);
spi_completed_flag = true;
}
/**************************************************************************************************/
void spi_init(void)
{
spi_bus_config_t buscfg = {
.mosi_io_num = SPI_MOSI,
.miso_io_num = SPI_MISO,
.sclk_io_num = SPI_CLK,
.data2_io_num = -1, // union with quadwp_io_num
.data3_io_num = -1, // union with quadhd_io_num
.data4_io_num = -1,
.data5_io_num = -1,
.data6_io_num = -1,
.data7_io_num = -1,
.max_transfer_sz = MAX_TRANSFER_SIZE,
.flags = SPICOMMON_BUSFLAG_SLAVE,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
.isr_cpu_id = INTR_CPU_ID_AUTO,
#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
#endif
.intr_flags = 0,
};
spi_slave_interface_config_t ifcfg = {
.spics_io_num = SPI_CS,
.flags = 0,
.queue_size = QUEUE_SIZE,
.mode = SPI_MODE,
.post_setup_cb = NULL,
.post_trans_cb = spi_completed_cb,
};
spi_buf = (uint8_t *)heap_caps_calloc(BUFFER_SIZE, sizeof(uint8_t), MALLOC_CAP_DMA | MALLOC_CAP_32BIT);
assert(spi_buf != NULL);
esp_err_t err = spi_slave_initialize(SPI_BUS, &buscfg, &ifcfg, SPI_DMA_CH_AUTO);
assert(err == ESP_OK);
spi_completed_flag = false;
}
/**************************************************************************************************/
void spi_send(uint32_t size)
{
spi_completed_flag = false;
memset(&trans, 0, sizeof(spi_slave_transaction_t));
trans.tx_buffer = spi_buf;
trans.rx_buffer = NULL;
trans.length = 8 * size; // in bit size
esp_err_t err = spi_slave_queue_trans(SPI_BUS, &trans, portMAX_DELAY);
assert(err == ESP_OK);
Serial.printf("spi_send(%"PRIu32")\n", size);
Serial.printf("trans.tx_buffer:0x%08X\n", (unsigned int)trans.tx_buffer);
Serial.printf("trans.rx_buffer:0x%08X\n", (unsigned int)trans.rx_buffer);
Serial.printf("trans.length:%"PRIu32"\n", (uint32_t)trans.length);
}
/**************************************************************************************************/
void spi_receive(uint32_t size)
{
spi_completed_flag = false;
memset(&trans, 0, sizeof(spi_slave_transaction_t));
trans.tx_buffer = NULL;
trans.rx_buffer = spi_buf;
trans.length = 8 * size; // in bit size
esp_err_t err = spi_slave_queue_trans(SPI_BUS, &trans, portMAX_DELAY);
assert(err == ESP_OK);
Serial.printf("spi_receive(%"PRIu32")\n", size);
Serial.printf("trans.tx_buffer:0x%08X\n", (unsigned int)trans.tx_buffer);
Serial.printf("trans.rx_buffer:0x%08X\n", (unsigned int)trans.rx_buffer);
Serial.printf("trans.length:%"PRIu32"\n", (uint32_t)trans.length);
}
/**************************************************************************************************/
bool spi_completed(void)
{
return spi_completed_flag;
}
void spi_ack(void)
{
spi_slave_transaction_t *resp_tran;
spi_slave_get_trans_result(SPI_BUS, &resp_tran, portMAX_DELAY);
Serial.printf("resp_tran->tx_buffer:0x%08X\n", (unsigned int)resp_tran->tx_buffer);
Serial.printf("resp_tran->rx_buffer:0x%08X\n", (unsigned int)resp_tran->rx_buffer);
Serial.printf("resp_tran->length:%"PRIu32"\n", (uint32_t)resp_tran->length);
}
/**************************************************************************************************/
uint32_t *spi_buf_get(void)
{
return (uint32_t *)spi_buf;
}
/**************************************************************************************************/
/**************************************************************************************************/
/**************************************************************************************************/
#define DBG_ENABLED 1
#define DBG_SPI_OPS_ENABLED 1
#if DBG_ENABLED
#define DBG_TGR_PIN 19
#define DBG_IDLE_TIME 10 /*ms*/
#define DBG_SEND_SIZE (10 * sizeof(uint32_t))
#define DBG_STATE_IDLE 0
#define DBG_STATE_SPI_SEND 1
#define DBG_STATE_WAIT_SPI_COMPLETED 2
char *dbg_state_names[] = {
"DBG_STATE_IDLE",
"DBG_STATE_SPI_SEND",
"DBG_STATE_WAIT_SPI_COMPLETED"
};
uint32_t dbg_state,
dbg_state_copy,
dbg_idle_etime;
/**************************************************************************************************/
void dbg_log_state_name(void)
{
Serial.printf("%s\n", dbg_state_names[dbg_state]);
}
/**************************************************************************************************/
void dbg_init(void)
{
pinMode(DBG_TGR_PIN, OUTPUT);
digitalWrite(DBG_TGR_PIN, LOW);
dbg_idle_etime = millis();
dbg_state = DBG_STATE_IDLE;
dbg_state_copy = dbg_state;
dbg_log_state_name();
}
/**************************************************************************************************/
void dgb_update(void)
{
switch(dbg_state)
{
case DBG_STATE_IDLE:
if(millis() > dbg_idle_etime)
{
dbg_state = DBG_STATE_SPI_SEND;
}
break;
case DBG_STATE_SPI_SEND:
#if DBG_SPI_OPS_ENABLED
memset(spi_buf, 0x55, BUFFER_SIZE);
spi_send(DBG_SEND_SIZE);
#endif
digitalWrite(DBG_TGR_PIN, HIGH);
dbg_state = DBG_STATE_WAIT_SPI_COMPLETED;
break;
case DBG_STATE_WAIT_SPI_COMPLETED:
#if DBG_SPI_OPS_ENABLED
if(spi_completed())
{
spi_ack();
#else
if(millis() > dbg_idle_etime + 50)
{
#endif
digitalWrite(DBG_TGR_PIN, LOW);
dbg_idle_etime = millis() + DBG_IDLE_TIME;
dbg_state = DBG_STATE_IDLE;
}
break;
default:
break;
}
if(dbg_state_copy != dbg_state)
{
dbg_state_copy = dbg_state;
dbg_log_state_name();
}
}
#endif /* DBG_ENABLED */
/**************************************************************************************************/
/**************************************************************************************************/
/**************************************************************************************************/
void setup()
{
Serial.begin(115200);
spi_init();
#if DBG_ENABLED
Serial.printf("\n Start [DBG]\n");
dbg_init();
#else
Serial.printf("\n Start \n");
#endif
}
/**************************************************************************************************/
void loop()
{
#if DBG_ENABLED
dgb_update();
#else
#endif
}
Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1