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

pstorage problem when turning power off

I'm currently using the pstorage functions to be able to store permenant data when turning off the power, it works good with me while writing or reading but when I turn off the power, the data is erased from the memory, I think it may be it's a volatile memory, but on its documentation it's said that it write data to flash memory and the flash memory is a non-volatile memory.

thanks in advance

	static void example_pstorage_init()
{
		uint32_t err_code;         
		pstorage_module_param_t p_example_param;    
		// Setup pstorage with 5blocks of 16byte in each.
		p_example_param.block_size  = 0x10; // recommended to be >= 4 byte
		p_example_param.block_count = 10;
		p_example_param.cb          = example_cb_handler;
	  err_code = pstorage_init();
	  //APP_ERROR_CHECK(err_code);  
		err_code = pstorage_register (&p_example_param, &m_p_example_id);
			if (err_code == NRF_SUCCESS)
			{
					pattern_ID_4();
					flash_init();
			}

}

		int main(void)
	{ 	
			pg_size = NRF_FICR->CODEPAGESIZE;
			pg_num  = NRF_FICR->CODESIZE - 1; 
			address = (uint32_t *)(pg_size * pg_num);
			Dt_store = * address;
			// Initialize
			leds_init();
			timers_init();
			gpiote_init();
			ble_stack_init();
			scheduler_init();    
			gap_params_init();
			services_init();
			advertising_init();
			conn_params_init();
			sensor_simulator_init();
			sec_params_init();
		//	if(Dt_store != 0x0001)
					example_pstorage_init();

			// Start execution
			advertising_start();
			LPCOMP_init();
			// Enter main loop
			for (;;)
			{
					app_sched_execute();
					power_manage();
			}
	}

	void edit_speed_ID(uint8_t speed)
{	
			static uint8_t value __attribute__((aligned(8)));
		uint32_t err_code;
	    value = speed;
		err_code = pstorage_block_identifier_get(&m_p_example_id, dummy_block, &p_block_id);
		if (err_code == NRF_SUCCESS)
					pattern_ID_4();		
			nrf_delay_ms(1000);
		
		err_code = pstorage_store(&p_block_id, &value, dummy_size, dummy_offset);
			if (err_code == NRF_SUCCESS)
					pattern_ID_4();
			nrf_delay_ms(1000);
	
			//APP_ERROR_CHECK(err_code);
	
}
    1. Why did you remove APP_ERR_CHECK after pstorage_init function?

    2. Why is Dt_store pointing to the end of flash memory? you are trying to write anything there right? if not used by bootloader, pstorage uses that memory as swap memory.

    3. what is dummy_block and how are you checking that the value stored by pstorage_store function is erased? this function writes to non-volatile memory, so it should retain the value between power cycles.

    1. I removed it because while I'm checking, this function didn't cause any problems with me

    2)"Why is Dt_store pointing to the end of flash memory" I don't know how you know that the DT_Store pointing to the end of flash memory

    3)I check this by trying read the values stored before & after turning off the power, it read it before the poweroff & didn't read it after poweroff.

  • it didn't work also with burnt my code with the bootloader

  • in the documentation: devzone.nordicsemi.com/.../a00018.html

    its said that :Power off is not handled by the module. Hence power off when a flash operation is on-going or pending results in lose of data.

    what's meant by power off is not handled by the module ? ?

    			#include <stdint.h>
    		#include <string.h>
    		#include "nordic_common.h"
    		#include "nrf.h"
    		#include "app_error.h"
    		#include "nrf_gpio.h"
    		#include "nrf51_bitfields.h"
    		#include "ble.h"
    		#include "ble_hci.h"
    		#include "ble_srv_common.h"
    		#include "ble_advdata.h"
    		#include "ble_conn_params.h"
    		#include "boards.h"
    		#include "app_scheduler.h"
    		#include "softdevice_handler.h"
    		#include "app_timer_appsh.h"
    		#include "ble_error_log.h"
    		#include "app_gpiote.h"
    		#include "app_button.h"
    		#include "ble_debug_assert_handler.h"
    		#include "pstorage.h"
    		#include "ble_bas.h"
    		#include "nrf_drv_lpcomp.h"
    		#include "bsp.h"
    		#include "ble_gap.h"
    		#include "ble_LEDS.h"
    		#include "sensorsim.h"
    		#include "ble_dis.h"
    		#include "nrf_delay.h" 
    		#include "app_pwm.h"
    
    		//#include "nrf_pwm.h"
    
    		#define IS_SRVC_CHANGED_CHARACT_PRESENT 0                                           /**< Include or not the service_changed characteristic. if not enabled, the server's database cannot be changed for the lifetime of the device*/
    
    		#define DEVICE_NAME                     "Diamodo"                             /**< Name of device. Will be included in the advertising data. */
    		#define MANUFACTURER_NAME               "WaveWork INC"                        /**< Manufacturer. Will be passed to Device Information Service. */
    
    		#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    		#define APP_ADV_TIMEOUT_IN_SECONDS      180                                         /**< The advertising timeout (in units of seconds). */
    
    		#define APP_TIMER_PRESCALER             0                                           /**< Value of the RTC1 PRESCALER register. */
    		#define APP_TIMER_MAX_TIMERS            4                                           /**< Maximum number of simultaneously created timers. */
    		#define APP_TIMER_OP_QUEUE_SIZE         4                                           /**< Size of timer operation queues. */
    
    		#define BATTERY_LEVEL_MEAS_INTERVAL     APP_TIMER_TICKS(200000, APP_TIMER_PRESCALER) /**< Battery level measurement interval (ticks). */
    		#define MIN_BATTERY_LEVEL               50                                         /**< Minimum simulated battery level. */
    		#define MAX_BATTERY_LEVEL               100                                        /**< Maximum simulated battery level. */
    		#define BATTERY_LEVEL_INCREMENT         1                                          /**< Increment between each simulated battery level measurement. */
    
    
    		#define PNP_ID_VENDOR_ID_SOURCE         0x02                                        /**< Vendor ID Source. */
    		#define PNP_ID_VENDOR_ID                0x1915                                      /**< Vendor ID. */
    		#define PNP_ID_PRODUCT_ID               0xEEEE                                      /**< Product ID. */
    		#define PNP_ID_PRODUCT_VERSION          0x0001                                      /**< Product Version. */
    
    
    		#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(100, UNIT_1_25_MS)            /**< Minimum acceptable connection interval (0.5 seconds). */
    		#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(200, UNIT_1_25_MS)            /**< Maximum acceptable connection interval (1 second). */
    		#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    		#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds). */
    		#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(20000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (15 seconds). */
    		#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER)  /**< Time between each call to sd_ble_gap_conn_param_update after the first call (5 seconds). */
    		#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    		#define APP_GPIOTE_MAX_USERS            1                                           /**< Maximum number of users of the GPIOTE handler. */
    
    		#define SEC_PARAM_TIMEOUT               30                                          /**< Timeout for Pairing Request or Security Request (in seconds). */
    		#define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
    		#define SEC_PARAM_MITM                  0                                           /**< Man In The Middle protection not required. */
    		#define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                        /**< No I/O capabilities. */
    		#define SEC_PARAM_OOB                   0                                           /**< Out Of Band data not available. */
    		#define SEC_PARAM_MIN_KEY_SIZE          7                                           /**< Minimum encryption key size. */
    		#define SEC_PARAM_MAX_KEY_SIZE          16                                          /**< Maximum encryption key size. */
    
    		#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    
    		#define pattern_1												0x01
    		#define pattern_2												0x02
    		#define pattern_3												0x03
    		#define pattern_4												0x04
    		#define pattern_5												0x05
    		#define pattern_6												0x06
    		#define pattern_7												0x07
    		#define pattern_8												0x08
    		#define edit_speed											0x09
    		#define edit_intensity	  							0x10
    		#define edit_direction									0x11
    		#define edit_pattern										0X12
    		#define okay_is_pressed									0x13
    		#define Cancel_is_pressed								0x14
    		#define pattern_default									0x15
    		#define Reset_is_pressed								0x16
    
    		static ble_gap_sec_params_t             m_sec_params;                               /**< Security requirements for this application. */
    		static uint16_t                         m_conn_handle = BLE_CONN_HANDLE_INVALID;    /**< Handle of the current connection. */
    		static LEDS_handling                    m_LEDS;
    		static ble_bas_t                        m_bas;                                      /**< Structure used to identify the battery service. */
    
    
    		static sensorsim_cfg_t                  m_battery_sim_cfg;                          /**< Battery Level sensor simulator configuration. */
    		static sensorsim_state_t                m_battery_sim_state;                        /**< Battery Level sensor simulator state. */
    
    		static app_timer_id_t                   m_battery_timer_id;                         /**< Battery timer. */
    
    
    		//	APP_PWM_INSTANCE(PWM0,1);// Create the instance "PWM0" using TIMER1.
    		//	APP_PWM_INSTANCE(PWM1,2);// Create the instance "PWM1" using TIMER2
    
    
    		static volatile bool ready_flag;            // A flag indicating PWM status.
    
    
    		#define SCHED_MAX_EVENT_DATA_SIZE       sizeof(app_timer_event_t)                   /**< Maximum size of scheduler events. Note that scheduler BLE stack events do not contain any data, as the events are being pulled from the stack in the event handler. */
    		#define SCHED_QUEUE_SIZE                10                                          /**< Maximum number of events in the scheduler queue. */
    
    		void pattern_ID_1(void);
    		void pattern_ID_3(void);
    		void pattern_ID_2(void);
    		void pattern_ID_4(void);
    		void pattern_ID_5(void);
    		void edit_speed_ID(uint8_t speed);
    
    
    		// Persistent storage system event handler
    		void pstorage_sys_event_handler (uint32_t p_evt);
    
    
    
    
    		/**@brief Function for error handling, which is called when an error has occurred.
    		 *
    		 * @warning This handler is an example only and does not fit a final product. You need to analyze
    		 *          how your product is supposed to react in case of error.
    		 *
    		 * @param[in] error_code  Error code supplied to the handler.
    		 * @param[in] line_num    Line number where the handler is called.
    		 * @param[in] p_file_name Pointer to the file name.
    		 */
    
    		void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
    		{
    				// This call can be used for debug purposes during application development.
    				// @note CAUTION: Activating this code will write the stack to flash on an error.
    				//                This function should NOT be used in a final product.
    				//                It is intended STRICTLY for development/debugging purposes.
    				//                The flash write will happen EVEN if the radio is active, thus interrupting
    				//                any communication.
    				//                Use with care. Un-comment the line below to use.
    				ble_debug_assert_handler(error_code, line_num, p_file_name);
    
    				// On assert, the system can only recover with a reset.
    				//NVIC_SystemReset();
    		}
    
    
    		/**@brief Callback function for asserts in the SoftDevice.
    		 *
    		 * @details This function will be called in case of an assert in the SoftDevice.
    		 *
    		 * @warning This handler is an example only and does not fit a final product. You need to analyze
    		 *          how your product is supposed to react in case of Assert.
    		 * @warning On assert from the SoftDevice, the system can only recover on reset.
    		 *
    		 * @param[in]   line_num   Line number of the failing ASSERT call.
    		 * @param[in]   file_name  File name of the failing ASSERT call.
    		 */
    		void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    		{
    				app_error_handler(DEAD_BEEF, line_num, p_file_name);
    		}
    
    
    		/**@brief Function for the LEDs initialization.
    		 *
    		 * @details Initializes all LEDs used by the application.
    		 */
    		static void leds_init(void)
    		{
    				nrf_gpio_cfg_input(3, NRF_GPIO_PIN_NOPULL);
    				
    		//  nrf_gpio_cfg_sense_input(26, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);
    				nrf_gpio_range_cfg_output(LED_1,LED_4);
    				nrf_delay_ms(25);
    				nrf_gpio_pin_clear(LED_1);
    				nrf_gpio_pin_clear(LED_2);
    				nrf_gpio_pin_clear(LED_3);
    				nrf_gpio_pin_clear(LED_4);
    				nrf_delay_ms(50);
    				nrf_gpio_pin_set(LED_1);
    				nrf_gpio_pin_set(LED_2);
    				nrf_gpio_pin_set(LED_3);
    				nrf_gpio_pin_set(LED_4);
    		} 
    
    
    		/**@brief Function for the GAP initialization.
    		 *
    		 * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
    		 *          device including the device name, appearance, and the preferred connection parameters.
    		 */
    		static void gap_params_init(void)
    		{
    				uint32_t                err_code;
    				ble_gap_conn_params_t   gap_conn_params;
    				ble_gap_conn_sec_mode_t sec_mode;
    
    				BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
    				err_code = sd_ble_gap_device_name_set(&sec_mode,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME));
    				APP_ERROR_CHECK(err_code);
    				err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_PHONE );
    				APP_ERROR_CHECK(err_code);
    				memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
    				gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    				gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    				gap_conn_params.slave_latency     = SLAVE_LATENCY;
    				gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
    				err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    				APP_ERROR_CHECK(err_code);
    		}
    
    
    		/**@brief Function for initializing the Advertising functionality.
    		 *
    		 * @details Encodes the required advertising data and passes it to the stack.
    		 *          Also builds a structure to be passed to the stack when starting advertising.
    		 */
    		static void advertising_init(void)
    		{
    				uint32_t      err_code;
    				ble_advdata_t advdata;
    				ble_advdata_t scanrsp;
    				
    				ble_uuid_t adv_uuids[] = {{LEDS_SERVICES_UUID, m_LEDS.uuid_type},
    																	{BLE_UUID_BATTERY_SERVICE,BLE_UUID_TYPE_BLE},
    																	{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}};
    
    				// Build and set advertising data
    				memset(&advdata, 0, sizeof(advdata));
    
    				advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    				advdata.include_appearance      = true;
    				advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
    			
    				memset(&scanrsp, 0, sizeof(scanrsp));
    				scanrsp.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    				scanrsp.uuids_complete.p_uuids  = adv_uuids;
    				
    				err_code = ble_advdata_set(&advdata, &scanrsp);
    				APP_ERROR_CHECK(err_code);
    		}
    
    
    		static void led_write_handler(LEDS_handling * p_leds, uint8_t OP_ID[])
    		{
    					uint8_t Operation_ID;
    					Operation_ID=OP_ID[0];
    					switch (Operation_ID){
    						case  pattern_1:
    								pattern_ID_1();
    								break;
    						case  pattern_2:
    								pattern_ID_2();
    								break;
    						case  pattern_3:
    								pattern_ID_3();
    								break;
    						case  pattern_4:
    								pattern_ID_4();
    								break;
    						case  pattern_5:
    								pattern_ID_5();
    								break;
    						case  pattern_6:
    								break;
    						case  pattern_7:
    								break;
    						case  pattern_8:
    								break;
    						case  edit_speed:
    							 edit_speed_ID(OP_ID[1]);
    								break;
    						case  edit_intensity:
    								break;
    						case  edit_direction:
    								break;
    						case  edit_pattern:
    								break;
    						case  okay_is_pressed:
    								break;
    						case  Cancel_is_pressed:
    								break;
    						case  pattern_default:
    								break;
    						case  Reset_is_pressed:
    								break;
    						default:
    								break;
    						}	
    
    		}
    		/**@brief Function for performing a battery measurement, and update the Battery Level characteristic in the Battery Service.
    		 */
    		static void battery_level_update(void)
    		{
    				uint32_t err_code;
    				uint8_t  battery_level;
    
    				battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg);
    
    				err_code = ble_bas_battery_level_update(&m_bas, battery_level);
    				if ((err_code != NRF_SUCCESS) &&
    						(err_code != NRF_ERROR_INVALID_STATE) &&
    						(err_code != BLE_ERROR_NO_TX_BUFFERS) &&
    						(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
    				)
    				{
    						APP_ERROR_HANDLER(err_code);
    				}
    		}
    
    		/**@brief Function for handling the Battery measurement timer timeout.
    		 *
    		 * @details This function will be called each time the battery level measurement timer expires.
    		 *
    		 * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
    		 *                          app_start_timer() call to the timeout handler.
    		 */
    		static void battery_level_meas_timeout_handler(void * p_context)
    		{
    				UNUSED_PARAMETER(p_context);
    				battery_level_update();
    		}
    
    
    		/**@brief Function for the Timer initialization.
    		 *
    		 * @details Initializes the timer module.
    		 */
    		static void timers_init(void)
    		{
    				uint32_t err_code;
    		//		NRF_TIMER->POWER=TIMER_POWER_POWER_Enabled;
    				// Initialize timer module, making it use the scheduler.
    				APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
    
    				// Create battery timer.
    				err_code = app_timer_create(&m_battery_timer_id, APP_TIMER_MODE_REPEATED, battery_level_meas_timeout_handler);
    				APP_ERROR_CHECK(err_code);
    				err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL);
    				APP_ERROR_CHECK(err_code);
    
    		}
    		/**@brief Function for initializing Device Information Service.
    		 */
    		static void dis_init(void)
    		{
    				uint32_t         err_code;
    				ble_dis_init_t   dis_init_obj;
    				ble_dis_pnp_id_t pnp_id;
    
    				pnp_id.vendor_id_source = PNP_ID_VENDOR_ID_SOURCE;
    				pnp_id.vendor_id        = PNP_ID_VENDOR_ID;
    				pnp_id.product_id       = PNP_ID_PRODUCT_ID;
    				pnp_id.product_version  = PNP_ID_PRODUCT_VERSION;
    
    				memset(&dis_init_obj, 0, sizeof(dis_init_obj));
    
    				ble_srv_ascii_to_utf8(&dis_init_obj.manufact_name_str, MANUFACTURER_NAME);
    				dis_init_obj.p_pnp_id = &pnp_id;
    
    				BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&dis_init_obj.dis_attr_md.read_perm);
    				BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init_obj.dis_attr_md.write_perm);
    
    				err_code = ble_dis_init(&dis_init_obj);
    				APP_ERROR_CHECK(err_code);
    			
    		}
    
    
    
    
    		/**@brief Function for initializing Battery Service.
    		 */
    		static void bas_init(void)
    		{
    				uint32_t       err_code;
    				ble_bas_init_t bas_init_obj;
    
    				memset(&bas_init_obj, 0, sizeof(bas_init_obj));
    
    				bas_init_obj.evt_handler          = NULL;
    				bas_init_obj.support_notification = true;
    				bas_init_obj.p_report_ref         = NULL;
    				bas_init_obj.initial_batt_level   = 100;
    
    				BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&bas_init_obj.battery_level_char_attr_md.cccd_write_perm);
    				BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&bas_init_obj.battery_level_char_attr_md.read_perm);
    				BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init_obj.battery_level_char_attr_md.write_perm);
    
    				BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&bas_init_obj.battery_level_report_read_perm);
    
    				err_code = ble_bas_init(&m_bas, &bas_init_obj);
    				APP_ERROR_CHECK(err_code);
    		}
    
    
    		/**@brief Function for initializing services that will be used by the application.
    		 */
    		static void LEDS_init(void)
    		{
    				uint32_t err_code;
    				ble_LEDS_init_t init;
    				init.led_write_handler = led_write_handler;
    				err_code = ble_LEDS_init(&m_LEDS, &init); 
    				APP_ERROR_CHECK(err_code);
    		}
    
    		static void services_init(void)
    		{ 
    			dis_init();
    			LEDS_init();
    			bas_init();
    		}
    		/**@brief Function for initializing the battery sensor simulator.
    		 */
    		static void sensor_simulator_init(void)
    		{
    				m_battery_sim_cfg.min          = MIN_BATTERY_LEVEL;
    				m_battery_sim_cfg.max          = MAX_BATTERY_LEVEL;
    				m_battery_sim_cfg.incr         = BATTERY_LEVEL_INCREMENT;
    				m_battery_sim_cfg.start_at_max = true;
    
    				sensorsim_init(&m_battery_sim_state, &m_battery_sim_cfg);
    		}
    
    
    		/**@brief Function for initializing security parameters.
    		 */
    		static void sec_params_init(void)
    		{
    				
    				m_sec_params.bond         = SEC_PARAM_BOND;
    				m_sec_params.mitm         = SEC_PARAM_MITM;
    				m_sec_params.io_caps      = SEC_PARAM_IO_CAPABILITIES;
    				m_sec_params.oob          = SEC_PARAM_OOB;
    				m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
    				m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
    		}
    
    
    		/**@brief Function for handling the Connection Parameters Module.
    		 *
    		 * @details This function will be called for all events in the Connection Parameters Module which
    		 *          are passed to the application.
    		 *          @note All this function does is to disconnect. This could have been done by simply
    		 *                setting the disconnect_on_fail config parameter, but instead we use the event
    		 *                handler mechanism to demonstrate its use.
    		 *
    		 * @param[in]   p_evt   Event received from the Connection Parameters Module.
    		 */
    		static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    		{
    				uint32_t err_code;
    
    				if(p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    				{
    						err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    						APP_ERROR_CHECK(err_code);
    				}
    		}
    
    
    		/**@brief Function for handling a Connection Parameters error.
    		 *
    		 * @param[in]   nrf_error   Error code containing information about what went wrong.
    		 */
    		static void conn_params_error_handler(uint32_t nrf_error)
    		{
    				APP_ERROR_HANDLER(nrf_error);
    		}
    
    
    		/**@brief Function for initializing the Connection Parameters module.
    		 */
    		static void conn_params_init(void)
    		{
    				uint32_t               err_code;
    				ble_conn_params_init_t cp_init;
    
    				memset(&cp_init, 0, sizeof(cp_init));
    
    				cp_init.p_conn_params                  = NULL;
    				cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    				cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    				cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    				cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    				cp_init.disconnect_on_fail             = false;
    				cp_init.evt_handler                    = on_conn_params_evt;
    				cp_init.error_handler                  = conn_params_error_handler;
    
    				err_code = ble_conn_params_init(&cp_init);
    				APP_ERROR_CHECK(err_code);
    		}
    
    		/**@brief Function for starting advertising.
    		 */
    		static void advertising_start(void)
    		{
    				uint32_t             err_code;
    				ble_gap_adv_params_t adv_params;
    
    				// Start advertising
    				memset(&adv_params, 0, sizeof(adv_params));
    
    				adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;
    				adv_params.p_peer_addr = NULL;
    				adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    				adv_params.interval    = APP_ADV_INTERVAL;
    				adv_params.timeout     = APP_ADV_TIMEOUT_IN_SECONDS;
    
    				err_code = sd_ble_gap_adv_start(&adv_params);
    				APP_ERROR_CHECK(err_code);
    				// define a pattern ID and call the function passing the Id to it indicating that the advertising start 
    		}
    
    
    
    		/**@brief Function for handling the Application's BLE Stack events.
    		 *
    		 * @param[in]   p_ble_evt   Bluetooth stack event.
    		 */
    		static void on_ble_evt(ble_evt_t * p_ble_evt)
    		{
    				uint32_t                         err_code;
    				static ble_gap_evt_auth_status_t m_auth_status;
    				static ble_gap_master_id_t p_master_id;
    				static ble_gap_sec_keyset_t keys_exchanged;
    
    				switch (p_ble_evt->header.evt_id)
    				{
    						case BLE_GAP_EVT_CONNECTED:
    							 /* nrf_gpio_pin_set(CONNECTED_LED_PIN_NO);
    								nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO);*/
    								m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    								break;
    
    						case BLE_GAP_EVT_DISCONNECTED:
    								/*nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO);
    								m_conn_handle = BLE_CONN_HANDLE_INVALID;*/
    								advertising_start();
    								break;
    
    						case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
    								err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
    																											 BLE_GAP_SEC_STATUS_SUCCESS,
    																											 &m_sec_params,&keys_exchanged);
    								APP_ERROR_CHECK(err_code);
    								break;
    
    						case BLE_GATTS_EVT_SYS_ATTR_MISSING:
    								err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0,BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
    								APP_ERROR_CHECK(err_code);
    								break;
    
    						case BLE_GAP_EVT_AUTH_STATUS:
    								m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status;
    								break;
    
    						case BLE_GAP_EVT_SEC_INFO_REQUEST:
    								//p_enc_info = keys_exchanged.keys_central.p_enc_key
    								
    								if (p_master_id.ediv == p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv)
    								{
    										err_code = sd_ble_gap_sec_info_reply(m_conn_handle, &keys_exchanged.keys_central.p_enc_key->enc_info, &keys_exchanged.keys_central.p_id_key->id_info, NULL);
    										APP_ERROR_CHECK(err_code);
    										p_master_id.ediv = p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv;
    								}
    								else
    								{
    										// No keys found for this device
    										err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL,NULL);
    										APP_ERROR_CHECK(err_code);
    								}
    								break;
    
    						case BLE_GAP_EVT_TIMEOUT:
    								if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
    								{
    										/*nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO);
    
    										// Configure buttons with sense level low as wakeup source.
    										nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN,
    																						 BUTTON_PULL,
    																						 NRF_GPIO_PIN_SENSE_LOW);*/
    										
    										// Go to system-off mode (this function will not return; wakeup will cause a reset)                
    										err_code = sd_power_system_off();
    										APP_ERROR_CHECK(err_code);
    								}
    								break;
    
    						default:
    								// No implementation needed.
    								break;
    				}
    		}
    
    
    		/**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler.
    		 *
    		 * @details This function is called from the scheduler in the main loop after a BLE stack
    		 *          event has been received.
    		 *
    		 * @param[in]   p_ble_evt   Bluetooth stack event.
    		 */
    		static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    		{
    				on_ble_evt(p_ble_evt);
    				ble_conn_params_on_ble_evt(p_ble_evt);
    				ble_LEDS_on_ble_evt(&m_LEDS, p_ble_evt);
    				ble_bas_on_ble_evt(&m_bas, p_ble_evt);
    		}
    
    
    		/**@brief Function for dispatching a system event to interested modules.
    		 *
    		 * @details This function is called from the System event interrupt handler after a system
    		 *          event has been received.
    		 *
    		 * @param[in]   sys_evt   System stack event.
    		 */
    		static void sys_evt_dispatch(uint32_t sys_evt)
    		{
    				pstorage_sys_event_handler(sys_evt);
    		}
    
    
    		/**@brief Function for initializing the BLE stack.
    		 *
    		 * @details Initializes the SoftDevice and the BLE event interrupt.
    		 */
    		static void ble_stack_init(void)
    		{
    				uint32_t err_code;
    				// Enable BLE stack 
    				ble_enable_params_t ble_enable_params;
    				// Initialize the SoftDevice handler module.
    				ble_gap_addr_t addr;
    				SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
    				memset(&ble_enable_params, 0, sizeof(ble_enable_params));
    				ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
    				err_code = sd_ble_enable(&ble_enable_params);
    				APP_ERROR_CHECK(err_code);
    				
    				err_code = sd_ble_gap_address_get(&addr);
    				APP_ERROR_CHECK(err_code);
    				sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr);
    				APP_ERROR_CHECK(err_code);
    				// Subscribe for BLE events.
    				err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    				APP_ERROR_CHECK(err_code);
    				
    				// Register with the SoftDevice handler module for BLE events.
    				err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    				APP_ERROR_CHECK(err_code);
    		}
    
    
    		/**@brief Function for the Event Scheduler initialization.
    		 */
    		static void scheduler_init(void)
    		{
    				APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    		}
    
    		/**@brief Function for initializing the GPIOTE handler module.
    		 */
    		static void gpiote_init(void)
    		{
    				APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
    		}
    
    
    
    		/**@brief defining the patterns & the operations allowed to the user to edit the patterns */
    
    		/**@brief this function when the user press default button or reset */
    
    
    		/**@brief Function for the Power manager.
    		 */
    		static void power_manage(void)
    		{
    				uint32_t err_code = sd_app_evt_wait();
    				APP_ERROR_CHECK(err_code);
    		}
    
    
    		/**@brief Configures and enables the LPCOMP
    		 */
    
    		void LPCOMP_init(void)
    		{	
    		//	NRF_LPCOMP->POWER=LPCOMP_POWER_POWER_Enabled;
    				/* Enable interrupt on LPCOMP UP event */
    
    			NRF_LPCOMP->INTENSET   = (LPCOMP_INTENSET_UP_Enabled << LPCOMP_INTENSET_UP_Pos);
    			//NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set << GPIOTE_INTENSET_PORT_Pos;
    			NVIC_EnableIRQ(LPCOMP_IRQn);	
    			/* Configure LPCOMP - set input source to AVDD*4/8 */
    			NRF_LPCOMP->REFSEL |= (LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling << LPCOMP_REFSEL_REFSEL_Pos);
    			/* Configure LPCOMP - set reference input source to AIN pin 0, i.e. P0.26 */
    			NRF_LPCOMP->PSEL |= (LPCOMP_PSEL_PSEL_AnalogInput4 << LPCOMP_PSEL_PSEL_Pos);
    		//	NRF_LPCOMP->ANADETECT = LPCOMP_ANADETECT_ANADETECT_Up;
    
    			/* Enable and start the low power comparator */
    			NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled;	
    			NRF_LPCOMP->TASKS_START = 1;
    			nrf_delay_ms(1000);
    		}
    
    		void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function
    		{
    				ready_flag = true;
    		}
    
    		/*void PWM_init(void)
    		{
    				uint32_t err_code;
    				app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(1000L, BSP_LED_2,BSP_LED_0);
    				app_pwm_config_t pwm0_cfg = APP_PWM_DEFAULT_CONFIG_2CH(1000L, BSP_LED_3,BSP_LED_1);
    				err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
    				APP_ERROR_CHECK(err_code);
    				err_code = app_pwm_init(&PWM0,&pwm0_cfg,pwm_ready_callback);
    				APP_ERROR_CHECK(err_code);
    				app_pwm_enable(&PWM0);
    				app_pwm_enable(&PWM1);
    			
    				
    			nrf_pwm_config_t pwm_config = PWM_DEFAULT_CONFIG;
    				
    				pwm_config.mode             = PWM_MODE_LED_255;
    				pwm_config.num_channels     = 4;
    				pwm_config.gpio_num[0]      = LED_1;
    				pwm_config.gpio_num[1]      = LED_2;
    				pwm_config.gpio_num[2]      = LED_4;
    				pwm_config.gpio_num[3]      = LED_3;  
    			
    				err_code=nrf_pwm_init(&pwm_config);
    		}*/
    
    				uint16_t dummy_block = 0;
    				uint16_t dummy_size  = 16;
    				uint16_t dummy_offset = 0;
    				pstorage_handle_t p_block_id;
    				uint32_t  * address,speed,Dt_store;
    				uint8_t   addr_speed[16],speed_test;
    				uint32_t pg_size;
    				uint32_t pg_num;	
    				static pstorage_handle_t m_p_example_id;
    				pstorage_module_param_t p_example_param;    
    				// Setup pstorage with 5blocks of 16byte in each.
    
    	//	static pstorage_ntf_cb_t example_cb_handler;
    	static void example_cb_handler(pstorage_handle_t  * handle,
    																	uint8_t              op_code,
    																	uint32_t             result,
    																	uint8_t            * p_data,
    																	uint32_t             data_len)
    	{
    			switch(op_code)
    			{
    					
    					case PSTORAGE_LOAD_OP_CODE:
    						 if (result == NRF_SUCCESS)
    						 {
    								 // Store operation successful.
    						 }
    						 else
    						 {
    								 // Store operation failed.
    						 }
    						 // Source memory can now be reused or freed.
    						 break;       
    					case PSTORAGE_STORE_OP_CODE:
    						 if (result == NRF_SUCCESS)
    						 {
    								 // Update operation successful.
    						 }
    						 else
    						 {
    								 // Update operation failed.
    						 }
    						 break;
    				 case PSTORAGE_CLEAR_OP_CODE:
    						 if (result == NRF_SUCCESS)
    						 {
    								 // Clear operation successful.
    						 }
    						 else
    						 {
    								 // Clear operation failed.
    						 }
    						 break;
    			}
    	}
    	/*
    		void flash_init()
    		{
    				uint32_t value,err_code;//,err_code;
    				value=0x0001;
    				err_code=sd_flash_write(address,(uint32_t *) & value,1);
    				if (err_code == NRF_SUCCESS)
    							pattern_ID_3();
    				nrf_delay_ms(1000);
    		}*/
    
    		static void example_pstorage_init()
    		{
    				uint32_t err_code;         
    
    				p_example_param.block_size  = 0x10; // recommended to be >= 4 byte
    				p_example_param.block_count = 10;
    				p_example_param.cb          = example_cb_handler;
    
    				err_code = pstorage_init();
    					if (err_code == NRF_SUCCESS)
    					{
    							pattern_ID_4();
    					}
    				
    				err_code = pstorage_register (&p_example_param, &m_p_example_id);
    					if (err_code == NRF_SUCCESS)
    					{
    							pattern_ID_4();
    					}
    
    
    		}
    		/**@brief Function for application main entry.
    		 */
    
    
    
    			int main(void)
    			{ 	
    				/*	pg_size = NRF_FICR->CODEPAGESIZE;
    					pg_num  = NRF_FICR->CODESIZE - 1; 
    					address = (uint32_t *)(pg_size * pg_num);
    					Dt_store = * address;*/
    					// Initialize
    
    					nrf_gpio_cfg_input(3, NRF_GPIO_PIN_NOPULL);
    					leds_init();
    					timers_init();
    					gpiote_init();
    					ble_stack_init();
    					scheduler_init();    
    					gap_params_init();
    					services_init();
    					advertising_init();
    					conn_params_init();
    					example_pstorage_init();
    					sensor_simulator_init();
    					sec_params_init();
    						
    					// Start execution
    					advertising_start();
    					LPCOMP_init();
    
    					// Enter main loop
    					for (;;)
    					{
    							app_sched_execute();
    							power_manage();
    					}
    			}
    
    
    		void pattern_ID_1(void)
    		{	
    				uint32_t err_code;
    			//  addr_speed = &speed_test;
    				err_code = pstorage_load(addr_speed, &p_block_id, dummy_size,dummy_offset);
    				if (err_code == NRF_SUCCESS)
    							pattern_ID_4();
    			//	speed = * speed_test;
    				nrf_delay_ms(1000);
    				speed = 5 * addr_speed[0];
    				
    
    			for(uint8_t j = 0  ; j <1 ; j++)
    			{
    				for( uint8_t i =0 ; i < 4 ; i++ )
    				{
    					nrf_gpio_pin_set  (LED_1);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_set  (LED_2);
    					nrf_gpio_pin_clear(LED_1);
    					nrf_delay_ms((uint16_t)speed);
    					nrf_gpio_pin_set  (LED_1);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_set  (LED_4);
    					nrf_gpio_pin_clear(LED_2);
    					nrf_delay_ms((uint16_t)speed);
    					nrf_gpio_pin_set  (LED_2);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_set  (LED_3);
    					nrf_gpio_pin_clear(LED_4);
    					nrf_delay_ms((uint16_t)speed);
    					nrf_gpio_pin_set  (LED_4);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_clear(LED_3);
    					nrf_delay_ms((uint16_t)speed);
    					nrf_gpio_pin_set  (LED_3);
    				}
    			}
    		}
    
    		void pattern_ID_2(void)
    		{ 
    				uint32_t err_code;
    
    				err_code = pstorage_load(addr_speed, &p_block_id, dummy_size, dummy_offset);
    				if (err_code == NRF_ERROR_NULL)
    							pattern_ID_4();	
    				speed = * addr_speed;
    				speed = 5 * speed;	
    
    
    				for (uint8_t i=0; i<4 ; i++)
    				{
    					nrf_gpio_pin_clear(LED_1);
    					nrf_delay_ms((uint16_t)speed);
    					nrf_gpio_pin_set  (LED_1);
    					nrf_delay_ms((uint16_t)speed);
    				}
    		}
    
    		void pattern_ID_3(void)
    		{
    				for (uint8_t i=0; i<4 ; i++)
    				{
    					nrf_gpio_pin_clear(LED_2);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_set(LED_2);
    					nrf_delay_ms(200);
    				}
    
    		}
    
    		void pattern_ID_4(void)
    		{
    				for (uint8_t i=0; i<4 ; i++)
    				{
    					nrf_gpio_pin_clear(LED_3);
    					nrf_delay_ms(200);
    					nrf_gpio_pin_set(LED_3);
    					nrf_delay_ms(200);
    				}
    		}
    
    		void edit_speed_ID(uint8_t speed)
    		{	
    					static uint8_t value __attribute__((aligned(8)));
    					uint32_t err_code;
    					value = speed;
    				err_code = pstorage_block_identifier_get(&m_p_example_id, dummy_block, &p_block_id);
    				if (err_code == NRF_SUCCESS)
    							pattern_ID_4();		
    					nrf_delay_ms(500);
    				err_code=pstorage_clear(&p_block_id,dummy_size);
    				if (err_code == NRF_SUCCESS)
    							pattern_ID_4();
    					nrf_delay_ms(500);
    				err_code = pstorage_store(&p_block_id, &value, dummy_size, dummy_offset);
    					if (err_code == NRF_SUCCESS)
    							pattern_ID_4();
    					nrf_delay_ms(500);
    	 
    		//		memset(&value,value,sizeof(value));
    			
    					//APP_ERROR_CHECK(err_code);
    
    			
    		/*	//pattern_ID_3();
    			uint32_t value;//, err_code;
    		//	uint32_t *temp_addr;
    			value=5  * speed;
    			while(sd_flash_write(address,(uint32_t *) & value,1)==NRF_ERROR_BUSY);
    			nrf_delay_ms(1000);
    			pattern_ID_3();
    		//	APP_ERROR_CHECK(err_code);
    			flag=false;
    		//	flash_init();*/
    			
    		}
    		
    		
    		void pattern_ID_5(void)
    		{
    						//	NRF_POWER->SYSTEMOFF =POWER_SYSTEMOFF_SYSTEMOFF_Enter;
    						sd_power_system_off();
    		}
    		
    				/* Interrupt handler for LPCOMP */
    		void LPCOMP_IRQHandler(void)
    		{
    				// Clear event
    			 NRF_LPCOMP->EVENTS_UP = 0;
    			 NRF_LPCOMP->TASKS_SAMPLE = 1;
    			 if(NRF_LPCOMP->EVENTS_UP == 0x00000001)
    					 {
    					 NRF_LPCOMP->EVENTS_UP = 0;
    					 main();
    					 }
    
    		}
    
  • address = (uint32_t *)(pg_size * pg_num); Dt_store = * address; // if(Dt_store != 0x0001) example_pstorage_init();

    not sure what you are trying to do here.

    How do you know that the memory is erased after power off? I mean where are you testing it? you can only compare the values using pstorage_load function, where are you doing that?

Related