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

Changing Major Value of Beacon

Hello.

Now, I'm trying to make a Beacon with updatable Major Value, based on sample 'ble_app_beacon'.

I'm not really familiar with BLE and Nordic device, though...

I know the format of iBeacon. Also, I need to make  the device connectable (maybe scannable as well) to update data.

I've investigated numerous samples but nothing is decisive.

Below is my code.

#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_drv_spi.h"

#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"

#include "nrf_spi_mngr.h"

#include "sdk_config.h"
#include "nrf_drv_spis.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>

#if defined (LEGACY_DEFINE)

#undef NRFX_DEFINE
#define NRFX_DEFINE LEGACY_DEFINE

#endif 


#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
#define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
//#define APP_BLE_OBSERVER_PRIO           1                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */

//#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 CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(100, UNIT_1_25_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_COMPANY_IDENTIFIER          0x004C                             /**< 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 APP_SIGNAL_OUT                  0xc3                              /**< Proprietary SIGNAL OUT 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. */

#define UPDATE_MS                       5000
#define BEACON_INTERVAL                 APP_TIMER_TICKS(UPDATE_MS)
APP_TIMER_DEF(m_beacon_timer_id);                                               // Timer ID
static volatile bool m_beacon_timer_flag = false;                               // Timer Flag

#define APP_SPIS_SCK_PIN 26
#define APP_SPIS_MOSI_PIN 29
#define APP_SPIS_MISO_PIN 30

#define APP_SPIS_CS_PIN 31

#define SPI_INSTANCE  0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */

static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */

//#define TEST_STRING_RS                 0x1E, 0x00, 0x00
//static uint8_t       m_tx_buf_rs[] = TEST_STRING_RS;    /**< TX buffer. */
//static uint8_t       m_rx_buf_rs[sizeof(TEST_STRING_RS) + 1];    /**< RX buffer. */
//static const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */
uint8_t       m_rx_buf_rs[];

//#define TEST_STRING_RD                 0xA6, 0x00, 0x00
//static uint8_t       m_tx_buf_rd[] = TEST_STRING_RD;           /**< TX buffer. */
//static uint8_t       m_rx_buf_rd[sizeof(TEST_STRING_RD) + 1];    /**< RX buffer. */
//static const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
uint8_t       m_rx_buf_rd[];

/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    spi_xfer_done = true;
    NRF_LOG_INFO("Transfer completed.");
    if (m_rx_buf_rs[0] != 0) 
    {
        NRF_LOG_INFO(" Received:");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf_rs, strlen((const char *)m_rx_buf_rs));
    }
   if (m_rx_buf_rd[0] != 0) 
    {
        NRF_LOG_INFO(" Received:");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf_rd, strlen((const char *)m_rx_buf_rd));
    }

}

//****************************************************************************// 
// BLE FUNCTIONS
//****************************************************************************//
/**@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. */
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;
    uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    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.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_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.interval        = CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.
    //m_adv_params.duration        = 10;       // Never time out.
    

    m_adv_params.scan_req_notification = 1;   //VLS

    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 application timers.
 * @param   None.
 * @retval  None.
 */
static void application_timers_start(void)
{
	ret_code_t err_code;

	// Start application timers.
	err_code = app_timer_start(m_beacon_timer_id, BEACON_INTERVAL, NULL);
	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 stopping advertising.
 * @param   None.
 * @retval  None.
 */
static void advertising_stop(void)
{
	ret_code_t err_code;

	err_code = sd_ble_gap_adv_stop(m_adv_handle);
	APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err_code;

    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_SCAN_REQ_REPORT: 
      NRF_LOG_INFO("RSSI %d",p_ble_evt->evt.gap_evt.params.scan_req_report.rssi);
      break;

    default:
      // No implementation needed.
      break;
    }
}

