MSCAN0.c 25.8 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
******************************************************************************/

#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;
95
extern INT8U   BUS_OFF_FLAG;
崔立宝's avatar
崔立宝 committed
96
extern uint8_t DiagnosticReceived;
97 98
uint32_t                  MSCAN0TxID[3];
MSCAN0BusoffMonitorStruct MSCAN0Busoff;
崔立宝's avatar
崔立宝 committed
99

100
extern void SetErrState(unsigned char n); 
崔立宝's avatar
崔立宝 committed
101 102 103 104 105 106 107 108 109
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 );
110
extern void NM_Receive_isr_Fun(unsigned int id, unsigned char *pBuf) ;
崔立宝's avatar
崔立宝 committed
111 112 113 114 115

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 ;

116 117
extern uint8_t  Time10ms;
extern uint8_t  Time2ms;
崔立宝's avatar
崔立宝 committed
118 119 120 121 122 123 124

typedef struct 
{
  uint32_t Identifier;
  uint8_t  DLC;
  uint8_t  Data[8];
  uint8_t  Priority;  
125
} MSCAN0TxID_t;
崔立宝's avatar
崔立宝 committed
126 127 128 129 130 131

typedef struct 
{
  MSCAN0TxID_t TxBuf[32];
  uint8_t      TxHead;
  uint8_t      TxTail;  
132
} MSCAN0TxBuf_t;
崔立宝's avatar
崔立宝 committed
133 134

//static MSCAN0TxID_t  BackUpTxBuf[5];
135
static MSCAN0TxBuf_t MSCAN0TxBuf;
崔立宝's avatar
崔立宝 committed
136 137

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

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

237 238 239
    CAN0TXTBPR = BufSel; //MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Priority;                   //设置优先级,各Buffer优先级相同,则BufferID越小,优先级越高
    CAN0TFLG   = BufSel; //启动发送
    CAN0TIER  |= BufSel; //启动相应CAN发送中断
崔立宝's avatar
崔立宝 committed
240 241 242
    
    MSCAN0TxID[Priority] = MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier;    
    
243 244 245 246
    //MSCAN0_L_Data_Confirm(MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxHead].Identifier, COMPLETE);
    MSCAN0TxBuf.TxHead++;            
    if (MSCAN0TxBuf.TxHead >= 32)
      MSCAN0TxBuf.TxHead = 0; 
崔立宝's avatar
崔立宝 committed
247 248
          
    /*cnt = 0;
249
    while ((CAN0TFLG & BufSel) != BufSel) 
崔立宝's avatar
崔立宝 committed
250 251 252 253 254 255 256 257
    {
      cnt++;
      if(cnt >= 1800)  
        break;
    }*/
  }
}

258 259 260
//extern uint16_t StartCanOutTime0;
//extern uint16_t StartCanOutTime1;

崔立宝's avatar
崔立宝 committed
261 262 263 264
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;
265 266
  //uint16_t temp0, temp1;
  //uint8_t cnt = 0;
崔立宝's avatar
崔立宝 committed
267 268 269
  
  DisableInterrupts;
  
270
  //cnt = (tmp > MSCAN0TxBuf.TxTail) ? (MSCAN0TxBuf.TxHead - MSCAN0TxBuf.TxTail - 1) : (32 - MSCAN0TxBuf.TxTail + MSCAN0TxBuf.TxHead - 1); 
崔立宝's avatar
崔立宝 committed
271 272 273 274 275 276
  
  if ((DLC > 8) || (Priority > 2)) 
  { 
    EnableInterrupts;
    return;  
  }
277 278 279 280 281 282 283 284 285 286 287
  
  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)
崔立宝's avatar
崔立宝 committed
288
    {
289 290
      EnableInterrupts;
      return;
崔立宝's avatar
崔立宝 committed
291
    }
