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.

CCS: TMS320F28069M ECAN communicate with Arduino DUE

Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hello,

I want to use c2000 F28069M ECAN to connect a can bus transceiver with Arduino DUE.

For hardware part, transceiver TX/RX pin connect with each DUE TX/RX pin, CANH/CANL connect with F28069M CANH/CANL.

For software part, I had run F28069M ECanBack2Back self-test successful, but now I need to communicate with DUE, so I comment out the ECanaShadow.CANMC.bit.STM = 1;.

For My test, I set Mailbox0 as transmit, and DUE as receiver, when CCS is in debug mode, debug call stack always stop as shown below, It means transmit doesn't work.

On the other hand, I also try to set Mailbox0 as receiver and  Due as transmit, but F28069M doesn't receive any data.

Here is my code from controlsuit F28069M ECanBack2Back example, and migrate to motorware proj.1.

#include <math.h> // modules #include "sw/modules/math/src/32b/math.h" #include "sw/modules/memCopy/src/memCopy.h" #include "sw/drivers/can/src/32b/f28x/f2806x/can.h" #pragma DATA_SECTION(ECanaRegs,"ECanaRegsFile"); volatile struct ECAN_REGS ECanaRegs; #pragma DATA_SECTION(ECanaMboxes,"ECanaMboxesFile"); volatile struct ECAN_MBOXES ECanaMboxes; volatile struct ECAN_REGS ECanaShadow; // drivers // platforms #include "main.h" // ************************************************************************** // the defines #define LED_BLINK_FREQ_Hz 5 // ************************************************************************** // the globals uint_least32_t gLEDcnt = 0; // Counter used to divide down the ISR rate for visually blinking an LED HAL_Handle halHandle; // Handle to the Inverter hardware abstraction layer USER_Params gUserParams; // Contains the user.h settings HAL_PwmData_t gPwmData = {0,0,0}; // Contains PWM duty cycles in global Q format HAL_AdcData_t gAdcData = {0,0,0,0,0,0,0}; // Contains Current and Voltage ADC readings in global Q format volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT; #ifdef FLASH // Used for running BackGround in flash, and ISR in RAM extern uint_least16_t_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart; #endif #ifdef DRV8301_SPI // Watch window interface to the 8301 SPI DRV_SPI_8301_Vars_t gDrvSpi8301Vars; #endif uint_least32_t ErrorCount; uint_least32_t PassCount; uint_least32_t MessageReceivedCount; uint_least32_t TestMbox1 = 0; uint_least32_t TestMbox2 = 0; uint_least32_t TestMbox3 = 0; int i,j; long loopcount = 0; int MBX_data[32]; // This array stores the data to be transmitted // ************************************************************************** // the functions // Prototype statements for functions found within this file. void mailbox_check(int_least32_t T1, int_least32_t T2, int_least32_t T3); void mailbox_read(int_least16_t i); void InitECana(void); void main(void) { uint_least16_t j; MessageReceivedCount = 0; ErrorCount = 0; PassCount = 0; struct ECAN_REGS ECanaShadow; // Only used if running from FLASH // Note that the variable FLASH is defined by the project #ifdef FLASH // Copy time critical code and Flash setup code to RAM // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart // symbols are created by the linker. Refer to the linker files. memCopy((uint_least16_t_t *)&RamfuncsLoadStart,(uint_least16_t_t *)&RamfuncsLoadEnd,(uint_least16_t_t *)&RamfuncsRunStart); #endif // initialize the hardware abstraction layer halHandle = HAL_init(&hal,sizeof(hal)); // check for errors in user parameters USER_checkForErrors(&gUserParams); // store user parameter error in global variable gMotorVars.UserErrorCode = USER_getErrorCode(&gUserParams); // do not allow code execution if there is a user parameter error if(gMotorVars.UserErrorCode != USER_ErrorCode_NoError) { for(;;) { gMotorVars.Flag_enableSys = false; } } // initialize the user parameters USER_setParams(&gUserParams); // set the hardware abstraction layer parameters HAL_setParams(halHandle,&gUserParams); #ifdef LAUNCHPAD // Setup GPIOs 0 and 1 as outputs for use in project lab1 only. // This is specific to the launchpad because its LEDs are also used by the PWM channels. HAL_setupLaunchPadGpio0and1(halHandle); #endif // setup faults HAL_setupFaults(halHandle); // initialize the interrupt vector table HAL_initIntVectorTable(halHandle); // enable the ADC interrupts HAL_enableAdcInts(halHandle); // enable global interrupts HAL_enableGlobalInts(halHandle); // enable debug interrupts HAL_enableDebugInt(halHandle); // disable the PWM HAL_disablePwm(halHandle); #ifdef DRV8301_SPI // turn on the DRV8301 if present HAL_enableDrv(halHandle); // initialize the DRV8301 interface HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars); #endif InitECana(); ECanaMboxes.MBOX0.MSGID.all = 0x9555AAA0; ECanaRegs.CANMD.bit.MD0 = 0 //0 -> Tx 1 -> Rx // Enable all Mailboxes */ // Since this write is to the entire register (instead of a bit // field) a shadow register is not required. ECanaShadow.CANME.all = ECanaRegs.CANME.all; ECanaShadow.CANME.all = 0xFFFFFFFF; ECanaRegs.CANME.all = ECanaShadow.CANME.all; ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8; EALLOW; /************** comment out part **************/ /*ECanaRegs.CANMIM.all = 0xFFFFFFFF; // Configure the eCAN for self test mode // Enable the enhanced features of the eCAN. EALLOW; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.STM = 1; // Configure CAN for self-test mode ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; EDIS;*/ for(;;) { ECanaMboxes.MBOX0.MDL.all = 12345678; ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF; ECanaRegs.CANTRS.bit.TRS0 = 1; while(ECanaRegs.CANTA.bit.TA0 != 1 ) {} // Wait for all TAn bits to be set.. ECanaRegs.CANTA.bit.TA0 = 1; // Clear all TAn for(j=0; j<1; j++) // Read & check 16 mailboxes { mailbox_read(j); // This func reads the indicated mailbox data mailbox_check(TestMbox1,TestMbox2,TestMbox3); // Checks the received data } } interrupt void mainISR(void) { // toggle status LED if(gLEDcnt++ > (uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK_FREQ_Hz)) { HAL_toggleLed(halHandle,(GPIO_Number_e)HAL_Gpio_LED2); gLEDcnt = 0; } // acknowledge the ADC interrupt HAL_acqAdcInt(halHandle,ADC_IntNumber_1); // convert the ADC data HAL_readAdcData(halHandle,&gAdcData); // ADC processing and pwm result code goes here // write the PWM compare values HAL_writePwmData(halHandle,&gPwmData); return; } // end of mainISR() function void mailbox_read(int_least16_t MBXnbr) { volatile struct MBOX *Mailbox; Mailbox = &ECanaMboxes.MBOX0 + MBXnbr; TestMbox1 = Mailbox->MDL.all; // = 0x9555AAAn (n is the MBX number) TestMbox2 = Mailbox->MDH.all; // = 0x89ABCDEF (a constant) TestMbox3 = Mailbox->MSGID.all;// = 0x9555AAAn (n is the MBX number) } // MSGID of a rcv MBX is transmitted as the MDL data. void mailbox_check(int_least32_t T1, int_least32_t T2, int_least32_t T3) { if((T1 != T3) || ( T2 != 0x89ABCDEF)) { ErrorCount++; } else { PassCount++; } } void InitECana(void) // Initialize eCAN-A module { /* 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 or return false data. */ struct ECAN_REGS ECanaShadow; EALLOW; // asm(" asm(" EALLOW")") enables access to protected bits /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/ ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all; ECanaShadow.CANTIOC.bit.TXFUNC = 1; ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all; ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all; ECanaShadow.CANRIOC.bit.RXFUNC = 1; ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all; /* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */ // HECC mode also enables time-stamping feature ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.SCB = 1; ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; /* Initialize all bits of 'Message Control Register' to zero */ // Some bits of MSGCTRL register come up in an unknown state. For proper operation, // all bits (including reserved bits) of MSGCTRL must be initialized to zero ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000; ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000; // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again // as a matter of precaution. ECanaRegs.CANTA.all = 0xFFFFFFFF; /* Clear all TAn bits */ ECanaRegs.CANRMP.all = 0xFFFFFFFF; /* Clear all RMPn bits */ ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */ ECanaRegs.CANGIF1.all = 0xFFFFFFFF; /* Configure bit timing parameters for eCANA*/ ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1 ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; // Wait until the CPU has been granted permission to change the configuration registers do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set.. ECanaShadow.CANBTC.all = 0; /* The following block is for 80 MHz SYSCLKOUT. (40 MHz CAN module clock Bit rate = 1 Mbps See Note at end of file. */ ECanaShadow.CANBTC.bit.BRPREG = 1; ECanaShadow.CANBTC.bit.TSEG2REG = 4; ECanaShadow.CANBTC.bit.TSEG1REG = 13; ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all; EALLOW; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0 ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; // Wait until the CPU no longer has permission to change the configuration registers do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared.. /* Disable all Mailboxes */ ECanaRegs.CANME.all = 0; // Required before writing the MSGIDs //EDIS; }


For Arduino code, I use collin80/due_can - CAN_Echo Test example from GitHub.

Could anyone can help me to complete communicate?
Thanks!