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

nrf51822 sdk12 hangs after flash write

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;
}
Related