Hi all,
I am currently working with nRF52832 boards, and I am trying to save some values in my flash memory. I have already created a code for this purpose and I am able to save the temperature value and read it after that, but now I will like to create an temp_array where I will be able to save at least 10 values as well as pointer value after every iteration in different page. I have already done that, but without using BLE mesh which is the most important part of my project. Now, I converted to SoftDevice APIs related to mesh purposes and want to check how can I do that inside mesh SDK. I hope that you will understand what I want and help me. Thanks!
Best regards,
Adnan.
SDK code:
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "nrf.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "boards.h"
#include "nrf_delay.h"
#include "nrf_temp.h"
#include "app_error.h"
#include "bsp.h"
#include "app_util_platform.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_nvmc.h"
#include "nordic_common.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "nrf_cli.h"
#include "nrf_cli_uart.h"
void saadc_callback_handler (nrf_drv_saadc_evt_t const * p_event){
// Empty handler function
}
void saadc_init(void){
ret_code_t err_code;
// Create a config struct and assign it default values along with the pin number for ADC input
// Configure the input as Single Ended (One Pin Reading)
nrf_saadc_channel_config_t channel_config = NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
// Initilize the saadc
err_code = nrf_drv_saadc_init(NULL, saadc_callback_handler);
APP_ERROR_CHECK(err_code);
// Initilize the channel which will be connected to that specific pin
err_code = nrfx_saadc_channel_init(0, &channel_config);
APP_ERROR_CHECK(err_code);
}
float f_temp(){
float temp;
NRF_TEMP->TASKS_START = 1;
while (NRF_TEMP->EVENTS_DATARDY == 0)
{
// Do nothing.
}
NRF_TEMP->EVENTS_DATARDY = 0;
temp = (nrf_temp_read() / 4);
NRF_TEMP->TASKS_STOP = 1;
return temp;
}
float f_store(float temp, uint32_t *i, int temp_size){
uint32_t tmp_temp = temp;
uint32_t f_addr = 0x0007f000;
uint32_t * p_addr = (uint32_t *)f_addr;
uint32_t tmp_temp_array[*i+1];
for (int k = 0; k<=*i; k++) {
tmp_temp_array[k] = *(p_addr+k);
}
tmp_temp_array[*i] = tmp_temp;
nrf_nvmc_page_erase(f_addr);
nrf_nvmc_write_words(f_addr, tmp_temp_array, *i+1);
for (int j = 0; j<=*i; j++){
NRF_LOG_INFO("i memory is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i));
NRF_LOG_INFO("j is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(j));
NRF_LOG_INFO("In memory data is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*(p_addr+j)));
}
NRF_LOG_INFO("i at end of f_store is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i));
}
float f_compute(int temp_size){
uint32_t f_addr = 0x0007f000;
uint32_t * p_addr = (uint32_t *)f_addr;
uint32_t avg_addr = 0x0007d000;
uint32_t * avg_pointer = (uint32_t *)avg_addr;
float temp_sum = 0;
for (int k = 0; k<temp_size; k++){
temp_sum = temp_sum + (*(p_addr+k));
}
float average_temp = temp_sum / temp_size;
NRF_LOG_INFO("Average temperature is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(average_temp));
nrf_nvmc_page_erase(avg_addr);
nrf_nvmc_write_word(avg_addr, average_temp);
nrf_nvmc_page_erase(f_addr);
}
int main(void)
{
saadc_init();
nrf_saadc_value_t adc_val;
nrf_temp_init();
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
int temp_size = 10;
uint32_t i_addr = 0x0007e000;
uint32_t * i_pointer = (uint32_t *)i_addr;
NRF_LOG_INFO("Test is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i_pointer));
if (*i_pointer == -1){
nrf_nvmc_write_word(i_addr, 0);
}
NRF_LOG_INFO("after Test is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i_pointer));
while (true)
{
nrfx_saadc_sample_convert(0, &adc_val);
float voltage = adc_val * 3.6 / 1024;
NRF_LOG_INFO("Volts: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(voltage));
//NRF_LOG_INFO("Hello!\n");
if (voltage > 2.5){
NRF_LOG_INFO("i: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i_pointer));
if (*i_pointer < temp_size){
NRF_LOG_INFO("uso u if\n");
f_store(f_temp(), i_pointer, temp_size);
const uint32_t new_i = *(i_pointer) + 1;
NRF_LOG_INFO("i after f-store() is: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(new_i));
nrf_nvmc_page_erase(i_addr);
nrf_nvmc_write_word(i_addr, new_i);
NRF_LOG_INFO("after new i: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i_pointer));
//nrf_nvmc_write_word(i_addr, 2);
//NRF_LOG_INFO("after second new i: " NRF_LOG_FLOAT_MARKER " \n", NRF_LOG_FLOAT(*i_pointer));
} else {
NRF_LOG_INFO("uso u else\n");
f_compute(temp_size); //in this function, erase from memory
//i = 0;
nrf_nvmc_page_erase(i_addr);
nrf_nvmc_write_word(i_addr, 0);
}
}
else{
NRF_LOG_INFO("Not possible!\n");
}
nrf_delay_ms(5000);
NRF_LOG_FLUSH();
}
}
Mesh SDK code with SoftDevice APIs:
#include <stdint.h>
#include <string.h>
/* HAL */
#include "boards.h"
#include "simple_hal.h"
#include "app_timer.h"
/* Core */
#include "nrf_mesh_config_core.h"
#include "nrf_mesh_gatt.h"
#include "nrf_mesh_configure.h"
#include "nrf_mesh.h"
#include "mesh_stack.h"
#include "device_state_manager.h"
#include "access_config.h"
#include "proxy.h"
/* Provisioning and configuration */
#include "mesh_provisionee.h"
#include "mesh_app_utils.h"
/* Models */
#include "generic_onoff_server.h"
/* Logging and RTT */
#include "log.h"
#include "rtt_input.h"
/* Example specific includes */
#include "app_config.h"
#include "example_common.h"
#include "nrf_mesh_config_examples.h"
#include "light_switch_example_common.h"
#include "app_onoff.h"
#include "ble_softdevice_support.h"
#include "nrf_delay.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h "
static void sys_evt_dispatch(uint32_t sys_evt)
{
app_sys_event_handler(sys_evt);
}
NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, sys_evt_dispatch, NULL);
static uint8_t flash_operation_completed = false;
void app_sys_event_handler(uint32_t sys_evt)
{
switch (sys_evt)
{
case NRF_EVT_FLASH_OPERATION_SUCCESS:
flash_operation_completed = true;
break;
case NRF_EVT_FLASH_OPERATION_ERROR:
break;
}
}
static void initilize(void)
{
__LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
}
static uint32_t temp_read()
{
uint32_t temp;
sd_temp_get(&temp);
uint32_t temperature = (uint8_t)(temp/4);
__LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"temp_read = %d \n",temperature);
return temperature;
}
static int32_t f_store(uint32_t temperature)
{
uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
uint32_t pg_num = NRF_FICR->CODESIZE-2; // use last page in flash
uint32_t *addr = (uint32_t *)(pg_size * pg_num);
uint32_t tempa[1] = {temperature};
flash_operation_completed = false;
sd_flash_page_erase(pg_num);
while(!flash_operation_completed)
{
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Flash write finished successfully!\n");
sd_app_evt_wait();
break;
}
flash_operation_completed = false;
sd_flash_write((uint32_t*)addr, (uint32_t*)tempa, 1);
while(!flash_operation_completed)
{
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Flash write finished successfully!\n");
sd_app_evt_wait();
break;
}
__LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"temp_read = %d \n", *(uint32_t*)addr);
}
int main(void)
{
initilize();
while(true) {
__LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"Before temp_read function!\n");
temp_read();
__LOG(LOG_SRC_APP,LOG_LEVEL_INFO,"After temp_read function!\n");
f_store(temp_read());
nrf_delay_ms(10000);
}
for (;;)
{
(void)sd_app_evt_wait();
}
}