i am in very strange problem and was unable to debug it i am using following code to write 16 bytes data to flash memory, my app hangs after executing custom_flash_write function. function works as expected ( flash is erased , data is written and fucntion return without any error ). but my app hangs after executing few more lines. however when i omit custom_flash_erase function app works perfectly. please help me i had tried uart and gdb debugging but had no luck till now
note. i am using rtc to generate systicks and using custom conn_params library for ble
#define BUSY_CODE ( 1 << 0 )
#define SUCCESS_CODE ( 1 << 1 )
#define ERROR_CODE ( 1 << 2 )
#define is_flash_busy() ( flash_state & BUSY_CODE )
#define set_flash_state_busy() ( flash_state = BUSY_CODE )
#define set_flash_state_success() ( flash_state = SUCCESS_CODE )
#define set_flash_state_error() ( flash_state = ERROR_CODE )
#define is_flash_write_success() ( flash_state & SUCCESS_FLAG )
uint32_t word_to_write[4];
void sys_evt_dispatch(uint32_t sys_evt) {
if (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) {
set_flash_state_success();
} else if (sys_evt == NRF_EVT_FLASH_OPERATION_ERROR) {
set_flash_state_error();
} else {
}
}
void custom_flash_init() {
uint32_t err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
APP_ERROR_CHECK(err_code);
}
void custom_flash_erase(uint8_t * flash_addr){
uint32_t err_code;
set_flash_state_busy();
// erase page number, page size is 1024 = 2^10 thus shift right by 10 to calculate page number
// schedule erase command until accepted
do {
err_code = sd_flash_page_erase(((uint32_t) flash_addr) >> 10);
log(err_code);
} while (err_code != NRF_SUCCESS);
// wait till flash operation completed
while (is_flash_busy());
}
// flash_addr where buf data of given length should be written
uint8_t custom_flash_write(uint8_t * flash_addr, uint8_t * buf, uint32_t length) {
if (length == 0) {
return 0;
}
uint32_t err_code;
// if data length is not word align align it first
// that is length should be in multiple of 4
if (length & 0x03) {
// round of length to next 4 multiple
length += 4;
}
// lenth of words to write
length = length >> 2;
memcpy(word_to_write, buf, length<<2);
// assuming sequential write erase page at beginning only
if ((((uint32_t) flash_addr) & 0x000003FF) == 0) {
custom_flash_erase(flash_addr);
}
set_flash_state_busy();
do {
err_code = sd_flash_write((uint32_t *) flash_addr, word_to_write, length);
log(err_code);
} while(err_code != NRF_SUCCESS);
while (is_flash_busy());
return length*4;
}