#include "r_typedefs.h"
#include "dr7f701441.dvf.h"
#include  "CSIH.h"
#include  "GPIO.h"



void INTCSIH0IC(void);
void INTCSIH0IR(void);
void INTCSIH1IC(void);
void INTCSIH1IR(void);



/*  释放CPU回调,用于降低功耗 或 操作系统调度  */
static void CSIH_CPU_SleepIdle(void)
{
//    WDT_Clear();   /*  阻塞发送时,防止看门狗复位  */
}

/*  将MFS初始化成SPI的只发送模式  */
/*  参数 channel 为通道号:0 到 1  */
/*  参数 baud 为波特率,即你的SPI的SCK的频率 单位:K */
/*  参数 bitnum 为data数据的bit位数  */
/*  参数 sck_edge 为SCK时钟信号的格式 CSIH_SCKH_Rising,  在时钟信号空闲时,为高电平, 上升沿取数
                                    CSIH_SCKH_Falling, 在时钟信号空闲时,为高电平, 下降沿取数  
                                    CSIH_SCKL_Rising,  在时钟信号空闲时,为低电平, 上升沿取数  
                                    CSIH_SCKL_Falling, 在时钟信号空闲时,为低电平, 下降沿取数  */
/*  参数 dat_format 为MOSI信号的发送数据的格式 CSIH_DAT_LSbit 表示低位先发出
                                        	 CSIH_DAT_MSbit表示高位先发出 */