292 293 294
  }
    
  /*if (Identifier != 0x729 ) 
崔立宝's avatar
崔立宝 committed
295
  {
296
    if (Identifier == 0x402) 
崔立宝's avatar
崔立宝 committed
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
    {
      ;
    } 
    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;
  
313
  for (i = 0; i < 8; i++) 
崔立宝's avatar
崔立宝 committed
314 315
    MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Data[i] = 0;
        
316
  for (i = 0; i < DLC; i++) 
崔立宝's avatar
崔立宝 committed
317 318 319 320 321 322
    MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Data[i] = Data[i];
  
    
  MSCAN0TxBuf.TxBuf[MSCAN0TxBuf.TxTail].Priority = Priority;
      
  MSCAN0TxBuf.TxTail++;
323
  if (MSCAN0TxBuf.TxTail >= 32)
崔立宝's avatar
崔立宝 committed
324 325 326 327 328 329
    MSCAN0TxBuf.TxTail = 0;
 
  EnableInterrupts;
  
  return;
}
330

崔立宝's avatar
崔立宝 committed
331 332 333
#if 0
void MSCAN0_L_Data_Request ( uint32_t Identifier, uint8_t DLC, uint8_t *Data, uint8_t Priority )
{
334 335 336 337
  uint8_t  i;
  //uint8_t  BufDetect;
  uint8_t  BufSel;
  
崔立宝's avatar
崔立宝 committed
338

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
  /*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;
  }
崔立宝's avatar
崔立宝 committed
355

356 357
  BufSel   = 0x01;
  BufSel <<= Priority;
崔立宝's avatar
崔立宝 committed
358

359 360 361 362 363 364
  //当前优先级的发送缓冲区为空时,上报发送失败并退出发送
  if ( CAN0TFLG & BufSel == 0 )
  {
    MSCAN0_L_Data_Confirm ( Identifier, NOT_COMPLETE );
    return;
  }
崔立宝's avatar
崔立宝 committed
365

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
  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发送中断
崔立宝's avatar
崔立宝 committed
393 394 395
}
#endif 
/******************************************************************************
396 397 398 399 400 401 402 403 404
函数名:MSCAN0_L_Data_Indication
功  能:该函数用于向上层指示一帧报文的到来,并同时将报文数据传递至上层
        注意:1.使用时应将上层的报文传递函数包含于本函数之中,报文到来时则会调用
                相应的函数传递报文数据
              2.本函数与中断相关,被调用的上层的报文传递函数应尽可能简短
参  数:Identifier:报文ID
        DLC       :报文长度
        Data      :报文数据
返回值:无
崔立宝's avatar
崔立宝 committed
405 406 407 408 409
******************************************************************************/
void MSCAN0_L_Data_Indication ( uint32_t Identifier, uint8_t DLC, uint8_t *Data )
{
   /*PduInfoType NW_MessageBuffer; 
   
410
   if( ( Identifier >= 0x18FFFA00 ) && ( Identifier <= 0x18FFFAFF ) ) {//网络管理报文
崔立宝's avatar
崔立宝 committed
411 412 413 414 415 416 417
        NW_MessageBuffer.SduDataPtr = Data;
        NW_MessageBuffer.SduLength = DLC;
        CanNm_RxIndication(0, 0,&NW_MessageBuffer);   
        NM_RECEIVE=1; 
        sleepFlg=1;   
    
   } */
418
    ReceivedMsg(Identifier,DLC);
419
   //????1939-21 ?????????????
420 421 422 423 424 425
    //if( ( Identifier == DIAG_ID_Rx_PHY ) || ( Identifier == DIAG_ID_Rx_FUN ) )
   //{ 
       // DoCAN_L_Data_Indication ( Identifier, DLC, Data );
   //}
   //else
   //{
426
        //??????
崔立宝's avatar
崔立宝 committed
427
        CoCAN_L_Data_Indication ( Identifier, DLC, Data );
428
   //}
崔立宝's avatar
崔立宝 committed
429

430 431 432 433
  //if ((Identifier == 0x7E3) || (Identifier == 0x7EB))
  //  DoCAN_L_Data_Indication(Identifier, DLC, Data);
  //else
  //  CoCAN_L_Data_Indication(Identifier, DLC, Data);
崔立宝's avatar
崔立宝 committed
434 435
}

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

/******************************************************************************
456 457 458 459
函数名:MSCAN0_Bus_Off_Monitoring_Service
功  能:MSCAN0 Bus-off状态监控服务,监控Bus-off状态并尝试恢复
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
460
*******************************************************************************
461
注  意:该服务函数必须每20ms被调用一次
崔立宝's avatar
崔立宝 committed
462 463 464 465
******************************************************************************/
void MSCAN0_Bus_Off_Monitoring_Service ( void )
{
#if !MSCAN0_BUS_OFF_AUTO_RECOVERY
466
  #if MSCAN0_BUS_LIMP_MODE_ENABLE
崔立宝's avatar
崔立宝 committed
467

468 469
  if ( MSCAN0Busoff.Status == MSCAN0_BUS_LIMP )
    return;	                                    //CAN总线已经在跛行模式(多次恢复失败),则不再恢复
崔立宝's avatar
崔立宝 committed
470

471
  #endif
崔立宝's avatar
崔立宝 committed
472

473 474 475
  if ( CAN0MISC_BOHOLD )                        //如果Bus-off发生
  {
    MSCAN0Busoff.Timer++;
崔立宝's avatar
崔立宝 committed
476

477 478
    if ( MSCAN0Busoff.Status == MSCAN0_BUS_STABLE )
      MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV1;
崔立宝's avatar
崔立宝 committed
479

480 481 482 483 484 485 486
    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++;
崔立宝's avatar
崔立宝 committed
487

488 489 490 491 492
        if ( MSCAN0Busoff.Cnt >= 10 )
        {
          BUS_OFF_FLAG = 1;
          MSCAN0Busoff.Cnt = 0;
          MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV2;
崔立宝's avatar
崔立宝 committed
493
        }
494
      }
崔立宝's avatar
崔立宝 committed
495
    }