/**@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);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}


/**@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();
    }
}

static void update_beacon_data(void)
{

    //#define TEST_STRING_RS                 0x1E, 0x00, 0x00
    uint8_t       m_tx_buf_rs[3] = {0x1E, 0x00, 0x00};    /**< TX buffer. */
    m_rx_buf_rs[sizeof(m_tx_buf_rs) + 1];    /**< RX buffer. */
    const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */

    //#define TEST_STRING_RD                 0xA6, 0x00, 0x00
    uint8_t       m_tx_buf_rd[3] = {0xA6, 0x00, 0x00};           /**< TX buffer. */
    m_rx_buf_rd[sizeof(m_tx_buf_rd) + 1];    /**< RX buffer. */
    const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
    
    // beacon update
    advertising_stop();
    
    nrf_gpio_cfg_output(APP_SPIS_CS_PIN);
    nrf_gpio_pin_set(APP_SPIS_CS_PIN);
        
    memset(m_rx_buf_rs, 0, m_length_rs);
    memset(m_rx_buf_rd, 0, m_length_rd);
    spi_xfer_done = false;
        
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rs, m_length_rs, m_rx_buf_rs, m_length_rs));
    nrf_delay_ms(5);
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rd, m_length_rd, m_rx_buf_rd, m_length_rd));
    
    //nrf_delay_ms(10);
    nrf_delay_ms(5);
    
    m_beacon_info[18] = m_rx_buf_rd[2];
    m_beacon_info[19] = m_rx_buf_rd[3];

    advertising_init();
    advertising_start();
}  

/**
 * @brief Function for application main entry.
 */
int main(void)
{
    // Initialize.
    ret_code_t err_code;
    ble_advdata_t advdata;
    ble_advdata_manuf_data_t manuf_specific_data;

    //NRF_POWER->TASKS_CONSTLAT = 1;
    log_init();
    timers_init();
    leds_init();
    //power_management_init();
    ble_stack_init();
    advertising_init();
 
    NRF_LOG_INIT(NULL);

    // Start execution.
    NRF_LOG_INFO("Beacon started.");
    //application_timers_start();
    advertising_start();

    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = APP_SPIS_CS_PIN;
    spi_config.miso_pin = APP_SPIS_MISO_PIN;
    spi_config.mosi_pin = APP_SPIS_MOSI_PIN;
    spi_config.sck_pin  = APP_SPIS_SCK_PIN;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

    //memset(m_rx_buf, 0, m_length);
    //spi_xfer_done = false;

    //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)); 
    /*while (!spis_xfer_done)
    {
        __WFE();
    }*/

    //APP_ERROR_CHECK(nrf_drv_spis_init(&spis_2, &spis_config, spis_event_handler2));
    // Enter main loop.
    for (;; )
    {
        idle_state_handle();
        update_beacon_data();
    }
}

I changed parameter to 'BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED'.

However, it is not scannable and conectable.

Do you have any specific idea to make it?

My environment are the custom board with nRF52832 and SDK17.0.2.

Kindly Regards,

Shigeto

