Dear Dialog team,
We need to detect long press button on DA14683 and we are using SDK 1.0.14.1081. We use K1 button for this operation.
我们能够使用计数器检测5秒操作,并使系统转到睡眠模式。
Now, we need to wakeup the system from sleep mode, when the button is pressed for 5 seconds. We are able to wakeup the system for normal press (like touch and release button).
Can you suggest any example code for this operation or can you suggest flow how to do this?
Best regards
Malli
Device:
Hi powersquare,
You are not able to wake up the DA14683 when the button is pressed for 5 seconds. Please refer to the datasheet in WKUP_CTRL_REG description. You could configure the debouncing time up to 64msec by setting the WKUP_DEB_VALUE bitfield with the appropriate value. The “long press button” implementation with 5sec duration can be achieved when the system is in active mode, as you mentioned in your post.
Thanks, PM_Dialog
Hi Dialog team, Our objective is as follows.
1. Put the controller to hinbernate mode after the button is pushed for 5 sec long.
2. Wake the controller up form the hibernate mode after the button is pushed for 5 sec long.
The controller wakes up immedialty within a second after the button is pushed, which is not desired as this could be an accedental press.
Can you let us know how to acheive wakeup from hibernate mode after the button is pushed for 5 seconds?
Best Regards,
Malli
Hi powersquare,
As it is mentioned in my previous comment, waking the controller up from the hibernate mode after the button is pushed for 5 sec long is not possible to be achieved. Regarding your first requirement, can you please let me know if you need support on that or you have already implemented it?
Thanks, PM_Dialog
Dear Dialog team,
Thank you for your support.
For first requirement, we plan to implement like delay for 5 sec and check if button is still pressed or not. If its pressed, then go to hibernation or else continue with same state. We plan to do like below:
/* set up wake up controller for K1 button as below */
hw_wkup_set_debounce_time(63);
hw_wkup_set_pin_state(HW_GPIO_PORT_1, HW_GPIO_PIN_6, true);
hw_wkup_set_pin_trigger(HW_GPIO_PORT_1, HW_GPIO_PIN_6, HW_WKUP_PIN_STATE_LOW);
hw_wkup_register_interrupt(wkup_handler, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
/* wkup_handler() */
Run the loop for 5 times // for loop
{
delay (1000 ms) // OS_DELAY_MS(1000);
Check for button state // hw_gpio_get_pin_status(HW_GPIO_PORT_1, HW_GPIO_PIN_6);
if (low) { contine for loop }
else { set a flag and break the for loop }
}
if (flag not set)
{
pm_set_sleep_mode(pm_mode_hibernation);
}
Is the above approach ok ? do you suggest any other approach?
Is OS_DELAY_MS() function works in wakeup interrupt handler? If not, any other alternate solution.
Best regards
Malli
Hi powersquare,
You can do that with a software implemented approach, by polling a GPIO and check with a counter if the button is pressed for 5 sec. Be aware that in case of waking up from hibernation, the device will wake up before the expiration of the 5 sec, so if the button is pressed more than 5 sec the device will stay in active mode, otherwise it will enter the hibernation again. In case of the active mode, you have to check the value of the counter, and only if the button is pressed for 5sec the chip will enter the hibernation mode.
Thanks, PM_Dialog
Dear Dialog team,
Thank you for your support.
We implemented the first requirement, i.e. put the controller to hibernate mode, and it works fine.
For 2nd requirement, i.e. hiberbate to wakeup, since software approach doesn't work, can you suggest any other approach of using hardware timers or kernal timers for this functionality. Can you suggest any sample codes for this?
Best regards
Malli
Hi powersquare,
As I mentioned before, it is not possible to wake up the device from the hibernation mode after the button is pushed for 5 sec long. The chip will wake up earlier from 5sec.
Thanks, PM_Dialog
Dear Dialog team,
Thank you for your support.
For the first requirement, (Put the controller to hibernate mode after the button is pushed for 5 sec long), we tested this functionality with extended_sleep project and this works fine. When K1 button is pressed for 5 secs, the system goes to hibernate mode.
现在我们在ble_perip测试这个功能heral project. We configured K1 button pin and ported timer functionality from extended_sleep project (main.c) to ble_peripheral project main.c file. We attached main.c file of ble_peripheral project for your reference. There is no change made in SDK and in ble_peripheral project. Only change made is in main.c file to configure button and timer functionality.
When we tested this functionality (when we press K1 button for 5 secs), the system goes to hibernate and immediately wakes up. We don't want the system to wake up immediately. We also tested with this setting in main.c file, pm_set_wakeup_mode(false), but issue remains same.
Can you help us to resolve this issue in ble_peripheral project.
Best regards
Malli
Dear Dialog team,
Do you have any update on this?
Best regards
Malli
Hi powersquare,
Apologies for the delay. I used your attached code (main.c), and I replicated your issue working on the DA14683 SoC and SDK1.0.14.1081. With the same main.c file, the issue does not exist when using DA14681 SoC instead of DA14683. Please take a look at the apply_wfi() function in sdk/cpm/sys_power_mgr.c. The revision A (BLACK_ORCA_IC_REV_A) is applicable for the DA14681 devices and the revision B (BLACK_ORCA_IC_REV_B) is for DA14683 devices. In line 1393 of the sys_power_mgr.c file, if the DA14681 (BLACK_ORCA_IC_REV_A) is being used, before going to hibernation, all the IRQs are disabled and all pending interrupts are cleared except from VBUS and WKUP, so that the system is not reset by an already pending interrupt. This is applicable only in DA14681 devices. To do so, when using the DA14683 device, the pending interrupts are never cleared because the if-statement will always be false. As a result, the system after going to hibernation, it will immediately wake-up due to a pending interrupt. Also, keep in mind that in ble_peripheral example of the SDK, you will have BLE activity, so the most possible reason for waking up is due to a pending BLE interrupt, in contrast with extended_sleep example. A possible workaround might be to modify the source code of sys_power_mgr.c in order to explicitly clear all the pending interrupts in case of DA14683. Please check a reference code snippet:
In case of DA14683, all the pending interrupts are cleared except from WKUP because the chip can be woken up only from the WAKEUP controller and not from the VBUS. Please note that this is just a possible workaround which is not tested by the SDK team.
Another workaround would be to stop advertising and stop any other BLE activity before putting the chip into hibernation mode.
Thanks, PM_Dialog
Dear Dialog team,
Thank you for your support.
This solution seems to be working fine (changed made in line 1393 of the sys_power_mgr.c file).
Can you confirm with your SDK team about these changes?
Best regards
Malli
Hi Malli,
Glad the you figured your issue out. If you found the workaround useful, please mark the previous aswer as accepted. I have alredy let the SDK Team know about that.
Regards, PM_Dialog
Dear Dialog team,
Thank you for your support.
我们使用的是DA14683制造的定制板。此帖子中提到的按钮按下(5秒)在此定制板上不起作用。
The button is configured on port 4, pin4 on this board. When we press this button for 5 secs, we observed that hw_wkup_handler() function is called in hw_wkup.c file, but the call back function (intr_cb) is not called. The call back function is initialiazed in main.c using hw_wkup_register_interrupt(). In hw_wkup_handler(), the control goes inside "if (intr_cb) {" loop, but the call back is not called.
Can you help us to resolve, why this call back is not called?
Best regards
Malli
Hi powersquare,
I have driven the conversation through the below forum ticket:
https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-%E2%80%93-software/active-mode-hibernate-mode
Thanks, PM_Dialog