cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Transmit uint16_t size limit

SSmit.0
Associate II

Hello,

I would like to send a uint32_t size array via HAL_SPI_Transmit / HAL_SPI_Transmit_DMA but both are limited to 16 bit size.

I have tried casting as

HAL_SPI_Transmit(&hspi1,Array,(uint16_t)65537),10000)

but this doesn't work.

I have also tried editing the SPI driver and changing TxXferSize and TxXferCount to uint32_t but this only seems to get rid of the compiler warning and still overflows somewhere, i.e only 1 byte from the array is sent.

Please could anyone advise what else I need to change?

Thanks

13 REPLIES 13

Your approach.

The libraries have their limitations. You either accept them and maybe work around them (e.g. by repeated call of those functions), or write your own.

There's also an underlying hardware issue: the DMA's NDTR (counting) register is 16-bit long.

JW

PS. As somebody whose nick starts with "pic18f" you really shouldn't be shocked by a 16-bit limitation... ;)

...and exactly what did you think the result of "(uint16_t)65537" would be?

Sigh.

...and exactly what did you think the result of "(uint16_t)65537" would be?

Sigh.

GSome
Associate III

HAL_SPI_Transmit requires a pointer to the array

change HAL_SPI_Transmit(&hspi1,Array,(uint16_t)65537),10000)

to HAL_SPI_Transmit(&hspi1,(uint16_t*)Array, 65537 * 2 ,10000)

*2 require as it will then send the 32 bit number as 2 16 bit numbers;

The receiving end would then need to be able to handle it this way.

"HAL_SPI_Transmit requires a pointer to the array

change HAL_SPI_Transmit(&hspi1,Array,(uint16_t)65537),10000)

to HAL_SPI_Transmit(&hspi1,(uint16_t*)Array, 65537 * 2 ,10000)

*2 require as it will then send the 32 bit number as 2 16 bit numbers;

The receiving end would then need to be able to handle it this way."

Pretty sure that's not going to work in the way you describe.

You'd need to tell the SPI to use 16-bit transactions, the DMA count is in transfer units, not bytes, but is still bounded by 16-bit limits for the number space.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SSmit.0
Associate II

Thank for the replies, yes despite my username I am very new to micro controller programming thus sticking to HAL.

So I was thinking the simplest way would be to truncate the array at 65535 and send it in two HAL_SPI_Transmit pieces.

I.e HAL_SPI_Transmit(send first 65535 number of bytes), then HAL_SPI_Transmit(send remainder of array offset by 65535). Is it possible to do this?

Thanks

GSome
Associate III

My answer "change HAL_SPI_Transmit(&hspi1,Array,(uint16_t)65537),10000)

to HAL_SPI_Transmit(&hspi1,(uint16_t*)Array, 65537 * 2 ,10000)"

makes two assumptions

  1. ARRAY is defined as uint32_t ARRAY[65537];
  2. SPI mode is set to 16 bit as this is the maximum in HAL

I made a n error in that (uint16_t*)Array should be (uint16_t*)&Array

The (uint16_t*) cast tells the SPI_Transmit ARRAY is 16 bits not 32 bit.

"HAL_SPI_Transmit(&hspi1,(uint16_t*)&Array, 65537 * 2 ,10000)"

I do this with my ADC to PC transfer where I set up a 32 bit buffer to receive ADC Data

and transmit as 8 bit bytes

I know this works.

   uint32_t startBuffer[1];

   startBuffer[0] = 0x53530a0d; // SS\r\n

HAL_UART_Transmit_DMA(&huart6,(uint8_t *)&startBuffer, 4 ); // transmit 4 bytes

I see no reason this would not work the same in SPI

65537 * 2 still doesn't fit in a uint16_t width variable. The largest value there is 65535, and you're more than twice that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SSmit.0
Associate II

Hi Geosom & Clive,

To clarify my Array is: uint16_t Array [76800], (I posted it as 8 bit for simplification).

My suggested approach was

HAL_SPI_Transmit(&hspi1,(uint16_t*)Array, 65535 ,10000)

HAL_SPI_Transmit(&hspi1,(uint16_t*)Array, **LAST 11264** ,10000) -- I'm not sure how to implement this or if it's possible?

Thanks