/* * ADC 計測をしてデータ送信するアプリケーション制御 */ PRSEV_HANDLER_DEF(E_STATE_IDLE, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { static bool_t bFirst = TRUE; if (eEvent == E_EVENT_START_UP) { if (u32evarg & EVARG_START_UP_WAKEUP_RAMHOLD_MASK) { // Warm start message V_PRINTF(LB "*** Warm starting woke by %s. ***", sAppData.bWakeupByButton ? "DIO" : "WakeTimer"); } else { // 開始する // start up message vSerInitMessage(); V_PRINTF(LB "*** Cold starting"); V_PRINTF(LB "* start end device[%d]", u32TickCount_ms & 0xFFFF); // BME280 の初期化 } // RC クロックのキャリブレーションを行う ToCoNet_u16RcCalib(sAppData.sFlash.sData.u16RcClock); // センサーがらみの変数の初期化 u8sns_cmplt = 0; vBME280_Init( &sObjBME280, &sSnsObj ); if( bFirst ){ V_PRINTF(LB "*** BME280 Setting..."); bFirst = FALSE; bBME280_Setting(); } vSnsObj_Process(&sSnsObj, E_ORDER_KICK); if (bSnsObj_isComplete(&sSnsObj)) { // 即座に完了した時はセンサーが接続されていない、通信エラー等 u8sns_cmplt |= E_SNS_BME280_CMP; V_PRINTF(LB "*** BME280 comm err?"); ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移 return; } // ADC の取得 vADC_WaitInit(); vSnsObj_Process(&sAppData.sADC, E_ORDER_KICK); // RUNNING 状態 ToCoNet_Event_SetState(pEv, E_STATE_RUNNING); } else { V_PRINTF(LB "*** unexpected state."); ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移 } }
/** * ハードウェアイベント(遅延実行) * @param u32DeviceId * @param u32ItemBitmap */ static void cbAppToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) { switch (u32DeviceId) { case E_AHI_DEVICE_TICK_TIMER: vProcessLIS3DH(E_EVENT_TICK_TIMER); break; case E_AHI_DEVICE_ANALOGUE: /* * ADC完了割り込み */ V_PUTCHAR('@'); vSnsObj_Process(&sAppData.sADC, E_ORDER_KICK); if (bSnsObj_isComplete(&sAppData.sADC)) { u8sns_cmplt |= E_SNS_ADC_CMP_MASK; vStoreSensorValue(); } break; case E_AHI_DEVICE_SYSCTRL: break; case E_AHI_DEVICE_TIMER0: break; default: break; } }
/** * ハードウェアイベント(遅延実行) * @param u32DeviceId * @param u32ItemBitmap */ static void cbAppToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) { switch (u32DeviceId) { case E_AHI_DEVICE_TICK_TIMER: break; case E_AHI_DEVICE_ANALOGUE: /* * ADC完了割り込み */ V_PUTCHAR('@'); vSnsObj_Process(&sAppData.sADC, E_ORDER_KICK); if (bSnsObj_isComplete(&sAppData.sADC)) { // 全チャネルの処理が終わったら、次の処理を呼び起こす vStoreSensorValue(); ToCoNet_Event_Process(E_ORDER_KICK, 0, vProcessEvCore); } break; case E_AHI_DEVICE_SYSCTRL: break; case E_AHI_DEVICE_TIMER0: break; default: break; } }
static void vProcessTSL2561(teEvent eEvent) { if (bSnsObj_isComplete(&sSnsObj)) { return; } // イベントの処理 vSnsObj_Process(&sSnsObj, eEvent); // ポーリングの時間待ち if (bSnsObj_isComplete(&sSnsObj)) { u8sns_cmplt |= E_SNS_TSL2561_CMP; V_PRINTF(LB"!TSL2561: %dC", sObjTSL2561.u32Result ); // 完了時の処理 if (u8sns_cmplt == E_SNS_ALL_CMP) { ToCoNet_Event_Process(E_ORDER_KICK, 0, vProcessEvCore); } } }
static void vProcessBME280(teEvent eEvent) { if (bSnsObj_isComplete(&sSnsObj)) { return; } // イベントの処理 vSnsObj_Process(&sSnsObj, eEvent); // ポーリングの時間待ち if (bSnsObj_isComplete(&sSnsObj)) { u8sns_cmplt |= E_SNS_BME280_CMP; V_PRINTF(LB"!BME280: Temp : %d, Hum : %d, Pres : %d", sObjBME280.i16Temp, sObjBME280.u16Hum, sObjBME280.u16Pres ); // 完了時の処理 if (u8sns_cmplt == E_SNS_ALL_CMP) { ToCoNet_Event_Process(E_ORDER_KICK, 0, vProcessEvCore); } } }
static void vProcessLIS3DH(teEvent eEvent) { if (bSnsObj_isComplete(&sSnsObj)) { return; } // イベントの処理 vSnsObj_Process(&sSnsObj, eEvent); // ポーリングの時間待ち if (bSnsObj_isComplete(&sSnsObj)) { u8sns_cmplt |= E_SNS_LIS3DH_CMP; V_PRINTF(LB"!LIS3DH: X : %d, Y : %d, Z : %d", sObjLIS3DH.ai16Result[LIS3DH_IDX_X], sObjLIS3DH.ai16Result[LIS3DH_IDX_Y], sObjLIS3DH.ai16Result[LIS3DH_IDX_Z] ); // 完了時の処理 if (u8sns_cmplt == E_SNS_ALL_CMP) { ToCoNet_Event_Process(E_ORDER_KICK, 0, vProcessEvCore); } } }
/* パケットを送信する状態 */ PRSEV_HANDLER_DEF(E_STATE_RUNNING, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) { if (eEvent == E_EVENT_NEW_STATE) { // ADC の開始 vADC_WaitInit(); vSnsObj_Process(&sAppData.sADC, E_ORDER_KICK); } if (eEvent == E_ORDER_KICK) { V_PRINTF(LB"[E_STATE_RUNNING/SNS_COMP]"); sAppData.u16frame_count++; // シリアル番号を更新する tsTxDataApp sTx; memset(&sTx, 0, sizeof(sTx)); // 必ず0クリアしてから使う! uint8 *q = sTx.auData; sTx.u32SrcAddr = ToCoNet_u32GetSerial(); sTx.u16DelayMin = 0; sTx.u16DelayMax = 0; sTx.u16RetryDur = 0; sTx.u8Retry = 0; 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(sAppData.sFlash.sData.u8mode); // パケット識別子 S_OCTET(sAppData.sSns.u8Batt); S_BE_WORD(sAppData.sSns.u16Adc1); S_BE_WORD(sAppData.sSns.u16Adc2); // 立ち上がりで起動 or 立ち下がりで起動 if( sAppData.sFlash.sData.i16param == 1 ){ S_OCTET(0x01); } else { S_OCTET(0x00); } /* DIの入力状態を取得 */ uint8 DI_Bitmap = readInput(); S_OCTET( DI_Bitmap ); sAppData.bDI1_Now_Opened = ((DI_Bitmap & 1) == 0); 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回送信 if (IS_APPCONF_OPT_SECURE()) { sTx.bSecurePacket = TRUE; } if (ToCoNet_Nwk_bTx(sAppData.pContextNwk, &sTx)) { V_PRINTF(LB"TxOk"); ToCoNet_Tx_vProcessQueue(); // 送信処理をタイマーを待たずに実行する ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_TX); } else { V_PRINTF(LB"TxFl"); ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); } V_PRINTF(" FR=%04X", sAppData.u16frame_count); } }