Button handling issue
응답
16. 7. 14 오전 5:34

Hello,

What am I doing wrong and how to fix it?

When I run code posted below I get error: 

 asserted at Filename source/efm32/BUTTON/button_efm32.c , line no  101 

after few button press.

 

When I change approach to that from LedsAndButtons Example, I mean with callback, the buttons doesnt work at all (I get the same assertion error, but without any code executing) until i comment my for(;;) loop (than error doenst show up). This for loop is mandatory for proper work of prox_agent_task() function.

/*Some code*/

void appInitSystem(xTimerHandle xTimer)
{
	(void)xTimer;
	prox_agent_start();
}


void prox_agent_start(void)
{

/*Not important code here...*/

	/* Button initialization. */
	button_init();

	/* Main loop. */
	for(;;)
	{
		
		prox_agent_task();

		button_handler();
		
		/* Simple 1 sec delay */
		vTaskDelay(DELAY_1_SEC);
	}
}

/* Initialize Alarm button */
void button_init(void)
{
	/*Create alarm_button*/
	alarm_button = BUTTON_create(gpioButton1_Handle, GPIO_STATE_OFF);
	if(alarm_button != NULL)
		printf("alarm_button initialization success. \n");

	/*Enable alarm_button*/
	if(BUTTON_enable(alarm_button) == 0)
		printf("Button enabled: alarm_button. \n");

	/*Create alarm_button*/
	del_alarm_button = BUTTON_create(gpioButton2_Handle, GPIO_STATE_OFF);
	if(del_alarm_button != NULL)
		printf("del_alarm_button initialization success. \n");

	/*Enable del_alarm_button*/
	if(BUTTON_enable(del_alarm_button) == 0)
		printf("Button enabled: del_alarm_button. \n");

}

void button_handler(void)
{
	/* Button 1 is pressed */
 	if (BUTTON_isPressed(alarm_button))
 	{
 		printf("alarm_button has been pressed.\n");
 		is_alarm_button_pressed = true;
 	}

 	if (BUTTON_isReleased(alarm_button))
 	{
 		printf("alarm_button has been released.\n");
 		is_alarm_button_pressed = false;
 	}
	/* Button 2 is pressed */
 	if (BUTTON_isPressed(del_alarm_button))
 	{
 		printf("del_alarm_button has been pressed.\n");
 		is_del_alarm_button_pressed = true;
 	}

 	if (BUTTON_isReleased(del_alarm_button))
 	{
 		printf("del_alarm_button has been released.\n");
 		is_del_alarm_button_pressed = false;
 	}


 	if(is_alarm_button_pressed && is_del_alarm_button_pressed)
 	{
 	   	printf("XDK will change mode. \n");
 	   	is_pressed = BUTTON_BOTH;
 	   	mode = REQUEST_MODE_CHANGE;
 	}

 	if(is_alarm_button_pressed && !is_del_alarm_button_pressed)
 	{
 	   	printf("XDK will set alert. \n");
 	   	is_pressed = BUTTON1;
 	   	mode = CLEAR_REQUEST;
 	}

 	if(!is_alarm_button_pressed && is_del_alarm_button_pressed)
 	{
 	   	printf("XDK will clear alert. \n");
 	   	is_pressed = BUTTON2;
 	   	mode = CLEAR_REQUEST;
 	}

 	if(!is_alarm_button_pressed && !is_del_alarm_button_pressed)
 	{
 	  	is_pressed = NO_BUTTON;
 	   	mode = CLEAR_REQUEST;
 	}
}

 

Here is my callback approach:

/* Initialize Alarm button */
void button_init(void)
{
	/*Create alarm_button*/
	alarm_button = BUTTON_create(gpioButton1_Handle, GPIO_STATE_OFF);
	if(alarm_button != NULL)
		printf("alarm_button initialization success. \n");

	/*Enable alarm_button*/
	if(BUTTON_enable(alarm_button) == 0)
		printf("Button enabled: alarm_button. \n");

	/*Register callback for alarm_button*/
	if(BUTTON_setCallback(alarm_button, button_clb, CLB_ALERT_BUTTON) == 0)
		printf("Callback set: alarm_button \n");

	/*Create del_alarm_button*/
	del_alarm_button = BUTTON_create(gpioButton2_Handle, GPIO_STATE_OFF);
	if(del_alarm_button != NULL)
		printf("del_alarm_button initialization success. \n");

	/*Enable del_alarm_button*/
	if(BUTTON_enable(del_alarm_button) == 0)
		printf("Button enabled: del_alarm_button. \n");

	/*Register callback for del_alarm_button*/
	if(BUTTON_setCallback(del_alarm_button, button_clb, CLB_DEL_ALERT_BUTTON) == 0)
			printf("Callback set: del_alarm_button \n");

}

