/******************************************************************************
�� �� ����MSCAN0.h
����������MSCAN0�����շ����ƺ������ļ�
��    �ߣ�����
��    ����V1.0
��    �ڣ�2016.5.5
******************************************************************************/

#include <hidef.h>           /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "mc9s12xhy256.h"
#include "stdint.h" 
#include "comdef.h"
#include "Unit_Conv.h"


//#include "AutoGUI.h"
#include "main.h" 

/* Driver */
#include "CRG.h"
#include "ADC.h"
#include "GPIO.h"
#include "MSCAN0.h"
#include "PWM.h"
#include "SCI0_UART.h"

#include "Sound_List.h"

/* System */ 
#include "PowerManagement.h"
#include "API.h" 
#include "Line_In.h"
#include "Key.h"
#include "CRG.h"

/* Protocol */
#include "CAN_Communication_Matrix.h"
#include "Analog_Signal_Conversion.h"
#include "Communication_Over_CAN.h"
#include "Simulated_IIC_Master.h"
#include "Simulated_SPI_Master.h"
#include "YGV642_SPI.h"

/* Device */
#include "EEPROM_24Cxx.h"
#include "EEPROM_24Cxx_Remap.h"
#include "ISD2360.h"
#include "LED.h"
#include "GUI.h"
#include "YGV642.h"

/* Module */
#include "Flash_synchronizer.h"

#include "Non_volatile_Memorys.h"
#include "Sound_Player.h"
#include "System_Status_Monitor.h"
#include "TFT_LCD.h"

/* Implementation */
#include "Popup_List.h"
#include "IO_Manager.h"
#include "Popup_Scheduler.h"
#include "Sound_Scheduler.h"
#include "Warning_Processor.h"
#include "Data_Processor.h"
#include "IPC.h"

/* Application */

#include "Telltales.h"
//#include "Back_Light.h"
#include "Drive_Info.h"
#include "Gauges.h"
#include "Menus.h"
#include "Popups.h"

#include "Startup_Animation.h"

#include "FuelConfig.h" 
//#include "FuelConfig1.h" 
 
 
/*Diagnostic*/
#include "Diag_ID_Def.h"
#include "DoCAN_ISO15765_Config.h"
#include "DoCAN_ISO15765.h"
#include "UDS_ISO14229_Services.h"
#include "Diag_ID_Def.h"
#include "UDS_ISO14229_Server.h"
#include "UDS_ISO14229_Server_Config.h"

#include "API_BD8379.h"

extern uint8_t CanFrameExist;
extern INT8U BUS_OFF_FLAG;
extern uint8_t DiagnosticReceived;
uint32_t                      MSCAN0TxID[3];
MSCAN0BusoffMonitorStruct     MSCAN0Busoff;

extern   void SetErrState(unsigned char n); 
extern void SetRxState(unsigned char n); 
extern void SetTxState(unsigned char n);

extern void CoCAN_L_Data_Indication ( uint32_t Identifier, uint8_t DLC, uint8_t *Data );
extern void CAN1939_L_Data_Indication ( uint32_t Identifier, uint8_t DLC, uint8_t *Data );
//extern void CoCAN_L_Data_Confirm(uint32_t Identifier, uint8_t TransferStatus);

extern void DoCAN_L_Data_Indication ( uint32_t Identifier, uint8_t dlc, uint8_t *pData );
extern void DoCAN_L_Data_Confirm ( uint32_t Identifier, uint8_t TransferStatus );
extern   void NM_Receive_isr_Fun(unsigned int id, unsigned char *pBuf) ;

extern void MSCAN0_L_Data_Request ( uint32_t Identifier, uint8_t DLC, uint8_t *Data, uint8_t Priority ) ;
extern uint8_t  CANNetRxOFF ;
extern uint8_t  CANNetTxOFF ;

extern uint8_t   Time10ms;
extern uint8_t   Time2ms;

typedef struct 
{
  uint32_t Identifier;
  uint8_t  DLC;
  uint8_t  Data[8];
  uint8_t  Priority;  
}MSCAN0TxID_t;

typedef struct 
{
  MSCAN0TxID_t TxBuf[32];
  uint8_t      TxHead;
  uint8_t      TxTail;  
}MSCAN0TxBuf_t;

