Issues with SPI Slave
Posted: Fri Jul 26, 2019 6:04 am
Hi all,
I'm currently working with the SPI Slave peripheral but am running into 2 issues.
1. I'm setting up a transaction using spi_slave_transmit() with the ticks_to_wait argument set to portMAX_DELAY. I'd expect the function to block there until the Master initiates a transaction, but the task continues execution normally, continuing to set up transactions. I've analyzed the chip select line and can confirm that it's inactive. Am I wrong in believing that the function should be blocking while the chip select is still inactive? The function isn't returning any errors back, so I'm unsure if anything's set up incorrectly.
2. I can receive data from the master correctly but am unable to actually transmit anything back. I've tried to set up a transaction of 2 bytes to be sent back to the Master, but the MISO line is remaining low in all transactions.
I'm currently working with an SPI Master running in Mode 0 with a clock speed of 100kHz. I've attached the code for the peripheral initialization along with the listening task.
Does anyone have an idea whether I'm doing anything wrong here?
I'm currently working with the SPI Slave peripheral but am running into 2 issues.
1. I'm setting up a transaction using spi_slave_transmit() with the ticks_to_wait argument set to portMAX_DELAY. I'd expect the function to block there until the Master initiates a transaction, but the task continues execution normally, continuing to set up transactions. I've analyzed the chip select line and can confirm that it's inactive. Am I wrong in believing that the function should be blocking while the chip select is still inactive? The function isn't returning any errors back, so I'm unsure if anything's set up incorrectly.
2. I can receive data from the master correctly but am unable to actually transmit anything back. I've tried to set up a transaction of 2 bytes to be sent back to the Master, but the MISO line is remaining low in all transactions.
I'm currently working with an SPI Master running in Mode 0 with a clock speed of 100kHz. I've attached the code for the peripheral initialization along with the listening task.
Does anyone have an idea whether I'm doing anything wrong here?
Code: Select all
#define SPI_SLAVE_MOSI_PIN 39
#define SPI_SLAVE_MISO_PIN 32
#define SPI_SLAVE_SCK_PIN 13
#define SPI_SLAVE_CS_PIN 36
#define SPI_SLAVE_MAX_BUFER_SIZE 128
//!Initialize SPI slave interface. Pin definitions are in header file
static void spiSlaveInit()
{
BaseType_t xReturned;
esp_err_t err;
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.pin_bit_mask = 1ULL<<SPI_SLAVE_MOSI_PIN;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 0;
io_conf.pull_down_en = 0;
gpio_config(&io_conf);
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.pin_bit_mask = 1ULL<<SPI_SLAVE_SCK_PIN;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 0;
io_conf.pull_down_en = 0;
gpio_config(&io_conf);
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.pin_bit_mask = 1ULL<<SPI_SLAVE_CS_PIN;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
io_conf.pull_down_en = 0;
gpio_config(&io_conf);
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.pin_bit_mask = 1ULL<<SPI_SLAVE_MISO_PIN;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pull_up_en = 0;
io_conf.pull_down_en = 0;
gpio_config(&io_conf);
//Configuration for the SPI bus
spi_bus_config_t buscfg =
{
.mosi_io_num = SPI_SLAVE_MOSI_PIN,
.miso_io_num = SPI_SLAVE_MISO_PIN,
.sclk_io_num = SPI_SLAVE_SCK_PIN,
.quadwp_io_num = -1,
.quadhd_io_num = -1
};
//Configuration for the SPI slave interface
spi_slave_interface_config_t slvcfg =
{
.mode = 0,
.spics_io_num = SPI_SLAVE_CS_PIN,
.queue_size = 3,
.flags = 0,
.post_setup_cb=NULL,
.post_trans_cb=NULL
};
//Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
gpio_set_pull_mode(SPI_SLAVE_MOSI_PIN, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(SPI_SLAVE_SCK_PIN, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(SPI_SLAVE_CS_PIN, GPIO_PULLUP_ONLY);
_shared_mem_send_buffer = pvPortMallocCaps(SPI_SLAVE_MAX_BUFER_SIZE, MALLOC_CAP_DMA);
//Initialize SPI slave interface
err = spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 0);
if(err == ESP_OK)
{
ESP_LOGI(TAG, "spiSlaveInit: Initialized SPI Slave interface");
}
xReturned = xTaskCreatePinnedToCore(&spiSlaveListenTask, "spiSlaveListenTask", 8192, NULL, 5, NULL, 1);
if(pdPASS != xReturned)
{
ESP_LOGE(TAG, "spiSlaveInit: Could not initialize spi slave listener task. Heap available is %d", esp_get_free_heap_size());
}
}
//!Task which continually listens for data received over the SPI slave bus
static void spiSlaveListenTask()
{
WORD_ALIGNED_ATTR char* recvbuf = NULL;
WORD_ALIGNED_ATTR char dummy_buffer[32] = {0};
spi_slave_transaction_t t;
esp_err_t rv = ESP_OK;
recvbuf = pvPortMallocCaps(SPI_SLAVE_MAX_BUFER_SIZE, MALLOC_CAP_DMA);
ESP_LOGI(TAG, "spiSlaveListenTask: Starting to listen on SPI Slave interface");
while(1)
{
//Set up a transaction of bytes to send/receive
memset(&t, 0, sizeof(t));
t.length = 32*8;
t.tx_buffer = dummy_buffer;
t.rx_buffer = recvbuf;
dummy_buffer[0] = 0x0A;
dummy_buffer[1] = 0x0B;
rv = spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
if(ESP_OK != rv)
{
ESP_LOGE(TAG, "spiSlaveListenTask: Recevied error %d when setting up transaction!", rv);
}
ESP_LOGI(TAG, "spiSlaveListenTask: Transaction received with length of %d bytes", t.trans_len);
// while(!gpio_get_level(SPI_SLAVE_CS_PIN));
if(t.trans_len > 0)
{//received spi transaction
bzero(_shared_mem_send_buffer, SPI_SLAVE_MAX_BUFER_SIZE);
miscPrintHexadecimalString((char*)recvbuf, t.trans_len/8, "SPI slave received: ");
}
}
}