/************************************************************************************************** * CONSTANTS **************************************************************************************************/ #define HAL_KEY_RISING_EDGE 0 #define HAL_KEY_FALLING_EDGE 1 #define HAL_KEY_DEBOUNCE_VALUE 25 /* CPU port interrupt */ #define HAL_KEY_CPU_PORT_0_IF P0IF #define HAL_KEY_CPU_PORT_1_IF P1IF #define HAL_KEY_CPU_PORT_2_IF P2IF /* SW_6 is at P0.1 */ #define HAL_KEY_SW_1_PORT P2 #define HAL_KEY_SW_1_BIT BV(0) #define HAL_KEY_SW_1_SEL P2SEL #define HAL_KEY_SW_1_DIR P2DIR /* edge interrupt */ #define HAL_KEY_SW_1_EDGEBIT BV(3) #define HAL_KEY_SW_1_EDGE HAL_KEY_RISING_EDGE /* SW_6 interrupts */ #define HAL_KEY_SW_1_IEN IEN2 /* CPU interrupt mask register */ #define HAL_KEY_SW_1_IENBIT BV(1) /* Mask bit for all of Port_0 */ #define HAL_KEY_SW_1_ICTL P2IEN /* Port Interrupt Control register */ #define HAL_KEY_SW_1_ICTLBIT BV(0) /* P0IEN - P0.1 enable/disable bit */ #define HAL_KEY_SW_1_PXIFG P2IFG /* Interrupt flag at source */ //////////////////////////////////////////////////////////////////////// /* SW_2 is at P1.7 */ #define HAL_KEY_SW_2_PORT P1 #define HAL_KEY_SW_2_BIT BV(7) #define HAL_KEY_SW_2_SEL P1SEL #define HAL_KEY_SW_2_DIR P1DIR /* edge interrupt */ #define HAL_KEY_SW_2_EDGEBIT BV(2) #define HAL_KEY_SW_2_EDGE HAL_KEY_RISING_EDGE /* SW_2 interrupts */ #define HAL_KEY_SW_2_IEN IEN2 /* CPU interrupt mask register */ #define HAL_KEY_SW_2_IENBIT BV(4) /* Mask bit for all of Port_1 */ #define HAL_KEY_SW_2_ICTL P1IEN /* Port Interrupt Control register */ #define HAL_KEY_SW_2_ICTLBIT BV(7) /* P0IEN - P1.6 enable/disable bit */ #define HAL_KEY_SW_2_PXIFG P1IFG /* Interrupt flag at source */ //////////////////////////////////////////////////////////////////////// #define port P1_7 /************************************************************************************************** * TYPEDEFS **************************************************************************************************/ /************************************************************************************************** * GLOBAL VARIABLES **************************************************************************************************/ static uint8 halKeySavedKeys; /* used to store previous key state in polling mode */ static halKeyCBack_t pHalKeyProcessFunction; static uint8 HalKeyConfigured; bool Hal_KeyIntEnable; /* interrupt enable/disable flag */ /************************************************************************************************** * FUNCTIONS - Local **************************************************************************************************/ void halProcessKeyInterrupt(void); uint8 halGetJoyKeyInput(void); /************************************************************************************************** * FUNCTIONS - API **************************************************************************************************/ /************************************************************************************************** * @fn HalKeyInit * * @brief Initilize Key Service * * @param none * * @return None **************************************************************************************************/ void HalKeyInit( void ) { /* Initialize previous key to 0 */ halKeySavedKeys = 0; HAL_KEY_SW_1_SEL &= ~(HAL_KEY_SW_1_BIT); /* Set pin function to GPIO */ HAL_KEY_SW_1_DIR &= ~(HAL_KEY_SW_1_BIT); /* Set pin direction to Input */ HAL_KEY_SW_2_SEL &= ~(HAL_KEY_SW_2_BIT); /* Set pin function to GPIO */ HAL_KEY_SW_2_DIR &= ~(HAL_KEY_SW_2_BIT); /* Set pin direction to Input */ /* Initialize callback function */ pHalKeyProcessFunction = NULL; /* Start with key is not configured */ HalKeyConfigured = FALSE; } /************************************************************************************************** * @fn HalKeyConfig * * @brief Configure the Key serivce * * @param interruptEnable - TRUE/FALSE, enable/disable interrupt * cback - pointer to the CallBack function * * @return None **************************************************************************************************/ void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback) { /* Enable/Disable Interrupt or */ Hal_KeyIntEnable = interruptEnable; /* Register the callback fucntion */ pHalKeyProcessFunction = cback; /* Determine if interrupt is enable or not */ if (Hal_KeyIntEnable) { /* Rising/Falling edge configuratinn */ PICTL &= ~(HAL_KEY_SW_1_EDGEBIT); /* Clear the edge bit */ /* For falling edge, the bit must be set. */ #if (HAL_KEY_SW_1_EDGE == HAL_KEY_FALLING_EDGE) PICTL |= HAL_KEY_SW_1_EDGEBIT; #endif /* Interrupt configuration: * - Enable interrupt generation at the port * - Enable CPU interrupt * - Clear any pending interrupt */ HAL_KEY_SW_1_ICTL |= HAL_KEY_SW_1_ICTLBIT; HAL_KEY_SW_1_IEN |= HAL_KEY_SW_1_IENBIT; HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); PICTL &= ~(HAL_KEY_SW_2_EDGEBIT); /* Clear the edge bit SW_7*/ /* For falling edge, the bit must be set. */ #if (HAL_KEY_SW_2_EDGE == HAL_KEY_FALLING_EDGE) PICTL |= HAL_KEY_SW_2_EDGEBIT; #endif /* Interrupt configuration: SW_7 * - Enable interrupt generation at the port * - Enable CPU interrupt * - Clear any pending interrupt */ HAL_KEY_SW_2_ICTL |= HAL_KEY_SW_2_ICTLBIT; HAL_KEY_SW_2_IEN |= HAL_KEY_SW_2_IENBIT; HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Do this only after the hal_key is configured - to work with sleep stuff */ if (HalKeyConfigured == TRUE) { osal_stop_timerEx(Hal_TaskID, HAL_KEY_EVENT); /* Cancel polling if active */ } } else /* Interrupts NOT enabled */ { HAL_KEY_SW_1_ICTL &= ~(HAL_KEY_SW_1_ICTLBIT); /* don't generate interrupt */ HAL_KEY_SW_1_IEN &= ~(HAL_KEY_SW_1_IENBIT); /* Clear interrupt enable bit */ HAL_KEY_SW_2_ICTL &= ~(HAL_KEY_SW_2_ICTLBIT); /* don't generate interrupt */ HAL_KEY_SW_2_IEN &= ~(HAL_KEY_SW_2_IENBIT); /* Clear interrupt enable bit */ osal_set_event(Hal_TaskID, HAL_KEY_EVENT); } /* Key now is configured */ HalKeyConfigured = TRUE; } /************************************************************************************************** * @fn HalKeyRead * * @brief Read the current value of a key * * @param None * * @return keys - current keys status **************************************************************************************************/ uint8 HalKeyRead ( void ) { uint8 keys = 0; if (HAL_PUSH_BUTTON1()) { keys |= HAL_KEY_SW_1; } if (port==1) { keys |= HAL_KEY_SW_2; } return keys; } /************************************************************************************************** * @fn HalKeyPoll * * @brief Called by hal_driver to poll the keys * * @param None * * @return None **************************************************************************************************/ void HalKeyPoll (void) { uint8 keys = 0; /* 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; } /* Store the current keys for comparation next time */ halKeySavedKeys = keys; } else { /* Key interrupt handled here */ } if (HAL_PUSH_BUTTON1()) { keys |= HAL_KEY_SW_1; } if (port==1) { keys |= HAL_KEY_SW_2; } /* Invoke Callback if new keys were depressed */ if (keys && (pHalKeyProcessFunction)) { (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); } } /************************************************************************************************** * @fn halGetJoyKeyInput * * @brief Map the ADC value to its corresponding key. * * @param None * * @return keys - current joy key status **************************************************************************************************/ /************************************************************************************************** * @fn halProcessKeyInterrupt * * @brief Checks to see if it's a valid key interrupt, saves interrupt driven key states for * processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later. * * @param * * @return **************************************************************************************************/ void halProcessKeyInterrupt (void) { bool valid=FALSE; if (HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) /* Interrupt Flag has been set */ { HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear Interrupt Flag */ valid = TRUE; } if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT) /* Interrupt Flag has been set */ { HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear Interrupt Flag */ valid = TRUE; } if (valid) { osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE); } } /************************************************************************************************** * @fn HalKeyEnterSleep * * @brief - Get called to enter sleep mode * * @param * * @return **************************************************************************************************/ void HalKeyEnterSleep ( void ) { } /************************************************************************************************** * @fn HalKeyExitSleep * * @brief - Get called when sleep is over * * @param * * @return - return saved keys **************************************************************************************************/ uint8 HalKeyExitSleep ( void ) { /* Wake up and read keys */ return ( HalKeyRead () ); } /*************************************************************************************************** * INTERRUPT SERVICE ROUTINE ***************************************************************************************************/ /************************************************************************************************** * @fn halKeyPort0Isr * * @brief Port0 ISR * * @param * * @return **************************************************************************************************/ HAL_ISR_FUNCTION( halKeyPort1Isr, P1INT_VECTOR ) { HAL_ENTER_ISR(); if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT) { halProcessKeyInterrupt(); } /* Clear the CPU interrupt flag for Port_0 PxIFG has to be cleared before PxIF */ HAL_KEY_SW_2_PXIFG = 0; HAL_KEY_CPU_PORT_1_IF = 0; CLEAR_SLEEP_MODE(); HAL_EXIT_ISR(); } /************************************************************************************************** * @fn halKeyPort2Isr * * @brief Port2 ISR * * @param * * @return **************************************************************************************************/ HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR ) { HAL_ENTER_ISR(); if (HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) { halProcessKeyInterrupt(); } /* Clear the CPU interrupt flag for Port_2 PxIFG has to be cleared before PxIF Notes: P2_1 and P2_2 are debug lines. */ HAL_KEY_SW_1_PXIFG = 0; HAL_KEY_CPU_PORT_2_IF = 0; CLEAR_SLEEP_MODE(); HAL_EXIT_ISR(); } #else void HalKeyInit(void){} void HalKeyConfig(bool interruptEnable, halKeyCBack_t cback){} uint8 HalKeyRead(void){ return 0;} void HalKeyPoll(void){} #endif /* HAL_KEY */