Dual use pin (wkupct_enable_irq & GPIO_EnableIRQ)

4 posts / 0 new
Last post
justinturley
Offline
Last seen:4 years 5 months ago
加入:2016-06-19 23:55
Dual use pin (wkupct_enable_irq & GPIO_EnableIRQ)

Hi, I'm having trouble with setting up a pin to wake up the device during sleep, and also using the same pin to start advertising by long press.

分别长按功能working fine, and I have verified that the pin can wake the device by setting a LED on, but I can't get both to work together. So I want to know how I can use 1 pin to wake from sleep (wkupct_enable_irq) and if I hold the same pin for 3 seconds it will also start advertising (GPIO_EnableIRQ).

Setup GPIO interrupt:
// on btn2 interrupt call this function
GPIO_RegisterCallback(GPIO2_IRQn, button2_press);
// set to interrupt on falling edge/high
GPIO_EnableIRQ(BTN2_PORT_RGD, BTN2_PIN_RGD, GPIO2_IRQn, FALLING_EDGE, false, 10);

// long press on btn 2 starts adv
void button2_press(void)
{

switch(btnState_e)
{
case btnLow: // initial btn press
btnState_e + +;
GPIO_RegisterCallback(GPIO2_IRQn, button2_press);
// chng to interrupt on opposite edge for next time thru
GPIO_EnableIRQ(BTN2_PORT_RGD, BTN2_PIN_RGD, GPIO2_IRQn,RISING_EDGE , false, 10);
// start timer
tmrStrtBtn2 = systick_value();
btn2Released = false;
break;

case btnHigh: // btn release
btnState_e--;
GPIO_RegisterCallback(GPIO2_IRQn, button2_press);
// chng to interrupt on opposite edge for next time thru
GPIO_EnableIRQ(BTN2_PORT_RGD, BTN2_PIN_RGD, GPIO2_IRQn, FALLING_EDGE, false, 10);
// stop timer
tmrStopBtn2 = systick_value();
btn2Released = true;
break;

// start advertising on long press
}

Set up wkup timer:
wkupct_register_callback(btn_wakeup_cb);
wkupct_enable_irq(WKUP_EN_BTN2, WKUP_ACTV_LOW,1,0); // pin, active low, 1 event, debouncing time = 0ms

void btn_wakeup_cb(void)
{
如果(GetBits16 (SYS_STAT_REG, PER_IS_DOWN))
{
periph_init();
}

button2_press(); // <--------- I don't think the GPIO interrupt is firing, so try calling it here?
}

Calling button2_press() does not work, and since the GPIO interrupt is not firing I don't get the callback to execute the code.
Am I going about this wrong?
谢谢。

Device:
LT_Dialog (not verified)
Hi justinturley,

Hi justinturley,
If I understand your requirement correctly, "when the key is pressed, the system wakes up. And then from there if the key is kept pressed for more than 3 seconds, start advertising".
And I assume in your application, DA1458x enters the extended sleep mode.

GPIO module is powered off when DA1458x sleeps. All GPIO settings are not retained. When the system is waked up by a key press and nothing needs to be executed, it goes back to sleep again even the key is still being pressed. Then the settings set to the GPIO module in the function button2_press() are gone. This is probably you don't get GPIO interrupts.

One way you could do is:

void btn_presschecker(void) {
advertise if the btn is still pressed.
}
void btn_wakeup_cb(void) {
if the btn is pressed, register the call back function 'btn_presschecker' to app_easy_timer with an expiration of 3s.
call wakeup_enable()
}
void wakeup_enable(void) {
register to wkupct the callback function 'btn_wakeup_cb';
if the btn is high
wkupct_enable_irq(active low);
else
wkupct_enable_irq(active high);
}

justinturley
Offline
Last seen:4 years 5 months ago
加入:2016-06-19 23:55
Yes, I am using the extended

Yes, I am using the extended sleep mode. And thanks for the explanation. That makes sense now that I know the GPIO interrupts don't work during sleep. With your suggestion I will be able to get the long press functionality working.

I think I may have an other issue now. Everything I have written so far depends on the GPIO_EnableIRQ. I did not think about sleep until the very end, and now I'm realizing I may have to rethink a lot of my GPIO code. The device I am developing is a custom remote. The long button press to start advertizing only is need when there is no connection to the central device. So your suggestion will take care of that one. But, on any other button press I send the client a value related to each button. Will I need to have separate function for each button? One for sleep and one for not sleeping to set the right interrupts? Some of the buttons have dual short/long press functionality, and send diff values accordingly.

Otherwise, am I able to set multiple wkupct_enable_irq for each button? How do I know what button caused the wkupct interrupt after calling the cb function registered with wkupct_register_callback?

Is it possible to manually set a GPIO interrupt once woken from sleep? I guess I could scan all button in the cb function then set the correct interrupt, if that's possible. There are only 3 buttons.

LT_Dialog (not verified)
Hi justinturley,

Hi justinturley,
You could set multiple GPIOs with wkupct_enable_irq which share the only same setting of callback function/event count/debouncing time. You may refer to the function wkupct_enable_irq () in wkupct_quadec.c.

And since the callback function is shared between three keys, a key scan in the callback function could be performed to see which one is actually pressed.