#define GLOBALS_BSP_CAN                 //**   250bps  no resistor   **//
#include "../app_Headers/g_includes.h"


/*-------------------------------------------------------------------------
* Function Name  : bsp_CAN_Init
* Description    : CAN初始化
* Input          : None
* Output         : None
* Return         : None
* onther         : 
--------------------------------------------------------------------------*/
void  bsp_CAN_Init(void)
{
    INT16U b = null;
    CANCTL0_INITRQ = Enable;                //准备初始化 
    
    while(!CANCTL1_INITAK);                 //等待进入初始化模式
    
    CANCTL1   = CANCTL1_CANE_MASK | CANCTL1_BORM_MASK;  
    CANCTL1_WUPM   = Disable;               //所有显性唤醒
    /*
    SYNC_SEG + (PROP_SEG + PHASE_SEG1) + (PHASE_SEG2)
    1 Tq         4--16  Tq                  2--8  Tq 
    */ 
  
    CANBTR1_TSEG_10 = Seg1_5Tq;    //351page  75%  75<= sp<=83            6
    CANBTR1_TSEG_20 = Seg2_2Tq;  
    CANBTR1_SAMP    = SAMP_1;  
   // CANBTR1=(10)|(3<<4);		//设为1次采样                                        //2
    CANBTR0_SJW     = SJW_1Tq;     //重新同步        
    
    CANBTR0_BRP     = 0;     //one      null
    
             
    CANIDAC_IDAM   = IDAM_2_32Bit;
    CANIDAC_IDHIT  = IDHIT0;                //滤波器 0 有效   
         
    CANIDAR0       = null;                  //   标识符接收寄存器
    CANIDAR1       = null;
    CANIDAR2       = null;
    CANIDAR3       = null;
    CANIDAR4       = null;
    CANIDAR5       = null;
    CANIDAR6       = null;
    CANIDAR7       = null;   
     
    CANIDMR0       = 0xFF;                  //标识符掩码寄存器
    CANIDMR1       = 0xFF;
    CANIDMR2       = 0xFF;
    CANIDMR3       = 0xFF;
    CANIDMR4       = 0xFF;
    CANIDMR5       = 0xFF;
    CANIDMR6       = 0xFF;
    CANIDMR7       = 0xFF;
    //
    CANTIER = null;     
    CANCTL0_INITRQ = Disable;               //完成初始化
    while(CANCTL1_INITAK);                  //等待确认

    CANRFLG_RXF = ClearFlag;     
    CANRIER_RXFIE = Enable;                 //使能接收中断
    CANTIER_TXEIE = Disable;                //禁止发送中断 
    
    CANCTL0_TIME   = Enable;                //使能时间戳  
    CANCTL0_CSWAI  = WaitRun;               //等待模式下可以运行    
    CANCTL0_WUPE = Enable; 
}
/*-------------------------------------------------------------------------
* Function Name  : bsp_delay
* Description    : 延时
* Input          : None
* Output         : None
* Return         : None
* onther         : 
--------------------------------------------------------------------------*/
void bsp_IIC_delay(void)
{
    INT32U i= 0;
  	  
    while(i < 9999)
    {
	     i++;
	     _FEED_COP(); 
    }
}
/*-------------------------------------------------------------------------
* Function Name  : EXT_ID_TO_PGN
* Description    : 将扩展ID转换为PGN
* Input          : IDR0_Add          -> 对应的IDR0的地址
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/
INT32U    bsp_GET_PGN(INT8U *IDR0_Add)
{
    INT32U    dwPGN;
    INT8U     *bp;
    
    bp = (INT8U*)&dwPGN;
    
    *(bp    ) = *(IDR0_Add    ); 
    *(bp + 1) = *(IDR0_Add + 1); 
    *(bp + 2) = *(IDR0_Add + 2); 
    *(bp + 3) = *(IDR0_Add + 3); 

    dwPGN = ((dwPGN & 0x7FFFF) >> 1) | ((dwPGN & 0xFFE00000) >> 3);

    //return(GET_EXTPGN(dwPGN));                 //计算PGN
    return dwPGN;    
}
/*-------------------------------------------------------------------------
* Function Name  : GET_EXTID_SA
* Description    : 提取源地址
* Input          : IDR3_Add          -> 对应的IDR3的地址
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/
INT8U    bsp_GET_STAND_SA(INT8U *IDR3_Add)
{
    INT8U    SA;
    
    SA = *(IDR3_Add -1);
    SA = SA & 0x01;
    SA = SA << 7;
    SA = (*IDR3_Add >> 1) | SA;
    return(SA);
}
/*-------------------------------------------------------------------------
* Function Name  : GET_STAND_ID
* Description    : 提取标准ID
* Input          : IDR0_Add          -> 对应的IDR0的地址
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/
INT16U    bsp_GET_STAND_ID(INT8U *IDR0_Add)
{
    INT16U    dwPGN;
    INT8U     *bp;
    
    bp = (INT8U*)&dwPGN;
    
    *(bp    ) = *(IDR0_Add    ); 
    *(bp + 1) = *(IDR0_Add + 1); 


    dwPGN = dwPGN>>5;

    return(dwPGN);                 
}
/*-------------------------------------------------------------------------
* Function Name  : bsp_CANSendExtFrame
* Description    : 
* Input          : 
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/
 #if qi

INT8U bsp_CANSendExtFrame (INT32U id,INT8U priority,INT8U length,INT8U *txdata)
{
    INT8U txbuffer,index;
    INT16U cn = null;
    if (!CANTFLG) //Is Transmit Buffer full ? Full ( TXEx=0;)
      return   failt;
    if(id == null)
      return   failt;
    CANTBSEL = CANTFLG; /* Select lowest empty buffer */
    txbuffer = CANTBSEL; // Backup selected buffer
    /* Load Id to IDR Register */
    //*((unsigned long *) ((unsigned long)(&CANTXIDR0))) = id; // I appreciate this , easy and good.
   /* CANTXIDR0 = (INT8U)((id & 0x1fe00000)>>21);
    CANTXIDR1 = (INT8U)((id & 0x001c0000)>>13);
    CANTXIDR1 |= (INT8U)((id & 0x00038000)>>14);
    CANTXIDR1 |= 0x11;
    CANTXIDR2 = (INT8U)((id & 0x00007f80)>>7);
    CANTXIDR3 = (INT8U)((id & 0x0000007f)<<1);  
   */ 
    //====
        CANTXIDR0 = (INT8U)((id & 0x1fe00000)>>21);
        CANTXIDR1 = (INT8U)((id & 0x001c0000)>>13);
        CANTXIDR1 |= (INT8U)((id & 0x00038000)>>15);
        CANTXIDR1 |= 0x18;
        CANTXIDR2 = (INT8U)((id & 0x00007f80)>>7);
        CANTXIDR3 = (INT8U)((id & 0x0000007f)<<1); 
    
    
    ////==
    //====

    if(length>8)
        length=8;
    for ( index=0; index < length; index++) {
        *(&CANTXDSR0 + index) = txdata[index]; //Load data to Tx buffer Data Segment Registers
    }

    CANTXDLR = length; /* Set Data Length Code */
    CANTXTBPR = priority; /* Set Priority */
    CANTFLG = txbuffer; /* Start transmission */
   /* while ((CANTFLG & txbuffer) != txbuffer)
    {
          //; // Wait for Transmission   completion
          cn++;
          if(cn > 5000)
              break;
    } */
    return success;
}

