SPI HALFDUPLEX looses last bytes

KanyeKanye
Posts: 54
Joined: Mon Dec 05, 2016 12:34 am

SPI HALFDUPLEX looses last bytes

Postby KanyeKanye » Thu Dec 05, 2019 2:30 pm

I struggle with a SPI driver: my devices need some setup time between CS and CLK setup. Using command phase (command_bits>0), cs_ena_pretrans is avaliable only in HALFDUPLEX.
HALFDUPLEX seems to loose some last received bytes if transaction before tx anything:

Code: Select all

	// initialize
	spi_bus_config_t buscfg = {
		.miso_io_num=PIN_NUM_SPI_MISO, .mosi_io_num=PIN_NUM_SPI_MOSI, .sclk_io_num=PIN_NUM_SPI_CLK,
		.quadwp_io_num=-1, .quadhd_io_num=-1, .max_transfer_sz=1024
	};
	spi_device_interface_config_t devcfg = {
		.spics_io_num=PIN_NUM_SPI_CS,
		.clock_speed_hz=4000000, // 4MHz max
		.mode=1, // SPI MODE 1
		.command_bits=8, // 8-bit command length
		.queue_size=1,
		.cs_ena_pretrans = 1,
		.flags = SPI_DEVICE_HALFDUPLEX
	};

	spi_bus_initialize(VSPI_HOST, &buscfg, 1 /*dma_chan - 0 no DMA*/);
	ESP_ERROR_CHECK(spi_bus_add_device(VSPI_HOST, &devcfg, &spi));
	
	// transmit
	uint8_t N = 1; // ****** set N to 0, 1, 2, ...
	if (N > 0) { // skip if N == 0
	spi_transaction_t transaction;
	memset(&transaction, 0, sizeof(transaction));
	transaction.cmd = 0x81;
	transaction.length = N*8;
	transaction.flags = SPI_TRANS_USE_TXDATA;
	transaction.tx_data[0] = 0x00;
	transaction.tx_data[1] = 0x00;
	transaction.tx_data[2] = 0x00;
	transaction.tx_data[3] = 0x00;
	assert(spi_device_polling_transmit(spi, &transaction) == ESP_OK);
	ESP_LOGI(TAG, "Transmitted: %d bytes [%02x %02x %02x %02x]", N, transaction.tx_data[0], transaction.tx_data[1], transaction.tx_data[2], transaction.tx_data[3]);
	}
	
	// receive
	char * buffer = heap_caps_malloc(8, MALLOC_CAP_DMA);
	spi_transaction_t transaction;
	memset(&transaction, 0, sizeof(transaction));
	transaction.cmd = 0x01;
	transaction.rx_buffer = buffer;
	transaction.rxlength = 8 * 8;
	transaction.length = transaction.rxlength;
	assert(spi_device_polling_transmit(spi, &transaction) == ESP_OK);
	ESP_LOGI(TAG, "Received: %02x %02x %02x %02x %02x %02x %02x %02x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]);
When there is no transmitting part (N=0) received log looks alike:
Received: 11 11 11 11 11 11 11 11

When N = 1: Received: 11 11 11 11 11 11 11 00
When N = 2: Received: 11 11 11 11 11 11 00 00
When N = 3: Received: 11 11 11 11 11 00 00 00
When N = 4: Received: 11 11 11 11 cc 6c fb 3f

I checked using a logical analyzer: Regardless of the value of N, the received block is always correct (0x11 .. only).
Why last N bytes are loosed? Why zeros or this strange block when N=4?

Who is online

Users browsing this forum: No registered users and 118 guests