/******************************************************************************
�� �� ����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 uint16_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;
    if(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier == 0x7DA)
    {
      CAN0TXIDR0 = (uint8_t)((MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier & 0x07F8) >> 3);
      CAN0TXIDR1 = (uint8_t)((MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier & 0x0007) << 5);
      CAN0TXIDR1_SRR = 0;
      CAN0TXIDR1_IDE = 0;
    }
    
    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;
    }*/
  }
}

//extern uint16_t StartCanOutTime0;
//extern uint16_t StartCanOutTime1;

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;
  //uint16_t temp0, temp1;
  //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 ) 
  {
    //temp0 = StartCanOutTime0;
    //temp1 = StartCanOutTime1;
    //CANMsg18FEF717.Msg[4] = temp0;
    //CANMsg18FEF717.Msg[5] = temp0 >> 8;
    //CANMsg18FEF717.Msg[6] = temp1;
    //CANMsg18FEF717.Msg[7] = temp1 >> 8;
       
    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;   
    
   } */
    ReceivedMsg(Identifier,DLC);
   //????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 = 0x40; //0X41;    //2tq, Prescaler value=4,������ 8M/(1 * (1+3+12)=500k
  CAN0BTR1 = 0x2B; //0X14;    //���������� �������������1+12/1+12+3 = 81.25%�IJ�����
  /*
  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;
    uint32_t DiagMsgID;

    // 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
    		  
    DiagMsgID = ( ( 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;
    }
    if( ( DiagMsgID == DIAG_ID_Rx_PHY ) || ( DiagMsgID == DIAG_ID_Rx_FUN ) )
    { 
      DoCAN_L_Data_Indication ( DiagMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0 );
    }
    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