This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Flash erase/write problems

I've spent several days reading all the support tickets regarding this issue but I cannot find a resolution.

I am running the ble_central_uart example with SD 132, SES 4.30, SDK 15.3 on an nRF52 DK dev board.  

I have been unable to erase flash consistently or to write flash at all.  It appears that I am having problems with both erasing and writing flash.  I implemented the sd_flash_page_erase() function as follows:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
uint32_t static pg_size;
uint32_t static pg_num;
uint32_t static flash_addr;
uint32_t static p_flash_addr;
static uint32_t nrf5_flash_end_addr_get()
{
pg_size = NRF_FICR->CODEPAGESIZE;
pg_num = NRF_FICR->CODESIZE-2; // Use last page in flash
flash_addr = (uint32_t *)(pg_size * pg_num);
p_flash_addr = &flash_addr;
}
void erase_flash_page(void)
{
flash_operation_completed = false;
sd_flash_page_erase(pg_num);
while(!flash_operation_completed)
{
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

This code executes but it does not check for the flash erase function to complete.  In debugging the problem, I found that the write function sd_flash_write() was erroring out on err_code == NRF_ERROR_BUSY.  So I figured the erase function required more time to complete.  I added a delay nrf_delay_ms(100) and tried a timer as well.  Neither did any good.  So I added an error check on the sd_flash_page_erase() function, like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void erase_flash_page(void)
{
uint32_t evt = 0;
retry_flash:
flash_operation_completed = false;
sd_flash_page_erase(pg_num);
while(!flash_operation_completed)
{
sd_evt_get (&evt);
if (evt == NRF_EVT_FLASH_OPERATION_SUCCESS || evt == NRF_EVT_FLASH_OPERATION_ERROR)
{
flash_operation_completed = true;
goto resume_flash_operations;
}
else
{
start_flash_timer();
goto retry_flash;
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Line 11 never evaluates as true.  So the code gets stuck in this loop.

The other problem I have is that even when I put a delay in the erase code and let it pass through the erase function to the write function, I get an NRF_BUSY_ERROR in the write flash function.  See code below:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void write_flash_page(void)
{
ret_code_t err_code;
uint8_t block_size = sizeof(write_flash_block);
// sd_flash_write((uint32_t*)flash_addr, (uint32_t*)&write_flash_block, sizeof(write_flash_block));
// sd_flash_write((uint32_t*)&flash_addr, p_write_flash_block, sizeof(write_flash_block));
// sd_flash_write(p_flash_addr, p_write_flash_block, sizeof(write_flash_block));
flash_operation_completed = false;
err_code = sd_flash_write((uint32_t*)flash_addr, p_write_flash_block, block_size);
if (err_code != NRF_SUCCESS)
{
NRF_LOG_INFO("Error writing to flash, err_code = \"%x\" .", err_code);
if (err_code == NRF_ERROR_INVALID_LENGTH) while (1);
if (err_code == NRF_ERROR_INVALID_ADDR) while (1);
if (err_code == NRF_ERROR_BUSY) while (1);
if (err_code == NRF_ERROR_FORBIDDEN) while (1);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The code always hangs on line 18 - if (err_code == NRF_ERROR_BUSY) while (1);

I make sure that my writes are word aligned as shown:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct blockstruct // block to write into flash.
{
int desired_temp; // Last water temperature requested by user.
int desired_flow; // same
int user_max_temp;
int absolute_max_temp;
bool startup_done;
bool install_mode;
bool initialization_done;
bool clockwise_heat;
int shower_timer;
bool temp_scale;
int user_last_preset;
int user_last_temp;
}__ALIGN(4)write_flash_block, __ALIGN(4)read_flash_block;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

and my flash writes always begin at the start of the flash page which happens to be 7e000.  

Finally, I tried to supply my own event handler with this code:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void sys_evt_dispatch(uint32_t sys_evt)
{
app_sys_event_handler(sys_evt);
}
void app_sys_event_handler(uint32_t sys_evt)
{
// flash_operation_completed = false;
switch (sys_evt)
{
case NRF_EVT_FLASH_OPERATION_SUCCESS:
flash_operation_completed = true;
NRF_LOG_INFO("--> Flash page operation sucessfull.");
break;
case NRF_EVT_FLASH_OPERATION_ERROR:
// Handle error
NRF_LOG_INFO("--> Flash page operation FAILED!!!!!!!!!!!!!!.");
break;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

But it seems that this code isn't supported by SDK 15.3.  I get compile errors.

Where am I going wrong?