2

I'm working on a project with the STM32F303RE that requires full-duplex SPI and I am using the HAL library provided by STM. While all lines are working in terms of SCK, MOSI and MISO, I've noticed that the chip select line goes low much longer than necessary and seems to be triggering off around 20kHz as opposed to the 2MHz SPI. This is a problem as the slave I am using triggers off the CS line and during multiple SPI calls the data becomes corrupted. How can I fix the timing?

I'm currently using a manual GPIO that simply sets low/high before and after the SPI call. From reading online, it seems the CS pin is a problem source for quite a few people as there is also the option to use a hardware NSS signal although people recommend against this as it doesn't work properly.

// Set SS pin low to activate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

// Read Temp
if(HAL_SPI_TransmitReceive(&hspi2, (uint8_t*)&master_buffer_tx[4], (uint8_t*)&master_buffer_rx[4], 1, 1000)!=HAL_OK){
      Error_Handler();
}

// Check finished
while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY){
}

// Set SS pin high to deactivate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);

HAL_Delay(10);

I would expect CS to go low roughly half a cycle before SCK and similarly afterwards. These are the possible ideas I've had: Is the "Check finished" line causing the problem? Could it be my clock settings? Should the GPIO pin I use be the same as where NSS would be? Should I be using hardware NSS? Do I need to use interrupts and DMA?

Sorry if any of this seems naive as I'm still working on my understanding of the micro controller. Thanks!

CS and SCK timing

sophia_ash
  • 21
  • 1
  • 3
  • So there appears to be 30uS delay before CS is set to idle. That can be quite a few cycles, but it really depends your clock. Same for 500kHz vs 2MHz - that's definitely a clock misconfiguration. What are your clocks? Am I reading correctly 10V/div on CH2? – domen Apr 08 '19 at 13:39
  • Sorry for the late reply, I have updated the image and edited my question as I made a mistake, CS goes low for around 50us and therefore has frequency of around 20kHz. I believe my AHB bus is meant to be at 8MHz while I've also set GPIO speed to high. My SPI SCK is now 4MHz in the new photo. I'm clearly missing something here... – sophia_ash Apr 11 '19 at 12:53

1 Answers1

1

I think I can explain the delay between activation of CS and the SPI transfer: If you take a look inside HAL_SPI_TransmitReceive() you can see that it actually requires a lot of operations to set up and start the actual SPI transfer. Depending on your clock configuration this can easily take several microseconds (see also this question).

I am a bit puzzled about the delay after the SPI transfer until CS is de-asserted. The HAL code should need much less operations to finish the transfer compared to the transfer preparation. The "Check finished" code should neither need many cycles, since it actually only checks a software flag (not even a hardware register). The call is not necessary though, because HAL_SPI_TransmitReceive() is a blocking function which only returns after the SPI transfer has finished.

Regarding your problem I wanted to recommend using the hardware NSS feature. But at second thought this asserts CS as soon as the SPI unit is enabled. The ST HAL does not seem to disable the SPI unit after each transfer - so this will not work as intended.

I think you need to analyze further what happens inside the HAL between the actual SPI transfer and the de-assertion of CS. This does not look like a normal behavior. It is not necessary to use interrupts or DMA to improve the CS behavior. These features take load from the CPU but require more complex code, which might not improve the CS delay.

Blue
  • 820
  • 4
  • 17
  • Thanks for that insight! Additionally since this post, I managed to get the timing between transfer and CS more normal by slowing SPI right down to 15kHz (keeping GPIO speed as previously). I need to be operating a lot faster than this but this proves there is a clear timing issue. When I have the problem, I'm trying SPI at 2MHz and GPIO at 64MHz - do you know if there's anything I'm missing on that front? – sophia_ash May 22 '19 at 10:48