#include "USIM_API.h"
#include "USIM_Config.h"
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 變量定義 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
volatile USIM_STRUCT USIM_Data;

/**
 * @brief USIM 上電初始化
 *
 */
void fun_USIM_PowerOn()
{
#ifdef USIM_MODE_UART
	_simc0 = 0x10;
	SET_UART_Format_D8_NONE_S1(); // 數據傳輸格式設定
	SET_UART_BAUDRATE_38400();	// 波特率設定
	SET_UART_ADDRESS(DISABLE);
	SET_UART_RECEIVER_ISR(ENABLE);
	SET_UART_TRANSMITTER_ISR(ENABLE);
	SET_UART_TRANSMITTER_EMPTY_ISR(ENABLE);

	SET_USIM_UART_PIN();
	_uarten = 1; _utxen = 1; _urxen = 1;
	_usimf = 0;_txif = 0; _usime = 1;
	USIM_Data.RxLength = 6; //
#endif
#ifdef USIM_MODE_IIC
	SET_IIC_PIN();
	_sima = USIM_IIC_ADDRESS;
	_simc0 = (6 << 6) + (USIM_IIC_DEBOUNCE_TIME << 2);
	_simc1 = (USIM_IIC_ADDRESS_WAKE_UP << 1);
	_simtoc = (USIM_IIC_TIMEOUT << 7) + USIM_IIC_TIMEOUT_PERIOD;
	_simen = 1;_usimf = 0;_usime = 1;
#endif
#ifdef USIM_MODE_SPI
	SET_SPI_PIN();
	_simc0 = (USIM_SPI_MODE << 5);
	_simc2 = (USIM_SPI_CLOCK_EDGE << 4) + (USIM_SPI_DATA_MLS << 3) +( USIM_SPI_CSEN_PIN << 2);
	_simen = 1;_usimf = 0;_usime = 1;
#endif
   	_emi = 1;
}
/**
 * @brief USIM 休眠初始化
 *
 */
void fun_USIM_PowerDown()
{
#ifdef USIM_MODE_UART
	_uarten = 0; _utxen = 0; _urxen = 0;
	_usime = 0; _usimf = 0;
#endif
#ifdef USIM_MODE_IIC
	_simen = 0;
	_usime = 0; _usimf = 0;
#endif
#ifdef USIM_MODE_SPI
	_simen = 0;
	_usime = 0; _usimf = 0;
#endif
}

///********************************************************************
//Function: USIM
//INPUT	:
//OUTPUT:
//NOTE	: SPI/IIC/UART三選一
//********************************************************************/
DEFINE_ISR(USIM_ISR, USIM_VECTOR)
{

#ifdef USIM_MODE_UART
	// 奇偶校验出错
	// if (_perr0)
	// {
	// 	_acc = _usr;
	// 	_acc = _txr_rxr;
	// }
	// 錯誤處理
	if (_unf | _uferr | _uoerr)	//  噪声干扰错误 | 帧错误 | 溢出错误
	{
		_acc = _uusr;
		_acc = _utxr_rxr;
		USIM_Data.RxOffset = 0;
	}
	// 发送数据
	if (_utxif && USIM_Data.flag.b.TxIsBusy)
	{
		if ( USIM_Data.TxOffset <= USIM_Data.TxLength)
		{
			_utxr_rxr = USIM_Data.TxBuf[USIM_Data.TxOffset];
		}
		else
		{
			if (_utidle)
			{
				USIM_Data.flag.b.TxIsBusy = 0;
			}
		}
		USIM_Data.TxOffset++;
	}
	// 接收数据
	if (_urxif)
	{
		USIM_Data.RxBuf[USIM_Data.RxOffset] = _utxr_rxr;
		USIM_Data.RxOffset++;
		USIM_Data.RxTimeOut = 0;
        // 用戶需要在此寫Rx數據長度
        // 1 固定長度,則在初始化的時候初始化話 USIM_Data.RxLength
        // 2 協議自帶長度信息
//        if (USIM_Data.RxOffset == 3)
//        {
//        	USIM_Data.RxLength = USIM_Data.RxBuf[2];
//        }
        if (USIM_Data.RxOffset >= USIM_Data.RxLength)
        {
            USIM_Data.RxOffset = 0;
            USIM_Data.RxLength = 6;
            USIM_Data.flag.b.RxIsOK  = 1;
        }
	}
#endif
#ifdef USIM_MODE_IIC
	if (_simtof)		// TimeOut溢出中斷
	{
		_simtof  = 0;
		_simtoen = 1;	// reset TimerOut
		_iamwu   = 1;
		USIM_Data.RxOffset = 0;
		USIM_Data.TxOffset = 1;
	}
	else
	{
		if(_haas && _srw)	// addres match and IIC tx mode
		{
			_htx = 1;		// config SLAVE TO TX
			USIM_Data.TxOffset = 1;
			_simd = USIM_Data.TxBuf[USIM_Data.TxOffset];
			USIM_Data.TxOffset++;
		}
		else if (_haas && !_srw)	// addres match and IIC rx mode
		{
			_htx      = 0; 		// config SLAVE TO RX
			_txak     = 0;		// SET ACK signal
			_acc      = _simd;	// Dummy read from SIMD to release SCL line
			USIM_Data.RxOffset = 0;
		}
		else if (!_haas && _htx)	// addres not match and IIC tx mode
		{
			if(_rxak)
			{//rxak=1:主機停止拒絕接收下個字節，發出停止信號
				_htx  = 0;
				_txak = 0;
				_acc  = _simd;		//虛度數值釋放總線
			}
			else					//發送數據
			{
				_simd = USIM_Data.TxBuf[USIM_Data.TxOffset];
				USIM_Data.TxOffset ++;
			}
		}
		else if (!_haas && !_htx)	// addres not match and IIC rx mode
		{
			USIM_Data.RxBuf[USIM_Data.RxOffset] = _simd;
			USIM_Data.RxOffset++;
			if (USIM_Data.RxOffset >= 4)
			{
				USIM_Data.RxOffset = 0;
				USIM_Data.flag.b.RxIsOK = 1;
			}
		}
	}
#endif
#ifdef USIM_MODE_SPI
	if (_trf)
	{
		USIM_Data.RxBuf[USIM_Data.RxOffset] = _simd;
		_trf = 0;
		do
		{
			_wcol = 0;
			_simd = USIM_Data.TxBuf[USIM_Data.TxOffset];
		} while (_wcol);
#endif
}
/********************************************************************
Function: fun_SIMSPI_TxRxByte
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
unsigned char fun_SIMSPI_TxRxByte(unsigned char txData)
{
	do{
		_wcol = 0;
		GCC_CLRWDT();
		_simd = txData;
	}
	while(_wcol);
	while(!_trf)
	{
		GCC_CLRWDT();
	}
	_trf = 0;
	return _simd;
}

/********************************************************************
Function: uart發送開始
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
void fun_UartStartTx(unsigned char TxLength)
{
	USIM_Data.TxLength = TxLength;
	// Start TX
	USIM_Data.flag.b.TxIsBusy = 1; // uart 忙碌
	USIM_Data.TxOffset = 1; // 因為0已經直接發送了
	_acc = _usr;
	_txr_rxr = USIM_Data.TxBuf[0];
}
void fun_UartTimeOutReset()
{
    if (USIM_Data.RxTimeOut > 10)
    {
		_acc = _uusr;
		_acc = _utxr_rxr;
		USIM_Data.RxOffset = 0;
    }
}