Problems getting ECAN nodes to transmit.

Thread Starter

Simy

Joined Aug 8, 2013
7
I'm having a great deal of trouble getting these two nodes to communicate with each other. They work in loopback mode but not in normal mode. I've included the two most likely problem functions below, as well as a quick schematic, and pictures of the nodes. I'm not sure if it is software or hardware. I have tried many different things, but I can't seem to get them to work.

A zipfile containing the J1939 library I have used once before and had to modify, as well as my current hobbled together code. I used the XC8 compiler with MPLABX and the PICKIT3. The files are located at http://tomt.me/halp/CANTest.zip

Thank you for your time, and any insights you can help me with.


Rich (BB code):
//Send a test message
void testmsg(unsigned char msg){
    TXB0EIDH = 0x0000;          //Clear extended IDs
    TXB0SIDH = msg;
    TXB0D0 = 1;
    TXB0DLC = 0x00 | 1;   //changed from count to 1  //Set the RTR flag to false, and set the DLC register.
    TXB0CON = TXB0CON | 0x08 ; //Set the TXREQ flag.
    LED3 = 1;
    while (TXB0CONbits.TXREQ); 
    while (!(LED3=0)); //This SHOULDN'T BE REQUIRED!!!
    LED1 ^= 1;


}
Rich (BB code):
/*
 * Initilize the chip, and CAN module.
 */
void Init(){
    // Set the internal oscillator to 64MHz
    OSCCONbits.IRCF = 7;
    OSCTUNEbits.PLLEN = 1;

    //Initialize I/O to be digital
    ANCON0 = ANCON1 = 0x00;

    //Set I/O
    TRISC = 0x0F; // LED's then Inputs

    //Set all LED's off.
    LATC = 0x00;

    //Set io for tx/rx pins
    TRISB3 = 1; //RX pin
    TRISB2 = 0; //TX Pin




    // Initialize CAN module

    // Enter CAN module into config mode
    CANCON = 0x80;    //REQOP<2:0>=100
    while(!(CANSTATbits.OPMODE ==0x04));

    //Select ECAN Mode 2
    ECANCON = 0xA0; //enhanced fifo, with interrupt when one buffer remains,  Acceptance Filters 0, 1, 2 and BRGCON2, 3

    // Initialize CAN Timing to 1 Mbps @ 64MHz
    //BRGCON1 = 0x81; //0000 0011     //SJW=3TQ     BRP  1
    //BRGCON2 = 0xB8; //1011 1000     //SEG2PHTS 1    sampled once  PS1=8TQ  PropagationT 1TQ
    //BRGCON3 = 0x05; //0000 0101     //PS2  6TQ

    //  100 Kbps @ 64MHz
    BRGCON1 = 0x93; //0001 1111     //SJW=3TQ     BRP  31
    BRGCON2 = 0xB8; //1010 0000     //SEG2PHTS 1    sampled once  PS1=8TQ  PropagationT 1TQ
    BRGCON3 = 0x05; //0000 0010     //PS2  6TQ


    // Initialize Receive Masks
    //Recieve ALL messages
    RXM0EIDH = 0x00;    //Extended ID Mask
    RXM0EIDL = 0x00;
    RXM0SIDH = 0x00;    // Standard ID Mask
    RXM0SIDL = 0x00;


    //Disable Filters
    RXFCON0 = 0x00;     //Disable all
    RXFCON1 = 0x00;     //Disable all


    // Enter CAN module into normal mode
    //CANCON = 0x40; //Loopback Mode
    CANCON = 0x00; //Normal Mode
    while(CANSTATbits.OPMODE==0x00);

    // Set Receive Mode for buffers
    RXB0CON = 0x00;
    RXB1CON = 0x00;

}


 

Papabravo

Joined Feb 24, 2006
21,225
Having a terminating resistor between CANH and CANL on each board is a really bad idea. As you increase the number of nodes it becomes harder to drive the cable with all those terminators in parallel.

First things first. If you have a lonely node you can send a packet and it will try to send that packet forever looking for an acknowledgement. This should allow you to determine if the transmitters are working and what badurate you have selected. When you attach the second node you will either get acknowledgement and all is well or the receiver will throw ERROR FRAMES. At first they will be ERROR ACTIVE frames, then ERROR PASSIVE frames and finally the nodes will go BUS OFF. You should monitor the status register to see if these condition occur. Getting CAN to work is generally easier than rolling out of bed on a Saturday morning, but you have to pay attention to small details.
 

Thread Starter

Simy

Joined Aug 8, 2013
7
I had seen previously that the node goes into busoff state.

After reading your post I went through over and over again, and I found out I was trying to use the banked method of transmitting, while setting the flags for the interrupt method. It seems to be working now, I'll have to play with it some more.

Thanks for the nudge!


For those who are interested, the changed code was to testmsg:
Rich (BB code):
void testmsg(unsigned int msg){

    ECANCONbits.EWIN = 0x003; //Select Transmit buffer one.
    RXB0EIDH = 0x00;          //Clear extended IDs
    RXB0SIDL = 0x00;
    RXB0SIDH = msg >> 8;
    RXB0SIDL = msg;
    RXB0D0 = 0xF8;
    RXB0DLC = 0x00 | 1;   //changed from count to 1  //Set the RTR flag to false, and set the DLC register.
    RXB0CON |= 0x08 ; //Set the TXREQ flag.
    while (RXB0CON & 0x80); //Waiting to xmit.
    LED1 ^= 1;


}
 
Top