Ejemplo n.º 1
0
/****************************************************************************
 *
 * NAME: cbvMcRxHandler
 *
 * DESCRIPTION:
 *
 * RETURNS:
 *
 ****************************************************************************/
PUBLIC void cbToCoNet_vRxEvent(tsRxDataApp *pRx) {
	int i;

	// print coming payload
	V_PRINTF(
			"\n\r[PKT Ad:%04x,Ln:%03d,Seq:%03d,Lq:%03d,Tms:%05d \"",
			pRx->u32SrcAddr, pRx->u8Len, // Actual payload byte: the network layer uses additional 4 bytes.
			pRx->u8Seq, pRx->u8Lqi, pRx->u32Tick & 0xFFFF);

	for (i = 0; i < pRx->u8Len; i++) {
		if (i < 32) {
			V_PUTCHAR((pRx->auData[i] >= 0x20 && pRx->auData[i] <= 0x7f) ?
							pRx->auData[i] : '.');
		} else {
			V_PRINTF( "..");
			break;
		}
	}
	V_PRINTF( "\"]");

	// 直接受信したパケットを上位へ転送する
	if (pRx->auData[0] == 'T') {
		tsTxDataApp sTx;
		memset(&sTx, 0, sizeof(sTx));

		sTx.u32DstAddr = TOCONET_NWK_ADDR_PARENT;
		sTx.u32SrcAddr = ToCoNet_u32GetSerial(); // Transmit using Long address
		sTx.u8Cmd = 0; // data packet.

		sTx.u8Seq = pRx->u8Seq;
		sTx.u8CbId = pRx->u8Seq;

		sTx.u16DelayMax = 300; // 送信開始の遅延を大きめに設定する

		memcpy(sTx.auData, pRx->auData, pRx->u8Len);
		sTx.auData[0] = 'R';
		sTx.u8Len = pRx->u8Len;

#ifdef USE_AES
		sTx.bSecurePacket = TRUE;
#endif

		SPRINTF_vRewind();
		vfPrintf(SPRINTF_Stream, ":%03d", pRx->u8Lqi);

		memcpy(sTx.auData + sTx.u8Len, SPRINTF_pu8GetBuff(), SPRINTF_u16Length());
		sTx.u8Len += SPRINTF_u16Length();

		ToCoNet_Nwk_bTx(sAppData.pContextNwk, &sTx);
	}
}
Ejemplo n.º 2
0
/** @ingroup MBUSA
 * 自身のシリアル番号を出力する(起動時メッセージにも利用)
 * @param pSer 出力先ストリーム
 */
void vModbOut_MySerial(tsFILE *pSer) {
	uint8 *q = au8SerOutBuff;

	S_OCTET(VERSION_MAIN);
	S_OCTET(VERSION_SUB);
	S_OCTET(VERSION_VAR);

	S_BE_DWORD(ToCoNet_u32GetSerial());

	SerCmdAscii_Output_AdrCmd(pSer,
			SERCMD_ADDR_FR_MODULE,
			SERCMD_ID_INFORM_MODULE_ADDRESS,
			au8SerOutBuff,
			q - au8SerOutBuff);
}
Ejemplo n.º 3
0
/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 *
 * RETURNS:
 *
 ****************************************************************************/
void cbAppColdStart(bool_t bAfterAhiInit) {
	if (!bAfterAhiInit) {
		// before AHI initialization (very first of code)

		// Module Registration
		ToCoNet_REG_MOD_ALL();
	} else {
		// clear application context
		memset(&sAppData, 0x00, sizeof(sAppData));

		// SPRINTF
		SPRINTF_vInit128();

		// Configuration
		// フラッシュメモリからの読み出し
		//   フラッシュからの読み込みが失敗した場合、ID=15 で設定する
		sAppData.bFlashLoaded = Config_bLoad(&sAppData.sFlash);

		// ToCoNet configuration
		sToCoNet_AppContext.u32AppId = sAppData.sFlash.sData.u32appid;
		sToCoNet_AppContext.u8Channel = sAppData.sFlash.sData.u8ch;
		sToCoNet_AppContext.u32ChMask = sAppData.sFlash.sData.u32chmask;

		sToCoNet_AppContext.u8TxMacRetry = 1;
		sToCoNet_AppContext.bRxOnIdle = TRUE;

		// event machine
		ToCoNet_Event_Register_State_Machine(vProcessEvCore); // main state machine

		// Other Hardware
		vSerialInit();
		ToCoNet_vDebugInit(&sSerStream);
		ToCoNet_vDebugLevel(TOCONET_DEBUG_LEVEL);

		vInitHardware(FALSE);
		Interactive_vInit();

		// START UP MESSAGE
		vfPrintf(&sSerStream, "\r\n*** ToCoTemp Parent %d.%02d-%d ***",
				VERSION_MAIN, VERSION_SUB, VERSION_VAR);
		vfPrintf(&sSerStream, LB "* App ID:%08x Long Addr:%08x Short Addr %04x",
				sToCoNet_AppContext.u32AppId, ToCoNet_u32GetSerial(),
				sToCoNet_AppContext.u16ShortAddress);
	}
}
Ejemplo n.º 4
0
/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 *
 * RETURNS:
 *
 ****************************************************************************/
