cancel
Showing results for 
Search instead for 
Did you mean: 

SPI2 Communication on STM32H743X

SFons.1
Associate II

I have been using STM32H743x for a project. There i use SPI2 to communicate with a serial flash IC.

I need different packet sizes when accessing the Flash. The problem i have is, when i change the TSIZE at different stages, the firmware freezes at the second time update of the SPI2-> CR2 register. Here is my code.

_Bool Write_To_SerialFlash(_Bool _FlushOrWrite){
 
	uint8_t _Data[40],_Command_Data[4];
	uint32_t _TX_Data=0;
 
	memset(_Data,0,sizeof(uint8_t)*40);
	memset(_Command_Data,0,sizeof(uint8_t)*4);
 
	SPI2->CR1 &= ~SPI_CR1_SPE;
	SPI2->CFG1 &= 0xFFFFFE1F;//Set FTHLV=4b0000
	SPI2->CR2 |= (uint32_t)0x00000001;//TSIZe is set to 1
	SPI2->CR1 |= SPI_CR1_SPE;
 
	if(_FlushOrWrite){
 
		for(uint8_t i=0;i<40;i++){
 
			_Data[i] = (uint8_t)50 + i;
		}
 
	}
 
	_Command_Data[0]=0x02;
	_Command_Data[1]=0x00;
	_Command_Data[2]=0x00;
	_Command_Data[3]=0x00;
 
	for(uint8_t i=3;i>0;i--){
 
		_TX_Data |= (uint32_t)_Command_Data[i];
		_TX_Data = _TX_Data<<8;
	}
 
	_TX_Data |= (uint32_t)_Command_Data[0];
 
	while(1){
 
		if((SPI2->SR & SPI_SR_TXP)>0)
			break;
	}
 
	HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);//Set CS=0
	HAL_Delay(1);
 
	SPI2->TXDR = 0x06;//Send WREN Command
	SPI2->CR1 |= SPI_CR1_CSTART;//Initiates SCK. The length depends on the size defined in the TXFIFO
 
	while(1){
 
		if((SPI2->SR & SPI_SR_TXC)>0)//Check whether the transaction is completed.
			break;
	}
	//End of Sending WREN Command
	//******************************************************************************************************
 
	//Send <Write_Command><3 Address Bytes>
	SPI2->CR1 &= ~SPI_CR1_SPE;
	SPI2->CFG1 &= 0xFFFFFE1F;//Set FTHLV=4b0000
	SPI2->CFG1 |= (uint32_t)0x60;//Set FTHLV=4b0011 indicating FIFO size is 4-byte wide
 
	SPI2->CR2 &= (uint32_t)0xFFFFFFFE;
	SPI2->CR2 |= (uint32_t)0x00000004;//TSIZE is seto to 4, in order to create 32 clock pulses
 
	SPI2->CR1 |= SPI_CR1_SPE;
	HAL_Delay(1);
 
	HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);//Set CS=1
 
	while(1){
 
		if((SPI2->SR & SPI_SR_TXP)>0)
			break;
	}
 
	SPI2->TXDR = _TX_Data;
 
	HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);//Set CS=0
	HAL_Delay(1);
 
	SPI2->CR1 |= SPI_CR1_CSTART;//Initiates SCK. The length depends on the size defined in the TXFIFO
 
	while(1){
 
		if((SPI2->SR & SPI_SR_TXC)>0)//The program freezes here. Neither TXC nor EOT flag is set.
			break;
	}
	//End of sending Write Command
	//******************************************************************************************************
 
	//Start Sending Data to the Flash
	for(uint8_t i=0;i<40;){
 
		while(1){
 
			if((SPI2->SR & SPI_SR_TXP)>0)
				break;
		}
 
		_TX_Data=0;
		for(int8_t j=i+3;j>=i;j--){
 
			_TX_Data = _TX_Data<<8;
			_TX_Data |= _Data[j];
 
		}
		i+=4;
 
		SPI2->TXDR = _TX_Data;
 
		SPI2->CR1 |= SPI_CR1_CSTART;//Initiates SCK
 
		while(1){
 
			if((SPI2->SR & SPI_SR_TXC)>0)//Check whether the transaction is completed.
				break;
		}
	}
	//End of Sending Data to the Flash
	//******************************************************************************************************
 
	HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);//Set CS=1
 
	return 1;
}

I would be glad, if someone could tell me where the error is.

2 REPLIES 2
TDK
Guru

What does "firmware freezes" mean? When you debug and step through, what happens?

Nothing about "SPI2->CR2 &= (uint32_t)0xFFFFFFFE;" should cause an issue.

Using standard CMSIS definitions for the registers would help readability.

If you feel a post has answered your question, please click "Accept as Solution".

TXC flag is not set when the SPI2->CR2 is updated with TSIZE = 4.

	//Send <Write_Command><3 Address Bytes>
	SPI2->CR1 &= ~SPI_CR1_SPE;
	SPI2->CFG1 &= 0xFFFFFE1F;//Set FTHLV=4b0000
	SPI2->CFG1 |= (uint32_t)0x60;//Set FTHLV=4b0011 indicating FIFO size is 4-byte wide
 
	SPI2->CR2 &= (uint32_t)0xFFFFFFFE;
	SPI2->CR2 |= (uint32_t)0x00000004;//TSIZE is seto to 4, in order to create 32 clock pulses
 
	SPI2->CR1 |= SPI_CR1_SPE;

Neither TXC nor EOT flag is set when the START condition is issued on the CR1 register.

	SPI2->CR1 |= SPI_CR1_CSTART;//Initiates SCK. The length depends on the size defined in the TXFIFO
 
	while(1){
 
		if((SPI2->SR & SPI_SR_TXC)>0)//The program freezes here. Neither TXC nor EOT flag is set.
			break;
	}

The used conventions are the real register names defined in the device datasheet. I wanted to access this level in order to get an idea about the complete functionality of the system. I would be glad if you could help. For further information, no interrupt is used.