cancel
Showing results for 
Search instead for 
Did you mean: 

Is TXP Necessary for SPI Slave?

EthanMankins
Senior

I am having issues with my slave responding to my master. I am trying to lessen complexity by only using RXP on the slave, without TXP. The slave (Nucleo-H743ZI) responds one byte late.

On the CS interrupt I send 0 for the first byte and enable RXP.

*((__IO uint8_t *)&hspi1.Instance->TXDR) = 0;
__HAL_SPI_ENABLE_IT(&hspi1, SPI_IT_RXP);
__HAL_SPI_ENABLE(&hspi1);

I then receive a byte and set the next transmit byte. I use FPint so the master does not send data when it is low (used for later implementation).  

void spiISRSTM(SPI_HandleTypeDef *hspi) {

	//Receive if ready
	if (hspi->Instance->SR & SPI_FLAG_RXP) {
		HAL_GPIO_WritePin(nFPINT_GPIO_Port, nFPINT_Pin, GPIO_PIN_RESET);	
    	rxBuffer = (*(__IO uint8_t *)&hspi->Instance->RXDR);
    	(*(__IO uint8_t *)&hspi->Instance->TXDR) = 1;
    	HAL_GPIO_WritePin(nFPINT_GPIO_Port, nFPINT_Pin, GPIO_PIN_SET);

	}
	__HAL_SPI_CLEAR_UDRFLAG(hspi);
	__HAL_SPI_CLEAR_OVRFLAG(hspi);
	__HAL_SPI_CLEAR_EOTFLAG(hspi);
	__HAL_SPI_CLEAR_FREFLAG(hspi);

}

The MISO line for this setup is:

0011 1111

I would expect:

0111 1111

Any Ideas what is causing this?

1 ACCEPTED SOLUTION

Accepted Solutions
EthanMankins
Senior

The issue was an underrun after the first byte. Disabling and reenabling spi after read and before transmit solved the issue.

sr = hspi->Instance->SR;
if ((sr & (SPI_FLAG_RXP | SPI_FLAG_TXC)) == (SPI_FLAG_RXP | SPI_FLAG_TXC)) {
		HAL_GPIO_WritePin(nFPINT_GPIO_Port, nFPINT_Pin, GPIO_PIN_RESET);	//Lower nFPINT
		rxBuffer = (*(__IO uint8_t *)&hspi->Instance->RXDR);
		__HAL_SPI_DISABLE(&hspi1);
		__HAL_SPI_ENABLE(&hspi1);
		pPacketSlave->ProcessSPI();
		(*(__IO uint8_t *)&hspi->Instance->TXDR) = txBuffer;
	}

View solution in original post

4 REPLIES 4
Saket_Om
ST Employee

Hello @EthanMankins 

Could you try activating DXP interrupt and checking on DXP flag instead of RXP? 

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Hi @Saket_Om 

I have tried this and it does not make difference to the timing.

I have found I get an UDR Interrupt error on the second byte, not sue how this happens because the transmit is set right after each read, and the master does not send a new byte until FPInt is raised. No other bytes are UDR

EthanMankins
Senior

The issue was an underrun after the first byte. Disabling and reenabling spi after read and before transmit solved the issue.

sr = hspi->Instance->SR;
if ((sr & (SPI_FLAG_RXP | SPI_FLAG_TXC)) == (SPI_FLAG_RXP | SPI_FLAG_TXC)) {
		HAL_GPIO_WritePin(nFPINT_GPIO_Port, nFPINT_Pin, GPIO_PIN_RESET);	//Lower nFPINT
		rxBuffer = (*(__IO uint8_t *)&hspi->Instance->RXDR);
		__HAL_SPI_DISABLE(&hspi1);
		__HAL_SPI_ENABLE(&hspi1);
		pPacketSlave->ProcessSPI();
		(*(__IO uint8_t *)&hspi->Instance->TXDR) = txBuffer;
	}