AnsweredAssumed Answered

FlexCAN interface not working on i.MX 6SoloX M4 and A9

Question asked by Jason Queen on Jun 21, 2017

Hi all,

 

I have created a FreeRTOS  application on the M4 of the SoloX which uses the FlexCAN driver library. While I was developing the application I used UBoot to boot the M4 without booting the A9. The FlexCAN library worked perfectly and I was able to perform many tests on a CAN network. Below is how I initialize the FlexCAN related hardware and driver (hardware_init is called before flexcan_init): 

void hardware_init(void)
{
    /* Board specific RDC settings */
    BOARD_RdcInit();

    /* Board specific clock settings */
    BOARD_ClockInit();

    /* initialize debug uart */
    dbg_uart_init();

    /* In this example, we need to grasp board flexcan exclusively */
    RDC_SetPdapAccess(RDC, BOARD_FLEXCAN_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false);

    /* Select board flexcan derived from OSC clock(24M) */
    CCM_SetRootMux(CCM, BOARD_FLEXCAN_CCM_ROOT, ccmRootmuxPerclkClkOsc24m);

    /* Set relevant divider = 1. */
    CCM_SetRootDivider(CCM, BOARD_FLEXCAN_CCM_DIV, 0);

    /* Enable flexcan clock */
    CCM_ControlGate(CCM, BOARD_FLEXCAN_CCM_CCGR, ccmClockNeededAll);
    CCM_ControlGate(CCM, BOARD_FLEXCAN_CCM_CCGR_SERIAL, ccmClockNeededAll);

    /* FLEXCAN Pin setting */
    configure_flexcan_pins(BOARD_FLEXCAN_BASEADDR);
}

 

void flexcan_init(void)
{
   
    /* Define the CANbus config */
    flexcan_init_config_t initConfig = {
        .timing = timing_table[2],
        .operatingMode = flexCanNormalMode,
        //.operatingMode = flexcanLoopBackMode,
        .maxMsgBufNum  = 16
    };
   

    /* Initialize FlexCAN module. */
    FLEXCAN_Init(BOARD_FLEXCAN_BASEADDR, &initConfig);
   
    /* Enable FlexCAN Clock. */
    FLEXCAN_Enable(BOARD_FLEXCAN_BASEADDR);
   
    /* Set FlexCAN to use Global mask mode. */
    FLEXCAN_SetRxMaskMode(BOARD_FLEXCAN_BASEADDR, /*flexcanRxMaskIndividual*/flexcanRxMaskGlobal);
   
    /* Set FlexCAN global mask. */
    FLEXCAN_SetRxGlobalMask(BOARD_FLEXCAN_BASEADDR, ~CAN_ID_STD(FLEXCAN_GLOBAL_MASK));

    /* Clear Rx message buffer interrupt pending bit. */
    FLEXCAN_ClearMsgBufStatusFlag(BOARD_FLEXCAN_BASEADDR, FLEXCAN_RX_MSG_BUF_NUM);
    /* Enable Rx message buffer interrupt. */
    FLEXCAN_SetMsgBufIntCmd(BOARD_FLEXCAN_BASEADDR, FLEXCAN_RX_MSG_BUF_NUM, true);
   
    /* Clear Tx message buffer interrupt pending bit. */
    FLEXCAN_ClearMsgBufStatusFlag(BOARD_FLEXCAN_BASEADDR, FLEXCAN_TX_MSG_BUF_NUM);
    /* Enable Tx message buffer interrupt. */
    FLEXCAN_SetMsgBufIntCmd(BOARD_FLEXCAN_BASEADDR, FLEXCAN_TX_MSG_BUF_NUM, true);

    /* Initialize Global variable. */
    txMsgBufPtr = FLEXCAN_GetMsgBufPtr(BOARD_FLEXCAN_BASEADDR, FLEXCAN_TX_MSG_BUF_NUM);
    rxMsgBufPtr = FLEXCAN_GetMsgBufPtr(BOARD_FLEXCAN_BASEADDR, FLEXCAN_RX_MSG_BUF_NUM);
   
    /* Setup Rx MsgBuf to receive Frame. */
    rxMsgBufPtr->idStd = FLEXCAN_RX_IDENTIFIER;
    rxMsgBufPtr->code  = flexcanRxEmpty;

    /* Set FlexCAN interrupt priority. */
    NVIC_SetPriority(BOARD_FLEXCAN_IRQ_NUM, 3);
    /* Enable FlexCAN interrupt. */
    NVIC_EnableIRQ(BOARD_FLEXCAN_IRQ_NUM);
}

 

I then wanted to get the A9 to boot the M4 automatically when the power switch was turned on. I followed the instructions in the article linked in the answer to this question (Boot M4 automatically on i.MX6 SoloX SABRE-SDB ). I instructions said to run the following commands in UBoot:

env default -a
setenv fdt_file imx6sx-sdb-m4.dtb
setenv m4image 'my_freertos_application.bin'
setenv run_m4_tcm 'if run loadm4image; then cp.b ${loadaddr} 0x7f8000 0x8000; bootaux 0x7f8000; fi'
setenv bootcmd "run run_m4_tcm;${bootcmd}"
setenv mmcargs "${mmcargs} uart_from_osc"
saveenv
boot

 

This worked and the A9 now boots the M4 on startup. However, the FlexCAN interrupt service routine in the FreeRTOS application is never fired and I am also unable to bring up any CAN interfaces on the A9. When only the A9 is booted then there are 2 CAN interfaces (can0 and can1) which are visible when using if config. This is what I now get:

root@imx6sxsabresd:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:04:9f:04:0d:be
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth1      Link encap:Ethernet  HWaddr 00:04:9f:04:0d:bf
          UP BROADCAST MULTICAST DYNAMIC  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:140 (140.0 B)  TX bytes:140 (140.0 B)

root@imx6sxsabresd:~# sudo ip link set can0 type can bitrate 125000
Cannot find device "can0"

 

Ideally, I would like both the A9 and the M4 to be able to access at least one CAN port each. Is this possible? if so, what do I need to change?

 

PS: I have attached a copy of the boot logs. There may be some information of interest in them

 

Any help will be greatly appreciated :-)

 

Thanks,

Jason.

Original Attachment has been moved to: BootOutput.txt.zip

Outcomes