This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Can't get CANa to receive.

Hi,

I'm working with the 2808 development kit and I'm trying to get the CANa to receive.  The code is below.  It gets stuck on the do/while loop waiting for CANRMP to change.

 

 

// TI File $Revision: /main/2 $

// Checkin $Date: July 31, 2009 14:26:08 $

//###########################################################################

// Filename: Example_28xEcan_A_to_B_Xmit.c

//

// Description: eCAN-A To eCAN-B TXLOOP - Transmit loop

//

// ASSUMPTIONS:

//

// This program requires the DSP280x header files.

//

// Both CAN ports of the 280x DSP need to be connected

// to each other (via CAN transceivers)

//

// eCANA is on GPIO31 (CANTXA) and

// GPIO30 (CANRXA)

//

// eCANB is on GPIO8 (CANTXB) and

// GPIO10 (CANRXB)

//

// As supplied, this project is configured for "boot to SARAM"

// operation. The 280x Boot Mode table is shown below.

// For information on configuring the boot mode of an eZdsp,

// please refer to the documentation included with the eZdsp,

//

// Boot GPIO18 GPIO29 GPIO34

// Mode SPICLKA SCITXDA

// SCITXB

// -------------------------------------

// Flash 1 1 1

// SCI-A 1 1 0

// SPI-A 1 0 1

// I2C-A 1 0 0

// ECAN-A 0 1 1

// SARAM 0 1 0 <- "boot to SARAM"

// OTP 0 0 1

// I/0 0 0 0

//

//

// DESCRIPTION:

//

// This example TRANSMITS data to another CAN module using MAILBOX5

// This program could either loop forever or transmit "n" # of times,

// where "n" is the TXCOUNT value.

//

// This example can be used to check CAN-A and CAN-B. Since CAN-B is

// initialized in DSP280x_ECan.c, it will acknowledge all frames

// transmitted by the node on which this code runs. Both CAN ports of

// the 280x DSP need to be connected to each other (via CAN transceivers)

//

//###########################################################################

// Original Author: HJ

//

// $TI Release: DSP280x C/C++ Header Files V1.70 $

// $Release Date: July 27, 2009 $

//###########################################################################

 

#include

 

 

"DSP280x_Device.h" // DSP280x Headerfile Include File

#include

 

 

"DSP280x_Examples.h" // DSP280x Examples Include File

 

#define

 

 

TXCOUNT 10 // Transmission will take place (TXCOUNT) times..

 

// Globals for this example

long

 

 

i;

long

 

 

loopcount = 0;

 

 

void

 

 

main()

