This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OnBoard_KeyCallBack CC2540

Other Parts Discussed in Thread: CC2540

Holla. I have a question about the void OnBoard_KeyCallBack, is this an interrupt? If yes how can I use it? Since my teacher told me configure the switch using this OnBoard_KeyCallBack, is it possible to do that?

  • OnBoard_KeyCallBack is just a callback function which would be called once there is key event sent from hal_key.c.
  • Ah, so it cannot use as interrupt something like that? And does it mean it basically serve only the key event for hal_key.c?

  • You can refer to the red codes in InitBoard(). You should use HalKeyConfig to enable interrupt and connect OnBoard_KeyCallback.

    void InitBoard( uint8 level )
    {
      if ( level == OB_COLD )
      {
        // Interrupts off
        osal_int_disable( INTS_ALL );
        // Turn all LEDs off
        HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );
        // Check for Brown-Out reset
    //    ChkReset();
      }
      else  // !OB_COLD
      {
        /* Initialize Key stuff */
        OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
        HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
      }
    }

  • You are welcome.
  • That means I need to type the code I want into this HalKeyConfig function? Can you tell me more about this? I am a little bit confuse
  • I don't think you have to type anything. If you set "OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;" and call "HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);", HalKeyPoll will call OnBoard_KeyCallback when there is a key interrupt.
  • Oh I see, but all the things run in the keyfobdemo right? Can I call these functions in keyfobdemo?
  • I don't understand your question. Can you elaborate?
  • Sorry for the late reply and I have few questions, hope you can help me a bit.

    1. Since the "HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);" and " OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;" is inside Onboard.c , that means I can only use this function in Onboard.c only right?

    2. void OnBoard_KeyCallback ( uint8 keys, uint8 state )

    {

     uint8 shift;

     (void)state;

     // shift key (S1) is used to generate key interrupt

     // applications should not use S1 when key interrupt is enabled

     shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);

     if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )

     {

       // Process SW1 here

       if ( keys & HAL_KEY_SW_1 )  // Switch 1

       {

       }

       // Process SW2 here

       if ( keys & HAL_KEY_SW_2 )  // Switch 2

       {

       }

       // Process SW3 here

       if ( keys & HAL_KEY_SW_3 )  // Switch 3

       {      

       }

       // Process SW4 here

       if ( keys & HAL_KEY_SW_4 )  // Switch 4

       {

       }

       // Process SW5 here

       if ( keys & HAL_KEY_SW_5 )  // Switch 5

       {

       }

       // Process SW6 here

       if ( keys & HAL_KEY_SW_6 )  // Switch 6

       {

       }

     }

     /* If any key is currently pressed down and interrupt

        is still enabled, disable interrupt and switch to polling */

     if( keys != 0 )

     {

       if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )

       {

         OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;

         HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

       }

     }

     /* If no key is currently pressed down and interrupt

        is disabled, enable interrupt and turn off polling */

     else

     {

       if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )

       {

         OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;

         HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

       }

     }

    }


    There are few questions regarding the code above, the 1st question is the blue code. Izzit the code means if the input cannot be detected , it will be process under the if ( keys & HAL_KEY_SW_4 ) there? But why inside it is empty?

    Then the red code, why we need to disable the interrupt if the key is pressed down and enable the interrupt when there is no key is pressed down?

    Hope you can answer me and sorry for those silly questions >.<

  • 1. OnBoard_SendKeys would transfer key event to application layer. Usually, we prefer to handle key event in application level instead of osal level so those blue lines are left empty.
    2. Since we already detect key is pressed and is processing it, we don't need to detect interrupt again in this period. That's why we would disable the interrupt if the key is pressed down.
  • Thanks for your reply and your answer is clear for me!!!

    One more thing, if I want to use  OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE; and HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); for my switch, means I can only used it in Onboard.c since it is declare inside Onboard.c ?

  • It's declare as extern function in hal_key.h so you can use HalKeyConfig anywhere. But, we usually do it in Onboard.c.
  • Hey Yikai, I am not sure whether the interrupt will work or not if I put like this. My code is like this and I hope you can gimme some answer, I put the code in Onboard.c

    void InitBoard( uint8 level )

    {

     P1SEL = 0x00;

     P1DIR = 0x03;

     P2SEL = 0x00;

     P2DIR = 0x00;

     if ( level == OB_COLD )

     {

       // Interrupts off

       osal_int_disable( INTS_ALL );

       // Turn all LEDs off

    #ifndef FEATURE_OAD

       HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );

    #endif

       // Check for Brown-Out reset

    //    ChkReset();

     }

     else  // !OB_COLD

     {

    #ifndef FEATURE_OAD

       /* Initialize Key stuff */

       while(1)

       {

         if( P2_0 == 0 )

         {

           OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;

           HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

           if ( P2_0 == 0 )

           {

             P1_0 = 1;

             P1_1 = 1;

           }

           else

           {

             P1_0 = 0;

             P1_1 = 0;

           }

         }

         else

         {

           P1_0 = 0;

           P1_1 = 0;

         }

       }

    #endif

     }

    }

    The blue code is the code I type. The port 1 here is LED where port is for my switch. My switch is 0 when I pressed down and 1 when the switch is not pressed.

  • If you intend to use P2.0 as interrupt source, you can refer to HAL_KEY_JOY_MOVE_XXX related code in hal_key.c
  • Since I want to use interrupt for switch and my switch is P2.0, but if I defined like the code I posted above, it will work or not?
  • I think your code won't work completely if you don't register ISR for P2.0.
  • So how can I register the ISR ? any example for me to refer ?
  • I have told you to refer to HAL_KEY_JOY_MOVE_XXX related code in hal_key.c
  • Oops ok, but I found Port 2 ISR but I dunno whether it is for P2.0 or not

    HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )
    {
    HAL_ENTER_ISR();

    #ifdef FOBO_ENABLED
    LL__IsrPort2();
    #endif

    HAL_KEY_CPU_PORT_2_IF = 0;

    CLEAR_SLEEP_MODE();

    HAL_EXIT_ISR();
    return;
    }

    #else

    void HalKeyInit(void){}
    void HalKeyConfig(bool interruptEnable, halKeyCBack_t cback){}
    uint8 HalKeyRead(void){ return 0;}
    void HalKeyPoll(void){}

    #endif
  • The following defines are for P2.0 to set interrupt service in hal_key.c.

    /* Joy stick move at P2.0 */
    #define HAL_KEY_JOY_MOVE_PORT P2
    #define HAL_KEY_JOY_MOVE_BIT BV(0)
    #define HAL_KEY_JOY_MOVE_SEL P2SEL
    #define HAL_KEY_JOY_MOVE_DIR P2DIR

    /* edge interrupt */
    #define HAL_KEY_JOY_MOVE_EDGEBIT BV(3)
    #define HAL_KEY_JOY_MOVE_EDGE HAL_KEY_FALLING_EDGE

    /* Joy move interrupts */
    #define HAL_KEY_JOY_MOVE_IEN IEN2 /* CPU interrupt mask register */
    #define HAL_KEY_JOY_MOVE_IENBIT BV(1) /* Mask bit for all of Port_2 */
    #define HAL_KEY_JOY_MOVE_ICTL P2IEN /* Port Interrupt Control register */
    #define HAL_KEY_JOY_MOVE_ICTLBIT BV(0) /* P2IENL - P2.0<->P2.3 enable/disable bit */
    #define HAL_KEY_JOY_MOVE_PXIFG P2IFG /* Interrupt flag at source */
  • Ah I see, so if I defined like the code you wrote the interrupt will work fine?
  • You have to do everything about HAL_KEY_JOY_MOVE_XXX related code in hal_key.c and it would work.
  • Means I need to declare all the things ( P2.0 ) inside hal_key.c right?
  • and so I have to declare everything in those HalKeyInit() and others right?
  • Yikai, I referred the code and found that they define #if defined ( CC2540_MINIDK ). And what is that?
  • CC2540_MINIDK is the one of CC2540 developer kit provided by TI and you can find it at www.ti.com/.../cc2541dk-mini . If developer use this CC2540_MINIDK, he can define CC2540_MINIDK in example to make it work.
  • Ah, so I am using other board so I can just ignore the cc2540 minidk?
  • Thanks for that !!!!!
  • You are welcome.
  • Yikai, can you tell me what is this #pragmavector ><
  • Where do you see this #pragmavector?
  • I didn't see it but I am just curious about it since I seen them appear in some of the example in the web.
  • Well Yikai, I can't get my expected result. The expected result is when I press the switch, the led should on and when I released the led should be off. But now, when I press the switch the led stay on till few seconds and then off >.< but I dunno where my code gone wrong. Can you help me check a bit?
  • Can you show me how you implement it?
  • #include "hal_mcu.h"

    #include "hal_defs.h"

    #include "hal_types.h"

    #include "hal_drivers.h"

    #include "hal_adc.h"

    #include "hal_key.h"

    #include "osal.h"

    /*#ifdef FOBO_ENABLED

    #include "isr.h"

    #include "key.h"

    #endif

    */

    #if (defined HAL_KEY) && (HAL_KEY == TRUE)

    #define HAL_KEY_RISING_EDGE   0

    #define HAL_KEY_FALLING_EDGE  1

    #define HAL_KEY_DEBOUNCE_VALUE  50

    /* 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

    #define HAL_KEY_SW3_PORT     P2

    #define HAL_KEY_SW3_BIT      BV(0)

    #define HAL_KEY_SW3_SEL      P2SEL

    #define HAL_KEY_SW3_DIR      P2DIR

    #define HAL_KEY_SW3_EDGE     HAL_KEY_FALLING_EDGE

    #define HAL_KEY_SW3_EDGEBIT  BV(3)

    #define HAL_KEY_SW3_IEN      IEN2

    #define HAL_KEY_SW3_IENBIT   BV(1)

    #define HAL_KEY_SW3_ICTL     P2IEN

    #define HAL_KEY_SW3_ICTLBIT  BV(0)

    #define HAL_KEY_SW3_PXIFG    P2IFG

    static uint8 halKeySavedKeys;     /* used to store previous key state in polling mode */

    static halKeyCBack_t pHalKeyProcessFunction;

    bool Hal_KeyIntEnable;            /* interrupt enable/disable flag */

    void halProcessKeyInterrupt(void);

    ___________________________________________________________________________________________________

    void HalKeyInit( void )

    {

     halKeySavedKeys = 0;  // Initialize previous key to 0.

     HAL_KEY_SW3_SEL &= ~(HAL_KEY_SW3_BIT);

     HAL_KEY_SW3_DIR &= ~(HAL_KEY_SW3_BIT);

     P2INP = 0x01;

     /* Initialize callback function */

     pHalKeyProcessFunction  = NULL;

    }

    ______________________________________________________________________________________________________

    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)

     {

       HAL_KEY_SW3_ICTL &= ~(HAL_KEY_SW3_EDGEBIT);

    #if(HAL_KEY_SW3_EDGE == HAL_KEY_FALLING_EDGE)

       HAL_KEY_SW3_ICTL |= HAL_KEY_SW3_EDGEBIT;

    #endif

       HAL_KEY_SW3_ICTL |= HAL_KEY_SW3_ICTLBIT;

       HAL_KEY_SW3_IEN |= HAL_KEY_SW3_IENBIT;

       HAL_KEY_SW3_PXIFG = ~(HAL_KEY_SW3_BIT);

     }

     else    /* Interrupts NOT enabled */

     {

       HAL_KEY_SW3_ICTL &= ~(HAL_KEY_SW3_ICTLBIT);

       HAL_KEY_SW3_IEN &= ~(HAL_KEY_SW3_IENBIT);

       HAL_KEY_SW3_PXIFG = ~(HAL_KEY_SW3_BIT);  

     }

    }

    _______________________________________________________________________________________________

    uint8 HalKeyRead ( void )

    {

     uint8 keys = 0;

     if((HAL_KEY_SW3_PORT & HAL_KEY_SW3_BIT))

     {

       keys |= HAL_KEY_SW3_BIT;

     }

     return keys;

    }

    _______________________________________________________________________________________________

    void HalKeyPoll (void)

    {

     uint8 keys = 0;

     uint8 notify = 0;

     if(!(HAL_KEY_SW3_PORT & HAL_KEY_SW3_BIT))

     {

       keys |= HAL_KEY_SW3_BIT;;

     }

     /* 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;

       }

     }

     /* Store the current keys for comparation next time */

     halKeySavedKeys = keys;

     /* Invoke Callback if new keys were depressed */

     if (notify && (pHalKeyProcessFunction))

     {

       (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);

     }

    }

    ________________________________________________________________________________________________

    void halProcessKeyInterrupt (void)

    {

     bool valid = FALSE;

     if(HAL_KEY_SW3_PXIFG & HAL_KEY_SW3_BIT)

     {

       HAL_KEY_SW3_PXIFG = ~(HAL_KEY_SW3_BIT);

       valid = TRUE;

     }

     if(valid)

     {

       osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE );

     }

    }

    ___________________________________________________________________________________________________

    void HalKeyEnterSleep ( void )

    {

     return;

    }

    __________________________________________________________________________________________________

    uint8 HalKeyExitSleep ( void )

    {

     /* Wake up and read keys */

     return ( HalKeyRead () );

    }

    __________________________________________________________________________________________________

    //ISR

    HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )

    {

     HAL_ENTER_ISR();

     if( HAL_KEY_SW3_PXIFG & HAL_KEY_SW3_BIT )

     {

       halProcessKeyInterrupt();

     }

     HAL_KEY_SW3_PXIFG = 0;

     HAL_KEY_CPU_PORT_2_IF = 0;

     CLEAR_SLEEP_MODE();

     HAL_EXIT_ISR();

     return;

    }

    #else

    void HalKeyInit(void){}

    void HalKeyConfig(bool interruptEnable, halKeyCBack_t cback){}

    uint8 HalKeyRead(void){ return 0;}

    void HalKeyPoll(void){}

    #endif

    The blue code was typed by me. Sorry for disturbing.

  • Where do you control LED?
  • I control it in keyfobdemo.c there
  • Where is it exactly in keyfobdemo.c?
  • uint8 SwitchIntEnable;

    #define INTERRUPT_ENABLE 0x01

    while(1)
    {
    if ( SW3 == 0 )
    {
    SwitchIntEnable = INTERRUPT_ENABLE;
    HalKeyConfig( SwitchIntEnable, OnBoard_KeyCallback );
    if ( SW3 == 0 )
    {
    Led_On( LED_PORT_1, ( LED_RED_PIN | LED_BLUE_PIN ) );
    }
    else
    {
    Led_Off( LED_PORT_1, ( LED_RED_PIN | LED_BLUE_PIN ) );
    }
    }
    else
    {
    Led_Off( LED_PORT_1, ( LED_RED_PIN | LED_BLUE_PIN ) );
    }
    }
    I defined the SwitchIntEnable and INTERRUPT_ENABLE in keyfobdemo.c .
  • I don't understand. Where do you put this while-loop in keyfobdemo.c?
  • I put the while loop because the event could be trigger infinite times. The process can be repeat again and again. I put it in void KeyFobApp_Init( uint8 task_id )
  • You cannot put a while-loop in KeyFobApp_Init. You should process key event in keyfobapp_HandleKeys.
  • Ah, means I should put the LED things inside the key handler there right? Since I am just a newbie and mainly focus one thing at one time so my teacher said is Ok to do that.
  • Oh, any problem for the interrupt code that I typed in the hal_key.c because I merely follow the code. Some I don't quite understand , but most of them I think I understand =) , I am not sure is the interrupt cause my LED stay on for few seconds when I released.
  • You just shouldn't put a while loop in KeyFobApp_Init. You have to do it in keyfobapp_HandleKeys.