From 6d7141db0c73af34fd887fda9723c77aaaf1e349 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 29 May 2015 00:00:05 +0200 Subject: o Initial import of Phone Remote firmware, forked from the old soil moisture project. --- main.c | 429 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c new file mode 100644 index 0000000..34b8ae4 --- /dev/null +++ b/main.c @@ -0,0 +1,429 @@ +/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ +/** @example examples/ble_peripheral/ble_app_hrs/main.c + * + * @brief Heart Rate Service Sample Application main file. + * + * This file contains the source code for a sample application using the Heart Rate service + * (and also Battery and Device Information services). This application uses the + * @ref srvlib_conn_params module. + */ + +#include +#include +#include "nordic_common.h" +#include "nrf.h" +#include "app_error.h" +#include "nrf51_bitfields.h" +#include "ble.h" +#include "ble_hci.h" +#include "ble_srv_common.h" +#include "ble_advdata.h" +#include "ble_gatt.h" +#include "ble_bas.h" +#include "ble_hrs.h" +#include "ble_dis.h" +#ifdef BLE_DFU_APP_SUPPORT +#include "ble_dfu.h" +#include "dfu_app_handler.h" +#endif // BLE_DFU_APP_SUPPORT +#include "ble_conn_params.h" +#include "boards.h" +#include "ble_sensorsim.h" +#include "softdevice_handler.h" +#include "app_timer.h" +#include "device_manager.h" +#include "pstorage.h" +#include "app_trace.h" +#include "app_timer.h" +#include "app_gpiote.h" +#include "app_timer.h" +#include "bsp.h" + +#include "phone_remote.h" +#include "LiquidCrystal.h" + +#include + +#define dbg printf + +#define IS_SRVC_CHANGED_CHARACT_PRESENT 0 /**< Include or not the service_changed characteristic. if not enabled, the server's database cannot be changed for the lifetime of the device*/ + +// BOARD_PCA10031 doesn't have any buttons according to the BSP +#ifndef BOARD_PCA10031 +#define WAKEUP_BUTTON_ID 0 /**< Button used to wake up the application. */ +#define BOND_DELETE_ALL_BUTTON_ID 1 /**< Button used for deleting all bonded centrals during startup. */ +#endif + +#define DEVICE_NAME "Woot-51" +#define MANUFACTURER_NAME "NordicSemiconductor" +#define APP_ADV_INTERVAL 40 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 25 ms). */ +#define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout in units of seconds. */ + +#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ +#define APP_TIMER_MAX_TIMERS (6+BSP_APP_TIMERS_NUMBER) /**< Maximum number of simultaneously created timers. */ +#define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */ + +#define SENSOR_CONTACT_DETECTED_INTERVAL APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER) /**< Sensor Contact Detected toggle interval (ticks). */ + +#define MIN_CONN_INTERVAL MSEC_TO_UNITS(500, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */ +#define MAX_CONN_INTERVAL MSEC_TO_UNITS(1000, UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */ + +#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(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 SEC_PARAM_TIMEOUT 30 /**< Timeout for Pairing Request or Security Request (in seconds). */ +#define SEC_PARAM_BOND 1 /**< Perform bonding. */ +#define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */ +#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ +#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ +#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ +#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ + +#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ + +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ +static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ + +static dm_application_instance_t m_app_handle; /**< Application identifier allocated by device manager */ + +static bool m_memory_access_in_progress = false; /**< Flag to keep track of ongoing operations on persistent memory. */ + + +static app_timer_id_t hello_timer; + +void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) +{ + app_error_handler(DEAD_BEEF, line_num, p_file_name); +} + +static uint32_t seconds = 0; + +static void hello_timer_handler(void* data) +{ + uint32_t ticks; + app_timer_cnt_get(&ticks); + + uint32_t ms = (1000 * (1 + APP_TIMER_PRESCALER) * ticks) / APP_TIMER_CLOCK_FREQ; + + seconds++; + printf("hello world, seconds=%" PRIu32 ", ticks=%" PRIu32 ", ms=%" PRIu32 "\r\n", seconds, ticks, ms); +} + +static void timers_init(void) +{ + uint32_t err_code; + + // Initialize timer module. + APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false); + + err_code = app_timer_create(&hello_timer, APP_TIMER_MODE_REPEATED, hello_timer_handler); + APP_ERROR_CHECK(err_code); +} + +static void timers_start() { + uint32_t err_code; + + uint32_t ticks = APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER); + err_code = app_timer_start(hello_timer, ticks, NULL); + APP_ERROR_CHECK(err_code); +} + +static void gap_params_init(void) +{ + uint32_t err_code; + ble_gap_conn_params_t gap_conn_params; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, + (const uint8_t *)DEVICE_NAME, + strlen(DEVICE_NAME)); + APP_ERROR_CHECK(err_code); + + err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT); + 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 void advertising_init(void) +{ + uint32_t err_code; + ble_advdata_t advdata; + uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + + ble_uuid_t adv_uuids[] = {}; + + // Build and set advertising data. + memset(&advdata, 0, sizeof(advdata)); + + advdata.name_type = BLE_ADVDATA_FULL_NAME; + advdata.include_appearance = true; + advdata.flags.size = sizeof(flags); + advdata.flags.p_data = &flags; + advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); + advdata.uuids_complete.p_uuids = adv_uuids; + + err_code = ble_advdata_set(&advdata, NULL); + APP_ERROR_CHECK(err_code); + + // Initialize advertising parameters (used when starting advertising). + memset(&m_adv_params, 0, sizeof(m_adv_params)); + + m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + m_adv_params.p_peer_addr = NULL; // Undirected advertisement. + m_adv_params.fp = BLE_GAP_ADV_FP_ANY; + m_adv_params.interval = APP_ADV_INTERVAL; + m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; +} + +/**@brief Function for initializing services that will be used by the application. + * + * @details Initialize the Heart Rate, Battery and Device Information services. + */ +static void services_init(void) +{ + uint32_t err_code = NRF_SUCCESS; + +// err_code = sm_add_services(); + APP_ERROR_CHECK(err_code); +} + +static void advertising_start(void) +{ + uint32_t err_code; + uint32_t count; + + // Verify if there is any flash access pending, if yes delay starting advertising until + // it's complete. + err_code = pstorage_access_status_get(&count); + APP_ERROR_CHECK(err_code); + + if (count != 0) + { + m_memory_access_in_progress = true; + return; + } + + err_code = sd_ble_gap_adv_start(&m_adv_params); + APP_ERROR_CHECK(err_code); + + err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); + APP_ERROR_CHECK(err_code); +} + +static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) +{ + uint32_t err_code; + + if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) + { + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); + APP_ERROR_CHECK(err_code); + } +} + +static void conn_params_error_handler(uint32_t nrf_error) +{ + APP_ERROR_HANDLER(nrf_error); +} + +static void conn_params_init(void) +{ + uint32_t err_code; + ble_conn_params_init_t cp_init; + + memset(&cp_init, 0, sizeof(cp_init)); + + cp_init.p_conn_params = NULL; + cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; + cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; + cp_init.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); +} + +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + + err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); + APP_ERROR_CHECK(err_code); + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + break; + + case BLE_GAP_EVT_DISCONNECTED: + err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); + advertising_start(); + break; + + case BLE_GAP_EVT_TIMEOUT: + + if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) + { + printf("re-starting advertisement"); + advertising_start(); + /* + err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); + + // Go to system-off mode (this function will not return; wakeup will cause a reset). + err_code = sd_power_system_off(); + APP_ERROR_CHECK(err_code); + */ + } + break; + + default: + // No implementation needed. + break; + } +} + +static void ble_evt_dispatch(ble_evt_t * p_ble_evt) +{ +// sm_on_ble_evt(p_ble_evt); + + dm_ble_evt_handler(p_ble_evt); + on_ble_evt(p_ble_evt); +} + +static void sys_evt_dispatch(uint32_t sys_evt) +{ + pstorage_sys_event_handler(sys_evt); +} + +static void ble_stack_init(void) +{ + uint32_t err_code; + + // Initialize the SoftDevice handler module. + SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false); + + ble_enable_params_t ble_enable_params; + memset(&ble_enable_params, 0, sizeof(ble_enable_params)); + ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT; + err_code = sd_ble_enable(&ble_enable_params); + APP_ERROR_CHECK(err_code); + + err_code = 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); +} + +static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle, + dm_event_t const * p_event, + api_result_t event_result) +{ + APP_ERROR_CHECK(event_result); + + switch(p_event->event_id) + { + } + + return NRF_SUCCESS; +} + +static void device_manager_init(void) +{ + uint32_t err_code; + dm_init_param_t init_data; + dm_application_param_t register_param; + + // Initialize persistent storage module. + err_code = pstorage_init(); + APP_ERROR_CHECK(err_code); + + init_data.clear_persistent_data = false; // was true + + err_code = dm_init(&init_data); + APP_ERROR_CHECK(err_code); + + memset(®ister_param.sec_param, 0, sizeof(ble_gap_sec_params_t)); + + register_param.sec_param.timeout = SEC_PARAM_TIMEOUT; + register_param.sec_param.bond = SEC_PARAM_BOND; + register_param.sec_param.mitm = SEC_PARAM_MITM; + register_param.sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; + register_param.sec_param.oob = SEC_PARAM_OOB; + register_param.sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; + register_param.sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; + register_param.evt_handler = device_manager_evt_handler; + register_param.service_type = DM_PROTOCOL_CNTXT_GATT_SRVR_ID; + + err_code = dm_register(&m_app_handle, ®ister_param); + APP_ERROR_CHECK(err_code); +} + +static void power_manage(void) +{ + uint32_t err_code = sd_app_evt_wait(); + APP_ERROR_CHECK(err_code); +} + +int main(void) +{ + app_trace_init(); + + dbg("Soil Moisture device starting...\r\n"); + + ble_stack_init(); + timers_init(); + + APP_GPIOTE_INIT(2); + + uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL); + APP_ERROR_CHECK(err_code); + +// device_manager_init(); +// gap_params_init(); +// advertising_init(); +// services_init(); +// conn_params_init(); + + timers_start(); + + liquid_crystal_init(APP_TIMER_TICKS(1, APP_TIMER_PRESCALER)); + liquid_crystal_write_string("hello world!"); + + advertising_start(); + + for (;; ) + { + power_manage(); + } +} -- cgit v1.2.3