cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f4xx FLASH_ProgramWord error, FLASH_ERROR_PROGRAM

Angelo1
Associate II
Posted on April 02, 2014 at 16:13

Dear,

i am getting this error, this is my flash write routine:


 #include <stm32f4xx_flash.h>
 #include ''flash.h''
 uint8_t flash_status;
 volatile uint32_t* flash_location_sect3 = (volatile uint32_t*)0x800C000;
 #define FLASH_CFG_ULONGS 512
 int save_data_to_flash(unsigned long *data)
{
int x;
flash_status = FLASH_COMPLETE;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR |FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
/* Get the number of the start and end sectors */
//sector_start = GetSector(FLASH_USER_START_ADDR);
//secto_end = GetSector(FLASH_USER_END_ADDR);
flash_status = FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3);
if (flash_status != FLASH_COMPLETE) {
FLASH_Lock();
return ERR_BAD_ERASE;
}
for (x = 0; x < FLASH_CFG_ULONGS; ++x) {
if (*flash_location_sect3 != 0xffffffff)
return 254;
//program first run status bit
flash_status =
FLASH_ProgramWord((uint32_t)flash_location_sect3, *data);
flash_location_sect3++;
data++;
if (flash_status != FLASH_COMPLETE) {
FLASH_Lock();
return flash_status;
}
}
return -1;
}

I already checked that: - erase works properly - write fail probably at second FLASH_ProgramWord() (since i see the first value written correctly) The error i am getting is FLASH_ERROR_PROGRAM (7) Every help is welcome.
7 REPLIES 7
Posted on April 02, 2014 at 16:21

flash_location_sect3 is what?

You'd really help yourself if you provide complete/concise examples.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Angelo1
Associate II
Posted on April 02, 2014 at 17:16

Sry,

i updated the above code.

I have seen some thread over the forum, also from you, about flash programming, and i don't see anything wrong/different in my code.

Posted on April 02, 2014 at 17:53

This worked for me, in Keil on an STM32F4-DISCO

// STM32F4 FLASH - sourcer32@gmail.com

#include <

stdio.h

>

#include ''stm32f4xx.h''

/**************************************************************************************/

#define FLASH_CFG_ULONGS 512

int save_data_to_flash(unsigned long *data)

{

FLASH_Status flash_status;

volatile uint32_t *addr = (volatile uint32_t *)0x0800C000; // Sector 3 0x0800C000 .. 0x0800FFFF

int x;

flash_status = FLASH_COMPLETE;

FLASH_Unlock();

FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR |FLASH_FLAG_WRPERR |

FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

flash_status = FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3);

if (flash_status != FLASH_COMPLETE)

{

FLASH_Lock();

return(66); // ERR_BAD_ERASE

}

for(x=0; x<

FLASH_CFG_ULONGS

; x++)

{

if (*addr != 0xFFFFFFFF) // Not blank

return(99);

//program first run status bit

flash_status

=

FLASH_ProgramWord

((uint32_t)addr, *data);

if (flash_status != FLASH_COMPLETE)

{

printf(''ProgramWord fails @ %08X, status:%d\n'', (uint32_t)addr, flash_status);

FLASH_Lock();

return((int)flash_status);

}

addr++;

data++;

}

return(-1);

}

/**************************************************************************************/

int main(void)

{

int i;

puts(''FLASH Test'');

for(

i

=

0

; i<3; i++)

printf(''#%d - save_data_to_flash status:%d\n'', i, save_data_to_flash((void *)(0x1FFF0000 + (FLASH_CFG_ULONGS * sizeof(unsigned long) * i))) );

while(1); // Don't want to exit

}

//******************************************************************************

// Hosting of stdio functionality through SWV - Serial Wire Viewer

//******************************************************************************

#include <rt_misc.h>

#pragma import(__use_no_semihosting_swi)

struct __FILE { int handle; /* Add whatever you need here */ };

FILE __stdout;

FILE __stdin;

int fputc(int ch, FILE *f)

{

ITM_SendChar(ch);

return(ch);

}

int fgetc(FILE *f)

{

char ch;

ch = '?';

return((int)ch);

}

int ferror(FILE *f)

{

/* Your implementation of ferror */

return EOF;

}

void _ttywrch(int ch)

{

ITM_SendChar(ch);

}

void _sys_exit(int return_code)

{

label: goto label; /* endless loop */

}

//******************************************************************************

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t* file, uint32_t line)

{

/* User can add his own implementation to report the file name and line number,

ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

/* Infinite loop */

while (1)

{

}

}

#endif

//******************************************************************************

I don't understand the merits of having the address variable being global, sets you up for failure on multiple calls.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Angelo1
Associate II
Posted on April 02, 2014 at 19:03

Hi Clive,

many thanks,

incredible, the fact you pointed out to avoid the address declaration as a global solved my issue:

once moved the same declaration inside the function scope solved the issue and i could write correctly all the 512 32bit words block.

Now i need to understand why. I mean, for a single call of the function, there shouldn't be any difference between using global or local stack address. Since the first FLASH_ProgramWord write was successful but not the second one, seems like the address get wrong at the second call.

Thanks for now !

Angelo1
Associate II
Posted on April 02, 2014 at 22:57

Since i don't believe in ghosts, i went deeper in the global pointer failure.

I found an error in the linker script :

i was using
.data : ALIGN(16) {
_data_beg = .;
_data_start = .;
*(.data)
*(.data*)
_data_end = .;
} >flash
instead of
.data : ALIGN(16) {
_data_beg = .;
_data_start = .;
*(.data)
*(.data*)
_data_end = .;
} >ram AT > flash

So still tanks, 2 problems solved in one thread :) now i have also globals working as expected :)
Posted on April 02, 2014 at 23:05

Watch for *(.bss) and *(.bss*) also, with things not being zero

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 03, 2014 at 00:43

Linker script example

https://drive.google.com/file/d/0B7OY5pub_GfIY01DaHY4OVp4NUk/edit?usp=sharing

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..