Refs #316. Added Lawicel CANUSB CAN interface support to LibOpenBLT and updated version numbers of LibOpenBLT and BootCommander.

git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@354 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
Frank Voorburg 2017-08-24 17:16:22 +00:00
parent f21ff722f8
commit 1c9770dd64
9 changed files with 536 additions and 99 deletions

View File

@ -38,7 +38,7 @@ PROJECT_NAME = "BootCommander - Reference Manual"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.0.0
PROJECT_NUMBER = 1.1.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@ -38,7 +38,7 @@ PROJECT_NAME = "OpenBLT Host Library - Reference Manual"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.0.0
PROJECT_NUMBER = 1.1.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

Binary file not shown.

View File

@ -397,7 +397,7 @@ int main(int argc, char const * const argv[])
static void DisplayProgramInfo(void)
{
printf("--------------------------------------------------------------------------\n");
printf("BootCommander version 1.00. Performs firmware updates on a microcontroller\n");
printf("BootCommander version 1.01. Performs firmware updates on a microcontroller\n");
printf("based system that runs the OpenBLT bootloader.\n\n");
printf("Copyright (c) 2017 by Feaser http://www.feaser.com\n");
printf("-------------------------------------------------------------------------\n");

View File

@ -46,13 +46,13 @@
* Macro definitions
****************************************************************************************/
/** \brief The version number of the library as an integer. The number has two digits
* for major-, minor-, and build-version. Version 1.05.12 would for example be
* for major-, minor-, and patch-version. Version 1.05.12 would for example be
* 10512.
*/
#define BLT_VERSION_NUMBER (10000u)
#define BLT_VERSION_NUMBER (10100u)
/** \brief The version number of the library as a null-terminated string. */
#define BLT_VERSION_STRING "1.00.00"
#define BLT_VERSION_STRING "1.01.00"
/****************************************************************************************

View File

@ -46,7 +46,7 @@
/***************************************************************************************
* Type definitions
****************************************************************************************/
/* Type definitions of the function in the Kvaser CANLIB API that this CAN interface
/* Type definitions of the functions in the Kvaser CANLIB API that this CAN interface
* uses.
*/
typedef void (__stdcall * tLeafLightLibFuncInitializeLibrary)(void);

View File

@ -41,6 +41,19 @@
#include "lawicel_can.h" /* for Lawicel CANUSB API */
/***************************************************************************************
* Type definitions
****************************************************************************************/
/* Type definitions of the functions in the Lawicel CANUSB API that this CAN interface
* uses.
*/
typedef CANHANDLE (__stdcall * tCanUsbLibFuncOpen)(LPCSTR szID, LPCSTR szBitrate, uint32_t acceptance_code, uint32_t acceptance_mask, uint32_t flags);
typedef int32_t (__stdcall * tCanUsbLibFuncClose)(CANHANDLE h);
typedef int32_t (__stdcall * tCanUsbLibFuncWrite)(CANHANDLE h, CANMsg *msg);
typedef int32_t (__stdcall * tCanUsbLibFuncStatus)(CANHANDLE h);
typedef int32_t (__stdcall * tCanUsbLibFuncSetReceiveCallBack)(CANHANDLE h, LPFNDLL_RECEIVE_CALLBACK fn);
/***************************************************************************************
* Function prototypes
****************************************************************************************/
@ -52,8 +65,19 @@ static void CanUsbDisconnect(void);
static bool CanUsbTransmit(tCanMsg const * msg);
static bool CanUsbIsBusError(void);
static void CanUsbRegisterEvents(tCanEvents const * events);
/* CAN message reception thread. */
static DWORD WINAPI CanUsbReceptionThread(LPVOID pv);
static bool CanUsbOpenChannel(void);
static bool CanUsbCloseChannel(void);
/* Lawicel CANUSB library handling. */
static void CanUsbLibLoadDll(void);
static void CanUsbLibUnloadDll(void);
static void __stdcall CanUsbLibReceiveCallback(CANMsg const * pMsg);
static CANHANDLE CanUsbLibFuncOpen(LPCSTR szID, LPCSTR szBitrate,
uint32_t acceptance_code, uint32_t acceptance_mask,
uint32_t flags);
static int32_t CanUsbLibFuncClose(CANHANDLE h);
static int32_t CanUsbLibFuncWrite(CANHANDLE h, CANMsg * msg);
static int32_t CanUsbLibFuncStatus(CANHANDLE h);
static int32_t CanUsbLibFuncSetReceiveCallBack(CANHANDLE h, LPFNDLL_RECEIVE_CALLBACK fn);
/****************************************************************************************
@ -84,11 +108,26 @@ static tCanEvents * canUsbEventsList;
/** \brief Total number of event entries into the \ref canUsbEventsList list. */
static uint32_t canUsbEventsEntries;
/** \brief Handle for the event to terminate the reception thread. */
static HANDLE canUsbTerminateEvent;
/** \brief Handle to the Lawicel CANUSB dynamic link library. */
static HINSTANCE canUsbDllHandle;
/** \brief Handle for the CAN reception thread. */
static HANDLE canUsbRxThreadHandle;
/** \brief Handle to the CAN channel. */
static CANHANDLE canUsbCanHandle;
/** \brief Function pointer to the Lawicel CANUSB canusb_Open function. */
static tCanUsbLibFuncOpen canUsbLibFuncOpenPtr;
/** \brief Function pointer to the Lawicel CANUSB canusb_Close function. */
static tCanUsbLibFuncClose canUsbLibFuncClosePtr;
/** \brief Function pointer to the Lawicel CANUSB canusb_Write function. */
static tCanUsbLibFuncWrite canUsbLibFuncWritePtr;
/** \brief Function pointer to the Lawicel CANUSB canusb_Status function. */
static tCanUsbLibFuncStatus canUsbLibFuncStatusPtr;
/** \brief Function pointer to the Lawicel CANUSB canusb_setReceiveCallBack function. */
static tCanUsbLibFuncSetReceiveCallBack canUsbLibFuncSetReceiveCallBackPtr;
/***********************************************************************************//**
@ -115,8 +154,14 @@ static void CanUsbInit(tCanSettings const * settings)
/* Initialize locals. */
canUsbEventsList = NULL;
canUsbEventsEntries = 0;
canUsbTerminateEvent = NULL;
canUsbRxThreadHandle = NULL;
canUsbDllHandle = NULL;
canUsbCanHandle = 0;
/* Reset library function pointers. */
canUsbLibFuncOpenPtr = NULL;
canUsbLibFuncClosePtr = NULL;
canUsbLibFuncWritePtr = NULL;
canUsbLibFuncStatusPtr = NULL;
canUsbLibFuncSetReceiveCallBackPtr = NULL;
/* Reset CAN interface settings. */
canUsbSettings.devicename = "";
canUsbSettings.channel = 0;
@ -146,7 +191,10 @@ static void CanUsbInit(tCanSettings const * settings)
canUsbSettings.devicename = canDeviceName;
}
}
/* ##Vg TODO Perform initialization of Lawicel CANUSB API. */
/* Perform initialization of Lawicel CANUSB API. */
CanUsbLibLoadDll();
/* Open the CAN channel. */
(void)CanUsbOpenChannel();
}
} /*** end of CanUsbInit ***/
@ -157,7 +205,10 @@ static void CanUsbInit(tCanSettings const * settings)
****************************************************************************************/
static void CanUsbTerminate(void)
{
/* ##Vg TODO Perform termination of Lawicel CANUSB API. */
/* Close the CAN channel. */
(void)CanUsbCloseChannel();
/* Perform termination of Lawicel CANUSB API. */
CanUsbLibUnloadDll();
/* Release memory that was allocated for storing the device name. */
if (canUsbSettings.devicename != NULL)
{
@ -186,56 +237,27 @@ static void CanUsbTerminate(void)
static bool CanUsbConnect(void)
{
bool result = false;
bool baudrateSupported = true;
/* Note that the device name itself is not needed anymore at this point, it was only
* needed by the CAN driver to link the correct interface (this one). The channel is
* also don't care as the adapter only has one channel. Check settings.
*/
assert(baudrateSupported);
/* Invalidate handles. */
canUsbTerminateEvent = NULL;
canUsbRxThreadHandle = NULL;
/* Only continue with valid settings. */
if (baudrateSupported)
/* Only continue with an opened CAN channel. */
if (canUsbCanHandle != 0)
{
/* Init result code to success and only negate it on detection of error. */
result = true;
/* ##Vg TODO Process and verify settings, configure acceptance filter, connect. */
result = false; /* Temporary. */
/* Create the terminate event handle used in the reception thread. */
if (result)
/* Set the reception callback function. */
if (CanUsbLibFuncSetReceiveCallBack(canUsbCanHandle,
CanUsbLibReceiveCallback) <= 0)
{
canUsbTerminateEvent = CreateEvent(NULL, TRUE, FALSE, "");
if (canUsbTerminateEvent == NULL)
{
result = false;
}
}
/* Start the reception thread as the last step. */
if (result)
{
canUsbRxThreadHandle = CreateThread(NULL, 0, CanUsbReceptionThread,
NULL, 0, NULL);
if (canUsbRxThreadHandle == NULL)
{
result = false;
}
result = false;
}
}
/* Clean-up in case an error occurred. */
if (!result)
{
if (canUsbTerminateEvent != NULL)
if (canUsbCanHandle != 0)
{
/* Close the event handle. */
(void)CloseHandle(canUsbTerminateEvent);
canUsbTerminateEvent = NULL;
/* Reset the reception callback handler and close the channel. */
(void)CanUsbLibFuncSetReceiveCallBack(canUsbCanHandle, NULL);
}
}
/* Give the result back to the caller. */
@ -249,24 +271,11 @@ static bool CanUsbConnect(void)
****************************************************************************************/
static void CanUsbDisconnect(void)
{
/* Stop the reception thread. */
if (canUsbRxThreadHandle != NULL)
/* Reset the reception callback handler and close the channel. */
if (canUsbCanHandle != 0)
{
/* Trigger event to request the reception thread to stop. */
(void)SetEvent(canUsbTerminateEvent);
/* Wait for the thread to signal termination. */
(void)WaitForSingleObject(canUsbRxThreadHandle, INFINITE);
/* Close the thread handle. */
(void)CloseHandle(canUsbRxThreadHandle);
canUsbRxThreadHandle = NULL;
(void)CanUsbLibFuncSetReceiveCallBack(canUsbCanHandle, NULL);
}
/* Close the terminate event handle. */
if (canUsbTerminateEvent != NULL)
{
(void)CloseHandle(canUsbTerminateEvent);
canUsbTerminateEvent = NULL;
}
/* ##Vg TODO Go off the bus and close the channel. */
} /*** end of CanUsbDisconnect ***/
@ -279,14 +288,47 @@ static void CanUsbDisconnect(void)
static bool CanUsbTransmit(tCanMsg const * msg)
{
bool result = false;
CANMsg txMsg;
tCanEvents const * pEvents;
/* Check parameters. */
assert(msg != NULL);
/* Only continue with valid parameters. */
if (msg != NULL) /*lint !e774 */
/* Only continue with valid parameters and handle. */
if ( (msg != NULL) && (canUsbCanHandle != 0) ) /*lint !e774 */
{
/* ##Vg TODO Transmit and trigger event(s). */
/* Convert the message to a type supported by the PCAN-Basic API. */
txMsg.id = msg->id & 0x1fffffffu;
txMsg.flags = 0;
if ((msg->id & CAN_MSG_EXT_ID_MASK) != 0)
{
txMsg.flags |= CANMSG_EXTENDED;
}
txMsg.len = msg->dlc;
for (uint8_t idx = 0; idx < msg->dlc; idx++)
{
txMsg.data[idx] = msg->data[idx];
}
/* Submit CAN message for transmission. */
if (CanUsbLibFuncWrite(canUsbCanHandle, &txMsg) > 0)
{
/* Update result value to success. */
result = true;
/* Trigger transmit complete event(s). */
pEvents = canUsbEventsList;
for (uint32_t idx = 0; idx < canUsbEventsEntries; idx++)
{
if (pEvents != NULL)
{
if (pEvents->MsgTxed != NULL)
{
pEvents->MsgTxed(msg);
}
/* Move on to the next entry in the list. */
pEvents++;
}
}
}
}
/* Give the result back to the caller. */
return result;
@ -301,9 +343,27 @@ static bool CanUsbTransmit(tCanMsg const * msg)
static bool CanUsbIsBusError(void)
{
bool result = false;
int32_t status;
/* ##Vg TODO Check and process status. */
/* Only continue with valid handle. */
if (canUsbCanHandle != 0)
{
/* Check and process status. */
status = CanUsbLibFuncStatus(canUsbCanHandle);
if ((status & CANSTATUS_BUS_ERROR) != 0)
{
result = true;
/* Due to poor time performance of the Lawicel CANUSB API when opening and closing
* the CAN channel, this is not done in CanUsbConnect/Disconnect, but in
* CanUsbInit/Terminate as a performance optimization workaround. Usually, when a
* bus error is detected here, the caller will do a Disconnect/Connect sequence to
* resolve the error, but this won't have any effect due to the before mentioned
* workaround. For this reason a CAN channel close/open was explicitely added here.
*/
(void)CanUsbCloseChannel();
(void)CanUsbOpenChannel();
}
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbIsBusError ***/
@ -350,37 +410,414 @@ static void CanUsbRegisterEvents(tCanEvents const * events)
/************************************************************************************//**
** \brief CAN message reception thread.
** \param pv Pointer to thread parameters.
** \return Thread exit code.
** \brief Opens the CAN channel. Note that the opening of the CAN channel takes a
** long time in the Lawicel CANUSB API, therefore this is not done in
** CanUsbConnect() for this CAN interface.
** \return True if successful, false otherwise.
**
****************************************************************************************/
static DWORD WINAPI CanUsbReceptionThread(LPVOID pv)
static bool CanUsbOpenChannel(void)
{
DWORD waitResult;
bool running = true;
bool result = false;
bool baudrateSupported = true;
char bitrateStr[16] = "";
/* Parameter not used. */
(void)pv;
/* Reset the channel handle. */
canUsbCanHandle = 0;
/* Enter thread's infinite loop. */
while (running)
/* Convert the baudrate to a value supported by the Lawical CANUSB API. */
switch (canUsbSettings.baudrate)
{
waitResult = WaitForSingleObject(canUsbTerminateEvent, 10);
switch (waitResult)
case CAN_BR10K:
strcat(bitrateStr, "10");
break;
case CAN_BR20K:
strcat(bitrateStr, "20");
break;
case CAN_BR50K:
strcat(bitrateStr, "50");
break;
case CAN_BR100K:
strcat(bitrateStr, "100");
break;
case CAN_BR125K:
strcat(bitrateStr, "0x03:0x1c");
break;
case CAN_BR250K:
strcat(bitrateStr, "250");
break;
case CAN_BR500K:
strcat(bitrateStr, "500");
break;
case CAN_BR800K:
strcat(bitrateStr, "800");
break;
case CAN_BR1M:
strcat(bitrateStr, "1000");
break;
default:
baudrateSupported = false;
break;
}
/* Validate baudrate. */
assert(baudrateSupported);
/* Only continue with a valid baudrate. */
if (baudrateSupported)
{
/* Configure reception acceptance filter. Default to an open filter, which will be
* used in case both 11-bit standard and 29-bit extended CAN identiers should be
* received. It is not possible to optimize the filter for this scenario, because
* the SJA1000's acceptance filter on the CANUSB is pre-configured for dual filter
* mode.
*/
uint8_t regACR0 = 0x00u;
uint8_t regAMR0 = 0xffu;
uint8_t regACR1 = 0x00u;
uint8_t regAMR1 = 0xffu;
uint8_t regACR2 = 0x00u;
uint8_t regAMR2 = 0xffu;
uint8_t regACR3 = 0x00u;
uint8_t regAMR3 = 0xffu;
/* Use bit logic to determine if the filter should accept standard 11-bit and/or
* extended 29-bit identifiers:
* acceptStdId = ((mask & code & CAN_MSG_EXT_ID_MASK) == 0)
* acceptExtId = ((mask & code & CAN_MSG_EXT_ID_MASK) != 0) ||
* ((mask & CAN_MSG_EXT_ID_MASK) == 0)
*/
bool acceptStdID = ((canUsbSettings.mask & canUsbSettings.code & CAN_MSG_EXT_ID_MASK) == 0);
bool acceptExtID = ((canUsbSettings.mask & canUsbSettings.code & CAN_MSG_EXT_ID_MASK) != 0) ||
((canUsbSettings.mask & CAN_MSG_EXT_ID_MASK) == 0);
/* Configure acceptance filter for standard 11-bit identifiers. */
if (acceptStdID)
{
/* Termination event. */
case WAIT_OBJECT_0 + 0: /*lint !e835 */
/* Stop thread. */
running = false;
break;
default:
break;
/* Set 11-bit code and mask, taking into account that the meaning of the mask bits
* on the SJA1000 is inverted: 1=don't care and 0=care.
*/
uint16_t code11bit = canUsbSettings.code & 0x7ffu;
uint16_t mask11bit = ~(canUsbSettings.mask & 0x7ffu);
/* Convert to ACRx and AMRx register values. */
regACR0 = (uint8_t)(code11bit >> 3);
regAMR0 = (uint8_t)(mask11bit >> 3);
regACR1 = ((uint8_t)(code11bit << 5)) | 0x1fu;
regAMR1 = ((uint8_t)(mask11bit << 5)) | 0x1fu;
regACR2 = (uint8_t)(code11bit >> 3);
regAMR2 = (uint8_t)(mask11bit >> 3);
regACR3 = ((uint8_t)(code11bit << 5)) | 0x1fu;
regAMR3 = ((uint8_t)(mask11bit << 5)) | 0x1fu;
}
/* Configure acceptance filter for extended 29-bit identifiers. */
else if (acceptExtID)
{
/* Set 29-bit code and mask, taking into account that the meaning of the mask bits
* on the SJA1000 is inverted: 1=don't care and 0=care. Also note that only the 16
* most significant bits of the CAN identifier can be filters due to hardware
* restrictions of the SJA1000.
*/
uint16_t code29bit = (uint16_t)((canUsbSettings.code & 0x1fffffffu) >> 13);
uint16_t mask29bit = ~((uint16_t)((canUsbSettings.mask & 0x1fffffffu) >> 13));
/* Convert to ACRx and AMRx register values. */
regACR0 = (uint8_t)(code29bit >> 8);
regAMR0 = (uint8_t)(mask29bit >> 8);
regACR1 = (uint8_t)code29bit;
regAMR1 = (uint8_t)mask29bit;
regACR2 = (uint8_t)(code29bit >> 8);
regAMR2 = (uint8_t)(mask29bit >> 8);
regACR3 = (uint8_t)code29bit;
regAMR3 = (uint8_t)mask29bit;
}
/* Convert to 32-bit code and mask values. */
uint32_t acceptCode = ((uint32_t)regACR3 << 24) & 0xff000000u;
acceptCode |= ((uint32_t)regACR2 << 16) & 0x00ff0000u;
acceptCode |= ((uint32_t)regACR1 << 8) & 0x0000ff00u;
acceptCode |= ((uint32_t)regACR0) & 0x000000ffu;
uint32_t acceptMask = ((uint32_t)regAMR3 << 24) & 0xff000000u;
acceptMask |= ((uint32_t)regAMR2 << 16) & 0x00ff0000u;
acceptMask |= ((uint32_t)regAMR1 << 8) & 0x0000ff00u;
acceptMask |= ((uint32_t)regAMR0) & 0x000000ffu;
/* Open the CAN channel, configure the reception acceptance filter and obtains the
* channel handle.
*/
canUsbCanHandle = CanUsbLibFuncOpen(NULL, bitrateStr, acceptCode, acceptMask, 0);
if (canUsbCanHandle != 0)
{
result = true;
}
}
/* Exit thread. */
return 0;
} /*** end of CanUsbReceptionThread ***/
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbOpenChannel ***/
/************************************************************************************//**
** \brief Closes the CAN channel. Note that the closing of the CAN channel takes a
** long time in the Lawicel CANUSB API, therefore this is not done in
** CanUsbDisconnect() for this CAN interface.
** \return True if successful, false otherwise.
**
****************************************************************************************/
static bool CanUsbCloseChannel(void)
{
bool result = false;
/* Close the CAN channel. */
if (canUsbCanHandle != 0)
{
if (CanUsbLibFuncClose(canUsbCanHandle) >= 0)
{
result = true;
}
canUsbCanHandle = 0;
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbCloseChannel ***/
/************************************************************************************//**
** \brief Loads the Lawicel CANUSBDRV DLL and initializes the API function pointers.
**
****************************************************************************************/
static void CanUsbLibLoadDll(void)
{
/* Reset the channel handle. */
canUsbCanHandle = 0;
/* Start out by resetting the API function pointers. */
canUsbLibFuncOpenPtr = NULL;
canUsbLibFuncClosePtr = NULL;
canUsbLibFuncWritePtr = NULL;
canUsbLibFuncStatusPtr = NULL;
canUsbLibFuncSetReceiveCallBackPtr = NULL;
/* Attempt to load the library and obtain a handle to it. */
canUsbDllHandle = LoadLibrary("canusbdrv");
/* Assert libary handle. */
assert(canUsbDllHandle != NULL);
/* Only continue if the library was successfully loaded */
if (canUsbDllHandle != NULL) /*lint !e774 */
{
/* Set canusb_Open function pointer. */
canUsbLibFuncOpenPtr = (tCanUsbLibFuncOpen)GetProcAddress(canUsbDllHandle, "canusb_Open");
/* Set canusb_Close function pointer. */
canUsbLibFuncClosePtr = (tCanUsbLibFuncClose)GetProcAddress(canUsbDllHandle, "canusb_Close");
/* Set canusb_Write function pointer. */
canUsbLibFuncWritePtr = (tCanUsbLibFuncWrite)GetProcAddress(canUsbDllHandle, "canusb_Write");
/* Set canusb_Status function pointer. */
canUsbLibFuncStatusPtr = (tCanUsbLibFuncStatus)GetProcAddress(canUsbDllHandle, "canusb_Status");
/* Set canusb_setReceiveCallBack function pointer. */
canUsbLibFuncSetReceiveCallBackPtr = (tCanUsbLibFuncSetReceiveCallBack)GetProcAddress(canUsbDllHandle, "canusb_setReceiveCallBack");
}
} /*** end of CanUsbLibLoadDll ***/
/************************************************************************************//**
** \brief Unloads the Lawicel CANUSBDRV DLL and resets the API function pointers.
**
****************************************************************************************/
static void CanUsbLibUnloadDll(void)
{
/* Reset the API function pointers. */
canUsbLibFuncOpenPtr = NULL;
canUsbLibFuncClosePtr = NULL;
canUsbLibFuncWritePtr = NULL;
canUsbLibFuncStatusPtr = NULL;
canUsbLibFuncSetReceiveCallBackPtr = NULL;
/* Reset the channel handle. */
canUsbCanHandle = 0;
/* Unload the library and invalidate its handle. */
if (canUsbDllHandle != NULL)
{
(void)FreeLibrary(canUsbDllHandle);
canUsbDllHandle = NULL;
}
} /*** end of CanUsbLibUnloadDll **/
/************************************************************************************//**
** \brief Callback function that gets called by the Lawicel CANUSB API each time a
** CAN message was received.
** \param pMsg Pointer to the received CAN message.
**
****************************************************************************************/
static void __stdcall CanUsbLibReceiveCallback(CANMsg const * pMsg)
{
tCanMsg rxMsg;
tCanEvents const * pEvents;
/* Only continue with a valid message. */
if (pMsg != NULL)
{
/* Ignore remote frames. */
if ((pMsg->flags & CANMSG_RTR) == 0)
{
rxMsg.id = pMsg->id;
if ((pMsg->flags & CANMSG_EXTENDED) != 0)
{
rxMsg.id |= CAN_MSG_EXT_ID_MASK;
}
rxMsg.dlc = pMsg->len;
for (uint8_t idx = 0; idx < rxMsg.dlc; idx++)
{
rxMsg.data[idx] = pMsg->data[idx];
}
/* Trigger message reception event(s). */
pEvents = canUsbEventsList;
for (uint32_t idx = 0; idx < canUsbEventsEntries; idx++)
{
if (pEvents != NULL)
{
if (pEvents->MsgRxed != NULL)
{
pEvents->MsgRxed(&rxMsg);
}
/* Move on to the next entry in the list. */
pEvents++;
}
}
}
}
} /*** end of CanUsbLibReceiveCallback ***/
/************************************************************************************//**
** \brief Open a channel to a physical CAN interface.
** \param szID Serial number for adapter or NULL to open the first found.
** \param szBitrate "10", "20", "50", "100", "250", "500", "800" or "1000" (kbps) or
** as a btr pair. btr0:btr1 pair ex. "0x03:0x1c" can be used to set a custom
** baudrate.
** \param acceptance_code Set to CANUSB_ACCEPTANCE_CODE_ALL to get all messages or
** another code to filter messages.
** \param acceptance_mask Set to CANUSB_ACCEPTANCE_MASK_ALL to get all messages or
** another code to filter messages.
** \param flags Optional flags CANUSB_FLAG_xxx.
** \return Handle to device if open was successful or zero on failure.
**
****************************************************************************************/
static CANHANDLE CanUsbLibFuncOpen(LPCSTR szID, LPCSTR szBitrate,
uint32_t acceptance_code, uint32_t acceptance_mask,
uint32_t flags)
{
CANHANDLE result = 0;
/* Check function pointer and library handle. */
assert(canUsbLibFuncOpenPtr != NULL);
assert(canUsbDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((canUsbLibFuncOpenPtr != NULL) && (canUsbDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = canUsbLibFuncOpenPtr(szID, szBitrate, acceptance_code, acceptance_mask,
flags);
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbLibFuncOpen ***/
/************************************************************************************//**
** \brief Close channel with handle h.
** \param h Handle to the opened device.
** \return > 0 if successful, ERROR_CANUSB_xxx (<= 0) otherwise.
**
****************************************************************************************/
static int32_t CanUsbLibFuncClose(CANHANDLE h)
{
int32_t result = ERROR_CANUSB_GENERAL;
/* Check function pointer and library handle. */
assert(canUsbLibFuncClosePtr != NULL);
assert(canUsbDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((canUsbLibFuncClosePtr != NULL) && (canUsbDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = canUsbLibFuncClosePtr(h);
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbLibFuncClose ***/
/************************************************************************************//**
** \brief Write message to channel with handle h.
** \param h Handle to the opened device.
** \param msg CAN message to send.
** \return > 0 if successful, ERROR_CANUSB_xxx (<= 0) otherwise.
**
****************************************************************************************/
static int32_t CanUsbLibFuncWrite(CANHANDLE h, CANMsg * msg)
{
int32_t result = ERROR_CANUSB_GENERAL;
/* Check function pointer and library handle. */
assert(canUsbLibFuncWritePtr != NULL);
assert(canUsbDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((canUsbLibFuncWritePtr != NULL) && (canUsbDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = canUsbLibFuncWritePtr(h, msg);
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbLibFuncWrite ***/
/************************************************************************************//**
** \brief Get Adapter status for channel with handle h.
** \param h Handle to the opened device.
** \return CANSTATUS_xxx if status info is set, 0 otherwise.
**
****************************************************************************************/
static int32_t CanUsbLibFuncStatus(CANHANDLE h)
{
int32_t result = 0;
/* Check function pointer and library handle. */
assert(canUsbLibFuncStatusPtr != NULL);
assert(canUsbDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((canUsbLibFuncStatusPtr != NULL) && (canUsbDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = canUsbLibFuncStatusPtr(h);
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbLibFuncStatus ***/
/************************************************************************************//**
** \brief With this method one can define a function that will receive all incoming
** messages.
** \param h Handle to the opened device.
** \param fn Pointer to the callback function to set. NULL removes it again.
** \return > 0 if successful, ERROR_CANUSB_xxx (<= 0) otherwise.
**
****************************************************************************************/
static int32_t CanUsbLibFuncSetReceiveCallBack(CANHANDLE h, LPFNDLL_RECEIVE_CALLBACK fn)
{
int32_t result = ERROR_CANUSB_GENERAL;
/* Check function pointer and library handle. */
assert(canUsbLibFuncSetReceiveCallBackPtr != NULL);
assert(canUsbDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((canUsbLibFuncSetReceiveCallBackPtr != NULL) && (canUsbDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = canUsbLibFuncSetReceiveCallBackPtr(h, fn);
}
/* Give the result back to the caller. */
return result;
} /*** end of CanUsbLibFuncSetReceiveCallBack ***/
/*********************************** end of canusb.c ***********************************/

View File

@ -44,7 +44,7 @@
/***************************************************************************************
* Type definitions
****************************************************************************************/
/* Type definitions of the function in the PCAN-Basic API that this CAN interface uses.*/
/* Type definitions of the functions in the PCAN-Basic API that this CAN interface uses.*/
typedef TPCANStatus (__stdcall * tPCanUsbLibFuncInitialize)(TPCANHandle, TPCANBaudrate, TPCANType, DWORD, WORD);
typedef TPCANStatus (__stdcall * tPCanUsbLibFuncUninitialize)(TPCANHandle);
typedef TPCANStatus (__stdcall * tPCanUsbLibFuncGetStatus)(TPCANHandle);

Binary file not shown.