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