/**
 * @file Drv_USIM.c
 * @author 吳星萍(iris@e-besthealth.com)
 * @brief USIM0 USIM1 驅動程序
 * @version 0.1
 * @date 2020-06-27
 *
 * @copyright BEST HEALTH ELECTRONIC INC (c) 2019
 *
 * Compiler Ver. : V3.57
 * IDE3000  Ver. : V8.03
 * MCU/CFG  Ver. : BH67F5362/1.1
 */
#include "Project_Global.h"
#include "BH67F5362.h"
#include "Drv_USIM.h"
#include "Drv_GPIO.h"

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 變量定義 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
volatile USIM_STRUCT USIM_Data;

/**
 * @brief USIM 上電初始化
 *
 */
void Drv_USIM_PowerOn()
{

#ifdef USIM_MODE_IIC
	SET_PA5_SCK_SCL();
	SET_PA4_SDI_SDA(); 
	_sima = USIM_IIC_ADDRESS;
	_simc0 = 0xc4;		
	_simc1 = 0x02;			
	_simtoc = (USIM_IIC_TIMEOUT << 7) + USIM_IIC_TIMEOUT_PERIOD;
	_simen = 1;_simf = 0;_sime = 1;
#endif
#ifdef USIM_MODE_SPI
	SET_USIM_SPI_PIN();

//	_simc0 =0xa0; 			//SPI從機模式
	_simc0 =0x00;			//SPI主機模式，時鐘為Fsys/4
	_simc2 = 0x04;			//SCK 為高電平且在SCK 上升沿抓取數据，數據傳輸時低位優先
	_simen = 1;_simf = 0;_sime = 1;
#endif
    _mf3f=0;
    _mf3e=1;
   	_emi = 1;
}
/**
 * @brief USIM 休眠初始化
 *
 */
void Drv_USIM_PowerDown()
{

#ifdef USIM_MODE_IIC
	_simen = 0;
	_sime = 0; _simf = 0;
#endif
#ifdef USIM_MODE_SPI
	_simen = 0;
	_sime = 0; _simf = 0;
#endif
}

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

#ifdef USIM_MODE_IIC
	_simf=0;	
	if (_simtof)		// TimeOut溢出中斷
	{
		_simtof  = 0;
		_simtoen = 1;	// reset TimerOut
		_iamwu   = 1;
		USIM_Data.RxOffset = 0;
		USIM_Data.TxOffset = 0;
	}
	else
	{
		if(_haas && _srw)	// addres match and IIC tx mode
		{
			_htx = 1;		// config SLAVE TO TX
			_simd = USIM_Data.TxBuf[USIM_Data.TxOffset];
			USIM_Data.TxOffset++;
	/*		if (USIM_Data.TxOffset > 3)
			{
				USIM_Data.TxOffset = 0;
			}*/
		}
		if (_haas && !_srw)	// addres match and IIC rx mode
		{
			_htx      = 0; 		// config SLAVE TO RX
			_txak     = 0;		// SET ACK signal
			USIM_Data.RxBuf[USIM_Data.RxOffset] = _simd;	// Dummy read from SIMD to release SCL line
			USIM_Data.RxOffset++;
			
			if(USIM_Data.RxOffset >= 3)
			{
				USIM_Data.RxOffset = 0;
			}
		}
		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 ++;
				if (USIM_Data.TxOffset >= 3)
				{
					USIM_Data.TxOffset = 0;
				}
			}
		}
		if (!_haas && !_htx)	// addres not match and IIC rx mode
		{
			USIM_Data.RxBuf[USIM_Data.RxOffset] = _simd;
			USIM_Data.RxOffset++;
			if (USIM_Data.RxOffset > 3)
			{
				USIM_Data.RxOffset = 0;
				USIM_Data.flag.b.RxIsOK = 1;
			}
		}
	}
#endif
#ifdef USIM_MODE_SPI
	if (_trf)					//發送/接受結束標誌位
	{
		USIM_Data.RxBuf[USIM_Data.RxOffset] = _simd;
		USIM_Data.RxOffset ++;
		_trf = 0;
		do
		{
			_wcol = 0;
			
			_simd = USIM_Data.TxBuf[USIM_Data.TxOffset];
			USIM_Data.TxOffset ++;
			if (USIM_Data.RxOffset >= TXBUF_LENGTH)
			{
				USIM_Data.RxOffset = 0;
				USIM_Data.TxOffset = 0;
				USIM_Data.flag.b.RxIsOK = 1;
			}
		} while (_wcol);

    }
#endif
}
/********************************************************************
Function: Drv_SIMSPI_TxRxByte
INPUT	:
OUTPUT	:
NOTE	:
********************************************************************/
unsigned char Drv_SIMSPI_TxRxByte(volatile unsigned char txByte)
{
	do
	{
		_wcol = 0;				//寫衝突，有數據寫入
		GCC_CLRWDT();
		_simd = txByte;
	}while(_wcol);
	while(!_trf)
	{
		GCC_CLRWDT();
	}
	_trf = 0;
	return _simd;
}

void Drv_SIMSPI_TxRxBuf(unsigned char len, volatile unsigned char* txBuf)
{
	volatile unsigned char i=0;
	for(i=0;i<len;i++)
	{
		USIM_Data.RxBuf[i]=Drv_SIMSPI_TxRxByte(*(txBuf+i));
		_simf=0;
	}
}
