PRSEV_HANDLER_DEF(E_STATE_RUNNING, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { // 短期間スリープからの起床をしたので、センサーの値をとる if ((eEvent == E_EVENT_START_UP) && (u32evarg & EVARG_START_UP_WAKEUP_RAMHOLD_MASK)) { V_PRINTF("#"); vProcessLIS3DH(E_EVENT_START_UP); } // 2回スリープすると完了 if (u8sns_cmplt != E_SNS_ALL_CMP && (u8sns_cmplt & E_SNS_ADC_CMP_MASK)) { // ADC 完了後、この状態が来たらスリープする pEv->bKeepStateOnSetAll = TRUE; // スリープ復帰の状態を維持 vAHI_UartDisable(UART_PORT); // UART を解除してから(このコードは入っていなくても動作は同じ) vAHI_DioWakeEnable(0, 0); // スリープを行うが、WAKE_TIMER_0 は定周期スリープのためにカウントを続けているため // 空いている WAKE_TIMER_1 を利用する ToCoNet_vSleep(E_AHI_WAKE_TIMER_1, 50, FALSE, FALSE); // PERIODIC RAM OFF SLEEP USING WK1 } // 送信処理に移行 if (u8sns_cmplt == E_SNS_ALL_CMP) { ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_TX); } // タイムアウト if (ToCoNet_Event_u32TickFrNewState(pEv) > 100) { V_PRINTF(LB"! TIME OUT (E_STATE_RUNNING)"); ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移 } }
/** * アプリケーション再送の条件判定と短いスリープ処理 * * @param E_SATET_APP_RETRY * @param pEv * @param eEvent * @param u32evarg */ PRSEV_HANDLER_DEF(E_STATE_APP_RETRY, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { V_PRINTF(LB"!E_STATE_APP_RETRY (%d)", u8RetryCount); if (!bRetry || u8RetryCount == 0) { ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移 return; } // 遷移してきたとき if (eEvent == E_EVENT_NEW_STATE) { if (u8RetryCount == 0xff) { u8RetryCount = sAppData.sFlash.sData.u8wait % 10; } // 短いスリープを行う (u8RetryCount > 0) pEv->bKeepStateOnSetAll = TRUE; V_FLUSH(); uint16 u16dur = u16RetryDur / 2 + (ToCoNet_u32GetRand() % u16RetryDur); // +/-50% のランダム化 ToCoNet_vSleep(E_AHI_WAKE_TIMER_1, u16dur, FALSE, FALSE); return; } // スリープ復帰 if (eEvent == E_EVENT_START_UP) { V_PRINTF(LB"!woke from mini sleep(%d)", u8RetryCount); if (IS_APPCONF_OPT_SECURE()) { bRegAesKey(sAppData.sFlash.sData.u32EncKey); } ToCoNet_Nwk_bResume(sAppData.pContextNwk); ToCoNet_Event_SetState(pEv, E_STATE_APP_RETRY_TX); u8RetryCount--; // 再送回数を減らす return; } }
/* スリープをする状態 */ PRSEV_HANDLER_DEF(E_STATE_APP_SLEEP, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { if (eEvent == E_EVENT_NEW_STATE) { // Sleep は必ず E_EVENT_NEW_STATE 内など1回のみ呼び出される場所で呼び出す。 V_PRINTF(LB"Sleeping..."); V_FLUSH(); // Mininode の場合、特別な処理は無いのだが、ポーズ処理を行う ToCoNet_Nwk_bPause(sAppData.pContextNwk); // print message. vAHI_UartDisable(UART_PORT); // UART を解除してから(このコードは入っていなくても動作は同じ) // set UART Rx port as interrupt source vAHI_DioSetDirection(PORT_INPUT_MASK, 0); // set as input (void)u32AHI_DioInterruptStatus(); // clear interrupt register vAHI_DioWakeEnable(PORT_INPUT_MASK, 0); // also use as DIO WAKE SOURCE // i16paramに関わらず状態の変化で起床 if(sAppData.bDI1_Now_Opened) { vAHI_DioWakeEdge(0, PORT_INPUT_MASK); // 割り込みエッジ(立下りに設定) } else { vAHI_DioWakeEdge(PORT_INPUT_MASK, 0); // 割り込みエッジ(立上がりに設定) } // wake up using wakeup timer as well. ToCoNet_vSleep(E_AHI_WAKE_TIMER_0, sAppData.sFlash.sData.u32Slp, FALSE, FALSE ); // PERIODIC RAM OFF SLEEP USING WK0 } }
PRSEV_HANDLER_DEF(E_STATE_APP_SLEEP, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { if (eEvent == E_EVENT_NEW_STATE) { // Sleep は必ず E_EVENT_NEW_STATE 内など1回のみ呼び出される場所で呼び出す。 V_PRINTF(LB"! Sleeping..."); V_FLUSH(); // Mininode の場合、特別な処理は無いのだが、ポーズ処理を行う ToCoNet_Nwk_bPause(sAppData.pContextNwk); // センサー用の電源制御回路を Hi に戻す vPortSetSns(FALSE); #ifdef LITE2525A vPortSetLo(LED); #else vPortSetHi(LED); #endif vAHI_DioWakeEnable(0, PORT_INPUT_MASK); // DISABLE DIO WAKE SOURCE ToCoNet_vSleep( E_AHI_WAKE_TIMER_0, sAppData.sFlash.sData.u32Slp, FALSE, FALSE); } }
/* * 送信後のチャタリング対策を行う状態 */ PRSEV_HANDLER_DEF(E_STATE_APP_CHAT_SLEEP, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { /* 遷移してきたとき一旦眠る */ if(eEvent == E_EVENT_NEW_STATE){ V_PRINTF(LB"Safe Chattering..."); V_FLUSH(); // Mininode の場合、特別な処理は無いのだが、ポーズ処理を行う ToCoNet_Nwk_bPause(sAppData.pContextNwk); // 割り込み禁止でスリープ pEv->bKeepStateOnSetAll = TRUE; // この状態から起床 vAHI_DioWakeEnable(0, PORT_INPUT_MASK); // DISABLE DIO WAKE SOURCE ToCoNet_vSleep(E_AHI_WAKE_TIMER_1, 200UL, FALSE, FALSE); /* 起床後すぐこの状態になったときずっと眠る状態へ */ }else if(eEvent == E_EVENT_START_UP){ pEv->bKeepStateOnSetAll = FALSE; ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移 } }