{

Uint32 mdl;

Uint32 mdh;

 

 

/* Create a shadow register structure for the CAN control registers. This is

needed, since, only 32-bit access is allowed to these registers. 16-bit access

to these registers could potentially corrupt the register contents. This is

especially true while writing to a bit (or group of bits) among bits 16 - 31 */

 

 

struct ECAN_REGS ECanaShadow;

 

// Step 1. Initialize System Control:

// PLL, WatchDog, enable Peripheral Clocks

// This example function is found in the DSP280x_SysCtrl.c file.

InitSysCtrl();

 

// Step 2. Initalize GPIO:

// This example function is found in the DSP280x_Gpio.c file and

// illustrates how to set the GPIO to it's default state.

// InitGpio(); // Skipped for this example

 

 

// Just initalize eCAN pins for this example

 

// This function is in DSP280x_ECan.c

InitECanGpio();

 

// Step 3. Clear all interrupts and initialize PIE vector table:

// Disable CPU interrupts

DINT;

 

// Initialize the PIE control registers to their default state.

// The default state is all PIE interrupts disabled and flags

// are cleared.

// This function is found in the DSP280x_PieCtrl.c file.

InitPieCtrl();

 

// Disable CPU interrupts and clear all CPU interrupt flags:

IER = 0x0000;

IFR = 0x0000;

 

// Initialize the PIE vector table with pointers to the shell Interrupt

// Service Routines (ISR).

// This will populate the entire table, even if the interrupt

// is not used in this example. This is useful for debug purposes.

// The shell ISR routines are found in DSP280x_DefaultIsr.c.

// This function is found in DSP280x_PieVect.c.

InitPieVectTable();

 

// Interrupts that are used in this example are re-mapped to

// ISR functions found within this file.

 

// No interrupts used in this example.

 

// Step 4. Initialize all the Device Peripherals:

// This function is found in DSP280x_InitPeripherals.c

// InitPeripherals(); // Not required for this example

 

 

// In this case just initalize eCAN-A and eCAN-B

 

// This function is in DSP280x_ECan.c

InitECan();

 

// Step 5. User specific code:

 

/* Write to the MSGID field */

 

// ECanaMboxes.MBOX15.MSGID.all = 0x95555555; // Extended Identifier

 

ECanaMboxes.MBOX25.MSGID.all = 0x81800000;

//Standard Identifier - Transmit MBOX 15

ECanaMboxes.MBOX3.MSGID.all = 0xC200;

// Standard Identifier - Rcv MBOX 3

 

/* Configure Mailbox under test as a Transmit mailbox */

 

ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;

ECanaShadow.CANMD.bit.MD15 = 0;

ECanaShadow.CANMD.bit.MD3 = 1;

ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

 

/* Enable Mailbox under test */

 

ECanaShadow.CANME.all = ECanaRegs.CANME.all;

ECanaShadow.CANME.bit.ME15 = 1;

ECanaShadow.CANME.bit.ME3 = 1;

ECanaRegs.CANME.all = ECanaShadow.CANME.all;

 

/* Write to DLC field in Master Control reg */

 

ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;

ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 4;

 

/* Clear to the transmit mailbox RAM field */

 

ECanaMboxes.MBOX15.MDL.all = 0x00000000;

ECanaMboxes.MBOX15.MDH.all = 0x00000000;

 

/* Begin reading from receive mailbox 3 */

 

ECanaShadow.CANRMP.bit.RMP3 = 0;

ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;

mdl=0;

mdh=0;

 

 

do

{

ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;

}

while(ECanaShadow.CANRMP.bit.RMP3 == 0); // Wait for CANRMP bit to be set..

 

 

ECanaRegs.CANRMP.bit.RMP3 = 1;

mdl = ECanaMboxes.MBOX3.MDL.all;

mdh = ECanaMboxes.MBOX3.MDH.all;

 

 

/* Copy received data to the transmit mailbox RAM field */

 

ECanaMboxes.MBOX15.MDL.all = mdl;

ECanaMboxes.MBOX15.MDH.all = mdh;

 

ECanaRegs.CANRMP.bit.RMP3 = 0;

 

 

/* Begin transmitting */

 

 

 

for(i=0; i < TXCOUNT; i++)

{

ECanaShadow.CANTRS.all = 0;

ECanaShadow.CANTRS.bit.TRS15 = 1;

// Set TRS for mailbox under test

ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;

 

 

do

{

ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;

}

while(ECanaShadow.CANTA.bit.TA15 == 0 );

 

ECanaShadow.CANTA.all = 0;

ECanaShadow.CANTA.bit.TA15 = 1;

// Clear TA5

ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;

 

loopcount ++;

}

 

asm(" ESTOP0"); // Stop here

}

 

 

  • Who is sending the messages? Is it another node? Can you see that messages with an analyzer? What data rate do you use? Can you verify that data rate with an analyzer? 

    In your code there are wrong lines, so that this code will never work:

    (1) You set the MSGID for mailbox 25, but later you operate on mailbox 15 

     ECanaMboxes.MBOX25.MSGID.all = 0x81800000;

    (2) If you want to use standard id's, you have to set the identifier to the correct positions in MSGID ( a 32 bit register, the upper bits are used for the 11 std id's). However, your initialisation uses the lower 16 bits:

     ECanaMboxes.MBOX3.MSGID.all = 0xC200;

    // Standard Identifier - Rcv MBOX 3

    (3) Why do you initialize the DLC two times? It doesn't make sense:

     /* Write to DLC field in Master Control reg */

     ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;

    ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 4;

  • The messages are being sent from a PCAN-USB adapter.  I have a scope on the input to the CPU and I see the messages there.  The waveforms look pretty clean.  I'm using 125Kbits/s.  I don't have an analyzer.

    1) I have fixed yesterday that but that was for the transmit.

    2) I have also tried 0xC2000000.  No success

    3) One is for transmit and one for receive.  I also caught that.  The DLC=4 should go to MBOX3.  I fixed it yesterday and no change.

    As an experiment, last night I tried to use some code from here http://www.claytonmcneil.com/pages/contentpgs/ti_f2808_ecan_guide/TI_F2808_eCAN_Guide_P1.htm.  I had the same issue.  I could transmit but I could not receive.  I think the problem is in my handling of the interrupt/flag as that is where things seem to get stuck.  Another place that might be a problem is the BRP stuff.  I'm not sure what is best.  BRPREG=9, TSEG2REG=1, and TSEG1REG=6.

    I have attached the code with the changes from the above website.  Again, I can transmit but I can't receive and it gets stuck waiting for the received message line

    if (ECanaRegs.CANRMP.all > 0 && ECanaRegs.CANGIF0.bit.MIV0 == 3)

     

     

     

    // TI File $Revision: /main/2 $
    // Checkin $Date: July 31, 2009   14:26:08 $
    //###########################################################################
    // Filename: Example_28xEcan_A_to_B_Xmit.c
    //
    // Description: eCAN-A To eCAN-B TXLOOP - Transmit loop
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP280x header files.
    //
    //    Both CAN ports of the 280x DSP need to be connected
    //    to each other (via CAN transceivers)
    //
    //       eCANA is on GPIO31 (CANTXA)  and
    //                   GPIO30 (CANRXA)
    //
    //       eCANB is on GPIO8  (CANTXB)  and
    //                   GPIO10 (CANRXB)
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The 280x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //       Boot      GPIO18     GPIO29    GPIO34
    //       Mode      SPICLKA    SCITXDA
    //                 SCITXB
    //       -------------------------------------
    //       Flash       1          1        1
    //       SCI-A       1          1        0
    //       SPI-A       1          0        1
    //       I2C-A       1          0        0
    //       ECAN-A      0          1        1
    //       SARAM       0          1        0  <- "boot to SARAM"
    //       OTP         0          0        1
    //       I/0         0          0        0
    //
    //
    // DESCRIPTION:
    //
    //    This example TRANSMITS data to another CAN module using MAILBOX5
    //    This program could either loop forever or transmit "n" # of times,
    //    where "n" is the TXCOUNT value.
    //
    //    This example can be used to check CAN-A and CAN-B. Since CAN-B is
    //    initialized in DSP280x_ECan.c, it will acknowledge all frames
    //    transmitted by the node on which this code runs. Both CAN ports of
    //    the 280x DSP need to be connected to each other (via CAN transceivers)
    //
    //###########################################################################
    // Original Author: HJ
    //
    // $TI Release: DSP280x C/C++ Header Files V1.70 $
    // $Release Date: July 27, 2009 $
    //###########################################################################
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    #define TXCOUNT  10  // Transmission will take place (TXCOUNT) times..
    
    // Globals for this example
    long      i;
    long 	  loopcount = 0;
    
    void ReceiveCANMsg(int16, Uint32*, Uint32*);
    void SendCANMsg(int16, Uint32, Uint32);
    
    void main()
    {
    
    Uint32 datah;
    Uint32 datal;
    
    Uint32* raw_datah;
    Uint32* raw_datal;
    	
    //Uint32	mdl;
    //Uint32 	mdh;
    
    
    /* Create a shadow register structure for the CAN control registers. This is
     needed, since, only 32-bit access is allowed to these registers. 16-bit access
     to these registers could potentially corrupt the register contents. This is
     especially true while writing to a bit (or group of bits) among bits 16 - 31 */
       struct ECAN_MBOXES MBoxesShadow;
       struct ECAN_REGS ECanaShadow;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP280x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP280x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
       // Just initalize eCAN pins for this example
       // This function is in DSP280x_ECan.c
       InitECanGpio();
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP280x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP280x_DefaultIsr.c.
    // This function is found in DSP280x_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    
    // No interrupts used in this example.
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP280x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
    
       // In this case just initalize eCAN-A and eCAN-B
       // This function is in DSP280x_ECan.c
       InitECan();
    
    // Step 5. User specific code:
    
    /* Write to the MSGID field  */
    
    //   ECanaMboxes.MBOX15.MSGID.all = 0x95555555; // Extended Identifier
    
       ECanaMboxes.MBOX15.MSGID.all = 0x81800000; //Standard Identifier - Transmit MBOX 15
    //   ECanaMboxes.MBOX3.MSGID.all = 0xC2000000; // Standard Identifier - Rcv MBOX 3
       MBoxesShadow.MBOX3.MSGID.bit.AAM = 0;
       MBoxesShadow.MBOX3.MSGID.bit.AME = 0;
       MBoxesShadow.MBOX3.MSGID.bit.IDE = 0;
       MBoxesShadow.MBOX3.MSGID.bit.STDMSGID = 0XFF;
       ECanaMboxes.MBOX3.MSGID.all = MBoxesShadow.MBOX3.MSGID.all;
       
       ECanaRegs.CANGAM.all = 0x8003FFFF; 
       
    /* Configure Mailbox under test as a Transmit mailbox */
    
       ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
       ECanaShadow.CANMD.bit.MD15 = 0;
       ECanaShadow.CANMD.bit.MD3 = 1;
       ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
    
    /* Enable Mailbox under test */
    
       ECanaShadow.CANME.all = ECanaRegs.CANME.all;
       ECanaShadow.CANME.bit.ME15 = 1;
       ECanaShadow.CANME.bit.ME3 = 1;
       ECanaRegs.CANME.all = ECanaShadow.CANME.all;
    
    /* Write to DLC field in Master Control reg */
    
       ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
       ECanaMboxes.MBOX3.MSGCTRL.bit.DLC = 4;
    
    /* Turn off RTR */
    
       ECanaMboxes.MBOX15.MSGCTRL.bit.RTR = 0;
       ECanaMboxes.MBOX3.MSGCTRL.bit.RTR = 0;
    
    /* Set up/disable interrupts */
    
       EALLOW;
           ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;    
           ECanaShadow.CANGIM.bit.MTOM = 0;   
           ECanaShadow.CANGIM.bit.TCOM = 0;
           ECanaShadow.CANGIM.bit.AAIM = 0;
           ECanaShadow.CANGIM.bit.WDIM = 0;
           ECanaShadow.CANGIM.bit.WUIM = 0;
           ECanaShadow.CANGIM.bit.RMLIM = 0;
           ECanaShadow.CANGIM.bit.BOIM = 0;
           ECanaShadow.CANGIM.bit.EPIM = 0;
           ECanaShadow.CANGIM.bit.WLIM = 0;
    
           ECanaShadow.CANGIM.bit.GIL = 0; // Map global interrupts to ECAN0INT
           ECanaShadow.CANGIM.bit.I1EN = 0;
           ECanaShadow.CANGIM.bit.I0EN = 1;
           ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all; 
    
          ECanaRegs.CANMIM.all = 0x00000006;
    
          ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
          ECanaShadow.CANMC.bit.DBO = 0;
          ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
        EDIS;
    
          ECanaRegs.CANMIL.all = 0xFFFFFFFF;   // Mailbox Interrupt Level: All    
    
          ECanaRegs.CANOPC.all = 0x00000000;
    
    datah = 0x55555555;
    datal = 0xAAAAAAAA;
    
    raw_datah = &datah;
    raw_datah = &datal;
    
    
    
        for(;;) 
        {  
            if (ECanaRegs.CANRMP.all > 0 && ECanaRegs.CANGIF0.bit.MIV0 == 3)
            {
                ReceiveCANMsg(3, raw_datah, raw_datal);
                SendCANMsg(15, datah, datal);
            }
     //           SendCANMsg(15, datah, datal);
            
        }
    
    
    
    
    
    }
    
    void ReceiveCANMsg(int16 MBXnum, Uint32 *raw_datah, Uint32 *raw_datal)
    {
        volatile struct MBOX *srcMBox;
    
        if (0 <= MBXnum && MBXnum <= 32)
        {
            // Get pointer to mailbox struct and grab data
            srcMBox = &ECanaMboxes.MBOX0 + MBXnum;
            *raw_datah = srcMBox->MDH.all; 
            *raw_datal = srcMBox->MDL.all; 
            ECanaRegs.CANRMP.all = (0x00000001 << MBXnum);
    
            /* Process Data */
        }
    }
    
    void SendCANMsg(int16 MBXnum,  Uint32 MBXDL,  Uint32 MBXDH)
    {
        volatile struct MBOX *srcMBox;
    
        if (0 <= MBXnum && MBXnum <= 32)
        {
            Uint32 MBXflag = (0x00000001 << MBXnum);
    
            srcMBox = &ECanaMboxes.MBOX0 + MBXnum;
            srcMBox->MDL.all = MBXDL;
            srcMBox->MDH.all = MBXDH;
    
            ECanaRegs.CANTRS.all = MBXflag;
            while(ECanaRegs.CANTA.all != MBXflag) {}
            ECanaRegs.CANTA.all = MBXflag;
        }
    
    }
    
    
    
    
    
    
    
    
    
    /*      
    // Clear to the transmit mailbox RAM field 
    
       ECanaMboxes.MBOX15.MDL.all = 0x00000000;
       ECanaMboxes.MBOX15.MDH.all = 0x00000000;
    
    // Begin reading from receive mailbox 3 
    
       ECanaShadow.CANRMP.bit.RMP3 = 0;
       ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;
       mdl=0;
       mdh=0;
       
        do
        {
          ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
        } while(ECanaShadow.CANRMP.bit.RMP3 == 0);       // Wait for CANRMP bit to be set..
    
       
       ECanaRegs.CANRMP.bit.RMP3 = 1;
       mdl = ECanaMboxes.MBOX3.MDL.all;
       mdh = ECanaMboxes.MBOX3.MDH.all;
    
    
    // Copy received data to the transmit mailbox RAM field 
       
       ECanaMboxes.MBOX15.MDL.all = mdl;
       ECanaMboxes.MBOX15.MDH.all = mdh;
    
       ECanaRegs.CANRMP.bit.RMP3 = 0;
    
    
    // Begin transmitting 
    
    
       for(i=0; i < TXCOUNT; i++)
       {
           ECanaShadow.CANTRS.all = 0;
           ECanaShadow.CANTRS.bit.TRS15 = 1;     // Set TRS for mailbox under test
           ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
    
           do
    	   {
    	       ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
           } while(ECanaShadow.CANTA.bit.TA15 == 0 );
    
           ECanaShadow.CANTA.all = 0;
           ECanaShadow.CANTA.bit.TA15 = 1;     	 // Clear TA5
           ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
    
           loopcount ++;
        }
         asm(" ESTOP0");  // Stop here
    }
    
    */