#else
INT8U bsp_CANSendExtFrame(INT32U id,INT8U prio ,INT8U len,INT8U *dat)
{  
    INT8U txbuffer,i;
    INT16U cnt = 0;

    if (!CANTFLG)    return   failt;
    if(id == null)   return   failt;          
    
     CANTBSEL = CANTFLG;                                                //Select lowest empty buffer 
    txbuffer = CANTBSEL;                                                    // Backup selected buffer
    if (id < 0x00000800)                                                      //standerd   frame   0X7FF
    {
        CANTXIDR0 = (INT8U)(id>>3);
        CANTXIDR1 = id<<5;
        CANTXIDR2 = 0;
        CANTXIDR3 = 0;
    } 
    else                                                                                  //ext  frame
    {
        CANTXIDR0 = (INT8U)((id & 0x1fe00000)>>21);      
        CANTXIDR1 = (INT8U)((id & 0x001c0000)>>13);
        CANTXIDR1 |= (INT8U)((id & 0x00038000)>>15);
        CANTXIDR1 |= 0x18;
        CANTXIDR2 = (INT8U)((id & 0x00007f80)>>7);
        CANTXIDR3 = (INT8U)((id & 0x0000007f)<<1);        
    }             
    for(i=0;i<8;i++)   *(&CANTXDSR0+i) = *dat++;  //Load data to Tx buffer Data Segment Registers          
    if(len>8)   len=8;
    CANTXDLR = len;                                                // Set Data Length Code 
    CANTXTBPR = prio;                                             // Set Priority 
    CANTFLG = txbuffer;                                               // Start transmission 
    return txbuffer;
    // while ((CANTFLG & txbuffer) != txbuffer)  if(++cnt>WaitOverTime)break;    return success;           // Wait for Transmission   completion    
}
   
   #endif 
