Esempio n. 1
0
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); // スリープ状態へ遷移
		}
}