//static MSCAN0TxID_t  BackUpTxBuf[5];
static MSCAN0TxBuf_t                 MSCAN0TxBuf;

/******************************************************************************
��������MSCAN0_L_Data_Request
��  �ܣ��ú������ϲ����,���������������Ϸ���һ�鱨��
��  ����Identifier������ID
        DLC       �����ij���
        Data      ����������
        Priority  ���������ȼ� 0 - 2 ����ԽС���ȼ�Խ��
����ֵ����
******************************************************************************/
void MSCAN0_L_Data_Service(void)
{                                     
  uint8_t  BufSel;
  uint16_t cnt = 0;
  uint8_t Priority = 0;
  static uint32_t temp = 0;
  
  if((MSCAN0TxBuf.TxHead != MSCAN0TxBuf.TxTail) && (TpTimingCtrl.Cnt - temp >= 20)) 
  {    
    BufSel   = 0x01;
    BufSel <<= MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;

    //��ǰ���ȼ��ķ��ͻ�����Ϊ��ʱ,�ϱ�����ʧ�ܲ��˳�����
    if ((CAN0TFLG & 0x07) == 0)
    {
      temp = TpTimingCtrl.Cnt;
      return;
    }
    
    DisableInterrupts;
    
   // CAN0TBSEL = BufSel;   		                //ѡ��ָ��ָ���ķ��ͻ�����
    if((CAN0TFLG & 0x01) == 0x01) 
    {
      Priority = 0;
      CAN0TBSEL = 1;
    }//ѡ��ָ��ָ���ķ��ͻ�����
    else if((CAN0TFLG & 0x02) == 0x02) 
    {
      Priority = 1;
      CAN0TBSEL = 2;  
    } 
    else if((CAN0TFLG & 0x04) == 0x04) 
    {
      Priority = 2; 
      CAN0TBSEL = 4;
    }
    
    BufSel = CAN0TBSEL;
    
   // CAN0TXIDR0 = (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 3);  //д���ʶ��ID
  //  CAN0TXIDR1 = (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier << 5);
    
       //д���ʶ��ID
    CAN0TXIDR0 =  (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 21);
    CAN0TXIDR1 =  ((uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 13) & 0xE0) | ((uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 15) & 0x07);
    CAN0TXIDR2 =  (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 7);
    CAN0TXIDR3 =  (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier << 1) & 0xFE;
    
    CAN0TXIDR1_SRR = 1;
    CAN0TXIDR1_IDE = 1;
    
    CAN0TXDLR = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].DLC;
    
    CAN0TXDSR0 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[0]; //
    CAN0TXDSR1 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[1];  //
    CAN0TXDSR2 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[2];  //
    CAN0TXDSR3 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[3];  //
    CAN0TXDSR4 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[4];
    CAN0TXDSR5 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[5];
    CAN0TXDSR6 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[6];
    CAN0TXDSR7 = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[7];
    
/*                                                      
      BackUpTxBuf[BufSel].Identifier=MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier; 
      BackUpTxBuf[BufSel].DLC = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].DLC;
      BackUpTxBuf[BufSel].Priority =  MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;
      BackUpTxBuf[BufSel].Data[0] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[0];
      BackUpTxBuf[BufSel].Data[1] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[1];
      BackUpTxBuf[BufSel].Data[2] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[2];
      BackUpTxBuf[BufSel].Data[3] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[3];
      BackUpTxBuf[BufSel].Data[4] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[4];
      BackUpTxBuf[BufSel].Data[5] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[5];
      BackUpTxBuf[BufSel].Data[6] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[6];
      BackUpTxBuf[BufSel].Data[7] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Data[7];
                                                                                     */
    
    EnableInterrupts;
               
//   if(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier==0x729)
//    CAN0TXTBPR = 1;//MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;                    //�������ȼ�,��Buffer���ȼ���ͬ,��BufferIDԽС,���ȼ�Խ��
//    else

    CAN0TXTBPR = BufSel;//MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;                    //�������ȼ�,��Buffer���ȼ���ͬ,��BufferIDԽС,���ȼ�Խ��
    CAN0TFLG  = BufSel;                       //��������
    CAN0TIER |= BufSel;                       //������ӦCAN�����ж�
    
    MSCAN0TxID[Priority] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier;    
    
   // MSCAN0_L_Data_Confirm(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier, COMPLETE);
      MSCAN0TxBuf.TxHead++;            
      if(MSCAN0TxBuf.TxHead >= 32)
        MSCAN0TxBuf.TxHead = 0; 
          
    /*cnt = 0;
    while((CAN0TFLG & BufSel) != BufSel) 
    {
      cnt++;
      if(cnt >= 1800)  
        break;
    }*/
  }
}