PUBLIC void cbAppColdStart(bool_t bAfterAhiInit) {
	if (!bAfterAhiInit) {
		// before AHI initialization (very first of code)

		// Module Registration
		ToCoNet_REG_MOD_ALL();
	} else {
		// clear application context
		memset(&sAppData, 0x00, sizeof(sAppData));
		memset(&sSerCmd, 0x00, sizeof(sSerCmd));

		// SPRINTF
		SPRINTF_vInit128();

		// configure network]
		sToCoNet_AppContext.u32AppId = APP_ID;
		sToCoNet_AppContext.u8Channel = CHANNEL;
		sToCoNet_AppContext.u32ChMask = CHMASK;

		sToCoNet_AppContext.u8TxMacRetry = 1;
		sToCoNet_AppContext.bRxOnIdle = TRUE;

		// version info
		sAppData.u32ToCoNetVersion = ToCoNet_u32GetVersion();

		// event machine
		ToCoNet_Event_Register_State_Machine(vProcessEvCore); // main state machine

		// Other Hardware
		vSerialInit();
		ToCoNet_vDebugInit(&sSerStream);
		ToCoNet_vDebugLevel(TOCONET_DEBUG_LEVEL);

		vInitHardware(FALSE);

		// START UP MESSAGE
		vfPrintf(&sSerStream, "\r\n\r\n*** " APP_NAME " %d.%02d-%d ***",
				VERSION_MAIN, VERSION_SUB, VERSION_VAR);
		vfPrintf(&sSerStream, LB "* App ID:%08x Long Addr:%08x Short Addr %04x",
				sToCoNet_AppContext.u32AppId, ToCoNet_u32GetSerial(),
				sToCoNet_AppContext.u16ShortAddress);
	}
}
/** @ingroup FLASH
 * フラッシュ設定構造体をデフォルトに巻き戻します。
 * - ここでシステムのデフォルト値を決めています。
 *
 * @param p 構造体へのアドレス
 */
