Beispiel #1
0
/*
 * DIの状態をBitMapにして返す
 */
static uint8 readInput(void)
{
	uint8	bitmap = 0;
	bool_t	btn;
	uint8	i;

	uint8 au8PortTbl_DIn[4] = {
		PORT_INPUT1,
		PORT_INPUT2,
		PORT_INPUT3,
		PORT_INPUT4
	};

	for( i=0; i<4; i++ ){
		btn = bPortRead(au8PortTbl_DIn[i]);
		if( btn ){
			bitmap |= ( 1UL<<i );
		}
	}
	return bitmap;
}
/**
 * UART コマンド待ち
 * @param E_STATE_RUNNING
 * @param pEv
 * @param eEvent
 * @param u32evarg
 */
PRSEV_HANDLER_DEF(E_STATE_RUNNING, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
	if (eEvent == E_EVENT_NEW_STATE) {
		uint8 au8msg[16], *q = au8msg;

		V_PRINTF(LB "[RUNNING]");
		V_FLUSH();

		// 起動メッセージとしてシリアル番号を出力する
		S_BE_DWORD(ToCoNet_u32GetSerial());
		sSerCmdOut.au8data = au8msg;
		sSerCmdOut.u16len = q - au8msg;

		sSerCmdOut.vOutput(&sSerCmdOut, &sSerStream);
	} else
#if 0
	if (!bPortRead(DIO_BUTTON)) {
		// DIO_BUTTON が Hi に戻ったらスリープに戻す
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);
	} else
#endif
	if (eEvent == E_ORDER_KICK) {
		// UARTのコマンドが入力されるまで待って、送信
		tsSerCmd_Context *pCmd = NULL;
		if (u32evarg) {
			pCmd = (void*)u32evarg;
		}

		if (pCmd && pCmd->u16len <= 80) {
			; // この場合は処理する
		} else {
			ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);
			return;
		}

		V_PRINTF(LB"[RUNNING/UARTRECV ln=%d]", pCmd->u16len);
		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_UART); // パケット識別子
		S_OCTET(pCmd->u16len); // ペイロードサイズ
		memcpy(q, pCmd->au8data, pCmd->u16len); // データ部
		q += pCmd->u16len;

		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_RETRY);
		}

		if (bRetry) {
			sTx_Retry = sTx;
		}

		V_PRINTF(" FR=%04X", sAppData.u16frame_count);
	}

	// タイムアウト(期待の時間までにデータが来なかった)
	if (ToCoNet_Event_u32TickFrNewState(pEv) > sAppData.sFlash.sData.u32Slp) {
		V_PRINTF(LB"! TIME OUT (E_STATE_RUNNING)");
		ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
	}
}