void MSCAN0_L_Data_Request(uint32_t Identifier, uint8_t DLC, uint8_t *Data, uint8_t Priority)
{
  uint8_t i = 0;
  uint8_t tmp = MSCAN0TxBuf.TxHead;
  uint8_t cnt = 0;
  
  DisableInterrupts;
  
  cnt = (tmp > MSCAN0TxBuf.TxTail) ? (MSCAN0TxBuf.TxHead - MSCAN0TxBuf.TxTail - 1) : (32 - MSCAN0TxBuf.TxTail + MSCAN0TxBuf.TxHead - 1); 
  
  if ((DLC > 8) || (Priority > 2)) 
  { 
    EnableInterrupts;
    return;  
  }
  if(Identifier==0x18FEF717 ) 
    {
      if(1 == CANNetTxOFF)
      {
         EnableInterrupts;
         return;
       }
    }
  /*if(Identifier != 0x729 ) 
  {
    if(Identifier == 0x402) 
    {
      ;
    } 
    else 
    {
      if(DIAG_TST_BIT_SET(m_28SerComCtrlState ,DIAG_COM_NOR_TX,uint8_t)) 
      {          
        EnableInterrupts;
        return;  
      }
    }
  }
  */  
  MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Identifier = Identifier;
  MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].DLC = DLC;
  
  for(i = 0; i < 8; i++) 
    MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Data[i] = 0;
        
  for(i = 0; i < DLC; i++) 
    MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Data[i] = Data[i];
  
    
  MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Priority = Priority;
      
  MSCAN0TxBuf.TxTail++;
  if(MSCAN0TxBuf.TxTail >= 32)
    MSCAN0TxBuf.TxTail = 0;
 
  EnableInterrupts;
  
  return;
}
#if 0
void MSCAN0_L_Data_Request ( uint32_t Identifier, uint8_t DLC, uint8_t *Data, uint8_t Priority )
{
    uint8_t  i;
    //uint8_t  BufDetect;
    uint8_t  BufSel;
    

    /*if((Identifier >= 0x400) && (Identifier <= 0x4ff) ) 
    {
      if(1 == CANNetTxOFF)
         return;
      
    }*/
    if(Identifier==0x18FEF717 ) 
    {
      if(1 == CANNetTxOFF)
         return;
      
    }
    //MSCAN��CAN BUS��ͬ��,��ID��Ч,�������ݳ��ȴ���8,�����ȼ����ô���ʱ,�ϱ�����ʧ�ܲ��˳�����
    if ( ( CAN0CTL0_SYNCH == 0 ) || ( DLC > 8 ) || ( Priority > 2 ) ) //|| (Identifier > 0x07FF)
    {
        MSCAN0_L_Data_Confirm ( Identifier, NOT_COMPLETE );
        return;
    }



    BufSel   = 0x01;
    BufSel <<= Priority;

    //��ǰ���ȼ��ķ��ͻ�����Ϊ��ʱ,�ϱ�����ʧ�ܲ��˳�����
    if ( CAN0TFLG & BufSel == 0 )
    {
        MSCAN0_L_Data_Confirm ( Identifier, NOT_COMPLETE );
        return;
    }

    if ( MSCAN0TxID[Priority] != 0xFFFF )     //ǰһ�α��ķ���δ�õ��������Buffer���������
        MSCAN0_L_Data_Confirm ( MSCAN0TxID[Priority], NOT_COMPLETE );

    MSCAN0TxID[Priority] = Identifier;        //����ID
    CAN0TBSEL = BufSel;   		                //ѡ��ָ��ָ���ķ��ͻ�����
   /* CAN0TXIDR0 = ( uint8_t ) ( Identifier >> 3 ); //д���ʶ��ID
    CAN0TXIDR1 = ( uint8_t ) ( Identifier << 5 );
    CAN0TXIDR1_SRR = 0;
    CAN0TXIDR1_IDE = 0;*/

    //д���ʶ��ID
    CAN0TXIDR0 =  (uint8_t)(Identifier >> 21);
    CAN0TXIDR1 =  ((uint8_t)(Identifier >> 13) & 0xE0) | ((uint8_t)(Identifier >> 15) & 0x07);
    CAN0TXIDR2 =  (uint8_t)(Identifier >> 7);
    CAN0TXIDR3 =  (uint8_t)(Identifier << 1) & 0xFE;

    //���ͣ���չ֡��
    CAN0TXIDR1_SRR = 1;
    CAN0TXIDR1_IDE = 1;
  
    for ( i = 0; i < DLC; i++ )               //�����
        * ( ( &CAN0TXDSR0 ) + i ) = Data[i];

    CAN0TXDLR = DLC;
    //CAN0TXTBPR = 0;                         //�������ȼ�,��Buffer���ȼ���ͬ,��BufferIDԽС,���ȼ�Խ��
    CAN0TFLG  = BufSel;                       //��������
    CAN0TIER |= BufSel;                       //������ӦCAN�����ж�
}
#endif 
/******************************************************************************
��������MSCAN0_L_Data_Indication
��  �ܣ��ú����������ϲ�ָʾһ֡���ĵĵ���,��ͬʱ���������ݴ������ϲ�
        ע�⣺1.ʹ��ʱӦ���ϲ�ı��Ĵ��ݺ��������ڱ�����֮��,���ĵ���ʱ������
                ��Ӧ�ĺ������ݱ�������
              2.���������ж����,�����õ��ϲ�ı��Ĵ��ݺ���Ӧ�����ܼ��
��  ����Identifier������ID
        DLC       �����ij���
        Data      ����������
����ֵ����
******************************************************************************/
void MSCAN0_L_Data_Indication ( uint32_t Identifier, uint8_t DLC, uint8_t *Data )
{
   /*PduInfoType NW_MessageBuffer; 
   
   if( ( Identifier >= 0x18FFFA00 ) && ( Identifier <= 0x18FFFAFF ) ) {//�����������
        NW_MessageBuffer.SduDataPtr = Data;
        NW_MessageBuffer.SduLength = DLC;
        CanNm_RxIndication(0, 0,&NW_MessageBuffer);   
        NM_RECEIVE=1; 
        sleepFlg=1;   
    
   } */
     
   //����1939-21 ������Ķ������
    if( ( Identifier == DIAG_ID_Rx_PHY ) || ( Identifier == DIAG_ID_Rx_FUN ) )
   { 
        DoCAN_L_Data_Indication ( Identifier, DLC, Data );
   }
   else
   {
        //Ӧ�ñ���
        CoCAN_L_Data_Indication ( Identifier, DLC, Data );
   }

    //if ((Identifier == 0x7E3) || (Identifier == 0x7EB))
    //  DoCAN_L_Data_Indication(Identifier, DLC, Data);
    //else
    //  CoCAN_L_Data_Indication(Identifier, DLC, Data);
}

 /******************************************************************************
��������MSCAN0_L_Data_Confirm
��  �ܣ��ú����������ϲ�ָʾ�����͵ı��ĵķ��ͽ��
        ע�⣺1.ʹ��ʱӦ���ϲ�ı��ķ��ͽ�����ݺ��������ڱ�����֮��,���ķ�����
                ������ʱ��������Ӧ�ĺ������ݱ��ķ��ͽ��
              2.���������ж����,�����õ��ϲ�ı��ķ��ͽ�����ݺ���Ӧ�����ܼ��
��  ����Identifier    ������ID
        TransferStatus�����ķ��ͽ����COMPLETE     �������
                                      NOT_COMPLETE ����δ�ܷ������
����ֵ����
******************************************************************************/
void MSCAN0_L_Data_Confirm ( uint32_t Identifier, uint8_t TransferStatus )
{
    if (Identifier == DIAG_ID_Tx)
    {
        DoCAN_L_Data_Confirm ( Identifier, TransferStatus );
    }
}

