Sudhanshu kumar

How to handle transmit error in CAN communication on mc9s12xdp512

Discussion created by Sudhanshu kumar on Sep 16, 2008
Latest reply on Sep 22, 2008 by Daniel Lundin
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.................
 

Outcomes