CAN Error: Timeout occurred

We are running version 2.0 of the Toradex Libraries and am are using the can_demo.c file to listen to signals on the board.

However, we are not able to read any CAN signals. The program will time out and throw this error:

CanLib Warning: Timeout occurred

CAN Error: Timeout occurred

We get the same result running our main application.

Here is our version of can_demo.c:

///
/// @file         Can_Demo.c
/// @copyright    Copyright (c) 2014 Toradex AG
/// $Author: germano.kern $
/// $Rev: 4280 $
/// $Date: 2018-01-12 15:38:22 +0100 (Fri, 12 Jan 2018) $
/// @brief        Program to show how to use CAN library
///               A CAN transceiver is required. Colibri Evaluation Board V3.2 provides the facility to use
///               on board CAN transceiver, refer its datasheet for more details.
/// @target       Colibri VFxx Modules
/// @test         Tested on: VFxx
/// @caveats      None
///

#include <windows.h>
//Uncomment the line below if you want to use TdxAllLibrariesDll.dll
//#define USE_DLL
#include "can.h"
#include "coproc.h"
#include "gpio.h"

//*****************************************************************************
/// CAN receive process
/// @param[in]  hCan       Handle to CAN channel
DWORD CanRxProcess(HANDLE hCan)
{
    INT i;
    tCanMsg canBuf = {0};
    BYTE data[8] = {0};   // Rx buffer

    // Configure timeout to 5 sec, by default it is set to 1 sec
    Can_SetConfigInt(hCan, L"Timeout", 5000, StoreVolatile);    // optional

    // 4. Use CAN
    canBuf.dataLen = 8;
    if (Can_Read(hCan, &canBuf))
    {
        printf("\nCAN Receive: Frame ID = 0x%x, Remote/Data Frame = %s %s len %d\n", canBuf.id, (canBuf.canMsgFlags & CanMsgFlags_RTR  ? "REMOTE" :  "DATA"), (canBuf.canMsgFlags & CanMsgFlags_IDE  ? "EXTENDED" : "STANDARD" ), canBuf.dataLen);
        // display received data
        if ((canBuf.canMsgFlags & CanMsgFlags_RTR) == 0)
        {
            printf("Data:");
            for (i = 0; i < 8; i++)
            {
                printf(" %d", canBuf.data[i]);
            }
        }
    }
    else
    {
        printf("\nCAN Receive error\r\n");
    }

    return 0;
}

//*****************************************************************************
/// CAN transmit process
/// @param[in]  hCan       Handle to CAN channel
DWORD CanTxProcess(HANDLE hCan)
{
    INT i;
    tCanMsg canBuf = {0};
    BYTE data[8] = {0, 1, 2, 3, 4, 5, 6, 7};   // Tx buffer

    // 4. Use CAN
    canBuf.id    = rand() & 0x7FF;         // CAN frame ID
    canBuf.canMsgFlags = 0;
    memcpy(canBuf.data, data, sizeof(data));
    canBuf.dataLen = 8;

    if (Can_Write(hCan, &canBuf))
    {
        printf("\nCAN Transmit: Frame ID = 0x%x Remote/Data Frame = %s\nData:", canBuf.id, (canBuf.canMsgFlags & CanMsgFlags_RTR  ? "REMOTE" :  "DATA"));
        // display Transmit data
        for (i = 0; i < 8; i++)
        {
            printf(" %d", canBuf.data[i]);
        }
    }
    else
    {
        printf("CAN Transmit error\r\n");
    }

    return 0;
}


