openblt/Host/Source/LibOpenBLT/port/windows/usbbulk.c

375 lines
15 KiB
C

/************************************************************************************//**
* \file port/windows/usbbulk.c
* \brief USB bulk driver source file.
* \ingroup XcpTpUsb
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved
*
*----------------------------------------------------------------------------------------
* L I C E N S E
*----------------------------------------------------------------------------------------
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You have received a copy of the GNU General Public License along with OpenBLT. It
* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
*
* \endinternal
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include <assert.h> /* for assertions */
#include <stdint.h> /* for standard integer types */
#include <stddef.h> /* for NULL declaration */
#include <stdbool.h> /* for boolean type */
#include <windows.h> /* for Windows API */
#include "usbbulk.h" /* USB bulk driver */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/* USB bulk driver return values. */
#define UBL_ERROR (0u)
#define UBL_OKAY (1u)
/****************************************************************************************
* Type definitions
****************************************************************************************/
/* USB bulk driver interface functions. */
typedef uint8_t (__stdcall * tUsbBulkLibFuncOpen)(LPGUID guid);
typedef void (__stdcall * tUsbBulkLibFuncClose)(void);
typedef uint8_t (__stdcall * tUsbBulkLibFuncTransmit)(uint8_t * data, uint16_t len);
typedef uint8_t (__stdcall * tUsbBulkLibFuncReceive)(uint8_t * data, uint16_t len, uint32_t timeout);
/***************************************************************************************
* Function prototypes
****************************************************************************************/
/* USB bulk driver handling. */
static void UsbBulkLibLoadDll(void);
static void UsbBulkLibUnloadDll(void);
static uint8_t UsbBulkLibFuncOpen(LPGUID guid);
static void UsbBulkLibFuncClose(void);
static uint8_t UsbBulkLibFuncTransmit(uint8_t * data, uint16_t len);
static uint8_t UsbBulkLibFuncReceive(uint8_t * data, uint16_t len, uint32_t timeout);
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief Handle to the USB bulk driver dynamic link library. */
static HINSTANCE usbBulkLibDllHandle;
/** \brief Function pointer to the USB bulk driver library Open function. */
static tUsbBulkLibFuncOpen usbBulkLibFuncOpenPtr;
/** \brief Function pointer to the USB bulk driver library Close function. */
static tUsbBulkLibFuncClose usbBulkLibFuncClosePtr;
/** \brief Function pointer to the USB bulk driver library Transmit function. */
static tUsbBulkLibFuncTransmit usbBulkLibFuncTransmitPtr;
/** \brief Function pointer to the USB bulk driver library Receive function. */
static tUsbBulkLibFuncReceive usbBulkLibFuncReceivePtr;
/************************************************************************************//**
** \brief Initializes the USB bulk driver.
**
****************************************************************************************/
void UsbBulkInit(void)
{
/* Initialize locals. */
usbBulkLibDllHandle = NULL;
/* Reset library function pointers. */
usbBulkLibFuncOpenPtr = NULL;
usbBulkLibFuncClosePtr = NULL;
usbBulkLibFuncTransmitPtr = NULL;
usbBulkLibFuncReceivePtr = NULL;
/* Perform initialization of USB bulk driver API. */
UsbBulkLibLoadDll();
} /*** end of UsbBulkInit ***/
/************************************************************************************//**
** \brief Terminates the USB bulk driver.
**
****************************************************************************************/
void UsbBulkTerminate(void)
{
/* Perform termination of USB bulk driver API. */
UsbBulkLibUnloadDll();
} /*** end of UsbBulkTerminate ***/
/************************************************************************************//**
** \brief Opens the connection with the USB device.
** \return True if successful, false otherwise.
**
****************************************************************************************/
bool UsbBulkOpen(void)
{
/* This must be the same GUID as the one declared in the *.inf driver file. */
static GUID deviceGuidOpenBLT =
{
0x807999C3, 0xE4E0, 0x40EA, 0x81, 0x88, 0x48, 0xE8, 0x52, 0xB5, 0x4F, 0x2B
};
bool result = false;
/* Open the connection with the USB device. */
if (UsbBulkLibFuncOpen(&deviceGuidOpenBLT) == UBL_OKAY)
{
result = true;
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkOpen ***/
/************************************************************************************//**
** \brief Closes the connection with the USB device.
**
****************************************************************************************/
void UsbBulkClose(void)
{
/* Close the connection with the USB device. */
UsbBulkLibFuncClose();
} /*** end of UsbBulkClose ***/
/************************************************************************************//**
** \brief Writes data to the USB device.
** \param data Pointer to byte array with data to write.
** \param length Number of bytes in the data array.
** \return True if successful, false otherwise.
**
****************************************************************************************/
bool UsbBulkWrite(uint8_t const * data, uint16_t length)
{
bool result = false;
/* Check parameters. */
assert(data != NULL);
assert(length > 0);
/* Only continue with valid parameters. */
if ((data != NULL) && (length > 0)) /*lint !e774 */
{
/* Write data to the USB device. */
if (UsbBulkLibFuncTransmit((uint8_t *)data, length) == UBL_OKAY)
{
result = true;
}
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkWrite ***/
/************************************************************************************//**
** \brief Reads data from the USB device.
** \param data Pointer to byte array where received data should be stored.
** \param length Number of bytes to read from the USB device.
** \param timeout Timeout in milliseconds for the read operation.
** \return True if successful, false otherwise.
**
****************************************************************************************/
bool UsbBulkRead(uint8_t * data, uint16_t length, uint32_t timeout)
{
bool result = false;
(void)timeout;
/* Check parameters. */
assert(data != NULL);
assert(length > 0);
/* Only continue with valid parameters. */
if ((data != NULL) && (length > 0)) /*lint !e774 */
{
/* Read data from the USB device. */
if (UsbBulkLibFuncReceive(data, length, timeout) == UBL_OKAY)
{
result = true;
}
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkRead ***/
/************************************************************************************//**
** \brief Loads the USB bulk driver DLL and initializes the API function pointers.
**
****************************************************************************************/
static void UsbBulkLibLoadDll(void)
{
/* Start out by resetting the API function pointers. */
usbBulkLibFuncOpenPtr = NULL;
usbBulkLibFuncClosePtr = NULL;
usbBulkLibFuncTransmitPtr = NULL;
usbBulkLibFuncReceivePtr = NULL;
/* Attempt to load the library and obtain a handle to it. */
usbBulkLibDllHandle = LoadLibrary("UsbBulkLib");
/* Assert libary handle. */
assert(usbBulkLibDllHandle != NULL);
/* Only continue if the library was successfully loaded */
if (usbBulkLibDllHandle != NULL) /*lint !e774 */
{
/* Set UblOpen function pointer. */
usbBulkLibFuncOpenPtr = (tUsbBulkLibFuncOpen)GetProcAddress(usbBulkLibDllHandle, "UblOpen");
/* Set UblClose function pointer. */
usbBulkLibFuncClosePtr = (tUsbBulkLibFuncClose)GetProcAddress(usbBulkLibDllHandle, "UblClose");
/* Set UblTransmit function pointer. */
usbBulkLibFuncTransmitPtr = (tUsbBulkLibFuncTransmit)GetProcAddress(usbBulkLibDllHandle, "UblTransmit");
/* Set UblReceive function pointer. */
usbBulkLibFuncReceivePtr = (tUsbBulkLibFuncReceive)GetProcAddress(usbBulkLibDllHandle, "UblReceive");
}
} /*** end of UsbBulkLibLoadDll ***/
/************************************************************************************//**
** \brief Unloads the USB bulk driver DLL and resets the API function pointers.
**
****************************************************************************************/
static void UsbBulkLibUnloadDll(void)
{
/* Reset the API function pointers. */
usbBulkLibFuncOpenPtr = NULL;
usbBulkLibFuncClosePtr = NULL;
usbBulkLibFuncTransmitPtr = NULL;
usbBulkLibFuncReceivePtr = NULL;
/* Unload the library and invalidate its handle. */
if (usbBulkLibDllHandle != NULL)
{
(void)FreeLibrary(usbBulkLibDllHandle);
usbBulkLibDllHandle = NULL;
}
} /*** end of UsbBulkLibUnloadDll ***/
/************************************************************************************//**
** \brief Opens and configures the connection with the USB bulk device.
** \param guid Pointer to GUID of the USB bulk device as found in the driver's
** INF-file.
** \return UBL_OKAY if successful, UBL_ERROR otherwise.
**
****************************************************************************************/
static uint8_t UsbBulkLibFuncOpen(LPGUID guid)
{
uint8_t result = UBL_ERROR;
/* Check function pointer and library handle. */
assert(usbBulkLibFuncOpenPtr != NULL);
assert(usbBulkLibDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((usbBulkLibFuncOpenPtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = usbBulkLibFuncOpenPtr(guid);
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkLibFuncOpen ***/
/************************************************************************************//**
** \brief Closes the connection with the USB bulk device and frees all the related
** handles.
**
****************************************************************************************/
static void UsbBulkLibFuncClose(void)
{
/* Check function pointer and library handle. */
assert(usbBulkLibFuncClosePtr != NULL);
assert(usbBulkLibDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((usbBulkLibFuncClosePtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
usbBulkLibFuncClosePtr();
}
} /*** end of UsbBulkLibFuncClose ***/
/************************************************************************************//**
** \brief Starts transmission of the data on the bulk OUT pipe. Because USB bulk
** transmissions are quick, this function does not use the overlapped
** functionality, which means the caller is blocked until the tranmission
** completed.
** \param data Pointer to byte array with transmit data.
** \param len Number of bytes to transmit.
** \return UBL_OKAY if successful, UBL_ERROR otherwise.
**
****************************************************************************************/
static uint8_t UsbBulkLibFuncTransmit(uint8_t * data, uint16_t len)
{
uint8_t result = UBL_ERROR;
/* Check function pointer and library handle. */
assert(usbBulkLibFuncTransmitPtr != NULL);
assert(usbBulkLibDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((usbBulkLibFuncTransmitPtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = usbBulkLibFuncTransmitPtr(data, len);
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkLibFuncTransmit ***/
/************************************************************************************//**
** \brief Starts the asynchronous reception of the data from the bulk IN pipe. This
** function makes use of the overlapped functionality, which means the calling
** thread is placed into sleep mode until the reception is complete.
** \param data Pointer to byte array where the data will be stored.
** \param len Number of bytes to receive.
** \param timeout Maximum time in milliseconds for the read to complete.
** \return UBL_OKAY if successful, UBL_TIMEOUT if failure due to timeout or
** UBL_ERROR otherwise.
**
****************************************************************************************/
static uint8_t UsbBulkLibFuncReceive(uint8_t * data, uint16_t len, uint32_t timeout)
{
uint8_t result = UBL_ERROR;
/* Check function pointer and library handle. */
assert(usbBulkLibFuncReceivePtr != NULL);
assert(usbBulkLibDllHandle != NULL);
/* Only continue with valid function pointer and library handle. */
if ((usbBulkLibFuncReceivePtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
{
/* Call library function. */
result = usbBulkLibFuncReceivePtr(data, len, timeout);
}
/* Give the result back to the caller. */
return result;
} /*** end of UsbBulkLibFuncReceive ***/
/*********************************** end of usbbulk.c **********************************/