/**@brief Processes an ANT messages while in the address available state. * * @param[in] Pointer to the raw ant message received. */ static void process_message_address_available(uint8_t * p_ant_message) { uint32_t err_code; switch (p_ant_message[ANT_MESSAGE_ID_OFFSET]) { case MESG_RESPONSE_EVENT_ID: { if(p_ant_message[ANT_MESSAGE_DATA0_OFFSET] == MESG_EVENT_ID) //Channel event { switch(p_ant_message[ANT_MESSAGE_DATA1_OFFSET]) { case EVENT_TX: { if(m_is_command_pending == true) { ascm_set_state(SENDING_COMMAND); } else if(m_device_registry.count > 0 && ++m_msg_counter_address_available > MAX_TX_MESSAGES_ADDRESS_AVAILABLE) { m_msg_counter_address_available = 0; ascm_set_state(POLLING); } break; } } } break; } case MESG_BROADCAST_DATA_ID: //fall-through case MESG_ACKNOWLEDGED_DATA_ID: { //Process by page switch (p_ant_message[DECODE_PAGE_ID_BYTE]) { case REQUEST_ADDRESS_PID: { if(m_is_address_available) { uint32_t* p_serial_number = &(m_handshaking_device.serial_number); err_code = asc_decode_request_address_page(p_serial_number, p_ant_message); APP_ERROR_CHECK(err_code); ascm_set_state(HANDSHAKING); } break; } case UPDATE_DATA_PID: { process_device_update(p_ant_message); break; } default: { break; } } break; } default: break; } }
/** @brief Function for the Power manager. */ static void power_manage(void) { uint32_t err_code = sd_app_evt_wait(); APP_ERROR_CHECK(err_code); }
static void handle_data_packet(dfu_packet_t* p_packet, uint16_t length) { mesh_packet_t* p_cache_packet = packet_cache_entry_get(p_packet); if (p_cache_packet) { transport_tx_skip(p_cache_packet); } bool do_relay = false; if (p_packet->payload.data.transaction_id == m_transaction.transaction_id) { /* check and add to cache */ if (data_packet_in_cache(p_packet)) { return; } m_data_cache[(m_data_index++) & (DATA_CACHE_SIZE - 1)] = p_packet->payload.data.segment; if (m_state == BL_STATE_DFU_READY) { if (p_packet->payload.start.segment == 0) { bl_info_segment_t* p_segment = NULL; switch (m_transaction.type) { case DFU_TYPE_APP: p_segment = m_bl_info_pointers.p_segment_app; break; case DFU_TYPE_SD: p_segment = m_bl_info_pointers.p_segment_sd; break; case DFU_TYPE_BOOTLOADER: p_segment = m_bl_info_pointers.p_segment_bl; break; default: APP_ERROR_CHECK(NRF_ERROR_NOT_SUPPORTED); } m_transaction.p_indicated_start_addr = (uint32_t*) p_packet->payload.start.start_address; uint32_t start_address = p_packet->payload.start.start_address; /* if the host doesn't know the start address, we use start of segment: */ if (start_address == START_ADDRESS_UNKNOWN) { start_address = p_segment->start; } uint32_t segment_count = ((p_packet->payload.start.length * 4) + (start_address & 0x0F) - 1) / 16 + 1; if (p_packet->payload.start.signature_length != 0) { segment_count += p_packet->payload.start.signature_length / SEGMENT_LENGTH; } if (segment_count > 0xFFFF) { /* can't have more than 65536 segments in a transmission */ segment_count = 0xFFFF; } m_transaction.segments_remaining = segment_count; m_transaction.segment_count = segment_count; m_transaction.p_start_addr = (uint32_t*) start_address; m_transaction.length = p_packet->payload.start.length * 4; m_transaction.signature_length = p_packet->payload.start.signature_length; m_transaction.segment_is_valid_after_transfer = p_packet->payload.start.last; m_transaction.p_last_requested_entry = NULL; m_transaction.signature_bitmap = 0; if (m_transaction.type == DFU_TYPE_BOOTLOADER) { m_transaction.p_bank_addr = (uint32_t*) ( (m_bl_info_pointers.p_segment_app->start) + (m_bl_info_pointers.p_segment_app->length) - (m_transaction.length & ((uint32_t) ~(PAGE_SIZE - 1))) - (PAGE_SIZE) ); } else { m_transaction.p_bank_addr = m_transaction.p_start_addr; } if ((uint32_t) m_transaction.p_start_addr >= p_segment->start && (uint32_t) m_transaction.p_start_addr + m_transaction.length <= p_segment->start + p_segment->length) { start_target(); do_relay = true; } } else { m_tid_cache[(m_tid_index++) & (TRANSACTION_ID_CACHE_SIZE - 1)] = m_transaction.transaction_id; start_req(m_transaction.type, true); /* go back to req, we've missed packet 0 */ } } else if (m_state == BL_STATE_DFU_TARGET) { if (p_packet->payload.data.segment > 0 && p_packet->payload.data.segment <= m_transaction.segment_count) { uint32_t* p_addr = NULL; uint32_t error_code = NRF_ERROR_NULL; if (p_packet->payload.data.segment <= m_transaction.segment_count - m_transaction.signature_length / SEGMENT_LENGTH) { p_addr = addr_from_seg(p_packet->payload.data.segment); error_code = dfu_data((uint32_t) p_addr, p_packet->payload.data.data, length - (DFU_PACKET_LEN_DATA - SEGMENT_LENGTH)); } else /* treat signature packets at the end */ { uint32_t index = p_packet->payload.data.segment - (m_transaction.segment_count - m_transaction.signature_length / SEGMENT_LENGTH) - 1; if (index >= m_transaction.signature_length / SEGMENT_LENGTH || m_transaction.signature_bitmap & (1 << index)) { error_code = NRF_ERROR_INVALID_STATE; } else { memcpy(&m_transaction.signature[index * SEGMENT_LENGTH], p_packet->payload.data.data, length - (DFU_PACKET_LEN_DATA - SEGMENT_LENGTH)); m_transaction.signature_bitmap |= (1 << index); error_code = NRF_SUCCESS; } } if (error_code == NRF_SUCCESS) { set_timeout(STATE_TIMEOUT_TARGET); m_transaction.segments_remaining--; do_relay = true; /* check whether we've lost any entries, and request them */ uint32_t* p_req_entry = NULL; uint32_t req_entry_len = 0; mesh_packet_t* p_req_packet; if (dfu_get_oldest_missing_entry( m_transaction.p_last_requested_entry, &p_req_entry, &req_entry_len) && ( /* don't request the previous packet yet */ ADDR_SEGMENT(p_req_entry, m_transaction.p_start_addr) < p_packet->payload.data.segment - 1 || m_transaction.segment_count == p_packet->payload.data.segment ) ) { if(!mesh_packet_acquire(&p_req_packet)) { return; } if (mesh_packet_build(p_req_packet, DFU_PACKET_TYPE_DATA_REQ, ADDR_SEGMENT(p_req_entry, m_transaction.p_start_addr), (uint8_t*) &m_transaction.transaction_id, 4) == NRF_SUCCESS && transport_tx(p_req_packet, TX_REPEATS_REQ, TX_INTERVAL_TYPE_REQ, NULL)) { m_transaction.p_last_requested_entry = (uint32_t*) p_req_entry; } mesh_packet_ref_count_dec(p_req_packet); } } } /* ending the DFU */ if (m_transaction.segments_remaining == 0) { dfu_end(); start_rampdown(); } } else if (m_state == BL_STATE_RELAY_CANDIDATE || m_state == BL_STATE_RELAY) { m_state = BL_STATE_RELAY; transport_tx_abort(mp_beacon); set_timeout(STATE_TIMEOUT_RELAY); do_relay = true; } } if (do_relay) { relay_packet(p_packet, length); } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static uint16_t s_conn_handle = BLE_CONN_HANDLE_INVALID; static ble_gap_sec_keyset_t s_sec_keyset; ble_gap_enc_info_t * p_enc_info; 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); s_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_SEC_PARAMS_REQUEST: s_sec_keyset.keys_central.p_enc_key = NULL; s_sec_keyset.keys_central.p_id_key = NULL; s_sec_keyset.keys_central.p_enc_key = NULL; err_code = sd_ble_gap_sec_params_reply(s_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &s_sec_keyset); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(s_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_SEC_INFO_REQUEST: if (s_sec_keyset.keys_periph.p_enc_key != NULL) { p_enc_info = &s_sec_keyset.keys_periph.p_enc_key->enc_info; err_code = sd_ble_gap_sec_info_reply(s_conn_handle, p_enc_info, NULL, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(s_conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); err_code = app_button_disable(); APP_ERROR_CHECK(err_code); if (err_code == NRF_SUCCESS) { // Configure buttons with sense level low as wakeup source. // err_code = bsp_buttons_enable((1 << BLE_BUTTON_ID) | (1 << GZLL_BUTTON_ID)); // nrf_gpio_cfg_sense_input(BLE_BUTTON_PIN_NO, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); // // nrf_gpio_cfg_sense_input(GZLL_BUTTON_PIN_NO, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); // Go to system-off mode. // (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { data_t adv_data; data_t type_data; // Initialize advertisement report for parsing. adv_data.p_data = (uint8_t *)p_gap_evt->params.adv_report.data; adv_data.data_len = p_gap_evt->params.adv_report.dlen; err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, &adv_data, &type_data); if (err_code != NRF_SUCCESS) { // Compare short local name in case complete name does not match. err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, &adv_data, &type_data); } // Verify if short or complete name matches target. if (err_code == NRF_SUCCESS) { uint16_t extracted_uuid; // UUIDs found, look for matching UUID for (uint32_t u_index = 0; u_index < (type_data.data_len / UUID16_SIZE); u_index++) { UUID16_EXTRACT(&extracted_uuid, &type_data.p_data[u_index * UUID16_SIZE]); APPL_LOG("\t[APPL]: %x\r\n", extracted_uuid); if (extracted_uuid == TARGET_UUID) { // Stop scanning. err_code = sd_ble_gap_scan_stop(); if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Scan stop failed, reason %d\r\n", err_code); } err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_scan_param.selective = 0; // Initiate connection. err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.peer_addr, &m_scan_param, &m_connection_param); m_whitelist_temporarily_disabled = false; if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Connection Request Failed, reason %d\r\n", err_code); } break; } } } break; } case BLE_GAP_EVT_TIMEOUT: if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) { APPL_LOG("[APPL]: Scan timed out.\r\n"); scan_start(); } else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) { APPL_LOG("[APPL]: Connection Request timed out.\r\n"); } break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Accepting parameters requested by peer. err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update_request.conn_params); APP_ERROR_CHECK(err_code); break; default: break; } }
static void sensor_timer_stop(void) { uint32_t err_code = app_timer_stop(iss_struct.meas_timer); APP_ERROR_CHECK(err_code); iss_struct.timer_running = false; }
/**@brief Function for initializing services that will be used by the application. */ static void services_init(void) { uint32_t err_code = bluetooth_init(); APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; ble_gatts_rw_authorize_reply_params_t auth_reply; 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_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // enable buttons to wake-up from power off err_code = bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) |(1 << BOND_DELETE_ALL_BUTTON_ID) ); 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; case BLE_GAP_EVT_PASSKEY_DISPLAY: { char passkey[PASSKEY_LENGTH+1]; memcpy(passkey,p_ble_evt->evt.gap_evt.params.passkey_display.passkey,PASSKEY_LENGTH); passkey[PASSKEY_LENGTH] = 0; // Don't send delayed Security Request if security procedure is already in progress. err_code = app_timer_stop(m_sec_req_timer_id); APP_ERROR_CHECK(err_code); printf("Passkey: %s\n",passkey); break; } case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: if(p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.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(m_conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } break; case BLE_GAP_EVT_AUTH_STATUS: case BLE_GAP_EVT_CONN_SEC_UPDATE: break; default: // No implementation needed. break; } }
/* * Function for bootloader main entry. */ int main(void) { uint32_t err_code; bool dfu_start = false; bool app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START); if (app_reset) { NRF_POWER->GPREGRET = 0; } leds_init(); #if defined(DBGLOG_SUPPORT) uart_init(); #endif PUTS("\nBootloader *** " __DATE__ " " __TIME__ " ***"); // This check ensures that the defined fields in the bootloader // corresponds with actual setting in the nRF51 chip. APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START); APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE); // Initialize. timers_init(); #if defined(BUTTON_SUPPORT) buttons_init(); #endif (void)bootloader_init(); if (bootloader_dfu_sd_in_progress()) { nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED); err_code = bootloader_dfu_sd_update_continue(); APP_ERROR_CHECK(err_code); ble_stack_init(!app_reset); scheduler_init(); err_code = bootloader_dfu_sd_update_finalize(); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED); } else { // If stack is present then continue initialization of bootloader. ble_stack_init(!app_reset); scheduler_init(); dis_init(); } dfu_start = app_reset; #if defined(BUTTON_SUPPORT) dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) ? true: false); #endif if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START))) { nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED); PUTS("Start DFU"); // Initiate an update of the firmware. err_code = bootloader_dfu_start(); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED); } if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress()) { PUTS("Start App"); // Select a bank region to use as application region. // @note: Only applications running from DFU_BANK_0_REGION_START is supported. bootloader_app_start(DFU_BANK_0_REGION_START); } NVIC_SystemReset(); }
/** @brief Function for initializing PPI used in infrared signal decoding * The PPI is needed to convert the timer event into a task. */ uint32_t ir_ppi_init(void) { uint32_t gpiote_event_addr; uint32_t timer_task_addr; nrf_ppi_channel_t ppi_channel; ret_code_t err_code; nrf_drv_gpiote_in_config_t config; config.sense = NRF_GPIOTE_POLARITY_HITOLO; config.pull = NRF_GPIO_PIN_PULLUP; config.hi_accuracy = false; config.is_watcher = false; nrf_drv_timer_config_t timer_config; timer_config.frequency = NRF_TIMER_FREQ_1MHz; timer_config.mode = NRF_TIMER_MODE_TIMER; timer_config.bit_width = NRF_TIMER_BIT_WIDTH_32; timer_config.interrupt_priority = 3; err_code = nrf_drv_timer_init(&ir_timer, &timer_config, timer_dummy_handler); APP_ERROR_CHECK(err_code); // Set up GPIOTE err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_1, &config, ir_in_pin_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_2, &config, ir_in_pin_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_3, &config, ir_in_pin_handler); APP_ERROR_CHECK(err_code); // Set up timer for capturing nrf_drv_timer_capture_get(&ir_timer, NRF_TIMER_CC_CHANNEL0); // Set up PPI channel err_code = nrf_drv_ppi_channel_alloc(&ppi_channel); APP_ERROR_CHECK(err_code); timer_task_addr = nrf_drv_timer_capture_task_address_get(&ir_timer, NRF_TIMER_CC_CHANNEL0); gpiote_event_addr = nrf_drv_gpiote_in_event_addr_get(IR_RECEIVER_PIN_1); //err_code = nrf_drv_ppi_channel_assign(ppi_channel, gpiote_event_addr, timer_task_addr); //APP_ERROR_CHECK(err_code); //err_code = nrf_drv_ppi_channel_enable(ppi_channel); //APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_1, true); nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_2, true); nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_3, true); // Enable timer nrf_drv_timer_enable(&ir_timer); return 0; }
/** @brief Function for main application entry. */ int main(void) { TaskHandle_t compress_task_handle; TimerHandle_t spi_timer_handle; uint32_t err_code; err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); // Setup bsp module. //bsp_configuration(); //uart initialization const app_uart_comm_params_t comm_params = { RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, APP_UART_FLOW_CONTROL_ENABLED, false, UART_BAUDRATE_BAUDRATE_Baud38400 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_handle, APP_IRQ_PRIORITY_LOW, err_code); APP_ERROR_CHECK(err_code); //nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_HIGH; //config.init_state = true; //err_code = nrf_drv_gpiote_out_init(20, &config); //while(app_uart_put(65) != NRF_SUCCESS); //printf("1 ms = %d\n", pdMS_TO_TICKS(1)); intan_setup(); //while(app_uart_put(65) != NRF_SUCCESS); compression_init(); uesb_config_t uesb_config = UESB_DEFAULT_CONFIG; uesb_config.event_handler = uesb_event_handler; if (uesb_init(&uesb_config)!= UESB_SUCCESS) { printf("ESB init messed up\r\n"); } tx_payload.length = UESB_CORE_MAX_PAYLOAD_LENGTH; tx_payload.pipe = 0; while(app_uart_put(66) != NRF_SUCCESS); //printf("yo\n"); UNUSED_VARIABLE(xTaskCreate(compress_task, "c_task", configMINIMAL_STACK_SIZE + 200, NULL, 1, &compress_task_handle)); if(compress_task_handle == NULL) { printf("compression task init messed up\r\n"); } while(app_uart_put(67) != NRF_SUCCESS); //Test read intan company ID timer //spi_timer_handle = xTimerCreate("s_timer", 1, pdTRUE, NULL, spi_intan_id_handler); // Sample timer spi_timer_handle = xTimerCreate("s_timer", 1, pdTRUE, NULL, spi_data_collection_evt_handler); // LED1 timer creation if(spi_timer_handle == NULL) { printf("SPI timer init messed up\r\n"); } while(app_uart_put(68) != NRF_SUCCESS); if(xTimerStart(spi_timer_handle, 0) != pdPASS) { printf("Timer could not be started\r\n"); } while(app_uart_put(69) != NRF_SUCCESS); /* Activate deep sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // Start FreeRTOS scheduler. vTaskStartScheduler(); //timers_init(); //while(app_uart_put(67) != NRF_SUCCESS); //data_collection_timers_start(); //while(app_uart_put(68) != NRF_SUCCESS); for (;;) { printf("Messed up\r\n"); //power_manage(); /*if (m_transfer_completed) { //while(app_uart_put(72) != NRF_SUCCESS); m_transfer_completed = false; intan_convert(m_tx_data_spi, m_rx_data_spi,intan_convert_channel); //while(app_uart_put(73) != NRF_SUCCESS); intan_convert_channel ++; intan_convert_channel = intan_convert_channel % 32; //print m_rx_data_spi results switch_state(); //while(app_uart_put(74) != NRF_SUCCESS); //for (int i; i< RX_MSG_LENGTH; i++){ // while(app_uart_put(m_rx_data_spi[i]) != NRF_SUCCESS); //} nrf_delay_ms(DELAY_MS); //while(app_uart_put(75) != NRF_SUCCESS); }*/ //while(app_uart_put(76) != NRF_SUCCESS); } }
static inline void spi_write(const void * data, size_t size) { APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0)); }
/**@brief Processes an ANT messages while in the sending command state. * * @param[in] Pointer to the raw ant message received. */ static void process_message_sending_command(uint8_t* p_ant_message) { uint32_t err_code; switch (p_ant_message[ANT_MESSAGE_ID_OFFSET]) { case MESG_RESPONSE_EVENT_ID: { if(p_ant_message[ANT_MESSAGE_DATA0_OFFSET] == MESG_EVENT_ID) //Channel event { switch(p_ant_message[ANT_MESSAGE_DATA1_OFFSET]) { case EVENT_TX: { //This event will be received if broadcast messages were used //Automatically retry to increase the chances of a successful transmission asc_encode_command_page(m_current_command_data, m_tx_buffer); if(m_send_command_as_ack) { err_code = sd_ant_acknowledge_message_tx(m_channel_number, ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer); } else { err_code = sd_ant_broadcast_message_tx(m_channel_number, ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer); } APP_ERROR_CHECK(err_code); if(++m_msg_counter_sending_command > m_retries) { m_is_command_pending = false; ascm_set_state(m_previous_state); } break; } case EVENT_TRANSFER_TX_COMPLETED: { //The message was successfully received. No need to resend m_is_command_pending = false; ascm_set_state(m_previous_state); break; } case EVENT_TRANSFER_TX_FAILED: { asc_encode_command_page(m_current_command_data, m_tx_buffer); err_code = sd_ant_acknowledge_message_tx(m_channel_number, ANT_STANDARD_DATA_PAYLOAD_SIZE, m_tx_buffer); APP_ERROR_CHECK(err_code); //retry untitl success, or until too many retries have occured if(++m_msg_counter_sending_command > m_retries) { m_is_command_pending = false; ascm_set_state(m_previous_state); } break; } default: { break; } } } break; } case MESG_ACKNOWLEDGED_DATA_ID: //fall-through case MESG_BROADCAST_DATA_ID: { //Process by page switch (p_ant_message[DECODE_PAGE_ID_BYTE]) { case UPDATE_DATA_PID: { process_device_update(p_ant_message); break; } default: { break; } } break; } default: { break; } } }
/**@brief Processes an ANT messages while in the handshaking state. * * @param[in] Pointer to the raw ant message received. */ static void process_message_handshaking(uint8_t * p_ant_message) { uint32_t err_code; switch (p_ant_message[ANT_MESSAGE_ID_OFFSET]) { case MESG_RESPONSE_EVENT_ID: { if(p_ant_message[ANT_MESSAGE_DATA0_OFFSET] == MESG_EVENT_ID) //Channel event { switch(p_ant_message[ANT_MESSAGE_DATA1_OFFSET]) { case EVENT_TX: if(++m_msg_counter_handshaking > MAX_TX_MESSAGES_HANDSHAKING) { m_msg_counter_handshaking = 0; //lint --e{534} deviceregistry_remove_device(pm_device_registry, m_handshaking_device.shared_address); ascm_set_state(ADDRESS_AVAILABLE); } break; default: break; } } break; } case MESG_BROADCAST_DATA_ID: //fall-through case MESG_ACKNOWLEDGED_DATA_ID: //Process by page switch (p_ant_message[DECODE_PAGE_ID_BYTE]) { case CONFIRM_ACQUIRE_PID: { asc_confirm_acquire_paramters_t params; bool is_from_handshaking_device; err_code = asc_decode_confirm_acquire_page(m_handshaking_device.serial_number, &is_from_handshaking_device, ¶ms, p_ant_message); APP_ERROR_CHECK(err_code); //Confirm that it is the correct device if(is_from_handshaking_device) { m_handshaking_device.serial_number = params.serial_number; m_handshaking_device.model_number = params.model_number; m_handshaking_device.hw_revision = params.hw_revision; m_handshaking_device.sw_revision = params.sw_revision; //lint --e{534} deviceregistry_add_device(pm_device_registry, &m_handshaking_device); ascm_set_state(ADDRESS_AVAILABLE); //This ensures that after requesting the page we are returned back to Address Available } break; } default: break; } break; default: break; } }
static void sensor_timer_init(void) { uint32_t err_code; err_code = app_timer_create(&iss_struct.meas_timer,APP_TIMER_MODE_SINGLE_SHOT,update_value_timer_handler); APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t * p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t m_keys = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; 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; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events (assuming that the button events are only needed in connected state). If this is uncommented out here, 1. Make sure that app_button_disable() is called when handling BLE_GAP_EVT_DISCONNECTED below. 2. Make sure the app_button module is initialized. err_code = app_button_enable(); APP_ERROR_CHECK(err_code); */ break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events. This should be done to save power when not connected to a peer. err_code = app_button_disable(); APP_ERROR_CHECK(err_code); */ break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_keys); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } }
static void sensor_timer_start(uint16_t offset) { uint32_t err_code = app_timer_start(iss_struct.meas_timer, APP_TIMER_TICKS(offset ? offset : iss_struct.samp_freq_in_m_sec, APP_TIMER_PRESCALER), &iss_struct); APP_ERROR_CHECK(err_code); iss_struct.timer_running = true; }
/**@brief Function for application main entry, does not return. */ int main(void) { uint32_t err_code; // Setup UART. #if defined(TRACE_UART) const app_uart_comm_params_t comm_params = { RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, APP_UART_FLOW_CONTROL_DISABLED, false, UART_BAUDRATE_BAUDRATE_Baud38400 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_handle, APP_IRQ_PRIORITY_LOW, err_code); APP_ERROR_CHECK(err_code); #endif err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, softdevice_assert_callback); APP_ERROR_CHECK(err_code); // Set application IRQ to lowest priority. err_code = sd_nvic_SetPriority(PROTOCOL_EVENT_IRQn, NRF_APP_PRIORITY_LOW); APP_ERROR_CHECK(err_code); // Enable application IRQ (triggered from protocol). err_code = sd_nvic_EnableIRQ(PROTOCOL_EVENT_IRQn); APP_ERROR_CHECK(err_code); // Open HRM RX channel. hrm_rx_open(); uint8_t event; uint8_t ant_channel; uint8_t event_message_buffer[ANT_EVENT_MSG_BUFFER_MIN_SIZE]; printf("Enter hrm rx main processing loop...\n"); // Main loop. for (;;) { err_code = sd_app_event_wait(); APP_ERROR_CHECK(err_code); // Extract and process all pending ANT events. do { err_code = sd_ant_event_get(&ant_channel, &event, event_message_buffer); if (err_code == NRF_SUCCESS) { if (event == EVENT_RX) { // We are only interested of RX events. hrm_rx_channel_event_handle(event_message_buffer); } } } while (err_code == NRF_SUCCESS); } }
static void advertising_start(void){ uint32_t err_code; err_code = sd_ble_gap_adv_start(&m_adv_params); APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { const ble_gap_evt_adv_report_t *p_adv_report = &p_gap_evt->params.adv_report; //TODO: implement whitelist bool friend = true; // Whitelist substitute for (int i = 0; i < BLE_GAP_ADDR_LEN - 1; i++) // Last number of address doesnt count. Others should be same as ours. { if (p_adv_report->peer_addr.addr[BLE_GAP_ADDR_LEN - 1 - i] != l_device_address[i]) { friend = false; break; } } if (friend) { make_report(NRF_RTC1->COUNTER, timer_epoch, p_adv_report->rssi, p_adv_report->peer_addr.addr[0]); } break; } case BLE_GAP_EVT_CONNECTED: err_code = NRF_SUCCESS; sd_ble_gap_scan_stop(); __LOG("conn. scan stopped"); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; __LOG("disco. scan start"); scan_start(); //initialize advertising again in case power level changed. //advertised power is not by default tx power advertising_init(); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: //advertising starts itself. scan_start(); __LOG("timeout. scan start"); break; case BLE_GATTS_EVT_TIMEOUT: if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); } //TODO: manage timeout. __LOG("GATTS timeout."); break; case BLE_EVT_TX_COMPLETE: if (m_file_in_transit) ble_nus_data_transfer(); break; default: // No implementation needed. break; } }
int main(void) { u32 err; //Initialize the UART Terminal Terminal::Init(); //Initialialize the SoftDevice and the BLE stack bleInit(); //Enable logging for some interesting log tags Logger::getInstance().enableTag("NODE"); Logger::getInstance().enableTag("STORAGE"); Logger::getInstance().enableTag("DATA"); Logger::getInstance().enableTag("SEC"); //Initialize the storage class Storage::getInstance(); //Init the magic node = new Node(Config->meshNetworkIdentifier); new Testing(); struct mallinfo used = mallinfo(); volatile u32 size = used.uordblks + used.hblkhd; //Start Timers initTimers(); while (true) { u32 err = NRF_ERROR_NOT_FOUND; //Check if there is input on uart Terminal::PollUART(); do { //Fetch the event sizeOfCurrentEvent = sizeOfEvent; err = sd_ble_evt_get(currentEventBuffer, &sizeOfCurrentEvent); //Handle ble event event if (err == NRF_SUCCESS) { //logt("EVENT", "--- EVENT_HANDLER %d -----", currentEvent->header.evt_id); bleDispatchEventHandler(currentEvent); } //No more events available else if (err == NRF_ERROR_NOT_FOUND) { //Handle Timer event that was waiting if (node && node->passsedTimeSinceLastTimerHandler > 0) { //Call the timer handler from the node node->TimerTickHandler(node->passsedTimeSinceLastTimerHandler); //Dispatch timer to all other modules timerEventDispatch(node->passsedTimeSinceLastTimerHandler, node->appTimerMs); node->passsedTimeSinceLastTimerHandler = 0; } err = sd_app_evt_wait(); APP_ERROR_CHECK(err); sd_nvic_ClearPendingIRQ(SD_EVT_IRQn); break; } else { APP_ERROR_CHECK(err); break; } } while (true); } }
/**@snippet [Handling the data received over BLE] */ static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length) { uint32_t err_code; if (length==1) //< Control Command { switch(p_data[0]) { /** Radio transmit power in dBm * (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). */ case '1': err_code = ble_nus_string_send(p_nus, (uint8_t *) "Power set to -40", 16); APP_ERROR_CHECK(err_code); gap_tx_power = -40; err_code = sd_ble_gap_tx_power_set(gap_tx_power); APP_ERROR_CHECK(err_code); break; case '2': err_code = ble_nus_string_send(p_nus, (uint8_t *) "Power set to -20", 16); APP_ERROR_CHECK(err_code); gap_tx_power = -20; err_code = sd_ble_gap_tx_power_set(gap_tx_power); APP_ERROR_CHECK(err_code); break; case '3': err_code = ble_nus_string_send(p_nus, (uint8_t *) "Power set to 0", 14); APP_ERROR_CHECK(err_code); gap_tx_power = 0; err_code = sd_ble_gap_tx_power_set(gap_tx_power); APP_ERROR_CHECK(err_code); break; case 'c': ; storage_clear(); err_code = ble_nus_string_send(p_nus, (uint8_t *) "Storage cleared.", 16); APP_ERROR_CHECK(err_code); break; case 'l': ; char str_l[17]; sprintf(str_l, "Toggled lock to %d", storage_toggle_lock()); ble_nus_string_send(p_nus, (uint8_t *) str_l, 18); break; case 'r': store_read_init(); read_store_data(m_nus_data, &m_data_length); nrf_delay_ms(MAX_CONN_INTERVAL * 2); m_file_in_transit = true; err_code = ble_nus_string_send(p_nus, (uint8_t *) "***DATA TRANSFER***", 19); APP_ERROR_CHECK(err_code); break; case 't': ; char str_t[20]; uint8_t c; uint32_t ts = NRF_RTC1->COUNTER; c = sprintf(str_t, "ts:%lu epoch:%d", ts, timer_epoch); err_code = ble_nus_string_send(p_nus, (uint8_t *) str_t, c); APP_ERROR_CHECK(err_code); break; } } __LOG("NUSCON:%s", p_data); }
/**@brief Callback handling device manager events. * * @details This function is called to notify the application of device manager events. * * @param[in] p_handle Device Manager Handle. For link related events, this parameter * identifies the peer. * @param[in] p_event Pointer to the device manager event. * @param[in] event_status Status of the event. */ static ret_code_t device_manager_event_handler(const dm_handle_t * p_handle, const dm_event_t * p_event, const ret_code_t event_result) { uint32_t err_code; switch (p_event->event_id) { case DM_EVT_CONNECTION: { APPL_LOG("[APPL]: >> DM_EVT_CONNECTION\r\n"); #ifdef ENABLE_DEBUG_LOG_SUPPORT ble_gap_addr_t * peer_addr; peer_addr = &p_event->event_param.p_gap_param->params.connected.peer_addr; #endif // ENABLE_DEBUG_LOG_SUPPORT APPL_LOG("[APPL]:[%02X %02X %02X %02X %02X %02X]: Connection Established\r\n", peer_addr->addr[0], peer_addr->addr[1], peer_addr->addr[2], peer_addr->addr[3], peer_addr->addr[4], peer_addr->addr[5]); err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_event->event_param.p_gap_param->conn_handle; m_dm_device_handle = (*p_handle); // Discover peer's services. err_code = ble_db_discovery_start(&m_ble_db_discovery, p_event->event_param.p_gap_param->conn_handle); APP_ERROR_CHECK(err_code); m_peer_count++; if (m_peer_count < CENTRAL_LINK_COUNT) { scan_start(); } APPL_LOG("[APPL]: << DM_EVT_CONNECTION\r\n"); break; } case DM_EVT_DISCONNECTION: { APPL_LOG("[APPL]: >> DM_EVT_DISCONNECTION\r\n"); memset(&m_ble_db_discovery, 0, sizeof(m_ble_db_discovery)); err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); if (m_peer_count == CENTRAL_LINK_COUNT) { scan_start(); } m_peer_count--; APPL_LOG("[APPL]: << DM_EVT_DISCONNECTION\r\n"); break; } case DM_EVT_SECURITY_SETUP: { APPL_LOG("[APPL]:[0x%02X] >> DM_EVT_SECURITY_SETUP\r\n", p_handle->connection_id); // Slave securtiy request received from peer, if from a non bonded device, // initiate security setup, else, wait for encryption to complete. err_code = dm_security_setup_req(&m_dm_device_handle); APP_ERROR_CHECK(err_code); APPL_LOG("[APPL]:[0x%02X] << DM_EVT_SECURITY_SETUP\r\n", p_handle->connection_id); break; } case DM_EVT_SECURITY_SETUP_COMPLETE: { APPL_LOG("[APPL]: >> DM_EVT_SECURITY_SETUP_COMPLETE\r\n"); // Running Speed and Cadence service discovered. Enable Running Speed and Cadence notifications. err_code = ble_rscs_c_rsc_notif_enable(&m_ble_rsc_c); APP_ERROR_CHECK(err_code); APPL_LOG("[APPL]: << DM_EVT_SECURITY_SETUP_COMPLETE\r\n"); break; } case DM_EVT_LINK_SECURED: APPL_LOG("[APPL]: >> DM_LINK_SECURED_IND\r\n"); APPL_LOG("[APPL]: << DM_LINK_SECURED_IND\r\n"); break; case DM_EVT_DEVICE_CONTEXT_LOADED: APPL_LOG("[APPL]: >> DM_EVT_LINK_SECURED\r\n"); APP_ERROR_CHECK(event_result); APPL_LOG("[APPL]: << DM_EVT_DEVICE_CONTEXT_LOADED\r\n"); break; case DM_EVT_DEVICE_CONTEXT_STORED: APPL_LOG("[APPL]: >> DM_EVT_DEVICE_CONTEXT_STORED\r\n"); APP_ERROR_CHECK(event_result); APPL_LOG("[APPL]: << DM_EVT_DEVICE_CONTEXT_STORED\r\n"); break; case DM_EVT_DEVICE_CONTEXT_DELETED: APPL_LOG("[APPL]: >> DM_EVT_DEVICE_CONTEXT_DELETED\r\n"); APP_ERROR_CHECK(event_result); APPL_LOG("[APPL]: << DM_EVT_DEVICE_CONTEXT_DELETED\r\n"); break; default: break; } return NRF_SUCCESS; }
/** * \brief Slave driver main state machine * For UML graph, please refer to SDK documentation */ static void spi_slave_event_handle(nrf_drv_spis_event_t event) { static uint32_t err_code = NRF_SUCCESS; static uint16_t packetLength; switch (m_trans_state) { case SPI_RAW_STATE_SETUP_HEADER: m_trans_state = SPI_RAW_STATE_RX_HEADER; err_code = header_get(); break; case SPI_RAW_STATE_RX_HEADER: if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); set_ready_line(); } if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE); packetLength = uint16_decode(m_header_rx_buffer); if (packetLength != 0 ) { m_trans_state = SPI_RAW_STATE_MEM_REQUESTED; m_buffer_reqested_flag = true; m_rx_packet_length = packetLength; callback_memory_request(packetLength); } else { if (m_p_tx_buffer) { clear_request_line(); m_trans_state = SPI_RAW_STATE_TX_HEADER; err_code = header_send(m_tx_packet_length); } else { //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert err_code = header_send(0); } } } break; case SPI_RAW_STATE_MEM_REQUESTED: if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event { m_buffer_reqested_flag = false; m_trans_state = SPI_RAW_STATE_RX_PAYLOAD; m_accumulated_rx_packet_length = 0; err_code = frame_get(); } break; case SPI_RAW_STATE_RX_PAYLOAD: if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); set_ready_line(); } if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length); m_accumulated_rx_packet_length += m_current_rx_frame_length; if (m_accumulated_rx_packet_length < m_rx_packet_length ) { err_code = frame_get(); } else { spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); m_trans_state = SPI_RAW_STATE_RX_HEADER; err_code = header_get(); if (!m_trash_payload_flag) { callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length); } else { callback_packet_dropped(); } } } break; case SPI_RAW_STATE_TX_HEADER: if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); set_ready_line(); } if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE + 1); m_trans_state = SPI_RAW_STATE_TX_PAYLOAD; m_accumulated_tx_packet_length = 0; err_code = frame_send(); } break; case SPI_RAW_STATE_TX_PAYLOAD: if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); set_ready_line(); } if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) { DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length + 1); m_accumulated_tx_packet_length += m_current_tx_frame_length; if ( m_accumulated_tx_packet_length < m_tx_packet_length ) { err_code = frame_send(); } else { spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); //clear pointer before callback m_p_tx_buffer = NULL; callback_packet_transmitted(); //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header m_trans_state = SPI_RAW_STATE_RX_HEADER; err_code = header_get(); } } break; default: err_code = NRF_ERROR_INVALID_STATE; break; } APP_ERROR_CHECK(err_code); }
/** * @brief Database discovery collector initialization. */ static void db_discovery_init(void) { uint32_t err_code = ble_db_discovery_init(); APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_N); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_N); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; err_code = app_button_enable(); break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_N); m_conn_handle = BLE_CONN_HANDLE_INVALID; err_code = app_button_disable(); if (err_code == NRF_SUCCESS) { advertising_start(); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_N); // Go to system-off mode (this function will not return; wakeup will cause a reset) GPIO_WAKEUP_BUTTON_CONFIG(WAKEUP_BUTTON_PIN); uart_tx_str("reset by timeout"); err_code = sd_power_system_off(); } break; case BLE_GATTS_EVT_WRITE: break; case BLE_GAP_EVT_CONN_PARAM_UPDATE: nrf_gpio_pin_toggle (LEDBUTTON_LED_PIN_NO); break; default: break; } APP_ERROR_CHECK(err_code); }
void bootloader_rtc_irq_handler(void) { NRF_RTC0->INTENCLR = (1 << (RTC_BL_STATE_CH + RTC_INTENCLR_COMPARE0_Pos)); switch (m_state) { case BL_STATE_FIND_FWID: bootloader_abort(BL_END_FWID_VALID); break; case BL_STATE_DFU_REQ: case BL_STATE_DFU_READY: bootloader_abort(BL_END_ERROR_NO_START); break; case BL_STATE_DFU_TARGET: start_req(m_transaction.type, true); break; case BL_STATE_VALIDATE: if (signature_check()) { /* Don't want any interrupts disturbing this final stage */ uint32_t was_masked; _DISABLE_IRQS(was_masked); /* write new version in bl info: */ bl_info_entry_t new_version_entry; memcpy(&new_version_entry.version, m_bl_info_pointers.p_fwid, sizeof(fwid_t)); bl_info_type_t sign_info_type = BL_INFO_TYPE_INVALID; if (m_bl_info_pointers.p_flags == NULL) { APP_ERROR_CHECK(NRF_ERROR_NULL); } /* copy flags, then mark the type we just verified as intact before reflashing it. */ bl_info_entry_t flags_entry; memcpy(&flags_entry, m_bl_info_pointers.p_flags, ((BL_INFO_LEN_FLAGS + 3) & ~0x03UL)); switch (m_transaction.type) { case DFU_TYPE_APP: memcpy((void*) &new_version_entry.version.app, (void*) &m_transaction.target_fwid_union.app, DFU_FWID_LEN_APP); sign_info_type = BL_INFO_TYPE_SIGNATURE_APP; flags_entry.flags.app_intact = true; break; case DFU_TYPE_SD: memcpy((void*) &new_version_entry.version.sd, (void*) &m_transaction.target_fwid_union.sd, DFU_FWID_LEN_SD); sign_info_type = BL_INFO_TYPE_SIGNATURE_SD; flags_entry.flags.sd_intact = true; break; case DFU_TYPE_BOOTLOADER: memcpy((void*) &new_version_entry.version.bootloader, (void*) &m_transaction.target_fwid_union.bootloader, DFU_FWID_LEN_BL); sign_info_type = BL_INFO_TYPE_SIGNATURE_BL; flags_entry.flags.bl_intact = true; break; default: break; } m_bl_info_pointers.p_fwid = &bootloader_info_entry_put(BL_INFO_TYPE_VERSION, &new_version_entry, BL_INFO_LEN_FWID)->version; m_bl_info_pointers.p_flags = &bootloader_info_entry_put(BL_INFO_TYPE_FLAGS, &flags_entry, BL_INFO_LEN_FLAGS)->flags; /* add signature to bl info, if applicable: */ if (m_transaction.signature_length != 0) { bootloader_info_entry_put(sign_info_type, (bl_info_entry_t*) m_transaction.signature, DFU_SIGNATURE_LEN); } _ENABLE_IRQS(was_masked); bootloader_abort(BL_END_SUCCESS); } else { /* someone gave us anauthorized firmware, and we're broken. need to reboot and try to request a new transfer */ bootloader_abort(BL_END_ERROR_UNAUTHORIZED); } break; case BL_STATE_RELAY: case BL_STATE_RELAY_CANDIDATE: bootloader_abort(BL_END_SUCCESS); break; default: break; } }
/**@brief Function for initializing the nrf log module. */ static void nrf_log_init(void) { ret_code_t err_code = NRF_LOG_INIT(); APP_ERROR_CHECK(err_code); }
uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, ble_advdata_t const * p_srdata, ble_adv_modes_config_t const * p_config, ble_advertising_evt_handler_t const evt_handler, ble_advertising_error_handler_t const error_handler) { uint32_t err_code; if((p_advdata == NULL) || p_config == NULL) { return NRF_ERROR_NULL; } m_adv_mode_current = BLE_ADV_MODE_IDLE; m_evt_handler = evt_handler; m_error_handler = error_handler; m_adv_modes_config = *p_config; ble_advertising_peer_address_clear(); // Prepare Whitelist. Address and IRK double pointers point to allocated arrays. m_whitelist.pp_addrs = mp_whitelist_addr; m_whitelist.pp_irks = mp_whitelist_irk; // Copy and set advertising data. memset(&m_advdata, 0, sizeof(m_advdata)); // Copy advertising data. m_advdata.name_type = p_advdata->name_type; m_advdata.include_appearance = p_advdata->include_appearance; m_advdata.flags = p_advdata->flags; m_advdata.short_name_len = p_advdata->short_name_len; /* if(p_advdata->uuids_complete != NULL) { m_advdata.uuids_complete = p_advdata->uuids_complete; } */ m_advdata.uuids_complete = p_advdata->uuids_complete; m_advdata.uuids_more_available = p_advdata->uuids_more_available; m_advdata.uuids_solicited = p_advdata->uuids_solicited; if(p_advdata->p_manuf_specific_data != NULL) { m_advdata.p_manuf_specific_data = &m_manuf_specific_data; m_manuf_specific_data.data.p_data = m_manuf_data_array; m_advdata.p_manuf_specific_data->company_identifier = p_advdata->p_manuf_specific_data->company_identifier; m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size; for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++) { m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i]; } } if(p_advdata->p_service_data_array != NULL) { m_service_data.data.p_data = m_service_data_array; m_advdata.p_service_data_array = &m_service_data; m_advdata.p_service_data_array->data.p_data = m_service_data_array; m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size; m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid; for(uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++) { m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i]; } m_advdata.service_data_count = p_advdata->service_data_count; } if(p_advdata->p_slave_conn_int != NULL) { m_advdata.p_slave_conn_int = &m_slave_conn_int; m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval; m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval; } if(p_advdata->p_tx_power_level != NULL) { m_advdata.p_tx_power_level = &m_tx_power_level; m_advdata.p_tx_power_level = p_advdata->p_tx_power_level; } err_code = ble_advdata_set(&m_advdata, p_srdata); APP_ERROR_CHECK(err_code); return err_code; }
/**@brief Sets the state machine to the specified state. */ static void ascm_set_state(ascm_states_t new_state) { uint32_t err_code; if(new_state != m_state) { switch (new_state) { case ASCM_OFF: { //Close the channel m_previous_state = m_state; m_state = new_state; err_code = sd_ant_channel_close(m_channel_number); APP_ERROR_CHECK(err_code); break; } case ADDRESS_AVAILABLE: { if (m_state == ASCM_OFF) { //Open the channel err_code = sd_ant_channel_open(m_channel_number); APP_ERROR_CHECK(err_code); } m_previous_state = m_state; m_state = new_state; m_is_address_available = !deviceregistry_is_full(pm_device_registry); ascm_send_address_available_page(); break; } case HANDSHAKING: { if(m_state != ADDRESS_AVAILABLE) { asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE); return; } m_previous_state = m_state; m_state = new_state; //there is no need to check for validity of this shared address, as there must be a free address available //to be in the handshaking state at all. m_handshaking_device.shared_address = deviceregistry_get_next_free_shared_address(pm_device_registry); m_msg_counter_handshaking = 0; ascm_send_busy_acquiring_page(); break; } case POLLING: { if(m_state != ADDRESS_AVAILABLE && m_state != SENDING_COMMAND) { asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE); return; } m_previous_state = m_state; m_state = new_state; //If the previous state was not SENDING_COMMAND, start from the beginning of the polling cycle. //Otherwise, allow the process_message handler to finish the cycle if(m_previous_state != SENDING_COMMAND) { m_current_shared_address_polling = deviceregistry_get_first_registered_shared_address(pm_device_registry); if(m_current_shared_address_polling != INVALID_SHARED_ADDRESS) { m_msg_counter_polling = 0; send_polling_message(); } else { //no devices are registered, go back to address available ascm_set_state(ADDRESS_AVAILABLE); } } break; } case SENDING_COMMAND: { //Only allow sending commands if the device is in the //Address available or polling states if(m_state != ADDRESS_AVAILABLE && m_state != POLLING) { asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE); return; } m_previous_state = m_state; m_state = new_state; m_msg_counter_sending_command = 0; break; } default: { //if the new state was not recognized, return to avoid setting the state changed event asc_event_set(&m_asc_event_flags, EVENT_ASC_DEVICE_IN_WRONG_STATE); return; } } asc_event_set(&m_asc_event_flags, EVENT_ASC_STATE_CHANGED); } }