How to handle transmit error in CAN communication on mc9s12xdp512

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to handle transmit error in CAN communication on mc9s12xdp512

2,083 Views
KumarSudhanshu
Contributor I
Hi Everyboby i am new to mc9xdp512 . There are 5 CAN nodes on the board. Node 0 and NODE 1 are having the mc33388 transceiver wich is fault tolerent and the Node 2 and Node 4 are having the having the simple transceiver PCA82c250  which is not fault tolerent. AND node 3 is having the mc33989.
My problem is when i am commuinicating between the CAN0(fault tolerent transceiver) and CAN1(fault tolerent tranceiver) my software code is working fine. But when i try to commuinicate between the CAN2 (simple transceiver)and CAN4(simple transceiver) there is transmit error. And no transmission takes place. When I am transmitting from CAN 4(simple transceiver ) and CAN0(fault tolerent transceiver)
the data is received and the never come out of the ISR although i have written the code to clear the receiver flag. And there is Overrun error at the receiver side.And the receive flag is always set.
I am providing the transmit and the receive ISR which i am CAN 2 and CAN 4.
 
//////////////////////// header file mscan.h which i am using for CAN reg address///////////////////////////////////////
#include <hidef.h>
//////////////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////////////
#define MAX_TX_BUFFERS      3
#define MAX_RX_BUFFERS      5
#define MaskOR(A)           (0x01<<A)
#define MSCAN_0             0
#define MSCAN_1             1
#define MSCAN_2             2
#define MSCAN_3             3
#define MSCAN_4             4
#define CANCTL0             0x00
#define CANCTL0_INITRQ_MASK 0x01
#define CANCTL0_SYNCH_MASK  0x10
#define CANCTL1             0x01
#define CANCTL1_INITAK_MASK 0x01
#define CANBTR0             0x02
#define CANBTR1             0x03
#define CANRFLG             0x04
#define CANRFLG_RXF_MASK    0x01
#define CANRIER             0x05
#define CANTFLG             0x06
#define CANTIER             0x07
#define CANTARQ             0x08
#define CANTAAK             0x09
#define CANTBSEL            0x0A
#define CANIDAC             0x0B
#define CANMISC             0x0D
#define CANRXERR            0x0E
#define CANTXERR            0x0F
#define CANIDAR_1B          0x10    // First bank: 4 registers
#define CANIDMR_1B          0x14    // First bank: 4 registers
#define CANIDAR_2B          0x18    // Second bank: 4 registers
#define CANIDMR_2B          0x1C    // Second bank: 4 registers
#define CANRXIDR            0x20    // 4 registers
#define CANRXDSR            0x24    // 8 registers
#define CANRXDLR            0x2C
//#define TBPR              0x2D    // Not available for receive buffers
#define CANRXTSRH           0x2E
#define CANRXTSRL           0x2F
#define CANTXIDR            0x30    // 4 registers
#define CANTXDSR            0x34    // 8 registers
#define CANTXDLR            0x3C
#define CANTXTBPR           0x3D
#define CANTXTSRH           0x3E
#define CANTXTSRL           0x3F
struct can_msg {
    unsigned int id;
    Bool RTR;
    unsigned char data[8];
    unsigned char len;
    unsigned char prty;
};

//////////////////////////////////////////////////////////////////////////////
// Functions
//////////////////////////////////////////////////////////////////////////////
void MSCANInit(unsigned char can_num);
Bool MSCANSendMsg(unsigned char can_num, struct can_msg msg);
 
//////////////////////////////////////////////////// Fuction Definition is available here which is used in the program ////////
 

#include "mc9s12xdp512.h"
#include "mscan.h"
//////////////////////////////////////////////////////////////////////////////
// Variables
//////////////////////////////////////////////////////////////////////////////
unsigned char *can_periph[5] = {
    &CAN0CTL0,
    &CAN1CTL0,
    &CAN2CTL0,
    &CAN3CTL0,
    &CAN4CTL0
};
//////////////////////////////////////////////////////////////////////////////
// MSCAN Peripheral Initialization
//////////////////////////////////////////////////////////////////////////////
void MSCANInit(unsigned char can_num)
{
    unsigned char *can_pt;
    can_pt = can_periph[can_num];
   
    // If MSCAN peripheral is not in Initialization Mode, enables the Inizialization Mode Request
    if(!(can_pt[CANCTL1]&CANCTL1_INITAK_MASK))
        {
        can_pt[CANCTL0] = CANCTL0_INITRQ_MASK;
        while(!(can_pt[CANCTL1]&CANCTL1_INITAK_MASK))
            ;
        }
    // Enables MSCAN peripheral and chooses Oscillator Clock, Loop Disabled and Normal Operation
    can_pt[CANCTL1] = 0x80;
    // Configures SJW = 3Tq and Prescaler = 3
    can_pt[CANBTR0] = 0x82;
    // Configures One Sample, Time Segment 1 = 6Tq and Time Segment 2 = 3Tq
    can_pt[CANBTR1] = 0x25;
    // Disables all the Filters
    can_pt[CANIDMR_1B+0] = 0xFF;
    can_pt[CANIDMR_1B+1] = 0xFF;
    can_pt[CANIDMR_1B+2] = 0xFF;
    can_pt[CANIDMR_1B+3] = 0xFF;
    can_pt[CANIDMR_2B+0] = 0xFF;
    can_pt[CANIDMR_2B+1] = 0xFF;
    can_pt[CANIDMR_2B+2] = 0xFF;
    can_pt[CANIDMR_2B+3] = 0xFF;
    // Restarts MSCAN peripheral and waits for Initialization Mode exit
    can_pt[CANCTL0] = 0x00;
    while(can_pt[CANCTL1]&CANCTL1_INITAK_MASK)
        ;
    // Waits for MSCAN synchronization with the CAN bus
    while(!(can_pt[CANCTL0]&CANCTL0_SYNCH_MASK))
        ;
}
//////////////////////////////////////////////////////////////////////////////
// MSCAN Send Message Routine
//////////////////////////////////////////////////////////////////////////////
Bool MSCANSendMsg(unsigned char can_num, struct can_msg msg)
{
    unsigned char n_tx_buf = 0, i;
    unsigned char *can_pt;
    can_pt = can_periph[can_num];
    if(msg.len > 8)
        return(FALSE);
    if(!(can_pt[CANCTL0]&CANCTL0_SYNCH_MASK))
        return(FALSE);
    while(!(can_pt[CANTFLG]&MaskOR(n_tx_buf)))
        n_tx_buf = (n_tx_buf == MAX_TX_BUFFERS)? 0: (unsigned char)(n_tx_buf + 1);
    can_pt[CANTBSEL] = MaskOR(n_tx_buf);
  
    can_pt[CANTXIDR+0] = (unsigned char)(msg.id>>3);
    can_pt[CANTXIDR+1] = (unsigned char)(msg.id<<5);
    if(msg.RTR)
        can_pt[CANTXIDR+1] |= 0x10;
    for(i = 0; i < msg.len; i++)
        can_pt[CANTXDSR+i] = msg.data[i];
    can_pt[CANTXDLR] = msg.len;
    can_pt[CANTXTBPR] = msg.prty;
    can_pt[CANTFLG] = MaskOR(n_tx_buf);
    return(TRUE);
}
///////////////////////////  Here is the main program which i have witten for transmission from CAN 4 to CAN0//
 
