cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Transmit does not transfer 8 bits

pass3master
Senior

We want to use HAL_SPI_Transmit to send data (master) in 8-bit units.
However, even though we have set SPI_DATASIZE_8BIT, data is sent in 16 bits.

Is there anything incorrect in the code below?

 

uint8_t *spi_txdata;

spi_txdata = (uint8_t *)malloc(2 * sizeof(uint8_t));

spi_txdata[0] = 1;

spi_txdata[1] = 2;

 

/* SPI5_CS High_out */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_SET);

 

/* SPI5_CLK En */

__HAL_SPI_ENABLE(&hspi5);

 

/* SPI5_CS Low_out */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET);

 

/* SPI5_Transmit */

hal_spi_err = HAL_SPI_Transmit(&hspi5, spi_txdata, sizeof(spi_txdata), 1000);

 

/* SPI5_CS High_out */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_SET);

 

**************************************************************

static void MX_SPI5_Init(void)

{

/* SPI5 parameter configuration*/

hspi5.Instance = SPI5;

hspi5.Init.Mode = SPI_MODE_MASTER;

hspi5.Init.Direction = SPI_DIRECTION_2LINES;

hspi5.Init.DataSize = SPI_DATASIZE_8BIT;

hspi5.Init.CLKPolarity = SPI_POLARITY_HIGH;

hspi5.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi5.Init.NSS = SPI_NSS_SOFT;

hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;

hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi5.Init.TIMode = SPI_TIMODE_DISABLE;

hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi5.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi5) != HAL_OK)

{

Error_Handler();

}

}

 

4 REPLIES 4
TDK
Guru

> hal_spi_err = HAL_SPI_Transmit(&hspi5, spi_txdata, sizeof(spi_txdata), 1000);

spi_txdata is a pointer, so sizeof(spi_txdata) = 4. (This is true regardless of whether the pointer is valid, or whatever you put in the malloc call).

If you want to send 2 bytes stored at spi_txdata:

 

hal_spi_err = HAL_SPI_Transmit(&hspi5, spi_txdata, 2, 1000);

 

If you feel a post has answered your question, please click "Accept as Solution".
BarryWhit
Lead II

Is there anything incorrect in the code below?

yes, you should have placed it inside a code block (looks like </> in the toolbar) so it would be easier to read.

 

There is no reason to call __HAL_SPI_ENABLE by hand,  HAL_SPI_Transmit does that for you.

In general, be careful about calling methods prefixed by double underscore, they are (usually) not intended to be called by user API, only internally. Sometimes, for example if you're replacing a HAL function that doesn't suit your needs with something slightly different, you will find yourself doing this.

 

Also, It's generally better to avoid malloc in embedded code unless there's an actual need.

 

#define TXBUF_BYTELEN (2)
uint8_t spi_txdata[TXBUF_BYTELEN];
spi_txdata[0] = 1;
spi_txdata[1] = 2;

// This works, since spi_txdata is now an array, not a pointer.
// Placing opaque constants behind a define, as done 
// here with TXBUF_BYTELEN is also good practice.
assert(sizeof(spi_txdata) == TXBUF_BYTELEN); 

 

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.

Thank you for your answer.
Even if you set it with 2 bytes, it will be sent 16 bits.
We would like to use 8-bit transmission, but what else should I do?

> Even if you set it with 2 bytes, it will be sent 16 bits.

Perhaps show a picture of what you're describing.

2 bytes are 16 bits.

If you want to send 8 bits, send 1 byte.

 

> hspi5.Init.DataSize = SPI_DATASIZE_8BIT;

It's clearly set up to send 8 bit word size.

If you feel a post has answered your question, please click "Accept as Solution".