496
    else if ( MSCAN0Busoff.Status == MSCAN0_BUS_OFF_LV2 )
崔立宝's avatar
崔立宝 committed
497
    {
498 499
      if ( MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 20 )
      {
崔立宝's avatar
崔立宝 committed
500
        MSCAN0Busoff.Timer = 0;
501 502 503 504 505
        CAN0MISC_BOHOLD = 1;                    //写1清零,请求恢复Bus-off
      }

    #if MSCAN0_BUS_LIMP_MODE_ENABLE
      MSCAN0Busoff.Cnt++;
崔立宝's avatar
崔立宝 committed
506

507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
      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;
  }
崔立宝's avatar
崔立宝 committed
530 531 532 533
#endif
}

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

/******************************************************************************
547 548 549 550
函数名:MSCAN0_Init
功  能:MSCAN0初始化程序
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
551 552 553
******************************************************************************/
void MSCAN0_Init ( void )
{
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
  //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;        //正常运行模式(非监听模式)
崔立宝's avatar
崔立宝 committed
579
#if MSCAN0_BUS_OFF_AUTO_RECOVERY
580
  CAN0CTL1_BORM = 0;	        //自动总线BUS_OFF恢复
崔立宝's avatar
崔立宝 committed
581
#else
582
  CAN0CTL1_BORM = 1;	        //总线BUS_OFF由用户控制恢复
崔立宝's avatar
崔立宝 committed
583
#endif
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
  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%的采样点
  /*
  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;
崔立宝's avatar
崔立宝 committed
608
#if MSCAN0_BUS_LIMP_MODE_ENABLE
609
  MSCAN0Busoff.Cnt   = 0;
崔立宝's avatar
崔立宝 committed
610 611
#endif

612 613
  // for ( i = 0; i < 3; i++ )
  //   MSCAN0TxID[i] = 0xFFFF;   //0xFFFF表示无效ID
崔立宝's avatar
崔立宝 committed
614 615 616 617 618
  MSCAN0TxBuf.TxHead = 0;
  MSCAN0TxBuf.TxTail = 0;   
}

/******************************************************************************
619 620 621 622
函数名:MSCAN0_Enter_Low_Power_Mode
功  能:令MSCAN0进入低功耗模式
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
623 624 625 626
******************************************************************************/

void MSCAN0_Enter_Low_Power_Mode ( void )
{
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
  //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
崔立宝's avatar
崔立宝 committed
645 646 647
}

/******************************************************************************
648 649 650 651
函数名:MSCAN0_Exit_Low_Power_Mode
功  能:令MSCAN0退出低功耗模式
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
652 653 654
******************************************************************************/
void MSCAN0_Exit_Low_Power_Mode ( void )
{
655
  CAN0CTL0_SLPRQ = 0;         //使得MSCAN退出睡眠
崔立宝's avatar
崔立宝 committed
656

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

660 661 662
  CAN0CTL0_WUPE = 0;			    //禁用唤醒功能
  CAN0_STB = 0;               //使能CAN收发器
  CAN0RIER_RXFIE = 1;   			//使能CAN接收中断
崔立宝's avatar
崔立宝 committed
663 664 665
}

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

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

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

702 703 704 705 706 707 708 709
    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 );
崔立宝's avatar
崔立宝 committed
710

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

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

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

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

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

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

781
	if (CAN0RXIDR1_IDE || CAN0RXIDR1_SRR)     //如果收到的数据为扩展帧,或为远程帧
崔立宝's avatar
崔立宝 committed
782
	{
783 784
    CAN0RFLG_RXF=1;                         //清接收中断标志
		CAN0RIER_RXFIE=1;                       //重新启动MSCAN接收中断
崔立宝's avatar
崔立宝 committed
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 824 825

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

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

/******************************************************************************
831 832 833 834
函数名:MSCAN0_WAKEUP_ISR
功  能:MSCAN0唤醒中断
参  数:无
返回值:无
崔立宝's avatar
崔立宝 committed
835 836 837 838
******************************************************************************/

void interrupt MSCAN0_WAKEUP_ISR ( void )
{
839 840 841 842 843 844
  CAN0RFLG_WUPIF = 1;
  CAN0_STB = 0;
  Time2ms  = 0;
  Time10ms = 0;
  API_Start();
  CanFrameExist = 1;
崔立宝's avatar
崔立宝 committed
845 846 847
}

#pragma CODE_SEG DEFAULT