/********************************************************************* * @fn zclHomelink_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * * @return none */ static void zclHomelink_HandleKeys( byte shift, byte keys ) { if ((keys & (HAL_KEY_SW_2 | HAL_KEY_SW_3 | HAL_KEY_SW_4)) == (HAL_KEY_SW_2 | HAL_KEY_SW_3 | HAL_KEY_SW_4)) // Press all three for one second to reset device { // Check if keys still pressed after 500 ms debounce delay (in hal_key.c) if ((HalKeyRead() & (HAL_KEY_SW_2 | HAL_KEY_SW_3 | HAL_KEY_SW_4)) == (HAL_KEY_SW_2 | HAL_KEY_SW_3 | HAL_KEY_SW_4)) { zclHomelink_zigbeeReset(); } return; } osal_stop_timerEx(zclHomelink_TaskID, HOMELINK_RESET_EVT); // Check if any keys still pressed after 800 ms debounce delay (in hal_key.c) if (HalKeyRead() & (HAL_KEY_SW_2 | HAL_KEY_SW_3 | HAL_KEY_SW_4)) { // If so do nothing, probably programming mode } else if (keys & HAL_KEY_SW_2) { if (osal_get_timeoutEx(zclHomelink_TaskID, HOMELINK_SW2_EVT) == 0) { zclHomelink_SendCmdToggle(ENDPOINT); } osal_start_timerEx( zclHomelink_TaskID, HOMELINK_SW2_EVT, HOMELINK_SW_BLANKING ); } else if (keys & HAL_KEY_SW_3) { if (osal_get_timeoutEx(zclHomelink_TaskID, HOMELINK_SW3_EVT) == 0) { zclHomelink_SendCmdToggle(ENDPOINT+1); } osal_start_timerEx( zclHomelink_TaskID, HOMELINK_SW3_EVT, HOMELINK_SW_BLANKING ); } else if (keys & HAL_KEY_SW_4) { if (osal_get_timeoutEx(zclHomelink_TaskID, HOMELINK_SW4_EVT) == 0) { zclHomelink_SendCmdToggle(ENDPOINT+2); } osal_start_timerEx( zclHomelink_TaskID, HOMELINK_SW4_EVT, HOMELINK_SW_BLANKING ); } }
/************************************************************************************************** * @fn HalKeyPoll * * @brief Called by hal_driver to poll the keys * * @param None * * @return None **************************************************************************************************/ void HalKeyPoll (void) { #if (HAL_KEY == TRUE) uint8 keys = 0; /* * If interrupts are enabled, get the status of the interrupt-driven keys from 'halSaveIntKey' * which is updated by the key ISR. If Polling, read these keys directly. */ keys = HalKeyRead(); /* Exit if polling and no keys have changed */ if (!Hal_KeyIntEnable) { if (keys == halKeySavedKeys) { return; } halKeySavedKeys = keys; /* Store the current keys for comparation next time */ } /* Invoke Callback if new keys were depressed */ if ((keys != HAL_KEY_CODE_NOKEY || Hal_KeyIntEnable) && (pHalKeyProcessFunction)) { // When interrupt is enabled, send HAL_KEY_CODE_NOKEY as well so that // application would know the previous key is no longer depressed. (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); } if (Hal_KeyIntEnable) { if (keys != HAL_KEY_CODE_NOKEY) { // In order to trigger callback again as far as the key is depressed, // timer is called here. osal_start_timerEx(Hal_TaskID, HAL_KEY_EVENT, 50); } else { halKeyTimerRunning = FALSE; } } #endif /* HAL_KEY */ }
/********************************************************************* * @fn SAPI_Init * * @brief Initialization function for the Simple API Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notification ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void SAPI_Init( byte task_id ) { sapi_TaskID = task_id; sapi_bindInProgress = 0xffff; sapi_epDesc.task_id = &sapi_TaskID; sapi_epDesc.endPoint = 0; #if ( SAPI_CB_FUNC ) sapi_epDesc.endPoint = zb_SimpleDesc.EndPoint; sapi_epDesc.task_id = &sapi_TaskID; sapi_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&zb_SimpleDesc; sapi_epDesc.latencyReq = noLatencyReqs; // Register the endpoint/interface description with the AF afRegister( &sapi_epDesc ); #endif // Turn off match descriptor response by default afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE); // Register callback evetns from the ZDApp ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp ); ZDO_RegisterForZDOMsg( sapi_TaskID, Match_Desc_rsp ); #if ( SAPI_CB_FUNC ) #if (defined HAL_KEY) && (HAL_KEY == TRUE) // Register for HAL events RegisterForKeys( sapi_TaskID ); if ( HalKeyRead () == HAL_KEY_SW_5) { // If SW5 is pressed and held while powerup, force auto-start and nv-restore off and reset uint8 startOptions = ZCD_STARTOPT_CLEAR_STATE | ZCD_STARTOPT_CLEAR_CONFIG; zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions ); zb_SystemReset(); } #endif // HAL_KEY // Set an event to start the application osal_set_event(task_id, ZB_ENTRY_EVENT); #endif }
/************************************************************************************************** * @fn HalKeyPoll * * @brief This function is called by Hal_ProcessEvent() on a HAL_KEY_EVENT. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void HalKeyPoll(void) { uint8 newKeys; if (Hal_KeyIntEnable) { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); newKeys = isrKeys; isrKeys = 0; HAL_EXIT_CRITICAL_SECTION(intState); } else { uint8 keys = HalKeyRead(); newKeys = (halKeys ^ keys) & keys; halKeys = keys; } if (newKeys && pHalKeyProcessFunction) { (pHalKeyProcessFunction)(newKeys, HAL_KEY_STATE_NORMAL); } }
/************************************************************************************************** * @fn HalKeyExitSleep * * @brief - Get called when sleep is over * * @param * * @return - return saved keys **************************************************************************************************/ uint8 HalKeyExitSleep ( void ) { /* Wake up and read keys */ return ( HalKeyRead () ); }
/************************************************************************************************** * @fn HalKeyExitSleep * * @brief - Get called when sleep is over * * @param * * @return - return saved keys **************************************************************************************************/ uint8 HalKeyExitSleep ( void ) { return ( HalKeyRead () ); }
/************************************************************************************************** * @fn HalKeyPoll * * @brief Called by hal_driver to poll the keys * * @param None * * @return None **************************************************************************************************/ void HalKeyPoll (void) { uint8 keysbounce = 0; keystate = HalKeyRead();// read the key hal_key_mode now keysbounce = HalKeyBounce();// read the key bounce now /* If interrupts are not enabled, previous key status and current key status * are compared to find out if a key has changed status. */ if (!Hal_KeyIntEnable) { // exit the double_hit mode if(hal_key_mode == 0x03) { (pHalKeyProcessFunction) (keysbounce, HAL_KEY_STATE_EIXT_DOUBLE_HIT); hal_key_mode = 0x00; } /* Store the current keys for comparation next time */ halKeySavedKeystate = keystate; /* Invoke Callback if new keys were depressed */ if (keysbounce && (pHalKeyProcessFunction)) { /***********************whether the double_hit mode************/ if( (keysbounce == halKeySavedKeybounce) && ( (keysbounce & HAL_KEY_DEC) || (keysbounce & HAL_KEY_INC) ) && (hal_key_mode == 0x00) // only can double hit in the normal mode )// the same key depressed { //if the gap is less than the MAX_DOUBLE_HIT_GAP, the key double hit if(key_depressed_gap < MAX_DOUBLE_HIT_GAP) { double_hit = TRUE; //double_hit_count++; //and start the count for next double hit } } /***********************whether the double_hit mode************/ // only save the kesbounce when the key depressed halKeySavedKeybounce = keysbounce; if(keystate & HAL_KEY_PWR) // the shift is pressed ,another key is depressed { (pHalKeyProcessFunction) (keysbounce, HAL_KEY_STATE_SHIFT); hal_key_mode = 0x01; } else // not the shift hal_key_mode or exit the shift hal_key_mode { if(hal_key_mode == 0x01)// in the shift hal_key_mode, the shift depressed //will create the shiftevent(exit the shift hal_key_mode) { //keys &= ~HAL_KEY_PWR; hal_key_mode = 0x00; (pHalKeyProcessFunction) (keysbounce, HAL_KEY_STATE_SHIFTBOUNCE); } else { (pHalKeyProcessFunction) (keysbounce, HAL_KEY_STATE_NORMAL); } } } } else { ; /* Key interrupt handled here */ } // the maxium gap between the depressed if(key_depressed_gap >= MAX_DOUBLE_HIT_GAP) { // exit the double_hit mode only when the double_hit // change from TRUE to FALSE if(double_hit) { hal_key_mode = 0x03; } key_depressed_gap = MAX_DOUBLE_HIT_GAP - 1; double_hit = FALSE;//the gap is the maxium value,can never be double hit } if(keysbounce)// clear the gap between the key depressed ,recount the gap { key_depressed_gap = 0; } key_depressed_gap++;// the (double_hit_gap * 100) ms between the keys // depressed }
/********************************************************************* * @fn TimeApp_Init * * @brief Initialization function for the Time App App Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notificaiton ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void TimeApp_Init( uint8 task_id ) { timeAppTaskId = task_id; // Setup the GAP Peripheral Role Profile { uint8 advEnable = FALSE; uint16 advertOffTime = 0; uint8 updateRequest = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 minInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 maxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 slaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 connTimeout = DEFAULT_DESIRED_CONN_TIMEOUT; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advEnable ); GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &advertOffTime ); GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &updateRequest ); GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &minInterval ); GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &maxInterval ); GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &slaveLatency ); GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &connTimeout ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( timeAppScanData ), timeAppScanData ); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( timeAppAdvData ), timeAppAdvData ); } // Setup GAP GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, timeAppDeviceName ); // Setup the GAP Bond Manager { uint32 passkey = DEFAULT_PASSCODE; uint8 pairMode = DEFAULT_PAIRING_MODE; uint8 mitm = DEFAULT_MITM_MODE; uint8 ioCap = DEFAULT_IO_CAPABILITIES; uint8 bonding = DEFAULT_BONDING_MODE; GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey ); GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof( uint8 ), &bonding ); } // Initialize GATT Client VOID GATT_InitClient(); // Register to receive incoming ATT Indications/Notifications GATT_RegisterForInd( timeAppTaskId ); // Initialize GATT attributes GGS_AddService( GATT_ALL_SERVICES ); // GAP GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes // Register for all key events - This app will handle all key events RegisterForKeys( timeAppTaskId ); // makes sure LEDs are off HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF ); // If key pressed on startup clear all stored bonds if ( HalKeyRead() & HAL_KEY_CENTER ) { GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, 0 ); } // Start clock update timer osal_start_timerEx( timeAppTaskId, CLOCK_UPDATE_EVT, DEFAULT_CLOCK_UPDATE_PERIOD ); // Setup a delayed profile startup osal_set_event( timeAppTaskId, START_DEVICE_EVT ); }
/************************************************************************************************** * @fn processKey * * @brief * * @param none * * @return None **************************************************************************************************/ void processKey(void) { uint8 keys = 0; // uint8 notify = 0; // uint8 event_id = HAL_KEY_EVENT_INVALID; keys = HalKeyRead(); #if 1 /* If interrupts are not enabled, previous key status and current key status * are compared to find out if a key has changed status. */ if (!Hal_KeyIntEnable) { if (keys == halKeySavedKeys) { /* Exit - since no keys have changed */ return; } else { // notify = 1; } } else { /* Key interrupt handled here */ if (keys) { // notify = 1; } } #endif #if 0 counter++; //long push if( (keys & HAL_KEY_SW_1) && (counter > HAL_KEY_LONG_PUSH) ) { counter = 0; event_id = HAL_KEY_EVENT_LONG; keyStatus = HAL_KEY_EVENT_LONG; } //short push if( (keys & HAL_KEY_SW_1) && counter >= 2 ) { event_id = HAL_KEY_EVENT_DOWN; } if( !(keys & HAL_KEY_SW_1) && (counter >=2 && counter < HAL_KEY_LONG_PUSH)) { counter = 0; event_id = HAL_KEY_EVENT_SHORT; } if( !(keys & HAL_KEY_SW_1) && (event_id == HAL_KEY_EVENT_INVALID) ) { counter = 0; if( keyStatus == HAL_KEY_EVENT_LONG ) { HalLedSet(HAL_LED_R, HAL_LED_MODE_OFF); } event_id = HAL_KEY_EVENT_UP; } if( event_id != HAL_KEY_EVENT_INVALID ) { if(key_event_tbl[event_id]) key_event_tbl[event_id](); } #endif if( keys & HAL_USB_DETECT_SW ) // exit power on { if( HAL_CHARGE_EVENT_FINISHED == chargeStatus) { HalLedSet(HAL_LED_G, HAL_LED_MODE_ON); } else { chargeStatus = HAL_CHARGE_EVENT_CHARGING; if( HAL_CHARGE_EVENT_CHARGING == chargeStatus ) { HalLedSet(HAL_LED_R, HAL_LED_MODE_ON); } } } else if( !(keys & HAL_USB_DETECT_SW )) // exit power off { chargeStatus = HAL_CHARGE_EVENT_OFF; if( HAL_CHARGE_EVENT_OFF == chargeStatus ) { HalLedSet(HAL_LED_R, HAL_LED_MODE_OFF); HalLedSet(HAL_LED_G, HAL_LED_MODE_OFF); } } if( keys & HAL_CHG_STATUS_SW ) // charge finished { /* chargeStatus = HAL_CHARGE_EVENT_FINISHED; if( HAL_CHARGE_EVENT_FINISHED == chargeStatus ) { HalLedSet(HAL_LED_R, HAL_LED_MODE_OFF); HalLedSet(HAL_LED_G, HAL_LED_MODE_ON); }*/ } /* Store the current keys for comparation next time */ halKeySavedKeys = keys; }