Goodday
I have integrated the fstorage peripheral example with the BLE_beaconing example. SDK 15.2. I can read and write strings. I cannot read back the hex number if declared as an int or a float
my problem lies in how to use this function to read a float or int.
rc = nrf_fstorage_read(&fstorage, 0x3e100, &m_data_read,sizeof(m_data_read));
My Main.c code below
/** * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @file * * @defgroup ble_sdk_app_beacon_main main.c * @{ * @ingroup ble_sdk_app_beacon * @brief Beacon Transmitter Sample Application main file. * * This file contains the source code for an Beacon transmitter sample application. */ #include <stdbool.h> #include <stdint.h> #include "nordic_common.h" #include "bsp.h" #include "nrf_soc.h" #include "nrf_sdh.h" #include "nrf_sdh_ble.h" #include "ble_advdata.h" #include "app_timer.h" #include "nrf_pwr_mgmt.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_fstorage_sd.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_sdh.h" #include "nrf_sdh_ble.h" #include "nrf_fstorage_sd.h" #else #include "nrf_drv_clock.h" #include "nrf_fstorage_nvmc.h" #endif #define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */ #define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */ #define APP_BEACON_INFO_LENGTH 0x17 /**< Total length of information advertised by the Beacon. */ #define APP_ADV_DATA_LENGTH 0x15 /**< Length of manufacturer specific data in the advertisement. */ #define APP_DEVICE_TYPE 0x02 /**< 0x02 refers to Beacon. */ #define APP_MEASURED_RSSI 0xC3 /**< The Beacon's measured RSSI at 1 meter distance in dBm. */ #define APP_COMPANY_IDENTIFIER 0x0059 /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */ #define APP_MAJOR_VALUE 0x01, 0x02 /**< Major value used to identify Beacons. */ #define APP_MINOR_VALUE 0x03, 0x04 /**< Minor value used to identify Beacons. */ #define APP_BEACON_UUID 0x01, 0x12, 0x23, 0x34, \ 0x45, 0x56, 0x67, 0x78, \ 0x89, 0x9a, 0xab, 0xbc, \ 0xcd, 0xde, 0xef, 0xf0 /**< Proprietary UUID for Beacon. */ #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ #if defined(USE_UICR_FOR_MAJ_MIN_VALUES) #define MAJ_VAL_OFFSET_IN_BEACON_INFO 18 /**< Position of the MSB of the Major Value in m_beacon_info array. */ #define UICR_ADDRESS 0x10001080 /**< Address of the UICR register used by this example. The major and minor versions to be encoded into the advertising data will be picked up from this location. */ #endif static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */ static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded advertising set. */ static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt); NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) = { /* Set a handler for fstorage events. */ .evt_handler = fstorage_evt_handler, /* These below are the boundaries of the flash space assigned to this instance of fstorage. * You must set these manually, even at runtime, before nrf_fstorage_init() is called. * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the * last page of flash available to write data. */ .start_addr = 0x3e000, .end_addr = 0x3ffff, }; /* Dummy data to write to flash. */ const uint32_t m_data = 123456; const uint32_t m_data_read ; // used to store the read back from flash char m_hello_world[12] = "hello world"; char m_hello_world_read[12]="\0"; // used to store the read back from flash /**@brief Helper function to obtain the last address on the last page of the on-chip flash that * can be used to write user data. */ static uint32_t nrf5_flash_end_addr_get() { uint32_t const bootloader_addr = NRF_UICR->NRFFW[0]; uint32_t const page_sz = NRF_FICR->CODEPAGESIZE; uint32_t const code_sz = NRF_FICR->CODESIZE; return (bootloader_addr != 0xFFFFFFFF ? bootloader_addr : (code_sz * page_sz)); } /**@brief Struct that contains pointers to the encoded advertising data. */ static ble_gap_adv_data_t m_adv_data = { .adv_data = { .p_data = m_enc_advdata, .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX }, .scan_rsp_data = { .p_data = NULL, .len = 0 } }; static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] = /**< Information advertised by the Beacon. */ { APP_DEVICE_TYPE, // Manufacturer specific information. Specifies the device type in this // implementation. APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the // manufacturer specific data in this implementation. APP_BEACON_UUID, // 128 bit UUID value. APP_MAJOR_VALUE, // Major arbitrary value that can be used to distinguish between Beacons. APP_MINOR_VALUE, // Minor arbitrary value that can be used to distinguish between Beacons. APP_MEASURED_RSSI // Manufacturer specific information. The Beacon's measured TX power in // this implementation. }; /**@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 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; uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; ble_advdata_manuf_data_t manuf_specific_data; manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER; #if defined(USE_UICR_FOR_MAJ_MIN_VALUES) // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the // UICR instead of using the default values. The major and minor values obtained from the UICR // are encoded into advertising data in big endian order (MSB First). // To set the UICR used by this example to a desired value, write to the address 0x10001080 // using the nrfjprog tool. The command to be used is as follows. // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value> // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the // the following command should be used. // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102 uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16; uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF); uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO; m_beacon_info[index++] = MSB_16(major_value); m_beacon_info[index++] = LSB_16(major_value); m_beacon_info[index++] = MSB_16(minor_value); m_beacon_info[index++] = LSB_16(minor_value); #endif manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info; manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH; // Build and set advertising data. memset(&advdata, 0, sizeof(advdata)); advdata.name_type = BLE_ADVDATA_NO_NAME; advdata.flags = flags; advdata.p_manuf_specific_data = &manuf_specific_data; // Initialize advertising parameters (used when starting advertising). memset(&m_adv_params, 0, sizeof(m_adv_params)); m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; m_adv_params.p_peer_addr = NULL; // Undirected advertisement. m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY; m_adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL; m_adv_params.duration = 0; // Never time out. err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); APP_ERROR_CHECK(err_code); } /**@brief Function for starting advertising. */ static void advertising_start(void) { ret_code_t err_code; err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG); APP_ERROR_CHECK(err_code); err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); APP_ERROR_CHECK(err_code); } /**@brief Function for initializing the BLE stack. * * @details Initializes the SoftDevice and the BLE event interrupt. */ static void ble_stack_init(void) { ret_code_t err_code; err_code = nrf_sdh_enable_request(); APP_ERROR_CHECK(err_code); // Configure the BLE stack using the default settings. // Fetch the start address of the application RAM. uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); APP_ERROR_CHECK(err_code); // Enable BLE stack. err_code = nrf_sdh_ble_enable(&ram_start); APP_ERROR_CHECK(err_code); } static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt) { if (p_evt->result != NRF_SUCCESS) { NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation."); return; } switch (p_evt->id) { case NRF_FSTORAGE_EVT_WRITE_RESULT: { NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.", p_evt->len, p_evt->addr); } break; case NRF_FSTORAGE_EVT_ERASE_RESULT: { NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.", p_evt->len, p_evt->addr); } break; default: break; } } /**@brief Sleep until an event is received. */ static void power_manage(void) { #ifdef SOFTDEVICE_PRESENT (void) sd_app_evt_wait(); #else __WFE(); #endif } static void print_flash_info(nrf_fstorage_t * p_fstorage) { NRF_LOG_INFO("========| flash info |========"); NRF_LOG_INFO("erase unit: \t%d bytes", p_fstorage->p_flash_info->erase_unit); NRF_LOG_INFO("program unit: \t%d bytes", p_fstorage->p_flash_info->program_unit); NRF_LOG_INFO("=============================="); } 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)) { power_manage(); } } /**@brief Function for initializing logging. */ static void log_init(void) { ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } /**@brief Function for initializing LEDs. */ static void leds_init(void) { ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL); APP_ERROR_CHECK(err_code); } /**@brief Function for initializing timers. */ static void timers_init(void) { ret_code_t err_code = app_timer_init(); APP_ERROR_CHECK(err_code); } /**@brief Function for initializing power management. */ static void power_management_init(void) { ret_code_t err_code; err_code = nrf_pwr_mgmt_init(); APP_ERROR_CHECK(err_code); } /**@brief Function for handling the idle state (main loop). * * @details If there is no pending log operation, then sleep until next the next event occurs. */ static void idle_state_handle(void) { if (NRF_LOG_PROCESS() == false) { nrf_pwr_mgmt_run(); } } /** as per example but * @brief Function for application main entry. */ int main(void) { ret_code_t rc = NRF_LOG_INIT(NULL); // Initialize. log_init(); timers_init(); leds_init(); power_management_init(); ble_stack_init(); advertising_init(); // Start execution. NRF_LOG_INFO("Beacon example started."); advertising_start(); nrf_fstorage_api_t * p_fs_api; #ifdef SOFTDEVICE_PRESENT NRF_LOG_INFO("SoftDevice is present."); NRF_LOG_INFO("Initializing nrf_fstorage_sd implementation..."); /* Initialize an fstorage instance using the nrf_fstorage_sd backend. * nrf_fstorage_sd uses the SoftDevice to write to flash. This implementation can safely be * used whenever there is a SoftDevice, regardless of its status (enabled/disabled). */ p_fs_api = &nrf_fstorage_sd; #else NRF_LOG_INFO("SoftDevice not present."); NRF_LOG_INFO("Initializing nrf_fstorage_nvmc implementation..."); /* Initialize an fstorage instance using the nrf_fstorage_nvmc backend. * nrf_fstorage_nvmc uses the NVMC peripheral. This implementation can be used when the * SoftDevice is disabled or not present. * * Using this implementation when the SoftDevice is enabled results in a hardfault. */ p_fs_api = &nrf_fstorage_nvmc; #endif rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL); APP_ERROR_CHECK(rc); print_flash_info(&fstorage); /* It is possible to set the start and end addresses of an fstorage instance at runtime. * They can be set multiple times, should it be needed. The helper function below can * be used to determine the last address on the last page of flash memory available to * store data. */ (void) nrf5_flash_end_addr_get(); /* Let's write to flash. */ NRF_LOG_INFO("Writing \"%x\" to flash.", m_data); rc = nrf_fstorage_write(&fstorage, 0x3e000, &m_data, sizeof(m_data), NULL); APP_ERROR_CHECK(rc); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); #ifdef SOFTDEVICE_PRESENT // Enable the SoftDevice and the BLE stack. NRF_LOG_INFO("Enabling the SoftDevice."); // ble_stack_init(); // m_data = 0xDEADBEEF; NRF_LOG_INFO("Writing \"%x\" to flash.", m_data); rc = nrf_fstorage_write(&fstorage, 0x3e100, &m_data, sizeof(m_data), NULL); APP_ERROR_CHECK(rc); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); #endif NRF_LOG_INFO("Writing \"%s\" to flash.", m_hello_world); rc = nrf_fstorage_write(&fstorage, 0x3f000, m_hello_world, sizeof(m_hello_world), NULL); APP_ERROR_CHECK(rc); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); rc = nrf_fstorage_read(&fstorage, 0x3f000, m_hello_world_read, sizeof(m_hello_world_read)); APP_ERROR_CHECK(rc); NRF_LOG_INFO("Reading \"%s\" from flash.", m_hello_world_read); wait_for_flash_ready(&fstorage); NRF_LOG_INFO("Done."); rc = nrf_fstorage_read(&fstorage, 0x3e100, &m_data_read,sizeof(m_data_read)); APP_ERROR_CHECK(rc); NRF_LOG_INFO("Reading \"%s\" from flash.", m_data_read); // Enter main loop. for (;; ) { idle_state_handle(); } } /** * @} */