/******************************************************************************
��������MSCAN0_Bus_Off_Monitoring_Service
��  �ܣ�MSCAN0 Bus-off״̬��ط���,���Bus-off״̬�����Իָ�
��  ������
����ֵ����
*******************************************************************************
ע  �⣺�÷���������ÿ20ms������һ��
******************************************************************************/
void MSCAN0_Bus_Off_Monitoring_Service ( void )
{
#if !MSCAN0_BUS_OFF_AUTO_RECOVERY
#if MSCAN0_BUS_LIMP_MODE_ENABLE

    if ( MSCAN0Busoff.Status == MSCAN0_BUS_LIMP )
        return;	                                  //CAN�����Ѿ�������ģʽ(��λָ�ʧ��),���ٻָ�

#endif

    if ( CAN0MISC_BOHOLD )                        //���Bus-off����
    {
        MSCAN0Busoff.Timer++;

        if ( MSCAN0Busoff.Status == MSCAN0_BUS_STABLE )
            MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV1;

        if ( MSCAN0Busoff.Status == MSCAN0_BUS_OFF_LV1 )
        {
            if ( MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_LV1_RECOVERY_TIME / 20 )
            {
                MSCAN0Busoff.Timer = 0;
                CAN0MISC_BOHOLD = 1;                      //д1����,����ָ�Bus-off
                MSCAN0Busoff.Cnt++;

                if ( MSCAN0Busoff.Cnt >= 10 )
                {
                    BUS_OFF_FLAG = 1;
                    MSCAN0Busoff.Cnt = 0;
                    MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV2;
                }
            }
        }
        else if ( MSCAN0Busoff.Status == MSCAN0_BUS_OFF_LV2 )
        {
            if ( MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 20 )
            {
                MSCAN0Busoff.Timer = 0;
                CAN0MISC_BOHOLD = 1;                      //д1����,����ָ�Bus-off
            }

#if MSCAN0_BUS_LIMP_MODE_ENABLE
            MSCAN0Busoff.Cnt++;

            if ( MSCAN0Busoff.Cnt > MSCAN0_BUS_LIMP_MODE_THRESHOLD )
            {
                MSCAN0Busoff.Cnt = 0;
                MSCAN0Busoff.Status = MSCAN0_BUS_LIMP;  //����CAN��������ģʽ
                CAN0_PHY_STB = 1;                       //����ʡ��ģʽ
                MSCAN0_Init();				                  //ͨ����ʼ����ֹ����CAN�շ�
                CAN0RIER_RXFIE = 0;   		              //��ֹCAN�����ж�
                CAN0RIER_WUPIE = 0;                     //�رջ����ж�
                CAN0CTL0_WUPE  = 0;                     //��ֹ����ʹ��

                if ( CAN0RFLG_WUPIF )
                    CAN0RFLG_WUPIF = 1;                   //����л����ж������־Ҳһ�����(д1����)
            }

#endif
        }
    }
    else                                          //��������,û��Bus-off����
    {
        BUS_OFF_FLAG = 0;
        MSCAN0Busoff.Status = MSCAN0_BUS_STABLE;
        MSCAN0Busoff.Timer = 0;
        MSCAN0Busoff.Cnt   = 0;
    }

#endif
}

