/**
 * @file   CUnet.c
 * @author StepTechnica
 * @date   Sep. 05, 2025
 *
 * @brief Evaluation Board 用ソースファイル「CUnet 処理」
 *
 * @copyright (C) 2022- StepTechnica Co.,Ltd.
 *
 * このソフトウェアは、コピー利用、配布、変更の追加、変更を加えたもの再配布、商用利用、有料販売など、どなたも自由にお使いいただくことができます。
 * このソフトウェアには保証はついていません。
 * このソフトウェアを利用したことで問題が起きた際に、ソフトウェアの製作者は一切の責任を負いません。
 *
 */

/* -----------------------------------------------------------------------------
 * #include
 */
#include "CUnet.h"

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#include "ctrlUART4.h"
#include "IB49config.h"
#include "Utility.h"

/* -----------------------------------------------------------------------------
 * enumタグ定義 (typedefを同時に行う)
 */
typedef enum _CUStatus
{
    st_STOP = 0,	// STOP phase
	st_CALL,      	// CALL phase
	st_BREAK,       // BREAK phase
	st_RUN,	        // RUN phase
	st_GMM,	        // GMM phase
}CUStatus;


/* -----------------------------------------------------------------------------
 * 変数定義
 */
CUStatus        	gCUState = st_STOP;

/* -----------------------------------------------------------------------------
 * 関数プロトタイプ宣言
 */
void CUnet_main(void);
void CUnet_initialize(void);


/**
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * @brief： CUnet 処理
 * 
 * @note： main() から呼ばれるメインルーチン
 * 
 * @param  none
 * @retval none
 * 
 */
void CUnet_main(void)
{
	unsigned scr;
	unsigned cctr;

	scr = MKY_Read16(MKY49_SSR0);
	switch (gCUState) {
	case st_STOP:
		if ( scr & (1<<BIT_regSSR0_RUN) )
		{
			print_string("CUnet state=<RUN>.\n");
			gCUState = st_RUN;
		}
		else
		{
			if ( scr & (1<<BIT_regSSR0_CALL) )
			{
				//ビット10（CALL）が“1”になった。
				print_string("CUnet state=<CALL>.\n");
				gCUState = st_CALL;
			}
			if ( scr & (1<<BIT_regSSR0_BRK) )
			{
				//ビット11（BRK）が“1”になった。
				print_string("CUnet state=<BREAK>.\n");
				gCUState = st_BREAK;
			}
			if ( scr & (1<<BIT_regSSR0_GMM) )
			{
				//ビット15（GMM）が“1”になった。
				print_string("CUnet state=<GMM>.\n");
				gCUState = st_GMM;
			}
		}
		break;
	case st_CALL:
		if ( scr & (1<<BIT_regSSR0_RUN) )
		{
			print_string("CUnet state=<RUN>.\n");
			gCUState = st_RUN;
		}
		else
		{
			if ( !( scr & (1<<BIT_regSSR0_START) ) )
			{
				//ビット8（START）が“0”になった。
				print_string("CUnet state=<STOP>.\n");
				gCUState = st_STOP;
			}
		}
		break;
	case st_BREAK:
		if ( scr & (1<<BIT_regSSR0_RUN) )
		{
			print_string("CUnet state=<RUN>.\n");
			gCUState = st_RUN;
		}
		else
		{
			if ( !( scr & (1<<BIT_regSSR0_START) ) )
			{
				//ビット8（START）が“0”になった。
				print_string("CUnet state=<STOP>.\n");
				gCUState = st_STOP;
			}
		}
		break;
	case st_RUN:
		if ( !( scr & (1<<BIT_regSSR0_START) ) )
		{
			//ビット8（START）が“0”になった。
			print_string("CUnet state=<STOP>.\n");
			gCUState = st_STOP;
		}
		else
		{
			cctr = MKY_Read16(MKY49_CCTR);
			if ((cctr & 0xFF00) != 0 )
			{
				print_string("\nCUnet MCARE Detected.\n");
				MKY_Write16(MKY49_CCTCR, 0x0100);
			}
			if ((cctr & 0x00FF) != 0 )
			{
				print_string("\nCUnet LCARE Detected.\n");
				MKY_Write16(MKY49_CCTCR, 0x0001);
			}
		}
		break;
	case st_GMM:
		if ( !( scr & (1<<BIT_regSSR0_GMM) ) )
		{
			//ビット15（GMM）が“0”になった。
			print_string("CUnet state=<STOP>.\n");
			gCUState = st_STOP;
		}

		break;
	}

}


/**
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * @brief： CUnet 初期化
 * 
 * @note： メインループの前に実施する初期化
 * 
 * @param  none
 * @retval none
 * 
 */
void CUnet_initialize(void)
{
	bool	ret, matchCCR;
	int		loop;
	char	strCCR[10];

	gCUState = st_STOP;
	// Device Initialize
	ret = MKY_Initialize();
	if (ret == false) {
		// 初期化失敗
		print_string("Device initialize failed.\n");
		return;
	}

	loop = 0;
	do {
		delay_us(100);
		matchCCR = true;

		MKY_ReadBlock(MKY49_CCR, &strCCR[0], 8);
		strCCR[8] = '\0';
		if (strcmp(strCCR, VAL_CCR) != 0)	matchCCR = false;

		loop++;
		if (loop == 10000) {
			// CCR 確認失敗
			char string_buff[128];
			sprintf(&string_buff[0], "CCR is not correct.([%s]!=[%s])\n", VAL_CCR, strCCR);
			print_string(&string_buff[0]);
			return;
		}
	} while (matchCCR == false);

	//① 内部のメモリ（GM、MSB、MRB0、MRB1）へ“00H” のデータをライトし、ゼロクリアします。
	//前半
	MKY_FillMemory(MKY_OFS_MEMORY, 0, MKY_LEN_MEMORY);

#if defined(MKY_OFS_MEMORY_1) && (MKY_LEN_MEMORY_1 > 0)
	//後半
	MKY_FillMemory(MKY_OFS_MEMORY_1, 0, MKY_LEN_MEMORY_1);
#endif

}