void Config_vSetDefaults(tsFlashApp *p) {
	p->u32appid = ToCoNet_u32GetSerial();
	p->u8ch = ((p->u32appid - 1) & 0xF) + 11;	// 1..0x10 => 11..26
	p->u32chmask = (1UL << p->u8ch);
	p->u8pow = 3;

	p->u8role = E_APPCONF_ROLE_MAC_NODE;
	p->u8layer = 1;

	p->u16SleepDur_ms = MODE4_SLEEP_DUR_ms;
	p->u16SleepDur_s = (MODE7_SLEEP_DUR_ms / 1000);
	p->u8Fps = 32;

	p->u32PWM_Hz = 1000;

	p->u32baud_safe = UART_BAUD_SAFE;
	p->u8parity = 0; // none

#ifdef USE_TOCOSTICK
	p->u32Opt = E_APPCONF_OPT_DISABLE_ADC;  // ToCoStick では AI 入力は未接続なので無効化しておく
	p->u8id = 121; // ToCoStick では親機をデフォルトにする
#elif BICYCLEFINDER_MASTER
	p->u8id = 127;
	p->u32Opt = E_APPCONF_OPT_DISABLE_ADC|E_APPCONF_OPT_NO_ADC_BASED_TRANSMIT|E_APPCONF_OPT_ON_PRESS_TRANSMIT;
#elif BICYCLEFINDER_SLAVE
	p->u8id = 124;
	p->u32Opt = (E_APPCONF_OPT_PWM_INIT_LOW
			| E_APPCONF_OPT_LOUDNESS_EN1 | E_APPCONF_OPT_LOUDNESS_EN2
			| E_APPCONF_OPT_DISABLE_ADC);
#else
	p->u8id = 0;
	p->u32Opt = E_APPCONF_OPT_DISABLE_ADC;	// DISABLE_ADC
#endif

#ifdef BICYCLEFINDER_SLAVE
	p->u32Opt2 = 0x00000030;	// DO1-2のpull up停止
#else
	p->u32Opt2 = 0x00000000;
#endif

	p->u8MML_idx = 0;
}
Ejemplo n.º 6
0
/** @ingroup MASTER
 * I2C のコマンドを実行して、応答を返します。
 * 無線経由ので要求の場合は、応答は送信元へ無線パケットで戻されます。
 * アドレスが0xDBの場合は、要求は自身のモジュールで実行された上 UART に応答します。
 *
 * - 入力フォーマット
 *   - OCTET: ネットワークアドレス(宛先,0xDBは自身のモジュールで実行してUARTに出力)
 *   - OCTET: 0x88
 *   - OCTET: 要求番号
 *   - OCTET: コマンド (0x1: Write, 0x2: Read, 0x3: Write and Increment, 0x4: Write and Read)
 *   - OCTET: I2Cアドレス
 *   - OCTET: I2Cコマンド
 *   - OCTET: データサイズ (無い時は 0)
 *   - OCTET[N]: データ (データサイズが0のときは、本フィールドは無し)
 *
 * - 出力フォーマット
 *   - OCTET: ネットワークアドレス
 *   - OCTET: 0x89
 *   - OCTET: 要求番号、入力フォーマットの値がコピーされる
 *   - OCTET: コマンド (0x1: Write, 0x2: Read)
 *   - OCTET: 0:FAIL, 1:SUCCESS
 *   - OCTET: データサイズ (無い時は 0)
 *   - OCTET[N]: データ (データサイズが0のときは、本フィールドは無し)
 *
 * @param p 入力書式のバイト列
 * @param u16len バイト列長
 * @param u8AddrSrc 要求元のネットワークアドレス
 */
void vProcessI2CCommand(uint8 *p, uint16 u16len, uint8 u8AddrSrc) {
	//uint8 *p_end = p + u16len;
	uint8 au8OutBuf[256 + 32];
	uint8 *q = au8OutBuf;

	bool_t bOk = TRUE;
	uint8 n;
	static volatile uint16 x;

	// 入力データの解釈
	uint8 u8Addr = G_OCTET();
	(void) u8Addr;

	uint8 u8Command = G_OCTET();
	if (u8Command != SERCMD_ID_I2C_COMMAND) {
		return;
	}

	uint8 u8ReqNum = G_OCTET();
	uint8 u8I2C_Oper = G_OCTET();
	uint8 u8I2C_Addr = G_OCTET();
	uint8 u8I2C_Cmd = G_OCTET();
	uint8 u8DataSize = G_OCTET();

	uint8 *pu8data = p;
	//uint8 *pu8data_end = p + u8DataSize;

#if 0
	if (pu8data_end != p_end) {
		DBGOUT(1, "I2CCMD: incorrect data."LB);
		return;
	}
#endif

	// 出力用のバッファを用意しておく
	S_OCTET(sAppData.u8AppLogicalId);
	S_OCTET(SERCMD_ID_I2C_COMMAND_RESP);
	S_OCTET(u8ReqNum);
	S_OCTET(u8I2C_Oper);
	//ここで q[0] 成功失敗フラグ, q[1] データサイズ, q[2]... データ
	q[0] = FALSE;
	q[1] = 0;

	DBGOUT(1, "I2CCMD: req#=%d Oper=%d Addr=%02x Cmd=%02x Siz=%d"LB, u8ReqNum,
			u8I2C_Oper, u8I2C_Addr, u8I2C_Cmd, u8DataSize);

	switch (u8I2C_Oper) {
	case 1:
		bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd, u8DataSize,
				u8DataSize == 0 ? NULL : pu8data);
		break;

	case 2:
		if (u8DataSize > 0) {
			bOk &= bSMBusSequentialRead(u8I2C_Addr, u8DataSize, &(q[2]));
			if (bOk)
				q[1] = u8DataSize;
		} else {
			bOk = FALSE;
		}
		break;

	case 3:
		for (n = 0; n < u8DataSize; n++) {
			bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd + n, 1, &pu8data[n]);
			for (x = 0; x < 16000; x++)
				; //wait (e.g. for memory device)
		}
		break;

	case 4:
		if (u8DataSize > 0) {
			bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd, 0, NULL );
			if (bOk)
				bOk &= bSMBusSequentialRead(u8I2C_Addr, u8DataSize, &(q[2]));
			if (bOk)
				q[1] = u8DataSize;
		} else {
			bOk = FALSE;
		}
		break;