void button_clb(void *handle, uint32_t button_param) /*FIXME It doesnt run with main loop in AppInit*/
{													  /*When i comment for(;;) it works, but without clb solution, asserion issues occurs*/
	is_pressed = NO_BUTTON;
	printf("Kesrsajdiodnasisandas\n");
    switch (button_param)
    {
    /*  Button 1 press/release */
    case CLB_ALERT_BUTTON:
        if (BUTTON_isPressed(handle))
        {
        	printf("alarm_button has been pressed.\n");
        	is_alarm_button_pressed = true;

        }
        if (BUTTON_isReleased(handle))
        {
        	printf("alarm_button has been released.\n");
        	is_alarm_button_pressed = false;
        }
        break;

        /* Button 2 press/release */
    case CLB_DEL_ALERT_BUTTON:
        if (BUTTON_isPressed(handle))
        {
        	printf("del_alarm_button has been pressed.\n");
        	is_del_alarm_button_pressed = true;
        }
        if (BUTTON_isReleased(handle))
        {
        	printf("del_alarm_button has been released.\n");
        	is_del_alarm_button_pressed = false;
        }
        break;
    default:
        printf("ERROR: Unknown button! \n\r");
        break;
    }

    if(is_alarm_button_pressed && is_del_alarm_button_pressed)
    {
    	printf("XDK will change mode. \n");
    	is_pressed = BUTTON_BOTH;
    	mode = REQUEST_MODE_CHANGE;
    }

    if(is_alarm_button_pressed && !is_del_alarm_button_pressed)
    {
    	printf("XDK will set alert. \n");
    	is_pressed = BUTTON1;
    	mode = CLEAR_REQUEST;
    }

    if(!is_alarm_button_pressed && is_del_alarm_button_pressed)
    {
    	printf("XDK will clear alert. \n");
    	is_pressed = BUTTON2;
    	mode = CLEAR_REQUEST;
    }
    if(!is_alarm_button_pressed && !is_del_alarm_button_pressed)
    {
    	is_pressed = NO_BUTTON;
    	mode = CLEAR_REQUEST;
    }
}

In addition id say, that all of printfs prints message except of that ones in button_clb() [that callback function probably isnt called at all].

I would appriciate any help.

Best,

Pawel

+1 (1 투표)
RE: Button handling issue
응답
16. 7. 14 오전 7:07 as a reply to Tomasz Polak.

Hello Tomasz,

in order to help you I need your full project with variable definitions. Please post me your E-mail address in here that I can contact you.

Kind regards,
Franjo

0 (0 투표)
RE: Button handling issue
응답
16. 7. 14 오전 7:32 as a reply to Franjo Stjepandic.

Hi,

My email: pzydziak@proximetry.pl

Paweł

0 (0 투표)
RE: Button handling issue
응답
16. 7. 14 오후 4:21 as a reply to Tomasz Polak.

Hello Tomasz,

I have contacted you and I am waiting to receive your project.
If there is any progress I will keep you posted in here.

Kind regards,
Franjo

0 (0 투표)
RE: Button handling issue
응답
16. 7. 19 오후 2:04 as a reply to Franjo Stjepandic.

Hello,

I was able to reproduce the occuring issue. I guess you used the LedsAndButtons example as starting point. This example is implemented with so called interrupts. Interrupts provide an eventbased control. Therefore no implementation of a timer or infinite loop is necessary.

Your application crashes because of the infinite loop.  
I recommend to use the functions of the button.h headerfile to implement a stable event control. Therefore you can use the BUTTON_setCallback() function to implement the event control. This function takes the buttonhandle, the callback and a callbackparameter that link the used button. Your code to execute that is triggered by the button can be implemented in the callback function.

If you can't avoid the for loop, I would suggest you to use the
XdkDataloggerDemo as starting point. In XDK_Datalogger_cc.c you can see triggered events in infinite loops. Anyway I would recommend to avoid the infinite loop und use the implementation that is provided by the button.h interface.

I hope this could help you.

Kind regards,
Franjo

0 (0 투표)