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.

CC2541: Advertising stopping during button pressing and buzzert alert

Part Number: CC2541
Other Parts Discussed in Thread: BLE-STACK

Hi all,

i'm developing my cc2541 based device through simplebleperipheral project. My device sends dynamic advertising packets (containing temperature, battery level and button pressing information) every 500 ms for 10 secs, then it's turned off for 50 secs then it restarts advertising and so on. If a button installed on the device is pressed corresponding byte in the advertising packets changes state, and a buzzer sounds. 

In the function performperiodicTask (which lasts 50 ms) i control the button state, and consequently the buzzer alert through following instruction

static void performperiodicTask (void)

{

if (alarm ==1) //condition set by interrupt on pin P0_0

{

for (i=1; i<=250; i++)

P1_6 = 1; //pin that drives the buzzer is forced to 1

}

else

P1_6 = 0; // pin that drive buzzer is forced to 0, buzzer of

My problem is that the buzzer sounds well in this way but device advertising, during the alert period, stops,. If I reduce the duration of the for loop, acting on superior limit of i, advertising is ok but the alarm sound of the buzzer is a small clatter. It's not sounding well.

Can anyone help me please with some advice?

Regards, 

Vito

  • Hi Vito,

    The CC2541 does not have a pre-emptive operating system, which means that the you are actually preventing the BLE-Stack from processing (scheduling, executing) a radio event. Please avoid using for loops in systems like this and consider using a software timer to flip the GPIO.

  • Thanks for your reply, Joakim,

    Searching in the forum I found this "Creating  a new event and set a timer using osal_start_timerEx()." , i looked at osal_start_timerEx() function but i cant understand it properly.

    I want to flip the gpio P1_6 for 300 msec, for example

    Can you help please? 

    uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint32 timeout_value )
    {
    halIntState_t intState;
    osalTimerRec_t *newTimer;

    HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.

    // Add timer
    newTimer = osalAddTimer( taskID, event_id, timeout_value );

    HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.

    return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
    }

  • Hi,

    This is what you should implement; After you toggle gpio P1_6 (i.e. ON) you will need to start timer, i.e.

    Call osal_start_timerEx(project_task_id, CUSTOM_EVENT, 300)

    You will need to add the CUSTOM_EVENT to the OSAL loop (project_task_id). In that event, you will toggle gpio P1_6 again (i.e. OFF).

    Note that the project_task_id and CUSTOM_EVENT are made up by me for this particular post. project_task_id should already be available in you project under another name and CUSTOM_EVENT is something you need to create (and thus name) yourself.

  • Hello Joakim,

    thanks for your reply, you are very kind.

    I've followed your advices but still doesnt work.

    In the performperiodictask function, called by sbp periodic event, i've written the following instructions

    if (alarm == 1)

    {

    p1_6 = 1;

    osal_start_timerEx (simpleBLEPeripheral, SBP_BUZZER_ALERT_EVT, SBP_BUZZER_ALERT_PERIOD)

    }

    else P1_6 = 0;

    In the SimpleBLEPeripheral_ProcessEvent function i've added this (toggling the pin P1_6 OFF)

    if (events & SBP_BUZZER_ALERT_EVT)

    {

    P1_6 = 0;

    return (events ^ SBP_BUZZER_ALERT_EVT)

    }

    No errors but it simply works as previously, with the buzzer sound is a small clutter. I've missing something, definitely.

    Could you help me please?

  • Hi Vito,

    Probably because the device goes into sleep (PM2) while the timer is running and the GPIO setting might not be retained. If I remember correctly, it should be possible to modify hal_sleep.c to retain the gpio. But still, I find this information in SWRU191F:

    4.1.3 PM2

    PM2 has the second-lowest power consumption. In PM2, the power-on reset, external interrupts, selected

    32-kHz oscillator, and Sleep Timer peripherals are active. I/O pins retain the I/O mode and output value

    set before entering PM2. All other internal circuits are powered down. The voltage regulator is also turned

    off. 

    Would you be able to verify the GIPO state with a logic analyzer or oscilloscope.

  • The GPIO state is basically a small 3,3V pulse, lasting a few usecs. It corresponds, i think, to the small clatter that i heard from the buzzer.

    Do i have to disable the sleep mode?

    The information you found said that actually the GPIO setting might be retained while the timer is running?

  • Hi Vito,

    "The information you found said that actually the GPIO setting might be retained while the timer is running?"

    Yes, that is why I'm a bit puzzled. Could you try to disable power saving, just to check what happens. It should be possible by removing/renaming POWER_SAVING symbol in the pre-defines.

  • Could it be possible that having inserted the toggling of pin p1_6 (P1_6 = 1) in the project periodic event (that lasts 50 msec) is generating this strange behavior?

  • I solved. I moved the gpio toggling in the periodic event directly, before it was placed in the performperiodictask () function called in it.