/** * \brief Main function of the Performance Analyzer application * \ingroup group_app_init */ int main(void) { irq_initialize_vectors(); /* Initialize the board. * The board-specific conf_board.h file contains the configuration of * the board initialization. */ board_init(); sysclk_init(); /* * Power ON - so set the board to INIT state. All hardware, PAL, TAL and * stack level initialization must be done using this function */ set_main_state(INIT, NULL); cpu_irq_enable(); sio2host_init(); /* INIT was a success - so change to WAIT_FOR_EVENT state */ set_main_state(WAIT_FOR_EVENT, NULL); /* Endless while loop */ while (1) { pal_task(); /* Handle platform specific tasks, like serial interface */ tal_task(); /* Handle transceiver specific tasks */ app_task(); /* Application task */ serial_data_handler(); } }
/* * \brief This function is called rest the application equivalent to soft reset * */ void app_reset(void) { /* app reset - this is to make the node to restart application as * bootup */ set_main_state(INIT, NULL); /* INIT was a success - so change to WAIT_FOR_EVENT state */ set_main_state(WAIT_FOR_EVENT, NULL); }
/** * \brief Callback that is called once tx is done in wait for peer search conf * state. * * \param status Status of the transmission procedure * \param frame Pointer to the transmitted frame structure */ static void wait_for_conf_rx_cb(frame_info_t *mac_frame_info) { app_payload_t *msg; if (*(mac_frame_info->mpdu) == (FRAME_OVERHEAD + ((sizeof(app_payload_t) - sizeof(general_pkt_t)) + sizeof(peer_conf_t)))) { /* Point to the message : 1 =>size is first byte and 2=>FCS*/ msg = (app_payload_t *)(mac_frame_info->mpdu + 1 + FRAME_OVERHEAD - 2); if ((msg->cmd_id) == PEER_CONFIRM) { if (node_info.peer_short_addr == (msg->payload.peer_conf_data.nwk_addr)) { print_event(PRINT_PEER_SEARCH_SUCCESS); app_led_event(LED_EVENT_PEER_SEARCH_DONE); switch (node_info.main_state) { case PEER_SEARCH_RANGE_RX: /* Peer success - set the board to * RANGE_TEST_TX_OFF state */ set_main_state(RANGE_TEST_TX_OFF, 0); break; case PEER_SEARCH_PER_RX: /* Peer success - set the board to * RANGE_TEST_TX_OFF state */ set_main_state(PER_TEST_RECEPTOR, 0); break; /* To keep the GCC compiler happy */ case INIT: case WAIT_FOR_EVENT: case PEER_SEARCH_RANGE_TX: case PEER_SEARCH_PER_TX: case RANGE_TEST_TX_ON: case RANGE_TEST_TX_OFF: case SINGLE_NODE_TESTS: case PER_TEST_INITIATOR: case PER_TEST_RECEPTOR: case NUM_MAIN_STATES: break; default: /* Do nothing */ break; } } } } }
/** * \brief Peer rsp received state init function * * \arg argument to be used in init function */ static void peer_rsp_rcvd_init(void *arg) { /* Set the newly assigned address */ tal_pib_set(macShortAddress, (pib_value_t *)arg); if (send_peer_conf()) { /* Print messge if the Peer search failed in Range mode */ if (PEER_SEARCH_RANGE_TX == node_info.main_state) { print_event(PRINT_PEER_SEARCH_FAILED); } else if (PEER_SEARCH_PER_TX == node_info.main_state) { /* Send the confirmation to the PC application via Serial interface */ usr_perf_start_confirm(NO_PEER_FOUND, START_MODE_PER, NULL, NUL_VAL, NULL, NULL, NULL, NUL_VAL); } /* PEER CONF send failed - so change to WAIT_FOR_EVENT state*/ set_main_state(WAIT_FOR_EVENT, NULL); } }
/** * \brief Timer handler for supporting peer search * * \param parameter pass parameters to timer handler */ static void app_peer_conf_tmr_handler_cb( void *parameter) { trx_id_t trx = (trx_id_t)parameter; print_event(trx, PRINT_PEER_SEARCH_FAILED); /* No PEER CONF so change to WAIT_FOR_EVENT state*/ set_main_state(trx, WAIT_FOR_EVENT, 0); }
/** * \brief Timer handler for supporting peer search * * \param parameter pass parameters to timer handler */ static void app_peer_conf_tmr_handler_cb(void *parameter) { print_event(PRINT_PEER_SEARCH_FAILED); /* No PEER CONF so change to WAIT_FOR_EVENT state*/ set_main_state(WAIT_FOR_EVENT, 0); /* keep compiler happy */ parameter = parameter; }
/* * \brief This function is called rest the application equivalent to soft reset * */ void app_reset(trx_id_t trx) { /* app reset - this is to make the node to restart application as boot *up */ init_after_disconnect(trx); /* INIT was a success - so change to WAIT_FOR_EVENT state */ set_main_state(trx, WAIT_FOR_EVENT, NULL); }
/** * \brief Application task handling peer search * * This function * - Implements the peer search state machine. */ static void peer_rsp_send_init(void *arg) { peer_search_receptor_arg_t *arg_ptr = (peer_search_receptor_arg_t *)arg; if (send_peer_rsp(&(arg_ptr->peer_ieee_addr))) { print_event(PRINT_PEER_SEARCH_FAILED); /* PEER RSP send failed - so change to WAIT_FOR_EVENT state*/ set_main_state(WAIT_FOR_EVENT, 0); } }
/** * \brief Callback that is called once tx is done in PEER_RSP_SEND state. * * \param status Status of the transmission procedure * \param frame Pointer to the transmitted frame structure */ static void peer_rsp_send_tx_done_cb(retval_t status, frame_info_t *frame) { if (status == MAC_SUCCESS) { peer_search_receptor_set_sub_state(WAIT_FOR_PEER_CONF, 0); } else { print_event(PRINT_PEER_SEARCH_FAILED); /* No PEER RSP send failed so change to WAIT_FOR_EVENT state*/ set_main_state(WAIT_FOR_EVENT, 0); } /* Keep compiler happy */ frame = frame; }
/* * \brief Application task handling user events like key press or * character on UART * * This function * - Implements the event handling in WAIT_FOR_EVENT state. */ void wait_for_event_task(void) { uint8_t key_press; /* Check for any key press */ key_press = app_debounce_button(); if (key_press != 0) { print_event(PRINT_KEY_PRESS_PEER_SEARCH_INITIATOR); /* key press detected - so change to state PEER_SEARCH_RANGE_TX */ set_main_state(PEER_SEARCH_RANGE_TX, NULL); } }
/* * \brief Application task handling Range Measurement when the node is in * * RANGE_TEST_TX_OFF state, where no TX is enabled and only RX is ON */ void range_test_tx_off_task(void) { int char_received; uint8_t key_press; /* See if any character received on the UART */ char_received = sio2host_getchar_nowait(); /* Check for any key press */ key_press = app_debounce_button(); if (key_press != 0) { /* key press detected - so change to state RANGE_TEST_TX_OFF */ set_main_state(RANGE_TEST_TX_ON, 0); } else if (char_received != -1) { print_event(PRINT_RANGE_MEASURE_STATSTICS); } }
/** * \brief Callback that is called once tx is done in peer rsp rcvd state. * * \param status Status of the transmission procedure * \param frame Pointer to the transmitted frame structure */ static void peer_rsp_rcvd_tx_cb(retval_t status, frame_info_t *frame) { if (MAC_SUCCESS == status) { node_info.peer_found = true; /* Change LED pattern */ app_led_event(LED_EVENT_PEER_SEARCH_DONE); switch (node_info.main_state) { case PEER_SEARCH_RANGE_TX: { print_event(PRINT_PEER_SEARCH_SUCCESS); /* Peer success - set the board to RANGE_TEST_TX_ON state */ set_main_state(RANGE_TEST_TX_ON, NULL); } break; case PEER_SEARCH_PER_TX: { /* Peer success - set the board to PER_TEST_INITIATOR state */ set_main_state(PER_TEST_INITIATOR, NULL); } break; /* To keep the GCC compiler happy */ case INIT: case WAIT_FOR_EVENT: case PEER_SEARCH_RANGE_RX: case PEER_SEARCH_PER_RX: case RANGE_TEST_TX_ON: case RANGE_TEST_TX_OFF: case SINGLE_NODE_TESTS: case PER_TEST_INITIATOR: case PER_TEST_RECEPTOR: case NUM_MAIN_STATES: break; default: /* Do nothing */ break; } } else { /* Print messge if the Peer search failed in Range mode */ if (PEER_SEARCH_RANGE_TX == node_info.main_state) { print_event(PRINT_PEER_SEARCH_FAILED); } else if (PEER_SEARCH_PER_TX == node_info.main_state) { /* Send the confirmation to the PC application via Serial interface */ usr_perf_start_confirm(NO_PEER_FOUND, START_MODE_PER, NULL, NUL_VAL, NULL, NULL, NULL, NUL_VAL); } /* PEER CONF send failed so change to WAIT_FOR_EVENT state*/ set_main_state(WAIT_FOR_EVENT, NULL); } /* Keep compiler happy */ frame = frame; }
/** * \brief Application task handling peer request send * */ static void peer_req_send_task() { static uint8_t count = 0; if (sw_timer_is_running(APP_TIMER_TO_TX)) { return; } if (MAX_NUMBER_PEER_REQ_RETRY == count) { count = 0; switch (node_info.main_state) { case PEER_SEARCH_PER_TX: { /* In confiuration mode allow the user to do peer search again */ if (node_info.configure_mode == true) { /* PEER REQ command failed - so change to WAIT_FOR_EVENT state */ set_main_state(WAIT_FOR_EVENT, NULL); } else { /* Peer search was failed in PER mode - so change to SINGLE_NODE_TESTS state */ set_main_state(SINGLE_NODE_TESTS, NULL); } } break; case PEER_SEARCH_RANGE_TX: { print_event(PRINT_PEER_SEARCH_FAILED); /* PEER REQ command failed - so change to WAIT_FOR_EVENT state */ set_main_state(WAIT_FOR_EVENT, NULL); } break; /* To keep the GCC compiler happy */ case INIT: case WAIT_FOR_EVENT: case PEER_SEARCH_RANGE_RX: case PEER_SEARCH_PER_RX: case RANGE_TEST_TX_ON: case RANGE_TEST_TX_OFF: case SINGLE_NODE_TESTS: case PER_TEST_INITIATOR: case PER_TEST_RECEPTOR: case NUM_MAIN_STATES: break; default: /* Do nothing */ break; } return; } count++; /* Print messge if the Peer search is in progress in Range mode */ if (PEER_SEARCH_RANGE_TX == node_info.main_state) { print_event(PRINT_PEER_SEARCH_IN_PROGRESS); } /* Send Peer Requests */ if (!send_peer_req()) { sw_timer_start(APP_TIMER_TO_TX, PEER_REQUEST_SEND_INTERVAL_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)app_peer_req_tmr_handler_cb, NULL); } }
/* * \brief Callback that is called if data has been received by trx * in WAIT_FOR_EVENT state. This allow the node to participate in * Peer Search process as receptor * * \param frame Pointer to received frame */ void wait_for_event_rx_cb(frame_info_t *mac_frame_info) { app_payload_t *msg; peer_search_receptor_arg_t peer_info; uint8_t expected_frame_size = FRAME_OVERHEAD_SRC_IEEE_ADDR + ((sizeof(app_payload_t) - sizeof(general_pkt_t)) + sizeof(peer_req_t)); /* Frame received on air: Processing the same */ if (*(mac_frame_info->mpdu) == expected_frame_size) { /* Point to the message : 1 =>size is first byte and 2=>FCS*/ msg = (app_payload_t *)(mac_frame_info->mpdu + LENGTH_FIELD_LEN + FRAME_OVERHEAD_SRC_IEEE_ADDR - FCS_LEN); /* Is this a peer request cmd */ if ((msg->cmd_id) == PEER_REQUEST) { uint8_t frame_len = mac_frame_info->mpdu[0]; uint8_t ed_val = mac_frame_info->mpdu[frame_len + LQI_LEN + ED_VAL_LEN]; /* Check the threshold if the configuarion mode is * enabled, not otherwise */ if (((msg->payload.peer_req_data.config_mode == true) && (ed_val > CONFIG_ED_THRESHOLD)) || (msg->payload.peer_req_data.config_mode == false)) { peer_info.my_short_addr = (msg->payload.peer_req_data. nwk_addr); memcpy(&(peer_info.peer_ieee_addr), (mac_frame_info->mpdu + LENGTH_FIELD_LEN + OFFSET_FOR_SRC_IEEE_ADDR), sizeof(peer_info.peer_ieee_addr)); switch (msg->payload.peer_req_data.op_mode) { case RANGE_MEASURE_MODE: /* * Frame found to be peer search for * range test * so change to state * PEER_SEARCH_RANGE_RX */ set_main_state(PEER_SEARCH_RANGE_RX, &peer_info); print_event( PRINT_KEY_PRESS_PEER_SEARCH_RECEPTOR); break; case PER_TEST_MODE: /* * Frame found to be peer search for * range test * so change to state PEER_SEARCH_PER_RX */ set_main_state(PEER_SEARCH_PER_RX, &peer_info); print_event( PRINT_UART_CHAR_PEER_SEARCH_RECEPTOR); break; default: /* The node has got a wrong frame: No * change of mode */ print_event( PRINT_PEER_SEARCH_RECEPTOR_BAD_FRAME); break; } } } } }