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.

CC2540 Running two timers

Other Parts Discussed in Thread: CC2540

Hi,

I need to use two timers (OSAL timer) at same time but so far I cannot even set event during timer is running. My scenario is like below.

1. Timer1 is for periodic status check. It checks status and changes led sign.

for example,

uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )

{

...

...

...

if ( events & SIMPLEBLEPERIPHERAL_LED_EVT)

{

    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT, 10 );

    if (status)

    {

        // generating LED sign using shift register

        // clock and latch inputs are given from port 0 in CC2540 so I need to keep it running

    }

    else

    {

        // generating LED sign using shift register

        // clock and latch inputs are given from port 0 in CC2540 so I need to keep it running

    }

    return events ^ SIMPLEBLEPERIPHERAL_LED_EVT;

}

...

...

}

2. Timer2 starts when you click the button (on rising interrupt). I need to check if this was long press or not. So I started timer and checked it for certain amount of time. When the button is released, it changes the status (global variable shared by both Timer1 and Timer2).

for example,

HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )

{

    if ( P0IFG & BV(7) )

    {

        osal_set_event( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_BUTTON_EVT);

    }

    P0IFG = 0;

    P0IF = 0;

}

uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )

{

...

...

...

if ( events & SIMPLEBLEPERIPHERAL_BUTTON_EVT)

{

    if ( buttonCount < BUTTON_LONG_COUNT )

    {

        if (P0_7)

        {

            buttonCount++;

            osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_BUTTON_EVT, 100 );

        }

        else // short button press

        {

            status = 0;

        }

    }

    else // long button press

    {

        status = 1;

    }

    return events ^ SIMPLEBLEPERIPHERAL_BUTTON_EVT;

}

...

...

}

Real usage is little different but concept is like above - I need to run two timers at same time (one is for output and the other one is for input) and they share one global variable.

The problem is that, while SIMPLEBLEPERIPHERAL_LED_EVT is running, I cannot initiate SIMPLEBLEPERIPHERAL_BUTTON_EVT. It seems that it skips SIMPLEBLEPERIPHERAL_BUTTON_EVT as another event keeps running. Can anyone please help me? If my implementation is not right, please guide me. Basically I want to see if it's long press or short press while LED is always on.

Thanks,

Brian

  • How do you define SIMPLEBLEPERIPHERAL_LED_EVT and SIMPLEBLEPERIPHERAL_BUTTON_EVT?
  • I defined them followed by simpleBLEPeripheral.h file, like

    #define SPEND_START_DEVICE_EVT 0x0001
    #define SIMPLEBLEPERIPHERAL_LED_EVT 0x0002
    #define SIMPLEBLEPERIPHERAL_BUTTON_EVT 0x0004

    Thanks,
    Brian
  • Your defines look fine. Can you show me the exact codes that you use this two events.
  • Okay, below are real source code. Please look and see if there is any wrong implementation.

    1. LED event

    if ( events & SIMPLEBLEPERIPHERAL_LED_EVT )
    {
    if (ledLightCount-- > 0 )
    {
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT, 10 );
    }
    else
    {
    uint8 cardName[6];
    if (osal_snv_read(cardTemporalId, 5, cardName) == SUCCESS)
    {
    setAlphabet(cardName);
    ledLightCount = 1000;
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT, 10 );
    }
    else
    {
    turnOffLED();
    }
    }

    turnOnLED(alphabet);

    return (events ^ SIMPLEBLEPERIPHERAL_LED_EVT);
    }

    2. Button Interrupt

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
    {
    if (BUTTON_IFG & BUTTON_BIT)
    {
    if ( cardTemporalId == 0 )
    {
    setAlphabet("empty");
    ledLightCount = 1000;
    osal_set_event( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT );
    }
    else
    {
    osal_set_event( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_BUTTON_EVT );
    }
    }
    BUTTON_IFG = 0;
    BUTTON_IF = 0;
    }

    3. Button event

    if ( events & SIMPLEBLEPERIPHERAL_BUTTON_EVT )
    {
    if ( buttonTimeCount < 30 )
    {
    if ( BUTTON == 1 )
    {
    buttonTimeCount++;
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_BUTTON_EVT, 100 );
    }
    else // button press release, short click
    {
    uint8 card[6];
    if (osal_snv_read(cardTemporalId + 1, 6, card) == SUCCESS)
    {
    setAlphabet(card);
    }
    else
    {
    setAlphabet("error");
    }
    ledLightCount = 2000;
    buttonReady();
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT, 10 );
    }
    }
    else // long click
    {
    uint8 card[6];
    if (osal_snv_read(cardBestId, 6, card) == SUCCESS)
    {
    setAlphabet(card);
    }
    else
    {
    setAlphabet("err.r");
    }
    ledLightCount = 2000;
    buttonReady();
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_LED_EVT, 10 );
    }

    return ( events ^ SIMPLEBLEPERIPHERAL_BUTTON_EVT );
    }

    When LED event is running, Button event waits until LED event is done so I cannot initiate button click event while LED is on. In start state (LED is off), I verified button clicking turns on LED.

    Thanks,
    Brian
  • What is the initial value of ledLightCount? I see it never stay on 0 in your code. Is this the root cause why your button won't trigger after first time?
  • Initially, it's 0. You are right, led is always on. But when the button is clicked, interrupt calls

    osal_set_event( simpleBLEPeripheral_TaskID, SIMPLEBLEPERIPHERAL_BUTTON_EVT );

    and, in the button event, it calls

    setAlphabet(card);

    But the LED doesn't change.

    Once the LED is on, setAlphabet(card); in SIMPLEBLEPERIPHERAL_BUTTON_EVT doesn't have any effect. That's my problem.

    Thanks,
    Brian
  • If you need to blink led, you can use API HalLedBlink(). There is no need to implement SIMPLEBLEPERIPHERAL_LED_EVT.
  • Sorry if I confused you, but it's actually DOT Matrix, not a LED. I connected 3 pins of CC2540 to shift registers to control multiple LEDs (about hundred). That's why I used turnOnLED(alphabet);

    Thanks,
    Brian
  • Try to call osal_stop_timerEx to stop previous timer event before you call osal_start_timerEx.
  • Now CC2540 doesn't detect button interrupt... It's so weird and I have no clue.. But I'll try your suggestion later once the interrupts work again.

    Thanks,
    Brian
  • Let me know if you have any problem later.
  • osal_stop_timerEx worked. Looks like it doesn't let me run two timers at same time but at least I was able to figure out the work around.

    Thanks,
    Brian
  • Cool! It's great to know it works for you.