#include <mc9s12xdp512.h>     /* derivative information */
#include <mscan.h>
#pragma LINK_INFO DERIVATIVE "mc9s12xdp512"

///////////////////////////////////////////////////////////////////////////
////////          Global Variable declairation                    /////////
///////////////////////////////////////////////////////////////////////////
#define CAN_MSG_ID          1
  
//////////////////////////////////////////////////////////////////////////////
//                       Peripheral Initialization
//////////////////////////////////////////////////////////////////////////////
void PeriphInit(void)
{
   
        // Configures PB[3..0] as output and PB[7..4] as input
    PORTB = 0x00;
    DDRB = 0x0F;
   
    MSCANInit(MSCAN_4);
    MSCANInit(MSCAN_2);
   
    CAN2RFLG = 0xC0;         
   
    CAN2RIER = 0x01;
                     
    EnableInterrupts;
}
//////////////////////////////////////////////////////////////////////
///////         DELAY Function                              //////////
//////////////////////////////////////////////////////////////////////
void Delay (void) {
    unsigned int counter;
   
    for (counter=0;counter<10000;counter++);
}
///////////////////////////////////////////////////////////////////////
///////           Main Program Starts From Here               /////////
///////////////////////////////////////////////////////////////////////
void main(void) {
 
      struct can_msg msg_send;
      
      PeriphInit();
   
      for(;:smileywink:
      {
          
            msg_send.id = CAN_MSG_ID;
            msg_send.data[0] =0x0B;
            msg_send.len = 1;
            msg_send.RTR = FALSE;
            msg_send.prty = 0;
            (void)MSCANSendMsg(MSCAN_4, msg_send);
            Delay();
          
        }
                 
}
//////////////////////////////////////////////////////////////////////////
///////         ISR starts from here                    //////////////////
//////////////////////////////////////////////////////////////////////////
#pragma CODE_SEG NON_BANKED
void interrupt CAN2RxISR(void)
 {  unsigned char i;
   
    struct can_msg msg;
    msg.id =( ((CAN2RXIDR0<<3)&0x0700) | (unsigned char)(CAN2RXIDR0<<3) | (unsigned char)(CAN2RXIDR1)>>5);
    if(CAN2RXIDR1&0x10)
        msg.RTR = TRUE;
    else
        msg.RTR = FALSE;
    msg.len = CAN2RXDLR;
    for(i = 0; i < msg.len; i++)
        msg.data[i] = *(&CAN2RXDSR0+i);
      
        PORTB= msg.data[0];
       
              
    CAN2RFLG = CANRFLG_RXF_MASK; 
   
}
  
#pragma CODE_SEG DEFAULT
   
 
///////////////////////  The ISR is VECTORED to 0xFFA2 ///////////////////////
 
PLEASE HELP ME ..............
Waiting for the any help.................
 
Labels (1)
0 Kudos
3 Replies

559 Views
Lundin
Senior Contributor IV
Just a dumb question, I'm not sure if I understand you correctly... are you using high-speed CAN and fault-tolerant CAN tranceivers on the same bus...?

Fault-tolerant CAN is 0-5V and high-speed can is 2.5V +- 1V.
0 Kudos

559 Views
KumarSudhanshu
Contributor I
I am agree with you on this point , but there should be the communication between the two high speed CAN transceiver that is not working. There is transmit error during transmission.
0 Kudos

559 Views
Lundin
Senior Contributor IV
I assume you have the fault-tolerant tranceivers disconnected from the bus when you are doing your test.

Fault-tolerant CAN_Hi idles on 0V and CAN_Lo on 5V. High speed CAN idles on 2.5V for both lines.

I have no idea what strange hybrid you have there... high-speed CAN requires bus termination for example, I don't think fault-tolerant CAN does.

They aren't meant to be mixed. If you are doing that... well, no wonder it ain't working.
0 Kudos