Hi,
I'm using S112 v6.0 with SDK 15.0 on nRF52810. It's based on app_ble_uart example. I have some data to save in flash. I define the address as follow:
#define PAGRE_TO_ERASE 1
#define FLASH_START_ADDR 0x27000
#define FLASH_STOP_ADDR 0x28000
#define FLASH_START_WRITE_ADDR FLASH_START_ADDR
I could write data to flash when powered up after nrf_fstorage_init and I could read them out. But when I wirte the data received from UART, I found that it have not write them into the flash. When I receive the data from uart, I would call read_clear_data() then delay 300ms, then I write them. When I read them out, I found that it's the data I write when powered up.
Attachment is my test code. Could anyone give me some advice? Thanks
#include "app_util.h"
#include "stdio.h"
#include "string.h"
#include "user_config.h"
#include "nrf_fstorage.h"
#include "nrf_fstorage_sd.h"
#include "nrf_delay.h"
#include "app_timer.h"
#include "nrf_nvic.h"
#include "Flash_Handler.h"
#define PAGRE_TO_ERASE 1
#define FLASH_START_ADDR 0x27000
#define FLASH_STOP_ADDR 0x28000
#define FLASH_START_WRITE_ADDR FLASH_START_ADDR
uint8_t fs_event_num = 0;
at_com_data_t at_com_data;
//static bool reset_write_para = false;
void idle_state_handle(void);
void fs_evt_handler(nrf_fstorage_evt_t * evt);
void fs_evt_handler(nrf_fstorage_evt_t * p_evt)
{
if (p_evt->result != NRF_SUCCESS)
{
return;
}
switch (p_evt->id)
{
case NRF_FSTORAGE_EVT_WRITE_RESULT:
{
// printf("wrote %d bytes at address 0x%x.\r\n",
// p_evt->len, p_evt->addr);
//uint32_t err_code = sd_nvic_SystemReset();
} break;
case NRF_FSTORAGE_EVT_ERASE_RESULT:
{
// printf("erased %d page from address 0x%x.\r\n",
// p_evt->len, p_evt->addr);
} break;
default:
break;
}
}
NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
.evt_handler = fs_evt_handler,
.start_addr = FLASH_START_ADDR,
.end_addr = FLASH_STOP_ADDR,
};
void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
/* While fstorage is busy, sleep and wait for an event. */
while (nrf_fstorage_is_busy(p_fstorage))
{
idle_state_handle();
}
}
void wait_flash_complete(void)
{
wait_for_flash_ready(&fstorage);
}
void flash_clear(void)
{
ret_code_t rc = nrf_fstorage_erase(
&fstorage, /* The instance to use. */
FLASH_START_WRITE_ADDR, /* The address of the flash pages to erase. */
PAGRE_TO_ERASE, /* The number of pages to erase. */
NULL /* Optional parameter, backend-dependent. */
);
// printf("clear rc=0x%02x \r\n",rc);
if (rc == NRF_SUCCESS)
{
// printf("Clear OK\r\n");
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_ERASE_RESULT event
is sent to the callback function registered by the instance. */
}
}
void flash_write(uint8_t *dat,uint16_t len)
{
ret_code_t rc = nrf_fstorage_write(
&fstorage, /* The instance to use. */
FLASH_START_WRITE_ADDR, /* The address in flash where to store the data. */
dat, /* A pointer to the data. */
len, /* Lenght of the data, in bytes. */
NULL /* Optional parameter, backend-dependent. */
);
// printf("write rc=0x%02x\r\n",rc);
if (rc == NRF_SUCCESS)
{
// printf("Write OK\r\n");
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_WRITE_RESULT event
is sent to the callback function registered by the instance. */
}
}
void flash_read(uint8_t *dat,uint16_t len)
{
ret_code_t rc = nrf_fstorage_read(
&fstorage, /* The instance to use. */
FLASH_START_WRITE_ADDR, /* The address in flash where to read data from. */
dat, /* A buffer to copy the data into. */
len /* Lenght of the data, in bytes. */
);
// printf("read rc=0x%02x\r\n",rc);
if (rc == NRF_SUCCESS)
{
// printf("Read OK\r\n");
/* The operation was accepted.
Upon completion, the NRF_FSTORAGE_READ_RESULT event
is sent to the callback function registered by the instance.
Once the event is received, it is possible to read the contents of 'number'. */
}
}
void read_clear_data(void)
{
flash_read((uint8_t *)&at_com_data,sizeof(at_com_data));
flash_clear();
}
void flash_init(void)
{
uint8_t name[] = "Test-string";
nrf_fstorage_init(
&fstorage, /* You fstorage instance, previously defined. */
&nrf_fstorage_sd, /* Name of the backend. */
NULL /* Optional parameter, backend-dependant. */
);
read_clear_data();
memset(&at_com_data,0,sizeof(at_com_data));
printf("power=%d\r\n",at_com_data.tx_power);
at_com_data.tx_power = -8;
memcpy(&at_com_data.device_name[1],name,strlen((char *)name));
at_com_data.device_name[0] = strlen((char *)name);
flash_write((uint8_t *)&at_com_data,sizeof(at_com_data));
memset(&at_com_data,0,sizeof(at_com_data));
flash_read((uint8_t *)&at_com_data,sizeof(at_com_data));
printf("aa_power=%d\r\n",at_com_data.tx_power);
printf("%s\r\n",(char *)&at_com_data.device_name[1]);
}
void flash_operate(uint8_t event)
{
if(fs_event_num == FS_ERASE_EVT)
{
fs_event_num = FS_IDLE;
// at_com_data.tx_power = 0x33;
// printf("power=%x\r\n",at_com_data.tx_power);
// printf("name=%s\r\n",&at_com_data.device_name[1]);
// printf("con_interval=%x\r\n",at_com_data.con_interval.conInterval);
// printf("adv_interval=%x\r\n",at_com_data.adver_interval);
// printf("uart_cfg=%x\r\n",at_com_data.uart_cfg.br);
read_clear_data();
nrf_delay_ms(100);
flash_write((uint8_t *)&at_com_data,sizeof(at_com_data));
wait_flash_complete();
// printf("init power=%x\r\n",at_com_data.tx_power);
// flash_read((uint8_t *)&at_com_data,sizeof(at_com_data));
}
}
//static void PowerUp_write_timeout_handler(void * p_context)
//{
//
//// printf("name=%s len=%d\r\n",&at_com_data.device_name[1],at_com_data.device_name[0]);
//// printf("con_interval=%x\r\n",at_com_data.con_interval.conInterval);
//// printf("adv_interval=%x\r\n",at_com_data.adver_interval);
// if((reset_write_para)&&(PowerUp_uart_rec))
// {
//// printf("Timeout write\r\n");
// fs_event_num = FS_ERASE_EVT;
// }
//
//}
//void PowerUp_write_timer_init(void)
//{
// app_timer_create(&m_PowerUp_write_id,
// APP_TIMER_MODE_SINGLE_SHOT,
// PowerUp_write_timeout_handler);
//
// app_timer_start(m_PowerUp_write_id,POWER_UP_WRITE_TIMEOUT_INTERVAL,NULL);
// reset_write_para = true;
//}