STM32F401 - Hard Fault while programmin FLASH - IAP
Hello!
I am working on a custom USB bootloader for a stm32F401VCT6.
The communicatio with the host PC over USB is working. Also the erasing of the Flash memory is working. I am using the HAL drivers by the way.
The bootlaoder sits in the first two sectors of the Flash memory.
The problem now is, when I want to write data to flash, it goes into a hard fault error. The point where the hard fault error occurs is in the function:
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startingAddress, dummy);
more specific, in this function another function is called:
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
this function is called 2 times in the HAL_Flash_Program function. the second time it causes an hard fault. The type of the hard fault is: Bus, memory management, or usage fault. more specific: Attempt to execute an undefined instruction
I tryed to disable the write protection. But still causes a hard fault when trying to write to flash.
My write to flash function:
static void Write(void)
{
uint32_t startingAddress = APPLICATION_START_ADDRESS;
int numBytes;
uint8_t i;
uint8_t diff = 0;
HAL_StatusTypeDef returnval;
/*
uint32_t error1 = FLASH_SR_PROGERR;
uint32_t error2 = FLASH_SR_PGAERR;
uint32_t error3 = FLASH_SR_PGSERR;
*/
// Receive the number of bytes to be written
WaitForUSBData(TIMEOUT_VALUE);
numBytes = pRxBuffer[0];
//FLASH_If_Init();
// Check checksum
if(CheckChecksum(pRxBuffer, 2) != 1)
{
// invalid checksum
Send_NACK();
return;
}
else
{
// valid checksum
if(numBytes == 32)
{
Send_ACK();
}
}
do
{
// Receive the data, a maxiumum of 32 Bytes of data and 1 Byte of checksum can be received
WaitForUSBData(TIMEOUT_VALUE);
i = 0;
/*
if(pRxBuffer[0] == 0 && pRxBuffer[1] == 0x80 && pRxBuffer[2] == 1){
HAL_GPIO_TogglePin(GPIOD, LED2_Pin);
HAL_Delay(150);
HAL_GPIO_TogglePin(GPIOD, LED2_Pin);
HAL_Delay(150);
HAL_GPIO_TogglePin(GPIOD, LED2_Pin);
HAL_Delay(150);
HAL_GPIO_TogglePin(GPIOD, LED2_Pin);
}
*/
HAL_FLASH_Unlock();
while(numBytes > 0)
{
// Program a double word (8 Byte) at once
// First bring it to the right Bit format
dummy = 0;
dummyH = 0;
dummyL = 0;
for(x = i; x < (i + 4); x++)
{
dummyL += pRxBuffer[x] << ((x - i) * 8);
dummyH += pRxBuffer[x + 4] << ((x - i) * 8);
}
dummy = (uint64_t) dummyH << 32;
dummy += (uint64_t) dummyL;
//If the last Doubleword is not complete, fill up the rest with 1
if(numBytes % 8 != 0)
{
shadowdummy = 1;
diff = 32 - numBytes;
for(x = 1; x < diff; x++)
{
shadowdummy += 1 << x;
}
dummy |= shadowdummy << (8 - diff);
}
//stuck here...
returnval = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startingAddress, dummy);
if(returnval != HAL_OK)
{
//HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
Send_NACK();
break;
}
/* Check the written value */
if (*(uint64_t*)startingAddress != dummy)
{
/* Flash content doesn't match received content */
//HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
Send_NACK();
break;
}
//startingAddress += 8;
startingAddress += sizeof(uint64_t);
i += sizeof(uint64_t);
//CLEAR_BIT (FLASH->CR, (FLASH_CR_PG));
numBytes -= 8;
}
HAL_FLASH_Lock();
Send_ACK();
// Receive the number of bytes to be written
WaitForUSBData(TIMEOUT_VALUE);
// Check checksum
if(CheckChecksum(pRxBuffer, 2) != 1)
{
// invalid checksum
Send_NACK();
return;
}
else
{
// valid checksum
Send_ACK();
}
numBytes = pRxBuffer[0];
}while(numBytes > 0);
Any ideas what could be wrong?
