MSCAN0.c 28 KB
Newer Older
崔立宝's avatar
崔立宝 committed
1
/******************************************************************************
2 3 4 5 6
文 件 名:MSCAN0.h
功能描述:MSCAN0总线收发控制函数库文件
作    者:张暄
版    本:V1.0
日    期:2016.5.5
崔立宝's avatar
崔立宝 committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
******************************************************************************/

#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;

/******************************************************************************
140 141 142 143 144 145 146
函数名:MSCAN0_L_Data_Request
功  能:该函数由上层调用,用于请求向总线上发送一组报文
参  数:Identifier:报文ID
        DLC       :报文长度
        Data      :报文数据
        Priority  :发送优先级 0 - 2 数字越小优先级越高
返回值:无
崔立宝's avatar
崔立宝 committed
147 148 149 150 151 152 153 154
******************************************************************************/
void MSCAN0_L_Data_Service(void)
{                                     
  uint8_t  BufSel;
  uint16_t cnt = 0;
  uint8_t Priority = 0;
  static uint32_t temp = 0;
  
155
  if ((MSCAN0TxBuf.TxHead != MSCAN0TxBuf.TxTail) && (TpTimingCtrl.Cnt - temp >= 20)) 
崔立宝's avatar
崔立宝 committed
156 157 158 159
  {    
    BufSel   = 0x01;
    BufSel <<= MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;

160
    //当前优先级的发送缓冲区为空时,上报发送失败并退出发送
崔立宝's avatar
崔立宝 committed
161 162 163 164 165 166 167 168
    if ((CAN0TFLG & 0x07) == 0)
    {
      temp = TpTimingCtrl.Cnt;
      return;
    }
    
    DisableInterrupts;
    
169
   // CAN0TBSEL = BufSel;   		                //选择指向指定的发送缓冲区
崔立宝's avatar
崔立宝 committed
170 171 172 173
    if((CAN0TFLG & 0x01) == 0x01) 
    {
      Priority = 0;
      CAN0TBSEL = 1;
174
    }//选择指向指定的发送缓冲区
崔立宝's avatar
崔立宝 committed
175 176 177 178 179 180 181 182 183 184 185 186 187
    else if((CAN0TFLG & 0x02) == 0x02) 
    {
      Priority = 1;
      CAN0TBSEL = 2;  
    } 
    else if((CAN0TFLG & 0x04) == 0x04) 
    {
      Priority = 2; 
      CAN0TBSEL = 4;
    }
    
    BufSel = CAN0TBSEL;
    
188
   // CAN0TXIDR0 = (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier >> 3);  //写入标识符ID
崔立宝's avatar
崔立宝 committed
189 190
  //  CAN0TXIDR1 = (uint8_t)(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier << 5);
    
191
       //写入标识符ID
崔立宝's avatar
崔立宝 committed
192 193 194 195 196 197 198
    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;
199 200 201 202 203 204 205
    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;
    }
崔立宝's avatar
崔立宝 committed
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    
    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)
235
//    CAN0TXTBPR = 1;//MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;                    //设置优先级,各Buffer优先级相同,则BufferID越小,优先级越高
崔立宝's avatar
崔立宝 committed
236 237
//    else

238 239 240
    CAN0TXTBPR = BufSel;//MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;                    //设置优先级,各Buffer优先级相同,则BufferID越小,优先级越高
    CAN0TFLG  = BufSel;                       //启动发送
    CAN0TIER |= BufSel;                       //启动相应CAN发送中断
崔立宝's avatar
崔立宝 committed
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
    
    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;
      
    }
338
    //MSCAN与CAN BUS不同步,或ID无效,或发送数据长度大于8,或优先级设置错误时,上报发送失败并退出发送
崔立宝's avatar
崔立宝 committed
339 340 341 342 343 344 345 346 347 348 349
    if ( ( CAN0CTL0_SYNCH == 0 ) || ( DLC > 8 ) || ( Priority > 2 ) ) //|| (Identifier > 0x07FF)
    {
        MSCAN0_L_Data_Confirm ( Identifier, NOT_COMPLETE );
        return;
    }



    BufSel   = 0x01;
    BufSel <<= Priority;

350
    //当前优先级的发送缓冲区为空时,上报发送失败并退出发送
