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.

TM4C1233H6PM: Trouble instantiating CAN0

Part Number: TM4C1233H6PM
Other Parts Discussed in Thread: TM4C123GH6PM

I've been working on a new revision of a CCA we designed that has this micro onboard, supplanting a TM4C123GH6PM due to parts availability.  One of the main differences in our application is that the new micro has only one CAN bus, CAN0, whereas there are 2 CAN buses on the legacy part.  I'm currently using TivaWare v2.2.0.295 - this version supports a new API call to unlock special pins, which was needed in my application.

Regardless of how I attempt to instantiate and enable CAN0, I get nothing out of the Tx pin on the scope.  I have a CAN message being transmitted every 250 ms.  Interrupt handling was not working either, so I removed the transceiver so I could probe the pins from the micro directly.  At first I suspected that I was making some sort of mistake in unlocking the special pin for one of the ports needed for CAN0 on Port F.  However, after inspecting the SYSCTL registers for GPIO PORTF, I concluded that everything was indeed set correctly - I simply get a 3.3V constant output on the Tx pin.  

CAN0 can also be setup on Port B and Port E, so I gave that a shot.  Neither of the sets of pins on those ports are special pins, so the job is significantly more straightforward, but to no avail.  I get the same response out of the Tx pins on the corresponding ports, a constant 3.3V output.  

I have attempted to configure CAN0 using API calls as well as DRM calls, but achieve the same result.  I looked up the errata for the micro and read the DID0 register for the device and silicon revision, but do not see anything indicating that my microprocessor has any issue with CAN0 or GPIO configuration (processor is a rev A1).  I switched scopes to confirm the result and inspected the crystal oscillator configuration as well.  I'm at a bit of a loss as standing up a CAN bus on a Cortex CPU has never been this challenging.  Here's my initialization code for CAN0 on some of the alternative ports (port F and B):

Common initialization for my CCA:

	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_20MHZ);
	ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
	gSysTickPeriod = ROM_SysCtlClockGet(); // no idea what speed this will result in yet...

	// setup SysTick timer for 200 Hz interrupts
	ROM_SysTickPeriodSet(gSysTickPeriod / MAIN_LOOP_FREQ);

	// disable sleep mode on all peripherals being used
	ROM_SysCtlPeripheralClockGating(true);
	

Port F Implementation

	// Must unlock and configure PF0 since it defaults to GPIO and is a special config pin (NMI)
      ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        
      ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

      // use nominal API for non-special CAN pin
      ROM_GPIOPinConfigure(GPIO_PF3_CAN0TX);
      ROM_GPIOPinTypeCAN(GPIO_PORTF_BASE, GPIO_PIN_3);
      
      // direct register programming required for special pin
      HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; // unlock pin
      HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = GPIO_PIN_0;
      HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; // unlock pin
      HWREG(GPIO_PORTF_BASE + GPIO_O_AFSEL) |= GPIO_PIN_0;
                
#if 0
      // using the ROM functions doesn't seem to be working for this
      ROM_GPIOPinConfigure(GPIO_PF0_CAN0RX);
      ROM_GPIOPinConfigure(GPIO_PF3_CAN0TX);
      ROM_GPIOPinTypeCAN(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_3);
#else
      HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) |= GPIO_PIN_0;
      HWREG(GPIO_PORTF_BASE + GPIO_O_PCTL) |= 3U;    // bit 3 of GPIOFPCTL is CAN0Rx
    
#endif

      // lock the registers
      HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
      HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0x00;
      HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;

Note that I had some issues using the API calls for configuring port F for CAN, so resorted to DRM instead.

Port B Configuration

	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	ROM_GPIOPinConfigure(GPIO_PB4_CAN0RX);
	ROM_GPIOPinConfigure(GPIO_PB5_CAN0TX);
	ROM_GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

Subsequent CAN bus initialization

    gCANbase = CAN0_BASE; // 0x40040000

	// Reset the state of the message objects and the CAN module.
	CANInit(gCANbase);

	// Configure the controller for 1 Mbit operation.
#if 1
	uint32_t temp = CANBitRateSet(gCANbase, gSysTickPeriod, 1000000);
#else
	tCANBitClkParms CANBitClk;
	CANBitClk.ui32SyncPropPhase1Seg = 5;
	CANBitClk.ui32Phase2Seg = 2;
	CANBitClk.ui32QuantumPrescaler = 5;
	CANBitClk.ui32SJW = 2;
	CANBitTimingSet(gCANbase, &CANBitClk);
#endif

	// Enable interrupts for the CAN in the NVIC.
	IntEnable(gCANbase == CAN0_BASE ? INT_CAN0 : INT_CAN1);

	// Enable interrups from CAN controller.
	CANIntEnable(gCANbase, CAN_INT_MASTER | CAN_INT_STATUS);

	InitCANMessages();

	// enable automatic retransmission behavior
	CANRetrySet(gCANbase, TRUE);

	// Take the CAN0 device out of INIT state.
	CANEnable(gCANbase);

