cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Slave NSS Interrupt

Issinski.Anton
Associate II

We are using STM32H743 to implement SPI Slave. We would like to use NSS pin to hardware synchronize the beginning and end of our data packet, which is about 100 bytes long. The reason for that - the SPI wires are long and noisy and we would like to push the speed to the limits. So errors like lost/inserted clock and hence frame bit are possible. Rather than timing out on the entire data packet integrity, NSS wire comes very handy. Many hardware manufactures use NSS for exactly same purpose: to signal the beginning and/or end of the command packet.

Is there any way to generate an interrupt when NSS wire changes its state? We would like to keep GPIO in the Alternative Function NSS for the SPI slave so it will synchronize the beginning of the byte frame if clocks are lost, and at the same time use NSS level to signal the upper-level protocol end-of-packet event.

Receive interrupt will not work in such case: if one clock is lost, the last byte will not be received. However, the NSS will go high and we would like to catch this event promptly.

Thank you.

8 REPLIES 8
T J
Lead

You could run a wire from the NSS input to an External interrupt pin

Issinski.Anton
Associate II

Good idea. But kind of late for us: it is already materialised in the hardware. Is it possible somehow to connect EXTI internally to the SS or tap in parallel to the pin?

T J
Lead

not sure, :(

I use LQFP parts so the prototyping can be hacked, are you using a BGA package ?

which package ?

Issinski.Anton
Associate II

LQFP100. Our NSS has free GPIO pin next to it, so simple solder bridge will do, thank you for the solution. Still hope ST will come with more humane design :).

T J
Lead

I wonder if that pin has an interrupt function...

On most STM32 the EXTI functionality of a pin is independent on its usage (unless it's set as Analog), i.e. a pin set as SPI_NSS can simultaneously be input to EXTI too. I don't use the 'H7 but would be surprised if this would be different there.

JW

DAnsp
Associate II

On the STM32L073, I've successfully enabled the EXTI on the NSS pin (PA15 in this case) while using hspi1.Init.NSS = SPI_NSS_HARD_INPUT in slave mode.

The key here is to initialize the EXTI first using something similar to the following:

void MX_GPIO_Init_Custom(void)
{
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /*Configure GPIO pin : PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	/* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
...
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (GPIO_Pin == GPIO_PIN_15)
	{
		if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_15) == GPIO_PIN_SET)
		{
                ...  Code to service request
		}
	}
}

Then continue to initialize the SPI as usual. In the case of the STM32L073, the EXTI interrupts continued to work even after the SPI configuration changed the GPIO mode on the PA15 pin to GPIO_InitStruct.Mode = GPIO_MODE_AF_PP

Tom Schrauf
Associate II

2 yrs later .... Thank you DAnsp for the information given. I implement an SPI slave with F103s that switches to slave mode when LTC6820 (Isospi chip) requests a transfer by driving NSS (PB12 in my case) low. The same SPI is used to act as a master locally and I can drive the CS from the remote busmaster and force the slaves to listen before the actual SPI transfer begins not requiring an additional pin.

Tom