I'm struggling to get the eCAN module working for my custom board. The board is an electronic speed controller, and I want to be able to transmit signals relating to current/voltage/temperature, as well as receive signals to set the motor's speed or torque. At this point, all I want to do is send a simple signal from board to computer and see it work.
I have setup the eCAN connection to the CPU clock in hal.c (CLK_enableEcanaClock()) and set GPIO 30 and 31 as CANRXA and CANTXA, respectively. Below is my initialization of the eCAN module. I'm not sure if my bit timing is correct, I used the spreadsheet here to determine the values in CANBTC. That was based on a bit rate of 1 Mb/sec b/c that's the maximum rate listed in the spec for my bus (PCAN-USB), but I don't know if that's correct or whether or not I need to set a bit rate somewhere else (I'm new to CAN and am still trying to understand how the process works). Steps are labeled as specified in the TMS320x2805x Piccolo section 12.7.2, "Steps to Configure eCAN".
#include "sw/drivers/can/src/32b/f28x/f2805x/can.h"
#include "sw/drivers/cpu/src/32b/f28x/f2805x/cpu.h"
#pragma DATA_SECTION(ECanaRegs,"ECanaRegsFile");
volatile struct ECAN_REGS ECanaRegs;
#pragma DATA_SECTION(ECanaMboxes,"ECanaMboxesFile");
volatile struct ECAN_MBOXES ECanaMboxes;
int Test = 0;
void CAN_InitECana(void){
ENABLE_PROTECTED_REGISTER_WRITE_MODE;
ECanaRegs.CANTIOC.bit.TXFUNC = 1; // step 2
ECanaRegs.CANRIOC.bit.RXFUNC = 1;
if(ECanaRegs.CANES.bit.CCE == 0){ // step 3
ECanaRegs.CANMC.bit.CCR = 1;
while(ECanaRegs.CANES.bit.CCE == 0);
}
ECanaRegs.CANBTC.bit.TSEG1REG = 8; // step 4
ECanaRegs.CANBTC.bit.TSEG2REG = 5;
ECanaRegs.CANBTC.bit.SJWREG = 3;
ECanaRegs.CANBTC.bit.BRPREG = 0;
ECanaRegs.CANBTC.bit.SAM = 0;
// SCC?
ECanaRegs.CANMC.bit.CCR = 0; // step 6
ECanaRegs.CANMC.bit.PDR = 0;
ECanaRegs.CANMC.bit.DBO = 0;
ECanaRegs.CANMC.bit.WUBA = 0;
ECanaRegs.CANMC.bit.CDR = 0;
ECanaRegs.CANMC.bit.ABO = 0;
ECanaRegs.CANMC.bit.STM = 0;
ECanaRegs.CANMC.bit.SRES = 0;
ECanaRegs.CANMC.bit.MBNR = 0;
ECanaMboxes.MBOX1.MSGCTRL.all = 0; // step 7
DISABLE_PROTECTED_REGISTER_WRITE_MODE;
}
As a starting point, I copied most the program from the c2000 example project, "ecan_back2back", and am calling it as a function after initilization. Here's that:
//
// Prototype statements for functions found within this file.
//
void mailbox_check(uint32_t T1, uint32_t T2, uint32_t T3);
void mailbox_read(uint16_t i);
//
// Global variable for this example
//
uint32_t ErrorCount;
uint32_t PassCount;
uint32_t MessageReceivedCount;
uint32_t TestMbox1 = 0;
uint32_t TestMbox2 = 0;
uint32_t TestMbox3 = 0;
//
// Main
//
void run_eCAP(void)
{
uint16_t j;
//
// eCAN control registers require read/write access using 32-bits. Thus we
// will create a set of shadow registers for this example. These shadow
// registers will be used to make sure the access is 32-bits and not 16.
//
struct ECAN_REGS ECanaShadow;
//
// Step 5. User specific code, enable __interrupts:
//
MessageReceivedCount = 0;
ErrorCount = 0;
PassCount = 0;
CAN_InitECana(); // Initialize eCAN-A module
//
// Mailboxes can be written to 16-bits or 32-bits at a time
// Write to the MSGID field of TRANSMIT mailboxes MBOX0 - 15
//
ECanaMboxes.MBOX0.MSGID.all = 0x9555AAA0;
ECanaMboxes.MBOX1.MSGID.all = 0x9555AAA1;
ECanaMboxes.MBOX2.MSGID.all = 0x9555AAA2;
ECanaMboxes.MBOX3.MSGID.all = 0x9555AAA3;
ECanaMboxes.MBOX4.MSGID.all = 0x9555AAA4;
ECanaMboxes.MBOX5.MSGID.all = 0x9555AAA5;
ECanaMboxes.MBOX6.MSGID.all = 0x9555AAA6;
ECanaMboxes.MBOX7.MSGID.all = 0x9555AAA7;
ECanaMboxes.MBOX8.MSGID.all = 0x9555AAA8;
ECanaMboxes.MBOX9.MSGID.all = 0x9555AAA9;
ECanaMboxes.MBOX10.MSGID.all = 0x9555AAAA;
ECanaMboxes.MBOX11.MSGID.all = 0x9555AAAB;
ECanaMboxes.MBOX12.MSGID.all = 0x9555AAAC;
ECanaMboxes.MBOX13.MSGID.all = 0x9555AAAD;
ECanaMboxes.MBOX14.MSGID.all = 0x9555AAAE;
ECanaMboxes.MBOX15.MSGID.all = 0x9555AAAF;
//
// Write to the MSGID field of RECEIVE mailboxes MBOX16 - 31
//
ECanaMboxes.MBOX16.MSGID.all = 0x9555AAA0;
ECanaMboxes.MBOX17.MSGID.all = 0x9555AAA1;
ECanaMboxes.MBOX18.MSGID.all = 0x9555AAA2;
ECanaMboxes.MBOX19.MSGID.all = 0x9555AAA3;
ECanaMboxes.MBOX20.MSGID.all = 0x9555AAA4;
ECanaMboxes.MBOX21.MSGID.all = 0x9555AAA5;
ECanaMboxes.MBOX22.MSGID.all = 0x9555AAA6;
ECanaMboxes.MBOX23.MSGID.all = 0x9555AAA7;
ECanaMboxes.MBOX24.MSGID.all = 0x9555AAA8;
ECanaMboxes.MBOX25.MSGID.all = 0x9555AAA9;
ECanaMboxes.MBOX26.MSGID.all = 0x9555AAAA;
ECanaMboxes.MBOX27.MSGID.all = 0x9555AAAB;
ECanaMboxes.MBOX28.MSGID.all = 0x9555AAAC;
ECanaMboxes.MBOX29.MSGID.all = 0x9555AAAD;
ECanaMboxes.MBOX30.MSGID.all = 0x9555AAAE;
ECanaMboxes.MBOX31.MSGID.all = 0x9555AAAF;
//
// Configure Mailboxes 0-15 as Tx, 16-31 as Rx
// Since this write is to the entire register (instead of a bit
// field) a shadow register is not required.
//
ECanaRegs.CANMD.all = 0xFFFF0000;
//
// Enable all Mailboxes
// Since this write is to the entire register (instead of a bit
// field) a shadow register is not required.
//
ECanaRegs.CANME.all = 0xFFFFFFFF;
//
// Specify that 8 bits will be sent/received
//
ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX6.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX7.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX11.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX12.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX13.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX14.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
//
// Write to the mailbox RAM field of MBOX0 - 15
//
ECanaMboxes.MBOX0.MDL.all = 0x9555AAA0;
ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX1.MDL.all = 0x9555AAA1;
ECanaMboxes.MBOX1.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX2.MDL.all = 0x9555AAA2;
ECanaMboxes.MBOX2.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX3.MDL.all = 0x9555AAA3;
ECanaMboxes.MBOX3.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX4.MDL.all = 0x9555AAA4;
ECanaMboxes.MBOX4.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX5.MDL.all = 0x9555AAA5;
ECanaMboxes.MBOX5.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX6.MDL.all = 0x9555AAA6;
ECanaMboxes.MBOX6.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX7.MDL.all = 0x9555AAA7;
ECanaMboxes.MBOX7.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX8.MDL.all = 0x9555AAA8;
ECanaMboxes.MBOX8.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX9.MDL.all = 0x9555AAA9;
ECanaMboxes.MBOX9.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX10.MDL.all = 0x9555AAAA;
ECanaMboxes.MBOX10.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX11.MDL.all = 0x9555AAAB;
ECanaMboxes.MBOX11.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX12.MDL.all = 0x9555AAAC;
ECanaMboxes.MBOX12.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX13.MDL.all = 0x9555AAAD;
ECanaMboxes.MBOX13.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX14.MDL.all = 0x9555AAAE;
ECanaMboxes.MBOX14.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX15.MDL.all = 0x9555AAAF;
ECanaMboxes.MBOX15.MDH.all = 0x89ABCDEF;
//
// Since this write is to the entire register (instead of a bit
// field) a shadow register is not required.
//
ENABLE_PROTECTED_REGISTER_WRITE_MODE;
ECanaRegs.CANMIM.all = 0xFFFFFFFF;
DISABLE_PROTECTED_REGISTER_WRITE_MODE;
//
// Configure the eCAN for self test mode
// Enable the enhanced features of the eCAN.
//
ENABLE_PROTECTED_REGISTER_WRITE_MODE;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.STM = 1; // Configure CAN for self-test mode
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
DISABLE_PROTECTED_REGISTER_WRITE_MODE;
//
// Begin transmitting
//
for(;;)
{
ECanaRegs.CANTRS.all = 0x0000FFFF;// Set TRS for all transmit mailboxes
//
// Wait for all TAn bits to be set..
//
while(ECanaRegs.CANTA.all != 0x0000FFFF )
{
}
ECanaRegs.CANTA.all = 0x0000FFFF; // Clear all TAn
MessageReceivedCount++;
//
//Read from Receive mailboxes and begin checking for data
//
for(j=16; j<32; j++) // Read & check 16 mailboxes
{
mailbox_read(j); // This func reads the indicated mailbox data
mailbox_check(TestMbox1,TestMbox2,TestMbox3);//Checks received data
}
}
}
//
// This function reads out the contents of the indicated
// by the Mailbox number (MBXnbr).
//
void mailbox_read(uint16_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(uint32_t T1, uint32_t T2, uint32_t T3)
{
if((T1 != T3) || ( T2 != 0x89ABCDEF))
{
ErrorCount++;
}
else
{
PassCount++;
}
}
//
// End of file.
//
I could really use help in determining whether my bit timing configs are correct, if there's something wrong with the way I'm transmitting the signal, and anything else to help me get this working. My understanding of the CAN system is very limited.
Thank you