Last byte received from SPI slave is always zero
Posted: Thu Oct 29, 2020 3:05 am
Hi,
I'm using an ESP32 as a SPI master to receive samples from an AD converter. At every new sample, the AD pulls an ESP32 pin to low and the SPI transaction is executed. After the transaction, the received dataframe is stored in a queue that will be read by other task. My problem is that the last received byte is always zero. I verified the signals with a logic analyzer and it should not be zero.
Below is the code of the task:
The interrupt handler:
SPI initialization (I'm initializing other device to communicate with a lower SCLK frequency of 4MHz when necessary):
If I configure the temp_buff, zeros and the length of the transaction to be one byte larger, the extra byte is ignored when sending the dataframe to the queue and everything works fine, i.e., the last byte of the dataframe is received with its right value, different from 0x00.
Does anyone know why this is happening?
Thank you,
Mateus
I'm using an ESP32 as a SPI master to receive samples from an AD converter. At every new sample, the AD pulls an ESP32 pin to low and the SPI transaction is executed. After the transaction, the received dataframe is stored in a queue that will be read by other task. My problem is that the last received byte is always zero. I verified the signals with a logic analyzer and it should not be zero.
Below is the code of the task:
Code: Select all
void IRAM_ATTR vDataAcquisitonTask(void *pvParameters)
{
int dataRate= ads1299_get_datarate();//get the configured datarate from the AD
const uint32_t ulNumberOfSamples = (*((int*)pvParameters))*dataRate;// *pvParameters is the duration of the acquisiton
uint8_t* temp_buff = heap_caps_malloc(BYTES_PER_FRAME, MALLOC_CAP_DMA|MALLOC_CAP_32BIT);
uint8_t* zeros = heap_caps_malloc(BYTES_PER_FRAME, MALLOC_CAP_DMA|MALLOC_CAP_32BIT);
memset(zeros,0,BYTES_PER_FRAME);
uint32_t ulSamplesCounter = 0;
spi_transaction_t trans_desc = {
.rx_buffer = temp_buff,
.tx_buffer = zeros,
.length = 8*(BYTES_PER_FRAME)
};
xTaskToNotifyDRDY = xTaskGetCurrentTaskHandle();
gpio_intr_enable(GPIO_DRDY_PIN);//enable interrupt to identify new samples
ads1299_rdatac(ADS_ALL);//send command to AD to prepare it to the acquisition
spi_device_acquire_bus(spi_fast_handle, portMAX_DELAY);
gpio_set_level(GPIO_START_PIN, 1);//set start pin high to tell the AD to start acquiring samples
xTaskCreatePinnedToCore(vDataSendTask, "DataSend", 8*1024, &ulNumberOfSamples,
DATA_SEND_TASK_PRIORITY, NULL, PRO_CPU_NUM);//start task that will read the queue
while(ulSamplesCounter<ulNumberOfSamples)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);//waits for notification of new samples from ISR
spi_device_polling_transmit(spi_fast_handle, &trans_desc);
ESP_LOGI(TAG,"Last byte: %d",temp_buff[BYTES_PER_FRAME-1]);//print last received byte (always zero)
xQueueSend(xQueue, temp_buff, portMAX_DELAY);
ulSamplesCounter++;
}
//end of acquisiton
ESP_ERROR_CHECK( gpio_set_level(GPIO_START_PIN, 0) );
ESP_ERROR_CHECK( gpio_intr_disable(GPIO_DRDY_PIN) );
xTaskToNotifyDRDY = NULL;
spi_device_release_bus(spi_fast_handle);
ads1299_sdatac(ADS_ALL);
free(temp_buff);
free(zeros);
vTaskDelete(NULL);
}
Code: Select all
static void IRAM_ATTR vGPIOISRHandler(void* arg)
{
static BaseType_t xHigherPriorityTaskWoken;
if(xTaskToNotifyDRDY!=NULL){
vTaskNotifyGiveFromISR(xTaskToNotifyDRDY, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken == pdTRUE )
{
portYIELD_FROM_ISR();
}
}
}
Code: Select all
static int my_spi_init(void)
{
spi_bus_config_t bus_config = {
.mosi_io_num = GPIO_MOSI_PIN,
.miso_io_num = GPIO_MISO_PIN,
.sclk_io_num = GPIO_SCLK_PIN,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
spi_device_interface_config_t dev_config_slow = {
.mode = 1,
.clock_speed_hz = 4000000,
.spics_io_num = -1,
.queue_size = 1,
};
spi_device_interface_config_t dev_config_fast = {
.mode = 1,
.clock_speed_hz = SPI_MASTER_FREQ_20M,
.spics_io_num = -1,
.queue_size = 1,
};
spi_bus_initialize(VSPI_HOST, &bus_config, 1);
spi_bus_add_device(VSPI_HOST, &dev_config_slow, &spi_slow_handle);
spi_bus_add_device(VSPI_HOST, &dev_config_fast, &spi_fast_handle);
return 0;
}
Does anyone know why this is happening?
Thank you,
Mateus