RT1050_FreeRTOS_USB_Hello/middleware/usb/host/class/usb_host_printer.c

781 lines
30 KiB
C

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016,2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_host_config.h"
#if ((defined USB_HOST_CONFIG_PRINTER) && (USB_HOST_CONFIG_PRINTER))
#include "usb_host.h"
#include "usb_host_printer.h"
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief printer in pipe transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief printer out pipe transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief printer control pipe transfer callback.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief printer open interface. It is called when set interface request success or open alternate setting 0 interface.
*
* @param printerInstance printer instance pointer.
*
* @return kStatus_USB_Success or error codes.
*/
static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance);
/*!
* @brief printer set interface callback, open pipes.
*
* @param param callback parameter.
* @param transfer callback transfer.
* @param status transfer status.
*/
static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
/*!
* @brief printer send control transfer common code.
*
* @param classHandle the class handle.
* @param requestType setup packet request type.
* @param request setup packet request value.
* @param wvalue setup packet wValue.
* @param windex setup packet wIndex.
* @param wlength setup packet wlength value.
* @param data data buffer pointer
* @param callbackFn this callback is called after this function completes.
* @param callbackParam the first parameter in the callback function.
*
* @return An error code or kStatus_USB_Success.
*/
static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
uint8_t requestType,
uint8_t request,
uint16_t wvalue,
uint16_t windex,
uint16_t wlength,
uint8_t *data,
transfer_callback_t callbackFn,
void *callbackParam);
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
static void USB_HostPrinterClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
if (printerInstance->inCallbackFn != NULL)
{
/* callback to application, callback function is initialized in USB_HostPrinterRecv */
printerInstance->inCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
printerInstance->stallDataLength, kStatus_USB_TransferStall);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
static void USB_HostPrinterClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
if (printerInstance->outCallbackFn != NULL)
{
/* callback to application, callback function is initialized in USB_HostPrinterSend */
printerInstance->outCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
printerInstance->stallDataLength, kStatus_USB_TransferStall);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
static usb_status_t USB_HostPrinterClearHalt(usb_host_printer_instance_t *printerInstance,
usb_host_transfer_t *stallTransfer,
host_inner_transfer_callback_t callbackFn,
uint8_t endpoint)
{
usb_status_t status;
usb_host_transfer_t *transfer;
/* malloc one transfer */
status = USB_HostMallocTransfer(printerInstance->hostHandle, &transfer);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("allocate transfer error\r\n");
#endif
return status;
}
printerInstance->stallDataBuffer = stallTransfer->transferBuffer;
printerInstance->stallDataLength = stallTransfer->transferSofar;
/* save the application callback function */
printerInstance->controlCallbackFn = NULL;
printerInstance->controlCallbackParam = NULL;
/* initialize transfer */
transfer->callbackFn = callbackFn;
transfer->callbackParam = printerInstance;
transfer->transferBuffer = NULL;
transfer->transferLength = 0;
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
transfer->setupPacket->wLength = 0;
status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
if (status != kStatus_USB_Success)
{
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
printerInstance->controlTransfer = transfer;
return status;
}
#endif
static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
if (status == kStatus_USB_TransferStall)
{
if (USB_HostPrinterClearHalt(
printerInstance, transfer, USB_HostPrinterClearInHaltCallback,
(USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)printerInstance->inPipe)->endpointAddress)) ==
kStatus_USB_Success)
{
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
return;
}
}
#endif
if (printerInstance->inCallbackFn != NULL)
{
/* callback to application, callback function is initialized in USB_HostPrinterRecv */
printerInstance->inCallbackFn(printerInstance->inCallbackParam, transfer->transferBuffer,
transfer->transferSofar, status);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
if (status == kStatus_USB_TransferStall)
{
if (USB_HostPrinterClearHalt(
printerInstance, transfer, USB_HostPrinterClearOutHaltCallback,
(USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)printerInstance->outPipe)->endpointAddress)) ==
kStatus_USB_Success)
{
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
return;
}
}
#endif
if (printerInstance->outCallbackFn != NULL)
{
/* callback to application, callback function is initialized in USB_HostPrinterSend */
printerInstance->outCallbackFn(printerInstance->outCallbackParam, transfer->transferBuffer,
transfer->transferSofar, status);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
printerInstance->controlTransfer = NULL;
if (printerInstance->controlCallbackFn != NULL)
{
/* callback to application, callback to application, callback function is initialized in the
USB_HostPrinterControl,
USB_HostPrinterSetInterface or USB_HostHubClassRequestCommon, but is the same function */
printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, transfer->transferBuffer,
transfer->transferSofar, status);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance)
{
usb_status_t status;
uint8_t epIndex = 0;
usb_host_pipe_init_t pipeInit;
usb_descriptor_endpoint_t *epDesc = NULL;
usb_host_interface_t *interfacePointer;
if (printerInstance->inPipe != NULL)
{
status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when close pipe\r\n");
#endif
}
printerInstance->inPipe = NULL;
}
if (printerInstance->outPipe != NULL) /* close interrupt out pipe if it is open */
{
status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when close pipe\r\n");
#endif
}
printerInstance->outPipe = NULL;
}
/* open interface pipes */
interfacePointer = (usb_host_interface_t *)printerInstance->interfaceHandle;
for (epIndex = 0; epIndex < interfacePointer->epCount; ++epIndex)
{
epDesc = interfacePointer->epList[epIndex].epDesc;
if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
{
pipeInit.devInstance = printerInstance->deviceHandle;
pipeInit.pipeType = USB_ENDPOINT_BULK;
pipeInit.direction = USB_IN;
pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
pipeInit.interval = epDesc->bInterval;
pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
printerInstance->inPacketSize = pipeInit.maxPacketSize;
status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->inPipe, &pipeInit);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
#endif
return kStatus_USB_Error;
}
}
else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
{
pipeInit.devInstance = printerInstance->deviceHandle;
pipeInit.pipeType = USB_ENDPOINT_BULK;
pipeInit.direction = USB_OUT;
pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
pipeInit.interval = epDesc->bInterval;
pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
printerInstance->outPacketSize = pipeInit.maxPacketSize;
status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->outPipe, &pipeInit);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
#endif
return kStatus_USB_Error;
}
}
else
{
}
}
return kStatus_USB_Success;
}
static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
printerInstance->controlTransfer = NULL;
if (status == kStatus_USB_Success)
{
status = USB_HostPrinterOpenInterface(printerInstance); /* printer open interface */
}
if (printerInstance->controlCallbackFn != NULL)
{
/* callback to application, callback to application, callback function is initialized in the
USB_HostPrinterControl,
USB_HostPrinterSetInterface or USB_HostHubClassRequestCommon, but is the same function */
printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, NULL, 0, status);
}
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
usb_status_t USB_HostPrinterInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
{
uint32_t infoValue;
uint32_t *temp;
/* malloc printer class instance */
usb_host_printer_instance_t *printerInstance =
(usb_host_printer_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_printer_instance_t));
if (printerInstance == NULL)
{
return kStatus_USB_AllocFail;
}
/* initialize printer instance */
printerInstance->deviceHandle = deviceHandle;
printerInstance->interfaceHandle = NULL;
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &infoValue);
temp = (uint32_t *)infoValue;
printerInstance->hostHandle = (usb_host_handle)temp;
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &infoValue);
temp = (uint32_t *)infoValue;
printerInstance->controlPipe = (usb_host_pipe_handle)temp;
*classHandle = printerInstance;
return kStatus_USB_Success;
}
usb_status_t USB_HostPrinterSetInterface(usb_host_class_handle classHandle,
usb_host_interface_handle interfaceHandle,
uint8_t alternateSetting,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_status_t status;
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (classHandle == NULL)
{
return kStatus_USB_InvalidParameter;
}
/* notify host driver the interface is open */
status = USB_HostOpenDeviceInterface(printerInstance->deviceHandle, interfaceHandle);
if (status != kStatus_USB_Success)
{
return status;
}
printerInstance->interfaceHandle = interfaceHandle;
/* cancel transfers */
if (printerInstance->inPipe != NULL)
{
status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when cancel pipe\r\n");
#endif
}
}
if (printerInstance->outPipe != NULL)
{
status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when cancel pipe\r\n");
#endif
}
}
if (alternateSetting == 0U) /* open interface directly */
{
if (callbackFn != NULL)
{
status = USB_HostPrinterOpenInterface(printerInstance);
callbackFn(callbackParam, NULL, 0, status);
}
}
else /* send setup transfer */
{
/* malloc one transfer */
if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Error;
}
/* save the application callback function */
printerInstance->controlCallbackFn = callbackFn;
printerInstance->controlCallbackParam = callbackParam;
/* initialize transfer */
transfer->callbackFn = USB_HostPrinterSetInterfaceCallback;
transfer->callbackParam = printerInstance;
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
transfer->setupPacket->wLength = 0;
transfer->transferBuffer = NULL;
transfer->transferLength = 0;
status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
if (status == kStatus_USB_Success)
{
printerInstance->controlTransfer = transfer;
}
else
{
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
}
}
return status;
}
usb_status_t USB_HostPrinterDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
{
usb_status_t status;
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
if (deviceHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
if (classHandle != NULL) /* class instance has initialized */
{
if (printerInstance->inPipe != NULL)
{
status =
USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL); /* cancel pipe */
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when cancel pipe\r\n");
#endif
}
status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe); /* close pipe */
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when close pipe\r\n");
#endif
}
printerInstance->inPipe = NULL;
}
if (printerInstance->outPipe != NULL)
{
status =
USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL); /* cancel pipe */
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when cancel pipe\r\n");
#endif
}
status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe); /* close pipe */
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when close pipe\r\n");
#endif
}
printerInstance->outPipe = NULL;
}
if ((printerInstance->controlPipe != NULL) &&
(printerInstance->controlTransfer !=
NULL)) /* cancel control transfer if there is on-going control transfer */
{
status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->controlPipe,
printerInstance->controlTransfer);
if (status != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error when cancel pipe\r\n");
#endif
}
}
(void)USB_HostCloseDeviceInterface(
deviceHandle, printerInstance->interfaceHandle); /* notify host driver the interface is closed */
OSA_MemoryFree(printerInstance);
}
else
{
(void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
}
return kStatus_USB_Success;
}
usb_status_t USB_HostPrinterRecv(usb_host_class_handle classHandle,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (classHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
if (printerInstance->inPipe == NULL)
{
return kStatus_USB_Error;
}
/* malloc one transfer */
if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Busy;
}
/* save the application callback function */
printerInstance->inCallbackFn = callbackFn;
printerInstance->inCallbackParam = callbackParam;
/* initialize transfer */
transfer->transferBuffer = buffer;
transfer->transferLength = bufferLength;
transfer->callbackFn = USB_HostPrinterInPipeCallback;
transfer->callbackParam = printerInstance;
/* call host driver api */
if (USB_HostRecv(printerInstance->hostHandle, printerInstance->inPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("fail to USB_HostRecv\r\n");
#endif
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
return kStatus_USB_Success;
}
uint16_t USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
{
usb_host_printer_instance_t *phdcInstance = (usb_host_printer_instance_t *)classHandle;
if (classHandle == NULL)
{
return 0;
}
if (pipeType == USB_ENDPOINT_INTERRUPT)
{
if (direction == USB_IN)
{
return phdcInstance->inPacketSize;
}
else
{
return phdcInstance->outPacketSize;
}
}
return 0;
}
usb_status_t USB_HostPrinterSend(usb_host_class_handle classHandle,
uint8_t *buffer,
uint32_t bufferLength,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
usb_host_transfer_t *transfer;
if (classHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
if (printerInstance->outPipe == NULL)
{
return kStatus_USB_Error;
}
/* malloc one transfer */
if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Error;
}
/* save the application callback function */
printerInstance->outCallbackFn = callbackFn;
printerInstance->outCallbackParam = callbackParam;
/* initialize transfer */
transfer->transferBuffer = buffer;
transfer->transferLength = bufferLength;
transfer->callbackFn = USB_HostPrinterOutPipeCallback;
transfer->callbackParam = printerInstance;
/* call host driver api */
if (USB_HostSend(printerInstance->hostHandle, printerInstance->outPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("fail to USB_HostSend\r\n");
#endif
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
return kStatus_USB_Success;
}
static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
uint8_t requestType,
uint8_t request,
uint16_t wvalue,
uint16_t windex,
uint16_t wlength,
uint8_t *data,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_transfer_t *transfer;
if (printerInstance == NULL)
{
return kStatus_USB_InvalidHandle;
}
if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("error to get transfer\r\n");
#endif
return kStatus_USB_Busy;
}
/* save the application callback function */
printerInstance->controlCallbackFn = callbackFn;
printerInstance->controlCallbackParam = callbackParam;
/* initialize transfer */
transfer->transferBuffer = data;
transfer->transferLength = wlength;
transfer->callbackFn = USB_HostPrinterControlPipeCallback;
transfer->callbackParam = printerInstance;
transfer->setupPacket->bmRequestType = requestType;
transfer->setupPacket->bRequest = request;
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
/* call host driver api */
if (USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("fail for USB_HostSendSetup\r\n");
#endif
(void)USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
return kStatus_USB_Error;
}
printerInstance->controlTransfer = transfer;
return kStatus_USB_Success;
}
usb_status_t USB_HostPrinterGetDeviceId(usb_host_class_handle classHandle,
uint8_t interfaceIndex,
uint8_t alternateSetting,
uint8_t *buffer,
uint32_t length,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
uint32_t infoValue = 0U;
(void)USB_HostHelperGetPeripheralInformation(printerInstance->deviceHandle, (uint32_t)kUSB_HostGetDeviceConfigIndex,
&infoValue);
return USB_HostPrinterControl(
printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
USB_HOST_PRINTER_GET_DEVICE_ID, (uint16_t)infoValue,
(uint16_t)((uint16_t)((uint16_t)interfaceIndex << 8U) | alternateSetting), (uint16_t)length, buffer, callbackFn,
callbackParam);
}
usb_status_t USB_HostPrinterGetPortStatus(usb_host_class_handle classHandle,
uint8_t *portStatus,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
return USB_HostPrinterControl(
printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
USB_HOST_PRINTER_GET_PORT_STATUS, 0,
(uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 1,
portStatus, callbackFn, callbackParam);
}
usb_status_t USB_HostPrinterSoftReset(usb_host_class_handle classHandle,
transfer_callback_t callbackFn,
void *callbackParam)
{
usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
return USB_HostPrinterControl(
printerInstance, USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
USB_HOST_PRINTER_SOFT_RESET, 0,
(uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 0,
NULL, callbackFn, callbackParam);
}
#endif /* USB_HOST_CONFIG_PRINTER */