cancel
Showing results for 
Search instead for 
Did you mean: 

How to send 10-bit message using HAL_SPI_TRANSMIT

PMalh.1
Associate II

I am trying to interface with an AD8400 single channel digital potentiometer. It communicates over SPI and requires 2 address bits and 8 data bits to set its resistance. I am having trouble figuring out how to send a 10-bit message.

I have set the data size for the SPI channel to 10-bits in CubeMX and I can verify that that is the case in SPI initialisation structs within my code.

However, whenever I use HAL_SPI_TRANSMIT I get an error if the second parameter is not a uint8_t. I have checked the documentation for my microcontroller (the STM32F303CBT6) and I believe it should support transmissions of any data size between 4-16 bits.

0693W00000Y9hW9QAJ.png0693W00000Y9hW4QAJ.png

9 REPLIES 9
Mike_ST
ST Employee

Hello,

The second parameter of the HAL_SPI_Transmit() function is a uint8_t*, not a uint8_t:

HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);

So, if you want to send one 10 bit data, I guess you are storing it in a uint16_t variable.

In that case you have to cast it using (uint8_t*) &my_value, while taking care about the endianness too (i.e. you might have to switch MSB and LSB)

:HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, (uint8_t*) &my_value, 1, uint32_t Timeout);

Hope that helps.

PMalh.1
Associate II

Thanks for your reply. I understand now that the second parameter is a pointer to the data and the variable itself could be 16-bits. However, this raises the question, will all 16-bits be transmitted or will the transmission stop at 10-bits? I ask because if all 16-bits are transmitted, I may have to pad the 6 least significant bits.

Peter BENSCH
ST Employee

You will also find some additional hints on a similar question.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
S.Ma
Principal

I would try this:

  1. Wait the SPI is IDLE and FIFO are EMPTY
  2. Set the SPI to 10 bit mode without disabling it (violate the recommendation)
  3. Perform a 16 bit write to the SPI DR and observe the output
  4. When the SPI is IDLE and FIFO are EMPTY (end of transfer is known by RNXE)
  5. then change again the SPI bit to what you want (8, 16, etc...)

The other post is different as it's just a multiple of 8 bit, which is different than 8+2 or 10

PMalh.1
Associate II

Hi S.Ma,

I had seen the other post earlier and came to a similar conclusion. While it mentions the prospect of 9-bit messages, multiples of 8 were used.

As for what you have suggested, I would like to provide some context and ask a follow up question. This is a dedicated SPI bus. It only ever needs to send 10-bit messages. Can I assume that initialising it in 10-bit mode is sufficient or is setting it to 10-bit after it was initialised in 16-bit preferred due to something strange to do with how the HAL or the microcontroller work.

S.Ma
Principal

You can change the SPI register serializer to any size when it is idle. So how it is initialized is not so important.

However, most of the new SPI version got a 32 bit FIFO when writing to DR.

I guess you need to experiment (you need to try it as I was playing with this SPI dynamic length to generate SWD protocol). Using the HAL adds another doubt about what will be really generated.

My guess is that if you are in 10 bit mode and you use DMA to pipe data in/out to the SPI DR in 16 bit mode, the 10 bit LSB chunk will reach the shift register. Bijectivally, the received data as 16 bit DMA transfer will probably contain extra 000000.... there is a detailed SPI chapter in the reference manual that might shed some light of what is guaranteed. If this is not precise enough, maybe confirm that the RefMan SPI description needs edits for better assimilation by users.

PMalh.1
Associate II

Thanks for your reply. The best course of action seems to be writing some code on to a test-board and experimenting. I will also give my microcontroller's reference manual another look.

Is it possible to set the SPI DR to 10-bit mode? If not, I will keep in mind what you said about the 10-bit LSB chunk and just send a 16-bit message with the LSBs padded with ones. This way the first 10 MSBs can contain the address and message but the last bits will be ignored by the potentiometer as it will be looking for two address bits which are 00.

I checked the micro's reference manual. Data frame format is covered on page 961-962. From what I have read, sending a 10-bit message should be fine. That said, I am still going to go ahead and test to be sure.

S.Ma
Principal

👍