Hi,
I'm currently trying to make a flash logger using the nRF51822_XXAB. My logger is also advertising temperature, battery and other informations in beacon form. I also want to make it connectable so that I can push a 32bit word of epoch type that will then be written in flash between what I want to log to keep track of real time. All worked pretty well until I tried to turn my beacon to be connectable. I succesfully added everything I needed I thought, and I can now connect to it, write my characteristic and it is then written in flash as intended.
My problem is that I call advertising_init in my main loop after making various readings so that my data is updated. I also have a flag that looks if a connection has been made which is set to 1 in case BLE_GAP_EVT_CONNECTED in on_ble_evt function. It is then set to 0 in case BLE_GAP_EVT_DISCONNECTED. My adfvertising_init in my main loop is called only if(!connection_has_been_made). The thing is, sometimes when I connect and then disconnect I go in hard fault. I tried to look for where this is happenning and I don't see anywhere where my error_status is not 0. This error happens way less if I delay my main loop by doing something like : for (;;) { thicking++; if(thicking>1000000) { thicking=0; ..whole main loop.. }}. It must have something to do with where I am in my loop when I connect but I can't find it.
I have also a second problem, I write in flash once every 10 seconds and the process takes about 200 ms for various reasons, if I connect during this time I go in hard fault once I disconnect. For this error, I found that it happens when I call err_code = ble_advertising_start(BLE_ADV_MODE_FAST) in case BLE_GAP_EVT_DISCONNECTED in on_ble_evt function. The error status is 7, which means NRF_ERROR_INVALID_PARAM.
These are my .h and .c for everythng related to BLE:#ifndef __ADVERTISEMENT_H
#define __ADVERTISEMENT_H
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advertising.h"
#include "ble_advdata.h"
#include "ble_conn_params.h"
#include "ble_conn_state.h"
#include "softdevice_handler.h"
#include "app_timer.h"
#include "bsp.h"
#include "bsp_btn_ble.h"
#include "updateflash.h"
#include "SEGGER_RTT.h"
#include "SEGGER_RTT_Conf.h"
#define IS_SRVC_CHANGED_CHARACT_PRESENT 0 /**< Include the service_changed characteristic. If not enabled, the server's database cannot be changed for the lifetime of the device. */
#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */
#define CENTRAL_LINK_COUNT 0 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
#define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
#define APP_ADV_INTERVAL 128 /**< 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_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY 0 /**< Slave latency. */
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(8000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
#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 0x0325 /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */
#define APP_MAJOR_VALUE 0x00, 0x0C /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE 0x03, 0x05 /**< 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 BLE_UUID_OUR_BASE_UUID {{0x00, 0x00, 0xE5, 0xA9, 0xBB, 0xCA, 0x5E, 0xBA, 0x7A, 0xDA, 0x0C, 0xE9, 0x00, 0x00, 0x7E, 0xDA}} // 128-bit base UUID
#define BLE_UUID_OUR_SERVICE_UUID 0xABCD // Just a random, but recognizable value
#define BLE_UUID_OUR_CHARACTERISTC_UUID 0xDA7E // Just a random, but recognizable value
typedef struct
{
uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection).*/
uint16_t service_handle; /**< Handle of Our Service (as provided by the BLE stack). */
ble_gatts_char_handles_t char_handles;
}ble_os_t;
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name);
void gap_params_init(void);
void services_init(void);
void on_conn_params_evt(ble_conn_params_evt_t * p_evt);
void conn_params_error_handler(uint32_t nrf_error);
void conn_params_init(void);
void on_adv_evt(ble_adv_evt_t ble_adv_evt);
void on_ble_evt(ble_evt_t * p_ble_evt);
void ble_evt_dispatch(ble_evt_t * p_ble_evt);
void ble_stack_init(void);
void advertising_init(uint8_t data[],uint8_t size_data);
void our_service_init(ble_os_t * p_our_service);
#endif
#include "advertisement.h"
ble_os_t m_our_service;
//ble_nus_t m_nus; /**< Structure to identify the Nordic UART Service. */
uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
uint8_t connection_has_been_made=0;
char result[10];
extern uint32_t new_time_sync;
//ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */
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 Function for assert macro callback.
*
* @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 analyse
* 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] p_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 GAP initialization.
*
* @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
* the device. It also sets the permissions and appearance.
*/
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);
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);
}
static uint32_t our_char_add(ble_os_t * p_our_service)
{
uint32_t err_code;
ble_uuid_t char_uuid;
ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
char_uuid.uuid = BLE_UUID_OUR_CHARACTERISTC_UUID;
err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
APP_ERROR_CHECK(err_code);
ble_gatts_char_md_t char_md;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.write = 1;
ble_gatts_attr_md_t cccd_md;
memset(&cccd_md, 0, sizeof(cccd_md));
ble_gatts_attr_md_t attr_md;
memset(&attr_md, 0, sizeof(attr_md));
attr_md.vloc = BLE_GATTS_VLOC_STACK;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
ble_gatts_attr_t attr_char_value;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &char_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.max_len = 4;
attr_char_value.init_len = 4;
uint8_t value[4] = {0};
attr_char_value.p_value = value;
err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_handles);
APP_ERROR_CHECK(err_code);
return NRF_SUCCESS;
}
void our_service_init(ble_os_t * p_our_service)
{
uint32_t err_code; // Variable to hold return codes from library and softdevice functions
ble_uuid_t service_uuid;
ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
service_uuid.uuid = BLE_UUID_OUR_SERVICE_UUID;
err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
APP_ERROR_CHECK(err_code);
p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&service_uuid,
&p_our_service->service_handle);
APP_ERROR_CHECK(err_code);
our_char_add(p_our_service);
}
/**@brief Function for initializing services that will be used by the application.
*/
void services_init(void)
{
our_service_init(&m_our_service);
}
/**@brief Function for handling an event from 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.
*/
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);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: on_conn: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
}
}
/**@brief Function for handling errors from the Connection Parameters module.
*
* @param[in] nrf_error Error code containing information about what went wrong.
*/
void conn_params_error_handler(uint32_t nrf_error)
{
APP_ERROR_HANDLER(nrf_error);
}
/**@brief Function for initializing the Connection Parameters module.
*/
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 handling advertising events.
*
* @details This function will be called for advertising events which are passed to the application.
*
* @param[in] ble_adv_evt Advertising event.
*/
void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
uint32_t err_code;
switch (ble_adv_evt)
{
case BLE_ADV_EVT_FAST:
err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: ble_adv_evt fast: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
SEGGER_RTT_WriteString(0, " Fast \r\n");
break;
case BLE_ADV_EVT_IDLE:
SEGGER_RTT_WriteString(0, " Idle \r\n");
break;
default:
break;
}
}
/**@brief Function for the application's SoftDevice event handler.
*
* @param[in] p_ble_evt SoftDevice event.
*/
void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;
switch (p_ble_evt->header.evt_id)
{
// ######################## getting values ############################################
case BLE_GATTS_EVT_WRITE:
switch(p_ble_evt->evt.gatts_evt.params.write.uuid.uuid)
{
case 0xDA7E:
new_time_sync = (p_ble_evt->evt.gatts_evt.params.write.data[0] << 24) + (p_ble_evt->evt.gatts_evt.params.write.data[1] << 16) + (p_ble_evt->evt.gatts_evt.params.write.data[2] << 8) + p_ble_evt->evt.gatts_evt.params.write.data[3];
//uint16_to_uint8(distance_temp, data_temp);
//p_data_characteristic_right_max = data_temp;
//data_char_len = p_ble_evt->evt.gatts_evt.params.write.len;
SEGGER_RTT_WriteString(0, " Ecriture \r\n");
break;
}
break;
// ####################################################################################
case BLE_GAP_EVT_DISCONNECTED:
connection_has_been_made = 0;
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: disconn: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
// LED indication will be changed when advertising starts.
SEGGER_RTT_WriteString(0, " Disonnected \r\n");
break;
case BLE_GAP_EVT_CONNECTED:
connection_has_been_made = 1;
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: conn: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
SEGGER_RTT_WriteString(0, " Connected \r\n");
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: param reque: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: attr missing: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
break; // BLE_GATTS_EVT_SYS_ATTR_MISSING
case BLE_GATTC_EVT_TIMEOUT:
// Disconnect on GATT Client timeout event.
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: gattc timeout: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_TIMEOUT:
// Disconnect on GATT Server timeout event.
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: gatts timeout: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
break;
case BLE_EVT_USER_MEM_REQUEST:
err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: mem request: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
{
ble_gatts_evt_rw_authorize_request_t req;
ble_gatts_rw_authorize_reply_params_t auth_reply;
req = p_ble_evt->evt.gatts_evt.params.authorize_request;
if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
{
if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
{
if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
}
else
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
}
auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
&auth_reply);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: author request: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
}
}
} break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
#if (NRF_SD_BLE_API_VERSION == 3)
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle,
NRF_BLE_MAX_MTU_SIZE);
APP_ERROR_CHECK(err_code);
break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST
#endif
default:
// No implementation needed.
break;
}
}
static void on_ble_write(ble_os_t * p_our_service, ble_evt_t * p_ble_evt)
{
// Declare buffer variable to hold received data. The data can only be 32 bit long.
uint32_t data_buffer;
// Populate ble_gatts_value_t structure to hold received data and metadata.
ble_gatts_value_t rx_data;
rx_data.len = sizeof(uint32_t);
rx_data.offset = 0;
rx_data.p_value = (uint8_t*)&data_buffer;
// Check if write event is performed on our characteristic or the CCCD
if(p_ble_evt->evt.gatts_evt.params.write.handle == p_our_service->char_handles.value_handle)
{
// Get data
sd_ble_gatts_value_get(p_our_service->conn_handle, p_our_service->char_handles.value_handle, &rx_data);
}
else if(p_ble_evt->evt.gatts_evt.params.write.handle == p_our_service->char_handles.cccd_handle)
{
// Get data
sd_ble_gatts_value_get(p_our_service->conn_handle, p_our_service->char_handles.cccd_handle, &rx_data);
}
}
void ble_our_service_on_ble_evt(ble_os_t * p_our_service, ble_evt_t * p_ble_evt)
{
// OUR_JOB: Step 3.D Implement switch case handling BLE events related to our service.
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTS_EVT_WRITE:
on_ble_write(p_our_service, p_ble_evt);
SEGGER_RTT_WriteString(0, " Write4Real \r\n");
break;
case BLE_GAP_EVT_CONNECTED:
p_our_service->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
SEGGER_RTT_WriteString(0, " Connected4Real \r\n");
break;
case BLE_GAP_EVT_DISCONNECTED:
p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
SEGGER_RTT_WriteString(0, " Disonnected4Real \r\n");
break;
default:
// No implementation needed.
break;
}
}
/**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice
* event handler.
*
* @details This function is called from the SoftDevice event interrupt handler after a
* SoftDevice event has been received.
*
* @param[in] p_ble_evt SoftDevice event.
*/
void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
ble_conn_state_on_ble_evt(p_ble_evt);
ble_conn_params_on_ble_evt(p_ble_evt);
bsp_btn_ble_on_ble_evt(p_ble_evt);
ble_our_service_on_ble_evt(&m_our_service, p_ble_evt);
on_ble_evt(p_ble_evt);
ble_advertising_on_ble_evt(p_ble_evt);
}
void sys_evt_dispatch(uint32_t sys_evt)
{
fs_sys_event_handler(sys_evt);
ble_advertising_on_sys_evt(sys_evt);
}
/**@brief Function for the SoftDevice initialization.
*
* @details This function initializes the SoftDevice and the BLE event interrupt.
*/
void ble_stack_init(void)
{
uint32_t err_code;
nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
// Initialize SoftDevice.
SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
ble_enable_params_t ble_enable_params;
err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
PERIPHERAL_LINK_COUNT,
&ble_enable_params);
APP_ERROR_CHECK(err_code);
//Check the ram settings against the used number of links
CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
// Enable BLE stack.
#if (NRF_SD_BLE_API_VERSION == 3)
ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;
#endif
err_code = softdevice_enable(&ble_enable_params);
APP_ERROR_CHECK(err_code);
// Subscribe for BLE events.
err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
APP_ERROR_CHECK(err_code);
err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for initializing the Advertising functionality.
*/
//void advertising_init(void)
/*{
uint32_t err_code;
ble_advdata_t advdata;
ble_advdata_t srdata;
ble_adv_modes_config_t options;
uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
ble_advdata_manuf_data_t manuf_specific_data;
ble_advdata_manuf_data_t beacon_specific_data;
manuf_specific_data.company_identifier = 0x0325;
beacon_specific_data.company_identifier = 0x0325;
// Build and set
manuf_specific_data.data.p_data = (uint8_t *) 123;
manuf_specific_data.data.size = 12;
beacon_specific_data.data.p_data = (uint8_t *) m_beacon_info;
beacon_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;
// Build and set advertising data.
memset(&advdata, 0, sizeof(advdata));
advdata.flags = flags;
advdata.p_manuf_specific_data = &beacon_specific_data;
// Build and set scan response data.
memset(&srdata, 0, sizeof(srdata));
srdata.p_manuf_specific_data = &manuf_specific_data;
memset(&options, 0, sizeof(options));
options.ble_adv_fast_enabled = true;
options.ble_adv_fast_interval = APP_ADV_INTERVAL;
options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
err_code = ble_advertising_init(&advdata, &srdata, &options, on_adv_evt, NULL);
APP_ERROR_CHECK(err_code);
}*/
void advertising_init(uint8_t data[],uint8_t size_data)
{
if(!connection_has_been_made)
{
uint32_t err_code;
ble_advdata_t advdata;
ble_advdata_t srdata;
ble_adv_modes_config_t options;
uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
ble_advdata_manuf_data_t manuf_specific_data;
ble_advdata_manuf_data_t beacon_specific_data;
manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
beacon_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
// Build and set
manuf_specific_data.data.p_data = (uint8_t *) data;
manuf_specific_data.data.size = size_data;
beacon_specific_data.data.p_data = (uint8_t *) m_beacon_info;
beacon_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;
// Build and set advertising data.
memset(&advdata, 0, sizeof(advdata));
advdata.include_appearance = false;
advdata.flags = flags;
advdata.p_manuf_specific_data = &beacon_specific_data;
//advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
//advdata.uuids_complete.p_uuids = m_adv_uuids;
// Build and set scan response data.
memset(&srdata, 0, sizeof(srdata));
srdata.p_manuf_specific_data = &manuf_specific_data;
memset(&options, 0, sizeof(options));
options.ble_adv_fast_enabled = true;
options.ble_adv_fast_interval = APP_ADV_INTERVAL;
options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
err_code = ble_advertising_init(&advdata, &srdata, &options, on_adv_evt, NULL);
sprintf(result, "%d \n", err_code);
SEGGER_RTT_WriteString(0, "err_code: advertising_init: ");
SEGGER_RTT_WriteString(0, result);
APP_ERROR_CHECK(err_code);
}
}
This is my main:int main(void)
{
uint32_t thicking=0;
uint32_t err_code;
nrf_temp_init();
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL);
APP_ERROR_CHECK(err_code) ;
ble_stack_init() ;
gap_params_init() ;
services_init() ;
uint8_t data_ble[size_ble_data] = {type_beacon,0,battery_level,temperature[0],temperature[1],humidity,acceleration_x,0,acceleration_y,0,acceleration_z,0};
advertising_init(data_ble,size_ble_data) ;
conn_params_init() ;
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code) ;
SEGGER_RTT_WriteString(0, " RESET RESET RESET RESET RESET RESET \r\n");
// Enter main loop.
for (;;)
{
thicking++;
if(thicking>1000000)
{
thicking=0;
humidity = update_humidity(adc_treshold);
int_temperature = update_temperature();
nrf_delay_ms(5) ;
battery_level = update_battery();
nrf_delay_ms(10) ;
temperature[0] = int_temperature;
temperature[1] = int_temperature >> 8;
uint8_t data_ble[size_ble_data] = {type_beacon,0,battery_level,temperature[0],temperature[1],humidity,acceleration_x,0,acceleration_y,0,acceleration_z,0};
if(!connection_has_been_made)
{
advertising_init(data_ble,size_ble_data);
update_flash(int_temperature, new_time_sync, time_of_execution, speed_flash_update_temperature);
new_time_sync = 0;
SEGGER_RTT_WriteString(0, " Allo \r\n");
}
}
}
}
This is my fstorsge event handler:void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result)
{
if (result != FS_SUCCESS)
{
bsp_indication_set(BSP_INDICATE_FATAL_ERROR);
}
else
{
fs_callback_flag = 0;
}
}
EDIT: Forgot to mention I'm using SDK 12.3.0 with S130