feat: 完成弹力魔盒初版固件
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
/******************************************************************************
|
||||
* @file app_shake_wake.c
|
||||
* @brief PA3 vibration-switch wake detector.
|
||||
*
|
||||
* The fitted switch is normally closed to ground. A vibration opens the
|
||||
* contact, so PA3 goes high, then returns low when the contact closes again.
|
||||
* A wake is accepted only after the high level has been stable for the
|
||||
* re-arm interval and is generated on the following high-to-low transition.
|
||||
******************************************************************************/
|
||||
|
||||
#include "app_shake_wake.h"
|
||||
#include "board_pin.h"
|
||||
#include "asm/gpio.h"
|
||||
|
||||
typedef struct {
|
||||
AppShakeWakeAllowedFn allowed;
|
||||
AppShakeWakeTriggerFn trigger;
|
||||
uint8_t enable;
|
||||
uint8_t armed;
|
||||
uint8_t trigger_pending;
|
||||
uint8_t high_ticks;
|
||||
} AppShakeWakeCtx_t;
|
||||
|
||||
static AppShakeWakeCtx_t s_shake;
|
||||
|
||||
static void shake_reset_detection(void)
|
||||
{
|
||||
s_shake.armed = 0;
|
||||
s_shake.trigger_pending = 0;
|
||||
s_shake.high_ticks = 0;
|
||||
}
|
||||
|
||||
static void shake_pin_init(void)
|
||||
{
|
||||
#if BOARD_SHAKE_ENABLE
|
||||
gpio_set_die(BOARD_SHAKE_PIN, 1);
|
||||
gpio_direction_input(BOARD_SHAKE_PIN);
|
||||
gpio_set_pull_up(BOARD_SHAKE_PIN, 1);
|
||||
gpio_set_pull_down(BOARD_SHAKE_PIN, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void app_shake_wake_init(AppShakeWakeAllowedFn allowed,
|
||||
AppShakeWakeTriggerFn trigger)
|
||||
{
|
||||
s_shake.allowed = allowed;
|
||||
s_shake.trigger = trigger;
|
||||
s_shake.enable = 0;
|
||||
shake_reset_detection();
|
||||
shake_pin_init();
|
||||
}
|
||||
|
||||
void app_shake_wake_set_enable(uint8_t enable)
|
||||
{
|
||||
s_shake.enable = !!enable;
|
||||
shake_reset_detection();
|
||||
}
|
||||
|
||||
void app_shake_wake_reset(void)
|
||||
{
|
||||
shake_reset_detection();
|
||||
}
|
||||
|
||||
void app_shake_wake_poll(void)
|
||||
{
|
||||
uint8_t pin_high;
|
||||
uint8_t rearm_ticks;
|
||||
|
||||
if (!s_shake.enable) {
|
||||
shake_reset_detection();
|
||||
return;
|
||||
}
|
||||
|
||||
#if BOARD_SHAKE_ENABLE
|
||||
pin_high = (uint8_t)(gpio_read(BOARD_SHAKE_PIN) == BOARD_SHAKE_ACTIVE_LEVEL);
|
||||
#else
|
||||
pin_high = 0;
|
||||
#endif
|
||||
rearm_ticks = (uint8_t)(BOARD_SHAKE_REARM_MS / BOARD_SHAKE_POLL_MS);
|
||||
if (!rearm_ticks) {
|
||||
rearm_ticks = 1;
|
||||
}
|
||||
|
||||
if (pin_high) {
|
||||
if (s_shake.high_ticks < rearm_ticks) {
|
||||
s_shake.high_ticks++;
|
||||
}
|
||||
if (s_shake.high_ticks >= rearm_ticks) {
|
||||
s_shake.armed = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* The contact has closed again: this is the verified wake edge. */
|
||||
s_shake.high_ticks = 0;
|
||||
if (s_shake.armed) {
|
||||
s_shake.armed = 0;
|
||||
s_shake.trigger_pending = 1;
|
||||
}
|
||||
|
||||
if (!s_shake.trigger_pending) {
|
||||
return;
|
||||
}
|
||||
s_shake.trigger_pending = 0;
|
||||
if (!s_shake.allowed || !s_shake.allowed()) {
|
||||
shake_reset_detection();
|
||||
return;
|
||||
}
|
||||
if (s_shake.trigger) {
|
||||
s_shake.trigger();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user