635 lines
25 KiB
C
635 lines
25 KiB
C
/*
|
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "usb_device_config.h"
|
|
#include "usb.h"
|
|
#include "usb_device.h"
|
|
|
|
#include "usb_device_class.h"
|
|
|
|
#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U))
|
|
#include "usb_device_printer.h"
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_printer_struct_t
|
|
s_PrinterHandle[USB_DEVICE_CONFIG_PRINTER];
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
static usb_status_t USB_DevicePrinterAllocateHandle(usb_device_printer_struct_t **printerHandle)
|
|
{
|
|
uint8_t index;
|
|
|
|
for (index = 0; index < USB_DEVICE_CONFIG_PRINTER; ++index)
|
|
{
|
|
if (s_PrinterHandle[index].deviceHandle == NULL)
|
|
{
|
|
*printerHandle = &(s_PrinterHandle[index]);
|
|
return kStatus_USB_Success;
|
|
}
|
|
}
|
|
|
|
return kStatus_USB_Busy;
|
|
}
|
|
|
|
static usb_status_t USB_DevicePrinterFreeHandle(usb_device_printer_struct_t *printerHandle)
|
|
{
|
|
/* ensure that printerHandle is not NULL before calling this function */
|
|
printerHandle->deviceHandle = NULL;
|
|
printerHandle->classConfig = NULL;
|
|
printerHandle->alternate = 0xFFu;
|
|
printerHandle->configuration = 0;
|
|
printerHandle->interfaceNumber = 0;
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief bulk IN endpoint callback function.
|
|
*
|
|
* This callback function is used to notify upper layer the transfer result of a transfer.
|
|
* This callback pointer is passed when the bulk IN pipe initialized.
|
|
*
|
|
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
|
|
* @param message The result of the bulk IN pipe transfer.
|
|
* @param callbackParam The parameter for this callback. It is same with
|
|
* usb_device_endpoint_callback_struct_t::callbackParam.
|
|
* In the class, the value is the printer class handle.
|
|
*
|
|
* @retval kStatus_USB_Success The transfer is successful.
|
|
* @retval kStatus_USB_InvalidHandle The device handle not be found.
|
|
*/
|
|
static usb_status_t USB_DevicePrinterBulkInCallback(usb_device_handle handle,
|
|
usb_device_endpoint_callback_message_struct_t *message,
|
|
void *callbackParam)
|
|
{
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
|
|
if (callbackParam == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
printerHandle->bulkInBusy = 0U;
|
|
if ((NULL != printerHandle->classConfig) && (printerHandle->classConfig->classCallback))
|
|
{
|
|
/* Notify the application data received by calling the printer class callback.
|
|
ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
|
|
it is from the second parameter of classInit */
|
|
status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle,
|
|
kUSB_DevicePrinterEventSendResponse, message);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief bulk OUT endpoint callback function.
|
|
*
|
|
* This callback function is used to notify upper layer the transfer result of a transfer.
|
|
* This callback pointer is passed when the bulk OUT pipe initialized.
|
|
*
|
|
* @param handle The device handle. It equals the value returned from USB_DeviceInit.
|
|
* @param message The result of the bulk OUT pipe transfer.
|
|
* @param callbackParam The parameter for this callback. It is same with
|
|
* usb_device_endpoint_callback_struct_t::callbackParam.
|
|
* In the class, the value is the printer class handle.
|
|
*
|
|
* @retval kStatus_USB_Success The transfer is successful.
|
|
* @retval kStatus_USB_InvalidHandle The device handle not be found.
|
|
*/
|
|
static usb_status_t USB_DevicePrinterBulkOutCallback(usb_device_handle handle,
|
|
usb_device_endpoint_callback_message_struct_t *message,
|
|
void *callbackParam)
|
|
{
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
|
|
if (printerHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
printerHandle->bulkOutBusy = 0U;
|
|
if ((NULL != printerHandle->classConfig) && (printerHandle->classConfig->classCallback))
|
|
{
|
|
/* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
|
|
it is from the second parameter of classInit */
|
|
status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle,
|
|
kUSB_DevicePrinterEventRecvResponse, message);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief Initialize the endpoints of the printer class.
|
|
*
|
|
* This callback function is used to initialize the endpoints of the printer class.
|
|
*
|
|
* @param printerHandle The device printer class handle. It equals the value returned from
|
|
* usb_device_class_config_struct_t::classHandle.
|
|
*
|
|
* @return A USB error code or kStatus_USB_Success.
|
|
*/
|
|
static usb_status_t USB_DevicePrinterEndpointsInit(usb_device_printer_struct_t *printerHandle)
|
|
{
|
|
/* ensure that printerHandle is not NULL before calling this function */
|
|
usb_device_interface_list_t *configInterfaceList;
|
|
usb_device_interface_struct_t *interface = NULL;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
uint8_t interfaceIndex;
|
|
uint8_t index;
|
|
|
|
/* return error when configuration is invalid (0 or more than the configuration number) */
|
|
if ((printerHandle->configuration == 0U) ||
|
|
(printerHandle->configuration > printerHandle->classConfig->classInfomation->configurations))
|
|
{
|
|
return status;
|
|
}
|
|
|
|
configInterfaceList =
|
|
&(printerHandle->classConfig->classInfomation->interfaceList[printerHandle->configuration - 1]);
|
|
for (interfaceIndex = 0; interfaceIndex < configInterfaceList->count; ++interfaceIndex)
|
|
{
|
|
if (USB_DEVICE_CONFIG_PRINTER_CLASS_CODE == configInterfaceList->interfaces[interfaceIndex].classCode)
|
|
{
|
|
/* index means the alternate interface's index here */
|
|
for (index = 0; index < configInterfaceList->interfaces[interfaceIndex].count; ++index)
|
|
{
|
|
if (configInterfaceList->interfaces[interfaceIndex].interface[index].alternateSetting ==
|
|
printerHandle->alternate)
|
|
{
|
|
interface = &(configInterfaceList->interfaces[interfaceIndex].interface[index]);
|
|
break;
|
|
}
|
|
}
|
|
printerHandle->interfaceNumber = configInterfaceList->interfaces[interfaceIndex].interfaceNumber;
|
|
break;
|
|
}
|
|
}
|
|
if (interface == NULL)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
/* Keep new interface handle. */
|
|
printerHandle->interfaceHandle = interface;
|
|
|
|
/* Initialize the endpoints of the new interface. */
|
|
/* index means the endpoint's index here */
|
|
for (index = 0; index < interface->endpointList.count; ++index)
|
|
{
|
|
usb_device_endpoint_init_struct_t epInitStruct;
|
|
usb_device_endpoint_callback_struct_t epCallback;
|
|
epInitStruct.zlt = 0U;
|
|
epInitStruct.interval = interface->endpointList.endpoint[index].interval;
|
|
epInitStruct.endpointAddress = interface->endpointList.endpoint[index].endpointAddress;
|
|
epInitStruct.maxPacketSize = interface->endpointList.endpoint[index].maxPacketSize;
|
|
epInitStruct.transferType = interface->endpointList.endpoint[index].transferType;
|
|
|
|
if (((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT) == USB_IN)
|
|
{
|
|
epCallback.callbackFn = USB_DevicePrinterBulkInCallback;
|
|
printerHandle->bulkInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32;
|
|
printerHandle->bulkInPipeStall = 0U;
|
|
printerHandle->bulkInPipeDataLen = 0U;
|
|
}
|
|
else
|
|
{
|
|
epCallback.callbackFn = USB_DevicePrinterBulkOutCallback;
|
|
printerHandle->bulkOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32;
|
|
printerHandle->bulkOutPipeStall = 0U;
|
|
printerHandle->bulkOutPipeDataLen = 0U;
|
|
}
|
|
epCallback.callbackParam = printerHandle;
|
|
|
|
status = USB_DeviceInitEndpoint(printerHandle->deviceHandle, &epInitStruct, &epCallback);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief De-initialize the endpoints of the printer class.
|
|
*
|
|
* This callback function is used to de-initialize the endpoints of the printer class.
|
|
*
|
|
* @param printerHandle The device printer class handle. It equals the value returned from
|
|
* usb_device_class_config_struct_t::classHandle.
|
|
*
|
|
* @return A USB error code or kStatus_USB_Success.
|
|
*/
|
|
static usb_status_t USB_DevicePrinterEndpointsDeinit(usb_device_printer_struct_t *printerHandle)
|
|
{
|
|
/* ensure that printerHandle is not NULL before calling this function */
|
|
usb_status_t status = kStatus_USB_Error;
|
|
uint8_t index;
|
|
|
|
/* return directly when the interfaceHandle is NULL, it means USB_DevicePrinterEndpointsInit is not called */
|
|
if (printerHandle->interfaceHandle == NULL)
|
|
{
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
for (index = 0; index < printerHandle->interfaceHandle->endpointList.count; ++index)
|
|
{
|
|
status = USB_DeviceDeinitEndpoint(printerHandle->deviceHandle,
|
|
printerHandle->interfaceHandle->endpointList.endpoint[index].endpointAddress);
|
|
}
|
|
printerHandle->interfaceHandle = NULL;
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_DevicePrinterInit(uint8_t controllerId,
|
|
usb_device_class_config_struct_t *config,
|
|
class_handle_t *handle)
|
|
|
|
{
|
|
usb_device_handle deviceHandle;
|
|
usb_device_printer_struct_t *printerHandle;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
USB_OSA_SR_ALLOC();
|
|
|
|
/* get the controller's device handle */
|
|
status = USB_DeviceClassGetDeviceHandle(controllerId, &deviceHandle);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
return status;
|
|
}
|
|
if (deviceHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* Allocate a printer class handle. */
|
|
USB_OSA_ENTER_CRITICAL();
|
|
status = USB_DevicePrinterAllocateHandle(&printerHandle);
|
|
printerHandle->deviceHandle = deviceHandle; /* this printer instance is used */
|
|
USB_OSA_EXIT_CRITICAL();
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
printerHandle->classConfig = config;
|
|
printerHandle->alternate = 0xFFu;
|
|
printerHandle->configuration = 0;
|
|
printerHandle->interfaceNumber = 0;
|
|
printerHandle->interfaceHandle = NULL;
|
|
|
|
*handle = (class_handle_t)printerHandle;
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_DevicePrinterDeinit(class_handle_t handle)
|
|
{
|
|
usb_status_t status;
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
|
|
|
|
if (!handle)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
status = USB_DevicePrinterEndpointsDeinit(printerHandle);
|
|
USB_DevicePrinterFreeHandle(printerHandle);
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_DevicePrinterEvent(void *handle, uint32_t event, void *param)
|
|
{
|
|
usb_status_t status = kStatus_USB_Error;
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
|
|
uint16_t temp16;
|
|
uint8_t temp8;
|
|
|
|
if ((handle == NULL) || (param == NULL))
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
switch (event)
|
|
{
|
|
case kUSB_DeviceClassEventDeviceReset:
|
|
/* de-initialize printer instance */
|
|
printerHandle->interfaceHandle = NULL;
|
|
printerHandle->alternate = 0xFFu;
|
|
printerHandle->configuration = 0;
|
|
printerHandle->interfaceNumber = 0;
|
|
printerHandle->bulkInBusy = 0U;
|
|
printerHandle->bulkOutBusy = 0U;
|
|
status = kStatus_USB_Success;
|
|
break;
|
|
|
|
case kUSB_DeviceClassEventSetConfiguration:
|
|
temp8 = *((uint8_t *)param);
|
|
if (printerHandle->classConfig == NULL)
|
|
{
|
|
break;
|
|
}
|
|
if (temp8 == printerHandle->configuration)
|
|
{
|
|
status = kStatus_USB_Success;
|
|
break;
|
|
}
|
|
|
|
/* De-initialize the endpoints when current configuration is none zero. */
|
|
if (printerHandle->configuration != 0)
|
|
{
|
|
status = USB_DevicePrinterEndpointsDeinit(printerHandle);
|
|
}
|
|
/* Save new configuration. */
|
|
printerHandle->configuration = temp8;
|
|
printerHandle->alternate = 0U;
|
|
printerHandle->bulkInBusy = 0U;
|
|
printerHandle->bulkOutBusy = 0U;
|
|
|
|
/* Initialize the endpoints of the new current configuration */
|
|
status = USB_DevicePrinterEndpointsInit(printerHandle);
|
|
break;
|
|
|
|
case kUSB_DeviceClassEventSetInterface:
|
|
if (printerHandle->classConfig == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
/* Get the new alternate setting of the interface */
|
|
temp16 = *((uint16_t *)param);
|
|
/* Get the alternate setting value */
|
|
temp8 = (uint8_t)(temp16 & 0xFFU);
|
|
/* Whether the interface belongs to the class. */
|
|
if (printerHandle->interfaceNumber != ((uint8_t)(temp16 >> 8U)))
|
|
{
|
|
break;
|
|
}
|
|
/* Only handle new alternate setting. */
|
|
if (temp8 == printerHandle->alternate)
|
|
{
|
|
break;
|
|
}
|
|
|
|
/* De-initialize old endpoints */
|
|
status = USB_DevicePrinterEndpointsDeinit(printerHandle);
|
|
printerHandle->alternate = temp8;
|
|
printerHandle->bulkInBusy = 0U;
|
|
printerHandle->bulkOutBusy = 0U;
|
|
/* Initialize new endpoints */
|
|
status = USB_DevicePrinterEndpointsInit(printerHandle);
|
|
break;
|
|
|
|
case kUSB_DeviceClassEventSetEndpointHalt:
|
|
if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL))
|
|
{
|
|
break;
|
|
}
|
|
/* Get the endpoint address */
|
|
temp8 = *((uint8_t *)param);
|
|
for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16)
|
|
{
|
|
if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress)
|
|
{
|
|
/* Only stall the endpoint belongs to the class */
|
|
if (USB_IN == ((printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
|
|
{
|
|
printerHandle->bulkInPipeStall = 1U;
|
|
}
|
|
else
|
|
{
|
|
printerHandle->bulkOutPipeStall = 1U;
|
|
}
|
|
status = USB_DeviceStallEndpoint(printerHandle->deviceHandle, temp8);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kUSB_DeviceClassEventClearEndpointHalt:
|
|
if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL))
|
|
{
|
|
break;
|
|
}
|
|
/* Get the endpoint address */
|
|
temp8 = *((uint8_t *)param);
|
|
for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16)
|
|
{
|
|
if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress)
|
|
{
|
|
/* Only un-stall the endpoint belongs to the class */
|
|
status = USB_DeviceUnstallEndpoint(printerHandle->deviceHandle, temp8);
|
|
if (USB_IN == (((temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
|
|
{
|
|
if (printerHandle->bulkInPipeStall)
|
|
{
|
|
printerHandle->bulkInPipeStall = 0U;
|
|
if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != printerHandle->bulkInPipeDataBuffer)
|
|
{
|
|
status = USB_DeviceSendRequest(printerHandle->deviceHandle, (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
|
|
printerHandle->bulkInPipeDataBuffer, printerHandle->bulkInPipeDataLen);
|
|
if (kStatus_USB_Success != status)
|
|
{
|
|
usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
|
|
endpointCallbackMessage.buffer = printerHandle->bulkInPipeDataBuffer;
|
|
endpointCallbackMessage.length = printerHandle->bulkInPipeDataLen;
|
|
endpointCallbackMessage.isSetup = 0U;
|
|
USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,(void*)&endpointCallbackMessage, handle);
|
|
}
|
|
printerHandle->bulkInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32;
|
|
printerHandle->bulkInPipeDataLen = 0U;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (printerHandle->bulkOutPipeStall == 1U)
|
|
{
|
|
printerHandle->bulkOutPipeStall = 0U;
|
|
if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != printerHandle->bulkOutPipeDataBuffer)
|
|
{
|
|
status = USB_DeviceRecvRequest(printerHandle->deviceHandle, (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
|
|
printerHandle->bulkOutPipeDataBuffer, printerHandle->bulkOutPipeDataLen);
|
|
if (kStatus_USB_Success != status)
|
|
{
|
|
usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
|
|
endpointCallbackMessage.buffer = printerHandle->bulkOutPipeDataBuffer;
|
|
endpointCallbackMessage.length = printerHandle->bulkOutPipeDataLen;
|
|
endpointCallbackMessage.isSetup = 0U;
|
|
USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle, (void*)&endpointCallbackMessage, handle);
|
|
}
|
|
printerHandle->bulkOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32;
|
|
printerHandle->bulkOutPipeDataLen = 0U;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case kUSB_DeviceClassEventClassRequest:
|
|
if (param)
|
|
{
|
|
/* Handle the printer class specific request. */
|
|
usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param;
|
|
usb_device_printer_class_request_t classRequest;
|
|
|
|
if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) !=
|
|
USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
|
|
{
|
|
break;
|
|
}
|
|
|
|
switch (controlRequest->setup->bRequest)
|
|
{
|
|
case USB_DEVICE_PRINTER_GET_DEVICE_ID:
|
|
/* GET_DEVICE_ID */
|
|
classRequest.configIndex = (uint8_t)controlRequest->setup->wValue;
|
|
classRequest.interface = (uint8_t)(controlRequest->setup->wIndex >> 8);
|
|
classRequest.alternateSetting = (uint8_t)(controlRequest->setup->wIndex);
|
|
/* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
|
|
it is from the second parameter of classInit */
|
|
status = printerHandle->classConfig->classCallback(
|
|
(class_handle_t)printerHandle, kUSB_DevicePrinterEventGetDeviceId, &classRequest);
|
|
controlRequest->buffer = classRequest.buffer;
|
|
controlRequest->length = classRequest.length;
|
|
break;
|
|
|
|
case USB_DEVICE_PRINTER_GET_PORT_STATUS:
|
|
/* GET_PORT_STATUS */
|
|
classRequest.interface = (uint8_t)(controlRequest->setup->wIndex);
|
|
if (classRequest.interface != printerHandle->interfaceNumber)
|
|
{
|
|
controlRequest->buffer = NULL;
|
|
controlRequest->length = 0U;
|
|
}
|
|
else
|
|
{
|
|
/* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
|
|
it is from the second parameter of classInit */
|
|
status = printerHandle->classConfig->classCallback(
|
|
(class_handle_t)printerHandle, kUSB_DevicePrinterEventGetPortStatus, &classRequest);
|
|
controlRequest->buffer = classRequest.buffer;
|
|
controlRequest->length = classRequest.length;
|
|
}
|
|
break;
|
|
|
|
case USB_DEVICE_PRINTER_SOFT_RESET:
|
|
classRequest.interface = (uint8_t)(controlRequest->setup->wIndex);
|
|
if (classRequest.interface != printerHandle->interfaceNumber)
|
|
{
|
|
controlRequest->buffer = NULL;
|
|
controlRequest->length = 0U;
|
|
}
|
|
else
|
|
{
|
|
/* reset BULK_IN/OUT endpoint and inform application */
|
|
USB_DevicePrinterEndpointsDeinit(printerHandle);
|
|
USB_DevicePrinterEndpointsInit(printerHandle);
|
|
/* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
|
|
it is from the second parameter of classInit */
|
|
status = printerHandle->classConfig->classCallback(
|
|
(class_handle_t)printerHandle, kUSB_DevicePrinterEventGetPortStatus, &classRequest);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_DevicePrinterSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
|
|
{
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
|
|
if (!handle)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if (printerHandle->bulkInBusy)
|
|
{
|
|
return kStatus_USB_Busy;
|
|
}
|
|
printerHandle->bulkInBusy = 1U;
|
|
|
|
if (printerHandle->bulkInPipeStall)
|
|
{
|
|
printerHandle->bulkInPipeDataBuffer = buffer;
|
|
printerHandle->bulkInPipeDataLen = length;
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
status = USB_DeviceSendRequest(printerHandle->deviceHandle, ep, buffer, length);
|
|
if (kStatus_USB_Success != status)
|
|
{
|
|
printerHandle->bulkInBusy = 0U;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_DevicePrinterRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
|
|
{
|
|
usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle;
|
|
usb_status_t status = kStatus_USB_Error;
|
|
|
|
if (!handle)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if (printerHandle->bulkOutBusy)
|
|
{
|
|
return kStatus_USB_Busy;
|
|
}
|
|
printerHandle->bulkOutBusy = 1U;
|
|
|
|
if (printerHandle->bulkOutPipeStall)
|
|
{
|
|
printerHandle->bulkOutPipeDataBuffer = buffer;
|
|
printerHandle->bulkOutPipeDataLen = length;
|
|
return kStatus_USB_Success;
|
|
}
|
|
status = USB_DeviceRecvRequest(printerHandle->deviceHandle, ep, buffer, length);
|
|
if (kStatus_USB_Success != status)
|
|
{
|
|
printerHandle->bulkOutBusy = 0U;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
#endif
|