崔立宝's avatar
崔立宝 committed
351 352 353 354 355 356
    if ( CAN0TFLG & BufSel == 0 )
    {
        MSCAN0_L_Data_Confirm ( Identifier, NOT_COMPLETE );
        return;
    }

357
    if ( MSCAN0TxID[Priority] != 0xFFFF )     //前一次报文发送未得到结果但是Buffer被意外清空
崔立宝's avatar
崔立宝 committed
358 359
        MSCAN0_L_Data_Confirm ( MSCAN0TxID[Priority], NOT_COMPLETE );

360 361 362
    MSCAN0TxID[Priority] = Identifier;        //保存ID
    CAN0TBSEL = BufSel;   		                //选择指向指定的发送缓冲区
   /* CAN0TXIDR0 = ( uint8_t ) ( Identifier >> 3 ); //写入标识符ID
崔立宝's avatar
崔立宝 committed
363 364 365 366
    CAN0TXIDR1 = ( uint8_t ) ( Identifier << 5 );
    CAN0TXIDR1_SRR = 0;
    CAN0TXIDR1_IDE = 0;*/

367
    //写入标识符ID
崔立宝's avatar
崔立宝 committed
368 369 370 371 372
    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;

373
    //发送(扩展帧)
崔立宝's avatar
崔立宝 committed
374 375 376
    CAN0TXIDR1_SRR = 1;
    CAN0TXIDR1_IDE = 1;
  
377
    for ( i = 0; i < DLC; i++ )               //写入数据
崔立宝's avatar
崔立宝 committed
378 379 380
        * ( ( &CAN0TXDSR0 ) + i ) = Data[i];

    CAN0TXDLR = DLC;
381 382 383
    //CAN0TXTBPR = 0;                         //设置优先级,各Buffer优先级相同,则BufferID越小,优先级越高
    CAN0TFLG  = BufSel;                       //启动发送
    CAN0TIER |= BufSel;                       //启动相应CAN发送中断
崔立宝's avatar
崔立宝 committed
384 385 386
}
#endif 
/******************************************************************************
387 388 389 390 391 392 393 394 395
函数名:MSCAN0_L_Data_Indication
功  能:该函数用于向上层指示一帧报文的到来,并同时将报文数据传递至上层
        注意:1.使用时应将上层的报文传递函数包含于本函数之中,报文到来时则会调用
                相应的函数传递报文数据
              2.本函数与中断相关,被调用的上层的报文传递函数应尽可能简短
参  数:Identifier:报文ID
        DLC       :报文长度
        Data      :报文数据
返回值:无
崔立宝's avatar
崔立宝 committed
396 397 398 399 400
******************************************************************************/
void MSCAN0_L_Data_Indication ( uint32_t Identifier, uint8_t DLC, uint8_t *Data )
{
   /*PduInfoType NW_MessageBuffer; 
   
401
   if( ( Identifier >= 0x18FFFA00 ) && ( Identifier <= 0x18FFFAFF ) ) {//网络管理报文
崔立宝's avatar
崔立宝 committed
402 403 404 405 406 407 408
        NW_MessageBuffer.SduDataPtr = Data;
        NW_MessageBuffer.SduLength = DLC;
        CanNm_RxIndication(0, 0,&NW_MessageBuffer);   
        NM_RECEIVE=1; 
        sleepFlg=1;   
    
   } */
409 410 411 412 413 414 415 416 417
    ReceivedMsg(Identifier,DLC);
   //����1939-21 ������������
    //if( ( Identifier == DIAG_ID_Rx_PHY ) || ( Identifier == DIAG_ID_Rx_FUN ) )
   //{ 
       // DoCAN_L_Data_Indication ( Identifier, DLC, Data );
   //}
   //else
   //{
        //Ӧ�ñ���
崔立宝's avatar
崔立宝 committed
418
        CoCAN_L_Data_Indication ( Identifier, DLC, Data );
419
   //}
崔立宝's avatar
崔立宝 committed
420 421 422 423 424 425 426 427

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

 /******************************************************************************
428 429 430 431 432 433 434 435 436
函数名:MSCAN0_L_Data_Confirm
功  能:该函数用于向上层指示请求发送的报文的发送结果
        注意:1.使用时应将上层的报文发送结果传递函数包含于本函数之中,报文发送事
                件产生时则会调用相应的函数传递报文发送结果
              2.本函数与中断相关,被调用的上层的报文发送结果传递函数应尽可能简短
参  数:Identifier    :报文ID
        TransferStatus:报文发送结果:COMPLETE     发送完成
                                      NOT_COMPLETE 报文未能发送完成
返回值:无
崔立宝's avatar
崔立宝 committed
437 438 439 440 441 442 443 444 445 446
******************************************************************************/
void MSCAN0_L_Data_Confirm ( uint32_t Identifier, uint8_t TransferStatus )
{
    if (Identifier == DIAG_ID_Tx)
    {
        DoCAN_L_Data_Confirm ( Identifier, TransferStatus );
    }
}

/******************************************************************************
447 448 449 450
函数名:MSCAN0_Bus_Off_Monitoring_Service
功  能:MSCAN0 Bus-off状态监控服务,监控Bus-off状态并尝试恢复
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
451
*******************************************************************************
452
注  意:该服务函数必须每20ms被调用一次
崔立宝's avatar
崔立宝 committed
453 454 455 456 457 458 459
******************************************************************************/
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 )
460
        return;	                                  //CAN总线已经在跛行模式(多次恢复失败),则不再恢复
