Example #1
0
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();

		pEv->bKeepStateOnSetAll = FALSE; // スリープ復帰の状態を維持

		// Mininode の場合、特別な処理は無いのだが、ポーズ処理を行う
		ToCoNet_Nwk_bPause(sAppData.pContextNwk);

		// センサー用の電源制御回路を Hi に戻す
		vPortSetSns(FALSE);

#ifdef LITE2525A
		vPortSetLo(LED);
#else
		vPortSetHi(LED);
#endif
		// 周期スリープに入る
		if(sAppData.sFlash.sData.i16param == NORMAL || sAppData.sFlash.sData.i16param == NEKOTTER ){
			vSleep(sAppData.sFlash.sData.u32Slp, sAppData.u16frame_count == 1 ? FALSE : TRUE, FALSE);
		}else{
			//	割り込みの設定
			vAHI_DioSetDirection(PORT_INPUT_MASK_ADXL345, 0); // set as input
			(void)u32AHI_DioInterruptStatus(); // clear interrupt register
			vAHI_DioWakeEnable(PORT_INPUT_MASK_ADXL345, 0); // also use as DIO WAKE SOURCE
			vAHI_DioWakeEdge(PORT_INPUT_MASK_ADXL345, 0); // 割り込みエッジ(立上がりに設定)

			vSleep(0, FALSE, FALSE);
		}
	}
}
Example #2
0
PUBLIC void cbToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) {
	switch (u32DeviceId) {
	case E_AHI_DEVICE_ANALOGUE:
		break;

	case E_AHI_DEVICE_SYSCTRL:
		break;

	case E_AHI_DEVICE_TICK_TIMER:
		// LED BLINK
		vPortSet_TrueAsLo(PORT_KIT_LED2, u32TickCount_ms & 0x400);

		// LED ON when receive
		if (u32TickCount_ms - sAppData.u32LedCt < 300) {
			vPortSetLo(PORT_KIT_LED1);
		} else {
			vPortSetHi(PORT_KIT_LED1);
		}
		break;

	case E_AHI_DEVICE_TIMER0:
		break;

	default:
		break;
	}
}
/**
 * センサー値を格納する
 */
static void vStoreSensorValue() {
	// パルス数の読み込み
	bAHI_Read16BitCounter(E_AHI_PC_0, &sAppData.sSns.u16PC1); // 16bitの場合
	// パルス数のクリア
	bAHI_Clear16BitPulseCounter(E_AHI_PC_0); // 16bitの場合

	// パルス数の読み込み
	bAHI_Read16BitCounter(E_AHI_PC_1, &sAppData.sSns.u16PC2); // 16bitの場合
	// パルス数のクリア
	bAHI_Clear16BitPulseCounter(E_AHI_PC_1); // 16bitの場合

	// センサー値の保管
	sAppData.sSns.u16Adc1 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_ADC_1];
#ifdef USE_TEMP_INSTDOF_ADC2
	sAppData.sSns.u16Adc2 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_TEMP];
#else
	sAppData.sSns.u16Adc2 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_ADC_2];
#endif
	sAppData.sSns.u8Batt = ENCODE_VOLT(sAppData.sObjADC.ai16Result[TEH_ADC_IDX_VOLT]);

	// ADC1 が 1300mV 以上(SuperCAP が 2600mV 以上)である場合は SUPER CAP の直結を有効にする
	if (sAppData.sSns.u16Adc1 >= VOLT_SUPERCAP_CONTROL) {
		vPortSetLo(DIO_SUPERCAP_CONTROL);
	}

	// センサー用の電源制御回路を Hi に戻す
	vPortSetSns(FALSE);
}
/**
 * 始動時の処理
 *
 * @param E_STATE_IDLE
 * @param pEv
 * @param eEvent
 * @param u32evarg
 */
