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:
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) { sd_app_evt_wait(); flash_operation_completed = true; } }
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:
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; } } // nrf_delay_ms(10); // give flash time to finish while(!flash_operation_completed) { sd_app_evt_wait(); flash_operation_completed = true; } resume_flash_operations: return (12345); }
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:
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); } while(!flash_operation_completed) { sd_app_evt_wait(); flash_operation_completed = true; } }
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:
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;
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:
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; } } // Register with the SoftDevice handler module for BLE events. ret_code_t err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch); softdevice_sys_evt_handler_set(sys_evt_dispatch); APP_ERROR_CHECK(err_code);
But it seems that this code isn't supported by SDK 15.3. I get compile errors.
Where am I going wrong?