崔立宝's avatar
崔立宝 committed
461 462 463

#endif

464
    if ( CAN0MISC_BOHOLD )                        //如果Bus-off发生
崔立宝's avatar
崔立宝 committed
465 466 467 468 469 470 471 472 473 474 475
    {
        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;
476
                CAN0MISC_BOHOLD = 1;                      //写1清零,请求恢复Bus-off
崔立宝's avatar
崔立宝 committed
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
                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;
492
                CAN0MISC_BOHOLD = 1;                      //写1清零,请求恢复Bus-off
崔立宝's avatar
崔立宝 committed
493 494 495 496 497 498 499 500
            }

#if MSCAN0_BUS_LIMP_MODE_ENABLE
            MSCAN0Busoff.Cnt++;

            if ( MSCAN0Busoff.Cnt > MSCAN0_BUS_LIMP_MODE_THRESHOLD )
            {
                MSCAN0Busoff.Cnt = 0;
501 502 503 504 505 506
                MSCAN0Busoff.Status = MSCAN0_BUS_LIMP;  //进入CAN总线跛行模式
                CAN0_PHY_STB = 1;                       //进入省电模式
                MSCAN0_Init();				                  //通过初始化终止所有CAN收发
                CAN0RIER_RXFIE = 0;   		              //禁止CAN接收中断
                CAN0RIER_WUPIE = 0;                     //关闭唤醒中断
                CAN0CTL0_WUPE  = 0;                     //禁止唤醒使能
崔立宝's avatar
崔立宝 committed
507 508

                if ( CAN0RFLG_WUPIF )
509
                    CAN0RFLG_WUPIF = 1;                   //如果有唤醒中断请求标志也一并清除(写1清零)
崔立宝's avatar
崔立宝 committed
510 511 512 513 514
            }

#endif
        }
    }
515
    else                                          //总线正常,没有Bus-off发生
崔立宝's avatar
崔立宝 committed
516 517 518 519 520 521 522 523 524 525 526
    {
        BUS_OFF_FLAG = 0;
        MSCAN0Busoff.Status = MSCAN0_BUS_STABLE;
        MSCAN0Busoff.Timer = 0;
        MSCAN0Busoff.Cnt   = 0;
    }

#endif
}

/******************************************************************************
527 528 529 530 531 532
函数名:MSCAN0_Get_Bus_Status
功  能:获取MSCAN0总线状态
参  数:无
返回值:MSCAN0_BUS_STABLE:总线正常,稳定工作
        MSCAN0_BUS_OFF   :总线处于Bus-off状态
        MSCAN0_BUS_LIMP  :总线处于跛行状态(Bus-off后多次恢复均失败而关闭总线)
崔立宝's avatar
崔立宝 committed
533 534 535 536 537 538 539
******************************************************************************/
uint8_t MSCAN0_Get_Bus_Status ( void )
{
    return MSCAN0Busoff.Status;
}

