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.

TM4C123GH6PGE: CAN protocol with CAN0 base

Part Number: TM4C123GH6PGE
Other Parts Discussed in Thread: EK-TM4C123GXL, EK-TM4C1294XL, TM4C123GH6PM

Hello Everyone

I cannot communicate through the Can0 port on my custom board that I set up with tm4c123gh6pge, but I can communicate comfortably from the CAN1 port with the exact same code.
Likewise, on texas development boards (tm4c1294encpdt), I cannot communicate via CAN0 port, but I can communicate with the same code using CAN1.
What I'm wondering is, do I need to apply a separate configuration to use CAN0 base on texas MCU's?

Thanks, regards.

  • Hi Ayhan,

    I cannot communicate through the Can0 port on my custom board that I set up with tm4c123gh6pge, but I can communicate comfortably from the CAN1 port with the exact same code.

      Can you elaborate what is wrong with CAN0 communication? What do you see on the CAN0_TX and CAN0_RX pin.

      Can your CAN0 code for the TM4C123GH6PGE work on the EK-TM4C123GXL LaunchPad?

      Can you show both our CAN0 and CAN1 code? What is the difference?

      Here is a simple CAN example running on CAN0. Can you try and does it work? Please run on both the LaunchPad and the custom board. If it works on LaunchPad but not your custom board then you might want to check your custom board connections.

    //*****************************************************************************
    //
    // simple_tx.c - Example demonstrating simple CAN message transmission.
    //
    // Copyright (c) 2010-2017 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    //   Redistribution and use in source and binary forms, with or without
    //   modification, are permitted provided that the following conditions
    //   are met:
    // 
    //   Redistributions of source code must retain the above copyright
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the
    //   documentation and/or other materials provided with the  
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // 
    // This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/can.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup can_examples_list
    //! <h1>Simple CAN TX (simple_tx)</h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit messages
    //! on the CAN bus.  The CAN peripheral is configured to transmit messages
    //! with a specific CAN ID.  A message is then transmitted once per second,
    //! using a simple delay loop for timing.  The message that is sent is a 4
    //! byte message that contains an incrementing pattern.  A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - CAN0 peripheral
    //! - GPIO Port B peripheral (for CAN0 pins)
    //! - CAN0RX - PB4
    //! - CAN0TX - PB5
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example.  These are not required for operation of CAN.
    //! - GPIO port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - INT_CAN0 - CANIntHandler
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // A counter that keeps track of the number of times the TX interrupt has
    // occurred, which should match the number of TX messages that were sent.
    //
    //*****************************************************************************
    volatile uint32_t g_ui32MsgCount = 0;
    
    //*****************************************************************************
    //
    // A flag to indicate that some transmission error occurred.
    //
    //*****************************************************************************
    volatile bool g_bErrFlag = 0;
    
    //*****************************************************************************
    //
    // This function sets up UART0 to be used for a console to display information
    // as the example is running.
    //
    //*****************************************************************************
    void
    InitConsole(void)
    {
        //
        // Enable GPIO port A which is used for UART0 pins.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Configure the pin muxing for UART0 functions on port A0 and A1.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
    
        //
        // Enable UART0 so that we can configure the clock.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Select the alternate (UART) function for these pins.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    //*****************************************************************************
    //
    // This function provides a 1 second delay using a simple polling method.
    //
    //*****************************************************************************
    void
    SimpleDelay(void)
    {
        //
        // Delay cycles for 1 second
        //
        SysCtlDelay(16000000 / 3);
    }
    
    //*****************************************************************************
    //
    // This function is the interrupt handler for the CAN peripheral.  It checks
    // for the cause of the interrupt, and maintains a count of all messages that
    // have been transmitted.
    //
    //*****************************************************************************
    void
    CANIntHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Read the CAN interrupt status to find the cause of the interrupt
        //
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
            //
            // Read the controller status.  This will return a field of status
            // error bits that can indicate various errors.  Error processing
            // is not done in this example for simplicity.  Refer to the
            // API documentation for details about the error status bits.
            // The act of reading this status will clear the interrupt.  If the
            // CAN peripheral is not connected to a CAN bus with other CAN devices
            // present, then errors will occur and will be indicated in the
            // controller status.
            //
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    
            //
            // Set a flag to indicate some errors may have occurred.
            //
            g_bErrFlag = 1;
        }
    
        //
        // Check if the cause is message object 1, which what we are using for
        // sending messages.
        //
        else if(ui32Status == 1)
        {
            //
            // Getting to this point means that the TX interrupt occurred on
            // message object 1, and the message TX is complete.  Clear the
            // message object interrupt.
            //
            CANIntClear(CAN0_BASE, 1);
    
            //
            // Increment a counter to keep track of how many messages have been
            // sent.  In a real application this could be used to set flags to
            // indicate when a message is sent.
            //
            g_ui32MsgCount++;
    
            //
            // Since the message was sent, clear any error flags.
            //
            g_bErrFlag = 0;
        }
    
        //
        // Otherwise, something unexpected caused the interrupt.  This should
        // never happen.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    }
    
    //*****************************************************************************
    //
    // Configure the CAN and enter a loop to transmit periodic CAN messages.
    //
    //*****************************************************************************
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        tCANMsgObject sCANMessage;
        uint32_t ui32MsgData;
        uint8_t *pui8MsgData;
    
        pui8MsgData = (uint8_t *)&ui32MsgData;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_OSC)
                                           25000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
        //
        // Set up the serial console to use for displaying messages.  This is
        // just for this example program and is not needed for CAN operation.
        //
        InitConsole();
    
        //
        // For this example CAN0 is used with RX and TX pins on port B4 and B5.
        // The actual port and pins used may be different on your part, consult
        // the data sheet for more information.
        // GPIO port B needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        //
        // Configure the GPIO pin muxing to select CAN0 functions for these pins.
        // This step selects which alternate function is available for these pins.
        // This is necessary if your part supports GPIO pin function muxing.
        // Consult the data sheet to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using
        //
        GPIOPinConfigure(GPIO_PB4_CAN0RX);
        GPIOPinConfigure(GPIO_PB5_CAN0TX);
    
        //
        // Enable the alternate function on the GPIO pins.  The above step selects
        // which alternate function is available.  This step actually enables the
        // alternate function instead of GPIO for these pins.
        // TODO: change this to match the port/pin you are using
        //
        GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    
        //
        // The GPIO port and pins have been set up for CAN.  The CAN peripheral
        // must be enabled.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    
        //
        // Initialize the CAN controller
        //
        CANInit(CAN0_BASE);
    
        //
        // Set up the bit rate for the CAN bus.  This function sets up the CAN
        // bus timing for a nominal configuration.  You can achieve more control
        // over the CAN bus timing by using the function CANBitTimingSet() instead
        // of this one, if needed.
        // In this example, the CAN bus is set to 500 kHz.  In the function below,
        // the call to SysCtlClockGet() or ui32SysClock is used to determine the 
        // clock rate that is used for clocking the CAN peripheral.  This can be 
        // replaced with a  fixed value if you know the value of the system clock, 
        // saving the extra function call.  For some parts, the CAN peripheral is 
        // clocked by a fixed 8 MHz regardless of the system clock in which case 
        // the call to SysCtlClockGet() or ui32SysClock should be replaced with 
        // 8000000.  Consult the data sheet for more information about CAN 
        // peripheral clocking.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        CANBitRateSet(CAN0_BASE, ui32SysClock, 500000);
    #else
        CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
    #endif
    
        //
        // Enable interrupts on the CAN peripheral.  This example uses static
        // allocation of interrupt handlers which means the name of the handler
        // is in the vector table of startup code.  If you want to use dynamic
        // allocation of the vector table, then you must also call CANIntRegister()
        // here.
        //
        // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        //
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    
        //
        // Enable the CAN interrupt on the processor (NVIC).
        //
        IntEnable(INT_CAN0);
    
        //
        // Enable the CAN for operation.
        //
        CANEnable(CAN0_BASE);
    
        //
        // Initialize the message object that will be used for sending CAN
        // messages.  The message will be 4 bytes that will contain an incrementing
        // value.  Initially it will be set to 0.
        //
        ui32MsgData = 0;
        sCANMessage.ui32MsgID = 1;
        sCANMessage.ui32MsgIDMask = 0;
        sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        sCANMessage.ui32MsgLen = sizeof(pui8MsgData);
        sCANMessage.pui8MsgData = pui8MsgData;
    
        //
        // Enter loop to send messages.  A new message will be sent once per
        // second.  The 4 bytes of message content will be treated as an uint32_t
        // and incremented by one each time.
        //
        while(1)
        {
            //
            // Print a message to the console showing the message count and the
            // contents of the message being sent.
            //
            UARTprintf("Sending msg: 0x%02X %02X %02X %02X",
                       pui8MsgData[0], pui8MsgData[1], pui8MsgData[2],
                       pui8MsgData[3]);
    
            //
            // Send the CAN message using object number 1 (not the same thing as
            // CAN ID, which is also 1 in this example).  This function will cause
            // the message to be transmitted right away.
            //
            CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);
    
            //
            // Now wait 1 second before continuing
            //
            SimpleDelay();
    
            //
            // Check the error flag to see if errors occurred
            //
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
            }
            else
            {
                //
                // If no errors then print the count of message sent
                //
                UARTprintf(" total count = %u\n", g_ui32MsgCount);
            }
    
            //
            // Increment the value in the message data.
            //
            ui32MsgData++;
        }
    
        //
        // Return no errors
        //
        return(0);
    }
    

    Likewise, on texas development boards (tm4c1294encpdt), I cannot communicate via CAN0 port, but I can communicate with the same code using CAN1.

    For TM4C129 LaunchPad development board, you need to change the JP4 and JP5 jumpers to their vertical positions bring out CAN0. Otherwise, they are for UART0. 

      

  • Hello Charles

    Using the CAN0 port on the development board, I am able to communicate from the PA0-PA1 pins (CAN0) when the jumpers were vertical. However, this time I can't use the UART. I think I thought I couldn't send a message from the CAN0 port because the UART was disabled before. In the final version of the code, I converted CAN1 ports to CAN0 (PA0-PA1) and UART0s to UART1 and now I have PB0 and PB1 as an UART pins. However, when I run the program, I can send messages from the CAN0 port, but I cannot see it on the UART. What could be the reason for this?

    On my custom board, I'm sure CAN0 is not working, but I need some time to measure the outputs on the pins because all my current MCU boards have been modified to use the CAN1 port. To try again, I will modify a card for the CAN0 port and explain the situation to you in detail.

    Thanks for your interest. Regards.

  • Hi,

    However, when I run the program, I can send messages from the CAN0 port, but I cannot see it on the UART. What could be the reason for this?

    See below explanation. When in vertical jumper position, it is the UART2, not UART1 becomes the virtual COM port. 

  • Hello Charles, 

    First of all sorry for the late answer.

    I configured the PA6 and PA7 as UART2. 

    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA6_U2RX);
        GPIOPinConfigure(GPIO_PA7_U2TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
        UARTClockSourceSet(UART2_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        UARTStdioConfig(2, 115200, 16000000);
    }

    But still I can not see anything on the virtual COM port.

  • Hi Ayhan,

      I don't really see anything wrong with your modified code. I assume you change JP4 and JP5 to the vertical position on the EK-TM4C1294XL LaunchPad, right? I assume you are talking about the EK-TM4C1294XL LaunchPad, correct? Please note that EK-TM4C1294XL LaunchPad can select either UART0 or  UART2 as COM port. This is not the case on EK-TM4C123GXL board or your own custom board. For these boards, you will need an external FTDI chip on UART2. I just wanted to make sure we are talking about the same thing/board here. 

      Can you create a small program that uses UART2 as COM port only. In this program, just do a simple UARTprintf() to print something out? Show me the entire code so I can take a look and also run it. 

  • Hello Charles,

    Yes I changed JP4 and JP5 to the vertical position and the board is TM4C1294XL LaunchPad, I am sure of that.  (image below is from google but the same as with my card)

    The code below is hello world from texas examples. When JP4 and JP5 are in horizontal position, I upload this to the board and select UART0, I can see the message from the COM port.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "drivers/pinout.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    uint32_t g_ui32SysClock;
    
    void
    ConfigureUART(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioConfig(0, 115200, g_ui32SysClock);
    }
    
    int
    main(void)
    {
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240), 120000000);
        PinoutSet(false, false);
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);
        ConfigureUART();
        UARTprintf("Hello, world!\n");
        
        while(1)
        {
            LEDWrite(CLP_D1, 1);
            SysCtlDelay(g_ui32SysClock / 10 / 3);
            LEDWrite(CLP_D1, 0);
            SysCtlDelay(g_ui32SysClock / 10 / 3);
        }
    }
    

    Then I configured the UART0 to UART2. I upload the code to the card, the led is blinking, so the code is working, but I cannot see the messages from the COM port. I tried it with JP4 and JP5 on the horizontal and vertical position. Result was not change.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "drivers/pinout.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    uint32_t g_ui32SysClock;
    
    void
    ConfigureUART(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
        GPIOPinConfigure(GPIO_PA6_U2RX);
        GPIOPinConfigure(GPIO_PA7_U2TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
        UARTStdioConfig(2, 115200, g_ui32SysClock);
    }
    
    int
    main(void)
    {
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240), 120000000);
        PinoutSet(false, false);
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);
        ConfigureUART();
        UARTprintf("Hello, world!\n");
    
        while(1)
        {
            LEDWrite(CLP_D1, 1);
            SysCtlDelay(g_ui32SysClock / 10 / 3);
            LEDWrite(CLP_D1, 0);
            SysCtlDelay(g_ui32SysClock / 10 / 3);
        }
    }
    

  • Hi,

      I think I found the problem with your code. You should use PD4 for UR2RX and PD5 for UR2TX instead. See below code. It is working for me. Please also refer to the LaunchPad schematic.

    void
    ConfigureUART(void)
    {
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
    	GPIOPinConfigure(GPIO_PD4_U2RX);
    	GPIOPinConfigure(GPIO_PD5_U2TX);
    	GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    	UARTStdioConfig(2, 115200, g_ui32SysClock);
    }
    

  • Hello Charles,

    I configured the UART2 with PD4 and PD5 and it is working now.

    Actually I chose PA6 and PA7 according to the information in the datasheet bu I have missed that.

    Thanks for the information.

    By the way, I would appreciate if you don't close the topic because I will be modifying my Custom Board soon and you can help me to use the CAN0 port there.

    Thanks again, regards.

  • Hi Ayhan,

      Sure. You just need to reply to this thread and it will automatically reopen the thread. 

      Please bear in mind that your custom board will be different than the LaunchPad board. The LP has UART0 or UART2 routed to the onboard ICDI debug probe for COM port. Your custom board will need to use some type of USB to UART bridge like FTDI chip to implement the COM port function. 

  • Hello Charles,

    Reminder: I am using TM4C123GH6PGE on my custom board.

    I modified a board for CAN0 communication (PF0 and PF3). At the same time, this card is designed to be able to communicate CAN1 (PA0 and PA1) with a different transceiver.
    Below code for the CAN1 communication and it works without any problems:

    // multi_tx.c - Peripheral example demonstrating multiple CAN message transmission.
    
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <math.h>
    
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "driverlib/can.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/uart.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/debug.h"
    #include "utils/uartstdio.c"
    #include "utils/uartstdio.h"
    
    unsigned int sysClock = 16000000;
    volatile uint32_t g_ui32IntCount = 0;
    volatile uint32_t g_ui32Msg1Count = 0;
    volatile uint32_t g_ui32Msg2Count = 0;
    volatile uint32_t g_ui32Msg3Count = 0;
    volatile uint32_t g_ui32Msg4Count = 0;
    volatile uint32_t g_ui32Msg5Count = 0;
    volatile uint32_t g_ui32Msg6Count = 0;
    volatile uint32_t g_ui32Msg7Count = 0;
    volatile uint32_t g_ui32Msg8Count = 0;
    volatile uint32_t g_ui32Msg9Count = 0;
    volatile uint32_t g_ui32Msg10Count = 0;
    volatile uint32_t g_ui32Msg11Count = 0;
    volatile uint32_t g_ui32Msg12Count = 0;
    volatile bool g_bMsgObj6Sent = 0;
    volatile bool g_bErrFlag = 0;
    
    volatile bool g_bRXFlag1 = 0;
    volatile bool g_bRXFlag2 = 0;
    volatile bool g_bRXFlag3 = 0;
    volatile bool g_bRXFlag4 = 0;
    volatile bool g_bRXFlag5 = 0;
    volatile bool g_bRXFlag6 = 0;
    volatile bool g_bRXFlag7 = 0;
    volatile bool g_bRXFlag8 = 0;
    volatile bool g_bRXFlag9 = 0;
    volatile bool g_bRXFlag10 = 0;
    volatile bool g_bRXFlag11 = 0;
    volatile bool g_bRXFlag12 = 0;
    
    tCANMsgObject g_sCANMsgObject1;
    tCANMsgObject g_sCANMsgObject2;
    tCANMsgObject g_sCANMsgObject3;
    tCANMsgObject g_sCANMsgObject4;
    tCANMsgObject g_sCANMsgObject5;
    tCANMsgObject g_sCANMsgObject6;
    
    uint8_t g_pui8Msg1[8] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj);
    
    void
    CANIntHandler(void)
    {
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
    
        uint32_t ui32Status;
        ui32Status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
    
            ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);
            g_bErrFlag = 1;
            UARTprintf("TRANSMIT STATUS: %x\n", ui32Status);
        }
    
        else if(ui32Status == 1)
        {
            CANIntClear(CAN1_BASE, 1);
            g_ui32Msg1Count++;
            g_bRXFlag1 = 1;
            g_bErrFlag = 0;
    
        }
        else if(ui32Status == 2)
        {
            CANIntClear(CAN1_BASE, 2);
            g_ui32Msg2Count++;
            g_bRXFlag2 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 3)
        {
    
            CANIntClear(CAN1_BASE, 3);
            g_ui32Msg3Count++;
            g_bRXFlag3 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 4)
            {
    
                CANIntClear(CAN1_BASE, 4);
                g_ui32Msg4Count++;
                g_bRXFlag4 = 1;
                g_bErrFlag = 0;
            }
    
        else if(ui32Status == 5)
                {
    
                    CANIntClear(CAN1_BASE, 5);
                    g_ui32Msg5Count++;
                    g_bRXFlag5 = 1;
                    g_bErrFlag = 0;
                }
    
        else if(ui32Status == 6)
                {
    
                    CANIntClear(CAN1_BASE, 6);
                    g_ui32Msg6Count++;
                    g_bRXFlag6 = 1;
                    g_bMsgObj6Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 7)
                {
    
                    CANIntClear(CAN1_BASE, 7);
                    g_ui32Msg7Count++;
                    g_bRXFlag7 = 1;
                    //g_bMsgObj7Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 8)
                {
    
                    CANIntClear(CAN1_BASE, 8);
                    g_ui32Msg8Count++;
                    g_bRXFlag8 = 1;
                    //g_bMsgObj8Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 9)
                {
    
                    CANIntClear(CAN1_BASE, 9);
                    g_ui32Msg9Count++;
                    g_bRXFlag9 = 1;
                    //g_bMsgObj9Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 10)
                {
    
                    CANIntClear(CAN1_BASE, 10);
                    g_ui32Msg10Count++;
                    g_bRXFlag10 = 1;
                    //g_bMsgObj10Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 11)
                {
    
                    CANIntClear(CAN1_BASE, 11);
                    g_ui32Msg11Count++;
                    g_bRXFlag11 = 1;
                    //g_bMsgObj11Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 12)
                {
    
                    CANIntClear(CAN1_BASE, 12);
                    g_ui32Msg12Count++;
                    g_bRXFlag12 = 1;
                    //g_bMsgObj12Sent = 1;
                    g_bErrFlag = 0;
                }
    
        else
        {
    
        }
    }
    
    
    
    
    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        UARTStdioConfig(1, 115200, 16000000);
    }
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    void
    PrintCANMessageInfoRx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        if(psCANMsg->ui32Flags & MSG_OBJ_DATA_LOST)
        {
            //UARTprintf("CAN message loss detected on message object %d\n",
              //         ui32MsgObj);
        }
    
        UARTprintf("Msg Obj=%u ID=0x%05X len=%u data=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID, psCANMsg->ui32MsgLen);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    
    
    int
    main(void)
    {
    
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
        InitConsole();
        volatile uint32_t ui32Loop;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_CAN1RX);
        GPIOPinConfigure(GPIO_PA1_CAN1TX);
        GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1);
        CANInit(CAN1_BASE);
        CANBitRateSet(CAN1_BASE, 16000000, 500000);
        CANIntRegister(CAN1_BASE, CANIntHandler); // if using dynamic vectors
        CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
        IntEnable(INT_CAN1);
        CANEnable(CAN1_BASE);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_4);
    
    //----------------to transmit-----------------------------------
        g_sCANMsgObject1.ui32MsgID = 0x1006;
        g_sCANMsgObject1.ui32MsgIDMask = 0;
        g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);
        g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;
    
    
    
    //------------------to receive-------------------------------------------
        sCANMessage.ui32MsgID = 0x1002;
        sCANMessage.ui32MsgIDMask = 0xfffff;
        sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
                                 MSG_OBJ_EXTENDED_ID);
        sCANMessage.ui32MsgLen = 8;
    
        CANMessageSet(CAN1_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);
    
        for(;;)
        {
            
            SysCtlDelay(200000);
            PrintCANMessageInfoTx(&g_sCANMsgObject1, 7);
            CANMessageSet(CAN1_BASE, 7, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
    
            
    
            if(g_bRXFlag1)
                    {
    
                        sCANMessage.pui8MsgData = pui8MsgData;
                        CANMessageGet(CAN1_BASE, 1, &sCANMessage, 0);
                        g_bRXFlag1 = 0;
                        PrintCANMessageInfoRx(&sCANMessage, 1);
                    }
           
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
    
            }
            else
            {
                //UARTprintf(" total count = %u\n",
                //           g_ui32Msg1Count);
            }
    
    
        }
    
        return(0);
    }
    

    Below image is scope of the CANH and CANL pins for CAN1:

    and this is the received message from PCAN view:

    After this I tried same procedure with the CAN0 port (PF0 and PF3):

    // multi_tx.c - Peripheral example demonstrating multiple CAN message transmission.
    
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <math.h>
    
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "driverlib/can.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/uart.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/debug.h"
    #include "utils/uartstdio.c"
    #include "utils/uartstdio.h"
    
    unsigned int sysClock = 16000000;
    volatile uint32_t g_ui32IntCount = 0;
    volatile uint32_t g_ui32Msg1Count = 0;
    volatile uint32_t g_ui32Msg2Count = 0;
    volatile uint32_t g_ui32Msg3Count = 0;
    volatile uint32_t g_ui32Msg4Count = 0;
    volatile uint32_t g_ui32Msg5Count = 0;
    volatile uint32_t g_ui32Msg6Count = 0;
    volatile uint32_t g_ui32Msg7Count = 0;
    volatile uint32_t g_ui32Msg8Count = 0;
    volatile uint32_t g_ui32Msg9Count = 0;
    volatile uint32_t g_ui32Msg10Count = 0;
    volatile uint32_t g_ui32Msg11Count = 0;
    volatile uint32_t g_ui32Msg12Count = 0;
    volatile bool g_bMsgObj6Sent = 0;
    volatile bool g_bErrFlag = 0;
    
    volatile bool g_bRXFlag1 = 0;
    volatile bool g_bRXFlag2 = 0;
    volatile bool g_bRXFlag3 = 0;
    volatile bool g_bRXFlag4 = 0;
    volatile bool g_bRXFlag5 = 0;
    volatile bool g_bRXFlag6 = 0;
    volatile bool g_bRXFlag7 = 0;
    volatile bool g_bRXFlag8 = 0;
    volatile bool g_bRXFlag9 = 0;
    volatile bool g_bRXFlag10 = 0;
    volatile bool g_bRXFlag11 = 0;
    volatile bool g_bRXFlag12 = 0;
    
    tCANMsgObject g_sCANMsgObject1;
    tCANMsgObject g_sCANMsgObject2;
    tCANMsgObject g_sCANMsgObject3;
    tCANMsgObject g_sCANMsgObject4;
    tCANMsgObject g_sCANMsgObject5;
    tCANMsgObject g_sCANMsgObject6;
    
    uint8_t g_pui8Msg1[8] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj);
    
    void
    CANIntHandler(void)
    {
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
    
        uint32_t ui32Status;
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
    
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
            g_bErrFlag = 1;
            UARTprintf("TRANSMIT STATUS: %x\n", ui32Status);
        }
    
        else if(ui32Status == 1)
        {
            CANIntClear(CAN0_BASE, 1);
            g_ui32Msg1Count++;
            g_bRXFlag1 = 1;
            g_bErrFlag = 0;
    
        }
        else if(ui32Status == 2)
        {
            CANIntClear(CAN0_BASE, 2);
            g_ui32Msg2Count++;
            g_bRXFlag2 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 3)
        {
    
            CANIntClear(CAN0_BASE, 3);
            g_ui32Msg3Count++;
            g_bRXFlag3 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 4)
            {
    
                CANIntClear(CAN0_BASE, 4);
                g_ui32Msg4Count++;
                g_bRXFlag4 = 1;
                g_bErrFlag = 0;
            }
    
        else if(ui32Status == 5)
                {
    
                    CANIntClear(CAN0_BASE, 5);
                    g_ui32Msg5Count++;
                    g_bRXFlag5 = 1;
                    g_bErrFlag = 0;
                }
    
        else if(ui32Status == 6)
                {
    
                    CANIntClear(CAN0_BASE, 6);
                    g_ui32Msg6Count++;
                    g_bRXFlag6 = 1;
                    g_bMsgObj6Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 7)
                {
    
                    CANIntClear(CAN0_BASE, 7);
                    g_ui32Msg7Count++;
                    g_bRXFlag7 = 1;
                    //g_bMsgObj7Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 8)
                {
    
                    CANIntClear(CAN0_BASE, 8);
                    g_ui32Msg8Count++;
                    g_bRXFlag8 = 1;
                    //g_bMsgObj8Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 9)
                {
    
                    CANIntClear(CAN0_BASE, 9);
                    g_ui32Msg9Count++;
                    g_bRXFlag9 = 1;
                    //g_bMsgObj9Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 10)
                {
    
                    CANIntClear(CAN0_BASE, 10);
                    g_ui32Msg10Count++;
                    g_bRXFlag10 = 1;
                    //g_bMsgObj10Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 11)
                {
    
                    CANIntClear(CAN0_BASE, 11);
                    g_ui32Msg11Count++;
                    g_bRXFlag11 = 1;
                    //g_bMsgObj11Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 12)
                {
    
                    CANIntClear(CAN0_BASE, 12);
                    g_ui32Msg12Count++;
                    g_bRXFlag12 = 1;
                    //g_bMsgObj12Sent = 1;
                    g_bErrFlag = 0;
                }
    
        else
        {
    
        }
    }
    
    
    
    
    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        UARTStdioConfig(1, 115200, 16000000);
    }
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    void
    PrintCANMessageInfoRx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        if(psCANMsg->ui32Flags & MSG_OBJ_DATA_LOST)
        {
            //UARTprintf("CAN message loss detected on message object %d\n",
              //         ui32MsgObj);
        }
    
        UARTprintf("Msg Obj=%u ID=0x%05X len=%u data=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID, psCANMsg->ui32MsgLen);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    
    
    int
    main(void)
    {
    
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
        InitConsole();
        volatile uint32_t ui32Loop;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinConfigure(GPIO_PF0_CAN0RX);
        GPIOPinConfigure(GPIO_PF3_CAN0TX);
        GPIOPinTypeCAN(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_3);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
        CANInit(CAN0_BASE);
        CANBitRateSet(CAN0_BASE, 16000000, 500000);
        CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
        IntEnable(INT_CAN0);
        CANEnable(CAN0_BASE);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_4);
    
    //----------------to transmit-----------------------------------
        g_sCANMsgObject1.ui32MsgID = 0x1006;
        g_sCANMsgObject1.ui32MsgIDMask = 0;
        g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);
        g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;
    
    
    //------------------to receive-------------------------------------------
        sCANMessage.ui32MsgID = 0x1002;
        sCANMessage.ui32MsgIDMask = 0xfffff;
        sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
                                 MSG_OBJ_EXTENDED_ID);
        sCANMessage.ui32MsgLen = 8;
    
        CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);
    
        for(;;)
        {
            //uint32_t ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
            //UARTprintf("TRANSMIT STATUS: %x\n", ui32Status);
            SysCtlDelay(200000);
            //UARTprintf(" error - cable connected?\n");
            PrintCANMessageInfoTx(&g_sCANMsgObject1, 7);
            CANMessageSet(CAN0_BASE, 7, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
    
            if(g_bRXFlag1)
                    {
    
                        sCANMessage.pui8MsgData = pui8MsgData;
                        CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);
                        g_bRXFlag1 = 0;
                        PrintCANMessageInfoRx(&sCANMessage, 1);
                    }
            
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
    
            }
            else
            {
                //UARTprintf(" total count = %u\n",
                //           g_ui32Msg1Count);
            }
    
    
        }
    
        return(0);
    }
    

    Below image is scope of the CANH and CANL pins for CAN0:

    This is the PCAN view: 

    As you see there is no problem on the CAN1 port with the same code. I am sure of that the transceiver is not broken because I tried it with so many different cards and the result was everytime same.

    Do you have any idea about why this occuring?

  • Hi,

     Sorry, I'm on vacation. I will take a look next Monday. In the meantime, I will suggest you capture all the CAN1 register settings in the register window and compare with CAN0. Do you see any differences?

  • Hello Charles,


    As you said I captured all register settings for CAN0 and CAN1. 

    Picture for CAN0 was captured when port is set to CAN0(PF0-PF3) in the code.

      


    It seems like there is a problem on the CAN0 port.


    And also I had an error while I tried to see CAN0 register settings.

  • HI,

      I do see you enable CAN0. Without enabling CAN0, you will see what you showed with bunch of error. Can you add while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)) to your code? Does it make a difference? Can you also single step into CANInit() function?

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)) // Add this line
    {
    }

  • Can you also try two experiments?

     - Run TivaWare examples simple_tx.c or simple_rx.c on your custom board. What do you see?

     - Run your own software on the LaunchPad board? What do you see?

  • Hello,

    I add to my code this line 

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)) // Add this line
    {
    }

    And now I can see the values of the CAN0 register settings. But still there is no can message transmitted or received.

    (After I commented that line, registers are still visible so I think I made a mistake while I tried to capture CAN0 register settings before.)

     - Run TivaWare examples simple_tx.c or simple_rx.c on your custom board. What do you see?

    I already made this code with combining multi_tx and multi_rx from TivaWare examples. Like I said it works without any problems on CAN1.

    // multi_tx.c - Peripheral example demonstrating multiple CAN message transmission.
    
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <math.h>
    
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "driverlib/can.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/uart.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/debug.h"
    #include "utils/uartstdio.c"
    #include "utils/uartstdio.h"
    
    unsigned int sysClock = 16000000;
    volatile uint32_t g_ui32IntCount = 0;
    volatile uint32_t g_ui32Msg1Count = 0;
    volatile uint32_t g_ui32Msg2Count = 0;
    volatile uint32_t g_ui32Msg3Count = 0;
    volatile uint32_t g_ui32Msg4Count = 0;
    volatile uint32_t g_ui32Msg5Count = 0;
    volatile uint32_t g_ui32Msg6Count = 0;
    volatile uint32_t g_ui32Msg7Count = 0;
    volatile uint32_t g_ui32Msg8Count = 0;
    volatile uint32_t g_ui32Msg9Count = 0;
    volatile uint32_t g_ui32Msg10Count = 0;
    volatile uint32_t g_ui32Msg11Count = 0;
    volatile uint32_t g_ui32Msg12Count = 0;
    volatile bool g_bMsgObj6Sent = 0;
    volatile bool g_bErrFlag = 0;
    
    volatile bool g_bRXFlag1 = 0;
    volatile bool g_bRXFlag2 = 0;
    volatile bool g_bRXFlag3 = 0;
    volatile bool g_bRXFlag4 = 0;
    volatile bool g_bRXFlag5 = 0;
    volatile bool g_bRXFlag6 = 0;
    volatile bool g_bRXFlag7 = 0;
    volatile bool g_bRXFlag8 = 0;
    volatile bool g_bRXFlag9 = 0;
    volatile bool g_bRXFlag10 = 0;
    volatile bool g_bRXFlag11 = 0;
    volatile bool g_bRXFlag12 = 0;
    
    tCANMsgObject g_sCANMsgObject1;
    tCANMsgObject g_sCANMsgObject2;
    tCANMsgObject g_sCANMsgObject3;
    tCANMsgObject g_sCANMsgObject4;
    tCANMsgObject g_sCANMsgObject5;
    tCANMsgObject g_sCANMsgObject6;
    /*
    uint8_t g_pui8Msg1[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
    uint8_t g_pui8Msg2[8] = { 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01 };
    uint8_t g_pui8Msg3[8] = { 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 };
    uint8_t g_pui8Msg4[8] = { 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45 };
    uint8_t g_pui8Msg5[8] = { 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67 };
    uint8_t g_pui8Msg6[8] = { 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89 };
    
    
    */
    uint8_t g_pui8Msg1[8] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t g_pui8Msg2[8] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77 };
    uint8_t g_pui8Msg3[8] = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
    uint8_t g_pui8Msg4[8] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33 };
    uint8_t g_pui8Msg5[8] = { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 };
    uint8_t g_pui8Msg6[8] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
    /*
    uint8_t g_pui8Msg1[8] = { 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB };
    uint8_t g_pui8Msg2[8] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
    uint8_t g_pui8Msg3[8] = { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD };
    uint8_t g_pui8Msg4[8] = { 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE };
    uint8_t g_pui8Msg5[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    */
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj);
    
    void
    CANIntHandler(void)
    {
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
    
        uint32_t ui32Status;
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
    
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
            g_bErrFlag = 1;
            UARTprintf("TRANSMIT STATUS: %x\n", ui32Status);
        }
    
        else if(ui32Status == 1)
        {
            CANIntClear(CAN0_BASE, 1);
            g_ui32Msg1Count++;
            g_bRXFlag1 = 1;
            g_bErrFlag = 0;
    
        }
        else if(ui32Status == 2)
        {
            CANIntClear(CAN0_BASE, 2);
            g_ui32Msg2Count++;
            g_bRXFlag2 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 3)
        {
    
            CANIntClear(CAN0_BASE, 3);
            g_ui32Msg3Count++;
            g_bRXFlag3 = 1;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 4)
            {
    
                CANIntClear(CAN0_BASE, 4);
                g_ui32Msg4Count++;
                g_bRXFlag4 = 1;
                g_bErrFlag = 0;
            }
    
        else if(ui32Status == 5)
                {
    
                    CANIntClear(CAN0_BASE, 5);
                    g_ui32Msg5Count++;
                    g_bRXFlag5 = 1;
                    g_bErrFlag = 0;
                }
    
        else if(ui32Status == 6)
                {
    
                    CANIntClear(CAN0_BASE, 6);
                    g_ui32Msg6Count++;
                    g_bRXFlag6 = 1;
                    g_bMsgObj6Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 7)
                {
    
                    CANIntClear(CAN0_BASE, 7);
                    g_ui32Msg7Count++;
                    g_bRXFlag7 = 1;
                    //g_bMsgObj7Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 8)
                {
    
                    CANIntClear(CAN0_BASE, 8);
                    g_ui32Msg8Count++;
                    g_bRXFlag8 = 1;
                    //g_bMsgObj8Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 9)
                {
    
                    CANIntClear(CAN0_BASE, 9);
                    g_ui32Msg9Count++;
                    g_bRXFlag9 = 1;
                    //g_bMsgObj9Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 10)
                {
    
                    CANIntClear(CAN0_BASE, 10);
                    g_ui32Msg10Count++;
                    g_bRXFlag10 = 1;
                    //g_bMsgObj10Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 11)
                {
    
                    CANIntClear(CAN0_BASE, 11);
                    g_ui32Msg11Count++;
                    g_bRXFlag11 = 1;
                    //g_bMsgObj11Sent = 1;
                    g_bErrFlag = 0;
                }
        else if(ui32Status == 12)
                {
    
                    CANIntClear(CAN0_BASE, 12);
                    g_ui32Msg12Count++;
                    g_bRXFlag12 = 1;
                    //g_bMsgObj12Sent = 1;
                    g_bErrFlag = 0;
                }
    
        else
        {
    
        }
    }
    
    
    
    
    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        UARTStdioConfig(1, 115200, 16000000);
    }
    
    void
    PrintCANMessageInfoTx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    void
    PrintCANMessageInfoRx(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
    
        if(psCANMsg->ui32Flags & MSG_OBJ_DATA_LOST)
        {
            //UARTprintf("CAN message loss detected on message object %d\n",
              //         ui32MsgObj);
        }
    
        UARTprintf("Msg Obj=%u ID=0x%05X len=%u data=0x", ui32MsgObj,
                   psCANMsg->ui32MsgID, psCANMsg->ui32MsgLen);
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
            UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    
    
    int
    main(void)
    {
    
        //sysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
        InitConsole();
        volatile uint32_t ui32Loop;
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinConfigure(GPIO_PF0_CAN0RX);
        GPIOPinConfigure(GPIO_PF3_CAN0TX);
        GPIOPinTypeCAN(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_3);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)) // Add this line
        {
        }
    
        CANInit(CAN0_BASE);
        CANBitRateSet(CAN0_BASE, 16000000, 500000);
        CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
        IntEnable(INT_CAN0);
        CANEnable(CAN0_BASE);
    
    ;
    
    //----------------to transmit-----------------------------------
        g_sCANMsgObject1.ui32MsgID = 0x1006;
        g_sCANMsgObject1.ui32MsgIDMask = 0;
        g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);
        g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;
    
    
    //------------------to receive-------------------------------------------
        sCANMessage.ui32MsgID = 0x1002;
        sCANMessage.ui32MsgIDMask = 0xfffff;
        sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
                                 MSG_OBJ_EXTENDED_ID);
        sCANMessage.ui32MsgLen = 8;
    
        CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);
    
    
    
    
        for(;;)
        {
    
            SysCtlDelay(200000);
            PrintCANMessageInfoTx(&g_sCANMsgObject1, 7);
            CANMessageSet(CAN0_BASE, 7, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
    
    
    
    
            if(g_bRXFlag1)
                    {
    
                        sCANMessage.pui8MsgData = pui8MsgData;
                        CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);
                        g_bRXFlag1 = 0;
                        PrintCANMessageInfoRx(&sCANMessage, 1);
                    }
    
    
    
    
    
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
    
            }
            else
            {
                //UARTprintf(" total count = %u\n",
                //           g_ui32Msg1Count);
            }
    
    
        }
    
        return(0);
    }
    

    And this is the single step into the CANInit() function:

     - Run your own software on the LaunchPad board? What do you see?

    The code that I mentioned above is working perfectly on the LaunchPad board.

  • I already made this code with combining multi_tx and multi_rx from TivaWare examples. Like I said it works without any problems on CAN1.

    Tell me if you run the examples on CAN0 of your custom board. I understand it works on CAN1 of your custom board. 

    The code that I mentioned above is working perfectly on the LaunchPad board.

    If you code for CAN0 run fine on LaunchPad then your code is good. If the TivaWare example doesn't run on CAN0 of your custom board then it tells me something wrong may be with your board. Do you have another board to try? Can you replicate the problem on all custom boards?

  • Hello,

    Tell me if you run the examples on CAN0 of your custom board. I understand it works on CAN1 of your custom board. 

    I tried simple_tx from tivaware examples on my custom board and it is not working with CAN0.

    If you code for CAN0 run fine on LaunchPad then your code is good. If the TivaWare example doesn't run on CAN0 of your custom board then it tells me something wrong may be with your board. Do you have another board to try? Can you replicate the problem on all custom boards?

    Yes, I even tried it on almost 4-5 different custom boards. And this is the Schematics of the can transceiver part of my custom board.

  • I tried simple_tx from tivaware examples on my custom board and it is not working with CAN0.

    Can you probe CAN0TX pin running simple_tx.c example? Do you see PF3 wiggling?

    Also you reading your schematic you are driving CAN0TX to the transceiver directly. The MCU is a 3.3V device. You should go through a level shifter before driving a 5V xceiver. 

  • Hello Charles,

    I measured the PF3 with scope while running simple_tx.c

    Before I run the code it is constant 2.7V and after I run the code it is constant 3.3V.

    No wiggle or anything. Signal does not change when it is connected or not to the receiver.

    Also you reading your schematic you are driving CAN0TX to the transceiver directly. The MCU is a 3.3V device. You should go through a level shifter before driving a 5V xceiver. 

    Yes you're right but this is a one of to two transceivers and other one is working correctly with the same connection.

    Also I checked the PCB layout if there is any misconnected path, but there is not.

  • I measured the PF3 with scope while running simple_tx.c

    Before I run the code it is constant 2.7V and after I run the code it is constant 3.3V.

    No wiggle or anything. Signal does not change when it is connected or not to the receiver.

    The simple_tx example uses PB4 and PB5 pins for CAN0RX and CAN0TX? Did you change this code for PF0 and PF3 to run on your custom board? If you didn't change to PF0 and PF3 then it will not work obviously on your custom board. Please confirm.

    Suppose you run the simple_tx example as is, do you see CAN0TX wiggling on PB5 pin?

    Can you send me your entire CAN0 CCS project that uses PF0 and PF3 pins?

  • Hello,

    Yes I configured the code according to my custom board design.

    This is the wetransfer download link of the project:

    https://we.tl/t-0U4tzCi5dJ

  • Please attached the project zip file to this thread directly. My company blocks access to any external shared sites. You just need to drag the zip file into the editing window when you write. 

  • The reason that PF0/PF3 does not work on the LaunchPad board is because PF0 and PF3 are used for switch and LED. Can you check your schematic how PF0 and PF3 are connected? I tried to run CAN0 using PB4 (CAN0RX) and PB5 (CAN0TX) and I don't see any problem. Can you try PB4 and PB5? Do you see any difference? 

     

  • Hello,

    I actually work on my custom board with this code, Which PF0 and PF3 are directly connected to the transceivers RX and TX pins.

    On the launchpad this code works without any problems.

    Also this code works with CAN1 on my custom board (PA0&PA1). But whenever I change the port to the CAN0(PF0&PF3) on my custom board it not work.

  • On the launchpad this code works without any problems

    HI,

      I will try to run on my launchpad again. However, if you have run it on your launchpad and it works then the code is fine. The problem must be something board related. Can you do what I suggested you which is to try PB4/PB5 or PE4/PE5 for CAN0? I know this will require some changes to your board. But I really don't know what else to suggest since we know the fact that:

      1. Your code works on the LaunchPad. This means the code is good. If the code doesn't work on custom board, this leads to board problem. 

      2. TivaWare simple_tx does not work on your custom board. This again leads to board issue. 

  • Hello Charles,

    Ok I'll modify the board for try your advice and I'll let you know what is the result.

  • Hello again,

    I modified the board according to the Charles adviced, I tried the communicate with PB4/PB5 and PE4/PE5 both are not worked just like PF0/PF3.
    In case if there is a problem on the board, I soldered the pins directly over the MCU to the can transceiver TX-RX pins with a cable. This did not change the result, still CAN0 is not working.

    This is strange because CAN1 is working without any issue.

    Is it necessary to make a specific setting to use CAN0 in these model MCUs?
    This issue is very important to me because in our project, double CAN ports are required, but I can only use one.

    Thanks

  • Hi,

    I modified the board according to the Charles adviced, I tried the communicate with PB4/PB5 and PE4/PE5 both are not worked just like PF0/PF3.

    You are saying the PB5 and PE5 of which are both CANTX are simply just dead with flat line. Is that correct? Can you show a logic analyzer or scope capture of the CANTX pin for PB5 and PE5? Below is what I capture. I tried both PB5(TX)/PB4(RX) as well as PE5(TX)/PE4(RX) and in both cases I can see at least the TX is toggling on my LaunchPad, not just flat line. Please note I run the simple_tx with modification to use PB5/PB4 as well PE5/PE4 to produce the below capture.

    Base on our earlier discussion, please confirm one more time if below two cases are true. 

     1. Your code works on the LaunchPad. This means your code is good. If your code doesn't work on custom board, this leads to board problem. 

      2. TivaWare simple_tx does not work on your custom board. This again leads to board issue. 

      I have both the simple_tx for PB5 and PE5. See below attachment. Why don't you try it on your launchPad first and then on your custom board. If it still works on your LaunchPad but not your custom board, then I really don't know what else to suggest. Show me either the logic analyzer or scope capture on the TX pin when running on the LaunchPad vs. your custom board. 

    //*****************************************************************************
    //
    // simple_tx.c - Example demonstrating simple CAN message transmission.
    //
    // Copyright (c) 2010-2017 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    //   Redistribution and use in source and binary forms, with or without
    //   modification, are permitted provided that the following conditions
    //   are met:
    // 
    //   Redistributions of source code must retain the above copyright
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the
    //   documentation and/or other materials provided with the  
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // 
    // This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/can.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup can_examples_list
    //! <h1>Simple CAN TX (simple_tx)</h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit messages
    //! on the CAN bus.  The CAN peripheral is configured to transmit messages
    //! with a specific CAN ID.  A message is then transmitted once per second,
    //! using a simple delay loop for timing.  The message that is sent is a 4
    //! byte message that contains an incrementing pattern.  A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - CAN0 peripheral
    //! - GPIO Port B peripheral (for CAN0 pins)
    //! - CAN0RX - PB4
    //! - CAN0TX - PB5
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example.  These are not required for operation of CAN.
    //! - GPIO port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - INT_CAN0 - CANIntHandler
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // A counter that keeps track of the number of times the TX interrupt has
    // occurred, which should match the number of TX messages that were sent.
    //
    //*****************************************************************************
    volatile uint32_t g_ui32MsgCount = 0;
    
    //*****************************************************************************
    //
    // A flag to indicate that some transmission error occurred.
    //
    //*****************************************************************************
    volatile bool g_bErrFlag = 0;
    
    //*****************************************************************************
    //
    // This function sets up UART0 to be used for a console to display information
    // as the example is running.
    //
    //*****************************************************************************
    void
    InitConsole(void)
    {
        //
        // Enable GPIO port A which is used for UART0 pins.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Configure the pin muxing for UART0 functions on port A0 and A1.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
    
        //
        // Enable UART0 so that we can configure the clock.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Select the alternate (UART) function for these pins.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    //*****************************************************************************
    //
    // This function provides a 1 second delay using a simple polling method.
    //
    //*****************************************************************************
    void
    SimpleDelay(void)
    {
        //
        // Delay cycles for 1 second
        //
        SysCtlDelay(16000000 / 3);
    }
    
    //*****************************************************************************
    //
    // This function is the interrupt handler for the CAN peripheral.  It checks
    // for the cause of the interrupt, and maintains a count of all messages that
    // have been transmitted.
    //
    //*****************************************************************************
    void
    CANIntHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Read the CAN interrupt status to find the cause of the interrupt
        //
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
            //
            // Read the controller status.  This will return a field of status
            // error bits that can indicate various errors.  Error processing
            // is not done in this example for simplicity.  Refer to the
            // API documentation for details about the error status bits.
            // The act of reading this status will clear the interrupt.  If the
            // CAN peripheral is not connected to a CAN bus with other CAN devices
            // present, then errors will occur and will be indicated in the
            // controller status.
            //
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    
            //
            // Set a flag to indicate some errors may have occurred.
            //
            g_bErrFlag = 1;
        }
    
        //
        // Check if the cause is message object 1, which what we are using for
        // sending messages.
        //
        else if(ui32Status == 1)
        {
            //
            // Getting to this point means that the TX interrupt occurred on
            // message object 1, and the message TX is complete.  Clear the
            // message object interrupt.
            //
            CANIntClear(CAN0_BASE, 1);
    
            //
            // Increment a counter to keep track of how many messages have been
            // sent.  In a real application this could be used to set flags to
            // indicate when a message is sent.
            //
            g_ui32MsgCount++;
    
            //
            // Since the message was sent, clear any error flags.
            //
            g_bErrFlag = 0;
        }
    
        //
        // Otherwise, something unexpected caused the interrupt.  This should
        // never happen.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    }
    
    //*****************************************************************************
    //
    // Configure the CAN and enter a loop to transmit periodic CAN messages.
    //
    //*****************************************************************************
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        tCANMsgObject sCANMessage;
        uint32_t ui32MsgData;
        uint8_t *pui8MsgData;
    
        pui8MsgData = (uint8_t *)&ui32MsgData;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_OSC)
                                           25000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
        //
        // Set up the serial console to use for displaying messages.  This is
        // just for this example program and is not needed for CAN operation.
        //
        InitConsole();
    
        //
        // For this example CAN0 is used with RX and TX pins on port B4 and B5.
        // The actual port and pins used may be different on your part, consult
        // the data sheet for more information.
        // GPIO port B needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        //
        // Configure the GPIO pin muxing to select CAN0 functions for these pins.
        // This step selects which alternate function is available for these pins.
        // This is necessary if your part supports GPIO pin function muxing.
        // Consult the data sheet to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using
        //
        GPIOPinConfigure(GPIO_PB4_CAN0RX);
        GPIOPinConfigure(GPIO_PB5_CAN0TX);
    
        //
        // Enable the alternate function on the GPIO pins.  The above step selects
        // which alternate function is available.  This step actually enables the
        // alternate function instead of GPIO for these pins.
        // TODO: change this to match the port/pin you are using
        //
        GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_5 | GPIO_PIN_4);
    
        //
        // The GPIO port and pins have been set up for CAN.  The CAN peripheral
        // must be enabled.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    
        //
        // Initialize the CAN controller
        //
        CANInit(CAN0_BASE);
    
        //
        // Set up the bit rate for the CAN bus.  This function sets up the CAN
        // bus timing for a nominal configuration.  You can achieve more control
        // over the CAN bus timing by using the function CANBitTimingSet() instead
        // of this one, if needed.
        // In this example, the CAN bus is set to 500 kHz.  In the function below,
        // the call to SysCtlClockGet() or ui32SysClock is used to determine the 
        // clock rate that is used for clocking the CAN peripheral.  This can be 
        // replaced with a  fixed value if you know the value of the system clock, 
        // saving the extra function call.  For some parts, the CAN peripheral is 
        // clocked by a fixed 8 MHz regardless of the system clock in which case 
        // the call to SysCtlClockGet() or ui32SysClock should be replaced with 
        // 8000000.  Consult the data sheet for more information about CAN 
        // peripheral clocking.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        CANBitRateSet(CAN0_BASE, ui32SysClock, 500000);
    #else
        CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
    #endif
    
        //
        // Enable interrupts on the CAN peripheral.  This example uses static
        // allocation of interrupt handlers which means the name of the handler
        // is in the vector table of startup code.  If you want to use dynamic
        // allocation of the vector table, then you must also call CANIntRegister()
        // here.
        //
        // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        //
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    
        //
        // Enable the CAN interrupt on the processor (NVIC).
        //
        IntEnable(INT_CAN0);
    
        //
        // Enable the CAN for operation.
        //
        CANEnable(CAN0_BASE);
    
        //
        // Initialize the message object that will be used for sending CAN
        // messages.  The message will be 4 bytes that will contain an incrementing
        // value.  Initially it will be set to 0.
        //
        ui32MsgData = 0;
        sCANMessage.ui32MsgID = 1;
        sCANMessage.ui32MsgIDMask = 0;
        sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        sCANMessage.ui32MsgLen = sizeof(pui8MsgData);
        sCANMessage.pui8MsgData = pui8MsgData;
    
        //
        // Enter loop to send messages.  A new message will be sent once per
        // second.  The 4 bytes of message content will be treated as an uint32_t
        // and incremented by one each time.
        //
        while(1)
        {
            //
            // Print a message to the console showing the message count and the
            // contents of the message being sent.
            //
            UARTprintf("Sending msg: 0x%02X %02X %02X %02X",
                       pui8MsgData[0], pui8MsgData[1], pui8MsgData[2],
                       pui8MsgData[3]);
    
            //
            // Send the CAN message using object number 1 (not the same thing as
            // CAN ID, which is also 1 in this example).  This function will cause
            // the message to be transmitted right away.
            //
            CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);
    
            //
            // Now wait 1 second before continuing
            //
            SimpleDelay();
    
            //
            // Check the error flag to see if errors occurred
            //
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
            }
            else
            {
                //
                // If no errors then print the count of message sent
                //
                UARTprintf(" total count = %u\n", g_ui32MsgCount);
            }
    
            //
            // Increment the value in the message data.
            //
            ui32MsgData++;
        }
    
        //
        // Return no errors
        //
        return(0);
    }
    
    //*****************************************************************************
    //
    // simple_tx.c - Example demonstrating simple CAN message transmission.
    //
    // Copyright (c) 2010-2017 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    //   Redistribution and use in source and binary forms, with or without
    //   modification, are permitted provided that the following conditions
    //   are met:
    // 
    //   Redistributions of source code must retain the above copyright
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the
    //   documentation and/or other materials provided with the  
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // 
    // This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/can.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup can_examples_list
    //! <h1>Simple CAN TX (simple_tx)</h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit messages
    //! on the CAN bus.  The CAN peripheral is configured to transmit messages
    //! with a specific CAN ID.  A message is then transmitted once per second,
    //! using a simple delay loop for timing.  The message that is sent is a 4
    //! byte message that contains an incrementing pattern.  A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - CAN0 peripheral
    //! - GPIO Port B peripheral (for CAN0 pins)
    //! - CAN0RX - PB4
    //! - CAN0TX - PB5
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example.  These are not required for operation of CAN.
    //! - GPIO port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - INT_CAN0 - CANIntHandler
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // A counter that keeps track of the number of times the TX interrupt has
    // occurred, which should match the number of TX messages that were sent.
    //
    //*****************************************************************************
    volatile uint32_t g_ui32MsgCount = 0;
    
    //*****************************************************************************
    //
    // A flag to indicate that some transmission error occurred.
    //
    //*****************************************************************************
    volatile bool g_bErrFlag = 0;
    
    //*****************************************************************************
    //
    // This function sets up UART0 to be used for a console to display information
    // as the example is running.
    //
    //*****************************************************************************
    void
    InitConsole(void)
    {
        //
        // Enable GPIO port A which is used for UART0 pins.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Configure the pin muxing for UART0 functions on port A0 and A1.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
    
        //
        // Enable UART0 so that we can configure the clock.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Select the alternate (UART) function for these pins.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    //*****************************************************************************
    //
    // This function provides a 1 second delay using a simple polling method.
    //
    //*****************************************************************************
    void
    SimpleDelay(void)
    {
        //
        // Delay cycles for 1 second
        //
        SysCtlDelay(16000000 / 3);
    }
    
    //*****************************************************************************
    //
    // This function is the interrupt handler for the CAN peripheral.  It checks
    // for the cause of the interrupt, and maintains a count of all messages that
    // have been transmitted.
    //
    //*****************************************************************************
    void
    CANIntHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Read the CAN interrupt status to find the cause of the interrupt
        //
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
            //
            // Read the controller status.  This will return a field of status
            // error bits that can indicate various errors.  Error processing
            // is not done in this example for simplicity.  Refer to the
            // API documentation for details about the error status bits.
            // The act of reading this status will clear the interrupt.  If the
            // CAN peripheral is not connected to a CAN bus with other CAN devices
            // present, then errors will occur and will be indicated in the
            // controller status.
            //
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    
            //
            // Set a flag to indicate some errors may have occurred.
            //
            g_bErrFlag = 1;
        }
    
        //
        // Check if the cause is message object 1, which what we are using for
        // sending messages.
        //
        else if(ui32Status == 1)
        {
            //
            // Getting to this point means that the TX interrupt occurred on
            // message object 1, and the message TX is complete.  Clear the
            // message object interrupt.
            //
            CANIntClear(CAN0_BASE, 1);
    
            //
            // Increment a counter to keep track of how many messages have been
            // sent.  In a real application this could be used to set flags to
            // indicate when a message is sent.
            //
            g_ui32MsgCount++;
    
            //
            // Since the message was sent, clear any error flags.
            //
            g_bErrFlag = 0;
        }
    
        //
        // Otherwise, something unexpected caused the interrupt.  This should
        // never happen.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    }
    
    //*****************************************************************************
    //
    // Configure the CAN and enter a loop to transmit periodic CAN messages.
    //
    //*****************************************************************************
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        tCANMsgObject sCANMessage;
        uint32_t ui32MsgData;
        uint8_t *pui8MsgData;
    
        pui8MsgData = (uint8_t *)&ui32MsgData;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_OSC)
                                           25000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
        //
        // Set up the serial console to use for displaying messages.  This is
        // just for this example program and is not needed for CAN operation.
        //
        InitConsole();
    
        //
        // For this example CAN0 is used with RX and TX pins on port B4 and B5.
        // The actual port and pins used may be different on your part, consult
        // the data sheet for more information.
        // GPIO port B needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
        //
        // Configure the GPIO pin muxing to select CAN0 functions for these pins.
        // This step selects which alternate function is available for these pins.
        // This is necessary if your part supports GPIO pin function muxing.
        // Consult the data sheet to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using
        //
        GPIOPinConfigure(GPIO_PE4_CAN0RX);
        GPIOPinConfigure(GPIO_PE5_CAN0TX);
    
        //
        // Enable the alternate function on the GPIO pins.  The above step selects
        // which alternate function is available.  This step actually enables the
        // alternate function instead of GPIO for these pins.
        // TODO: change this to match the port/pin you are using
        //
        GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_5 | GPIO_PIN_4);
    
        //
        // The GPIO port and pins have been set up for CAN.  The CAN peripheral
        // must be enabled.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    
        //
        // Initialize the CAN controller
        //
        CANInit(CAN0_BASE);
    
        //
        // Set up the bit rate for the CAN bus.  This function sets up the CAN
        // bus timing for a nominal configuration.  You can achieve more control
        // over the CAN bus timing by using the function CANBitTimingSet() instead
        // of this one, if needed.
        // In this example, the CAN bus is set to 500 kHz.  In the function below,
        // the call to SysCtlClockGet() or ui32SysClock is used to determine the 
        // clock rate that is used for clocking the CAN peripheral.  This can be 
        // replaced with a  fixed value if you know the value of the system clock, 
        // saving the extra function call.  For some parts, the CAN peripheral is 
        // clocked by a fixed 8 MHz regardless of the system clock in which case 
        // the call to SysCtlClockGet() or ui32SysClock should be replaced with 
        // 8000000.  Consult the data sheet for more information about CAN 
        // peripheral clocking.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        CANBitRateSet(CAN0_BASE, ui32SysClock, 500000);
    #else
        CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
    #endif
    
        //
        // Enable interrupts on the CAN peripheral.  This example uses static
        // allocation of interrupt handlers which means the name of the handler
        // is in the vector table of startup code.  If you want to use dynamic
        // allocation of the vector table, then you must also call CANIntRegister()
        // here.
        //
        // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        //
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    
        //
        // Enable the CAN interrupt on the processor (NVIC).
        //
        IntEnable(INT_CAN0);
    
        //
        // Enable the CAN for operation.
        //
        CANEnable(CAN0_BASE);
    
        //
        // Initialize the message object that will be used for sending CAN
        // messages.  The message will be 4 bytes that will contain an incrementing
        // value.  Initially it will be set to 0.
        //
        ui32MsgData = 0;
        sCANMessage.ui32MsgID = 1;
        sCANMessage.ui32MsgIDMask = 0;
        sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        sCANMessage.ui32MsgLen = sizeof(pui8MsgData);
        sCANMessage.pui8MsgData = pui8MsgData;
    
        //
        // Enter loop to send messages.  A new message will be sent once per
        // second.  The 4 bytes of message content will be treated as an uint32_t
        // and incremented by one each time.
        //
        while(1)
        {
            //
            // Print a message to the console showing the message count and the
            // contents of the message being sent.
            //
            UARTprintf("Sending msg: 0x%02X %02X %02X %02X",
                       pui8MsgData[0], pui8MsgData[1], pui8MsgData[2],
                       pui8MsgData[3]);
    
            //
            // Send the CAN message using object number 1 (not the same thing as
            // CAN ID, which is also 1 in this example).  This function will cause
            // the message to be transmitted right away.
            //
            CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);
    
            //
            // Now wait 1 second before continuing
            //
            SimpleDelay();
    
            //
            // Check the error flag to see if errors occurred
            //
            if(g_bErrFlag)
            {
                UARTprintf(" error - cable connected?\n");
            }
            else
            {
                //
                // If no errors then print the count of message sent
                //
                UARTprintf(" total count = %u\n", g_ui32MsgCount);
            }
    
            //
            // Increment the value in the message data.
            //
            ui32MsgData++;
        }
    
        //
        // Return no errors
        //
        return(0);
    }
    

    I'm also curious on your pre-define settings. See below. What part number do you have entered in CCS? For me the LaunchPad has PART_TM4C123GH6PM. If you are using TM4C123GH6PGE then you need to reflect that in your setting. 

  • Hello Charles

    Thanks again for your support.

    I think I made a mistake in my previous attempt. In my last test, I was able to communicate with the PE4/PE5 pins via CAN0. It worked with both the simple_tx code and the code I used in my project. I did this by connecting a cable directly from the MCU's pins to the transceiver. This is the indication that my MCU's CAN0 port is working, and the settings that I made was right.

    However, for some reason, I still cannot communicate with the PF0 and PF3 pins that I am supposed to use in my project. Even if I connect directly from the MCU's pins to the transceiver with a cable, as I did to the PE4/PE5 pins, the result did not change.

    Below are the oscilloscope images of PF0 and PF3:
    By the way, according to the installed code, it should be sending periodic messages in every 100ms at the moment.
    The first and second images was taken with no PCan connected to the transceivers. (PF3 - PF0)

        


    The third, fourth and fifth images was taken when I connected PCAN to the transceiver. (PF3 - PF0 while oscilloscope auto scaled - PF0 while oscilloscope stopped)

           

    As you can see, when I connect the PCAN, I can actually see some signals on the receive side, but I think these signals are corrupted for some reason. Because the MCU cannot process the CAN message I sent.

    When I try to send a message, the status on the PCAN interface changes from OK to BUSHEAVY.

    While examining the datasheet, I saw a table like this, where I noticed that the "Pin Assignment" of PF0 and PF3 is 3, not 8, unlike other pins. I wonder if this requires me to do something different during configuration?

    By the way, here are my settings in the Predefined Symbols section of the CCS.

  • Hi Ayhan,

      Glad that you got it working on PE5/PE4.

    While examining the datasheet, I saw a table like this, where I noticed that the "Pin Assignment" of PF0 and PF3 is 3, not 8, unlike other pins. I wonder if this requires me to do something different during configuration?

    I think the reason is because PF[0] is a special pin. You must unlock this pin before you can use it for CAN. My bad, I should have communicated this to you earlier. By default, PF[0] is locked for GPIO mode only. To repurpose PF[0] for other functions, it needs to be unlocked first. Please use GPIOUnlockPin() to unlock it. 

      

  • Hello Charles,

    Finally it works when I unlocked the PF0 & PF3 pins.

    Thank you for all your support.

    Do you mind if I ask you to not lock the thread, because if I face any problem like this in the near future we'll continue to discussion on this thread.

    Thanks, regards.