ESP-IDF 32bit register SPI read/write

BinaryPoet
Posts: 9
Joined: Thu Aug 31, 2023 1:01 pm

ESP-IDF 32bit register SPI read/write

Postby BinaryPoet » Mon May 20, 2024 3:33 pm

Hello,
I am trying to read/write 32 bit registers from stepper driver TMC5240 using a ESP32S3 CPU.

According to stepper DS, the write operation should be performed writing the register address + 0x80 followed by 32 bit register values.
For example, for a write access to the register (VACTUAL), the address byte has to be set to 0x80 + 0x22 = 0xA2, so to write AABBCCDD to this register I should send 0xA2 0xAA 0xBB 0xCC.

The read operation consists in writing the register address followed by 4 bytes of zeros.

Does the 32 bits limit of SPI_TRANS_USE_TXDATA, SPI_TRANS_USE_RXDATA includes also the address?

the following functions does not work, in particular I always read the same value (0x39) from all the registers.

Code: Select all

int32_t tmc5240_readInt(TMC5240TypeDef *tmc5240, uint8_t address)
{
	uint8_t channel = tmc5240->config->channel;

	if (channel < stepperINVALID)
	{
		 esp_err_t err;
		 uint32_t RxDataBuff;
		 uint32_t value = 0;

		 // uint8_t pBuffer2[2];

		 spi_transaction_t spitr = {
		 	      .cmd       = address,
		 	      .length    = 4 * 8,
		 	      .flags     = SPI_TRANS_USE_TXDATA,
		 		  .tx_data = {value},
				  .rx_buffer = &RxDataBuff,
				  .rxlength = 32
		 	      //.user      = (void*) &sensor_ctx,
		 	  };

		 err = spi_device_acquire_bus(m_stepper_cfg[channel].hspi, portMAX_DELAY);
		 if (err != ESP_OK ) printf("SPI ACQ BUS ERROR\n");

		 err = spi_device_transmit(m_stepper_cfg[channel].hspi, &spitr);
		 ESP_ERROR_CHECK(err);
		 if (err != ESP_OK ) printf("SPI READ ERROR address %d\n", address);

		 spi_device_release_bus(m_stepper_cfg[channel].hspi);
		 //if (err != ESP_OK ) printf("SPI ACQ BUS ERROR\n");

		 //uint32_t res = SPI_SWAP_DATA_RX(RxDataBuff, 32);

		 return(RxDataBuff);
	}
	return -1;
}

Code: Select all

void   tmc5240_writeInt(TMC5240TypeDef *tmc5240, uint8_t address, int32_t value)
{
	uint8_t channel = tmc5240->config->channel;

	esp_err_t err;

	spi_transaction_t t = {
	      .cmd       = address + SPI_WRITE_CMD,
	      .length    = 4 * 8,
	      .flags     = SPI_TRANS_USE_TXDATA,
		  .tx_data = {value},
	  };

	err = spi_device_acquire_bus(m_stepper_cfg[channel].hspi, portMAX_DELAY);
	if (err != ESP_OK ) printf("SPI ACQ BUS ERROR\n");
	assert(err==ESP_OK);
	
	err = spi_device_polling_transmit(m_stepper_cfg[channel].hspi, &t);
	if (err != ESP_OK ) printf("SPI WRITE ERROR (%d)\n", address);

	spi_device_release_bus(m_stepper_cfg[channel].hspi);
}

BinaryPoet
Posts: 9
Joined: Thu Aug 31, 2023 1:01 pm

Re: ESP-IDF 32bit register SPI read/write

Postby BinaryPoet » Tue May 21, 2024 11:49 am

Finally I get the SPI working by setting the address bits to 8:

Code: Select all

spi_device_interface_config_t devcfg;

devcfg.clock_speed_hz = 10*1000*1000;           //Clock out at 10 MHz
devcfg.mode = 0;                                //SPI mode 0
devcfg.spics_io_num = (stepperAZ_AR == stepper ) ? PIN_NUM_CS1 : PIN_NUM_CS2;//CS pin
devcfg.queue_size = 8; 	//We want to be able to queue 5 transactions at a time
devcfg.command_bits = 0;
devcfg.address_bits = 8; 
and with the following read/write functions:

Code: Select all

int32_t tmc5240_readInt(TMC5240TypeDef *tmc5240, uint8_t address)
{
	uint8_t channel = tmc5240->config->channel;

	if (channel < stepperINVALID)
	{
		 esp_err_t err;

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

		spitr.flags = 0;
		spitr.length = (8*4);
		spitr.rxlength = (8*4);
		spitr.addr = address;
		spitr.tx_buffer = &TxBuff;
		spitr.rx_buffer = &RxBuff;

		err = spi_device_acquire_bus(m_stepper_cfg[channel].hspi, portMAX_DELAY);
		if (err != ESP_OK ) printf("SPI ACQ BUS ERROR\n");

		err = spi_device_polling_transmit(m_stepper_cfg[channel].hspi, &spitr);
		ESP_ERROR_CHECK(err);
		if (err != ESP_OK ) printf("SPI READ ERROR address %d\n", address);

		err = spi_device_polling_transmit(m_stepper_cfg[channel].hspi, &spitr);
		ESP_ERROR_CHECK(err);
		if (err != ESP_OK ) printf("SPI READ ERROR address %d\n", address);

		spi_device_release_bus(m_stepper_cfg[channel].hspi);

		uint32_t res = SPI_SWAP_DATA_RX(RxBuff, 32);

		return(res);
	}
	return -1;
}




void   tmc5240_writeInt(TMC5240TypeDef *tmc5240, uint8_t address, int32_t value)
{
	uint8_t channel = tmc5240->config->channel;

	esp_err_t err;
	spi_transaction_t spitr;
	memset(&spitr, 0, sizeof(spi_transaction_t));
	TxBuff = SPI_SWAP_DATA_RX(value, 32);
	RxBuff = 0;

	spitr.flags = 0;
	spitr.length = (8*4);
	spitr.rxlength = 0;
	spitr.addr = address | SPI_WRITE_CMD;
	spitr.tx_buffer = &TxBuff;
	spitr.rx_buffer = &RxBuff;

	err = spi_device_acquire_bus(m_stepper_cfg[channel].hspi, portMAX_DELAY);
	if (err != ESP_OK ) printf("SPI ACQ BUS ERROR\n");
	assert(err==ESP_OK);

	err = spi_device_polling_transmit(m_stepper_cfg[channel].hspi, &spitr);
	if (err != ESP_OK ) printf("SPI WRITE ERROR (%d)\n", address);
	assert(err==ESP_OK);

	spi_device_release_bus(m_stepper_cfg[channel].hspi);
}
The double read is related to the particular read mechanism of the device.

Who is online

Users browsing this forum: No registered users and 98 guests