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

#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);
}
}