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.)