/* * UART routines of Cypress USB Serial * Copyright (C) 2013 Cypress Semiconductor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "CyUSBCommon.h" #pragma pack(1) typedef struct { CY_UART_BAUD_RATE baudRate; UINT8 pinType; UINT8 dataWidth; UINT8 stopBits; UINT8 mode; UINT8 parity; UINT8 isMsbFirst; UINT8 txRetry;; UINT8 rxInvertPolarity; UINT8 rxIgnoreError; UINT8 isFlowControl; UINT8 isLoopBack; UINT8 flags; }CyUsUartConfig_t; #pragma pack() #define MAX_DEVICE_EP_SIZE 64 /* There is no way in the current library architecture Data Queue size can exceed 4 Max EP size Pages. */ #define NO_DATA_QUEUE_PAGES 4 #define NUM_MAX_UART_SCB 2 typedef struct dtQueue{ UINT8 cyDataQueue[NO_DATA_QUEUE_PAGES * MAX_DEVICE_EP_SIZE]; UINT8 pHeadPosition; UINT8 pTailPosition; UINT16 nTotalAvailableData; }CyDataQueue; CyDataQueue gSimpleDataQueue[NUM_MAX_UART_SCB]; //Timer helper functions for proper timing UINT32 getUartLapsedTime (struct timeval startTime){ signed int currentTime_sec, currentTime_usec, currentTime; struct timeval endTime; gettimeofday (&endTime, NULL); currentTime_sec = (endTime.tv_sec - startTime.tv_sec) * 1000; currentTime_usec = ((endTime.tv_usec - startTime.tv_usec)) / 1000; currentTime = currentTime_sec + currentTime_usec; return (unsigned int)currentTime; } // Queue Helper Functions.... void GetDataFromTheQueue( UINT8 scbIndex, PCY_DATA_BUFFER cyDataBuffer ) { UINT16 headPos = gSimpleDataQueue[scbIndex].pHeadPosition; UINT16 nCheckForWrapAround = 0; UINT8* buffer = &gSimpleDataQueue[scbIndex].cyDataQueue[headPos]; UINT16 nMaxBufferSize = (NO_DATA_QUEUE_PAGES * MAX_DEVICE_EP_SIZE); // Parameter Validation. if (gSimpleDataQueue[scbIndex].nTotalAvailableData == 0 ) return; // No data in the queue to return. // Is there any Memory space in the queue to add more. if (gSimpleDataQueue[scbIndex].pHeadPosition == gSimpleDataQueue[scbIndex].pTailPosition ) return; // Is this Invalid Parameters? if (scbIndex > 1 || cyDataBuffer == NULL || cyDataBuffer->length == 0) return; // Now make the transfer from the queue. if (cyDataBuffer->length >= gSimpleDataQueue[scbIndex].nTotalAvailableData ) { nCheckForWrapAround = (gSimpleDataQueue[scbIndex].pHeadPosition + gSimpleDataQueue[scbIndex].nTotalAvailableData); // Copy the data. if (nCheckForWrapAround <= nMaxBufferSize ) { memcpy(cyDataBuffer->buffer, buffer, gSimpleDataQueue[scbIndex].nTotalAvailableData); cyDataBuffer->transferCount = gSimpleDataQueue[scbIndex].nTotalAvailableData; } else { // Queue Wrap around occurred. UINT16 bufferLen1 = nMaxBufferSize - (gSimpleDataQueue[scbIndex].pHeadPosition); UINT16 bufferLen2 = gSimpleDataQueue[scbIndex].pTailPosition; memcpy(cyDataBuffer->buffer, buffer, bufferLen1); buffer = &gSimpleDataQueue[scbIndex].cyDataQueue[0]; memcpy(cyDataBuffer->buffer+bufferLen1, buffer, bufferLen2); cyDataBuffer->transferCount = (bufferLen1 + bufferLen2); } // Reset the queue. gSimpleDataQueue[scbIndex].pHeadPosition = 0; gSimpleDataQueue[scbIndex].pTailPosition = 0; gSimpleDataQueue[scbIndex].nTotalAvailableData = 0; return; } // Here the available data buffer length is more than the requested // transfer size. nCheckForWrapAround = (gSimpleDataQueue[scbIndex].pHeadPosition + cyDataBuffer->length); // Copy the data. if (nCheckForWrapAround <= nMaxBufferSize ) { memcpy(cyDataBuffer->buffer, buffer, cyDataBuffer->length); cyDataBuffer->transferCount = cyDataBuffer->length; gSimpleDataQueue[scbIndex].pHeadPosition += cyDataBuffer->length; } else { // Queue Wrap around occurred. UINT16 bufferLen1 = nMaxBufferSize - (gSimpleDataQueue[scbIndex].pHeadPosition); UINT16 bufferLen2 = cyDataBuffer->length - bufferLen1; memcpy(cyDataBuffer->buffer, buffer, bufferLen1); buffer = &gSimpleDataQueue[scbIndex].cyDataQueue[0]; memcpy(cyDataBuffer->buffer+bufferLen1, buffer, bufferLen2); cyDataBuffer->transferCount = (bufferLen1 + bufferLen2); gSimpleDataQueue[scbIndex].pHeadPosition = (UINT8)bufferLen2; } gSimpleDataQueue[scbIndex].nTotalAvailableData -= cyDataBuffer->length; } void AddDataToQueue( UINT8 scbIndex, UINT8* buffer, UINT8 length ) { UINT16 tailPos = gSimpleDataQueue[scbIndex].pTailPosition; UINT8* bufQueue = &gSimpleDataQueue[scbIndex].cyDataQueue[tailPos]; UINT16 nMaxBufferSize = (NO_DATA_QUEUE_PAGES * MAX_DEVICE_EP_SIZE); // Parameter Validation. if (gSimpleDataQueue[scbIndex].nTotalAvailableData >= nMaxBufferSize ) return; // No space in the queue. // Is this Invalid Parameters? if (scbIndex > 1 || buffer == NULL || length == 0) return; // Can this new data addition happens? if ( (gSimpleDataQueue[scbIndex].nTotalAvailableData + length) > nMaxBufferSize ) return; if ((tailPos + length) <= nMaxBufferSize ) { // Queue doesn't need wrap around for this new data addition. memcpy(bufQueue, buffer, length); gSimpleDataQueue[scbIndex].nTotalAvailableData += length; gSimpleDataQueue[scbIndex].pTailPosition += length; return; } else { // Queue Wrap around occurred. UINT16 bufferLen1 = nMaxBufferSize - (gSimpleDataQueue[scbIndex].pTailPosition); UINT16 bufferLen2 = length - bufferLen1; memcpy(bufQueue, buffer, bufferLen1); bufQueue = &gSimpleDataQueue[scbIndex].cyDataQueue[0]; memcpy(bufQueue, buffer+bufferLen1, bufferLen2); gSimpleDataQueue[scbIndex].pTailPosition = (UINT8)bufferLen2; gSimpleDataQueue[scbIndex].nTotalAvailableData += length; } } /* This API gets the current UART configuration of the device.Such as GPIO's assigned, flowcontrol, BaudRate etc. */ CY_RETURN_STATUS CyGetUartConfig ( CY_HANDLE handle, PCY_UART_CONFIG uartConfig ) { UINT16 wValue, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus; CY_DEVICE *device; CyUsUartConfig_t localUartConfig; libusb_device_handle *devHandle; UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT; UINT8 scbIndex = 0; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if (uartConfig == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameter..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } if (device->interfaceNum > 0) scbIndex = 1; bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; bmRequest = CY_UART_GET_CONFIG_CMD; wValue = (scbIndex << CY_SCB_INDEX_POS); wIndex = 0; wLength = CY_UART_CONFIG_LEN; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, (unsigned char*)&localUartConfig, wLength, ioTimeout); //Since we are not exposing all the configuration elements //parse and fill only relevant elements. if (rStatus == CY_UART_CONFIG_LEN){ uartConfig->dataWidth = localUartConfig.dataWidth; uartConfig->baudRate = localUartConfig.baudRate; uartConfig->stopBits = localUartConfig.stopBits; uartConfig->parityMode = (CY_UART_PARITY_MODE)localUartConfig.parity;; uartConfig->isDropOnRxErrors = localUartConfig.rxIgnoreError; //We are currently ignoring rest of the bits CY_DEBUG_PRINT_INFO ("CY:Successfully read UART Config\n"); return CY_SUCCESS; } else{ CY_DEBUG_PRINT_ERROR ("CY:Error in reading UART config ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } } /* This API sets the current UART configuration of the device.Such as GPIO's assigned, flowcontrol, BaudRate etc. */ CY_RETURN_STATUS CySetUartConfig ( CY_HANDLE handle, CY_UART_CONFIG *uartConfig ) { UINT16 wValue, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus; CyUsUartConfig_t localUartConfig; CY_DEVICE *device; libusb_device_handle *devHandle; UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT; UINT8 scbIndex = 0; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if (uartConfig == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameter..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } if (uartConfig->dataWidth < 7 || uartConfig->dataWidth > 8){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameter..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } if (uartConfig->stopBits < 1 || uartConfig->stopBits > 2){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameter..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->interfaceNum > 0) scbIndex = 1; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; bmRequest = CY_UART_SET_CONFIG_CMD; wValue = (scbIndex << CY_SCB_INDEX_POS); wIndex = 0; wLength = CY_UART_CONFIG_LEN; memset(&gSimpleDataQueue[scbIndex], 0, sizeof(CyDataQueue)); memset (&localUartConfig, 0, CY_UART_CONFIG_LEN); //Fill in rest of the UART config structure elements //that are not exposed in API with default values localUartConfig.baudRate = uartConfig->baudRate; localUartConfig.dataWidth = uartConfig->dataWidth; localUartConfig.stopBits = uartConfig->stopBits; localUartConfig.parity = (UCHAR) uartConfig->parityMode; localUartConfig.rxIgnoreError = uartConfig->isDropOnRxErrors; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, (unsigned char*)&localUartConfig, wLength, ioTimeout); if (rStatus == CY_UART_CONFIG_LEN){ CY_DEBUG_PRINT_INFO ("CY:Successfully Set UART Config \n"); return CY_SUCCESS; } else{ CY_DEBUG_PRINT_ERROR ("CY:Error in Setting UART config ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } } /* This Api writes the Data to UART block of the device. */ CY_RETURN_STATUS CyUartWrite ( CY_HANDLE handle, CY_DATA_BUFFER* writeBuffer, unsigned int ioTimeOut ) { int rStatus; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if ((writeBuffer == NULL) || (writeBuffer->buffer == NULL) || (writeBuffer->length == 0)){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameters..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } writeBuffer->transferCount = 0; device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } rStatus = libusb_bulk_transfer (devHandle, device->outEndpoint, writeBuffer->buffer, writeBuffer->length, (int *)&((writeBuffer->transferCount)), ioTimeOut); if ((rStatus == CY_SUCCESS)) { CY_DEBUG_PRINT_INFO ("CY: SuccessFull in Wrting Data,%d bytes were transfered \n", (writeBuffer->transferCount)); return CY_SUCCESS; } else if (rStatus == LIBUSB_ERROR_TIMEOUT){ CY_DEBUG_PRINT_ERROR ("CY:TimeOut error ...Function is %s\n", __func__); return CY_ERROR_IO_TIMEOUT; } else if (rStatus == LIBUSB_ERROR_PIPE){ CY_DEBUG_PRINT_ERROR ("CY:Pipe error endpoint Halted ...Function is %s\n", __func__); CyResetPipe (handle, device->outEndpoint); return CY_ERROR_PIPE_HALTED; } else if (rStatus == LIBUSB_ERROR_OVERFLOW){ CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow occured ...Function is %s\n", __func__); return CY_ERROR_BUFFER_OVERFLOW; } else if (rStatus == LIBUSB_ERROR_NO_DEVICE) { CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected .... Function is %s\n", __func__); return CY_ERROR_DEVICE_NOT_FOUND; } else { CY_DEBUG_PRINT_ERROR ("CY: Unknown error ....Libusb error is %d Function is %s\n", rStatus, __func__); return CY_ERROR_REQUEST_FAILED; } } /* This Api Reads the Data from UART block of the device. */ CY_RETURN_STATUS CyUartRead ( CY_HANDLE handle, CY_DATA_BUFFER* readBuffer, unsigned int ioTimeOut ) { int rStatus; CY_DEVICE *device; libusb_device_handle *devHandle; UINT32 length, totalRead = 0, newIoTimeout = ioTimeOut, elapsedTime; int transferCount; UCHAR *buffer; struct timeval startTime; UINT8 scbIndex = 0; UINT8 cyTempBuffer[64]; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if ((readBuffer == NULL) || (readBuffer->buffer == NULL) || (readBuffer->length == 0)){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameters..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } length = readBuffer->length; device = (CY_DEVICE *)handle; devHandle = device->devHandle; readBuffer->transferCount = 0; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } if (device->interfaceNum > 0) scbIndex = 1; if (gSimpleDataQueue[scbIndex].nTotalAvailableData > 0 ) { // We already have the data read from the device. // Provide this data to the API. GetDataFromTheQueue(scbIndex, readBuffer); if (readBuffer->length == readBuffer->transferCount) return CY_SUCCESS; totalRead = readBuffer->transferCount; length = (length - totalRead); } //Collect all the data in low baud rate for uart. As we get data in short packet do { // buffer will be pointing to new pointer buffer = &(readBuffer->buffer[totalRead]); //Start the tick gettimeofday(&startTime, NULL); rStatus = libusb_bulk_transfer (devHandle, device->inEndpoint, cyTempBuffer, MAX_DEVICE_EP_SIZE, &transferCount, newIoTimeout); elapsedTime = getUartLapsedTime(startTime); //Get the new timeout. newIoTimeout = newIoTimeout - elapsedTime; if (transferCount <= length ) { //Initialise totalRead to initially read + bytes returned now totalRead += transferCount; //length will initial length - transferCount length = (length - transferCount); memcpy(buffer, cyTempBuffer, transferCount); } else { totalRead += length; memcpy(buffer, cyTempBuffer, length); AddDataToQueue(scbIndex, cyTempBuffer+length, (transferCount - length)); length = 0; } }while ((rStatus == CY_SUCCESS) && (totalRead != readBuffer->length) && (newIoTimeout > 0)); if (newIoTimeout <= 0 && totalRead != readBuffer->length) rStatus = LIBUSB_ERROR_TIMEOUT; if (rStatus == CY_SUCCESS){ //CY_DUMP_DATA (readBuffer->buffer, readBuffer->transferCount); readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_INFO ("CY: SuccessFull in Reading Data,%d bytes were transfered \n", (readBuffer->transferCount)); return CY_SUCCESS; } else if (rStatus == LIBUSB_ERROR_TIMEOUT){ readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_ERROR ("CY:TimeOut error... Function is %s\n", __func__); return CY_ERROR_IO_TIMEOUT; } else if (rStatus == LIBUSB_ERROR_PIPE){ readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_ERROR ("CY:Pipe error endpoint Halted ...Function is %s\n", __func__); CyResetPipe (handle, device->inEndpoint); return CY_ERROR_PIPE_HALTED; } else if (rStatus == LIBUSB_ERROR_OVERFLOW){ readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow occured ...Function is %s\n", __func__); return CY_ERROR_BUFFER_OVERFLOW; } else if (rStatus == LIBUSB_ERROR_NO_DEVICE) { readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s\n", __func__); return CY_ERROR_DEVICE_NOT_FOUND; } else { readBuffer->transferCount = totalRead; CY_DEBUG_PRINT_ERROR ("CY: Unknown error ....Libusb error is %d Function is %s\n", rStatus, __func__); return CY_ERROR_REQUEST_FAILED; } } /* This Api sets the hardware flow control */ CY_RETURN_STATUS CyUartSetHwFlowControl ( CY_HANDLE handle, CY_FLOW_CONTROL_MODES mode ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if (mode < 0 || mode > 3){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_UART_SET_FLOW_CONTROL_CMD; wValue |= mode; wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus < 0){ CY_DEBUG_PRINT_ERROR ("CY:Error in setting uart flow control ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } device->uartFlowControlMode = mode; return CY_SUCCESS; } /* Api gets the current flow control mode */ CY_RETURN_STATUS CyUartGetHwFlowControl ( CY_HANDLE handle, CY_FLOW_CONTROL_MODES *mode ) { CY_DEVICE *device; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } if (mode == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid input parameters..Function is %s\n", __func__); return CY_ERROR_INVALID_PARAMETER; } device = (CY_DEVICE *)handle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } (*mode) = device->uartFlowControlMode; return CY_SUCCESS; } /* The API is used to break */ CYWINEXPORT CY_RETURN_STATUS CyUartSetBreak( CY_HANDLE handle, /*Valid handle to communicate with device*/ UINT16 timeout /*Break timeout value in milliseconds */ ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_UART_SEND_BREAK_CMD; wValue = timeout; wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus != LIBUSB_SUCCESS){ CY_DEBUG_PRINT_ERROR ("CY:Error in setting break ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } return CY_SUCCESS; } /* This Api sets the RTS UART pins High */ CY_RETURN_STATUS CyUartSetRts ( CY_HANDLE handle ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus; UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_SET_LINE_CONTROL_STATE_CMD; wValue |= (1 << 1) | (device->dtrValue); wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus == CY_SUCCESS){ device->rtsValue = 1; return CY_SUCCESS; } else { CY_DEBUG_PRINT_ERROR ("CY:Error in setting RTS of UART ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } } /* This Api clears the RTS UART pin and makes it low */ CY_RETURN_STATUS CyUartClearRts ( CY_HANDLE handle ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_SET_LINE_CONTROL_STATE_CMD; wValue = (device->dtrValue); wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus == CY_SUCCESS){ device->rtsValue = 0; return CY_SUCCESS; } else { CY_DEBUG_PRINT_ERROR ("CY:Error in clearing RTS of UART ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } } /* This Api sets the DTR UART pin High */ CY_RETURN_STATUS CyUartSetDtr ( CY_HANDLE handle ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_SET_LINE_CONTROL_STATE_CMD; wValue = ((device->rtsValue) << 1) | 1; wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus == CY_SUCCESS){ device->dtrValue = 1; return CY_SUCCESS; } else { CY_DEBUG_PRINT_ERROR ("CY:Error in setting DTR of UART ... Libusb Error is %d \n", rStatus); return CY_ERROR_REQUEST_FAILED; } } /* This Api clears the DTR UART pin and makes it low */ CY_RETURN_STATUS CyUartClearDtr ( CY_HANDLE handle ) { UINT16 wValue = 0, wIndex, wLength; UINT8 bmRequestType, bmRequest; int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ; CY_DEVICE *device; libusb_device_handle *devHandle; if (handle == NULL){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle..Function is %s\n", __func__); return CY_ERROR_INVALID_HANDLE; } device = (CY_DEVICE *)handle; devHandle = device->devHandle; if (device->deviceType != CY_TYPE_UART){ CY_DEBUG_PRINT_ERROR ("CY:Error invalid device type needs to be uart..Function is %s\n", __func__); return CY_ERROR_REQUEST_FAILED; } bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE; bmRequest = CY_SET_LINE_CONTROL_STATE_CMD; wValue = ((device->rtsValue) << 1); wIndex = device->interfaceNum; wLength = 0; rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, wValue, wIndex, NULL, wLength, ioTimeout); if (rStatus == CY_SUCCESS){ device->dtrValue = 0; return CY_SUCCESS; } else{ CY_DEBUG_PRINT_ERROR ("CY:Error in function %s... Libusb Error is %d \n",__func__, rStatus); return CY_ERROR_REQUEST_FAILED; } }