/******************************************************************************
��������MSCAN0_Get_Bus_Status
��  �ܣ���ȡMSCAN0����״̬
��  ������
����ֵ��MSCAN0_BUS_STABLE����������,�ȶ�����
        MSCAN0_BUS_OFF   �����ߴ���Bus-off״̬
        MSCAN0_BUS_LIMP  �����ߴ�������״̬(Bus-off���λָ���ʧ�ܶ��ر�����)
******************************************************************************/
uint8_t MSCAN0_Get_Bus_Status ( void )
{
    return MSCAN0Busoff.Status;
}

/******************************************************************************
��������MSCAN0_Init
��  �ܣ�MSCAN0��ʼ������
��  ������
����ֵ����
******************************************************************************/
void MSCAN0_Init ( void )
{
   // uint8_t i;
    CAN0CTL0 = 0x01;            //���� MSCAN�����ʼ��ģʽ

    while ( ! ( CAN0CTL1_INITAK ) ); //�ȴ������ʼ��ģʽ

    CAN0IDAC = 0;   		        //�����������ռĴ����Ĺ�����ʽ  two 32-bit filter
    CAN0IDAR0 = 0x00;     	    //�������ռĴ���
    CAN0IDAR1 = 0x00;
    CAN0IDAR2 = 0x00;
    CAN0IDAR3 = 0x00;
    CAN0IDMR0 = 0xFF;           //�������μĴ��� (��������Ϊ���б���ID������)
    CAN0IDMR1 = 0xFF;
    CAN0IDMR2 = 0xFF;
    CAN0IDMR3 = 0xFF;
    CAN0IDAR4 = 0x00;      	    //�������ռĴ���
    CAN0IDAR5 = 0x00;
    CAN0IDAR6 = 0x00;
    CAN0IDAR7 = 0x00;
    CAN0IDMR4 = 0xFF;           //�������μĴ��� (��������Ϊ���б���ID������)
    CAN0IDMR5 = 0xFF;
    CAN0IDMR6 = 0xFF;
    CAN0IDMR7 = 0xFF;
    CAN0CTL1_CANE   = 1;        //ʹ��MSCANģ��
    CAN0CTL1_CLKSRC = 0;        //ѡ��OSCCLK(8MHz)ΪMSCAN��ʱ��Դ
    CAN0CTL1_LISTEN = 0;        //��������ģʽ(�Ǽ���ģʽ)
#if MSCAN0_BUS_OFF_AUTO_RECOVERY
    CAN0CTL1_BORM = 0;	      //�Զ�����BUS_OFF�ָ�
#else
    CAN0CTL1_BORM = 1;	      //����BUS_OFF���û����ƻָ�
#endif
    CAN0CTL1_WUPM = 1;		      //�����Ѽ��˲�
    CAN0BTR0 = 0X43;   //���������� �������������81.25%�IJ�����
    CAN0BTR1 = 0X14;
    /*
    myBRP=5;            p=(myBRP-1);
    mySJW=3;           sj=(mySJW-1)<<6;		//ͬ����ת��=2       2015-3-12
    myTSEG1=11;    t_seg1=myTSEG1-1;
    myTSEG2=4;       t_seg2=(myTSEG2-1)<<4;
    CAN0BTR0=sj|p;
    CAN0BTR1=t_seg1|t_seg2;		//��Ϊ1�β���       */
    //---------------------------------
    //CAN0CTL0 = 0x00;
    CAN0CTL0 = 0x00;            //�˳���ʼ��ģʽ

    while ( CAN0CTL1_INITAK );  //�ȴ��˳���ʼ��ģʽ

    while ( !CAN0CTL0_SYNCH );  //�ȴ�MSCAN��CAN����ͬ��

    CAN0TIER = 0x00;            //��ֹCAN�����ж�
    CAN0RIER_RXFIE = 1;   		  //ʹ��CAN�����ж�
    CAN0RIER_WUPIE = 1;
    CAN0_STB = 0;   	          //ʹ��CAN�շ���
    MSCAN0Busoff.Status = MSCAN0_BUS_STABLE;
    MSCAN0Busoff.Timer = 0;
#if MSCAN0_BUS_LIMP_MODE_ENABLE
    MSCAN0Busoff.Cnt   = 0;
#endif

   // for ( i = 0; i < 3; i++ )
   //     MSCAN0TxID[i] = 0xFFFF;   //0xFFFF��ʾ��ЧID
  MSCAN0TxBuf.TxHead = 0;
  MSCAN0TxBuf.TxTail = 0;   
}

