Problem(assert) with spi_device_transmit()

afranko
Posts: 2
Joined: Wed Aug 15, 2018 2:10 pm

Problem(assert) with spi_device_transmit()

Postby afranko » Wed Aug 15, 2018 2:37 pm

Hi guys,

I'm trying to use SPI Master driver to control a DWM1000 module on my custom board.
Almost everything is fine, but after a while: I get an assertion. I checked with a counter and it fails at different palces at every turn.

Code: Select all

assertion "ret_trans==trans_desc" failed: file "C:/msys32/home/heged/esp/esp-idf/components/driver/spi_master.c", line 892, function: spi_device_transmit
abort() was cassertion alled at PC 0"ret_transx400d2fbf on ==trans_decore 0
I know that, the standard anwser is the following: "You can't use spi_device_transmit() if any transmission is queued with spi_device_queue_trans() but not exectued with spi_device_get_trans_result()."

The main problem is: I use only spi_device_transmit() in my code so anything shouldn't be queued.

The settings and related parts of my code:

Code: Select all

spi_bus_config_t buscfg={
		.miso_io_num=DW1000_MISO_PIN,
		.mosi_io_num=DW1000_MOSI_PIN,
		.sclk_io_num=DW1000_SCK_PIN,
		.quadwp_io_num=-1,
		.quadhd_io_num=-1,
		.max_transfer_sz=4096	
		};

spi_device_interface_config_t devcfg={
	    .clock_speed_hz = 1*1000*1000,           
		.mode = 0,                              
	    .spics_io_num = DW1000_SS_PIN,              
		.queue_size = 7,                         
		.flags = SPI_DEVICE_HALFDUPLEX,			
		};

Code: Select all

void spi_set_rate_low(void)
{
	printf("SET LOW\n");
	spi_bus_remove_device(spi);

	devcfg.clock_speed_hz=1*1000*1000;

	spi_bus_add_device(VSPI_HOST, &devcfg, &spi);
}

void spi_set_rate_high(void)
{
	printf("SET HIGH\n");
	spi_bus_remove_device(spi);

	devcfg.clock_speed_hz=8*1000*1000;

	spi_bus_add_device(VSPI_HOST, &devcfg, &spi);
}

Code: Select all

int writetospi(uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer)
{
	spi_transaction_t trans;
	memset(&trans, 0, sizeof(spi_transaction_t));
	uint8_t bigBuffer[headerLength*8+bodylength*8];
	for(uint16_t i = 0; i < headerLength; i++) {
		bigBuffer[i] = headerBuffer[i];
	}
	for(uint16_t i = 0; i < bodylength; i++) {
		bigBuffer[i+headerLength] = bodyBuffer[i];
	}

	trans.length = headerLength*8+bodylength*8;
	trans.tx_buffer = bigBuffer;

	if(spi_device_transmit(spi, &trans) != ESP_OK)
	{
		printf("SPI WRITE ERROR!\n");
		return -1;
	}

	return 0;
}

Code: Select all

int readfromspi(uint16 headerLength,  const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer)
{

	spi_transaction_t trans;
	memset(&trans, 0, sizeof(trans));

	trans.length 	= headerLength*8;
	trans.rxlength 	= readlength*8;
	trans.tx_buffer = headerBuffer;
	trans.rx_buffer = readBuffer;

	uint32_t err_code = spi_device_transmit(spi, &trans);

	if(err_code != ESP_OK) {
		printf("SPI READ ERROR!\n");
		return -1;
	}

	return 0;
}
One more thing: the assertion message is often wierd because some characters are not on corresponding place (as you can see above).

Any idea what can go wrong/I missed?

afranko
Posts: 2
Joined: Wed Aug 15, 2018 2:10 pm

Re: Problem(assert) with spi_device_transmit()

Postby afranko » Tue Sep 04, 2018 7:59 am

After a lot of debugging I figured it out: the readfromspi() function is called multiple times: the first call ain't returned yet, when it's called second time and that messes up the SPI. I wrote this code first on another platform, where I could use ciritical section that defends SPI, but due to FreeRTOS portENTER_CRITICAL() can't be used, since the SPI driver uses FreeRTOS functions.

Are there any efficient method - to substitude critical section - that I can use to solve this problem?

Return to “ESP32 IDF”

Who is online

Users browsing this forum: ESP-MJ, joe@shkila.com and 17 guests