Problem(assert) with spi_device_transmit()

afranko
Posts: 3
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: 3
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?

frcgnn
Posts: 1
Joined: Tue Oct 29, 2019 2:58 pm

Re: Problem(assert) with spi_device_transmit()

Postby frcgnn » Tue Oct 29, 2019 3:05 pm

Hi,
I'm very newbie in ESP-IDF programming... I have a esp32 and I'm trying to communicate with a dwm1000 through the spi but I'm issuing the same problems...could you please post your code?

Thanks a lot.

Cheers,
Francesco

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem(assert) with spi_device_transmit()

Postby ESP_Sprite » Fri Nov 01, 2019 10:02 am

To answer the original question: you would place e.g. a mutex around the call instead of a spinlock.

andreasfw
Posts: 1
Joined: Mon Nov 21, 2022 9:56 am

Re: Problem(assert) with spi_device_transmit()

Postby andreasfw » Mon Nov 21, 2022 12:53 pm

Hi guys,

I'm facing the same issue in my code [Environment: esp-idf 4.3.2]: I get the following assert failure:

assert failed: spi_device_transmit spi_master.c:859 (ret_trans == trans_desc)

Code: Select all

assert failed: spi_device_transmit spi_master.c:859 (ret_trans == trans_desc)

0x40081a4a: panic_abort at C:/dev/esp/esp-idf/components/esp_system/panic.c:404
Backtrace:0x40081a4a:0x3ffda200 0x40091ba5:0x3ffda220 0x400962a5:0x3ffda240 0x40193955:0x3ffda360 0x40119ea7:0x3ffda390 0x4011a525:0x3ffda3e0 0x400e0ae2:0x3ffda400 0x400dec2b:0x3ffda430 0x400dec9d:0x3ffda450 0x400e303e:0x3ffda480 0x400dc9ff:0x3ffda4b0

0x40091ba5: esp_system_abort at C:/dev/esp/esp-idf/components/esp_system/system_api.c:112

0x400962a5: __assert_func at C:/dev/esp/esp-idf/components/newlib/assert.c:85

0x40193955: spi_device_transmit at C:/dev/esp/esp-idf/components/driver/spi_master.c:859 (discriminator 1)

0x40119ea7: WriteCmnd at c:\dev\fw\build/../display/spi_4wires.c:216
The function WriteCmnd is called by a separate FSM to send a command to a SPI LCD display (e.g. turn on, turn off, inversion on). Its content is the following:

Code: Select all

SemaphoreHandle_t   spi_mutex = NULL;  //mutex, for spi command queue operation
void WriteCmnd( uint8_t aCmnd )
{
  esp_err_t        ret;
  spi_transaction_t t;

  /* clear entire transaction buffer */
  memset( &t, 0, sizeof( t ));

  /* initialize transaction buffer */
  t.length       = 8;                     /* commands are always one byte */
  t.tx_data[ 0 ] = aCmnd;                 /* store the command */
  t.flags        = SPI_TRANS_USE_TXDATA;

  /* send the command in polling mode */
  xSemaphoreTake(spi_mutex, portMAX_DELAY);
  ret = spi_device_transmit( SpiDeviceHandle, &t );
  assert( ret == ESP_OK );
  xSemaphoreGive(spi_mutex);
}
ESP_Sprite wrote: To answer the original question: you would place e.g. a mutex around the call instead of a spinlock.
I tried to protect the call to spi_device_transmit call within my code with a mutex, since there are multiple tasks entering that section (e.g. esp_timer, main, gpio_task), but it does not help.

Unfortunately, this behavior is not reproducible systematically.

Do you see any potential reason for this assert to fail and a way to fix it?

Thank you!

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem(assert) with spi_device_transmit()

Postby ESP_Sprite » Tue Nov 22, 2022 7:08 am

Are you sure that that is the only location in the code where you do anything with that particular SPI device? You'd need to mux off any other interactions as well.

buddhika
Posts: 7
Joined: Tue Sep 20, 2022 8:14 am

Re: Problem(assert) with spi_device_transmit()

Postby buddhika » Mon Jan 02, 2023 11:44 am

dear all,

I am facing the same issue . I am using a RFM98 Lora module. Some times it fails and reboots with showing error "assertion "ret_trans==trans_desc" failed". Some times stops triggering the interrupt pin. any one who has experience using this module with ESP32, any guidance will be highly appreciated .

Who is online

Users browsing this forum: No registered users and 121 guests