void CSIH_Init(uint8_t channel, 
                   uint16_t baud,
				   uint8_t bitnum,
                   CSIH_SCK_Edge sck_edge, 
                   CSIH_DAT_FORMAT dat_format
                   )
{  
    if(channel > 1U)
    {	
    }
    else
    {	
	CSIH[channel]->unCTL0.u8Register  = 0x00U;
	CSIH[channel]->unCTL1.u32Register = 0x00020000UL;

	if(channel == 1U)
	{
	    CSIH[channel]->unCTL2.stcField.CSIHnPRS = 0U;
	    
	    switch(baud)		
	    {
		case 1000:
		    CSIH[channel]->unCTL2.stcField.CSIHnBRS    = 4U;
		    CSIH[channel]->unCFG0.stcField.PSCLxOBRSSx = 0U;
		    break;
		case 500:
		    CSIH[channel]->unCTL2.stcField.CSIHnBRS    = 8U;
		    CSIH[channel]->unCFG0.stcField.PSCLxOBRSSx = 0U;
		    break;
		case 250:
		    CSIH[channel]->unCTL2.stcField.CSIHnBRS    = 16U;
		    CSIH[channel]->unCFG0.stcField.PSCLxOBRSSx = 0U;
		    break;
		case 100:
		    CSIH[channel]->unCTL2.stcField.CSIHnBRS    = 40U;
		    CSIH[channel]->unCFG0.stcField.PSCLxOBRSSx = 0U;
		    break;
		default:
		    break;
	    }
	}
	else
	{
	    switch(baud)		
	    {
		case 1000:
		    CSIH[channel]->unCTL2.stcField.CSIHnPRS = 1U;
		    CSIH[channel]->unBRS0.stcField.CSIHnBRS = 2U;
		    break;
		case 500:
		    CSIH[channel]->unCTL2.stcField.CSIHnPRS = 1U;
		    CSIH[channel]->unBRS0.stcField.CSIHnBRS = 4U;
		    break;
		case 250:
		    CSIH[channel]->unCTL2.stcField.CSIHnPRS = 1U;
		    CSIH[channel]->unBRS0.stcField.CSIHnBRS = 8U;
		    break;
		case 100:
		    CSIH[channel]->unCTL2.stcField.CSIHnPRS = 1U;
		    CSIH[channel]->unBRS0.stcField.CSIHnBRS = 20U;
		    break;
		default:
		    break;
	    }

	    CSIH[channel]->unCFG0.stcField.PSCLxOBRSSx = 0U;
	}

	CSIH[channel]->unMCTL0.u16Register = 0x0100U;
	CSIH[channel]->unSTCR0.u16Register = 0x010BU;

	CSIH[channel]->unCFG0.stcField.CSIHnPSx  = 0U;
	CSIH[channel]->unCFG0.stcField.CSIHnDLSx = bitnum;
	CSIH[channel]->unCFG0.stcField.CSIHnRCBx = 0U;

	if(dat_format == CSIH_DAT_LSbit )				
	{
	    CSIH[channel]->unCFG0.stcField.CSIHnDIRx = 1U;	
	}
	else
	{
	    CSIH[channel]->unCFG0.stcField.CSIHnDIRx = 0U;
	}

	switch(sck_edge)
	{
	    case CSIH_SCKH_Rising :
		CSIH[channel]->unCFG0.stcField.CSIHnCKPx = 0U;
		CSIH[channel]->unCFG0.stcField.CSIHnDAPx = 0U;
		break;
	    case CSIH_SCKH_Falling :
		CSIH[channel]->unCFG0.stcField.CSIHnCKPx = 0U;
		CSIH[channel]->unCFG0.stcField.CSIHnDAPx = 1U;
		break;
	    case CSIH_SCKL_Rising :
		CSIH[channel]->unCFG0.stcField.CSIHnCKPx = 1U;
		CSIH[channel]->unCFG0.stcField.CSIHnDAPx = 1U;
		break;
	    case CSIH_SCKL_Falling :
		CSIH[channel]->unCFG0.stcField.CSIHnCKPx = 1U;
		CSIH[channel]->unCFG0.stcField.CSIHnDAPx = 0U;
		break;
	    default:
		break;		
	}

	CSIH[channel]->unCFG0.stcField.CSIHnIDLx = 0U;
	CSIH[channel]->unCFG0.stcField.CSIHnIDx  = 0U;
	CSIH[channel]->unCFG0.stcField.CSIHnHDx  = 0U;
	CSIH[channel]->unCFG0.stcField.CSIHnINx  = 0U;
	CSIH[channel]->unCFG0.stcField.CSIHnSPx  = 0U;
	
	CSIH[channel]->unCTL0.u8Register  |= 0xE0U;
	

	switch(channel)
        {
            case 0:
			PBGFSGD0BPROT0 = 0x07FFFFFFUL;
			INTC2EIC78     = 0x0047UL;
			INTC2EIC79     = 0x0047UL;
			break;
            case 1:
			PBGFSGD0BPROT0 = 0x07FFFFFFUL;
			INTC2EIC137    = 0x0047UL;
			INTC2EIC138    = 0x0047UL;
			break;
            default:
		    break;
        }

    }
       
}

/*  获取发送的忙状态,即发送是忙着呢吗?  */
/*  参数 channel 为通道号:0 到 1  */
/*  返回值:MFS_SPI_OptSt_OK=发送空闲, MFS_SPI_OptSt_BUSY=发送忙中*/
static CSIH_OptSt CSIH_IsSendBusy(uint8_t channel)
{
    CSIH_OptSt re_value = CSIH_OptSt_BUSY;
    
    if(channel > 1U)
    {
        re_value = CSIH_OptSt_BUSY;
    }
    else
    {
        if(CSIH[channel]->unSTR0.stcField.CSIHnTSF == 1U)
        {
            re_value = CSIH_OptSt_BUSY;
        }
        else
        {
            re_value = CSIH_OptSt_OK;
        }
    }  

    return re_value;
}

/*  阻塞等待发送忙完,即发送准备好了  */
/*  参数 channel 为通道号:0 到 1 */
static void CSIH_WaitForSendReady(uint8_t channel)
{    
    while(CSIH[channel]->unSTR0.stcField.CSIHnTSF == 1U)
    {
        CSIH_CPU_SleepIdle();  /*  释放CPU  */
    }
}


