cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI master OVR error

DZimm.9
Associate II

Hi everyone,

I'm using the STM HAL for my SPI

communication in master mode. To

readout my ADC, I implemented a state machine, which starts

the ADC conversion and then once a data ready signal is received, the data is

clock out in SPI full duplex mode.

Once in a while the SPI handling stalls due to an overrun error. I can clear the error and reset the communication FSM, everything works as before, but I would like to know why I even end up with an overrun error... What I don’t get: the SPI is in master mode and the master/HAL decides when it is ready to clock another byte out. But somehow the HAL starts the next transfer even though the byte is not ready yet.

Here is a short overview how I use the HAL in the code, maybe I missunterstood how to use it...

SPI initialization:

The SPI is setup like this:

               // SETUP SPI 
               adc->spiHandle = spiHandle; 
 
               // SPI: Master / Full duplex / 8bit data / MSB first 
               adc->initStruct.Mode = SPI_MODE_MASTER;
               adc->initStruct.Direction = SPI_DIRECTION_2LINES; 
               adc->initStruct.DataSize = SPI_DATASIZE_8BIT;
               adc->initStruct.FirstBit = SPI_FIRSTBIT_MSB;
 
               // CPOL = 0 = low (in idle) / CPHA = 1 = triggers on falling edge 
               adc->initStruct.CLKPolarity = SPI_POLARITY_LOW;
               adc->initStruct.CLKPhase = SPI_PHASE_2EDGE;
 
               // software chip select
               adc->initStruct.NSS = SPI_NSS_SOFT;
 
               // F_SCL_max <= 2MHz, SPI base frequency = 42MHz -> prescaler = 8 (2 would be possible too)
               adc->initStruct.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
 
               // unused additional functionality
               adc->initStruct.TIMode = SPI_TIMODE_DISABLE;
               adc->initStruct.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
               adc->initStruct.CRCPolynomial = 10;
 
               // trigger HAL init
               if (HAL_SPI_Init(adc->spiHandle) != HAL_OK) {
                               Error_Handler();
}

To initiate a conversion, the FSM waits until the SPI is ready to be used and then starts the transfer with HAL_Transmit_IT:

// FSM while loop:
 
while(1) {
               ...
               case Start_Conversion:
               if(HAL_SPI_GetState(adc->spiHandle) == HAL_SPI_STATE_READY) {
                               // SPI free to use -> start config upload
                              // data preparation in pBuffer and dataLen
                               ...
 
                               HAL_SPI_Transmit_IT(adc->spiHandle, pBuffer, dataLen);
                               // move to next state -> await SPI TX complete event
               }
break;
                ...
}

Once the SPI transfer is complete, the FSM waits for the data ready signal and starts reading the ADC data:

while(1) {
               ...
               Case Read_Conversion:
               if(HAL_SPI_GetState(adc->spiHandle) == HAL_SPI_STATE_READY) {
                              // SPI free to use -> start config upload                         
                              // data preparation in pBuffer and dataLen
                               ...
 
                               if(HAL_SPI_TransmitReceive_IT(adc->spiHandle, adc->txBuffer, adc->rxBuffer, 4) == HAL_OK) {
                                              // reinit FSM to start a new conversion
                                               ...
	return true;
                              }
               }
break;
                ...
}

Thanks and best regards

Daniel

0 REPLIES 0