/******************************************************************************
540 541 542 543
函数名:MSCAN0_Init
功  能:MSCAN0初始化程序
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
544 545 546 547
******************************************************************************/
void MSCAN0_Init ( void )
{
   // uint8_t i;
548
    CAN0CTL0 = 0x01;            //请求 MSCAN进入初始化模式
崔立宝's avatar
崔立宝 committed
549

550
    while ( ! ( CAN0CTL1_INITAK ) ); //等待进入初始化模式
崔立宝's avatar
崔立宝 committed
551

552 553
    CAN0IDAC = 0;   		        //配置屏蔽验收寄存器的工作方式  two 32-bit filter
    CAN0IDAR0 = 0x00;     	    //设置验收寄存器
崔立宝's avatar
崔立宝 committed
554 555 556
    CAN0IDAR1 = 0x00;
    CAN0IDAR2 = 0x00;
    CAN0IDAR3 = 0x00;
557
    CAN0IDMR0 = 0xFF;           //设置屏蔽寄存器 (这里设置为所有报文ID都接收)
崔立宝's avatar
崔立宝 committed
558 559 560
    CAN0IDMR1 = 0xFF;
    CAN0IDMR2 = 0xFF;
    CAN0IDMR3 = 0xFF;
561
    CAN0IDAR4 = 0x00;      	    //设置验收寄存器
崔立宝's avatar
崔立宝 committed
562 563 564
    CAN0IDAR5 = 0x00;
    CAN0IDAR6 = 0x00;
    CAN0IDAR7 = 0x00;
565
    CAN0IDMR4 = 0xFF;           //设置屏蔽寄存器 (这里设置为所有报文ID都接收)
崔立宝's avatar
崔立宝 committed
566 567 568
    CAN0IDMR5 = 0xFF;
    CAN0IDMR6 = 0xFF;
    CAN0IDMR7 = 0xFF;
569 570 571
    CAN0CTL1_CANE   = 1;        //使能MSCAN模块
    CAN0CTL1_CLKSRC = 0;        //选择OSCCLK(8MHz)为MSCAN的时钟源
    CAN0CTL1_LISTEN = 0;        //正常运行模式(非监听模式)
崔立宝's avatar
崔立宝 committed
572
#if MSCAN0_BUS_OFF_AUTO_RECOVERY
573
    CAN0CTL1_BORM = 0;	        //自动总线BUS_OFF恢复
崔立宝's avatar
崔立宝 committed
574
#else
575
    CAN0CTL1_BORM = 1;	        //总线BUS_OFF由用户控制恢复
崔立宝's avatar
崔立宝 committed
576
#endif
577 578 579
    CAN0CTL1_WUPM = 1;		      //给唤醒加滤波
    CAN0BTR0 = 0X41;            //2tq, Prescaler value=4,波特率 8M/(2 * (1+2+5)=500k
    CAN0BTR1 = 0X14;            //波特率设置 现在这个配置是1+5/1+5+2 = 75%的采样点
崔立宝's avatar
崔立宝 committed
580 581
    /*
    myBRP=5;            p=(myBRP-1);
582
    mySJW=3;           sj=(mySJW-1)<<6;		//同步跳转段=2       2015-3-12
崔立宝's avatar
崔立宝 committed
583 584 585
    myTSEG1=11;    t_seg1=myTSEG1-1;
    myTSEG2=4;       t_seg2=(myTSEG2-1)<<4;
    CAN0BTR0=sj|p;
586
    CAN0BTR1=t_seg1|t_seg2;		//设为1次采样       */
崔立宝's avatar
崔立宝 committed
587 588
    //---------------------------------
    //CAN0CTL0 = 0x00;
589
    CAN0CTL0 = 0x00;            //退出初始化模式
崔立宝's avatar
崔立宝 committed
590

591
    while ( CAN0CTL1_INITAK );  //等待退出初始化模式
崔立宝's avatar
崔立宝 committed
592

593
    while ( !CAN0CTL0_SYNCH );  //等待MSCAN与CAN总线同步
崔立宝's avatar
崔立宝 committed
594

595 596
    CAN0TIER = 0x00;            //禁止CAN发送中断
    CAN0RIER_RXFIE = 1;   		  //使能CAN接收中断
崔立宝's avatar
崔立宝 committed
597
    CAN0RIER_WUPIE = 1;
598
    CAN0_STB = 0;   	          //使能CAN收发器
崔立宝's avatar
崔立宝 committed
599 600 601 602 603 604 605
    MSCAN0Busoff.Status = MSCAN0_BUS_STABLE;
    MSCAN0Busoff.Timer = 0;
#if MSCAN0_BUS_LIMP_MODE_ENABLE
    MSCAN0Busoff.Cnt   = 0;
#endif

   // for ( i = 0; i < 3; i++ )
606
   //     MSCAN0TxID[i] = 0xFFFF;   //0xFFFF表示无效ID
崔立宝's avatar
崔立宝 committed
607 608 609 610 611
  MSCAN0TxBuf.TxHead = 0;
  MSCAN0TxBuf.TxTail = 0;   
}