PRSEV_HANDLER_DEF(E_STATE_IDLE, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
	if (eEvent == E_EVENT_START_UP) {
		// 起動メッセージ
		vSerInitMessage();

		// 暗号化鍵の登録
		if (IS_APPCONF_OPT_SECURE()) {
			bool_t bRes = bRegAesKey(sAppData.sFlash.sData.u32EncKey);
			V_PRINTF(LB "*** Register AES key (%d) ***", bRes);
		}

		if (u32evarg & EVARG_START_UP_WAKEUP_RAMHOLD_MASK) {
			// Warm start message
			V_PRINTF(LB "*** Warm starting woke by %s. ***", sAppData.bWakeupByButton ? "DIO" : "WakeTimer");

			ToCoNet_Nwk_bResume(sAppData.pContextNwk);
			ToCoNet_Event_SetState(pEv, E_STATE_RUNNING);

			// RTS を設定
			vPortSetLo(PORT_RTS0);
		} else {
			// 開始する
			// start up message
			V_PRINTF(LB "*** Cold starting(UART)");
			V_PRINTF(LB "* start end device[%d]", u32TickCount_ms & 0xFFFF);

			sAppData.sNwkLayerTreeConfig.u8Role = TOCONET_NWK_ROLE_ENDDEVICE;
			// ネットワークの初期化
			sAppData.pContextNwk = ToCoNet_NwkLyTr_psConfig_MiniNodes(&sAppData.sNwkLayerTreeConfig);

			if (sAppData.pContextNwk) {
				// とりあえず初期化だけしておく
				ToCoNet_Nwk_bInit(sAppData.pContextNwk);
				ToCoNet_Nwk_bStart(sAppData.pContextNwk);
			}
			// 直ぐにスリープ
			ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);

			// RTS を設定
			vPortSetHi(PORT_RTS0);

			// 再送フラグ
			bRetry = ((sAppData.sFlash.sData.u8wait % 10) != 0);
			u16RetryDur = sAppData.sFlash.sData.u8wait * 10;
		}

		// ポート出力する
		vPortAsOutput(PORT_RTS0);

		// RC クロックのキャリブレーションを行う
		ToCoNet_u16RcCalib(sAppData.sFlash.sData.u16RcClock);
	}
}
PRSEV_HANDLER_DEF(E_STATE_APP_WAIT_TX, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
	if (eEvent == E_EVENT_NEW_STATE) {
		// ネットワークの初期化
		if (!sAppData.pContextNwk) {
			// 初回のみ
			sAppData.sNwkLayerTreeConfig.u8Role = TOCONET_NWK_ROLE_ENDDEVICE;
			sAppData.pContextNwk = ToCoNet_NwkLyTr_psConfig_MiniNodes(&sAppData.sNwkLayerTreeConfig);
			if (sAppData.pContextNwk) {
				ToCoNet_Nwk_bInit(sAppData.pContextNwk);
				ToCoNet_Nwk_bStart(sAppData.pContextNwk);
			} else {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
				return;
			}
		} else {
			// 一度初期化したら RESUME
			ToCoNet_Nwk_bResume(sAppData.pContextNwk);
		}

		uint8	au8Data[12];
		uint8*	q = au8Data;
		S_OCTET(sAppData.sSns.u8Batt);
		S_BE_WORD(sAppData.sSns.u16Adc1);
		S_BE_WORD(sAppData.sSns.u16Adc2);
		S_BE_WORD(sObjBME280.i16Temp);
		S_BE_WORD(sObjBME280.u16Hum);
		S_BE_WORD(sObjBME280.u16Pres);

		if ( bSendMessage( au8Data, q-au8Data ) ) {
		} else {
			ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // 送信失敗
		}

#ifdef LITE2525A
		vPortSetHi(LED);
#else
		vPortSetLo(LED);
#endif
		V_PRINTF(" FR=%04X", sAppData.u16frame_count);
	}

	if (eEvent == E_ORDER_KICK) { // 送信完了イベントが来たのでスリープする
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
	}

	// タイムアウト
	if (ToCoNet_Event_u32TickFrNewState(pEv) > 100) {
		V_PRINTF(LB"! TIME OUT (E_STATE_APP_WAIT_TX)");
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
	}
}
/**
 * センサー値を格納する
 */
static void vStoreSensorValue() {
	// センサー値の保管
	sAppData.sSns.u16Adc1 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_ADC_1];
#ifdef USE_TEMP_INSTDOF_ADC2
	sAppData.sSns.u16Adc2 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_TEMP];
#else
	sAppData.sSns.u16Adc2 = sAppData.sObjADC.ai16Result[TEH_ADC_IDX_ADC_2];
