You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
10 KiB
245 lines
10 KiB
#include "zapp.h"
|
|
|
|
#include "znordic.h"
|
|
|
|
typedef struct {
|
|
app_event_listener_t cbfunc;
|
|
} AppEventListener;
|
|
|
|
static device_state_t m_device_state = kstate_standby; // 设备状态
|
|
static uint32_t m_change_to_cur_state_tp = 0; // 切换到当前状态的时间戳
|
|
static on_state_change_t m_onstate_change;
|
|
static AppEventListener m_listener[10];
|
|
static int m_listener_num = 0;
|
|
|
|
APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器
|
|
#define SCHED_MAX_EVENT_DATA_SIZE MAX(sizeof(app_event_t), APP_TIMER_SCHED_EVENT_DATA_SIZE)
|
|
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr0); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr1); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr2); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr3); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr4); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr5); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr6); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr7); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr8); //
|
|
APP_TIMER_DEF(m_delay_event_preset_tmr9); //
|
|
|
|
typedef struct {
|
|
app_timer_id_t tmrid;
|
|
app_event_t eventcache;
|
|
bool usage;
|
|
} zevent_preset_tmr_t;
|
|
zevent_preset_tmr_t m_delay_event_preset_tmr[10] = {0};
|
|
|
|
/***********************************************************************************************************************
|
|
* CALL BAK *
|
|
***********************************************************************************************************************/
|
|
|
|
static void app_event_process_cb(void* p_event_data, uint16_t event_size) {
|
|
app_event_t* p_event = (app_event_t*)p_event_data;
|
|
if (p_event->hang_up_flag) {
|
|
*p_event->hang_up_flag = 0;
|
|
}
|
|
|
|
for (int i = 0; i < m_listener_num; i++) {
|
|
if (m_listener[i].cbfunc) {
|
|
m_listener[i].cbfunc(p_event_data, event_size);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void state_machine_driver_tmr_cb(void* p_context) { //
|
|
wd_feed();
|
|
static app_event_t appevent;
|
|
static uint8_t event_hang_up = 0;
|
|
appevent.eventType = kappevent_tmr_scheduler_event;
|
|
zapp_ebus_push_event_ext(&event_hang_up, &appevent);
|
|
}
|
|
|
|
static void delay_event_preset_tmr_cb(void* p_context) { //
|
|
zevent_preset_tmr_t* tmr = (zevent_preset_tmr_t*)p_context;
|
|
tmr->usage = false;
|
|
app_event_t* event = &tmr->eventcache;
|
|
ZASSERT(zapp_ebus_push_event(event));
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* EXTERN *
|
|
***********************************************************************************************************************/
|
|
void zapp_early_init() { APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, 20); }
|
|
void zapp_init() {
|
|
ZERROR_CHECK(app_timer_create(&m_state_machine_driver_tmr, APP_TIMER_MODE_REPEATED, state_machine_driver_tmr_cb));
|
|
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr0, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr1, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr2, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr3, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr4, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr5, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr6, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr7, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr8, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
ZERROR_CHECK(app_timer_create(&m_delay_event_preset_tmr9, APP_TIMER_MODE_SINGLE_SHOT, delay_event_preset_tmr_cb));
|
|
|
|
m_delay_event_preset_tmr[0].tmrid = m_delay_event_preset_tmr0;
|
|
m_delay_event_preset_tmr[1].tmrid = m_delay_event_preset_tmr1;
|
|
m_delay_event_preset_tmr[2].tmrid = m_delay_event_preset_tmr2;
|
|
m_delay_event_preset_tmr[3].tmrid = m_delay_event_preset_tmr3;
|
|
m_delay_event_preset_tmr[4].tmrid = m_delay_event_preset_tmr4;
|
|
m_delay_event_preset_tmr[5].tmrid = m_delay_event_preset_tmr5;
|
|
m_delay_event_preset_tmr[6].tmrid = m_delay_event_preset_tmr6;
|
|
m_delay_event_preset_tmr[7].tmrid = m_delay_event_preset_tmr7;
|
|
m_delay_event_preset_tmr[8].tmrid = m_delay_event_preset_tmr8;
|
|
m_delay_event_preset_tmr[9].tmrid = m_delay_event_preset_tmr9;
|
|
}
|
|
void zapp_start_schedule() { ZERROR_CHECK(app_timer_start(m_state_machine_driver_tmr, APP_TIMER_TICKS(1000), NULL)); }
|
|
|
|
/***********************************************************************************************************************
|
|
* state_machine *
|
|
***********************************************************************************************************************/
|
|
void zapp_state_machine_reg_state_change_listener(on_state_change_t listener) { m_onstate_change = listener; }
|
|
|
|
static void _zapp_state_machine_change_state(void* tostate_) {
|
|
device_state_t tostate = (device_state_t)tostate_;
|
|
ZLOGI("change state from %s to %s", device_state_to_str(m_device_state), device_state_to_str(tostate));
|
|
device_state_t nowstate = m_device_state;
|
|
|
|
m_device_state = tostate;
|
|
if (m_onstate_change) {
|
|
m_onstate_change(nowstate, m_device_state);
|
|
}
|
|
m_change_to_cur_state_tp = znordic_getpower_on_ms();
|
|
}
|
|
|
|
void zapp_state_machine_change_state(device_state_t tostate) { //
|
|
uint32_t ret = zapp_exec_in_main_context(NULL, _zapp_state_machine_change_state, (void*)tostate);
|
|
if(ret != 0){
|
|
ZLOGE("zapp_state_machine_change_state failed");
|
|
ZASSERT(0);
|
|
}
|
|
}
|
|
device_state_t zapp_state_machine_now_state() { return m_device_state; }
|
|
uint32_t zapp_state_machine_haspassed_ms() { return znordic_haspassed_ms(m_change_to_cur_state_tp); }
|
|
|
|
/***********************************************************************************************************************
|
|
* EBUS *
|
|
***********************************************************************************************************************/
|
|
bool zapp_ebus_push_event(app_event_t* event) {
|
|
uint32_t suc = app_sched_event_put(event, sizeof(app_event_t), app_event_process_cb); // app_event_process_cb(event, sizeof(app_event_t)
|
|
if (suc != 0) {
|
|
ZLOGE("app_sched_event_put failed");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool zapp_ebus_push_event_ext(uint8_t* hang_up_flag, app_event_t* event) {
|
|
event->hang_up_flag = hang_up_flag;
|
|
if (event->hang_up_flag) {
|
|
if (*event->hang_up_flag) {
|
|
return true;
|
|
}
|
|
|
|
*event->hang_up_flag = 1;
|
|
if (zapp_ebus_push_event(event)) {
|
|
return true;
|
|
} else {
|
|
*event->hang_up_flag = 0;
|
|
return false;
|
|
}
|
|
} else {
|
|
return zapp_ebus_push_event(event);
|
|
}
|
|
}
|
|
|
|
bool zapp_ebus_push_delayed_event(int delay, app_event_t* event) {
|
|
zevent_preset_tmr_t* tmr = NULL;
|
|
CRITICAL_REGION_ENTER();
|
|
for (int i = 0; i < 10; i++) {
|
|
if (!m_delay_event_preset_tmr[i].usage) {
|
|
tmr = &m_delay_event_preset_tmr[i];
|
|
tmr->usage = true;
|
|
break;
|
|
}
|
|
}
|
|
CRITICAL_REGION_EXIT();
|
|
if (tmr == NULL) {
|
|
return false;
|
|
}
|
|
|
|
tmr->eventcache = *event;
|
|
|
|
uint32_t suc = app_timer_start(tmr->tmrid, APP_TIMER_TICKS(delay), tmr);
|
|
if (suc != NRF_SUCCESS) {
|
|
tmr->usage = false;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void zapp_ebus_reg_event_listener(app_event_listener_t listener) {
|
|
ZASSERT(m_listener_num < 10);
|
|
m_listener[m_listener_num++].cbfunc = listener;
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* GSTATE *
|
|
***********************************************************************************************************************/
|
|
static gstate_t gstate;
|
|
gstate_t* zapp_get_gstate() { return &gstate; }
|
|
|
|
void zapp_gstate_set_is_over30s(bool over30s) {
|
|
gstate_t* p_gstate = zapp_get_gstate();
|
|
p_gstate->sample_capture_state_is_over30s = over30s;
|
|
}
|
|
void zapp_gstate_set_preview_state(bool is_preview) {
|
|
gstate_t* p_gstate = zapp_get_gstate();
|
|
p_gstate->is_preview = is_preview;
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* zapp_exec_in_main_context *
|
|
***********************************************************************************************************************/
|
|
typedef struct {
|
|
uint8_t* hang_up_flag;
|
|
void (*handler)(void*);
|
|
void* usrdata;
|
|
} zapp_exec_in_main_context_t;
|
|
|
|
static void zapp_exec_once_event_handler(void* p_event_data, uint16_t event_size) {
|
|
zapp_exec_in_main_context_t* event = (zapp_exec_in_main_context_t*)p_event_data;
|
|
if (event->hang_up_flag) {
|
|
*event->hang_up_flag = 0;
|
|
}
|
|
event->handler(event->usrdata);
|
|
}
|
|
|
|
uint32_t zapp_exec_in_main_context(uint8_t* hang_up_flag, void (*handler)(void*), void* usrdata) {
|
|
zapp_exec_in_main_context_t event = {0};
|
|
event.hang_up_flag = hang_up_flag;
|
|
event.handler = handler;
|
|
event.usrdata = usrdata;
|
|
|
|
/**
|
|
* @brief
|
|
* 1. 如果hang_up_flag为空,则无论事件队列中是否已经存在事件,都会推入事件队列
|
|
* 2. 如果hang_up_flag不为空,则只有当事件队列中没有该事件时,才会推入事件队列(应用于定时器周期调度事件)
|
|
*/
|
|
|
|
if (hang_up_flag) {
|
|
if (*hang_up_flag != 0) {
|
|
return 0;
|
|
}
|
|
|
|
*hang_up_flag = 1;
|
|
uint32_t ret = app_sched_event_put(&event, sizeof(zapp_exec_in_main_context_t), zapp_exec_once_event_handler);
|
|
if (ret != 0) {
|
|
*hang_up_flag = 0;
|
|
}
|
|
return ret;
|
|
} else {
|
|
return app_sched_event_put(&event, sizeof(zapp_exec_in_main_context_t), zapp_exec_once_event_handler);
|
|
}
|
|
}
|