Note that all of this code works fine on the legacy TM4C123GH6PM part on CAN1.  

Thanks for looking.

  • Hi,

      First of all, your images are unreadable to me. You can insert the code by selecting "Insert" -> "Code" in the menu if you want to me take a look. 

      Have you tried the TivaWare CAN examples? There are multiple examples in C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\can folder. Why don't you try the simple_tx first and it should work out of box for you. 

  • Updated using the code inserts - didn't see that before, my apologies.

    Yes, I've seen the CAN examples - the issue is that CAN0 doesn't appear to work on the new chip, but works fine on the old one.  Couldn't find any errata indicating that this might be an issue on the new part.

  • Hi,

      I cannot see your interrupt ISR handler for CAN0 nor how you specify the interrupt vector in the vector table. Is it possible that you still have interrupt vector for CAN1, not CAN0? See below code where CANIntHandler is mapped to CAN0. Otherwise, I don't really spot a problem with your code. Can you please run the simple_tx on your new revision? Although the example does not use interrupt on the TX, it should at least show some pin activities on PB5 whereas you said it did not work on any pin options. I will also recommend you rerun your CAN1 code on your new revision board. Will it still work? This is to rule out any board level issues on your new board. 

        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // Quadrature Encoder 1
        CANIntHandler,                          // CAN0
        IntDefaultHandler,                      // CAN1
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3

  • Hi Charles, thanks for responding.

    Yes, the same code which has CAN1 plumbed out works on the old board which has the TM4C123GH6PM code.  I will try to run one of the example projects, like simple_tx, as you suggested.

    The NVIC configuration is below:

    //*****************************************************************************
    //
    // startup_ewarm.c - Startup code for use with IAR's Embedded Workbench,
    //                   version 5.
    //
    // Copyright (c) 2012-2017 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.4.178 of the EK-TM4C123GXL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Enable the IAR extensions for this source file.
    //
    //*****************************************************************************
    #pragma language=extended
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the interrupt handler used by the application.
    //
    //*****************************************************************************
    extern void CAN1_IntHandler(void);
    extern void CAN0_IntHandler(void);
    // extern void SysTickIntHandler(void);
    extern void	Timer1AIntHandler(void);
    extern void Timer5AIntHandler(void);
    
    //*****************************************************************************
    //
    // The entry point for the application startup code.
    //
    //*****************************************************************************
    extern void __iar_program_start(void);
    
    //*****************************************************************************
    //
    // Reserve space for the system stack.
    //
    //*****************************************************************************
    static uint32_t pui32Stack[128] @ ".noinit";
    
    //*****************************************************************************
    //
    // A union that describes the entries of the vector table.  The union is needed
    // since the first entry is the stack pointer and the remainder are function
    // pointers.
    //
    //*****************************************************************************
    typedef union
    {
        void (*pfnHandler)(void);
        uint32_t ui32Ptr;
    }
    uVectorEntry;
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000.
    //
    //*****************************************************************************
    __root const uVectorEntry __vector_table[] @ ".intvec" =
    {
        { .ui32Ptr = (uint32_t)pui32Stack + sizeof(pui32Stack) },
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
    	IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,						// UART0 Rx and Tx
    	IntDefaultHandler,						// UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
    	Timer1AIntHandler,		                // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                       // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // Quadrature Encoder 1
        CAN0_IntHandler,                        // CAN0
        CAN1_IntHandler,                        // CAN1
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        Timer5AIntHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // Wide Timer 0 subtimer A
        IntDefaultHandler,                      // Wide Timer 0 subtimer B
        IntDefaultHandler,                      // Wide Timer 1 subtimer A
        IntDefaultHandler,                      // Wide Timer 1 subtimer B
        IntDefaultHandler,                      // Wide Timer 2 subtimer A
        IntDefaultHandler,                      // Wide Timer 2 subtimer B
        IntDefaultHandler,                      // Wide Timer 3 subtimer A
        IntDefaultHandler,                      // Wide Timer 3 subtimer B
        IntDefaultHandler,                      // Wide Timer 4 subtimer A
        IntDefaultHandler,                      // Wide Timer 4 subtimer B
        IntDefaultHandler,                      // Wide Timer 5 subtimer A
        IntDefaultHandler,                      // Wide Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        IntDefaultHandler,                      // Quadrature Encoder 2
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // PWM 1 Generator 0
        IntDefaultHandler,                      // PWM 1 Generator 1
        IntDefaultHandler,                      // PWM 1 Generator 2
        IntDefaultHandler,                      // PWM 1 Generator 3
        IntDefaultHandler                       // PWM 1 Fault
    };

  • Hi,

      I have not heard back from you. I hope you have resolved the issue yourself. I will close the thread for now. If you have some update, you can just write back to this post and the thread will automatically reopen.