/** * \brief This function initiates packet streaming test. * \param gap_time Gap to be provided between consecutive frames * in terms of milliseconds * \timeout : This parameter is used by the receptor node to * timeout/stop the packet streaming * \param frame_len Length of the Data frame to be streamed */ void pktstream_test(uint16_t gap_time,uint16_t timeout,bool start_stop,uint16_t frame_len) { pkt_stream_gap_time = gap_time; /*Return if the frame length is less than 127(Max MPDU Length)*/ if(frame_len<=127) { usr_pkt_stream_confirm(MAC_SUCCESS,start_stop); } else { usr_pkt_stream_confirm(INVALID_ARGUMENT,start_stop); } /* Send the Packet Stream Start Confirm in case of Receptor before beginning * packet streaming.Serial Handler will take care in sending the confirmation * over the air to the Host*/ if((node_info.main_state == PER_TEST_RECEPTOR)) { serial_data_handler(); } if(start_stop) { /*Configure the frame for streaming*/ configure_pkt_stream_frames(frame_len); op_mode=PKT_STREAM_MODE; /*Start the gap timer*/ if(pkt_stream_gap_time) { sw_timer_start(T_APP_TIMER,pkt_stream_gap_time*1E3,SW_TIMEOUT_RELATIVE,(FUNC_PTR)pkt_stream_gap_timer,NULL); } else { rdy_to_tx = true; } pkt_stream_stop = false; if((node_info.main_state == PER_TEST_RECEPTOR) && 1 <= timeout ) { sw_timer_start(CW_TX_TIMER, (uint32_t)timeout * 1E6, SW_TIMEOUT_RELATIVE, (FUNC_PTR)stop_pkt_streaming, NULL); } } else { /*stop packet streaming once the current packet transmission is completed*/ pkt_stream_stop = true; sw_timer_stop(T_APP_TIMER); op_mode=TX_OP_MODE; } }
/* * \brief Turns LEDs on/off to indicate specific events. * * \param ev the event to be indicated. * */ void app_led_event(led_event_t ev) { #if (LED_COUNT > 0) switch (ev) { case LED_EVENT_TX_FRAME: LED_On(TX_LED); sw_timer_start(APP_TIMER_TO_TX_LED_OFF, LED_ON_DURAION_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)app_switch_off_tx_led_cb, NULL); break; case LED_EVENT_RX_FRAME: LED_On(RX_LED); sw_timer_start(APP_TIMER_TO_RX_LED_OFF, LED_ON_DURAION_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)app_switch_off_rx_led_cb, NULL); break; case LED_EVENT_POWER_ON: LED_Off(STATUS_LED); LED_Off(RX_LED); LED_On(TX_LED); break; case LED_EVENT_START_PEER_SEARCH: LED_Off(STATUS_LED); LED_Off(TX_LED); LED_Off(RX_LED); break; case LED_EVENT_PEER_SEARCH_DONE: LED_Off(TX_LED); LED_Off(RX_LED); LED_On(STATUS_LED); break; case LED_EVENT_ALL_ON: LED_On(STATUS_LED); LED_On(TX_LED); LED_On(RX_LED); break; case LED_EVENT_ALL_OFF: LED_Off(STATUS_LED); LED_Off(TX_LED); LED_Off(RX_LED); break; } #endif }
/** * \brief Timer Callback function if identify command is received on air * by a node in reflector configuration. This is used to blink the LED * and thus identify itself * * \param parameter pass parameters to timer handler */ void led_blinker_timer_handler_cb(void *parameter) { #if (LED_COUNT > 0) static uint8_t led_count; parameter = parameter; /* LED Blinking sequence is completed */ if (led_count > LED_BLINK_COUNT_FOR_IDENTIFY) { led_count = 0; app_led_event(LED_EVENT_PEER_SEARCH_DONE); } else { /* Blink count is not completed */ /* For every timeout switch off and on all LEDs alternatively **/ if (led_count & 0x01) { led_count++; app_led_event(LED_EVENT_ALL_OFF); sw_timer_stop(APP_TIMER_TO_TX); } else { led_count++; app_led_event(LED_EVENT_ALL_ON); } sw_timer_start(APP_TIMER_TO_TX, LED_BLINK_RATE_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_blinker_timer_handler_cb, NULL); } #endif return; }
/** * @brief Notify the application of the status of its request to start a *network. * * The NLME-START.confirm primitive allows the NLME to notify the application of * the status of its request to start a network. * * @param Status nwk status */ static void nlme_start_confirm(nwk_enum_t Status) { printf("Node start completed - %s (0x%.2X)\r\n", get_status_text((nwk_enum_t)Status), Status); if (node_status == STARTING) { printf("> Press Enter to return to main menu: \r\n"); node_status = IDLE; } if (node_status == ALL_IN_ONE_START) { printf("\tPush button pairing.\r\n"); printf( "\tPress SEL key then keeping SEL pressed press any FUNC key.\r\n"); printf( "\tThis starts the push button pairing at the remote controller.\r\n"); sw_timer_start(led_timer, 500000, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); LED_On(LED_NWK_SETUP); dev_type_t RecDevTypeList[DEVICE_TYPE_LIST_SIZE]; profile_id_t RecProfileIdList[PROFILE_ID_LIST_SIZE]; RecDevTypeList[0] = (dev_type_t)SUPPORTED_DEV_TYPE_0; RecProfileIdList[0] = SUPPORTED_PROFILE_ID_0; pbp_rec_pair_request(APP_CAPABILITIES, RecDevTypeList, RecProfileIdList, (FUNC_PTR)pbp_rec_pair_confirm ); } }
retval_t pal_timer_start(uint8_t timer_id, uint32_t timer_count, timeout_type_t timeout_type, FUNC_PTR timer_cb, void *param_cb) { uint8_t status; status = sw_timer_start(timer_id, timer_count, (sw_timeout_type_t)timeout_type, timer_cb, param_cb); if(ERR_TIMER_ALREADY_RUNNING == (status_code_t)status) { /* * Timer is already running if the callback function of the * corresponding timer index in the timer array is not NULL. */ return PAL_TMR_ALREADY_RUNNING; } if (STATUS_OK == (status_code_genare_t)status) { return MAC_SUCCESS; } return MAC_INVALID_PARAMETER; }
/* * @brief Callback function usr_mlme_comm_status_ind * * @param SrcAddrSpec Pointer to source address specification * @param DstAddrSpec Pointer to destination address specification * @param status Result for related response operation */ void usr_mlme_comm_status_ind(wpan_addr_spec_t *SrcAddrSpec, wpan_addr_spec_t *DstAddrSpec, uint8_t status) { if (status == MAC_SUCCESS) { #if (defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006) recent_assoc_dev_no++; wpan_mlme_set_req(macDeviceTableEntries, NO_PIB_INDEX, &no_of_assoc_devices); wpan_mlme_get_req(macKeyTable, recent_assoc_dev_no); #endif /* * Now the association of the device has been successful and its * information, like address, could be stored. * But for the sake of simple handling it has been done * during assignment of the short address within the function * assign_new_short_addr() */ /* Start timer to initiate indirect data transmission. */ sw_timer_start(APP_TIMER_INDIRECT_DATA, ((uint32_t)APP_INDIRECT_DATA_DURATION_MS * 1000), SW_TIMEOUT_RELATIVE, (FUNC_PTR)indirect_data_cb, NULL); } else { } /* Keep compiler happy. */ SrcAddrSpec = SrcAddrSpec; DstAddrSpec = DstAddrSpec; }
void usr_mlme_gts_ind(uint16_t DeviceAddr, gts_char_t GtsChar) { sw_timer_start(APP_TIMER_GTS_DATA, ((uint32_t)APP_GTS_DATA_DURATION_MS * 1000), SW_TIMEOUT_RELATIVE, (FUNC_PTR)gts_data_cb, NULL); DeviceAddr =DeviceAddr; GtsChar = GtsChar; }
/** * \brief Function to initialize wait for peer search conf state. * * This function * - Implements the peer search state machine. */ static void wait_for_conf_init(void *arg) { sw_timer_start(APP_TIMER_TO_TX, PEER_RESPONSE_TIMEOUT_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)app_peer_conf_tmr_handler_cb, NULL); /* Keep compiler happy */ arg = arg; }
/** * @brief Handles the rc command indications at terminal target. * * @param PairingRef Pairing reference * @param nsduLength Length of the payload. * @param nsdu Actual payload * @param RxLinkQuality Link quality of received packet. * @param RxFlags Rx Flags. */ static void zrc_cmd_indication(uint8_t PairingRef, uint8_t nsduLength, uint8_t *nsdu, uint8_t RxLinkQuality, uint8_t RxFlags) { zrc_cmd_frm_t *zrc_frm; if (node_status == POWER_SAVE) { printf("Leaving power save mode.\r\n"); nlme_rx_enable_request(RX_DURATION_INFINITY, (FUNC_PTR)nlme_rx_enable_confirm ); node_status = IDLE; } /* Switch LED on indicating data reception */ LED_On(LED_DATA); sw_timer_start(led_timer, 250000, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); /* Check with frame control field which kind of data is indicated */ zrc_frm = (zrc_cmd_frm_t *)nsdu; switch (zrc_frm->fcf) { case USER_CONTROL_PRESSED: { printf("Rx: "); printf("%s", zrc_print_rc_cmd_text(zrc_frm->rc_cmd)); printf(" Press (0x%.2X), ", zrc_frm->rc_cmd); printf("from %d, LQI = 0x%.2X\r\n", PairingRef, RxLinkQuality); } break; case USER_CONTROL_REPEATED: printf("Rx: "); zrc_print_rc_cmd_text(zrc_frm->rc_cmd); printf(" Repeat (0x%.2X), ", zrc_frm->rc_cmd); printf("from %d, LQI = 0x%.2X\r\n", PairingRef, RxLinkQuality); break; case USER_CONTROL_RELEASED: printf("Rx: "); zrc_print_rc_cmd_text(zrc_frm->rc_cmd); printf(" Release (0x%.2X), ", zrc_frm->rc_cmd); printf("from %d, LQI = 0x%.2X\r\n", PairingRef, RxLinkQuality); break; default: break; } /* Keep compiler happy */ nsduLength = nsduLength; RxFlags = RxFlags; }
/* * \brief Initialization of Range Measurement mode in RANGE_TX_ON State * * \param arg arguments to init RANGE_TX_ON state */ void range_test_tx_on_init(void *arg) { print_event(PRINT_RANGE_MEASURE_TX_START); /* Peer process seq number */ seq_num = rand(); sw_timer_start(APP_TIMER_TO_TX, APP_SEND_TEST_PKT_INTERVAL_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)range_test_tx_timer_handler_cb, NULL); /* Keep compiler happy */ arg = arg; }
/** * \brief This function is called to abort the packet streaming mode inprogress */ void stop_pkt_streaming(void * parameter) { pkt_stream_stop = true; sw_timer_stop(T_APP_TIMER); if(sw_timer_is_running(CW_TX_TIMER)) { sw_timer_stop(CW_TX_TIMER); } usr_pkt_stream_confirm(MAC_SUCCESS,false); if(node_info.main_state == PER_TEST_RECEPTOR) { sw_timer_start(T_APP_TIMER, LED_BLINK_RATE_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_blinker_timer_handler_cb, NULL); } }
void pulse_cw_transmission(void) { uint16_t channel; /*Start the Pulse CW Trx after the confirmation is sent*/ if(node_info.main_state == PER_TEST_RECEPTOR && !cw_ack_sent) { remote_pulse_cw_start = true; usr_cont_pulse_tx_confirm(MAC_SUCCESS); return; } remote_pulse_cw_start = false; cw_ack_sent = false; op_mode = CONTINUOUS_TX_MODE; tal_pib_get(phyCurrentChannel,(uint8_t *)&channel); /* Save all user settings before continuous tx */ save_all_settings(); tal_reset(false); #if (TAL_TYPE == AT86RF233) /* Set the frequency back to already set value after tal_reset */ if (CC_BAND_0 != cc_band_ct) { tal_set_frequency_regs(cc_band_ct, cc_number_ct); } #endif /* End of (TAL_TYPE == AT86RF233) */ /* Start the Continuous Wave transmission */ tfa_continuous_tx_start(CW_MODE, false); /* Start the timer to stop the Continuous transmission */ sw_timer_start(T_APP_TIMER, PULSE_CW_TX_TIME_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)stop_pulse_cb, NULL); }
/** * @brief Function to handle the LED States based on application state. * * * @param callback_parameter callback parameter if any. */ static void led_handling(void *callback_parameter) { switch (node_status) { case ZID_CONNECTING: case ALL_IN_ONE_START: sw_timer_start(APP_TIMER, PAIR_WAIT_PERIOD, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); LED_Toggle(LED_NWK_SETUP); break; default: sw_timer_stop(APP_TIMER); break; } /* Keep compiler happy */ callback_parameter = callback_parameter; }
/** * \brief Callback function that handles timer in Range Measurement Mode * * \param parameter pass parameters to timer handler */ static void range_test_tx_timer_handler_cb(void *parameter) { /* Make compiler happy */ parameter = parameter; /* Transmit range test frame on Air */ range_test_frame_tx(); /* Toggle the LED indicating transmission */ app_led_event(LED_EVENT_TX_FRAME); /* Increment the frames transmitted counter */ num_of_frames_send++; /* Restart the timer */ sw_timer_start(APP_TIMER_TO_TX, APP_SEND_TEST_PKT_INTERVAL_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)range_test_tx_timer_handler_cb, NULL); }
/* * \brief Stop CW transmission on current channel page * \param parameter Pointer to the variable which defines * the Continuous transmission mode */ void stop_cw_transmission(void *parameter) { uint8_t cw_mode; cw_mode = *(uint8_t *)parameter; /* Stop CW transmission again */ tfa_continuous_tx_stop(); /* recover all user setting which were set before continuous tx */ recover_all_settings(); op_mode = TX_OP_MODE; usr_cont_wave_tx_confirm(MAC_SUCCESS, STOP_CWT /*stop*/, cw_mode); remote_cw_start = false; if(node_info.main_state == PER_TEST_RECEPTOR) { sw_timer_start(T_APP_TIMER, LED_BLINK_RATE_IN_MICRO_SEC, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_blinker_timer_handler_cb, NULL); } }
/** * @brief LED handling including timer control . */ static void led_handling(void *callback_parameter) { switch (node_status) { case PUSH_BUTTON_PAIRING: case ALL_IN_ONE_START: sw_timer_start(led_timer, 500000, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); LED_Toggle(LED_NWK_SETUP); break; default: sw_timer_stop(led_timer); LED_Off(LED_DATA); LED_Off(LED_NWK_SETUP); break; } /* Keep compiler happy */ callback_parameter = callback_parameter; }
/** * @brief Notify the application of the status of its request to start the NWK. * * * @param Status nwk status */ static void nlme_start_confirm(nwk_enum_t Status) { if (Status == NWK_SUCCESS) { sw_timer_start(APP_TIMER, PAIR_WAIT_PERIOD, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); dev_type_t RecDevTypeList[DEVICE_TYPE_LIST_SIZE]; profile_id_t RecProfileIdList[PROFILE_ID_LIST_SIZE]; RecDevTypeList[0] = (dev_type_t)SUPPORTED_DEV_TYPE_0; RecProfileIdList[0] = SUPPORTED_PROFILE_ID_0; node_status = ZID_CONNECTING; zid_rec_connect_request(APP_CAPABILITIES, RecDevTypeList, RecProfileIdList, (FUNC_PTR)zid_connect_confirm ); } }
void start_cw_transmission(uint8_t tx_mode,uint16_t tmr_val) { /* If the test is initiated on the receptor node, First send the * Start confirmation back to the host. * Once this is done the test could be started. * The cw_ack_sent flag is used for this purpose */ if(node_info.main_state == PER_TEST_RECEPTOR && !cw_ack_sent) { /* timer value should not exceed 3600 seconds */ if((tx_mode !=CW_MODE && tx_mode != PRBS_MODE) || (3600 < tmr_val)) { usr_cont_wave_tx_confirm(INVALID_ARGUMENT, 0x01, tx_mode); return; } else { /* Send Set confirmation with status SUCCESS and start CW trx on * successful transmission of the Confirmation message*/ usr_cont_wave_tx_confirm(MAC_SUCCESS, START_CWT, tx_mode); remote_cw_start = true; cw_start_mode = tx_mode; cw_tmr_val = tmr_val; return; } } else if(node_info.main_state == PER_TEST_INITIATOR || (node_info.main_state == SINGLE_NODE_TESTS) || ((node_info.main_state == PER_TEST_RECEPTOR) && cw_ack_sent)) { /* Save all user settings before continuous tx */ save_all_settings(); /* Added to ensure CW transmission happen in every attempt */ tal_reset(false); #if (ANTENNA_DIVERSITY == 1) if (ANT_DIV_DISABLE == ant_div_before_ct) { tal_ant_div_config(ANT_DIVERSITY_DISABLE, ant_sel_before_ct); } #endif if((node_info.main_state == PER_TEST_RECEPTOR) && 1 <= tmr_val ) { sw_timer_start(CW_TX_TIMER, (uint32_t)tmr_val * 1E6, SW_TIMEOUT_RELATIVE, (FUNC_PTR)stop_cw_transmission, (void *)&tx_mode); } switch (tx_mode) { case CW_MODE: /* CW mode*/ { /* In CW_MODE the parameter random_content is obsolete. */ tfa_continuous_tx_start(CW_MODE, false); } break; case PRBS_MODE: /* PRBS mode*/ { /* Start PRBS_MODE mode using random content. */ tfa_continuous_tx_start(PRBS_MODE, true); } break; default: { usr_cont_wave_tx_confirm(INVALID_ARGUMENT, 0x01, tx_mode); return; } } op_mode = CONTINUOUS_TX_MODE; if(node_info.main_state == PER_TEST_RECEPTOR ) { cw_ack_sent=false; } else { /* Send Set confirmation with status SUCCESS */ usr_cont_wave_tx_confirm(MAC_SUCCESS, START_CWT, tx_mode); } } }
/** * @brief Handle keyboard input * * @param input_char character typed from input device. */ static void handle_input(uint8_t input_char) { /* We allow user input if we are either in IDLE state ot POWER_SAVE * state * In case of POWER_SAVE state, we allow only reset & disabling * POWER_SAVE req*/ if (((node_status != IDLE) && (node_status != POWER_SAVE)) || ((node_status == POWER_SAVE) && (!((input_char == 'Y') || (input_char == 'R') || (input_char == 'A') || (input_char == 'W') || (input_char == 0x0D))))) { printf( "Node is in power save mode.Press (R) to Reset/Press (Y) to Disable power save mode.\r\n"); return; } switch (input_char) { case 'Y': if (node_status == POWER_SAVE) { printf( "Leaving standby (power save mode). Press Enter to return to main menu.\r\n "); nlme_rx_enable_request(RX_DURATION_INFINITY, (FUNC_PTR)nlme_rx_enable_confirm ); node_status = IDLE; } else { printf( "Entering standby (power save mode). Press Enter to return to main menu.\r\n "); nlme_rx_enable_request(nwkcMinActivePeriod, (FUNC_PTR)nlme_rx_enable_confirm ); node_status = POWER_SAVE; } break; case 'R': printf("Reset node - \r\n"); node_status = RESETTING; ch_ag_enabled = false; nlme_reset_request(true, (FUNC_PTR)nlme_reset_confirm ); break; case 'S': printf("Start node - \r\n"); node_status = STARTING; nlme_start_request( (FUNC_PTR)nlme_start_confirm ); break; case 'P': printf("Push button pairing -\r\n"); node_status = PUSH_BUTTON_PAIRING; sw_timer_start(led_timer, 500000, SW_TIMEOUT_RELATIVE, (FUNC_PTR)led_handling, NULL); LED_On(LED_NWK_SETUP); { dev_type_t RecDevTypeList[DEVICE_TYPE_LIST_SIZE]; profile_id_t RecProfileIdList[PROFILE_ID_LIST_SIZE]; RecDevTypeList[0] = (dev_type_t)SUPPORTED_DEV_TYPE_0; RecProfileIdList[0] = SUPPORTED_PROFILE_ID_0; pbp_rec_pair_request(APP_CAPABILITIES, RecDevTypeList, RecProfileIdList, (FUNC_PTR)pbp_rec_pair_confirm ); } break; case 'A': printf("All-in-one start; wait until done.\r\n"); node_status = ALL_IN_ONE_START; printf("\tReset node - "); ch_ag_enabled = false; nlme_reset_request(true, (FUNC_PTR)nlme_reset_confirm ); break; case 'W': previous_node_status = node_status; printf("Warm start - \r\n"); node_status = WARM_STARTING; nlme_reset_request(false, (FUNC_PTR)nlme_reset_confirm ); break; case 'T': previous_node_status = node_status; node_status = PRINTING_PAIRING_TABLE; print_pairing_table(true, NULL, 0); break; case 'U': node_status = UNPAIRING; print_unpair_submenu(); break; case 'C': if (ch_ag_enabled) { ch_ag_enabled = false; nwk_ch_agility_request(AG_STOP, (FUNC_PTR)nwk_ch_agility_confirm ); printf(" - Channel agility is stopped ...\r\n"); } else { ch_ag_enabled = true; node_status = CH_AGILITY_EXECUTION; printf(" - Channel agility is started ...\r\n"); nwk_ch_agility_request(AG_PERIODIC, (FUNC_PTR)nwk_ch_agility_confirm ); } break; case 'O': /* Start getting the NIBs value */ node_status = GETTING_CH_AG_NIBS; nlme_get_request(nwkPrivateChAgEdThreshold, 0, (FUNC_PTR)nlme_get_confirm ); break; case 'B': print_ch_change_submenu(); break; case 'D': print_vendor_data_submenu(BATTERY_STATUS_REQ); break; case 'V': print_vendor_data_submenu(FW_VERSION_REQ); break; case 'Z': print_vendor_data_submenu(ALIVE_REQ); break; default: print_main_menu(); break; } }
/** * \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 Application task and state machine */ static void app_task(void) { switch (node_status) { case IDLE: { button_id_t button; static uint32_t current_time; static uint32_t previous_button_time; uint8_t num_records = 1; static button_id_t previous_button; keyboard_input_desc_t *joystick_desc; zid_report_data_record_t zid_report_data_joystick[2]; uint8_t report_data_buffer_joystick[80]; uint8_t *msg_ptr = &report_data_buffer_joystick[0]; if(button_mode == BUTTON_GAME_MODE) { /* Create the input report for the ppt control */ zid_report_data_joystick[0].report_type = INPUT; zid_report_data_joystick[0].report_desc_identifier = KEYBOARD; zid_report_data_joystick[0].report_data = (void *)msg_ptr; joystick_desc = (keyboard_input_desc_t *)msg_ptr; joystick_desc->modifier_keys = 0x00; joystick_desc->key_code[0] = 0x00; joystick_desc->key_code[1] = 0x00; joystick_desc->key_code[2] = 0x00; joystick_desc->key_code[3] = 0x00; joystick_desc->key_code[4] = 0x00; joystick_desc->key_code[5] = 0x00; uint16_t x_temp = x_val; uint16_t y_temp = y_val; if (y_temp > (ADC_val + APPX_5_DEGREE_VALUE)) { joystick_desc->key_code[2] = 1;//down y-axis negative } else if (y_temp < (ADC_val - APPX_5_DEGREE_VALUE)) { joystick_desc->key_code[2] = 2;//up y-axis positive } else if (x_temp > (ADC_val + APPX_5_DEGREE_VALUE)) { joystick_desc->key_code[2] = 3;//left x-axis negative } else if (x_temp < (ADC_val - APPX_5_DEGREE_VALUE)) { joystick_desc->key_code[2] = 4;//right x-axis positive } else { // } } /* Scan the button events */ button = button_scan(); /* Check if any valid vents occurred */ if ((button != BUTTON_UNKNOWN) && (button == previous_button)) { /* Check time to previous transmission. */ current_time= sw_timer_get_time(); if ((current_time - previous_button_time) < zid_interframe_duration) { return; } else { /* Check if the key press mode is mouse mode */ if(BUTTON_MOUSE_MODE == button_mode) { if(!((key_mapping_mouse[b_state] <= BUTTON_UP_E) && (BUTTON_RIGHT_E >= key_mapping_mouse[b_state]))) { /* Inter-frame duration for mouse will be less than the actual key events */ if((current_time - previous_button_time) < INTER_FRAME_DURATION_MOUSE_US) { return; } } } /* Store current time */ previous_button_time = current_time; } /* Get the key index value for the actual event */ b_state = get_zid_keyrc_button(button); /* Check any mode change event occurred */ switch(key_mapping_media[b_state]) { case BUTTON_MOUSE_MODE: /* Configure for the mouse mode */ button_mode = BUTTON_MOUSE_MODE; LED_On(LED_2); LED_Off(LED_3); LED_Off(LED_4); LED_Off(LED_5); zid_interframe_duration = INTER_FRAME_DURATION_MOUSE_US; return; break; case BUTTON_PPT_MODE: /* Configure for the ppt mode */ button_mode = BUTTON_PPT_MODE; LED_Off(LED_2); LED_On(LED_3); LED_Off(LED_4); LED_Off(LED_5); zid_interframe_duration = INTER_FRAME_DURATION_US; return; break; case BUTTON_GAME_MODE: /* Configure for the game controller mode. */ button_mode = BUTTON_GAME_MODE; LED_Off(LED_2); LED_Off(LED_3); LED_On(LED_4); LED_Off(LED_5); read_acc(&x_val,&y_val,&z_val,&ADC_val); app_calculate_offset(); Correct_x_offset(&x_val,x_offset); Correct_y_offset(&y_val,y_offset); sw_timer_start(APP_TIMER_ACC_READ,ACCELEROMETER_SAMPLE_TIME,SW_TIMEOUT_RELATIVE, (FUNC_PTR)acc_read_cb,NULL); zid_interframe_duration = INTER_FRAME_DURATION_US; return; break; case BUTTON_MEDIA_MODE: /* Configure for the media player control mode */ button_mode = BUTTON_MEDIA_MODE; LED_Off(LED_2); LED_Off(LED_3); LED_Off(LED_4); LED_On(LED_5); zid_interframe_duration = INTER_FRAME_DURATION_US; return; break; default: LED_On(LED_1); break; } if(button_mode == BUTTON_MEDIA_MODE) { /* get the valid key inputs for the media player control */ zid_report_data_record_t zid_report_data[2]; uint8_t report_data_buffer[80]; uint8_t *msg_ptr = &report_data_buffer[0]; if(key_mapping_media[b_state] == BUTTON_INVALID) { return; } /* Create the input report for the media player control */ zid_report_data[0].report_type = INPUT; zid_report_data[0].report_desc_identifier = KEYBOARD; zid_report_data[0].report_data = (void *)msg_ptr; keyboard_input_desc_t *keyboard_input_desc; keyboard_input_desc = (keyboard_input_desc_t *)msg_ptr; keyboard_input_desc->modifier_keys = 0x00; keyboard_input_desc->key_code[0] = 0x00; keyboard_input_desc->key_code[1] = 0x00; keyboard_input_desc->key_code[2] = 0x00; keyboard_input_desc->key_code[3] = 0x00; keyboard_input_desc->key_code[4] = (uint8_t)key_mapping_media[b_state]; keyboard_input_desc->key_code[5] = (uint8_t)(key_mapping_media[b_state] >> 8); num_records = 1; if (zid_report_data_request(pairing_ref,num_records, zid_report_data, TX_OPTIONS #ifdef RF4CE_CALLBACK_PARAM ,(FUNC_PTR)zid_report_data_confirm #endif )) { node_status = TRANSMITTING; } } else if(button_mode == BUTTON_PPT_MODE) { /* get the valid key inputs for the ppt mode */ zid_report_data_record_t zid_report_data[2]; uint8_t report_data_buffer[80]; uint8_t *msg_ptr = &report_data_buffer[0]; if(key_mapping_ppt[b_state] == BUTTON_INVALID) { return; } /* Create the input report for the ppt control */ zid_report_data[0].report_type = INPUT; zid_report_data[0].report_desc_identifier = KEYBOARD; zid_report_data[0].report_data = (void *)msg_ptr; keyboard_input_desc_t *keyboard_input_desc; keyboard_input_desc = (keyboard_input_desc_t *)msg_ptr; keyboard_input_desc->modifier_keys = 0x00; keyboard_input_desc->key_code[0] = key_mapping_ppt[b_state]; keyboard_input_desc->key_code[1] = 0x00; keyboard_input_desc->key_code[2] = 0x00; keyboard_input_desc->key_code[3] = 0x00; keyboard_input_desc->key_code[4] = 0x00; keyboard_input_desc->key_code[5] = 0x00; num_records = 1; if (zid_report_data_request(pairing_ref,num_records, zid_report_data, TX_OPTIONS #ifdef RF4CE_CALLBACK_PARAM ,(FUNC_PTR)zid_report_data_confirm #endif )) { node_status = TRANSMITTING; b_state = BUTTON_INVALID; } } else if(button_mode == BUTTON_MOUSE_MODE) { /* get the valid key inputs for the mouse mode */ zid_report_data_record_t zid_report_data[2]; uint8_t report_data_buffer[80]; uint8_t *msg_ptr = &report_data_buffer[0]; mouse_desc_t *mouse_desc; if(key_mapping_mouse[b_state] == BUTTON_INVALID) { return; } /* Create the input report for the mouse control */ zid_report_data[0].report_type = INPUT; zid_report_data[0].report_desc_identifier = MOUSE; zid_report_data[0].report_data = (void *)msg_ptr; mouse_desc = (mouse_desc_t *)msg_ptr; mouse_desc->button0 = 0x00; mouse_desc->button1 = 0x00; mouse_desc->button2 = 0x00; mouse_desc->x_coordinate = 0x00; mouse_desc->y_coordinate = 0x00; switch(key_mapping_mouse[b_state]) { case BUTTON_UP_E: mouse_desc->y_coordinate = MOUSE_NEGATIVE_DISPLACEMENT; break; case BUTTON_LEFT_E: mouse_desc->x_coordinate = MOUSE_NEGATIVE_DISPLACEMENT; break; case BUTTON_RIGHT_E: mouse_desc->x_coordinate = MOUSE_POSITIVE_DISPLACEMENT; break; case BUTTON_DOWN_E: mouse_desc->y_coordinate = MOUSE_POSITIVE_DISPLACEMENT; break; case BUTTON_LEFT_SINGLE_CLK: mouse_desc->button0 = 0x01; break; case BUTTON_RIGHT_SINGLE_CLK: mouse_desc->button1 = 0x01; break; case BUTTON_MIDDLE_CLK: mouse_desc->button2 = 0x01; break; case BUTTON_SCROLL_UP: mouse_desc->y_coordinate = 1; mouse_desc->button2 = 0x80; break; case BUTTON_SCROLL_DOWN: mouse_desc->x_coordinate = -1; mouse_desc->button2 = 0x80; break; default: break; } msg_ptr += sizeof(mouse_desc_t); num_records = 1; if (zid_report_data_request(pairing_ref, num_records, zid_report_data, TX_OPTIONS #ifdef RF4CE_CALLBACK_PARAM ,(FUNC_PTR)zid_report_data_confirm #endif )) { node_status = TRANSMITTING; b_state = BUTTON_INVALID; } } else if(button_mode == BUTTON_GAME_MODE) { if(key_mapping_gamepad[b_state] == BUTTON_INVALID) { return; } switch(key_mapping_gamepad[b_state]) { case BUTTON_1: case BUTTON_2: case BUTTON_3: case BUTTON_4: joystick_desc->key_code[0]=key_mapping_gamepad[b_state]; break; case BUTTON_THROTTLE_UP: joystick_desc->key_code[1]=0x01; break; case BUTTON_THROTTLE_DOWN: joystick_desc->key_code[1]=0x02; default: break; } num_records = 1; } }