/******************************************************************************
612 613 614 615
函数名:MSCAN0_Enter_Low_Power_Mode
功  能:令MSCAN0进入低功耗模式
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
616 617 618 619 620
******************************************************************************/
 

void MSCAN0_Enter_Low_Power_Mode ( void )
{
621 622
   //MSCAN0_Init();            //透过初始化终止CAN收发
    CAN0_STB = 1;   	          //使能CAN收发器
崔立宝's avatar
崔立宝 committed
623

624
    if ( CAN0RFLG_WUPIF )       //唤醒中断请求标志 = 1 则写1清0
崔立宝's avatar
崔立宝 committed
625 626
        CAN0RFLG_WUPIF = 1;

627 628 629 630 631 632 633 634 635 636 637 638
    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
崔立宝's avatar
崔立宝 committed
639 640 641
}

/******************************************************************************
642 643 644 645
函数名:MSCAN0_Exit_Low_Power_Mode
功  能:令MSCAN0退出低功耗模式
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
646 647 648
******************************************************************************/
void MSCAN0_Exit_Low_Power_Mode ( void )
{
649
    CAN0CTL0_SLPRQ = 0;         //使得MSCAN退出睡眠
崔立宝's avatar
崔立宝 committed
650

651
    if ( CAN0RFLG_WUPIF )       //唤醒中断请求标志 = 1 则写1清0
崔立宝's avatar
崔立宝 committed
652 653
        CAN0RFLG_WUPIF = 1;

654 655 656
    CAN0CTL0_WUPE = 0;			    //禁用唤醒功能
    CAN0_STB = 0;               //使能CAN收发器
    CAN0RIER_RXFIE = 1;   			//使能CAN接收中断
崔立宝's avatar
崔立宝 committed
657 658 659
}

/******************************************************************************
660 661 662 663
函数名:MSCAN0_Get_Wake_Up_Flag
功  能:获取MSCAN0的唤醒状态
参  数:无
返回值:0 - 未被唤醒 1 - 已被唤醒
崔立宝's avatar
崔立宝 committed
664 665 666 667 668 669 670 671 672 673 674
******************************************************************************/
uint8_t MSCAN0_Get_Wake_Up_Flag ( void )
{
 
   
    if (( CAN0CTL0_SLPRQ == 0 )   ||(CanFrameExist==1))
        return 1;
 
    return 0;
}

675
#pragma CODE_SEG __NEAR_SEG NON_BANKED   	//置所有中断函数放在FLASH的非分页区
崔立宝's avatar
崔立宝 committed
676 677

/******************************************************************************
678 679 680 681 682
函数名:MSCAN0_TX_ISR
功  能:MSCAN0发送中断服务函数。
        当有CAN报文发送完毕或被中止发送时,执行此函数
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
683 684 685 686 687 688 689 690 691 692 693
******************************************************************************/
void interrupt MSCAN0_TX_ISR ( void )
{
    uint8_t i;
    uint8_t TxFlag;
    uint8_t TxBuf;
    uint8_t BufDetect;
    
    do
    {
        TxFlag = CAN0TFLG;
694 695
        TxBuf = CAN0TIER & TxFlag;              //获取发送完毕或被中止发送的报文Buffer
        CAN0TIER &= ~TxBuf;                     //关闭发送完毕或被中止发送的报文Buffer对应的中断
崔立宝's avatar
崔立宝 committed
696 697 698 699 700 701
        BufDetect = 1;

        for ( i = 0; i < 3; i++ )
        {
            if ( BufDetect & TxBuf )
            {
702
                if ( BufDetect & CAN0TAAK )         //报文被成功中止发送
崔立宝's avatar
崔立宝 committed
703
                    MSCAN0_L_Data_Confirm ( MSCAN0TxID[i], NOT_COMPLETE );
704
                else                                //报文发送成功
崔立宝's avatar
崔立宝 committed
705 706
                    MSCAN0_L_Data_Confirm ( MSCAN0TxID[i], COMPLETE );

707
                MSCAN0TxID[i] = 0xFFFF;             //清除报文记录
崔立宝's avatar
崔立宝 committed
708 709 710 711 712
            }

            BufDetect <<= 1;
        }
    }
713
    while ( TxFlag != CAN0TFLG );             //避免中断处理期间有新的报文发送完毕
崔立宝's avatar
崔立宝 committed
714 715 716 717 718 719
}




