Hi -
I'm using CW10.2 w/ProcExp to set-up CAN Bus communications between two processors.
I seem to be having trouble setting up the timing. For example, the 'Bit rate' parameter under 'Timing' only allows two values - 5851.429 bit/s and 1497.9657143 kbit/s. I wish to set the rate to 1Mbit/s. When I try to set it to a value between the two 'ranges', Processer Expert produces the error "Timing setting failed - it is impossible to set the following items: initialization value".
Any ideas?
Hi
I don't know about PE but you can set up the optimal CAN clock in code by using the following formula:
ptrCAN_control->CAN_CTRL1 = fnOptimalCAN_clock(pars->usMode, pars->ulSpeed);
Taken from uTasker Kinetis project:
// The best choice of clock input is from the external crystal (lowest jitter), however this may not always enable the best settings to achieve the required speed.// The choice of clock source is user-defined but this routine tries to achieve best settings using highest time quanta resolution. //// There are up to 25 time quanta in a CAN bit time and the bit frequency is equal to the clock frequency divided by the quanta number (8..25 time quanta range)// There is always a single time quanta at the start of a bit period called the SYNC_SEG which can not be changed (transitions are expected to occur on the bus during this period)// The sampling occurs after time segment 1, which is made up of a propagation segment (1..8 time quanta) plus a phase buffer segment 1 (1..8 time quanta),// followed by time segment 2, made up of phase buffer segment 2 (2..8 time quanta)//// CAN standard compliant bit segment settings give the following ranges (re-synchronisation jump width of 2 is used since it is complient with all))// Time segment 1 should be 5..10 when time segment 2 is 2 (min/max time quanta per bit is 8/13)// Time segment 1 should be 4..11 when time segment 2 is 3 (min/max time quanta per bit is 8/15)// Time segment 1 should be 5..12 when time segment 2 is 4 (min/max time quanta per bit is 10/17)// Time segment 1 should be 6..13 when time segment 2 is 5 (min/max time quanta per bit is 12/19)// Time segment 1 should be 7..14 when time segment 2 is 6 (min/max time quanta per bit is 14/21)// Time segment 1 should be 8..15 when time segment 2 is 7 (min/max time quanta per bit is 16/23)// Time segment 1 should be 9..16 when time segment 2 is 8 (min/max time quanta per bit is 18/25)//static unsigned long fnOptimalCAN_clock(unsigned short usMode, unsigned long ulSpeed){ unsigned long ulClockSourceFlag = EXTAL_CLK_SOURCE; unsigned long ulClockSpeed; unsigned long ulLowestError = 0xffffffff; unsigned long ulCanSpeed; unsigned long ulError; unsigned long ulPrescaler; int iTimeQuanta = 25; // highest value for highest control resolution int iBestTimeQuanta = 25; unsigned long ulBestPrescaler; if (CAN_USER_SETTINGS & usMode) { return ulSpeed; // the user is passing optimal configuration settings directly } if (CAN_PLL_CLOCK & usMode) { ulClockSpeed = (BUS_CLOCK); ulClockSourceFlag = CLK_SRC_PERIPH_CLK; } else { ulClockSpeed = _EXTERNAL_CLOCK; } while (iTimeQuanta >= 8) { // test for best time quanta ulCanSpeed = (ulClockSpeed/iTimeQuanta); // speed without prescaler ulPrescaler = ((ulCanSpeed + (ulSpeed/2))/ulSpeed); // best prescale value if (ulPrescaler > 256) { ulPrescaler = 256; // maximum possible prescale divider } ulCanSpeed /= ulPrescaler; if (ulCanSpeed >= ulSpeed) { // determine the absolute error value with this quanta setting ulError = (ulCanSpeed - ulSpeed); } else { ulError = (ulSpeed - ulCanSpeed); } if (ulError < ulLowestError) { // if this is an improvement ulLowestError = ulError; iBestTimeQuanta = iTimeQuanta; // best time quanta value ulBestPrescaler = ulPrescaler; } iTimeQuanta--; } ulBestPrescaler--; ulBestPrescaler <<= 24; // move the prescale value into position if (iBestTimeQuanta >= 18) { // determine the phase buffer length value ulBestPrescaler |= PHASE_BUF_SEG2_LEN8; iBestTimeQuanta -= (8 + 1); // remaining time quanta (time segment 1) after removal of the time segment 2 and the SYN_SEG } else if (iBestTimeQuanta >= 16) { ulBestPrescaler |= PHASE_BUF_SEG2_LEN7; iBestTimeQuanta -= (7 + 1); } else if (iBestTimeQuanta >= 14) { ulBestPrescaler |= PHASE_BUF_SEG2_LEN6; iBestTimeQuanta -= (6 + 1); } else if (iBestTimeQuanta >= 12) { ulBestPrescaler |= PHASE_BUF_SEG2_LEN5; iBestTimeQuanta -= (5 + 1); } else if (iBestTimeQuanta >= 10) { ulBestPrescaler |= PHASE_BUF_SEG2_LEN4; iBestTimeQuanta -= (4 + 1); } else { ulBestPrescaler |= PHASE_BUF_SEG2_LEN3; iBestTimeQuanta -= (3 + 1); } if (iBestTimeQuanta & 0x1) { // odd iBestTimeQuanta /= 2; // PROP_SEG and PSEG1 to achieve time segment 1 ulBestPrescaler |= iBestTimeQuanta; // set propogation bit time (1 more than phase buffer segment 1) iBestTimeQuanta--; ulBestPrescaler |= (iBestTimeQuanta << 19); // set phase buffer segment 1 } else { // even iBestTimeQuanta /= 2; // PROP_SEG and PSEG1 to achieve time segment 1 and phase buffer segment 1 iBestTimeQuanta--; ulBestPrescaler |= ((iBestTimeQuanta << 19) | (iBestTimeQuanta));// set equal propogation bit times } return (RJW_2 | ulClockSourceFlag | ulBestPrescaler); // initialise the CAN controller with the required speed and parameters}
Regards
Mark