/*  发送数据,采12bit对齐,2个数据块的方式  */
/*  参数 channel 为通道号:0 到 1  */
/*  返回值:CSIH_OptSt_OK=发送成功, CSIH_OptSt_BUSY=发送忙中*/
CSIH_OptSt CSIH_SendData_12bit8th(uint8_t channel, uint16_t* pdat)
{
    uint8_t i;
    
    CSIH_OptSt re_value = CSIH_OptSt_BUSY;
    
    if(channel > 1U)
    {
        re_value = CSIH_OptSt_BUSY;
    }
    else
    {
	CSIH_WaitForSendReady(channel);
	CSIH[channel]->unMCTL2.u32Register &= 0x7FFFFFFFUL;
	CSIH[channel]->unMRWP0.u32Register &= 0xFFFFFF80UL;
	
#ifdef TLC6C5912
	CSIH[channel]->unMCTL2.u32Register = (0x00000010UL | (TLC6C5912_TOTAL_CHIP_NUM << 16U));
#else
	CSIH[channel]->unMCTL2.u32Register  = 0x00080010UL;
#endif

#ifdef TLC6C5912
	for(i=0U;i<TLC6C5912_TOTAL_CHIP_NUM;i++)
	{
	    CSIH[channel]->unTX0W.u32Register = (0x00FE0000UL | pdat[i]);
	}
#else
	for(i=0U;i<8U;i++)
	{
	    CSIH[channel]->unTX0W.u32Register = (0x00FE0000UL | pdat[i]);
	}
#endif

	CSIH[channel]->unMCTL2.u32Register |= 0x80000000UL;
	
        re_value = CSIH_OptSt_OK;
    }  
    
    return re_value;
}

/*  发送数据,采9bit对齐,1个数据块的方式  */
/*  参数 channel 为通道号:0 到 1  */
/*  返回值:CSIH_OptSt_OK=发送成功, CSIH_OptSt_BUSY=发送忙中*/
CSIH_OptSt CSIH_SendData_9bit1th(uint8_t channel, uint16_t* pdat)
{
    uint8_t i;
    
    CSIH_OptSt re_value = CSIH_OptSt_BUSY;
    
    if(channel > 1U)
    {
        re_value = CSIH_OptSt_BUSY;
    }
    else
    {
	CSIH_WaitForSendReady(channel);
	CSIH[channel]->unMCTL2.u32Register &= 0x7FFFFFFFUL;
	CSIH[channel]->unMRWP0.u32Register &= 0xFFFFFF80UL;
	CSIH[channel]->unMCTL2.u32Register  = 0x00010010UL;

	for(i=0U;i<1U;i++)
	{
	    CSIH[channel]->unTX0W.u32Register = (0x00FE0000UL | pdat[i]);
	}

	CSIH[channel]->unMCTL2.u32Register |= 0x80000000UL;
	
        re_value = CSIH_OptSt_OK;
    }  
    
    return re_value;
}


void CSIH_Ch0_Rx_ISR(void)/* CSIH0 Reception Status interrupt INTCSIH0IR */
{
    uint32_t data;

    data = CSIH[0]->unRX0H.u16Register;
    
    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC78   &= 0xEFFFU; 
}  

void CSIH_Ch1_Rx_ISR(void)	/* CSIH1 Reception Status interrupt INTCSIH1IR */
{
    uint32_t data;

    data = CSIH[1]->unRX0H.u16Register;
    
    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC137   &= 0xEFFFU; 
}  


void CSIH_Ch0_Tx_ISR(void)	/* CSIH0 Communication Status interrupt INTCSIH0IC*/
{     
    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC79   &= 0xEFFFU; 
	/* storage */
	//TLC6C5912_nCS = 1U;
}  

void CSIH_Ch1_Tx_ISR(void)	/* CSIH1 Communication Status interrupt INTCSIH1IC*/
{     
    PBGFSGD0BPROT0 = 0x07FFFFFFUL;
    INTC2EIC138   &= 0xEFFFU; 
}