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.

CAN0 to CAN1 loop with LM4F232 eva board



I now have spend nearly two weeks investigating the 4F232 stellaris device and it's pitfalls, but even with tools like Code Composer Studio like I use it's hard to emit one single trap ... I sometimes feel with this hardware like beeing the early bird which will be caught by bugs (unlike it should catch bugs/worms).

As many other forum members before I also have huge trouble to get the CAN functionality at stellaris M4 devices working.
I now have wasted 3 days with without having some kindof "break-through" ...

Like most other people I used the example "multi_tx.c" from StellarisWare\examples\peripherals\can and adopted it to my board-layout.
My intention was to use Port B4 and B5 for sending out CAN frames to external "CAN observation equipment" (software called CANoe).
For doing this I connected an external CAN transceiver board I once purchased [made by Atmel] which I used a long time without any problems together with a "mbed-device" to send and receive CAN message.
This board only needs tx, rx, gnd and vcc.
After I connected this with my eva-board nothing happened.

OK. I removed the external board - only see the scope catching traffic on the output pins would be sufficently I thougt. But there will be no traffic at the pins.

The result of this attempt is additional code in a legacy project called "TestPort_DoPWM_at_PL2" 3858.TestPort_DoPWM_at_PL2.zip

After more reading the forum I found that I maybe have trouble with multiple pin functions - especialy JTAG related - so some port could be locked and one should unlock it by hand. But this only seems to be happen with port F at M4 devices.

So I made an new project now called "CAN" 7673.CAN.ZIPwhich contains nearly nothing exept CAN. The aim of these is to play with different GPIO configurations by using of "#if defined" and observing the IO-lines by scope


Not only no traffic is coming out of the port pins also no CAN-controller related interrupt I can ever catch. I have added CAN_x_IntHandler(void) into my main module and of course populated it as extern in startup_ccs.c in common plus added the handler to the  interrupt vectors list there.
The strange behave I see there is that this interrupt never seems to be catched because my breakpoint I have set in this handler will never become hit.
I also hade a timer interrupt in the main module of the former project "TestPort_DoPWM_at_PL2" started. These interrupt I can catch using breakpoints  but no CAN related interrupt - neither in "CAN" nor in "TestPort_DoPWM_at_PL2".

Later one I read in the processor manual that CAN related interrupt is automatically cleared if one reads out the corresponding register. So I removed the register window in the debugger because if the debugger shows me all registers it will have to read them before - maybe this could be the source of this behave - but this was not the case.


So I looked further for some working examples regarding "stellaris + M4 + CAN" on the web but found nothing.
The ultimate wisdom the stellarisware manual should give I thought. So I reread it - now with focus "CAN". In the section 5 "Controller Area Network (CAN)" there are two examples. One of them for looping between CAN0 and CAN1.

I used them in an third project called "CAN_loop"8103.CAN_loop.zip.

This should be the most primitive test for CAN as with this one could have running code and observe it at same time from outside. This example also will not work wit me.
Not only that TI has omited to set up most basic things here like the bit timings of both controllers there (in common with the negligence to mention the needed tCANBitClkParm-parameters for constructing some valid bit-timing for 1MBd) and also has omited the propper configuration of the GPIO pins which have to transfere the traffic, they also never enabled the peripherals CANx there. So I have some fudamental doubts that this code was ever more the an academical effusion.

But if I do all these stuff which they have not mentioned and I assume to be needed I will get nothing out and the debugger behaves like crazy and jumps over some of the code-columns.
After the debugger reaches the first breakpoint at SysCtlClockSet, an F6 (Step Over) brings the cursor to the next breakpoint some lines below and not the the next column.

Switching off optimisation  (-02 -> DISABLE) realized some more stringent behaviour of the code - the debugger not longer jumps crazy to lines which do not come next, but IO-traffic I will have neither.

There must be some deeper problem - maybe with compiler settings, maybe with my silicon, maybe with my own level of mastery - whatever I have no glue.
Please one could examine these two projects to give me some hints.

One simple+working project for looping CAN0 to CAN1 on M4 hardware would greatful be accepted.


I will have to find out if I the problem consists of some "silly silicon" or some "foolish operator".

The compiler setings of the regarded projects are as follows:

-mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me -g --include_path="C:/Programme/Texas Instruments/ccsv5/tools/compiler/tms470_4.9.1/include" --include_path="C:/Programme/Texas Instruments/StellarisWare/boards/ek-lm4f232/timers/ccs/../../../../boards/ek-lm4f232" --include_path="C:/Programme/Texas Instruments/StellarisWare/boards/ek-lm4f232/timers/ccs/../../../.." --gcc --define=ccs --define=PART_LM4F232H5QD --define=TARGET_IS_BLIZZARD_RA1 --diag_warning=225 --gen_func_subsections=on --ual

  • I have exactly the same problem with my Stellaris Launchpad (LM4F120). Neither my selfmade code, nor the demos work for me, nothing comes out of the TX Pin.

    Did you find out whats to do to get the CAN working?

    -Thomas

  • Thomas,

    I looked at your CAN_loop project.  I don't see anywhere you enable the GPIOs and assign them to the CAN  function.  You'll need something like the following:

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    GPIOPinConfigure(GPIO_PB4_CAN0RX);

    GPIOPinConfigure(GPIO_PB5_CAN0TX);

    Regards,

    Sue

  • My code looks like this:

    #define    PART_LM4F120H5QR

    #include "inc/hw_types.h"
    #include "inc/hw_can.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/can.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"



    void main( void )
    {

        tCANMsgObject sMsgObjectTx;
        unsigned char ucBufferOut[8];                                           

        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_8MHZ);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);                                      // Enable Peripheral Clocks
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

        GPIOPinConfigure(GPIO_PE5_CAN0TX);                                                        // Enable port PE5 for CAN0 CAN0TX
        GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_5);

        GPIOPinConfigure(GPIO_PE4_CAN0RX);                                                        // Enable port PE4 for CAN0 CAN0RX
        GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4);

        CANInit( CAN0_BASE );
        CANBitRateSet( CAN0_BASE, SysCtlClockGet(), 250000 );

        CANEnable( CAN0_BASE );

        sMsgObjectTx.ulMsgID = 0x400;
        sMsgObjectTx.ulFlags = 0;
        sMsgObjectTx.ulMsgLen = 8;
        sMsgObjectTx.pucMsgData = ucBufferOut;
        CANMessageSet(CAN0_BASE, 2, &sMsgObjectTx, MSG_OBJ_TYPE_TX);


        while(1)
        {

        }
        
    }

    As I said, I also tried the simple_tx sample, which is almost the same code as above (plus interrupts etc.) but neither of them worked :(

  • Hi Thomas,

    I can immediately see a problem - the Launchpad has a 16 MHz crystal. You should change the clock API to:

        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);


    Try that and see if your results improve.

    Regards,

    Sue

  • Oh, thanks for the hint but I already tried it that way. I just copied the wrong passage (from the simple_tx sample before changing it).

    Can someone just post the simplest code needed to get CAN working on the Stellaris Launchpad? No fancy stuff, only a hint how we have to initialize two pins and setup CAN to work (pls from top to bottom, no "example" like the one in the Driverlib documentation where all the important information is missing). This way I could exclude errors in software and start searching my hardware for errors.

  • +1. Same boat here. I have tried all of the samples, suggestions and plain trial and error without any success. All I seek to do is receive messages coming from the TX pin of a MCP2551 connected to a vehicle OBD2 port.

    I have even tried a loopback setup that performs a "CANMessageSet(CAN0_BASE, 1 ,&sCANMessage, MSG_OBJ_TYPE_TX);" when a button is pressed. This results in a complete lockup of the EK-LM4F120XL when interrupts are enabled. If they are not enabled I get nothing from the RX pin.

    Could we please have a TI engineer perform their own walkthrough and validation of the simple_rx sample to ensure that it works with these boards (EK-LM4F120XL)?

    Basic setup:

        SysCtlClockSet( SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN );
        
        // CAN Bus Setup
        SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOE );
        GPIOPinConfigure( GPIO_PE4_CAN0RX);
        GPIOPinConfigure( GPIO_PE5_CAN0TX);
        GPIOPinTypeCAN( GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5 );
        SysCtlPeripheralEnable( SYSCTL_PERIPH_CAN0 );
        
        CANInit( CAN0_BASE );
        CANBitRateSet( CAN0_BASE, SysCtlClockGet(), 500000 );

        IntEnable(INT_CAN0);
        CANEnable(CAN0_BASE);
        
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
       
        // Initialize the message object
        sCANMessage.ulMsgID = 1;                        // CAN message ID - use 1
        sCANMessage.ulMsgIDMask = 0;                    // no mask needed for TX
        sCANMessage.ulFlags = MSG_OBJ_TX_INT_ENABLE;    // enable interrupt on TX
        sCANMessage.ulMsgLen = sizeof(ucMsgData);       // size of message is 4
        sCANMessage.pucMsgData = ucMsgData;             // ptr to message content
       
        rCANMessage.ulMsgID = 0;                        // CAN msg ID - 0 for any
        rCANMessage.ulMsgIDMask = 0;                    // mask is 0 for any ID
        rCANMessage.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
        rCANMessage.ulMsgLen = 8;                       // allow up to 8 bytes
        CANMessageSet(CAN0_BASE, 1, &rCANMessage, MSG_OBJ_TYPE_RX);
       
     

  • Bryan Schremp said:
    SysCtlClockSet( SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL

    I feel your pain - yet do not yet share it.  Your code above directs your MCU to run @ the full PLL rate (200MHz) - I'm surprised that anything works!  (you really want SYSDIV_4 - at minimum - when the PLL is engaged)   (yields 50MHz system clock)

    Further - you PinConfigure and PinType (as CAN) before you SysCtlPeripheralEnable() CAN0.  That sequencing bothers me - although I'm not 100% sure...

    Long ago there was a restriction against any, "too quick" peripheral access - just after that peripheral's being enabled.  This restriction seems either lifted - it's certainly less prominent now - but I'd both alter your sequence (as above) and add some slight delay after each/every, "SysCtl PeripheralEnable()" - just in case this is a contributor to your torment.

    It may be helpful to look carefully @ your CAN Registers - as you "single step" thru each of the CAN set-up functions.  MCU datasheet should detail these - and - by this single stepping - you eliminate my fear of "too quick" register access.  Do all registers behave as the datasheet suggests?

    Clearly - "official" test/verify and report here - with the exact code used - would be ideal.  I offer this in case such response is delayed...  Good luck...