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.

TMS320F2808: Changing CAN Baud rate from 1 value to another

Part Number: TMS320F2808

Hello, I have a situation in which my F2808 will be connected to a device that defaults to a CAN baud rate of 20Kbps so I need the F2808 to start with 20Kbps and then the F2808 can update the device to 1Mbps and then the F2808 needs to change its baud rate to 1Mbps. So I have the F2808 communicating at 20Kbps to the device and successfully change the devices baud to 1Mbps. Now I need to change the F2808 to 1Mbps to continue communicating with the device however the baud rate change is getting hung the second time I try to do a change configuration.

void UpdateECanRate(volatile struct ECAN_REGS* ecanregs, CANBaud cbr)
{
/*******************************************************************/
/* Configure bit timing parameters for eCANx*/
ECanShadow.CANMC.all = ecanregs->CANMC.all;
ECanShadow.CANMC.bit.CCR = 1 ; // Set Change Configuration Request = 1
ecanregs->CANMC.all = ECanShadow.CANMC.all;

// Wait until the CPU has been granted permission to change the configuration registers
do
{
ECanShadow.CANES.all = ecanregs->CANES.all;
} while(ECanShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set.. <-- Hangs here when trying to set to 1Mbps after it communicated using 20Kbps- see Note below

ecanregs->CANBTC.all = ECanShadow.CANBTC.all;

/* The following block is only for 100 MHz SYSCLKOUT.
See Note at end of file.
Baud Rate = SYSCLKOUT / ((BRP + 1) * BT)
Bit-time = (TSEG1reg + 1) + (TSEG2reg + 1) + 1
*/
switch (cbr)
{
// Setup prescaler - orig BRPREG was 2
case CANBaud1000000:
// 100MHz/((9 + 1) * 10) = 1MHz
ECanShadow.CANBTC.bit.BRPREG = 9;
break;
case CANBaud500000:
ECanShadow.CANBTC.bit.BRPREG = 19;
break;
case CANBaud250000:
ECanShadow.CANBTC.bit.BRPREG = 39;
break;
case CANBaud125000:
ECanShadow.CANBTC.bit.BRPREG = 79;
break;
case CANBaud50000 :
ECanShadow.CANBTC.bit.BRPREG = 199;
break;
case CANBaud20000 :
ECanShadow.CANBTC.bit.BRPREG = 249;
break;
default:
break;
}

if(cbr != CANBaud20000)
{
// Set up BT of 15 = (2+1) + (10+1) + 1
// Orig was BT of 10 = (6+1) + (1+1) + 1
ECanShadow.CANBTC.bit.TSEG2REG = 1;//2; //1 Time Segment 2 <- Sample start
ECanShadow.CANBTC.bit.TSEG1REG = 6;//10; //6 Time Segment 1 <- Sample exists before sample start
}
else
{
ECanShadow.CANBTC.bit.TSEG2REG = 4;
ECanShadow.CANBTC.bit.TSEG1REG = 13;
}
ECanShadow.CANBTC.bit.SAM = 1; // Sample Point Setting
ecanregs->CANBTC.all = ECanShadow.CANBTC.all;

ECanShadow.CANMC.all = ecanregs->CANMC.all;
ECanShadow.CANMC.bit.CCR = 0 ; // Set Change Configuration Request = 0
ecanregs->CANMC.all = ECanShadow.CANMC.all;

// Wait until the CPU no longer has permission to change the configuration registers
do
{
ECanShadow.CANES.all = ecanregs->CANES.all;
} while(ECanShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared..
/*******************************************************************/
}

Note: Per the SPRUEU0–January 2009, once the CCE bit is cleared (as part of the module initialization), the CANRX pin must be sensed high before you can set the CCE bit to 1 again. How is this possible or is there another way to allow for change configuration again? (All transmitting and receiving is complete at this point.)

  • CANRX pin being high for a sustained period happens during bus idle. All transmitting/receiving being complete also means the bus is idle. Under this condition, the CANRX pin should indeed be high and the device should be able to set CCE to 1. Did you check the level of CANRX pin when your code gets stuck in that loop? Is this behavior consistent or do you only see it intermittently?

    is there another way to allow for change configuration again?

    The only way to change the bit-timing is to set the CCR bit, check if CCE is set and then proceed to update CANBTR.

  • Thanks for the reply. When stuck in the loop, the CANRXA, GPIO30, is 3.3 volts when stuck in the loop. The behavior of being stuck in the loop is consistent - it has always happened since I have tried to change the CAN configuration after CCE = 0. 

  • Jeff,

       In the private conversation, you mentioned the eCAN is not transmitting what you thought it was transmitting and that you need to debug that. Will await an update from you.

  • So I have resolved the Txing and Rxing from the CAN device. I get the following error though:

    CANES 0x00200000 - CRC error.

    Anyway to clear this bit to see if this is what is preventing me from being able to change the CAN configuration? 

    Also the logic analyzer is showing me that the F2808 seems to be putting out miscellaneous bits which may be causing the CRC error? Observe the 'x' in some of the high signals. Data fields defined as 0x00 show at least 1 high bit with the 'x'. I think error correction may be occurring on the other end since I am able to get the correct CAN response. Why the mysterious 'x' bits? See the BRPREG and TSEG[1,2] setups above. (These bits also exist why using an O'Scope in single sequence mode so it's not a logic analyzer anomaly.)

  • The CRC error is trying to tell you something. You don't get an error bit set for nothing.

    Is the CCR bit set as well. Note that this bit will get set if the node goes bus-off.

    F2808 seems to be putting out miscellaneous bits

    Those are stuff bits inserted by the transmitter. It is to be expected in CAN transmission.

    I think error correction may be occurring on the other end

    There is no error correction in CAN, only error detection. If there is an error in any part of the frame, other nodes detect it , transmit error frames and destroy the frame. 

    These bits also exist why using an O'Scope in single sequence mode

    Is your scope capable of triggering on CAN frames? Regardless, I think the scope screen will still show the stuff bits since they are supposed capture the bus activity faithfully. 

  • Hang my head in shame! I was reading the Memory Browser incorrectly. See image:

    However, the issue of the inability to reset the Configuration request bit remains. What can I do to be re-grant permission to change the configuration registers?

        /*******************************************************************/
        /* Configure bit timing parameters for eCANx*/
        ECanShadow.CANMC.all = ecanregs->CANMC.all;
        ECanShadow.CANMC.bit.CCR = 1 ;            // Set Change Configuration Request = 1
        ecanregs->CANMC.all = ECanShadow.CANMC.all;
    
        // Wait until the CPU has been granted permission to change the configuration registers
        do
        {
            ECanShadow.CANES.all = ecanregs->CANES.all; // <== HANGS HERE FOREVER 2ND TIME
        } while(ECanShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be set..

    I even tried to just go from 1Mbps to 1Mbps as a test instead of 20Kbps to 1MBps but the result is the same.

    Also, I am achieving good 20Kbs transmission (same if I try 1Mbps) as I am able to request information from the other CAN device and I am getting back what is expected.

    ISSUE FOUND: Seems my call to UpdateECanRate( ) the first time was in a EALLOW...EDIS routine but an outside call to the same function failed to setup the EALLOW...EDIS region that is required to update the CANBTC registers.

  • Not enabling EALLOW is a common mistake. I have mentioned this in the debug tips in www.ti.com/lit/spra876