/******************************************************************************
��������MSCAN0_Enter_Low_Power_Mode
��  �ܣ���MSCAN0����͹���ģʽ
��  ������
����ֵ����
******************************************************************************/
 

void MSCAN0_Enter_Low_Power_Mode ( void )
{
   //MSCAN0_Init();            //͸����ʼ����ֹCAN�շ�
    CAN0_STB = 1;   	          //ʹ��CAN�շ���

    if ( CAN0RFLG_WUPIF )       //�����ж������־ = 1 ��д1��0
        CAN0RFLG_WUPIF = 1;

    CAN0CTL0_WUPE = 1;			    //����ʹ��
    //��1��,��MSCAN���з������(���Ͷ��п�),����Ҳ���(CAN���߿���)��,
    //MSCAN ����SLEEPģʽ,������ CAN0CTL1_SLPAK=1��ʾȷ��
    //���ô�λǰ CAN0RFLG_WUPIF �������
    //��CAN0CTL0_SLPRQ=1,��CAN0CTL1_SLPAK=1 ,��ʾMSCAN�Ѿ�����˯��ģʽ
    CAN0CTL0_SLPRQ = 1;			    //������MSCAN����˯��ģʽ
    //��MSCAN����˯��ģʽ��,��� CAN0CTL0_WUPE = 1 ���յ�CAN���ĺ�,MSCAN�˳�˯��,��CAN0RFLG_WUPIF��1
    //ͬʱ CAN0CTL0_SLPRQ,CAN0CTL1_SLPAK Ҳ���Զ���0.
    //��MSCAN����˯��ģʽ��,����Ҳ����������CAN0CTL0_SLPRQ = 0,ʹ��MSCAN�˳�˯��,CAN0CTL1_SLPAK Ҳ���Զ���0.
    //�� CAN0CTL0_SLPRQ = 1��,���MSCAN��û�н���˯��ģʽ,��ô����������CAN0CTL0_SLPRQ = 0.
    CAN0TARQ = 0x07;            //������ֹ���б��ķ���.
    CAN0RIER_RXFIE = 0;   			//��ֹCAN�����ж�         20200618
}

