2018-10-30 11:41 AM
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
2018-10-30 12:00 PM
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... ;)
2018-10-30 12:19 PM
...and exactly what did you think the result of "(uint16_t)65537" would be?
Sigh.
2018-10-30 12:19 PM
...and exactly what did you think the result of "(uint16_t)65537" would be?
Sigh.
2018-10-30 12:44 PM
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.
2018-10-30 02:56 PM
"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.
2018-10-31 09:17 AM
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
2018-10-31 09:25 AM
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
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
2018-10-31 09:34 AM
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.
2018-10-31 09:44 AM
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