spi driver, spi_get_trans_result stuck
Posted: Fri Dec 04, 2020 7:08 pm
Hi,
I am trying to write an SPI driver for my project, but cant seems to work. I've tried to use spi_device_transmit, spi_device_polling_transmit, queue_trans, get_trans but i never seem to be able to get it working. I've tried multiple different bus and device config. But it is always stuck, waiting for the slave device to answer.
The spi_device_transmit seems alive since it does not trigger my thread watchdog. Inside the function, spi_device_queue_trans return ESP_OK, it is stuck inside spi_get_trans_result.
I am trying to write an SPI driver for my project, but cant seems to work. I've tried to use spi_device_transmit, spi_device_polling_transmit, queue_trans, get_trans but i never seem to be able to get it working. I've tried multiple different bus and device config. But it is always stuck, waiting for the slave device to answer.
Code: Untitled.cpp Select all
void initializeSPI(void)
{
esp_err_t err;
spi_bus_config_t buscfg;
buscfg.miso_io_num=19;
buscfg.mosi_io_num=23;
buscfg.sclk_io_num=18;
buscfg.quadwp_io_num=-1;
buscfg.quadhd_io_num=-1;
buscfg.max_transfer_sz=4094;
err=spi_bus_initialize(SPI3_HOST, &buscfg, 1); //return ESP_OK
printf("spi initialize err : %s\r\n", esp_err_to_name(err));
}
// SPI
#define SPI_MAX_CS 34 // GPIO 33 is the last port that can be used as output
#define BUFFER_SIZE 200
spi_device_handle_t spi[SPI_MAX_CS] = { 0 };
uint8_t _csPin_ = 21;
ICM_20948_SPI::ICM_20948_SPI()
{
}
ICM_20948_Status_e ICM_20948_SPI::begin(uint8_t csPin, uint32_t SPIFreq)
{
esp_err_t err;
spi_device_interface_config_t devcfg;
devcfg.clock_speed_hz=SPIFreq;
devcfg.mode=ICM_20948_SPI_DEFAULT_MODE;
devcfg.spics_io_num=_csPin_;
devcfg.queue_size=1;
devcfg.flags = 0;
devcfg.command_bits = 0; // no command bits used
devcfg.address_bits = 0; // register address is first byte in MOSI
devcfg.dummy_bits = 0; // no dummy bits used
devcfg.pre_cb =NULL;
devcfg.post_cb=NULL;
spi[_csPin_] = (spi_device_handle_t)malloc(sizeof(spi_device_handle_t));
err=spi_bus_add_device(SPI3_HOST, &devcfg, &spi[_csPin_]); // return ESP_OK
printf("icm 20948 add device err : %s\r\n", esp_err_to_name(err));
if (err != ESP_OK) free (spi[_csPin_]);
// Set up the serif
_serif.write = ICM_20948_write_SPI;
_serif.read = ICM_20948_read_SPI;
_serif.user = (void *)this; // refer to yourself in the user field
// Link the serif
_device._serif = &_serif;
// Perform default startup
status = startupDefault();
if (status != ICM_20948_Stat_Ok)
{
return status;
}
return ICM_20948_Stat_Ok;
}
ICM_20948_Status_e ICM_20948_write_SPI(uint8_t reg, uint8_t *data, uint32_t len, void *user)
{
static uint8_t mosi[BUFFER_SIZE];
mosi[0] = reg;
for (int i = 0; i < len; i++)
mosi[i+1] = data[i];
if (!spi_transfer_pf (mosi, NULL, len+1))
{
return ICM_20948_Stat_Err;
}
return ICM_20948_Stat_Ok;
}
ICM_20948_Status_e ICM_20948_read_SPI(uint8_t reg, uint8_t *buff, uint32_t len, void *user)
{
if (user == NULL)
{
return ICM_20948_Stat_ParamErr;
}
static uint8_t mosi[BUFFER_SIZE];
static uint8_t miso[BUFFER_SIZE];
memset (mosi, 0xff, BUFFER_SIZE);
memset (miso, 0xff, BUFFER_SIZE);
mosi[0] = reg;
if (!spi_transfer_pf (mosi, miso, len+1))
{
return ICM_20948_Stat_Err;
}
for (int i=0; i < len; i++)
buff[i] = miso[i+1];
return ICM_20948_Stat_Ok;
}
uint32_t spi_transfer_pf (const uint8_t *mosi, uint8_t *miso, uint32_t len)
{
spi_transaction_t spi_trans;
memset(&spi_trans, 0, sizeof(spi_trans)); // zero out spi_trans;
spi_trans.tx_buffer = mosi;
spi_trans.rx_buffer = miso;
spi_trans.length=len*8;
spi_trans.user=(void*)0;
// Stuck in here
if (spi_device_transmit(spi[_csPin_], &spi_trans) != ESP_OK) //spi_device_polling_transmit trigger watchdog
{
printf("spi device transmit != ESP_OK\r\n");
return 0;
}
printf("spi device transmit = ESP_OK\r\n");
return len;
}