#ifdef USE_I2C_ACM1620
	case 0x21: // ACM1620
		bDraw2LinesLcd_ACM1602((const char *) pu8data,
				(const char *) (pu8data + 16));
		break;
#endif

#ifdef USE_I2C_AQM0802A
	case 0x22: // ACM1620
		bDraw2LinesLcd_AQM0802A((const char *) pu8data,
				(const char *) (pu8data + 8));
		break;
#endif

	default:
		DBGOUT(1, "I2CCMD: unknown operation(%d)."LB, u8I2C_Oper);
		return;
	}

	q[0] = bOk; // 成功失敗フラグを書き込む
	q = q + 2 + q[1]; // ポインタ q を進める(データ末尾+1)

	if (u8AddrSrc == SERCMD_ADDR_TO_MODULE) {
		SerCmdAscii_Output_AdrCmd(&sSerStream, u8AddrSrc, au8OutBuf[1],
				au8OutBuf + 2, q - au8OutBuf - 2);
	} else {
		i16TransmitSerMsg(au8OutBuf, q - au8OutBuf, ToCoNet_u32GetSerial(),
				sAppData.u8AppLogicalId, u8AddrSrc, FALSE,
				sAppData.u8UartReqNum++);
	}
}
Ejemplo n.º 7
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);
		}

		// 初期化後速やかに送信要求
		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_LIS3DH); // パケット識別子

		S_OCTET(sAppData.sSns.u8Batt);
		S_BE_WORD(sAppData.sSns.u16Adc1);
		S_BE_WORD(sAppData.sSns.u16Adc2);
		S_BE_WORD(sObjLIS3DH.ai16Result[LIS3DH_IDX_X]);
		S_BE_WORD(sObjLIS3DH.ai16Result[LIS3DH_IDX_Y]);
		S_BE_WORD(sObjLIS3DH.ai16Result[LIS3DH_IDX_Z]);

		/*	DIの入力状態を取得	*/
		uint8 DI_Bitmap = readInput();
		S_OCTET( DI_Bitmap );

		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(); // 送信処理をタイマーを待たずに実行する
		} 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); // スリープ状態へ遷移
	}
}
/**
 * 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); // スリープ状態へ遷移
	}
}
Ejemplo n.º 9
0
/****************************************************************************
 *
 * NAME: vHandleSerialInput
 *
 * DESCRIPTION:
 *
 * PARAMETERS:      Name            RW  Usage
 *
 * RETURNS:
 *
 * NOTES:
 ****************************************************************************/
