From f7cd9b461ca33845339f4a11f49bdc142696827a Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Tue, 28 Jun 2016 09:51:29 +0200 Subject: Apalis_TK1_K20: SPI Communication, ADC, TSC, GPIO Support for Communication between TK1 SoC and K20 MCU This patch includes ADC, TSC and GPIO functionality. Signed-off-by: Dominik Sliwa --- usb_1.1.0/host/class/usb_host_hid.c | 804 ++++++++++++++++++++++++++++++++++++ 1 file changed, 804 insertions(+) create mode 100644 usb_1.1.0/host/class/usb_host_hid.c (limited to 'usb_1.1.0/host/class/usb_host_hid.c') diff --git a/usb_1.1.0/host/class/usb_host_hid.c b/usb_1.1.0/host/class/usb_host_hid.c new file mode 100644 index 0000000..ddaf3be --- /dev/null +++ b/usb_1.1.0/host/class/usb_host_hid.c @@ -0,0 +1,804 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "usb_host_config.h" +#if ((defined USB_HOST_CONFIG_HID) && (USB_HOST_CONFIG_HID)) +#include "usb_host.h" +#include "usb_host_hid.h" + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief hid in pipe transfer callback. + * + * @param param callback parameter. + * @param transfer callback transfer. + * @param status transfer status. + */ +static void USB_HostHidInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status); + +/*! + * @brief hid out pipe transfer callback. + * + * @param param callback parameter. + * @param transfer callback transfer. + * @param status transfer status. + */ +static void USB_HostHidOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status); + +/*! + * @brief hid control pipe transfer callback. + * + * @param param callback parameter. + * @param transfer callback transfer. + * @param status transfer status. + */ +static void USB_HostHidControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status); + +/*! + * @brief hid open interface. It is called when set interface request success or open alternate setting 0 interface. + * + * @param hidInstance hid instance pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostHidOpenInterface(usb_host_hid_instance_t *hidInstance); + +/*! + * @brief hid set interface callback, open pipes. + * + * @param param callback parameter. + * @param transfer callback transfer. + * @param status transfer status. + */ +static void USB_HostHidSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status); + +/*! + * @brief hid send control transfer common code. + * + * @param classHandle the class handle. + * @param requestType setup packet request type. + * @param request setup packet request value. + * @param wvalueL setup packet wvalue low byte. + * @param wvalueH setup packet wvalue high byte. + * @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_HostHidControl(usb_host_class_handle classHandle, + uint8_t requestType, + uint8_t request, + uint8_t wvalueL, + uint8_t wvalueH, + 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_HostHidClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param; + + hidInstance->controlTransfer = NULL; + if (hidInstance->inCallbackFn != NULL) + { + /* callback to application */ + hidInstance->inCallbackFn(hidInstance->inCallbackParam, hidInstance->stallDataBuffer, + hidInstance->stallDataLength, kStatus_USB_TransferStall); + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +static void USB_HostHidClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param; + + hidInstance->controlTransfer = NULL; + if (hidInstance->outCallbackFn != NULL) + { + /* callback to application */ + hidInstance->outCallbackFn(hidInstance->outCallbackParam, hidInstance->stallDataBuffer, + hidInstance->stallDataLength, kStatus_USB_TransferStall); + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +static usb_status_t USB_HostHidClearHalt(usb_host_hid_instance_t *hidInstance, + 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(hidInstance->hostHandle, &transfer); + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("allocate transfer error\r\n"); +#endif + return status; + } + hidInstance->stallDataBuffer = stallTransfer->transferBuffer; + hidInstance->stallDataLength = stallTransfer->transferSofar; + /* save the application callback function */ + hidInstance->controlCallbackFn = NULL; + hidInstance->controlCallbackParam = NULL; + /* initialize transfer */ + transfer->callbackFn = callbackFn; + transfer->callbackParam = hidInstance; + 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(hidInstance->hostHandle, hidInstance->controlPipe, transfer); + + if (status != kStatus_USB_Success) + { + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + } + hidInstance->controlTransfer = transfer; + + return status; +} +#endif + +static void USB_HostHidInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_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_HostHidClearHalt(hidInstance, transfer, USB_HostHidClearInHaltCallback, + (USB_REQUEST_TYPE_DIR_IN | + ((usb_host_pipe_t *)hidInstance->inPipe)->endpointAddress)) == kStatus_USB_Success) + { + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + return; + } + } +#endif + if (hidInstance->inCallbackFn != NULL) + { + hidInstance->inCallbackFn(hidInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar, + status); /* callback to application */ + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +static void USB_HostHidOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_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_HostHidClearHalt(hidInstance, transfer, USB_HostHidClearOutHaltCallback, + (USB_REQUEST_TYPE_DIR_OUT | + ((usb_host_pipe_t *)hidInstance->outPipe)->endpointAddress)) == kStatus_USB_Success) + { + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + return; + } + } +#endif + if (hidInstance->outCallbackFn != NULL) + { + hidInstance->outCallbackFn(hidInstance->outCallbackParam, transfer->transferBuffer, transfer->transferSofar, + status); /* callback to application */ + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +static void USB_HostHidControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param; + + hidInstance->controlTransfer = NULL; + if (hidInstance->controlCallbackFn != NULL) + { + hidInstance->controlCallbackFn(hidInstance->controlCallbackParam, transfer->transferBuffer, + transfer->transferSofar, status); /* callback to application */ + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +static usb_status_t USB_HostHidOpenInterface(usb_host_hid_instance_t *hidInstance) +{ + 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 (hidInstance->inPipe != NULL) /* close interrupt in pipe if it is open */ + { + status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->inPipe); + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when close pipe\r\n"); +#endif + } + hidInstance->inPipe = NULL; + } + if (hidInstance->outPipe != NULL) /* close interrupt out pipe if it is open */ + { + status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->outPipe); + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when close pipe\r\n"); +#endif + } + hidInstance->outPipe = NULL; + } + + /* open interface pipes */ + interfacePointer = (usb_host_interface_t *)hidInstance->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_INTERRUPT)) + { + pipeInit.devInstance = hidInstance->deviceHandle; + pipeInit.pipeType = USB_ENDPOINT_INTERRUPT; + 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 = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) & + USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK); + pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK; + + hidInstance->inPacketSize = pipeInit.maxPacketSize; + + status = USB_HostOpenPipe(hidInstance->hostHandle, &hidInstance->inPipe, &pipeInit); + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("USB_HostHidSetInterface 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_INTERRUPT)) + { + pipeInit.devInstance = hidInstance->deviceHandle; + pipeInit.pipeType = USB_ENDPOINT_INTERRUPT; + 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 = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) & + USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK); + pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK; + + hidInstance->outPacketSize = pipeInit.maxPacketSize; + + status = USB_HostOpenPipe(hidInstance->hostHandle, &hidInstance->outPipe, &pipeInit); + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("USB_HostHidSetInterface fail to open pipe\r\n"); +#endif + return kStatus_USB_Error; + } + } + else + { + } + } + + return kStatus_USB_Success; +} + +static void USB_HostHidSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param; + + hidInstance->controlTransfer = NULL; + if (status == kStatus_USB_Success) + { + status = USB_HostHidOpenInterface(hidInstance); /* hid open interface */ + } + + if (hidInstance->controlCallbackFn != NULL) + { + hidInstance->controlCallbackFn(hidInstance->controlCallbackParam, NULL, 0, + status); /* callback to application */ + } + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); +} + +usb_status_t USB_HostHidInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle) +{ + uint32_t infoValue; + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)USB_OsaMemoryAllocate( + sizeof(usb_host_hid_instance_t)); /* malloc hid class instance */ + + if (hidInstance == NULL) + { + return kStatus_USB_AllocFail; + } + + /* initialize hid instance */ + hidInstance->deviceHandle = deviceHandle; + hidInstance->interfaceHandle = NULL; + USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue); + hidInstance->hostHandle = (usb_host_handle)infoValue; + USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue); + hidInstance->controlPipe = (usb_host_pipe_handle)infoValue; + + *classHandle = hidInstance; + return kStatus_USB_Success; +} + +usb_status_t USB_HostHidSetInterface(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_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + usb_host_transfer_t *transfer; + + if (classHandle == NULL) + { + return kStatus_USB_InvalidParameter; + } + + hidInstance->interfaceHandle = interfaceHandle; + status = USB_HostOpenDeviceInterface(hidInstance->deviceHandle, + interfaceHandle); /* notify host driver the interface is open */ + if (status != kStatus_USB_Success) + { + return status; + } + + /* cancel transfers */ + if (hidInstance->inPipe != NULL) + { + status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->inPipe, NULL); + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when cancel pipe\r\n"); +#endif + } + } + if (hidInstance->outPipe != NULL) + { + status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->outPipe, NULL); + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when cancel pipe\r\n"); +#endif + } + } + + if (alternateSetting == 0) /* open interface directly */ + { + if (callbackFn != NULL) + { + status = USB_HostHidOpenInterface(hidInstance); + callbackFn(callbackParam, NULL, 0, status); + } + } + else /* send setup transfer */ + { + /* malloc one transfer */ + if (USB_HostMallocTransfer(hidInstance->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 */ + hidInstance->controlCallbackFn = callbackFn; + hidInstance->controlCallbackParam = callbackParam; + /* initialize transfer */ + transfer->callbackFn = USB_HostHidSetInterfaceCallback; + transfer->callbackParam = hidInstance; + 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 *)hidInstance->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(hidInstance->hostHandle, hidInstance->controlPipe, transfer); + + if (status == kStatus_USB_Success) + { + hidInstance->controlTransfer = transfer; + } + else + { + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + } + } + + return status; +} + +usb_status_t USB_HostHidDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle) +{ + usb_status_t status; + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + + if (deviceHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + if (classHandle != NULL) /* class instance has initialized */ + { + if (hidInstance->inPipe != NULL) + { + status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->inPipe, NULL); /* cancel pipe */ + status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->inPipe); /* close pipe */ + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when close pipe\r\n"); +#endif + } + hidInstance->inPipe = NULL; + } + if (hidInstance->outPipe != NULL) + { + status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->outPipe, NULL); /* cancel pipe */ + status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->outPipe); /* close pipe */ + + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when close pipe\r\n"); +#endif + } + hidInstance->outPipe = NULL; + } + if ((hidInstance->controlPipe != NULL) && + (hidInstance->controlTransfer != NULL)) /* cancel control transfer if there is on-going control transfer */ + { + status = + USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->controlPipe, hidInstance->controlTransfer); + } + USB_HostCloseDeviceInterface(deviceHandle, + hidInstance->interfaceHandle); /* notify host driver the interface is closed */ + USB_OsaMemoryFree(hidInstance); + } + else + { + USB_HostCloseDeviceInterface(deviceHandle, NULL); + } + + return kStatus_USB_Success; +} + +uint16_t USB_HostHidGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + if (classHandle == NULL) + { + return 0; + } + + if (pipeType == USB_ENDPOINT_INTERRUPT) + { + if (direction == USB_IN) + { + return hidInstance->inPacketSize; + } + else + { + return hidInstance->outPacketSize; + } + } + + return 0; +} + +usb_status_t USB_HostHidRecv(usb_host_class_handle classHandle, + uint8_t *buffer, + uint32_t bufferLength, + transfer_callback_t callbackFn, + void *callbackParam) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + usb_host_transfer_t *transfer; + + if (classHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + if (hidInstance->inPipe == NULL) + { + return kStatus_USB_Error; + } + + /* malloc one transfer */ + if (USB_HostMallocTransfer(hidInstance->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 */ + hidInstance->inCallbackFn = callbackFn; + hidInstance->inCallbackParam = callbackParam; + /* initialize transfer */ + transfer->transferBuffer = buffer; + transfer->transferLength = bufferLength; + transfer->callbackFn = USB_HostHidInPipeCallback; + transfer->callbackParam = hidInstance; + + if (USB_HostRecv(hidInstance->hostHandle, hidInstance->inPipe, transfer) != + kStatus_USB_Success) /* call host driver api */ + { +#ifdef HOST_ECHO + usb_echo("failt to USB_HostRecv\r\n"); +#endif + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + return kStatus_USB_Error; + } + + return kStatus_USB_Success; +} + +usb_status_t USB_HostHidSend(usb_host_class_handle classHandle, + uint8_t *buffer, + uint32_t bufferLength, + transfer_callback_t callbackFn, + void *callbackParam) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + usb_host_transfer_t *transfer; + + if (classHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + if (hidInstance->outPipe == NULL) + { + return kStatus_USB_Error; + } + + /* malloc one transfer */ + if (USB_HostMallocTransfer(hidInstance->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 */ + hidInstance->outCallbackFn = callbackFn; + hidInstance->outCallbackParam = callbackParam; + /* initialize transfer */ + transfer->transferBuffer = buffer; + transfer->transferLength = bufferLength; + transfer->callbackFn = USB_HostHidOutPipeCallback; + transfer->callbackParam = hidInstance; + + if (USB_HostSend(hidInstance->hostHandle, hidInstance->outPipe, transfer) != + kStatus_USB_Success) /* call host driver api */ + { +#ifdef HOST_ECHO + usb_echo("failt to USB_HostSend\r\n"); +#endif + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + return kStatus_USB_Error; + } + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostHidControl(usb_host_class_handle classHandle, + uint8_t requestType, + uint8_t request, + uint8_t wvalueL, + uint8_t wvalueH, + uint16_t wlength, + uint8_t *data, + transfer_callback_t callbackFn, + void *callbackParam) +{ + usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle; + usb_host_transfer_t *transfer; + + if (classHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + /* malloc one transfer */ + if (USB_HostMallocTransfer(hidInstance->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 */ + hidInstance->controlCallbackFn = callbackFn; + hidInstance->controlCallbackParam = callbackParam; + /* initialize transfer */ + transfer->transferBuffer = data; + transfer->transferLength = wlength; + transfer->callbackFn = USB_HostHidControlCallback; + transfer->callbackParam = hidInstance; + transfer->setupPacket.bmRequestType = requestType; + transfer->setupPacket.bRequest = request; + transfer->setupPacket.wValue = (wvalueL | (uint16_t)((uint16_t)wvalueH << 8)); + transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN( + ((usb_host_interface_t *)hidInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber); + transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength); + + if (USB_HostSendSetup(hidInstance->hostHandle, hidInstance->controlPipe, transfer) != + kStatus_USB_Success) /* call host driver api */ + { +#ifdef HOST_ECHO + usb_echo("failt for USB_HostSendSetup\r\n"); +#endif + USB_HostFreeTransfer(hidInstance->hostHandle, transfer); + return kStatus_USB_Error; + } + hidInstance->controlTransfer = transfer; + + return kStatus_USB_Success; +} + +usb_status_t USB_HostHidGetReportDescriptor(usb_host_class_handle classHandle, + uint8_t *buffer, + uint16_t buffer_len, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0, USB_DESCRIPTOR_TYPE_HID_REPORT, buffer_len, buffer, callbackFn, + callbackParam); +} + +usb_status_t USB_HostHidGetIdle(usb_host_class_handle classHandle, + uint8_t reportId, + uint8_t *idleRate, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_GET_IDLE, reportId, 0, 1, idleRate, callbackFn, callbackParam); +} + +usb_status_t USB_HostHidSetIdle(usb_host_class_handle classHandle, + uint8_t reportId, + uint8_t idleRate, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_SET_IDLE, reportId, idleRate, 0, NULL, callbackFn, callbackParam); +} + +usb_status_t USB_HostHidGetProtocol(usb_host_class_handle classHandle, + uint8_t *protocol, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_GET_PROTOCOL, 0, 0, 1, protocol, callbackFn, callbackParam); +} + +usb_status_t USB_HostHidSetProtocol(usb_host_class_handle classHandle, + uint8_t protocol, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_SET_PROTOCOL, protocol, 0, 0, NULL, callbackFn, callbackParam); +} + +usb_status_t USB_HostHidGetReport(usb_host_class_handle classHandle, + uint8_t reportId, + uint8_t reportType, + uint8_t *buffer, + uint32_t bufferLength, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_GET_REPORT, reportId, reportType, bufferLength, buffer, callbackFn, callbackParam); +} + +usb_status_t USB_HostHidSetReport(usb_host_class_handle classHandle, + uint8_t reportId, + uint8_t reportType, + uint8_t *buffer, + uint32_t bufferLength, + transfer_callback_t callbackFn, + void *callbackParam) +{ + return USB_HostHidControl( + classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE, + USB_HOST_HID_SET_REPORT, reportId, reportType, bufferLength, buffer, callbackFn, callbackParam); +} + +#endif /* USB_HOST_CONFIG_HID */ -- cgit v1.2.3