2021-09-09 01:15 AM
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.
2021-09-09 08:12 AM
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.
2021-09-09 10:10 PM
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.