PRIVATE void vHandleSerialInput() {
	// handle UART command
	while (!SERIAL_bRxQueueEmpty(sSerPort.u8SerialPort)) {
		int16 i16Char;

		i16Char = SERIAL_i16RxChar(sSerPort.u8SerialPort);

		// process
		if (i16Char >=0 && i16Char <= 0xFF) {
			uint8 u8res = u8ParseSerCmd(&sSerCmd, (uint8)i16Char);
			if (u8res == E_SERCMD_VERBOSE) {
				vfPrintf(&sSerStream, "\n\rVERBOSE MODE = %s", bSerCmd_VerboseMode ? "ON" : "OFF");
				continue;
			}
			if (!bSerCmd_VerboseMode) continue;

			switch (i16Char) {
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				sAppData.sFlash.sData.u8Layer = i16Char - '0';
				if (bFlash_Write(&sAppData.sFlash, FLASH_SECTOR_NUMBER - 1, 0)) {
					V_PRINTF( LB "Flash Saved (Router Layer #%d)... RESETTING", sAppData.sFlash.sData.u8Layer);
					vWait(100000);
					vAHI_SwReset();
				} else {
					V_PRINTF( LB "Failed to save flash...");
				}
				break;

			case 'i': // info
				_C {
					tsToCoNet_NwkLyTr_Context *pc = (tsToCoNet_NwkLyTr_Context *)(sAppData.pContextNwk);

					V_PRINTF( LB "Info: la=%d ty=%d ro=%02x st=%02x",
							pc->sInfo.u8Layer, pc->sInfo.u8NwkTypeId, pc->sInfo.u8Role, pc->sInfo.u8State);
					V_PRINTF( LB "Parent: %08x", pc->u32AddrHigherLayer);
					V_PRINTF( LB "LostParent: %d", pc->u8Ct_LostParent);
					V_PRINTF( LB "SecRescan: %d, SecRelocate: %d", pc->u8Ct_Second_To_Rescan, pc->u8Ct_Second_To_Relocate);
				}
				break;

			case '>':
				sToCoNet_AppContext.u8Channel++;
				if (sToCoNet_AppContext.u8Channel > 25)
					sToCoNet_AppContext.u8Channel = 0;
				ToCoNet_vRfConfig();
				V_PRINTF( LB"channel set to %d.", sToCoNet_AppContext.u8Channel);
				break;

			case '<':
				sToCoNet_AppContext.u8Channel--;
				if (sToCoNet_AppContext.u8Channel < 11)
					sToCoNet_AppContext.u8Channel = 25;
				ToCoNet_vRfConfig();
				V_PRINTF( LB"channel set to %d.", sToCoNet_AppContext.u8Channel);
				break;

			case 't':
				SPRINTF_vRewind();
				vfPrintf(SPRINTF_Stream, "TEST FROM ROUTER(#%08X)", ToCoNet_u32GetSerial());
				bTransmitToParent(sAppData.pContextNwk, SPRINTF_pu8GetBuff(), SPRINTF_u16Length());
				break;

			case 'd': case 'D':
				_C {
					static uint8 u8DgbLvl;

					u8DgbLvl++;
					if(u8DgbLvl > 10) u8DgbLvl = 0;
					ToCoNet_vDebugLevel(u8DgbLvl);

					V_PRINTF( LB"set NwkCode debug level to %d.", u8DgbLvl);
				}
				break;

			default:
				break;
			}
		}
	}
Ejemplo n.º 10
0
/**
 * 初期化メッセージ
 */
void vSerInitMessage() {
	V_PRINTF(LB "*** " APP_NAME " (Router) %d.%02d-%d ***", VERSION_MAIN, VERSION_SUB, VERSION_VAR);
	V_PRINTF(LB "* App ID:%08x Long Addr:%08x Short Addr %04x LID %02d",
			sToCoNet_AppContext.u32AppId, ToCoNet_u32GetSerial(), sToCoNet_AppContext.u16ShortAddress,
			sAppData.sFlash.sData.u8id);
}
Ejemplo n.º 11
0
/****************************************************************************
 *
 * NAME: cbvMcRxHandler
 *
 * DESCRIPTION:
 *
 * RETURNS:
 *
 ****************************************************************************/
PUBLIC void cbToCoNet_vRxEvent(tsRxDataApp *pRx) {
	int i;

	// print coming payload
	V_PRINTF(
			LB "[PKT Ad:%04x,Ln:%03d,Seq:%03d,Lq:%03d,Tms:%05d %s\"",
			pRx->u32SrcAddr, pRx->u8Len, // Actual payload byte: the network layer uses additional 4 bytes.
			pRx->u8Seq, pRx->u8Lqi, pRx->u32Tick & 0xFFFF, pRx->bSecurePkt ? "Enc " : "");

	for (i = 0; i < pRx->u8Len; i++) {
		if (i < 32) {
			V_PUTCHAR((pRx->auData[i] >= 0x20 && pRx->auData[i] <= 0x7f) ?
							pRx->auData[i] : '.');
		} else {
			V_PRINTF( "..");
			break;
		}
	}
	V_PRINTF( "\"]");

	// 暗号化対応時に平文パケットは受信しない
	if (IS_APPCONF_OPT_SECURE()) {
		if (!pRx->bSecurePkt) {
			V_PRINTF( ".. skipped plain packet.");
			return;
		}
	}

	// 直接受信したパケットを上位へ転送する
	//
	// 直接親機宛(TOCONET_NWK_ADDR_PARENT指定で送信)に向けたパケットはここでは処理されない。
	// 本処理はアドレス指定がTOCONET_NWK_ADDR_NEIGHBOUR_ABOVEの場合で、一端中継機が受け取り
	// その中継機のアドレス、受信時のLQIを含めて親機に伝達する方式である。
	if (pRx->auData[0] == 'T') {
		tsTxDataApp sTx;
		memset(&sTx, 0, sizeof(sTx));
		uint8 *q = sTx.auData;

		S_OCTET('R'); // 1バイト目に中継機フラグを立てる
		S_BE_DWORD(pRx->u32SrcAddr); // 子機のアドレスを
		S_OCTET(pRx->u8Lqi); // 受信したLQI を保存する

		memcpy(sTx.auData + 6, pRx->auData + 1, pRx->u8Len - 1); // 先頭の1バイトを除いて5バイト先にコピーする
		q += pRx->u8Len - 1;

		sTx.u8Len = q - sTx.auData;

		sTx.u32DstAddr = TOCONET_NWK_ADDR_PARENT;
		sTx.u32SrcAddr = ToCoNet_u32GetSerial(); // Transmit using Long address
		sTx.u8Cmd = 0; // data packet.

		sTx.u8Seq = pRx->u8Seq;
		sTx.u8CbId = pRx->u8Seq;

		sTx.u16DelayMax = 300; // 送信開始の遅延を大きめに設定する


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

		ToCoNet_Nwk_bTx(sAppData.pContextNwk, &sTx);
	}
}
Ejemplo n.º 12
0
static void vProcessEvCore(tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
	switch (pEv->eState) {

	/*
	 * 起動時の状態
	 *   ToCoNetの接続を行う。
	 *   - スリープ復帰時は直前のアドレスに対して復帰をかける。失敗した場合は再探索を行う。
	 */
	case E_STATE_IDLE:
		// start up message
		V_PRINTF(LB "*** ToCoSamp IO Monitor %d.%02d-%d %s ***", VERSION_MAIN, VERSION_SUB, VERSION_VAR, sAppData.bWakeupByButton ? "BTN" : "OTR");
		V_PRINTF(LB "* App ID:%08x Long Addr:%08x Short Addr %04x",
				sToCoNet_AppContext.u32AppId, ToCoNet_u32GetSerial(), sToCoNet_AppContext.u16ShortAddress);

		SERIAL_vFlush(UART_PORT);

		if (eEvent == E_EVENT_START_UP) {
			if (IS_APPCONF_OPT_SECURE()) {
				bool_t bRes = bRegAesKey(sAppData.sFlash.sData.u32EncKey);
				V_PRINTF(LB "*** Register AES key (%d) ***", bRes);
			}
#ifdef USE_LCD
			vLcdInit(); // register sLcd

			// 最下行を表示する
			V_PRINTF_LCD_BTM("*** ToCoSamp IO Monitor %d.%02d-%d ***", VERSION_MAIN, VERSION_SUB, VERSION_VAR);
			vLcdRefresh();
#endif
		}

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

			/*
			 * 接続復帰(スリープ後)
			 */
			sAppData.eLedState = E_LED_WAIT;

			ToCoNet_Nwk_bResume(sAppData.pContextNwk); // ネットワークの復元

			ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_NW_START);

		} else
		if (eEvent == E_EVENT_START_UP) {
			V_PRINTF(LB "* start end device[%d]", u32TickCount_ms & 0xFFFF);

			/*
			 * ネットワークの接続
			 */
			sAppData.sNwkLayerTreeConfig.u8Role = TOCONET_NWK_ROLE_ENDDEVICE; // EndDevice として構成する
			sAppData.sNwkLayerTreeConfig.u8ScanDur_10ms = 4; // 探索時間(中継機の数が数個程度なら 40ms 程度で十分)

			sAppData.pContextNwk = ToCoNet_NwkLyTr_psConfig(&sAppData.sNwkLayerTreeConfig); // 設定
			if (sAppData.pContextNwk) {
				ToCoNet_Nwk_bInit(sAppData.pContextNwk); // ネットワーク初期化
				ToCoNet_Nwk_bStart(sAppData.pContextNwk); // ネットワーク開始
			}

			sAppData.eLedState = E_LED_WAIT;
			ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_NW_START);

			break;
		}

		break;

	/*
	 * ネットワークの開始待ち
	 */
	case E_STATE_APP_WAIT_NW_START:
		if (eEvent == E_EVENT_TOCONET_NWK_START) {
			ToCoNet_Event_SetState(pEv, E_STATE_RUNNING);
		}
		if (ToCoNet_Event_u32TickFrNewState(pEv) > 500) {
			ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);
		}
		break;

	/*
	 * 実行時の状態
	 *   - ネットワーク開始後、メッセージプール要求を行う
	 *   - ネットワークがエラーになったり、タイムアウトが発生した場合はエラー状態とし、
	 *     再びスリープする
	 */
	case E_STATE_RUNNING:
		if (eEvent == E_EVENT_NEW_STATE) {
			// ネットワーク開始
			V_PRINTF(LB"[NWK STARTED and REQUEST IO STATE:%d]", u32TickCount_ms & 0xFFFF);
			static uint8 u8Ct;
#ifdef MSGPL_SLOT_TEST
			// メッセージプールの複数スロットのテストを行う
			// 起動ごとにスロット番号を変更して取得する
			u8Ct++;
#else
			u8Ct = 0;
#endif
			// メッセージプールの要求
			if (ToCoNet_MsgPl_bRequest(u8Ct % TOCONET_MOD_MESSAGE_POOL_MAX_ENTITY)) {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_WAIT_RX);
			} else {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_RECV_ERROR);
			}
		} else
		if (eEvent == E_EVENT_TOCONET_NWK_DISCONNECT) {
			ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_RECV_ERROR);
		} else {
			if (ToCoNet_Event_u32TickFrNewState(pEv) > ENDD_TIMEOUT_CONNECT_ms) {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_RECV_ERROR);
			}
		}
		break;

	/*
	 * メッセージプールからの伝達待ち。
	 * - メッセージプールは cbToCoNet_vNwkEvent() に通知され、
	 *   その関数中でE_EVENT_APP_GET_IC_INFOイベントを発行する。
	 */
	case E_STATE_APP_IO_WAIT_RX:
		if (eEvent == E_EVENT_NEW_STATE) {
			V_PRINTF(LB"[E_STATE_APP_IO_WAIT_RX:%d]", u32TickCount_ms & 0xFFFF);
		} if (eEvent == E_EVENT_APP_GET_IC_INFO) {
			// メッセージが届いた
			if (u32evarg) {
				V_PRINTF(LB"[E_STATE_APP_IO_WAIT_RX:GOTDATA:%d]", u32TickCount_ms & 0xFFFF);
				ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);
			} else {
				ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_RECV_ERROR);
			}
		} else {
			// タイムアウト
			if (ToCoNet_Event_u32TickFrNewState(pEv) > ENDD_TIMEOUT_WAIT_MSG_ms) {
				V_PRINTF(LB"[E_STATE_APP_IO_WAIT_RX:TIMEOUT:%d]", u32TickCount_ms & 0xFFFF);
				ToCoNet_Event_SetState(pEv, E_STATE_APP_IO_RECV_ERROR);
			}
		}
		break;

	/*
	 * 送信完了の処理
	 * - スリープ実行
	 */
	case E_STATE_APP_IO_RECV_ERROR:
	case E_STATE_APP_SLEEP:
		if (eEvent == E_EVENT_NEW_STATE) {
			if (pEv->eState == E_STATE_APP_SLEEP) {
				V_PRINTF(LB"[E_STATE_APP_SLEEP_LED:%d]", u32TickCount_ms & 0xFFFF);
				sAppData.eLedState = E_LED_RESULT;
			} else {
				V_PRINTF(LB"[E_STATE_APP_IO_RECV_ERROR:%d]", u32TickCount_ms & 0xFFFF);
				sAppData.eLedState = E_LED_ERROR;
			}

			vPortSetHi(PORT_KIT_LED1);
			vPortSetHi(PORT_KIT_LED2);
#ifdef NO_SLEEP
			ToCoNet_Event_SetState(pEv, E_STATE_APP_PREUDO_SLEEP);
#else
			ToCoNet_Nwk_bPause(sAppData.pContextNwk);

			SERIAL_vFlush(UART_PORT);
			vSleep(0, FALSE, FALSE);
#endif
		}
		break;

	case E_STATE_APP_PREUDO_SLEEP:
		// 指定時間スリープ相当の時間待ちを行う
		if (ToCoNet_Event_u32TickFrNewState(pEv) > ENDD_SLEEP_PERIOD_s * 1000UL) {
			ToCoNet_Event_SetState(pEv, E_STATE_RUNNING);
		}
		break;

	default:
		break;
	}
}
Ejemplo n.º 13
0
/*	パケットを送信する状態	*/
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);
	}
}