/******************************************************************************
��������MSCAN0_Exit_Low_Power_Mode
��  �ܣ���MSCAN0�˳��͹���ģʽ
��  ������
����ֵ����
******************************************************************************/
void MSCAN0_Exit_Low_Power_Mode ( void )
{
    CAN0CTL0_SLPRQ = 0;         //ʹ��MSCAN�˳�˯��

    if ( CAN0RFLG_WUPIF )       //�����ж������־ = 1 ��д1��0
        CAN0RFLG_WUPIF = 1;

    CAN0CTL0_WUPE = 0;			    //���û��ѹ���
    CAN0_STB = 0;               //ʹ��CAN�շ���
    CAN0RIER_RXFIE = 1;   			//ʹ��CAN�����ж�
}

/******************************************************************************
��������MSCAN0_Get_Wake_Up_Flag
��  �ܣ���ȡMSCAN0�Ļ���״̬
��  ������
����ֵ��0 - δ������ 1 - �ѱ�����
******************************************************************************/
uint8_t MSCAN0_Get_Wake_Up_Flag ( void )
{
 
   
    if (( CAN0CTL0_SLPRQ == 0 )   ||(CanFrameExist==1))
        return 1;
 
    return 0;
}

#pragma CODE_SEG __NEAR_SEG NON_BANKED   	//�������жϺ�������FLASH�ķǷ�ҳ��

/******************************************************************************
��������MSCAN0_TX_ISR
��  �ܣ�MSCAN0�����жϷ�������
        ����CAN���ķ�����ϻ���ֹ����ʱ��ִ�д˺���
��  ������
����ֵ����
******************************************************************************/
void interrupt MSCAN0_TX_ISR ( void )
{
    uint8_t i;
    uint8_t TxFlag;
    uint8_t TxBuf;
    uint8_t BufDetect;
    
    do
    {
        TxFlag = CAN0TFLG;
        TxBuf = CAN0TIER & TxFlag;              //��ȡ������ϻ���ֹ���͵ı���Buffer
        CAN0TIER &= ~TxBuf;                     //�رշ�����ϻ���ֹ���͵ı���Buffer��Ӧ���ж�
        BufDetect = 1;

        for ( i = 0; i < 3; i++ )
        {
            if ( BufDetect & TxBuf )
            {
                if ( BufDetect & CAN0TAAK )         //���ı��ɹ���ֹ����
                    MSCAN0_L_Data_Confirm ( MSCAN0TxID[i], NOT_COMPLETE );
                else                                //���ķ��ͳɹ�
                    MSCAN0_L_Data_Confirm ( MSCAN0TxID[i], COMPLETE );

                MSCAN0TxID[i] = 0xFFFF;             //������ļ�¼
            }

            BufDetect <<= 1;
        }
    }
    while ( TxFlag != CAN0TFLG );             //�����жϴ����ڼ����µı��ķ������
}




