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);
}