#endif
	sAppData.sSns.u8Batt = ENCODE_VOLT(sAppData.sObjADC.ai16Result[TEH_ADC_IDX_VOLT]);

	// ADC1 が 1300mV 以上(SuperCAP が 2600mV 以上)である場合は SUPER CAP の直結を有効にする
	if (sAppData.sSns.u16Adc1 >= VOLT_SUPERCAP_CONTROL) {
		vPortSetLo(DIO_SUPERCAP_CONTROL);
	}
}
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);
	}
}
Example #8
0
PRSEV_HANDLER_DEF(E_STATE_APP_WAIT_TX, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
	if (eEvent == E_EVENT_NEW_STATE) {
		// 暗号化鍵の登録
		if (IS_APPCONF_OPT_SECURE()) {
			bool_t bRes = bRegAesKey(sAppData.sFlash.sData.u32EncKey);
			V_PRINTF(LB "*** Register AES key (%d) ***", bRes);
		}

		// ネットワークの初期化
		if (!sAppData.pContextNwk) {
			// 初回のみ
			sAppData.sNwkLayerTreeConfig.u8Role = TOCONET_NWK_ROLE_ENDDEVICE;
			sAppData.pContextNwk = ToCoNet_NwkLyTr_psConfig_MiniNodes(&sAppData.sNwkLayerTreeConfig);
			if (sAppData.pContextNwk) {
				ToCoNet_Nwk_bInit(sAppData.pContextNwk);
				ToCoNet_Nwk_bStart(sAppData.pContextNwk);
			} else {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
				return;
			}
		} else {
			// 一度初期化したら RESUME
			ToCoNet_Nwk_bResume(sAppData.pContextNwk);
		}

		if( bFirst && sAppData.sFlash.sData.i16param != NORMAL && sAppData.sFlash.sData.i16param != NEKOTTER ){
			bFirst = FALSE;
			V_PRINTF(LB"*** First Sleep...");
			ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
		}else{
			bFirst = FALSE;
			// 初期化後速やかに送信要求
			V_PRINTF(LB"[SNS_COMP/TX]");
			sAppData.u16frame_count++; // シリアル番号を更新する

			tsTxDataApp sTx;
			memset(&sTx, 0, sizeof(sTx)); // 必ず0クリアしてから使う!
			uint8 *q =  sTx.auData;

			sTx.u32SrcAddr = ToCoNet_u32GetSerial();

			if (IS_APPCONF_OPT_TO_ROUTER()) {
				// ルータがアプリ中で一度受信して、ルータから親機に再配送
				sTx.u32DstAddr = TOCONET_NWK_ADDR_NEIGHBOUR_ABOVE;
			} else {
				// ルータがアプリ中では受信せず、単純に中継する
				sTx.u32DstAddr = TOCONET_NWK_ADDR_PARENT;
			}

			// ペイロードの準備
			S_OCTET('T');
			S_OCTET(sAppData.sFlash.sData.u8id);
			S_BE_WORD(sAppData.u16frame_count);

			S_OCTET(PKT_ID_ADXL345); // パケット識別子

			S_OCTET(sAppData.sSns.u8Batt);
			S_BE_WORD(sAppData.sSns.u16Adc1);
			S_BE_WORD(sAppData.sSns.u16Adc2);
			S_BE_WORD(sObjADXL345.ai16Result[ADXL345_IDX_X]);
			S_BE_WORD(sObjADXL345.ai16Result[ADXL345_IDX_Y]);
			S_BE_WORD(sObjADXL345.ai16Result[ADXL345_IDX_Z]);

			S_OCTET(sAppData.sFlash.sData.i16param & 0x00FF);

			sTx.u8Len = q - sTx.auData; // パケットのサイズ
			sTx.u8CbId = sAppData.u16frame_count & 0xFF; // TxEvent で通知される番号、送信先には通知されない
			sTx.u8Seq = sAppData.u16frame_count & 0xFF; // シーケンス番号(送信先に通知される)
			sTx.u8Cmd = 0; // 0..7 の値を取る。パケットの種別を分けたい時に使用する
			//sTx.u8Retry = 0x81; // 強制2回送信

			V_PRINTF( LB"INT = %02X", sObjADXL345.u8Interrupt );

			if (IS_APPCONF_OPT_SECURE()) {
				sTx.bSecurePacket = TRUE;
			}

			vPortAsOutput(LED);
			if (ToCoNet_Nwk_bTx(sAppData.pContextNwk, &sTx)) {

				V_PRINTF(LB"TxOk");
#ifdef LITE2525A
				vPortSetHi(LED);
#else
				vPortSetLo(LED);
#endif
				ToCoNet_Tx_vProcessQueue(); // 送信処理をタイマーを待たずに実行する
			} else {
				V_PRINTF(LB"TxFl");
				ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // 送信失敗
			}

			V_PRINTF(" FR=%04X", sAppData.u16frame_count);
		}
	}
	if (eEvent == E_ORDER_KICK) { // 送信完了イベントが来たのでスリープする
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
	}

	// タイムアウト
	if (ToCoNet_Event_u32TickFrNewState(pEv) > 100) {
		V_PRINTF(LB"! TIME OUT (E_STATE_APP_WAIT_TX)");
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
	}
}