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.

TM4C129ENCPDT: CAN bus parameter settings

Part Number: TM4C129ENCPDT

Hi guys,
I'm tryng to understand how to set correctly the CAN parameters.

First I initialize the GPIO:

GPIOPinConfigure(GPIO_PA0_CAN0RX);
GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PA1_CAN0TX);
GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_1);

Then, I usually use this commands to set parameters for my purpose:

SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)){}
CANInit(CAN0_BASE);
CANBitRateSet(CAN0_BASE,CLOCK,CAN_BITRATE); (where CLOCK is 40M and CAN_BITRATE is 1M)
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable(INT_CAN0);
IntPrioritySet(INT_CAN0, MEDIUM_PRIORITY); (medium priority is 2)
CANEnable(CAN0_BASE);

Using this settings, I am able to send and recive data from other devices.
Now, I need to include another device, that has some specific settings; in detail:


-Baud rate is set to 1 Mbit/sec (that is the same the I use, so no problem)

-Each message has a 4 byte payload (this part is ok too)

- Bit Time = 10, TSEG1 = 6, TSEG2 = 1, Sampling Point = 80% ( I have some problems for this part)

I read, in the Tivaware driverlib UG, that this parameters can be setted using the "CANBitTimingSet(uint32_t ui32Base, tCANBitClkParms *psClkParms)" function,

So, I setted:
tCANBitClkParms MyCANClkparam;

MyCANClkparam.ui32SyncPropPhase1Seg=6; (as requirements)
MyCANClkparam.ui32Phase2Seg=1; (as requirements)

Now, in the driverlib UG there is written: "The total bit time, in quanta, is the sum of the two Seg parameters, as follows: bit_time_q = ui32SyncPropPhase1Seg + ui32Phase2Seg + 1"

That, in my case, is (6+1)+1+1 = 9 (but, from spec, i need bit time = 10!)
Then, it also written: "The equation to determine the actual bit rate is as follows: CAN Clock / ((ui32SyncPropPhase1Seg + ui32Phase2Seg + 1) x (ui32QuantumPrescaler))"

but, in the setting config, i use the CANBitRateSet(CAN0_BASE,CLOCK,CAN_BITRATE); anyway it means that 1M= 40'000'000/ ((6+1)+1+1) x ui32QuantumPrescaler
So i think that ui32QuantumPrescaler=4, even if the final result is not 1000000, but 1111111 ( am I right? )

The last question is, what value I need to put in the ui32SJW field ?

Thanks in advance

Federico


 

  • Hi,

      I have forwarded your question to our CAN expert.

  • First, let me say that adding a new node to your network will not change the timing requirements of nodes already on the network unless the length of the network (physical cable length) is changed. Just because one node samples at 80%, does not mean that a different node sampling at 60% won't communicate reliably. Now if the length of the cable increases such that the propagation time down the cable and back requires the sample point to be moved to 80%, that is a different story. The downside of moving the sample point closer to the later edge of the bit is that it limits the SJW (synchronization jump width), the amount of time that one node can adjust to a difference in timing on another node.

    So if you look at how the CANBIT register is setup with your original code, you will see it contains the value 0x34C3. Decoding this you will see these values in the different fields:

    BRP : 3  // Means system clock divided by 4 

    SJW : 3 // Means synchronization jump width of up to 4 time quanta

    TSEG1: 4 // Means segment 1 is 5 time quanta

    TSEG2: 3 // Means segment 2 is 4 time quanta

    Notice that to efficiently store the values in the register, the value stored is one less than the value used. (0 means 1, 1 means 2 ...)

    So the CAN clock is system clock divided by 4, or in your case 10MHz. The bit timing is:

    1 TQ for synchronization, 5 TQ for segment 1 and 4 TQ for segment 2, for a total of 10 TQ. With a 10MHz CAN clock, the CAN baud rate is 10MHz/10 or 1M baud. The sample point is between the 6th and 7th TQ, or at 60% of the bit. The SJW is 4 TQ which is as big as it can be. It must be no larger than either SEG1 or SEG2.

    To change the sample point to 80%, you would need to change it to 1 TQ for synchronization, 7 for segment 1 and 2 for segment 2. (1+7+2=10). The maximum SJW would be 2. The value in CANBIT would be 0x1643.

    If you use the TivaWare function CANBitTimingsSet() to set the timings, this function adjust the parameters by minus 1 before they are written to the register. The proper initialization of the structure for a 40MHz system clock and 1M baud with sample point at 80% is:

        tCANBitClkParms MyCANClkparam;
    
        MyCANClkparam.ui32SyncPropPhase1Seg=7;
        MyCANClkparam.ui32Phase2Seg=2;
        MyCANClkparam.ui32SJW=2;
        MyCANClkparam.ui32QuantumPrescaler=4;
    

  • Hi Bob,
    thank you very much for your detailed and explanatory answer.

    I state that, using the function CANBitRateSet(CAN0_BASE,CLOCK,CAN_BITRATE); (where CLOCK is 40M and CAN_BITRATE is 1M), withou setting the parameters using the CANBitTimingSet(..) function, my device works quite correctly, without affecting the operation of the others already present (as you said).

    If i use the "CANBitTimingGet(uint32_t ui32Base, tCANBitClkParms *psClkParms)" function, after calling the CANBitRateSet, the values are:

    - MyCANClkparam.ui32SyncPropPhase1Seg=5

    -MyCANClkparam.ui32Phase2Seg=4;

    -MyCANClkparam.ui32SJW=4;

    -MyCANClkparam.ui32QuantumPrescaler=4;

    I note that bit time is (5+4+1=10)

    I don't use a long cable, about 5cm.

    Anyway, I tried with your parameters and it works equally. Honestly, I didn't know if the system worked correctly, without setting the parameters with the CANBitTimingSet function.

    Thanks again,


    Best regards

    Federico