/******************************************************************************
720 721 722 723 724
函数名:MSCAN0_RX_ISR
功  能:MSCAN0接收中断服务函数。
        当有CAN报文送达时,接收CAN报文
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
725 726 727 728 729
******************************************************************************/
void interrupt MSCAN0_RX_ISR ( void )
{
    uint32_t tmp;
    uint32_t CANMsgID;
730
    uint32_t DiagMsgID;
崔立宝's avatar
崔立宝 committed
731 732

   // uint8_t m8;
733
    CAN0RIER_RXFIE = 0;                      //先禁止MSCAN接收中断
崔立宝's avatar
崔立宝 committed
734 735


736
    /*  if ( CAN0RXIDR1_IDE || CAN0RXIDR1_SRR )  //如果收到的数据为扩展帧,或为远程帧
崔立宝's avatar
崔立宝 committed
737
    {
738 739
        CAN0RFLG_RXF = 1;                      //清接收中断标志
        CAN0RIER_RXFIE = 1;                    //重新启动MSCAN接收中断
崔立宝's avatar
崔立宝 committed
740 741 742 743
        
        return;
    } */

744
    //数据接收
崔立宝's avatar
崔立宝 committed
745 746 747 748 749 750
    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
    		  
751 752
    DiagMsgID = ( ( uint16_t ) ( CAN0RXIDR0 << 3 ) ) | ( ( uint16_t ) ( CAN0RXIDR1 >> 5 ) );
    /*if((CANMsgID >= 0x400) && (CANMsgID <= 0x4ff) ) 
崔立宝's avatar
崔立宝 committed
753 754 755 756 757 758 759 760 761 762
    {
      if( 1==CANNetRxOFF )
    	         return;
    	NM_Receive_isr_Fun(CANMsgID, &CAN0RXDSR0); 
    }*/
    if(CANMsgID==0x18FFA021)
    {
      if( 1==CANNetRxOFF )
         return;
    }
763 764 765 766
    if( ( DiagMsgID == DIAG_ID_Rx_PHY ) || ( DiagMsgID == DIAG_ID_Rx_FUN ) )
    { 
      DoCAN_L_Data_Indication ( DiagMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0 );
    }
崔立宝's avatar
崔立宝 committed
767 768
    MSCAN0_L_Data_Indication ( CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0 );
    CanFrameExist=1;
769 770
    CAN0RFLG_RXF = 1;                        //清接收中断标志
    CAN0RIER_RXFIE = 1;                      //重新启动MSCAN接收中断
崔立宝's avatar
崔立宝 committed
771 772 773 774 775 776
}
/*
void interrupt MSCAN0_RX_ISR(void)
{
  uint16_t CANMsgID;

777
	CAN0RIER_RXFIE = 0;                      //先禁止MSCAN接收中断
崔立宝's avatar
崔立宝 committed
778

779
	if (CAN0RXIDR1_IDE || CAN0RXIDR1_SRR)    //如果收到的数据为扩展帧,或为远程帧
崔立宝's avatar
崔立宝 committed
780
	{
781 782
    CAN0RFLG_RXF=1;                        //清接收中断标志
		CAN0RIER_RXFIE=1;                      //重新启动MSCAN接收中断
崔立宝's avatar
崔立宝 committed
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823

    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;
  	}
	}

824 825
  CAN0RFLG_RXF = 1;                        //清接收中断标志
	CAN0RIER_RXFIE = 1;                      //重新启动MSCAN接收中断
崔立宝's avatar
崔立宝 committed
826 827 828
}*/

/******************************************************************************
829 830 831 832
函数名:MSCAN0_WAKEUP_ISR
功  能:MSCAN0唤醒中断
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
833 834 835 836 837 838 839 840 841 842 843 844 845
******************************************************************************/

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

#pragma CODE_SEG DEFAULT