/*-------------------------------------------------------------------------
* Function Name  : bsp_CANSendFrame
* Description    : 
* Input          : 
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/

INT8U bsp_CANSendFrame (INT32U id,INT8U priority,INT8U length,INT8U *txdata)
{
    INT8U txbuffer,index;
    INT16U cn = null;
    if (!CANTFLG) //Is Transmit Buffer full ? Full ( TXEx=0;)
      return   failt;

    if(id == null)
      return   failt;
    
    CANTBSEL = CANTFLG; /* Select lowest empty buffer */
    txbuffer = CANTBSEL; // Backup selected buffer
    /* Load Id to IDR Register */
    //*((unsigned long *) ((unsigned long)(&CANTXIDR0))) = id; // I appreciate this , easy and good.
    CANTXIDR0 = (INT8U)(id>>3);
    CANTXIDR1 = id<<5;
    CANTXIDR2 = 0;
    CANTXIDR3 = 0;
    if(length>8)
        length=8;
    for ( index=0; index < length; index++) {
        *(&CANTXDSR0 + index) = txdata[index]; //Load data to Tx buffer Data Segment Registers
    }

    CANTXDLR = length; /* Set Data Length Code */
    CANTXTBPR = priority; /* Set Priority */
    CANTFLG = txbuffer; /* Start transmission */
    while ((CANTFLG & txbuffer) != txbuffer)
    {
          //; // Wait for Transmission   completion
          cn++;
          if(cn> 5000)
              break;
    } 
    return success;
}

#pragma CODE_SEG  NON_BANKED
#pragma TRAP_PROC
/*-------------------------------------------------------------------------
* Function Name  : bsp_CAN_Rev_isr
* Description    : 提取标准ID
* Input          : IDR0_Add          -> 对应的IDR0的地址
* Output         : None
* Return         : dwPGN
* onther         : 
--------------------------------------------------------------------------*/  
interrupt void bsp_CAN_Rev_isr(void)
{
   INT32U    ext_id;

   ext_id = bsp_GET_PGN((INT8U*)&CANRXIDR0);
    
   if(ext_id == 0x18DAF917)
   {
       if(Lock == 0) 
       {
          g_Msg18DAF917.Data[0] = CANRXDSR0;
          g_Msg18DAF917.Data[1] = CANRXDSR1;
          g_Msg18DAF917.Data[2] = CANRXDSR2;
          seed1  = CANRXDSR3;
          seed2  = CANRXDSR4;
          seed3  = CANRXDSR5;
          seed4  = CANRXDSR6;  
          g_Msg18DAF917.Data[7] = CANRXDSR7; 
          if((g_Msg18DAF917.Data[0] == 0x06)&& (g_Msg18DAF917.Data[1] == 0x67) && (g_Msg18DAF917.Data[2] == 0x01)) 
          {
             Lock = 1;
          }
       } 
       
       if(LockY == 0) 
       {
          g_Msg18DAF917.Data[0] = CANRXDSR0;
          g_Msg18DAF917.Data[1] = CANRXDSR1;
          g_Msg18DAF917.Data[2] = CANRXDSR2;
          seed1  = CANRXDSR3;
          seed2  = CANRXDSR4;
          seed3  = CANRXDSR5;
          seed4  = CANRXDSR6;  
          g_Msg18DAF917.Data[7] = CANRXDSR7; 
          if((g_Msg18DAF917.Data[0] == 0x06)&& (g_Msg18DAF917.Data[1] == 0x67) && (g_Msg18DAF917.Data[2] == 0x01)) 
          {
             LockY = 1;
          }
       }       
   }  

    
    ///        
    CANRFLG_RXF = ClearFlag; 
}
#pragma CODE_SEG DEFAULT