cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Triggering GPIO

EthanMankins
Associate III

SEE EDIT

I am using the STM32H7B3I-DK. I am trying to write my own simple SPI ISR to handle transmitting and receiving of just one byte I have gotten the slave working with my ISR (while master used HAL). I am now implementing on the master and having issues with the transmit. When I am in debug mode and transmit one byte then hit a breakpoint it works fine. However, when I just run normal after I start transmitting, my board says it starts receiving button presses. It is acting as if someone is randomly pressing all the buttons connected on the PC2 (input- pull down - active High) line. The weird thing is I don't have this issue if I use the HAL Transmit, only when I use my transmit. This occurs even if the slave is not on and the master is just sending bytes to a non powered device.

My SPI Setup uses SPI2 which PC2 could have the AF SPI2 MISO but I do not have it configured that way. Could the spi be interfering with the GPIO input internally? 

Any other suggestions to try?

 

SPI ISR:

 

 

volatile uint8_t rxBuffer[8];
volatile uint16_t rxIndex = 0;
volatile uint8_t txBuffer[8] = {1,2,3,4,5,6,7,8};
volatile uint16_t txIndex = 0;

[...]

void spiISR(SPI_HandleTypeDef *hspi) {

	//Receive if ready
	if (hspi->Instance->SR & SPI_FLAG_RXP) {
    	rxBuffer[rxIndex] = (*(__IO uint8_t *)&hspi->Instance->RXDR);
    	rxIndex = (rxIndex + 1) % 8;
	}

	if (hspi->Instance->SR & SPI_FLAG_TXP) {
		SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
		HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);  			// Pull CS low
		(*(__IO uint8_t *)&hspi->Instance->TXDR) = txBuffer[txIndex];
		txIndex++;

		//if sent whole buffer, end Transmission
		if(txIndex == 8){
			HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);    // Pull CS high
			txIndex = 0;
			return;
		}
		SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);

	}

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

 

 

EDIT:

I Seemed to fix the issue by changing my ISR slightly. I believe it was never leaving the ISR before but I am not sure how this was causing the Error. Any Explanations? 

void spiISR(SPI_HandleTypeDef *hspi) {

	//Receive if ready
	if (hspi->Instance->SR & SPI_FLAG_RXP) {
    	rxBuffer[rxIndex] = (*(__IO uint8_t *)&hspi->Instance->RXDR);
    	rxIndex = (rxIndex + 1) % 8;
	}

	if (hspi->Instance->SR & SPI_FLAG_TXP) {
		//if sent whole buffer, end Transmission
		if(txIndex == 8){
			__HAL_SPI_DISABLE_IT(&hspi2, SPI_IT_TXP);
			HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);    // Pull CS high
			return;
		}
		SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
		HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);  			// Pull CS low
		(*(__IO uint8_t *)&hspi->Instance->TXDR) = txBuffer[txIndex];
		txIndex++;

		SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);

	}

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
Saket_Om
ST Employee

Hello @EthanMankins 

In the first implementation, the NSS pin is being pulled high immediately after filling the data register with the last data. This causes the slave select to go high before the SPI peripheral has sent the last byte.

To address this issue, it is important to ensure that the NSS pin remains low until the SPI peripheral has completed the data transmission. This can be achieved by modifying the sequence of operations to ensure that the NSS pin is pulled high only after the transmission is confirmed to be complete.

For example, you can follow these steps:

  1. Fill the data register with the last data.
  2. Wait for the transmission to complete by checking the appropriate status flag (e.g., TXE or BSY flag).
  3. Pull the NSS pin high to indicate the end of the transaction.

This approach ensures that the NSS pin is pulled high only after the SPI peripheral has sent the data, preventing any premature deselection of the slave device.

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

Thanks
Omar

View solution in original post

1 REPLY 1
Saket_Om
ST Employee

Hello @EthanMankins 

In the first implementation, the NSS pin is being pulled high immediately after filling the data register with the last data. This causes the slave select to go high before the SPI peripheral has sent the last byte.

To address this issue, it is important to ensure that the NSS pin remains low until the SPI peripheral has completed the data transmission. This can be achieved by modifying the sequence of operations to ensure that the NSS pin is pulled high only after the transmission is confirmed to be complete.

For example, you can follow these steps:

  1. Fill the data register with the last data.
  2. Wait for the transmission to complete by checking the appropriate status flag (e.g., TXE or BSY flag).
  3. Pull the NSS pin high to indicate the end of the transaction.

This approach ensures that the NSS pin is pulled high only after the SPI peripheral has sent the data, preventing any premature deselection of the slave device.

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

Thanks
Omar