//*****************************************************************************
/// Main function
/// @param[in]  instance       Handle to program instance
/// @param[in]  prevInstance   Handle to previous program instance
/// @param[in]  cmdLine        Command line string pointer
/// @param[in]  cmdShow        Window state
/// @retval     1              Always returned
int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)
{
    HANDLE hCan = NULL;
    BOOL isSelectionDone = FALSE;
    INT selectedOption;
    BOOL returnValue = FALSE;
    DWORD busStatus;

	UNREFERENCED_PARAMETER(instance);
	UNREFERENCED_PARAMETER(prevInstance);
	UNREFERENCED_PARAMETER(cmdLine);
	UNREFERENCED_PARAMETER(cmdShow);

    printf("Toradex CAN demo\r\n");

    //// 1. Initialize CAN without affecting hardware registers
    //if (Cop_GetFormFactor() == FormFactor_Apalis)
        hCan = Can_Init(L"CAN1"); // Internal CAN
    //else
    //    hCan = Can_Init(L"SPI1"); // External MCP2515 Controller

    if (hCan == NULL)
    {
        printf("Error in CAN initialization\r\n");
        return FALSE;
    }

    // 2. Change configuration as required
    //    Please refer the documentation regarding the configurations from the .chm file present in the library package.
    //    Instead of calling this function, you can place values in the registry (not present by default). You may use
    //    StoreToRegistry instead of StoreVolatile to configure these values in registry from application for future use.
    //      [HKLM\SOFTWARE\TORADEX\CANx]
    //      Implementation = "VybridCAN"
    //      Interface      = "CAN1"
     {
        uIo ioRx =  COLIBRI_PIN(63);
        uIo ioTx =  COLIBRI_PIN(55);
        Can_SetConfigInt(hCan, L"ioRx", ioRx.GenericDefinition, StoreToRegistry);
        Can_SetConfigInt(hCan, L"ioTx", ioTx.GenericDefinition, StoreToRegistry);
    }
    //returnValue = Can_SetConfigString(hCan, L"FilterFrameFormat",    L"extended",     StoreVolatile);     // Set FilterFrameFormat
    //returnValue = Can_SetConfigString(hCan, L"FilterFrameFormat",    L"standard",     StoreVolatile);     // Set FilterFrameFormat
    //returnValue = Can_SetConfigString(hCan, L"FilterRemote",   L"remote",     StoreVolatile);     // Set FilterRemote to discard remote frames
    //returnValue = Can_SetConfigString(hCan, L"FilterRemote",   L"data",     StoreVolatile);     // Set FilterRemote to discard data frames
    //returnValue = Can_SetConfigInt(hCan, L"FilterID",   0x01,       StoreVolatile);     //
    //returnValue = Can_SetConfigInt(hCan, L"FilterMask", 0x03,       StoreVolatile);     //
    //returnValue = Can_SetConfigInt(hCan, L"SingleThread", 0,       StoreVolatile);     // activate single thread accessing MCP2515

    /*{
        DWORD bitRate;
        printf("Enter CAN bit rate in Hz:");
        scanf_s("%d", &bitRate);
        returnValue = Can_SetConfigInt(hCan, L"BitRateHz", bitRate, StoreVolatile);
    }*/

    // 3. Apply configuration to hardware
    if (!Can_Open(hCan))
    {
        printf("CAN Open failed\r\n");
        Can_Deinit(hCan);
        return 0;
    }

    returnValue = Can_GetConfigInt(hCan, L"BusStatus", &busStatus);
    printf("BusStatus %x\n",busStatus);

    do
    {
        printf("\nOptions:\n");
        printf("1. CAN Transmit   2. CAN Receive   3. Quit\n\n");
        printf("Choose the option and press Enter key: ");
        scanf_s("%d", &selectedOption);
        printf("\n");

        /// Enter only if there is only one character entered from key board.
        switch (selectedOption)
        {
            case 1:
                /// CAN Transmit
                CanTxProcess(hCan);
                break;

            case 2:
                /// CAN Receive
                CanRxProcess(hCan);
                break;

            case 3:
                /// Quits the demo
                isSelectionDone = TRUE;
                break;

            default:
                printf("Invalid entry, try again!\n\n");
                isSelectionDone = FALSE;
        }
    } while (!isSelectionDone);


    /// 5. Close CAN channel
    Can_Close(hCan);

    /// 6. Deinit CAN channel
    Can_Deinit(hCan);

    return(TRUE);
}

Sorry to reply with more questions rather than an answer, but we need to understand the issue a bit better to provide help.
Can you tell us a bit more about your HW setup, I see that you use Colibri EVB 3.2, it has jumpers to enable internal/external CAN controller, can you check that those are set as described in the datasheet?
What are you using to send CAN packets?
You may need to add termination resistors to have the bus working correctly.
What happens when you try to send data instead of receving (if you can check that the other end receives them)?

We’ve removed the internal/external CAN jumpers: JP4 and JP5. We are jumping from X38 to SODIMM 55 and 63 to route to the internal CAN signal out through the main CAN connector.

We’ve hooked up the a logic analyzer to sniff those lines and can see data when we select Transmit in the program. To send CAN packets, we hooked up a CAN analyzer to send packets at regular intervals. When we listen on the logic analyzer, we can see the CAN signals come into board from the Can analyzer, but when we select to receive in the program, we receive the timeout error in our application debugger. This is the same result as is happening in the application we are developing.

alt text

Hello @chronic788: Just to make sure, you are not facing an issue we already fixed. We had a customer that found some issues in the latest CANlib, that sound kind of similar to yours. Can you please quickly try to use the following intermediate library release? Do you still see the issues there? Here you get the libs.