diff --git a/Doc/doxygen/DoxyfileBootCommander b/Doc/doxygen/DoxyfileBootCommander index d24b9e36..bc582527 100644 --- a/Doc/doxygen/DoxyfileBootCommander +++ b/Doc/doxygen/DoxyfileBootCommander @@ -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 diff --git a/Doc/doxygen/DoxyfileLibOpenBLT b/Doc/doxygen/DoxyfileLibOpenBLT index 112d1daa..09dfc6ea 100644 --- a/Doc/doxygen/DoxyfileLibOpenBLT +++ b/Doc/doxygen/DoxyfileLibOpenBLT @@ -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 diff --git a/Host/BootCommander.exe b/Host/BootCommander.exe index a4ba9e0d..61df9303 100644 Binary files a/Host/BootCommander.exe and b/Host/BootCommander.exe differ diff --git a/Host/Source/BootCommander/main.c b/Host/Source/BootCommander/main.c index aac4e6c7..c65157dd 100644 --- a/Host/Source/BootCommander/main.c +++ b/Host/Source/BootCommander/main.c @@ -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"); diff --git a/Host/Source/LibOpenBLT/openblt.c b/Host/Source/LibOpenBLT/openblt.c index 3eb00559..8c05737c 100644 --- a/Host/Source/LibOpenBLT/openblt.c +++ b/Host/Source/LibOpenBLT/openblt.c @@ -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" /**************************************************************************************** diff --git a/Host/Source/LibOpenBLT/port/windows/canif/kvaser/leaflight.c b/Host/Source/LibOpenBLT/port/windows/canif/kvaser/leaflight.c index 999b4616..62d82ed5 100644 --- a/Host/Source/LibOpenBLT/port/windows/canif/kvaser/leaflight.c +++ b/Host/Source/LibOpenBLT/port/windows/canif/kvaser/leaflight.c @@ -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); diff --git a/Host/Source/LibOpenBLT/port/windows/canif/lawicel/canusb.c b/Host/Source/LibOpenBLT/port/windows/canif/lawicel/canusb.c index ecd04901..bc0c5a19 100644 --- a/Host/Source/LibOpenBLT/port/windows/canif/lawicel/canusb.c +++ b/Host/Source/LibOpenBLT/port/windows/canif/lawicel/canusb.c @@ -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 ***********************************/ diff --git a/Host/Source/LibOpenBLT/port/windows/canif/peak/pcanusb.c b/Host/Source/LibOpenBLT/port/windows/canif/peak/pcanusb.c index afb84d28..19d45760 100644 --- a/Host/Source/LibOpenBLT/port/windows/canif/peak/pcanusb.c +++ b/Host/Source/LibOpenBLT/port/windows/canif/peak/pcanusb.c @@ -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); diff --git a/Host/libopenblt.dll b/Host/libopenblt.dll index e38715d9..8d0796f0 100644 Binary files a/Host/libopenblt.dll and b/Host/libopenblt.dll differ