/******************************************************************************
��������MSCAN0_RX_ISR
��  �ܣ�MSCAN0�����жϷ�������
        ����CAN�����ʹ�ʱ������CAN����
��  ������
����ֵ����
******************************************************************************/
void interrupt MSCAN0_RX_ISR ( void )
{
    uint32_t tmp;
    uint32_t CANMsgID;

   // uint8_t m8;
    CAN0RIER_RXFIE = 0;                      //�Ƚ�ֹMSCAN�����ж�


    /*  if ( CAN0RXIDR1_IDE || CAN0RXIDR1_SRR )  //����յ�������Ϊ��չ֡,��ΪԶ��֡
    {
        CAN0RFLG_RXF = 1;                      //������жϱ�־
        CAN0RIER_RXFIE = 1;                    //��������MSCAN�����ж�
        
        return;
    } */

    //���ݽ���
    tmp = (uint32_t)(CAN0RXIDR0) << 21;
    tmp &= 0x1FE00000; 
    CANMsgID =  tmp | ((uint32_t)(CAN0RXIDR1 & 0xE0) <<13) |  ((uint32_t)(CAN0RXIDR1 & 0x07) <<15)
                  | ((uint32_t)(CAN0RXIDR2) << 7)
                  | ((uint32_t)(CAN0RXIDR3) >> 1);//ID
    		  
    /* CANMsgID = ( ( uint16_t ) ( CAN0RXIDR0 << 3 ) ) | ( ( uint16_t ) ( CAN0RXIDR1 >> 5 ) );
    if((CANMsgID >= 0x400) && (CANMsgID <= 0x4ff) ) 
    {
      if( 1==CANNetRxOFF )
    	         return;
    	NM_Receive_isr_Fun(CANMsgID, &CAN0RXDSR0); 
    }*/
    if(CANMsgID==0x18FFA021)
    {
      if( 1==CANNetRxOFF )
         return;
    }
    MSCAN0_L_Data_Indication ( CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0 );
    CanFrameExist=1;
    CAN0RFLG_RXF = 1;                        //������жϱ�־
    CAN0RIER_RXFIE = 1;                      //��������MSCAN�����ж�
}
/*
void interrupt MSCAN0_RX_ISR(void)
{
  uint16_t CANMsgID;

	CAN0RIER_RXFIE = 0;                      //�Ƚ�ֹMSCAN�����ж�

	if (CAN0RXIDR1_IDE || CAN0RXIDR1_SRR)    //����յ�������Ϊ��չ֡,��ΪԶ��֡
	{
    CAN0RFLG_RXF=1;                        //������жϱ�־
		CAN0RIER_RXFIE=1;                      //��������MSCAN�����ж�

    return;
	}

	CANMsgID = ((uint16_t)(CAN0RXIDR0 << 3)) | ((uint16_t)(CAN0RXIDR1 >> 5));

  if((CANMsgID >= 0x400) && (CANMsgID <= 0x47F))
    MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0);
  else
  {
  	switch(CANMsgID)
  	{
    	case  0x068 :
    	case  0x268 :
    	case  0x2D7 :
      case  0x4D4 :
      case  0x1C8 :
      case  0x370 :
      case  0x1C9 :
      case  0x0F2 :
      case  0x0E2 :
      case  0x082 :
      case  0x094 :
      case  0x288 :
      case  0x088 :
      case  0x120 :
      case  0x293 :
      case  0x115 :
      case  0x160 :
      case  0x07A :
      case  0x30F :
      case  0x2F1 :
      case  0x10D :
      case  0x7E3 :
      case  DIAG_ID_Rx_FUN :
      case  0x279 : MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0);
                    break;
      default     : break;
  	}
	}

  CAN0RFLG_RXF = 1;                        //������жϱ�־
	CAN0RIER_RXFIE = 1;                      //��������MSCAN�����ж�
}*/

/******************************************************************************
��������MSCAN0_WAKEUP_ISR
��  �ܣ�MSCAN0�����ж�
��  ������
����ֵ����
******************************************************************************/

void interrupt MSCAN0_WAKEUP_ISR ( void )
{
    CAN0RFLG_WUPIF = 1;
    CAN0_STB = 0;
    Time2ms=0;
    Time10ms=0;
    API_Start();
    CanFrameExist=1;
}

#pragma CODE_SEG DEFAULT