cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Transmit_IT blocks

Marc1
Associate III

Hello,

I've a problem with HAL_SPI_Transmit_IT() function as it blocks similar to HAL_SPI_Transmit.

Microcontroller: STM32F205VCT6

Compiler: arm-none-eabi-gcc, gcc version 7.3.1 20180622 (release)

[ARM/embedded-7-branch revision 261907] (15:7-2018-q2-4)

Code is generated by STM32CubeMX, Version 4.27.0

Activated peripherals:

SPI3 (Transmit Only Master), SPI3 global interrupt enabled

GPIOA.9 as output

My own code:

uint8_t buffer[3] = { 1, 2, 3 };
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_SPI_Transmit_IT(&hspi3, buffer, 1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);

If I hand over one single byte to HAL_SPI_Transmit_IT() it does not work non-blocking as you can see at the following scope.

0690X000006CGEWQA4.png

If I hand over more than one byte (e.g. 3 bytes), HAL_SPI_Transmit_IT() works correctly (non-blocking).

0690X000006CGEbQAO.png

What could be the reason? Why can't I send one single byte in non-blocking mode?

17 REPLIES 17

@Marc​ , what other library do you use then? or do you make changes at a register level?

Marc1
Associate III

I only use the CMSIS libraries.

S.Ma
Principal

For SPI master, transmission complete comes from RXNE. For generating the clocks, transmission is responsible.

DFlam
Associate II

I have a similar problem but, in my case, I use DMA on a slave SPI using Keil RTX OS.

In my scenario the SPI_DMATransmitCplt function is called inside ISR but, since systick is used for timeout, in case of error (when timeout could happen) systick is not incremented because the systick interrupt has lower priority than DMA interrupt; final result is a complete freeze into an endless loop iside DMA ISR.

I don't want to increase systick interrupt priority to avoid unpredictable behaviour in case of task switch inside ISR so I soved the problem creating a new DMA ISR function to set a thread flag to unblock a dedicated task that will execute the SPI_DMATransmitCplt. In this way ISR function will always exit and timeout is handled on a dedicated task leaving RTOS run, increment systick and making timeout expire.

I don't like to modify standard HAL libraries and this was the only solution I found.

Has anyone had the same issue and maybe solved it in a smarter way?

Thanks,

Davide.

You've been told several times in this thread already - Rx completion indicates Tx completion too.

JW

DFlam
Associate II

Yes, I know, but unfortunately HAL library waits for TX complete, RX complate and BUSY flag reset for both master and slave transaction.

Finally I found the root cause of my problem: it's an hardware bug on BUSY flag (sometimes not cleared at the end of transaction); that's why sometimes the code exited for timeout.

Being this, the only solution is to modify the HAL library to only check for reliable and usefull flags in save mode.

Thanks,

Davide.

S.Ma
Principal

Use bi directional SPI master mode, if you don't need receive MISO just don't activate the GPIO. (the monodir seems to have weird behaviour such as SCK gets out of control, also on new SPI IP, don't use the MISO/MOSI swap, it won't work as expected)

In this case, use DMA TX to trigger the transmission clocks. don't use any interrupt here.

Also activate prior this the DMA RX and trigger the completion DMA interrupt only.

When the interrupt comes, you are sure all is done.

And if you want multiple SPI masters running concurrently (which justifies multiple SPI IPs on the chip), above method works just fine as well.

You'll need to build an interrupt based state machine(s). Works with HAL.

Cvega.11
Associate II

Hello my friend

To communicate with the wifi module, use the SPI2 of the board but no more, the board does not give me any answer. Any idea how to implement an example ???

How to send the AT commanders in the SPI communication through the following lines:

HAL_SPI_TransmitReceive_IT (SPI_HandleTypeDef * hspi, uint8_t * pTxData, uint8_t * pRxData, uint16_t Size)

HAL_StatusTypeDef HAL_SPI_Transmit_IT (SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size)