/**************************************************************************** * * NAME: vInitHardware * * DESCRIPTION: * * RETURNS: * ****************************************************************************/ static void vInitHardware(int f_warm_start) { // インタラクティブモードの初期化 Interactive_vInit(); // LED's vPortAsOutput(PORT_KIT_LED1); vPortAsOutput(PORT_KIT_LED2); vPortAsOutput(PORT_KIT_LED3); vPortAsOutput(PORT_KIT_LED4); vPortSetHi(PORT_KIT_LED1); vPortSetHi(PORT_KIT_LED2); vPortSetHi(PORT_KIT_LED3); vPortSetHi(PORT_KIT_LED4); if (!f_warm_start && bPortRead(PORT_CONF2)) { sAppData.bConfigMode = TRUE; } // activate tick timers memset(&sTimerApp, 0, sizeof(sTimerApp)); sTimerApp.u8Device = E_AHI_DEVICE_TIMER0; sTimerApp.u16Hz = 1; sTimerApp.u8PreScale = 10; vTimerConfig(&sTimerApp); vTimerStart(&sTimerApp); }
PRIVATE void vInitHardware(int f_warm_start) { // LED's vPortAsOutput(PORT_KIT_LED1); vPortAsOutput(PORT_KIT_LED2); vPortAsOutput(PORT_KIT_LED3); vPortAsOutput(PORT_KIT_LED4); vPortSetHi(PORT_KIT_LED1); vPortSetHi(PORT_KIT_LED2); vPortSetHi(PORT_KIT_LED3); vPortSetHi(PORT_KIT_LED4); // activate tick timers memset(&sTimerApp, 0, sizeof(sTimerApp)); sTimerApp.u8Device = E_AHI_DEVICE_TIMER0; sTimerApp.u16Hz = 1; sTimerApp.u8PreScale = 10; vTimerConfig(&sTimerApp); vTimerStart(&sTimerApp); }
/** * 始動時の処理 * * @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 (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); // スリープ状態へ遷移 } }