Parents Reply
  • Hi,

    Sorry for a late reaction.

    I've added  sd_ble_cfg_set() with BLE_CONN_CFG_GAP into ble_stack_init function.

    But nrf_sdh_ble_enable function returns error #4.

    Again, I researched  the reason and never found out decisive solution.

    Do you have any ideas to solve this problem?

    (I have done amendments on sdk_config file.) 

    code of ble_stack_init is below

    static void ble_stack_init(void)
    {
        ret_code_t err_code;
        //ble_conn_cfg_t* conn_cfg;
        //ble_gap_cfg_t* gap_cfg_t;
        ble_cfg_t    ble_cfg;
        uint32_t     ram_start = 0;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        memset(&ble_cfg, 0, sizeof(ble_cfg));
      
        // Configure total number of connections.
        ble_cfg.conn_cfg.conn_cfg_tag                     = BLE_CONN_CFG_GAP;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = BLE_GAP_CONN_COUNT_DEFAULT * 3;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT * 10;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
    
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    

    Do I need to set up all the parameters for sd_ble_cfg_set() before nrf_sdh_ble_enable()????

    Kindly Regards,

    Shigeto

Children
  • sgret612 said:
    Do you have any ideas to solve this problem?

    Your new SoftDevice configuration likely needs more RAM, and you likely need to adjust the allocated RAM for the SoftDevice in your project.

     If you have set the start address for RAM to low, you will see the following output printed:

    You can then adjust the Section Placement Macro to have the correct values, so that it matches your configuration.

    See section 4 in this posthttps://devzone.nordicsemi.com/nordic/short-range-guides/b/getting-started/posts/adjustment-of-ram-and-flash-memory

  • Hi,

    Thanks for your quick reply!!!!

    I got it and it works.

    But it' not still connectable and scannable...

    Mmmm... it is my wonder why 'nRF Connect for iPhone' can not scan my beacon even though  an application called 'Beacon scan' catch and display the iBeacon...

    My code is below.

    #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_drv_spi.h"
    #include "ble_advertising.h"
    #include "ble_gap.h"
    
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    
    #include "nrf_spi_mngr.h"
    
    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    
    #if defined (LEGACY_DEFINE)
    
    #undef NRFX_DEFINE
    #define NRFX_DEFINE LEGACY_DEFINE
    
    #endif 
    
    
    #define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
    #define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    //#define APP_BLE_OBSERVER_PRIO           1                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    
    //#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 CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(100, UNIT_1_25_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_COMPANY_IDENTIFIER          0x004C                             /**< 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 APP_SIGNAL_OUT                  0xc3                              /**< Proprietary SIGNAL OUT 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. */
    
    #define UPDATE_MS                       5000
    #define BEACON_INTERVAL                 APP_TIMER_TICKS(UPDATE_MS)
    APP_TIMER_DEF(m_beacon_timer_id);                                               // Timer ID
    static volatile bool m_beacon_timer_flag = false;                               // Timer Flag
    
    #define APP_SPIS_SCK_PIN 26
    #define APP_SPIS_MOSI_PIN 29
    #define APP_SPIS_MISO_PIN 30
    
    #define APP_SPIS_CS_PIN 31
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    //#define TEST_STRING_RS                 0x1E, 0x00, 0x00
    //static uint8_t       m_tx_buf_rs[] = TEST_STRING_RS;    /**< TX buffer. */
    //static uint8_t       m_rx_buf_rs[sizeof(TEST_STRING_RS) + 1];    /**< RX buffer. */
    //static const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */
    uint8_t       m_rx_buf_rs[];
    
    //#define TEST_STRING_RD                 0xA6, 0x00, 0x00
    //static uint8_t       m_tx_buf_rd[] = TEST_STRING_RD;           /**< TX buffer. */
    //static uint8_t       m_rx_buf_rd[sizeof(TEST_STRING_RD) + 1];    /**< RX buffer. */
    //static const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
    uint8_t       m_rx_buf_rd[];
    
    #define BLE_GAP_EVENT_LENGTH_DEFAULT        (3)  /**< Default event length, in 1.25 ms units. */
    
    /**@brief Receive MPS used by IPSP. */
    #define BLE_IPSP_RX_MPS                                    50
    
    /**@brief Maximum number of receive buffers.
     *
     * @details Maximum number of receive buffers to be used per IPSP channel.
     *          Each receive buffer is of size @ref BLE_IPSP_RX_BUFFER_SIZE.
     *          This configuration has implications on the number of SDUs that can
     *          be received while an SDU is being consumed by the application
     *          (6LoWPAN/IP Stack).
     */
    #define BLE_IPSP_RX_BUFFER_COUNT                           4
    
    /**@brief Transmission MPS used by IPSP.
     *
     * @note The actual MPS used is minimum of this value and the one requested by
     *       the peer during the channel setup. Here, the value used is
     *       (23 + 27 * 7).
     */
    #define BLE_IPSP_TX_MPS                                    212
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf_rs[0] != 0) 
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf_rs, strlen((const char *)m_rx_buf_rs));
        }
       if (m_rx_buf_rd[0] != 0) 
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf_rd, strlen((const char *)m_rx_buf_rd));
        }
    
    }
    
    //****************************************************************************// 
    // BLE FUNCTIONS
    //****************************************************************************//
    /**@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. */
    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;
        //uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        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.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_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.interval        = CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        //m_adv_params.duration        = 10;       // Never time out.
        
    
        m_adv_params.scan_req_notification = 1;   //VLS
    
        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 application timers.
     * @param   None.
     * @retval  None.
     */
    static void application_timers_start(void)
    {
    	ret_code_t err_code;
    
    	// Start application timers.
    	err_code = app_timer_start(m_beacon_timer_id, BEACON_INTERVAL, NULL);
    	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);
        //err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_ADV_MODE_SLOW);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**
     * @brief   Function for stopping advertising.
     * @param   None.
     * @retval  None.
     */
    static void advertising_stop(void)
    {
    	ret_code_t err_code;
    
    	err_code = sd_ble_gap_adv_stop(m_adv_handle);
    	APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code;
    
        switch (p_ble_evt->header.evt_id)
        {
        case BLE_GAP_EVT_SCAN_REQ_REPORT: 
          NRF_LOG_INFO("RSSI %d",p_ble_evt->evt.gap_evt.params.scan_req_report.rssi);
          break;
    
        default:
          // No implementation needed.
          break;
        }
    }
    
    /**@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;
        //ble_conn_cfg_t* conn_cfg;
        //ble_gap_cfg_t* gap_cfg_t;
        ble_cfg_t    ble_cfg;
        uint32_t     ram_start = 0;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        //err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        //APP_ERROR_CHECK(err_code);
    
        memset(&ble_cfg, 0, sizeof(ble_cfg));
      
        // Configure total number of connections.
        ble_cfg.conn_cfg.conn_cfg_tag                     = APP_BLE_CONN_CFG_TAG;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = BLE_GAP_CONN_COUNT_DEFAULT * 2;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT * 10;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
        memset(&ble_cfg, 0, sizeof(ble_cfg));
    
        ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 256;
        err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@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();
        }
    }
    
    static void update_beacon_data(void)
    {
    
        //#define TEST_STRING_RS                 0x1E, 0x00, 0x00
        uint8_t       m_tx_buf_rs[3] = {0x1E, 0x00, 0x00};    /**< TX buffer. */
        m_rx_buf_rs[sizeof(m_tx_buf_rs) + 1];    /**< RX buffer. */
        const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */
    
        //#define TEST_STRING_RD                 0xA6, 0x00, 0x00
        uint8_t       m_tx_buf_rd[3] = {0xA6, 0x00, 0x00};           /**< TX buffer. */
        m_rx_buf_rd[sizeof(m_tx_buf_rd) + 1];    /**< RX buffer. */
        const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
        
        // beacon update
        advertising_stop();
        
        nrf_gpio_cfg_output(APP_SPIS_CS_PIN);
        nrf_gpio_pin_set(APP_SPIS_CS_PIN);
            
        memset(m_rx_buf_rs, 0, m_length_rs);
        memset(m_rx_buf_rd, 0, m_length_rd);
        spi_xfer_done = false;
            
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rs, m_length_rs, m_rx_buf_rs, m_length_rs));
        nrf_delay_ms(5);
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rd, m_length_rd, m_rx_buf_rd, m_length_rd));
        
        //nrf_delay_ms(10);
        nrf_delay_ms(5);
        
        m_beacon_info[18] = m_rx_buf_rd[2];
        m_beacon_info[19] = m_rx_buf_rd[3];
    
        //ble_stack_init();
        advertising_init();
        advertising_start();
    }  
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Initialize.
        ret_code_t err_code;
        ble_advdata_t advdata;
        ble_advdata_manuf_data_t manuf_specific_data;
    
        //NRF_POWER->TASKS_CONSTLAT = 1;
        log_init();
        timers_init();
        leds_init();
        //power_management_init();
        ble_stack_init();
        advertising_init();
     
        NRF_LOG_INIT(NULL);
    
        // Start execution.
        NRF_LOG_INFO("Beacon started.");
        //application_timers_start();
        advertising_start();
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = APP_SPIS_CS_PIN;
        spi_config.miso_pin = APP_SPIS_MISO_PIN;
        spi_config.mosi_pin = APP_SPIS_MOSI_PIN;
        spi_config.sck_pin  = APP_SPIS_SCK_PIN;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        //memset(m_rx_buf, 0, m_length);
        //spi_xfer_done = false;
    
        //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)); 
        /*while (!spis_xfer_done)
        {
            __WFE();
        }*/
    
        //APP_ERROR_CHECK(nrf_drv_spis_init(&spis_2, &spis_config, spis_event_handler2));
        // Enter main loop.
        for (;; )
        {
            idle_state_handle();
            update_beacon_data();
        }
    }

    Kindly Regards,

    Shigeto 

  • sgret612 said:
    Mmmm... it is my wonder why 'nRF Connect for iPhone' can not scan my beacon even though  an application called 'Beacon scan' catch and display the iBeacon...

     Do you see the advertising if you use nRF Connect for mobile?

    https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-mobile

  • Hi,

    I finally got it!!

    I have just misunderstood about NULL...

    That was it!!!

    the Code Below works fine. And an iphone app called 'Beacon Scan' shows

    the major value changing!!!  

    #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_drv_spi.h"
    #include "ble_advertising.h"
    #include "ble_gap.h"
    //#include "nrf_ble_gatt.h"
    
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    
    #include "nrf_spi_mngr.h"
    
    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    
    #if defined (LEGACY_DEFINE)
    
    #undef NRFX_DEFINE
    #define NRFX_DEFINE LEGACY_DEFINE
    
    #endif 
    
    
    #define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
    #define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    //#define APP_BLE_OBSERVER_PRIO           1                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    
    //#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 CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(100, UNIT_1_25_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_COMPANY_IDENTIFIER          0x004C                             /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */
    #define APP_MAJOR_VALUE                 0x00, 0x00                         /**< Major value used to identify Beacons. */
    #define APP_MINOR_VALUE                 0x00, 0x00                         /**< 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 APP_SIGNAL_OUT                  0xc3                              /**< Proprietary SIGNAL OUT 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. */
    
    //NRF_BLE_GATT_DEF(m_gatt);                                                       /**< GATT module instance. */
    
    #define UPDATE_MS                       5000
    #define BEACON_INTERVAL                 APP_TIMER_TICKS(UPDATE_MS)
    APP_TIMER_DEF(m_beacon_timer_id);                                               // Timer ID
    static volatile bool m_beacon_timer_flag = false;                               // Timer Flag
    
    #define APP_SPIS_SCK_PIN 26
    #define APP_SPIS_MOSI_PIN 29
    #define APP_SPIS_MISO_PIN 30
    
    #define APP_SPIS_CS_PIN 31
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    //#define TEST_STRING_RS                 0x1E, 0x00, 0x00
    //static uint8_t       m_tx_buf_rs[] = TEST_STRING_RS;    /**< TX buffer. */
    //static uint8_t       m_rx_buf_rs[sizeof(TEST_STRING_RS) + 1];    /**< RX buffer. */
    //static const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */
    uint8_t       m_rx_buf_rs[];
    
    //#define TEST_STRING_RD                 0xA6, 0x00, 0x00
    //static uint8_t       m_tx_buf_rd[] = TEST_STRING_RD;           /**< TX buffer. */
    //static uint8_t       m_rx_buf_rd[sizeof(TEST_STRING_RD) + 1];    /**< RX buffer. */
    //static const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
    uint8_t       m_rx_buf_rd[];
    
    #define BLE_GAP_EVENT_LENGTH_DEFAULT        (3)  /**< Default event length, in 1.25 ms units. */
    
    /**@brief Receive MPS used by IPSP. */
    #define BLE_IPSP_RX_MPS                                    50
    
    /**@brief Maximum number of receive buffers.
     *
     * @details Maximum number of receive buffers to be used per IPSP channel.
     *          Each receive buffer is of size @ref BLE_IPSP_RX_BUFFER_SIZE.
     *          This configuration has implications on the number of SDUs that can
     *          be received while an SDU is being consumed by the application
     *          (6LoWPAN/IP Stack).
     */
    #define BLE_IPSP_RX_BUFFER_COUNT                           4
    
    /**@brief Transmission MPS used by IPSP.
     *
     * @note The actual MPS used is minimum of this value and the one requested by
     *       the peer during the channel setup. Here, the value used is
     *       (23 + 27 * 7).
     */
    #define BLE_IPSP_TX_MPS                                    212
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf_rs[0] != 0) 
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf_rs, strlen((const char *)m_rx_buf_rs));
        }
       if (m_rx_buf_rd[0] != 0) 
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf_rd, strlen((const char *)m_rx_buf_rd));
        }
    
    }
    
    //****************************************************************************// 
    // BLE FUNCTIONS
    //****************************************************************************//
    /**@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. */
    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;
        //uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        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.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_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.interval        = CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        //m_adv_params.duration        = 10;       // Never time out.
        
    
        m_adv_params.scan_req_notification = 1;   //VLS
    
        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 application timers.
     * @param   None.
     * @retval  None.
     */
    static void application_timers_start(void)
    {
    	ret_code_t err_code;
    
    	// Start application timers.
    	err_code = app_timer_start(m_beacon_timer_id, BEACON_INTERVAL, NULL);
    	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);
        //err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_ADV_MODE_SLOW);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**
     * @brief   Function for stopping advertising.
     * @param   None.
     * @retval  None.
     */
    static void advertising_stop(void)
    {
    	ret_code_t err_code;
    
    	err_code = sd_ble_gap_adv_stop(m_adv_handle);
    	APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code;
    
        switch (p_ble_evt->header.evt_id)
        {
        case BLE_GAP_EVT_SCAN_REQ_REPORT: 
          NRF_LOG_INFO("RSSI %d",p_ble_evt->evt.gap_evt.params.scan_req_report.rssi);
          break;
    
        default:
          // No implementation needed.
          break;
        }
    }
    
    /**@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;
        //ble_conn_cfg_t* conn_cfg;
        //ble_gap_cfg_t* gap_cfg_t;
        ble_cfg_t    ble_cfg;
        uint32_t     ram_start = 0;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        //err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        //APP_ERROR_CHECK(err_code);
    
        memset(&ble_cfg, 0, sizeof(ble_cfg));
      
        // Configure total number of connections.
        ble_cfg.conn_cfg.conn_cfg_tag                     = APP_BLE_CONN_CFG_TAG;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = BLE_GAP_CONN_COUNT_DEFAULT * 2;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT * 10;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
        /*memset(&ble_cfg, 0, sizeof(ble_cfg));
    
        ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 256;
        err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);*/
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@brief Function for initializing the GATT module.
     */
    /*static void gatt_init(void)
    {
        ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
        APP_ERROR_CHECK(err_code);
    }*/
    
    /**@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();
        }
    }
    
    static void update_beacon_data(void)
    {
        ret_code_t err_code;
    
        //#define TEST_STRING_RS                 0x1E, 0x00, 0x00
        uint8_t       m_tx_buf_rs[3] = {0x1E, 0x00, 0x00};    /**< TX buffer. */
        m_rx_buf_rs[sizeof(m_tx_buf_rs) + 1];    /**< RX buffer. */
        const uint8_t m_length_rs = sizeof(m_tx_buf_rs);        /**< Transfer length. */
    
        //#define TEST_STRING_RD                 0xA6, 0x00, 0x00
        uint8_t       m_tx_buf_rd[3] = {0xA6, 0x00, 0x00};           /**< TX buffer. */
        m_rx_buf_rd[sizeof(m_tx_buf_rd) + 1];    /**< RX buffer. */
        const uint8_t m_length_rd = sizeof(m_tx_buf_rd);        /**< Transfer length. */
        
        // beacon update
        advertising_stop();
        
        nrf_gpio_cfg_output(APP_SPIS_CS_PIN);
        nrf_gpio_pin_set(APP_SPIS_CS_PIN);
            
        memset(m_rx_buf_rs, 0, m_length_rs);
        memset(m_rx_buf_rd, 0, m_length_rd);
        spi_xfer_done = false;
            
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rs, m_length_rs, m_rx_buf_rs, m_length_rs));
        nrf_delay_ms(5);
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf_rd, m_length_rd, m_rx_buf_rd, m_length_rd));
        
        //nrf_delay_ms(10);
        nrf_delay_ms(5);
        
        
        //m_beacon_info[18] = m_rx_buf_rd[2];
        //m_beacon_info[19] = m_rx_buf_rd[3];
        
        m_beacon_info[18] = m_beacon_info[18] + 1;
        m_beacon_info[19] = m_beacon_info[19] + 1;
    
        //ble_stack_init();
        advertising_init();
        advertising_start();
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Initialize.
        ret_code_t err_code;
        ble_advdata_t advdata;
        ble_advdata_manuf_data_t manuf_specific_data;
    
        //NRF_POWER->TASKS_CONSTLAT = 1;
        log_init();
        timers_init();
        leds_init();
        //power_management_init();
        ble_stack_init();
        //gatt_init();
        advertising_init();
        
        NRF_LOG_INIT(NULL);
    
        // Start execution.
        NRF_LOG_INFO("Beacon started.");
        //application_timers_start();
        advertising_start();
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = APP_SPIS_CS_PIN;
        spi_config.miso_pin = APP_SPIS_MISO_PIN;
        spi_config.mosi_pin = APP_SPIS_MOSI_PIN;
        spi_config.sck_pin  = APP_SPIS_SCK_PIN;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        //memset(m_rx_buf, 0, m_length);
        //spi_xfer_done = false;
    
        //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)); 
        /*while (!spis_xfer_done)
        {
            __WFE();
        }*/
    
        //APP_ERROR_CHECK(nrf_drv_spis_init(&spis_2, &spis_config, spis_event_handler2));
        // Enter main loop.
        for (;; )
        {
            idle_state_handle();
            update_beacon_data();
        }
    }
      

    To Sigurd,

    Thanks a lot!!! Thanks for your patience, advices and so on so on...

    I really appreciate all the supports that you gave me.

    Kindly Regards,

    Shigeto  

Related