Initial commit
This commit is contained in:
5
CyUSBSerial_SDK_Linux/linux/library/90-cyusb.rules
Normal file
5
CyUSBSerial_SDK_Linux/linux/library/90-cyusb.rules
Normal file
@@ -0,0 +1,5 @@
|
||||
# Cypress USB driver for FX2 and FX3 (C) Cypress Semiconductor Corporation / ATR-LABS
|
||||
# Rules written by V. Radhakrishnan ( rk@atr-labs.com )
|
||||
# Cypress USB vendor ID = 0x04b4
|
||||
KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTR{idVendor}=="04b4", MODE="666"
|
||||
KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="remove", TAG=="cyusb_dev"
|
||||
222
CyUSBSerial_SDK_Linux/linux/library/CyUSBCommon.h
Normal file
222
CyUSBSerial_SDK_Linux/linux/library/CyUSBCommon.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Common header file 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include "../../common/header/CyUSBSerial.h"
|
||||
#ifdef __x86_64__
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#endif
|
||||
typedef struct CY_DEVICE {
|
||||
|
||||
unsigned char inEndpoint;
|
||||
unsigned char outEndpoint;
|
||||
unsigned char interruptEndpoint;
|
||||
unsigned char interfaceNum;
|
||||
bool i2cCancelEvent;
|
||||
bool spiCancelEvent;
|
||||
bool uartCancelEvent;
|
||||
bool rtsValue;
|
||||
bool dtrValue;
|
||||
unsigned short numEndpoints;
|
||||
CY_FLOW_CONTROL_MODES uartFlowControlMode;
|
||||
struct libusb_transfer *spiTransfer;
|
||||
struct libusb_transfer *uartTransfer;
|
||||
libusb_device_handle *devHandle;
|
||||
pthread_t spiThreadId;
|
||||
pthread_t uartThreadId;
|
||||
pthread_mutex_t readLock;
|
||||
pthread_mutex_t writeLock;
|
||||
pthread_mutex_t notificationLock;
|
||||
CY_DEVICE_TYPE deviceType;
|
||||
|
||||
}CY_DEVICE,*PCY_DEVICE;
|
||||
#pragma pack()
|
||||
|
||||
CY_RETURN_STATUS CyResetPipe (CY_HANDLE handl, UINT8);
|
||||
#define CY_DEBUG_PRINT_INFO(...) //User need to enable this
|
||||
#define CY_DEBUG_PRINT_ERROR(...) //printf
|
||||
#define DUMP_DATA 1
|
||||
#ifdef DUMP_DATA
|
||||
#define CY_DUMP_DATA(INPUT,LEN)\
|
||||
{\
|
||||
int i = 0, len = LEN;\
|
||||
while ((len)) {\
|
||||
printf ("%x ", (INPUT)[i++]);\
|
||||
len--;\
|
||||
}\
|
||||
printf ("\n");\
|
||||
}
|
||||
#else
|
||||
#define CY_DUMP_DATA (INPUT, LEN) do { }while (0);
|
||||
#endif
|
||||
#define CY_USB_SERIAL_TIMEOUT 5000
|
||||
#define CY_EVENT_NOTIFICATION_TIMEOUT 0 //This will make the transfer infinite
|
||||
|
||||
#define CY_VENDOR_REQUEST_DEVICE_TO_HOST 0xC0
|
||||
#define CY_VENDOR_REQUEST_HOST_TO_DEVICE 0x40
|
||||
|
||||
#define CY_CLASS_INTERFACE_REQUEST_DEVICE_TO_HOST 0XA1
|
||||
#define CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE 0x21
|
||||
//I2C related macros
|
||||
#define CY_SCB_INDEX_POS 15
|
||||
#define CY_I2C_CONFIG_LENGTH 16
|
||||
#define CY_I2C_WRITE_COMMAND_POS 3
|
||||
#define CY_I2C_WRITE_COMMAND_LEN_POS 4
|
||||
#define CY_I2C_GET_STATUS_LEN 3
|
||||
#define CY_I2C_MODE_WRITE 1
|
||||
#define CY_I2C_MODE_READ 0
|
||||
#define CY_I2C_ERROR_BIT (1)
|
||||
#define CY_I2C_ARBITRATION_ERROR_BIT (1 << 1)
|
||||
#define CY_I2C_NAK_ERROR_BIT (1 << 2)
|
||||
#define CY_I2C_BUS_ERROR_BIT (1 << 3)
|
||||
#define CY_I2C_STOP_BIT_ERROR (1 << 4)
|
||||
#define CY_I2C_BUS_BUSY_ERROR (1 << 5)
|
||||
#define CY_I2C_ENABLE_PRECISE_TIMING 1
|
||||
#define CY_I2C_EVENT_NOTIFICATION_LEN 3
|
||||
//SPI related Macros
|
||||
#define CY_SPI_CONFIG_LEN 16
|
||||
#define CY_SPI_EVENT_NOTIFICATION_LEN 2
|
||||
#define CY_SPI_READ_BIT (1)
|
||||
#define CY_SPI_WRITE_BIT (1 << 1)
|
||||
#define CY_SPI_SCB_INDEX_BIT (1 << 15)
|
||||
#define CY_SPI_GET_STATUS_LEN 4
|
||||
#define CY_SPI_UNDERFLOW_ERROR (1)
|
||||
#define CY_SPI_BUS_ERROR (1 << 1)
|
||||
//Vendor UART related macros
|
||||
#define CY_UART_SET_FLOW_CONTROL_CMD 0x60
|
||||
#define CY_UART_SEND_BREAK_CMD 0x23
|
||||
#define CY_UART_CONFIG_LEN 16
|
||||
#define CY_SET_LINE_CONTROL_STATE_CMD 0x22
|
||||
#define CY_UART_EVENT_NOTIFICATION_LEN 10
|
||||
|
||||
#define CY_UART_SERIAL_STATE_CARRIER_DETECT 1
|
||||
#define CY_UART_SERIAL_STATE_TRANSMISSION_CARRIER (1 << 1)
|
||||
#define CY_UART_SERIAL_STATE_BREAK_DETECTION (1<< 2)
|
||||
#define CY_UART_SERIAL_STATE_RING_SIGNAL_DETECTION (1 << 3)
|
||||
#define CY_UART_SERIAL_STATE_FRAMING_ERROR (1 << 4)
|
||||
#define CY_UART_SERIAL_STATE_PARITY_ERROR (1 << 5)
|
||||
#define CY_UART_SERIAL_STATUE_OVERRUN (1 << 6)
|
||||
//Bootloader related macros
|
||||
#define CY_BOOT_CONFIG_SIZE 64
|
||||
#define CY_DEVICE_CONFIG_SIZE 512
|
||||
#define CY_FIRMWARE_BREAKUP_SIZE 4096
|
||||
#define CY_GET_SILICON_ID_LEN 4
|
||||
#define CY_GET_FIRMWARE_VERSION_LEN 8
|
||||
#define CY_GET_SIGNATURE_LEN 4
|
||||
//PHDC related macros
|
||||
#define CY_PHDC_SET_FEATURE 0X03
|
||||
#define CY_PHDC_CLR_FEATURE 0X01
|
||||
#define CY_PHDC_GET_DATA_STATUS 0x00
|
||||
|
||||
typedef enum CY_VENDOR_CMDS
|
||||
{
|
||||
CY_GET_VERSION_CMD = 0xB0, /* Get the version of the boot-loader.
|
||||
value = 0, index = 0, length = 4;
|
||||
data_in = 32 bit version. */
|
||||
|
||||
CY_GET_SIGNATURE_CMD = 0xBD, /*Get the signature of the firmware
|
||||
It is suppose to be 'CYUS' for normal firmware
|
||||
and 'CYBL' for Bootloader.*/
|
||||
CY_UART_GET_CONFIG_CMD = 0xC0, /* Retreive the 16 byte UART configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_in = 16 byte configuration. */
|
||||
CY_UART_SET_CONFIG_CMD, /* Update the 16 byte UART configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_out = 16 byte configuration information. */
|
||||
CY_SPI_GET_CONFIG_CMD, /* Retreive the 16 byte SPI configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_in = 16 byte configuration. */
|
||||
CY_SPI_SET_CONFIG_CMD, /* Update the 16 byte SPI configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_out = 16 byte configuration information. */
|
||||
CY_I2C_GET_CONFIG_CMD, /* Retreive the 16 byte I2C configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_in = 16 byte configuration. */
|
||||
CY_I2C_SET_CONFIG_CMD = 0xC5, /* Update the 16 byte I2C configuration information.
|
||||
MS bit of value indicates the SCB index.
|
||||
length = 16, data_out = 16 byte configuration information. */
|
||||
CY_I2C_WRITE_CMD, /* Perform I2C write operation.
|
||||
value = bit0 - start, bit1 - stop, bit3 - start on idle,
|
||||
bits[14:8] - slave address, bit15 - scbIndex. length = 0. The
|
||||
data is provided over the bulk endpoints. */
|
||||
CY_I2C_READ_CMD, /* Perform I2C read operation.
|
||||
value = bit0 - start, bit1 - stop, bit2 - Nak last byte,
|
||||
bit3 - start on idle, bits[14:8] - slave address, bit15 - scbIndex,
|
||||
length = 0. The data is provided over the bulk endpoints. */
|
||||
CY_I2C_GET_STATUS_CMD, /* Retreive the I2C bus status.
|
||||
value = bit0 - 0: TX 1: RX, bit15 - scbIndex, length = 3,
|
||||
data_in = byte0: bit0 - flag, bit1 - bus_state, bit2 - SDA state,
|
||||
bit3 - TX underflow, bit4 - arbitration error, bit5 - NAK
|
||||
bit6 - bus error,
|
||||
byte[2:1] Data count remaining. */
|
||||
CY_I2C_RESET_CMD, /* The command cleans up the I2C state machine and frees the bus.
|
||||
value = bit0 - 0: TX path, 1: RX path; bit15 - scbIndex,
|
||||
length = 0. */
|
||||
CY_SPI_READ_WRITE_CMD = 0xCA, /* The command starts a read / write operation at SPI.
|
||||
value = bit 0 - RX enable, bit 1 - TX enable, bit 15 - scbIndex;
|
||||
index = length of transfer. */
|
||||
CY_SPI_RESET_CMD, /* The command resets the SPI pipes and allows it to receive new
|
||||
request.
|
||||
value = bit 15 - scbIndex */
|
||||
CY_SPI_GET_STATUS_CMD, /* The command returns the current transfer status. The count will match
|
||||
the TX pipe status at SPI end. For completion of read, read all data
|
||||
at the USB end signifies the end of transfer.
|
||||
value = bit 15 - scbIndex */
|
||||
CY_JTAG_ENABLE_CMD = 0xD0, /* Enable JTAG module */
|
||||
CY_JTAG_DISABLE_CMD, /* Disable JTAG module */
|
||||
CY_JTAG_READ_CMD, /* JTAG read vendor command */
|
||||
CY_JTAG_WRITE_CMD, /* JTAG write vendor command */
|
||||
CY_GPIO_GET_CONFIG_CMD = 0xD8, /* Get the GPIO configuration: */
|
||||
CY_GPIO_SET_CONFIG_CMD, /* Set the GPIO configuration */
|
||||
CY_GPIO_GET_VALUE_CMD, /* Get GPIO value: */
|
||||
CY_GPIO_SET_VALUE_CMD, /* Set the GPIO value:*/
|
||||
CY_PROG_USER_FLASH_CMD = 0xE0, /*Program user flash area. The total space available is 512 bytes.
|
||||
This can be accessed by the user from USB. The flash area
|
||||
address offset is from 0x0000 to 0x00200 and can be written to
|
||||
page wise (128 byte).*/
|
||||
CY_READ_USER_FLASH_CMD, /*Read user flash area. The total space available is 512 bytes.
|
||||
This can be accessed by the user from USB. The flash area
|
||||
address offset is from 0x0000 to 0x00200 and can be written to
|
||||
page wise (128 byte).*/
|
||||
CY_DEVICE_RESET_CMD = 0xE3, /*Performs a device reset from firmware*/
|
||||
|
||||
} CY_VENDOR_CMDS;
|
||||
|
||||
//JTAG related Macros
|
||||
#define CY_JTAG_OUT_EP 0x04
|
||||
#define CY_JTAG_IN_EP 0x85
|
||||
|
||||
//GPIO related Macros
|
||||
#define CY_GPIO_GET_LEN 2
|
||||
#define CY_GPIO_SET_LEN 1
|
||||
|
||||
//PHDC related macros
|
||||
#define CY_PHDC_GET_STATUS_LEN 2
|
||||
#define CY_PHDC_CLR_FEATURE_WVALUE 0x1
|
||||
#define CY_PHDC_SET_FEATURE_WVALUE 0x0101
|
||||
|
||||
18
CyUSBSerial_SDK_Linux/linux/library/Makefile
Normal file
18
CyUSBSerial_SDK_Linux/linux/library/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
all:
|
||||
gcc -fPIC -g -Wall -o libcyusb.o -c cyusb.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcyuart.o -c cyuart.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcyi2c.o -c cyi2c.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcyspi.o -c cyspi.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcyphdc.o -c cyphdc.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcyjtag.o -c cyjtag.c -I ../../common/header
|
||||
gcc -fPIC -g -Wall -o libcymisc.o -c cymisc.c -I ../../common/header
|
||||
gcc -shared -g -Wl,-soname,libcyusbserial.so -o libcyusbserial.so.1 libcyusb.o libcyuart.o libcyi2c.o libcyspi.o libcyphdc.o libcyjtag.o libcymisc.o -l usb-1.0
|
||||
cp libcyusbserial.so.1 /usr/local/lib
|
||||
ln -sf /usr/local/lib/libcyusbserial.so.1 /usr/local/lib/libcyusbserial.so
|
||||
ldconfig
|
||||
rm -f libcyusb.o libcyuart.o libcyspi.o libcyi2c.o libcyphdc.o libcyjtag.o libcymisc.o
|
||||
clean:
|
||||
rm -f libcyusbserial.so libcyusbserial.so.1
|
||||
help:
|
||||
@echo 'make would compile and create the library and create a link'
|
||||
@echo 'make clean would remove the library and the soft link to the library (soname)'
|
||||
29
CyUSBSerial_SDK_Linux/linux/library/README.txt
Normal file
29
CyUSBSerial_SDK_Linux/linux/library/README.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
========================================================================================
|
||||
Cypress Semiconductor Corporation
|
||||
CyUSB Serial library.
|
||||
=========================================================================================
|
||||
Pre-requisite:
|
||||
1. libusb-1.0.9 is required for compilation and functioning of the APIs in the library.
|
||||
2. GNU Make and the GCC tool-chain are used for the build process.
|
||||
|
||||
Installation steps:
|
||||
|
||||
1.cd to the main directory where library source files are extracted and type
|
||||
'sudo make'
|
||||
|
||||
2.This will generate shared library libcyusbserial.so.1 and its soft link libcyusbserial.so.
|
||||
Both of them will be copied/installed to /usr/local/lib.
|
||||
|
||||
3.Application can link and start using the library.
|
||||
|
||||
Changing USB device node permission:
|
||||
|
||||
**Note:
|
||||
By default the USB device node created in linux do not have read/write permission
|
||||
for normal user. In order to make the USB device node accessable, copy 90-cyusb.rules
|
||||
which is inside the library folder of release package to /etc/udev/rules.d folder (Default VID mentioned is Cypress VID
|
||||
which is 0x4B4, if VID is changed then update it in ATTR{idVendor} section of rules file).
|
||||
|
||||
|
||||
|
||||
|
||||
690
CyUSBSerial_SDK_Linux/linux/library/cyi2c.c
Normal file
690
CyUSBSerial_SDK_Linux/linux/library/cyi2c.c
Normal file
@@ -0,0 +1,690 @@
|
||||
/*
|
||||
* I2C 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
|
||||
{
|
||||
UINT32 frequency; /* Frequency of operation. Only valid values are
|
||||
100KHz and 400KHz. */
|
||||
UINT8 sAddress; /* Slave address to be used when in slave mode. */
|
||||
BOOL isMsbFirst; /* Whether to transmit most significant bit first. */
|
||||
BOOL isMaster; /* Whether to block is to be configured as a master:
|
||||
CyTrue - The block functions as I2C master;
|
||||
CyFalse - The block functions as I2C slave. */
|
||||
BOOL sIgnore; /* Ignore general call in slave mode. */
|
||||
BOOL clockStretch; /* Wheteher to stretch clock in case of no FIFO availability. */
|
||||
BOOL isLoopback; /* Whether to loop back TX data to RX. Valid only
|
||||
for debug purposes. */
|
||||
UCHAR reserved[6]; /*Reserved for future use*/
|
||||
} CyUsI2cConfig_t;
|
||||
#pragma pack()
|
||||
#ifdef CY_I2C_ENABLE_PRECISE_TIMING
|
||||
struct timeval startTimeWrite, endTimeWrite, startTimeRead, endTimeRead;
|
||||
//Timer helper functions for proper timing
|
||||
void startI2cTick (bool isWrite) {
|
||||
if (isWrite)
|
||||
gettimeofday (&startTimeWrite, NULL);
|
||||
else
|
||||
gettimeofday (&startTimeRead, NULL);
|
||||
}
|
||||
|
||||
UINT32 getI2cLapsedTime (bool isWrite){
|
||||
|
||||
signed int currentTime_sec, currentTime_usec, currentTime;
|
||||
if (isWrite){
|
||||
gettimeofday (&endTimeWrite, NULL);
|
||||
currentTime_sec = (endTimeWrite.tv_sec - startTimeWrite.tv_sec) * 1000;
|
||||
currentTime_usec = ((endTimeWrite.tv_usec - startTimeWrite.tv_usec)) / 1000;
|
||||
currentTime = currentTime_sec + currentTime_usec;
|
||||
return (unsigned int)currentTime;
|
||||
}
|
||||
else{
|
||||
gettimeofday (&endTimeRead, NULL);
|
||||
currentTime_sec = (endTimeRead.tv_sec - startTimeRead.tv_sec) * 1000;
|
||||
currentTime_usec = ((endTimeRead.tv_usec - startTimeRead.tv_usec)) / 1000;
|
||||
currentTime = currentTime_sec + currentTime_usec;
|
||||
return (unsigned int)currentTime;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CY_RETURN_STATUS handleI2cError (UINT8 i2cStatus){
|
||||
|
||||
if (i2cStatus & CY_I2C_NAK_ERROR_BIT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Nacked by device ...Function is %s\n", __func__);
|
||||
return CY_ERROR_I2C_NAK_ERROR;
|
||||
}
|
||||
if (i2cStatus & CY_I2C_BUS_ERROR_BIT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error bus error occured... Function is %s\n", __func__);
|
||||
return CY_ERROR_I2C_BUS_ERROR;
|
||||
}
|
||||
if (i2cStatus & CY_I2C_ARBITRATION_ERROR_BIT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Arbitration error occured.. Function is %s\n", __func__);
|
||||
return CY_ERROR_I2C_ARBITRATION_ERROR;
|
||||
}
|
||||
if (i2cStatus & CY_I2C_STOP_BIT_ERROR){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Stop bit set by master..Function is %s\n", __func__);
|
||||
return CY_ERROR_I2C_STOP_BIT_SET;
|
||||
}
|
||||
else {
|
||||
//We should never hit this case!!!!
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Unknown error..Function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
//Used internally by read and write API to check if data is received at the I2C end.
|
||||
CY_RETURN_STATUS CyI2cGetStatus (CY_HANDLE handle, bool mode, UCHAR *i2cStatus);
|
||||
CY_RETURN_STATUS waitForNotification (CY_HANDLE handle, UINT16 *bytesPending, UINT32 ioTimeout);
|
||||
/*
|
||||
This API gets the current I2C config
|
||||
for the particluar interface of the device
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetI2cConfig (
|
||||
CY_HANDLE handle,
|
||||
CY_I2C_CONFIG *i2cConfig
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CyUsI2cConfig_t localI2cConfig;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
if (i2cConfig == NULL){
|
||||
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_I2C) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c ..Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_I2C_GET_CONFIG_CMD;
|
||||
wValue = (scbIndex << CY_SCB_INDEX_POS);
|
||||
wIndex = 0x00;
|
||||
wLength = CY_I2C_CONFIG_LENGTH;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)&localI2cConfig, wLength, ioTimeout);
|
||||
if (rStatus == CY_I2C_CONFIG_LENGTH){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Read I2C config ...size is %d \n", rStatus);
|
||||
i2cConfig->frequency = localI2cConfig.frequency;
|
||||
i2cConfig->slaveAddress = localI2cConfig.sAddress;
|
||||
i2cConfig->isMaster = localI2cConfig.isMaster;
|
||||
i2cConfig->isClockStretch = localI2cConfig.clockStretch;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
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 if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error time out ....Function is %s\n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in doing I2C read ...libusb error is %d function is %s!\n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API sets I2C config of the device for that
|
||||
interface
|
||||
*/
|
||||
CY_RETURN_STATUS CySetI2cConfig (
|
||||
CY_HANDLE handle,
|
||||
CY_I2C_CONFIG *i2cConfig
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
CyUsI2cConfig_t localI2cConfig;
|
||||
int rStatus;
|
||||
CY_DEVICE *device = NULL;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
if (i2cConfig == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (i2cConfig->frequency < 1000 || i2cConfig->frequency > 400000){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error frequency trying to set in out of ..range Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if ((i2cConfig->slaveAddress % 2) != 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error slave address needs to even..Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
scbIndex = device->interfaceNum;
|
||||
if (device->deviceType != CY_TYPE_I2C) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c ..Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_I2C_SET_CONFIG_CMD;
|
||||
wValue = (scbIndex << CY_SCB_INDEX_POS);
|
||||
wIndex = 0x00;
|
||||
wLength = CY_I2C_CONFIG_LENGTH;
|
||||
//We need to pass entire 16 bytes config structure to firmware
|
||||
//but we will not expose all the structure elements to user.
|
||||
//so filling some of the values.
|
||||
memset (&localI2cConfig, 0, CY_I2C_CONFIG_LENGTH);
|
||||
localI2cConfig.frequency = i2cConfig->frequency;
|
||||
localI2cConfig.sAddress = i2cConfig->slaveAddress;
|
||||
localI2cConfig.isMaster = i2cConfig->isMaster;
|
||||
localI2cConfig.clockStretch = i2cConfig->isClockStretch;
|
||||
localI2cConfig.isMsbFirst = 1;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)&localI2cConfig, wLength, ioTimeout);
|
||||
if (rStatus == CY_I2C_CONFIG_LENGTH){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Setting I2C config successful ...\n");
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
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 if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error time out ....Function is %s\n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in doing I2C read ...libusb error is %d function is %s!\n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API reads I2C data from the specified interface of the device
|
||||
interface
|
||||
*/
|
||||
CY_RETURN_STATUS CyI2cRead (
|
||||
CY_HANDLE handle,
|
||||
CY_I2C_DATA_CONFIG *i2cDataConfig,
|
||||
CY_DATA_BUFFER *readBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device = NULL;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue = 0, wIndex, wLength, bytesPending = 0;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
UCHAR i2cStatus[CY_I2C_GET_STATUS_LEN];
|
||||
UINT16 scbIndex = 0;
|
||||
bool mode = CY_I2C_MODE_READ;
|
||||
UINT32 elapsedTime;
|
||||
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 parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
readBuffer->transferCount = 0;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_I2C) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c ..Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (pthread_mutex_trylock (&device->readLock) == 0){
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
i2cDataConfig->slaveAddress = ((i2cDataConfig->slaveAddress & 0x7F) | (scbIndex << 7));
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_I2C_READ_CMD;
|
||||
wValue = ((i2cDataConfig->isStopBit) | (i2cDataConfig->isNakBit << 1));
|
||||
wValue |= (((i2cDataConfig->slaveAddress) << 8));
|
||||
wIndex = readBuffer->length;
|
||||
wLength = 0;
|
||||
rStatus = CyI2cGetStatus (handle, mode, (UCHAR *)i2cStatus);
|
||||
if (rStatus == CY_SUCCESS)
|
||||
{
|
||||
if ((i2cStatus[0] & CY_I2C_ERROR_BIT)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device busy ... function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return CY_ERROR_I2C_DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus == LIBUSB_ERROR_NO_DEVICE){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device disconnected ... \n");
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in sending Read vendor command ... Libusb Error is %d .. Function is %s \n", rStatus, __func__);
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return CY_ERROR_I2C_DEVICE_BUSY;
|
||||
}
|
||||
//Hoping that previous calls do not take much time!!
|
||||
#ifdef CY_I2C_ENABLE_PRECISE_TIMING
|
||||
startI2cTick(false);
|
||||
#endif
|
||||
rStatus = libusb_bulk_transfer (devHandle, device->inEndpoint, readBuffer->buffer, readBuffer->length,
|
||||
(int*)&readBuffer->transferCount, ioTimeout);
|
||||
#ifdef CY_I2C_ENABLE_PRECISE_TIMING
|
||||
elapsedTime = getI2cLapsedTime(false);
|
||||
//Giving an extra 10 msec to notification to findout the status
|
||||
ioTimeout = (ioTimeout - elapsedTime);
|
||||
if (ioTimeout == 0)
|
||||
ioTimeout = 10;
|
||||
#endif
|
||||
if (rStatus == LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Successfully read i2c data.. %d bytes Read ...\n", readBuffer->transferCount);
|
||||
bytesPending = readBuffer->length;
|
||||
rStatus = waitForNotification (handle, &bytesPending, ioTimeout);
|
||||
if (rStatus)
|
||||
readBuffer->transferCount = (readBuffer->length - bytesPending);
|
||||
else
|
||||
readBuffer->transferCount = readBuffer->length;
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return rStatus;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Timeout error ..Function is %s\n", __func__);
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_PIPE){
|
||||
CY_DEBUG_PRINT_INFO ("Pipe Error \n");
|
||||
rStatus = CyResetPipe (handle, device->outEndpoint);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("Error in reseting the pipe \n");
|
||||
}
|
||||
else
|
||||
CY_DEBUG_PRINT_INFO ("Reset pipe succeded \n");
|
||||
|
||||
rStatus = CyI2cGetStatus (handle, mode, (UCHAR *)i2cStatus);
|
||||
if (rStatus == CY_SUCCESS)
|
||||
{
|
||||
CyI2cReset (handle, mode);
|
||||
rStatus = handleI2cError (i2cStatus[0]);
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return rStatus;
|
||||
}
|
||||
else {
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
return CY_ERROR_I2C_DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_NO_DEVICE) {
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s\n", __func__);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error time out ....Function is %s\n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
pthread_mutex_unlock (&device->readLock);
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in doing I2C read ...libusb error is %d function is %s!\n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error API busy in servicing previous request... function is %s!\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API writes I2C data into the specified interface of the device
|
||||
*/
|
||||
CY_RETURN_STATUS CyI2cWrite (
|
||||
CY_HANDLE handle,
|
||||
CY_I2C_DATA_CONFIG *i2cDataConfig,
|
||||
CY_DATA_BUFFER *writeBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
UCHAR i2cStatus[CY_I2C_GET_STATUS_LEN];
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue = 0, wIndex, wLength, bytesPending = 0;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
UINT16 scbIndex = 0;
|
||||
BOOL mode = CY_I2C_MODE_WRITE;
|
||||
UINT32 elapsedTime;
|
||||
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 parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
writeBuffer->transferCount = 0;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
scbIndex = device->interfaceNum;
|
||||
if (device->deviceType != CY_TYPE_I2C){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c ..Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (pthread_mutex_trylock (&device->writeLock) == 0){
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_I2C_WRITE_CMD;
|
||||
i2cDataConfig->slaveAddress = ((i2cDataConfig->slaveAddress & 0x7F) | (scbIndex << 7));
|
||||
wValue = ((i2cDataConfig->isStopBit));
|
||||
wValue |= (((i2cDataConfig->slaveAddress) << 8));
|
||||
wIndex = (UINT16)(writeBuffer->length);
|
||||
wLength = 0;
|
||||
CY_DEBUG_PRINT_INFO ("wValue is %x \n", wValue);
|
||||
//Send I2C write vendor command before actually sending the data over bulk ep
|
||||
rStatus = CyI2cGetStatus (handle, mode, (UCHAR *)i2cStatus);
|
||||
if (rStatus == CY_SUCCESS)
|
||||
{
|
||||
if ((i2cStatus[0] & CY_I2C_ERROR_BIT)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Device busy ... function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_I2C_DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_NO_DEVICE){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device not found \n");
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus == LIBUSB_ERROR_NO_DEVICE){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device not found \n");
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in sending write vendor command ... Libusb Error is %d \n", rStatus);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_I2C_DEVICE_BUSY;
|
||||
}
|
||||
//After vendor command is sent send the actual data to be sent to i2c devic
|
||||
#ifdef CY_I2C_ENABLE_PRECISE_TIMING
|
||||
startI2cTick(true);
|
||||
#endif
|
||||
rStatus = libusb_bulk_transfer (devHandle, device->outEndpoint, writeBuffer->buffer, writeBuffer->length,
|
||||
(int*)&(writeBuffer->transferCount), ioTimeout);
|
||||
#ifdef CY_I2C_ENABLE_PRECISE_TIMING
|
||||
elapsedTime = getI2cLapsedTime(true);
|
||||
ioTimeout = (ioTimeout - elapsedTime);
|
||||
//Giving an extra 10 msec to notification to findout the status
|
||||
if (ioTimeout == 0)
|
||||
ioTimeout = 10;
|
||||
#endif
|
||||
//Once the data is sent to usbserial, check if it was actually written to i2c device.
|
||||
if (rStatus == LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Successfully written i2c data.. %d bytes written ...\n", writeBuffer->transferCount);
|
||||
bytesPending = writeBuffer->length;
|
||||
rStatus = waitForNotification (handle, &bytesPending, ioTimeout);
|
||||
if (rStatus)
|
||||
writeBuffer->transferCount = (writeBuffer->length - bytesPending);
|
||||
else
|
||||
writeBuffer->transferCount = writeBuffer->length;
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return rStatus;
|
||||
}
|
||||
//Transaction is stallled when we hit some I2C error while the transfer
|
||||
//was going on. After we hit this error clear stall and check why we hit this by
|
||||
//CyGetStatus.
|
||||
else if (rStatus == LIBUSB_ERROR_PIPE){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Pipe Error ... Function is %s\n", __func__);
|
||||
rStatus = CyResetPipe (handle, device->outEndpoint);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in reseting the pipe ..Function is %s\n", __func__);
|
||||
}
|
||||
else
|
||||
CY_DEBUG_PRINT_INFO ("Reset pipe succeded \n");
|
||||
|
||||
rStatus = CyI2cGetStatus (handle, mode, (UCHAR *)i2cStatus);
|
||||
if (rStatus == CY_SUCCESS)
|
||||
{
|
||||
CyI2cReset (handle, mode);
|
||||
rStatus = handleI2cError (i2cStatus[0]);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return rStatus;
|
||||
}
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_NO_DEVICE) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s\n", __func__);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error time out ....Function is %s\n", __func__);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in doing I2C read ...libusb error is %d function is %s!\n", rStatus, __func__);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY:API busy with servicing previous request... function is %s!\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
/*
|
||||
This Api gets the current status of the I2C data transaction
|
||||
*/
|
||||
CY_RETURN_STATUS CyI2cGetStatus (
|
||||
CY_HANDLE handle,
|
||||
bool mode,
|
||||
UCHAR *i2cStatus
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength, bmRequestType, bmRequest;;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
if (i2cStatus == NULL)
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_I2C) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c .. \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_I2C_GET_STATUS_CMD;
|
||||
wValue = ((scbIndex << CY_SCB_INDEX_POS) | mode);
|
||||
wIndex = 0;
|
||||
wLength = CY_I2C_GET_STATUS_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, (UCHAR*)i2cStatus, wLength, ioTimeout);
|
||||
if (rStatus < CY_I2C_GET_STATUS_LEN){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Error in sending I2C Get Status command...Libusb error is %d\n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
This Api resets the I2C module
|
||||
*/
|
||||
CY_RETURN_STATUS CyI2cReset (
|
||||
CY_HANDLE handle,
|
||||
BOOL resetMode
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength, bmRequestType, bmRequest;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_I2C) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not i2c .. \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_I2C_RESET_CMD;
|
||||
wValue = ((scbIndex << CY_SCB_INDEX_POS) | resetMode );
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in sending I2C Reset command ..libusb error is %d\n", rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
static void LIBUSB_CALL i2c_notification_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
UINT32 *completed = transfer->user_data;
|
||||
*completed = 1;
|
||||
}
|
||||
|
||||
CY_RETURN_STATUS waitForNotification (CY_HANDLE handle, UINT16 *bytesPending, UINT32 ioTimeout){
|
||||
|
||||
UINT32 transferCompleted = 0, length = CY_I2C_EVENT_NOTIFICATION_LEN;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
struct libusb_transfer *transfer;
|
||||
CY_RETURN_STATUS errorStatus, rStatus;
|
||||
UCHAR i2cStatus[CY_I2C_EVENT_NOTIFICATION_LEN];
|
||||
struct timeval time;
|
||||
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
transfer = libusb_alloc_transfer(0);
|
||||
if (transfer == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in allocating trasnfer \n");
|
||||
errorStatus = CY_ERROR_ALLOCATION_FAILED;
|
||||
(*bytesPending) = 0;
|
||||
return errorStatus;
|
||||
//callbackFn (errorStatus, 0);
|
||||
}
|
||||
libusb_fill_interrupt_transfer (transfer, devHandle, device->interruptEndpoint, i2cStatus, length,
|
||||
i2c_notification_cb, &transferCompleted, ioTimeout);
|
||||
if (libusb_submit_transfer (transfer)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in submitting interrupt transfer ...\n");
|
||||
libusb_cancel_transfer (transfer);
|
||||
libusb_free_transfer (transfer);
|
||||
(*bytesPending) = 0;
|
||||
//callbackFn (CY_ERROR_REQUEST_FAILED, 0);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
time.tv_sec = 0;
|
||||
time.tv_usec = 50;//polling timeout.
|
||||
while (transferCompleted == 0){
|
||||
libusb_handle_events_timeout (NULL, &time);
|
||||
}
|
||||
transferCompleted = 0;
|
||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Info successfully recieved data on interrupt pipe length is %d \n", transfer->actual_length);
|
||||
if (i2cStatus[0] & 0x80){ //Error notification is for write
|
||||
if ((i2cStatus[0] & CY_I2C_ERROR_BIT)){
|
||||
CY_DEBUG_PRINT_INFO ("Bytes pending is %x %x %x", i2cStatus[0], i2cStatus[1], i2cStatus[2]);
|
||||
if (i2cStatus[0] & 0x1E){
|
||||
//There was some error, so reset the i2c module and usb module
|
||||
//of the device, so branch out of the loop(Check below for the errors reported).
|
||||
rStatus = CyI2cReset (device, CY_I2C_MODE_WRITE);
|
||||
if (rStatus != CY_SUCCESS)
|
||||
CY_DEBUG_PRINT_INFO ("CY:i2c reset failed \n");
|
||||
//Report the amount of byte that were actually written
|
||||
memcpy(bytesPending, &i2cStatus[1], 2);
|
||||
errorStatus = handleI2cError (i2cStatus[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
errorStatus = CY_SUCCESS;
|
||||
}
|
||||
else //Error notification is for read
|
||||
{
|
||||
if ((i2cStatus[0] & CY_I2C_ERROR_BIT)){
|
||||
CY_DEBUG_PRINT_INFO ("Bytes pending is %x %x %x", i2cStatus[0], i2cStatus[1], i2cStatus[2]);
|
||||
if (i2cStatus[0] & 0x1E){
|
||||
rStatus = CyI2cReset (device, CY_I2C_MODE_READ);
|
||||
if (rStatus != CY_SUCCESS)
|
||||
CY_DEBUG_PRINT_INFO ("CY:i2c reset failed \n");
|
||||
//Report the amount of byte that were actually written
|
||||
memcpy(bytesPending, &i2cStatus[1], 2);
|
||||
errorStatus = handleI2cError (i2cStatus[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
errorStatus = CY_SUCCESS;
|
||||
}
|
||||
libusb_free_transfer (transfer);
|
||||
return errorStatus;
|
||||
}
|
||||
else{
|
||||
libusb_cancel_transfer (transfer);
|
||||
if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Timeout in getting i2c transfer status ....\n");
|
||||
CyI2cGetStatus (handle, 1, (UCHAR *)&errorStatus);
|
||||
errorStatus = CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
if (transfer->status == LIBUSB_TRANSFER_OVERFLOW){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error buffer overFlow in i2c transfer status ....\n");
|
||||
errorStatus = CY_ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED || transfer->status != LIBUSB_TRANSFER_COMPLETED){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in i2c transfer status ... Libusb transfer error is %d \n", transfer->status);
|
||||
errorStatus = CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
libusb_free_transfer (transfer);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
247
CyUSBSerial_SDK_Linux/linux/library/cyjtag.c
Normal file
247
CyUSBSerial_SDK_Linux/linux/library/cyjtag.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* JTAG 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"
|
||||
/*
|
||||
* This API enables the Jtag module
|
||||
*/
|
||||
CY_RETURN_STATUS CyJtagEnable (
|
||||
CY_HANDLE handle
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
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_JTAG) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_JTAG_ENABLE_CMD;
|
||||
wValue = 0x00;
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus >= 0){
|
||||
CY_DEBUG_PRINT_INFO ("CY: JTAG enable successfully \n");
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This API disables the Jtag module
|
||||
*/
|
||||
CY_RETURN_STATUS CyJtagDisable (
|
||||
CY_HANDLE handle
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
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_JTAG) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_JTAG_DISABLE_CMD;
|
||||
wValue = 0x00;
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus >= 0){
|
||||
CY_DEBUG_PRINT_INFO ("CY: JTAG disable successfully \n");
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error while enabling JTAG ..\n");
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error while enabling JTAG ...libusb error is %d function is %s!\n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This API is used to do jtag write
|
||||
*/
|
||||
CY_RETURN_STATUS CyJtagWrite (
|
||||
CY_HANDLE handle,
|
||||
CY_DATA_BUFFER *writeBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
int rStatus = 0;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
|
||||
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 parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_JTAG) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_JTAG_WRITE_CMD;
|
||||
wValue = writeBuffer->length;
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
writeBuffer->transferCount = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY: JTAG Vendor command failed %d...function is %s \n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
rStatus = libusb_bulk_transfer (devHandle, CY_JTAG_OUT_EP, writeBuffer->buffer, writeBuffer->length,
|
||||
(int*)&(writeBuffer->transferCount), ioTimeout);
|
||||
if ((rStatus == CY_SUCCESS)) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Number of bytes written is .... %d \n", writeBuffer->transferCount);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:TimeOut error ...Function is %s %d\n", __func__, writeBuffer->transferCount);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_PIPE){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Pipe error Function is %s \n", __func__);
|
||||
CyResetPipe (handle, CY_JTAG_OUT_EP);
|
||||
return CY_ERROR_PIPE_HALTED;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_OVERFLOW){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow..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: Error in Function %s...Libusb Error is %d !\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API is used to read JTAG data from device interface
|
||||
*/
|
||||
CY_RETURN_STATUS CyJtagRead (
|
||||
CY_HANDLE handle,
|
||||
CY_DATA_BUFFER *readBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_JTAG_READ_CMD;
|
||||
wValue = readBuffer->length;
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
|
||||
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 parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_JTAG) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
readBuffer->transferCount = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_INFO ("CY: JTAG Vendor Command failed %d.. Function is %s \n", rStatus, __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
rStatus = libusb_bulk_transfer (devHandle, CY_JTAG_IN_EP, readBuffer->buffer, readBuffer->length,
|
||||
(int*)&(readBuffer->transferCount), ioTimeout);
|
||||
if (rStatus == CY_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Number of bytes read is .... %d \n", readBuffer->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 Function is %s \n", __func__);
|
||||
CyResetPipe (handle, CY_JTAG_IN_EP);
|
||||
return CY_ERROR_PIPE_HALTED;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_OVERFLOW){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow..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: Error in function is %s ...Libusb Error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
584
CyUSBSerial_SDK_Linux/linux/library/cymisc.c
Normal file
584
CyUSBSerial_SDK_Linux/linux/library/cymisc.c
Normal file
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* Miscellaneous 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"
|
||||
|
||||
typedef struct NOTIFICATION_CB_PARAM{
|
||||
|
||||
CY_HANDLE handle;
|
||||
CY_EVENT_NOTIFICATION_CB_FN notificationCbFn;
|
||||
|
||||
}NOTIFICATION_CB_PARAM;
|
||||
/*
|
||||
This API is used to Read the Bootloder version
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetFirmwareVersion(
|
||||
CY_HANDLE handle,
|
||||
CY_FIRMWARE_VERSION *firmwareVersion
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_GET_VERSION_CMD;
|
||||
wValue = 0x00;
|
||||
wIndex = 0x00;
|
||||
wLength = CY_GET_FIRMWARE_VERSION_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)firmwareVersion, wLength, ioTimeout);
|
||||
|
||||
if (rStatus > 0){
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
The API resets the device
|
||||
*/
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyResetDevice (
|
||||
CY_HANDLE handle /*Valid device handle*/
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle \n");
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_DEVICE_RESET_CMD;
|
||||
wValue = 0xA6B6;
|
||||
wIndex = 0xADBA;
|
||||
wLength = 0;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
//return buffer will tell the status of the command
|
||||
if (rStatus == LIBUSB_SUCCESS)
|
||||
return CY_SUCCESS;
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CySetGpioValue (
|
||||
CY_HANDLE handle, /*Valid device handle*/
|
||||
UINT8 gpioNumber, /*GPIO configuration value*/
|
||||
UINT8 value /*Value that needs to be set*/
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest, buffer[CY_GPIO_SET_LEN];
|
||||
int rStatus;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (value)
|
||||
value = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_GPIO_SET_VALUE_CMD;
|
||||
wValue = gpioNumber;
|
||||
wIndex = value;
|
||||
wLength = 0;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, buffer, wLength, ioTimeout);
|
||||
if (rStatus >= 0){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Get Configuration of GPIO succedded...size is %d \n", rStatus);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyGetGpioValue (
|
||||
CY_HANDLE handle, /*Valid device handle*/
|
||||
UINT8 gpioNumber, /*GPIO configuration value*/
|
||||
UINT8 *value /*Value that needs to be set*/
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest, buffer[CY_GPIO_GET_LEN];
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_GPIO_GET_VALUE_CMD;
|
||||
wValue = gpioNumber;
|
||||
wIndex = 0x00;
|
||||
wLength = CY_GPIO_GET_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, buffer, wLength, ioTimeout);
|
||||
if (rStatus == CY_GPIO_GET_LEN){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Get GPIO Configuration succedded...size is %d \n", rStatus);
|
||||
//return buffer will tell the status of the command
|
||||
if (buffer[0] == 0){
|
||||
(*value) = buffer[1];
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
static void LIBUSB_CALL uart_notification_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
UINT32 *completed = transfer->user_data;
|
||||
*completed = 1;
|
||||
}
|
||||
|
||||
void* uartSetEventNotifcation (void *inputParameters)
|
||||
{
|
||||
int rStatus, transferCompleted = 0, length = CY_UART_EVENT_NOTIFICATION_LEN;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
struct libusb_transfer *transfer;
|
||||
UINT16 errorStatus = 0;
|
||||
UCHAR uartStatus[CY_UART_EVENT_NOTIFICATION_LEN];
|
||||
struct timeval time;
|
||||
CY_EVENT_NOTIFICATION_CB_FN callbackFn;
|
||||
NOTIFICATION_CB_PARAM *cbParameters = (NOTIFICATION_CB_PARAM*)inputParameters;
|
||||
callbackFn = cbParameters->notificationCbFn;
|
||||
|
||||
device = (CY_DEVICE *)cbParameters->handle;
|
||||
devHandle = device->devHandle;
|
||||
callbackFn = cbParameters->notificationCbFn;
|
||||
device->uartTransfer = transfer = libusb_alloc_transfer(0);
|
||||
if (transfer == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in allocating trasnfer \n");
|
||||
errorStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
callbackFn(errorStatus);
|
||||
goto END;
|
||||
}
|
||||
while (device->uartCancelEvent == false){
|
||||
libusb_fill_interrupt_transfer (transfer, devHandle, device->interruptEndpoint, uartStatus, length,
|
||||
uart_notification_cb, &transferCompleted, CY_EVENT_NOTIFICATION_TIMEOUT);
|
||||
rStatus = libusb_submit_transfer (transfer);
|
||||
if (rStatus){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error submitting uart interrupt token ... Libusb error is %d\n", rStatus);
|
||||
errorStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
callbackFn(errorStatus);
|
||||
break;
|
||||
}
|
||||
time.tv_sec = 0;
|
||||
time.tv_usec = 50;//polling timeout.
|
||||
while (transferCompleted == 0){
|
||||
libusb_handle_events_timeout (NULL, &time);
|
||||
}
|
||||
transferCompleted = 0;
|
||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED){
|
||||
CY_DEBUG_PRINT_INFO ("Successfully read and recieved data %d \n", transfer->actual_length);
|
||||
memcpy (&errorStatus, &uartStatus[8], 2);
|
||||
printf ("%x %x ", uartStatus[8], uartStatus[9]);
|
||||
callbackFn (errorStatus);
|
||||
errorStatus = 0;
|
||||
}
|
||||
else{
|
||||
errorStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
if (device->uartCancelEvent == false){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error uart interrupt thread encountered error... Libusb transmission error is %d \n", transfer->status);
|
||||
device->uartThreadId = 0;
|
||||
callbackFn(errorStatus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
CY_DEBUG_PRINT_INFO ("Exiting notification thread \n");
|
||||
libusb_free_transfer (transfer);
|
||||
END:
|
||||
free (inputParameters);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL spi_notification_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
UINT32 *completed = transfer->user_data;
|
||||
*completed = 1;
|
||||
}
|
||||
|
||||
void* spiSetEventNotifcation (void *inputParameters)
|
||||
{
|
||||
int transferCompleted = 0, length = CY_SPI_EVENT_NOTIFICATION_LEN;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
struct libusb_transfer *transfer;
|
||||
UINT8 spiStatus = 0;
|
||||
UINT16 errorStatus = 0;
|
||||
struct timeval time;
|
||||
CY_EVENT_NOTIFICATION_CB_FN callbackFn;
|
||||
NOTIFICATION_CB_PARAM *cbParameters = (NOTIFICATION_CB_PARAM*)inputParameters;
|
||||
|
||||
callbackFn = cbParameters->notificationCbFn;
|
||||
device = (CY_DEVICE *)cbParameters->handle;
|
||||
devHandle = device->devHandle;
|
||||
callbackFn = cbParameters->notificationCbFn;
|
||||
device->spiTransfer = transfer = libusb_alloc_transfer(0);
|
||||
if (transfer == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in allocating trasnfer \n");
|
||||
errorStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
callbackFn (errorStatus);
|
||||
goto END;
|
||||
}
|
||||
libusb_fill_interrupt_transfer (transfer, devHandle, device->interruptEndpoint, &spiStatus, length,
|
||||
spi_notification_cb, &transferCompleted, CY_EVENT_NOTIFICATION_TIMEOUT);
|
||||
while (device->spiCancelEvent == false){
|
||||
if (libusb_submit_transfer (transfer)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error submitting spi interrupt token ... \n");
|
||||
errorStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
callbackFn(errorStatus);
|
||||
break;
|
||||
}
|
||||
time.tv_sec = 0;
|
||||
time.tv_usec = 50;//polling timeout.
|
||||
while (transferCompleted == 0){
|
||||
libusb_handle_events_timeout (NULL, &time);
|
||||
}
|
||||
transferCompleted = 0;
|
||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED){
|
||||
CY_DEBUG_PRINT_INFO ("Successfully read and recieved data %d \n", transfer->actual_length);
|
||||
if (spiStatus & CY_SPI_UNDERFLOW_ERROR){
|
||||
errorStatus |= (CY_SPI_TX_UNDERFLOW_BIT);
|
||||
}
|
||||
if (spiStatus & CY_SPI_BUS_ERROR){
|
||||
errorStatus |= (CY_SPI_BUS_ERROR_BIT);
|
||||
}
|
||||
callbackFn (errorStatus);
|
||||
errorStatus = 0;
|
||||
}
|
||||
else{
|
||||
spiStatus |= CY_ERROR_EVENT_FAILED_BIT;
|
||||
if (device->spiCancelEvent == false){
|
||||
device->spiThreadId = 0;
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error spi interrupt thread was cancelled... Libusb transmission error is %d \n", transfer->status);
|
||||
callbackFn (spiStatus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
libusb_free_transfer (transfer);
|
||||
END:
|
||||
|
||||
free (inputParameters);
|
||||
pthread_exit (NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CySetEventNotification(
|
||||
CY_HANDLE handle, /*Valid handle to communicate with device*/
|
||||
CY_EVENT_NOTIFICATION_CB_FN notificationCbFn /*Call back function in case on error during Uart data transfers*/
|
||||
)
|
||||
{
|
||||
CY_DEVICE *device;
|
||||
NOTIFICATION_CB_PARAM *args = NULL;
|
||||
int ret;
|
||||
pthread_t threadID;
|
||||
|
||||
if (handle == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
if (notificationCbFn == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
device = (CY_DEVICE*)handle;
|
||||
pthread_mutex_lock (&device->notificationLock);
|
||||
args = (NOTIFICATION_CB_PARAM *)malloc (sizeof (NOTIFICATION_CB_PARAM));
|
||||
args->handle = handle;
|
||||
args->notificationCbFn = notificationCbFn;
|
||||
if (device->deviceType == CY_TYPE_SPI){
|
||||
if (device->spiThreadId != 0) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error already notification thread exists ... Function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_STATUS_MONITOR_EXIST;
|
||||
}
|
||||
ret = pthread_create (&threadID, NULL, spiSetEventNotifcation, (void *) args);
|
||||
if (ret == 0){
|
||||
device->spiThreadId = threadID;
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else {
|
||||
device->spiThreadId = 0;
|
||||
free (args);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error creating spi notification thread ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
else if (device->deviceType == CY_TYPE_UART){
|
||||
if (device->uartThreadId != 0) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error already notification thread exists ... Function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_STATUS_MONITOR_EXIST;
|
||||
}
|
||||
ret = pthread_create (&threadID, NULL, uartSetEventNotifcation, (void *) args);
|
||||
if (ret == 0){
|
||||
device->uartThreadId = threadID;
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else {
|
||||
device->uartThreadId = 0;
|
||||
free (args);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error creating uart notification thread ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error unknown device type ....Function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*The API is used to cancel the uart Event notification*/
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyAbortEventNotification(
|
||||
CY_HANDLE handle /*Valid handle to communicate with device*/
|
||||
)
|
||||
{
|
||||
CY_DEVICE *device;
|
||||
device = (CY_DEVICE*)handle;
|
||||
pthread_mutex_lock (&device->notificationLock);
|
||||
if (device->deviceType == CY_TYPE_UART){
|
||||
if ((device->uartThreadId == 0)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error uart event notification not created ....function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
device->uartCancelEvent = true;
|
||||
libusb_cancel_transfer (device->uartTransfer);
|
||||
pthread_join (device->uartThreadId, NULL);
|
||||
device->uartThreadId = 0;
|
||||
device->uartCancelEvent = false;
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (device->deviceType == CY_TYPE_SPI){
|
||||
if ((device->spiThreadId == 0)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error spi event notification not created ....function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
device->spiCancelEvent = true;
|
||||
libusb_cancel_transfer (device->spiTransfer);
|
||||
pthread_join (device->spiThreadId, NULL);
|
||||
device->spiThreadId = 0;
|
||||
device->spiCancelEvent = false;
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error.. unknown device type ....function is %s \n", __func__);
|
||||
pthread_mutex_unlock (&device->notificationLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
The API is used to programme user flash area
|
||||
*/
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyProgUserFlash (
|
||||
CY_HANDLE handle, /*Valid device handle*/
|
||||
CY_DATA_BUFFER *progBuffer, /*data buffer containing buffer address, length to write*/
|
||||
UINT32 flashAddress, /*Address to the data is written*/
|
||||
UINT32 ioTimeout /*Timeout value of the API*/
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
if ((progBuffer == NULL) || (progBuffer->buffer == NULL))
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_PROG_USER_FLASH_CMD;
|
||||
wValue = 0;
|
||||
wIndex = flashAddress;
|
||||
wLength = progBuffer->length;
|
||||
|
||||
CY_DEBUG_PRINT_INFO ("CY:The Length is %d , Value is %d and index is %d\n", wLength, wValue, wIndex);
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, progBuffer->buffer, wLength, ioTimeout);
|
||||
if (rStatus > 0){
|
||||
(progBuffer->transferCount) = rStatus;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
(progBuffer->transferCount) = 0;
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
(progBuffer->transferCount) = 0;
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
The API is used to programme user flash area
|
||||
*/
|
||||
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyReadUserFlash (
|
||||
CY_HANDLE handle, /*Valid device handle*/
|
||||
CY_DATA_BUFFER *readBuffer, /*data buffer containing buffer address, length to write*/
|
||||
UINT32 flashAddress, /*Address to the data is written*/
|
||||
UINT32 ioTimeout /*Timeout value of the API*/
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
if ((readBuffer == NULL) || (readBuffer == NULL))
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_READ_USER_FLASH_CMD;
|
||||
wValue = 0;
|
||||
wIndex = flashAddress;
|
||||
wLength = readBuffer->length;
|
||||
|
||||
CY_DEBUG_PRINT_INFO ("CY:The Length is %d , Value is %d and index is %d\n", wLength, wValue, wIndex);
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, readBuffer->buffer, wLength, ioTimeout);
|
||||
if (rStatus > 0){
|
||||
(readBuffer->transferCount) = rStatus;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
(readBuffer->transferCount) = 0;
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
(readBuffer->transferCount) = 0;
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This Api is used to get the signature of the device. It would be CYUS when we are in actual device mode
|
||||
and CYBL when we are bootloader modeñ
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetSignature (
|
||||
CY_HANDLE handle,
|
||||
UCHAR *signature
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_GET_SIGNATURE_CMD;
|
||||
wValue = 0x00;
|
||||
wIndex = 0x00;
|
||||
wLength = CY_GET_SIGNATURE_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)signature, wLength, ioTimeout);
|
||||
if (rStatus > 0){
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
130
CyUSBSerial_SDK_Linux/linux/library/cyphdc.c
Normal file
130
CyUSBSerial_SDK_Linux/linux/library/cyphdc.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* PHDC 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"
|
||||
/*
|
||||
PHDC clear feature
|
||||
*/
|
||||
CY_RETURN_STATUS CyPhdcClrFeature (CY_HANDLE handle)
|
||||
{
|
||||
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_PHDC_CLR_FEATURE;
|
||||
wValue = CY_PHDC_CLR_FEATURE_WVALUE;
|
||||
wIndex = device->interfaceNum;
|
||||
wLength = 0;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus == 0)
|
||||
return CY_SUCCESS;
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
PHDC set feature
|
||||
*/
|
||||
CY_RETURN_STATUS CyPhdcSetFeature (CY_HANDLE handle)
|
||||
{
|
||||
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT ;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_CLASS_INTERFACE_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_PHDC_SET_FEATURE;
|
||||
wValue = CY_PHDC_SET_FEATURE_WVALUE;
|
||||
wIndex = device->interfaceNum;
|
||||
wLength = 0;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus == 0)
|
||||
return CY_SUCCESS;
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
PHDC clear feature
|
||||
*/
|
||||
CY_RETURN_STATUS CyPhdcGetStatus (CY_HANDLE handle, UINT16 *dataStatus)
|
||||
{
|
||||
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
int rStatus;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT ;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
bmRequestType = CY_CLASS_INTERFACE_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_PHDC_GET_DATA_STATUS;
|
||||
wValue = 0x00;
|
||||
wIndex = device->interfaceNum;
|
||||
wLength = CY_PHDC_GET_STATUS_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)dataStatus, wLength, ioTimeout);
|
||||
if (rStatus > 0)
|
||||
return CY_SUCCESS;
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
644
CyUSBSerial_SDK_Linux/linux/library/cyspi.c
Normal file
644
CyUSBSerial_SDK_Linux/linux/library/cyspi.c
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* SPI 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"
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#pragma pack (1)
|
||||
typedef struct args {
|
||||
CY_HANDLE handle;
|
||||
UCHAR *readBuffer;
|
||||
UINT32 length;
|
||||
UINT32 ioTimeout;
|
||||
CY_RETURN_STATUS rStatus;
|
||||
UINT32 transferCount;
|
||||
}args;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 frequency;
|
||||
UINT8 dataWidth;
|
||||
UCHAR mode;
|
||||
UCHAR xferMode;
|
||||
BOOL isMsbFirst;
|
||||
BOOL isMaster;
|
||||
BOOL isContinuous;
|
||||
BOOL isSelectPrecede;
|
||||
BOOL cpha;
|
||||
BOOL cpol;
|
||||
BOOL isLoopback;
|
||||
UCHAR reserver[2];
|
||||
} CyUsSpiConfig_t;
|
||||
#pragma pack()
|
||||
|
||||
struct timeval startSpiTimeWrite, endSpiTimeWrite, startSpiTimeRead, endSpiTimeRead;
|
||||
//Timer helper functions for proper timing
|
||||
void startSpiTick (bool isWrite) {
|
||||
if (isWrite)
|
||||
gettimeofday (&startSpiTimeWrite, NULL);
|
||||
else
|
||||
gettimeofday (&startSpiTimeRead, NULL);
|
||||
}
|
||||
|
||||
UINT32 getSpiLapsedTime (bool isWrite){
|
||||
|
||||
signed int currentTime_sec, currentTime_usec, currentTime;
|
||||
if (isWrite){
|
||||
gettimeofday (&endSpiTimeWrite, NULL);
|
||||
currentTime_sec = (endSpiTimeWrite.tv_sec - startSpiTimeWrite.tv_sec) * 1000;
|
||||
currentTime_usec = ((endSpiTimeWrite.tv_usec - startSpiTimeWrite.tv_usec)) / 1000;
|
||||
currentTime = currentTime_sec + currentTime_usec;
|
||||
return (unsigned int)currentTime;
|
||||
}
|
||||
else{
|
||||
gettimeofday (&endSpiTimeRead, NULL);
|
||||
currentTime_sec = (endSpiTimeRead.tv_sec - startSpiTimeRead.tv_sec) * 1000;
|
||||
currentTime_usec = ((endSpiTimeRead.tv_usec - startSpiTimeRead.tv_usec)) / 1000;
|
||||
currentTime = currentTime_sec + currentTime_usec;
|
||||
return (unsigned int)currentTime;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API gets the current SPI config
|
||||
for the particluar interface of the device
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetSpiConfig (
|
||||
CY_HANDLE handle,
|
||||
CY_SPI_CONFIG *spiConfig
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
CyUsSpiConfig_t localSpiConfig;
|
||||
int rStatus;
|
||||
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 (spiConfig == NULL){
|
||||
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_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not spi ..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_SPI_GET_CONFIG_CMD;
|
||||
wValue = (scbIndex << CY_SCB_INDEX_POS);
|
||||
wIndex = 0;
|
||||
wLength = CY_SPI_CONFIG_LEN;
|
||||
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)&localSpiConfig, wLength, ioTimeout);
|
||||
if (rStatus == CY_SPI_CONFIG_LEN){
|
||||
//CY_DUMP_DATA ((unsigned char*)&localSpiConfig, wLength);
|
||||
CY_DEBUG_PRINT_INFO ("CY: Read SPI config successfully %d\n", rStatus);
|
||||
spiConfig->frequency = localSpiConfig.frequency;
|
||||
spiConfig->dataWidth = localSpiConfig.dataWidth;
|
||||
spiConfig->protocol = localSpiConfig.mode;
|
||||
spiConfig->isMsbFirst = localSpiConfig.isMsbFirst;
|
||||
spiConfig->isMaster = localSpiConfig.isMaster;
|
||||
spiConfig->isContinuousMode = localSpiConfig.isContinuous;
|
||||
spiConfig->isSelectPrecede = localSpiConfig.isSelectPrecede;
|
||||
spiConfig->isCpha = localSpiConfig.cpha;
|
||||
spiConfig->isCpol = localSpiConfig.cpol;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ... Function is %s\n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s...libusb error is %d !\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API sets SPI config of the device for that
|
||||
interface
|
||||
*/
|
||||
CY_RETURN_STATUS CySetSpiConfig (
|
||||
CY_HANDLE handle,
|
||||
CY_SPI_CONFIG *spiConfig
|
||||
)
|
||||
{
|
||||
UINT16 wValue, wIndex, wLength;
|
||||
UINT8 bmRequestType, bmRequest;
|
||||
CyUsSpiConfig_t localSpiConfig;
|
||||
int rStatus;
|
||||
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 (spiConfig == NULL){
|
||||
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_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not spi ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (spiConfig->frequency < 1000 || spiConfig->frequency > 3000000){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error frequency trying to set in out of range ... Function is %s\n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (spiConfig->protocol == CY_SPI_TI){
|
||||
if (!(spiConfig->isCpol == false && spiConfig->isCpha == true && spiConfig->isContinuousMode == false)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Wrong configuration for SPI TI mode \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
if (spiConfig->protocol == CY_SPI_NS){
|
||||
if (!(spiConfig->isCpol == false && spiConfig->isCpha == false && spiConfig->isSelectPrecede == false)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Wrong configuration for SPI ti mode \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (spiConfig->isSelectPrecede != false){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Wrong configuration for SPI motorola mode \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
if (device->interfaceNum > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_SPI_SET_CONFIG_CMD;
|
||||
wValue = (scbIndex << CY_SCB_INDEX_POS);
|
||||
wIndex = 0;
|
||||
wLength = CY_SPI_CONFIG_LEN;
|
||||
//We will not expose all the spi config structure elements to user.
|
||||
//Fill in rest of the values.
|
||||
|
||||
memset (&localSpiConfig, 0, CY_SPI_CONFIG_LEN);
|
||||
localSpiConfig.frequency = spiConfig->frequency;
|
||||
localSpiConfig.dataWidth = spiConfig->dataWidth;
|
||||
localSpiConfig.mode = spiConfig->protocol;
|
||||
localSpiConfig.isMsbFirst = spiConfig->isMsbFirst;
|
||||
localSpiConfig.isMaster = spiConfig->isMaster;
|
||||
localSpiConfig.isContinuous = spiConfig->isContinuousMode;
|
||||
localSpiConfig.isSelectPrecede = spiConfig->isSelectPrecede;
|
||||
localSpiConfig.cpha = spiConfig->isCpha;
|
||||
localSpiConfig.cpol = spiConfig->isCpol;
|
||||
//CY_DUMP_DATA ((unsigned char*)&localSpiConfig, wLength);
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, (unsigned char*)&localSpiConfig, wLength, ioTimeout);
|
||||
if (rStatus == CY_SPI_CONFIG_LEN){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Setting SPI config success ...\n");
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..Function is %s\n", __func__);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ... !libusb error is %d\n", __func__, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
/*Api will reset the spi module*/
|
||||
CY_RETURN_STATUS CySpiReset (CY_HANDLE handle)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength, bmRequestType, bmRequest;;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not spi ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_SPI_RESET_CMD;
|
||||
wValue = ((scbIndex << CY_SCB_INDEX_POS));
|
||||
wIndex = 0;
|
||||
wLength = 0;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, NULL, wLength, ioTimeout);
|
||||
if (rStatus < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in sending spi reset command...Libusb error is %d\n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
This API reads SPI data from the specified interface of the device
|
||||
interface
|
||||
*/
|
||||
|
||||
static void LIBUSB_CALL spi_read_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
UINT32 *completed = transfer->user_data;
|
||||
*completed = 1;
|
||||
}
|
||||
//We adopted for async method here because there are 2 thread polling same fd
|
||||
// i.e both read and write are polling same fd when one event triggers and other one is
|
||||
//not completed then another thread will wait for more than 60sec.
|
||||
CY_RETURN_STATUS CySpiRead (
|
||||
CY_HANDLE handle,
|
||||
CY_DATA_BUFFER *readBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
struct libusb_transfer *readTransfer;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
int readCompleted = 0;
|
||||
struct timeval time;
|
||||
int r;
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
readBuffer->transferCount = 0;
|
||||
readTransfer = libusb_alloc_transfer(0);
|
||||
if (readTransfer == NULL){
|
||||
CY_DEBUG_PRINT_ERROR("CY:Error in allocating transfers \n");
|
||||
return CY_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
libusb_fill_bulk_transfer(readTransfer, devHandle, device->inEndpoint, readBuffer->buffer, readBuffer->length,
|
||||
spi_read_cb, &readCompleted, ioTimeout);
|
||||
libusb_submit_transfer (readTransfer);
|
||||
time.tv_sec = (ioTimeout / 1000);
|
||||
time.tv_usec = ((ioTimeout % 1000) * 1000);//polling timeout.
|
||||
while (readCompleted == 0){
|
||||
r = libusb_handle_events_timeout_completed(NULL, &time, &readCompleted);
|
||||
if (r < 0) {
|
||||
if (r == LIBUSB_ERROR_INTERRUPTED)
|
||||
continue;
|
||||
libusb_cancel_transfer(readTransfer);
|
||||
while (!readCompleted)
|
||||
if (libusb_handle_events_completed(NULL, &readCompleted) < 0)
|
||||
break;
|
||||
readBuffer->transferCount = readTransfer->actual_length;
|
||||
libusb_free_transfer(readTransfer);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if ((readTransfer->status == LIBUSB_TRANSFER_COMPLETED)){
|
||||
readBuffer->transferCount = readTransfer->actual_length;
|
||||
libusb_free_transfer (readTransfer);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else{
|
||||
if (readTransfer->status == LIBUSB_TRANSFER_TIMED_OUT){
|
||||
//We should not be hitting this case.. As the time out is infinite!!
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Timeout error in doing SPI read/write .... %d Libusb errors %d\n",
|
||||
readTransfer->actual_length,readTransfer->status);
|
||||
readBuffer->transferCount = readTransfer->actual_length;
|
||||
CySpiReset (handle);
|
||||
libusb_free_transfer (readTransfer);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
if (readTransfer->status == LIBUSB_TRANSFER_OVERFLOW){
|
||||
//Need to handle this properly!
|
||||
CY_DEBUG_PRINT_ERROR ("CY:OverFlow error in doing SPI read/write .... Libusb errors %d %d \n",
|
||||
readTransfer->status, readTransfer->actual_length);
|
||||
readBuffer->transferCount = readTransfer->actual_length;
|
||||
CySpiReset (handle);
|
||||
libusb_free_transfer (readTransfer);
|
||||
return CY_ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
if (readTransfer->status != LIBUSB_TRANSFER_COMPLETED){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in doing SPI read/write .... Libusb errors are %d %d\n",
|
||||
readTransfer->status, readTransfer->actual_length);
|
||||
readBuffer->transferCount = readTransfer->actual_length;
|
||||
CySpiReset (handle);
|
||||
libusb_free_transfer (readTransfer);
|
||||
//If timer is not completed then it implies we have timeout error
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
}
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
/*Internal SPI get status API for Write operation*/
|
||||
CY_RETURN_STATUS CyGetSpiStatus (CY_HANDLE handle,
|
||||
int *spiStatus
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
UINT16 wValue, wIndex, wLength, bmRequestType, bmRequest;;
|
||||
UINT16 scbIndex = 0;
|
||||
UINT32 ioTimeout = 0;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not spi ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
scbIndex = device->interfaceNum;
|
||||
if (scbIndex > 0)
|
||||
scbIndex = 1;
|
||||
bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST;
|
||||
bmRequest = CY_SPI_GET_STATUS_CMD;
|
||||
wValue = ((scbIndex << CY_SCB_INDEX_POS));
|
||||
wIndex = 0;
|
||||
wLength = CY_SPI_GET_STATUS_LEN;
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,wValue, wIndex, (UCHAR*)spiStatus, wLength, ioTimeout);
|
||||
if (rStatus < CY_SPI_GET_STATUS_LEN){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Error in sending spi Get Status command...Libusb error is %d\n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/* Function to write on to SPI alone*/
|
||||
CY_RETURN_STATUS CySpiWrite (
|
||||
CY_HANDLE handle,
|
||||
CY_DATA_BUFFER *writeBuffer,
|
||||
UINT32 ioTimeout
|
||||
)
|
||||
{
|
||||
int rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
int spiStatus = 1;
|
||||
UINT32 newIoTimeout = ioTimeout, elapsedTime = 0, loopCount = 1;
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType != CY_TYPE_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not spi ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
startSpiTick (true);
|
||||
rStatus = libusb_bulk_transfer (devHandle, device->outEndpoint, writeBuffer->buffer, writeBuffer->length,
|
||||
(int*)&(writeBuffer->transferCount), newIoTimeout);
|
||||
elapsedTime = getSpiLapsedTime(true);
|
||||
newIoTimeout = ioTimeout - elapsedTime;
|
||||
//because we have a sleep of 1 msec after every getstatus
|
||||
if (newIoTimeout)
|
||||
loopCount = (newIoTimeout);
|
||||
if ((rStatus == LIBUSB_SUCCESS)){
|
||||
CY_DEBUG_PRINT_INFO ("CY: Successfully written SPI data.. %d bytes Read ...\n", writeBuffer->transferCount);
|
||||
while (loopCount){
|
||||
usleep (1000);
|
||||
rStatus = CyGetSpiStatus (handle, &spiStatus);
|
||||
if (rStatus == CY_SUCCESS){
|
||||
if (spiStatus == 0){
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Should never hit this case
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in getting spi status \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (ioTimeout)
|
||||
loopCount--;
|
||||
}
|
||||
if (loopCount == 0 && spiStatus > 0){
|
||||
writeBuffer->length = 0;
|
||||
CySpiReset (handle);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error TimeOut ...function is %s\n", __func__);
|
||||
CySpiReset (handle);
|
||||
return CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_PIPE){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Pipe error..function is %s\n", __func__);
|
||||
CySpiReset (handle);
|
||||
CyResetPipe (handle, device->outEndpoint);
|
||||
return CY_ERROR_PIPE_HALTED;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_OVERFLOW){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow...function is %s\n", __func__);
|
||||
return CY_ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
else if (rStatus == LIBUSB_ERROR_NO_DEVICE) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Device Disconnected ...function is %s\n", __func__);
|
||||
return CY_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in writing SPI data ...Libusb Error is %d and bytes read is %d!\n", rStatus, writeBuffer->transferCount);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}/*
|
||||
API to wrap up the data
|
||||
*/
|
||||
void spiCollectData (void *inputParameters) {
|
||||
|
||||
UINT32 readLength = 0, length;
|
||||
CY_DATA_BUFFER readBuffer;
|
||||
args *inputData = (args *) inputParameters;
|
||||
UCHAR *buffer;
|
||||
CY_RETURN_STATUS rStatus = CY_SUCCESS;
|
||||
buffer = readBuffer.buffer = inputData->readBuffer;
|
||||
length = readBuffer.length = inputData->length;
|
||||
CY_HANDLE handle = inputData->handle;
|
||||
int newTimeout = inputData->ioTimeout, elapsedTime;
|
||||
while (readLength != length && newTimeout >= 0 && rStatus == CY_SUCCESS){
|
||||
//Get current time
|
||||
//Buffer is pointing to next address where we are suppose to fill the data
|
||||
readBuffer.buffer = &buffer[readLength];
|
||||
//Updated length which total length minus the total length of data read
|
||||
readBuffer.length = length - readLength;
|
||||
//Libusb fix for mac os!!
|
||||
//ISSUE:when api times out in MAC it comes back and say read length = 0!!
|
||||
#ifdef __APPLE__
|
||||
if (readBuffer.length > 64)
|
||||
readBuffer.length = 64;
|
||||
#endif
|
||||
startSpiTick (false);
|
||||
rStatus = CySpiRead (handle, &readBuffer, newTimeout);
|
||||
elapsedTime = getSpiLapsedTime (false);
|
||||
//Do this only when newTimeout is non zero
|
||||
if (newTimeout){
|
||||
newTimeout = newTimeout - elapsedTime;
|
||||
//If timeout is 0 then libusb considers that as infinite
|
||||
//So forcefully make the loop to comeout
|
||||
if (newTimeout <= 0)
|
||||
rStatus = CY_ERROR_IO_TIMEOUT;
|
||||
}
|
||||
if (rStatus != CY_SUCCESS){
|
||||
readLength += readBuffer.transferCount;
|
||||
break;
|
||||
}
|
||||
readLength += readBuffer.transferCount;
|
||||
}
|
||||
if (readLength != length && rStatus == CY_ERROR_IO_TIMEOUT){
|
||||
CySpiReset (handle);
|
||||
}
|
||||
inputData->transferCount = readLength;
|
||||
inputData->rStatus = rStatus;
|
||||
}
|
||||
/*
|
||||
* Api used to do read as well as write on spi
|
||||
*/
|
||||
CY_RETURN_STATUS CySpiReadWrite (CY_HANDLE handle,
|
||||
CY_DATA_BUFFER *readBuffer,
|
||||
CY_DATA_BUFFER *writeBuffer,
|
||||
UINT32 ioTimeout)
|
||||
{
|
||||
struct args threadParameter;
|
||||
UINT32 ret;
|
||||
pthread_t readThreadID = (pthread_t)0;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
CY_RETURN_STATUS rStatus;
|
||||
unsigned short spiTransferMode = 0, scbIndex = 0;
|
||||
UINT16 wValue, wIndex = 0, wLength;
|
||||
UINT16 bmRequestType, bmRequest;
|
||||
|
||||
if (handle == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
if (readBuffer == NULL && writeBuffer == NULL){
|
||||
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_SPI) {
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error opened device is not spi .. \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
//Set both the bits and change it accordingly based on parameters parameters
|
||||
spiTransferMode |= ((CY_SPI_READ_BIT) | (CY_SPI_WRITE_BIT));
|
||||
if ((readBuffer == NULL || readBuffer->length == 0 || readBuffer->buffer == NULL))
|
||||
spiTransferMode &= ~(CY_SPI_READ_BIT);
|
||||
if ((writeBuffer == NULL || writeBuffer->length == 0 || writeBuffer->buffer == NULL))
|
||||
spiTransferMode &= ~(CY_SPI_WRITE_BIT);
|
||||
//if none of the bit is set it implies parameters sent is wrong
|
||||
if (spiTransferMode == 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (device->interfaceNum > 0)
|
||||
scbIndex = 1;
|
||||
//In read only case we take length to be equal to readBuffer length.
|
||||
//But in write or in write/read case we take length = writeBuffer length.
|
||||
if (spiTransferMode == 0x1)
|
||||
wIndex = readBuffer->length;
|
||||
else
|
||||
wIndex = writeBuffer->length;
|
||||
spiTransferMode |= (scbIndex << 15);
|
||||
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
|
||||
bmRequest = CY_SPI_READ_WRITE_CMD;
|
||||
wValue = (spiTransferMode);
|
||||
wLength = 0;
|
||||
if (pthread_mutex_trylock (&device->writeLock) == 0){
|
||||
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
|
||||
wValue, wIndex, NULL, wLength, 5000);
|
||||
if (rStatus){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Sending spi read write vendor command failed ... Libusb error is %d\n", rStatus);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
//Read Bit is not set then write Only
|
||||
if (!(spiTransferMode & CY_SPI_READ_BIT)) {
|
||||
writeBuffer->transferCount = 0;
|
||||
if (readBuffer)
|
||||
readBuffer->transferCount = 0;
|
||||
rStatus = CySpiWrite (handle, writeBuffer, ioTimeout);
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return rStatus;
|
||||
}
|
||||
//Write Bit is not set then read only
|
||||
if (!(spiTransferMode & CY_SPI_WRITE_BIT)) {
|
||||
// We are starting a thread so that we can collect all the data
|
||||
// FIX for short length packet issue on SPI.
|
||||
readBuffer->transferCount = 0;
|
||||
if (writeBuffer)
|
||||
writeBuffer->transferCount = 0;
|
||||
threadParameter.handle = handle;
|
||||
threadParameter.readBuffer = readBuffer->buffer;
|
||||
threadParameter.length = readBuffer->length;
|
||||
threadParameter.ioTimeout = ioTimeout;
|
||||
ret = pthread_create (&readThreadID, NULL, (void *)spiCollectData, (void *)&threadParameter);
|
||||
if (ret){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in creating read thread ... Reading failed \n");
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
readBuffer->transferCount = 0;
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
pthread_join (readThreadID, NULL);
|
||||
readBuffer->transferCount = threadParameter.transferCount;
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return threadParameter.rStatus;
|
||||
}
|
||||
writeBuffer->transferCount = 0;
|
||||
readBuffer->transferCount = 0;
|
||||
threadParameter.handle = handle;
|
||||
threadParameter.readBuffer = readBuffer->buffer;
|
||||
threadParameter.length = readBuffer->length;
|
||||
threadParameter.ioTimeout = ioTimeout;
|
||||
ret = pthread_create (&readThreadID, NULL, (void *)spiCollectData, (void *)&threadParameter);
|
||||
if (ret){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in creating read thread ... Reading failed \n");
|
||||
readBuffer->transferCount = 0;
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
rStatus = CySpiWrite (handle, writeBuffer, ioTimeout);
|
||||
if (rStatus == CY_SUCCESS) {
|
||||
pthread_join (readThreadID, NULL);
|
||||
rStatus = threadParameter.rStatus;
|
||||
readBuffer->transferCount = threadParameter.transferCount;
|
||||
}
|
||||
else {
|
||||
pthread_join (readThreadID, NULL);
|
||||
readBuffer->transferCount = threadParameter.transferCount;
|
||||
}
|
||||
pthread_mutex_unlock (&device->writeLock);
|
||||
return rStatus;
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error API busy in service previous request ... Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return rStatus;
|
||||
}
|
||||
755
CyUSBSerial_SDK_Linux/linux/library/cyuart.c
Normal file
755
CyUSBSerial_SDK_Linux/linux/library/cyuart.c
Normal file
@@ -0,0 +1,755 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
630
CyUSBSerial_SDK_Linux/linux/library/cyusb.c
Normal file
630
CyUSBSerial_SDK_Linux/linux/library/cyusb.c
Normal file
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* USB 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"
|
||||
|
||||
static bool glDriverInit = false;
|
||||
static libusb_device **glDeviceList;
|
||||
static UINT32 glNumDevices;
|
||||
/*The API initializes the Libusb library
|
||||
*/
|
||||
pthread_mutex_t criticalSection;
|
||||
CY_RETURN_STATUS CyLibraryInit ()
|
||||
{
|
||||
UINT32 rStatus;
|
||||
rStatus = libusb_init (NULL);
|
||||
|
||||
if (glDriverInit != true){
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Driver Init Failed ...\n");
|
||||
return CY_ERROR_DRIVER_INIT_FAILED;
|
||||
}
|
||||
glNumDevices = libusb_get_device_list (NULL, &glDeviceList);
|
||||
if (glNumDevices < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Building device list Failed ...\n");
|
||||
glNumDevices = -1;
|
||||
return CY_ERROR_DRIVER_INIT_FAILED;
|
||||
}
|
||||
pthread_mutex_init (&criticalSection, NULL);
|
||||
glDriverInit = true;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... library already initialized \n");
|
||||
return CY_ERROR_DRIVER_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
This API needs to be called after Calling CyGetListofDevices.
|
||||
*/
|
||||
CY_RETURN_STATUS CyLibraryExit ()
|
||||
{
|
||||
if (glDriverInit == true){
|
||||
if (glNumDevices >= 0)
|
||||
libusb_free_device_list (glDeviceList, 1);
|
||||
//This is to avoid loss of device handle issue with respect to libusb context.
|
||||
//libusb_exit (NULL);
|
||||
glDriverInit = false;
|
||||
pthread_mutex_destroy (&criticalSection);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Library not initialized \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
/*
|
||||
* This function Gets the number of all the devices currently
|
||||
* Connected to the host (It includes Cypress Device as well as
|
||||
* no Cypress Devices connected)
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetListofDevices (
|
||||
UINT8 *numDevices
|
||||
)
|
||||
{
|
||||
// Use this variable to call libusb_close and exit of the application
|
||||
if (numDevices == NULL)
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
if (!glDriverInit){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Library not initialised ...function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
pthread_mutex_lock (&criticalSection);
|
||||
libusb_free_device_list (glDeviceList, 1);
|
||||
glNumDevices = (*numDevices) = libusb_get_device_list (NULL, &glDeviceList);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
if (glNumDevices < 0){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Building device list Failed ...function is %s\n", __func__);
|
||||
glNumDevices = -1;
|
||||
(*numDevices) = -1;
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/* This function gets all the neccessary info such as VID,PID,
|
||||
String Descriptors and if is a cypress serial device you will
|
||||
get the info on class and device type
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetDeviceInfo (
|
||||
UINT8 deviceNumber,
|
||||
CY_DEVICE_INFO *deviceInfo
|
||||
)
|
||||
{
|
||||
struct libusb_device_descriptor deviceDesc;
|
||||
UINT32 rStatus, numInterfaces;
|
||||
UINT8 iManufacturer, iProduct, iSerial;
|
||||
libusb_device *usbDevice;;
|
||||
struct libusb_config_descriptor *configDesc;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
// Get the list of descriptor info for the device
|
||||
if (glDriverInit == false){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Library not initialised ...function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (deviceInfo == NULL)
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
pthread_mutex_lock (&criticalSection);
|
||||
if (deviceNumber >= glNumDevices){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid device number... \n");
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
usbDevice = glDeviceList[deviceNumber];
|
||||
rStatus = libusb_get_device_descriptor (usbDevice, &deviceDesc);
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... unable to retrieve device descriptor \n");
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
|
||||
deviceInfo->vidPid.vid = deviceDesc.idVendor;
|
||||
deviceInfo->vidPid.pid = deviceDesc.idProduct;
|
||||
// Get the all the index of the String descriptors so that it can be used
|
||||
// to retrieve the string descriptor info.
|
||||
iManufacturer = deviceDesc.iManufacturer;
|
||||
iProduct = deviceDesc.iProduct;
|
||||
iSerial = deviceDesc.iSerialNumber;
|
||||
//Get the Device handle so that we can communicate with the device retreiving
|
||||
// descriptor info
|
||||
deviceInfo->manufacturerName[0] = '\0';
|
||||
deviceInfo->productName[0] = '\0';
|
||||
deviceInfo->serialNum[0] = '\0';
|
||||
rStatus = libusb_open (usbDevice, &devHandle);
|
||||
if (rStatus == LIBUSB_ERROR_ACCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ...Insufficient permission... Libusb error is %d \n", rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_ACCESS_DENIED;
|
||||
}
|
||||
else if (rStatus != CY_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in opening the device... Libusb error is %d \n", rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
if (iManufacturer > 0){
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iManufacturer, deviceInfo->manufacturerName, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Getting Manufacturer name Error is <%x> \n", rStatus);
|
||||
}
|
||||
}
|
||||
if (iProduct > 0){
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iProduct, deviceInfo->productName, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Getting product name Error is <%d> \n", rStatus);
|
||||
}
|
||||
}
|
||||
if (iSerial > 0){
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iSerial, deviceInfo->serialNum, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Getting Serial name <%d>\n", rStatus);
|
||||
}
|
||||
}
|
||||
rStatus = libusb_get_config_descriptor (usbDevice, 0, &configDesc);
|
||||
if (rStatus == LIBUSB_SUCCESS){
|
||||
UINT32 index_i = 0;
|
||||
const struct libusb_interface *interface;
|
||||
numInterfaces = configDesc->bNumInterfaces;
|
||||
deviceInfo->numInterfaces = numInterfaces;
|
||||
interface = configDesc->interface;
|
||||
while ((numInterfaces) && (index_i < CY_MAX_DEVICE_INTERFACE)){
|
||||
deviceInfo->deviceClass[index_i] = (CY_DEVICE_CLASS)interface->altsetting->bInterfaceClass;
|
||||
if (deviceInfo->deviceClass[index_i] == CY_CLASS_VENDOR){
|
||||
deviceInfo->deviceType[index_i] = (CY_DEVICE_CLASS)interface->altsetting->bInterfaceSubClass;
|
||||
}
|
||||
else
|
||||
deviceInfo->deviceType[index_i] = CY_TYPE_DISABLED;
|
||||
index_i++;
|
||||
numInterfaces--;
|
||||
interface++;
|
||||
}
|
||||
libusb_free_config_descriptor(configDesc);
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in Getting config descriptor ...Libusb error is %d \n", rStatus);
|
||||
if (devHandle)
|
||||
libusb_close (devHandle);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
if (devHandle)
|
||||
libusb_close (devHandle);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/* This function gets all the neccessary info such as VID,PID,
|
||||
String Descriptors and if is a cypress serial device you will
|
||||
get the info on class and device type
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetDeviceInfoVidPid (
|
||||
CY_VID_PID vidPid,
|
||||
UINT8 *deviceNumber,
|
||||
PCY_DEVICE_INFO deviceInfoList,
|
||||
UINT8 *deviceCount,
|
||||
UINT8 infoListLength
|
||||
)
|
||||
{
|
||||
struct libusb_device_descriptor deviceDesc;
|
||||
UINT32 rStatus = CY_ERROR_DRIVER_INIT_FAILED, numInterfaces, index = 0, devNum;
|
||||
uint8_t iManufacturer, iProduct, iSerial;
|
||||
libusb_device *usbDevice;
|
||||
struct libusb_config_descriptor *configDesc;
|
||||
libusb_device_handle *devHandle = NULL;
|
||||
PCY_DEVICE_INFO deviceInfo;
|
||||
|
||||
if (glDriverInit == false){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Library not initialised ...function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if ((infoListLength) < 1){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error invalid device info list length specified should be > 0 .. function is %s\n", __func__);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (deviceNumber == NULL || deviceInfoList == NULL || deviceCount == NULL)
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
// Get the list of descriptor info for the device
|
||||
(*deviceCount) = 0;
|
||||
pthread_mutex_lock (&criticalSection);
|
||||
for (devNum = 0; devNum < glNumDevices; devNum++) {
|
||||
//We are making sure that we do not overrun
|
||||
//the list.
|
||||
deviceInfo = &(deviceInfoList [index]);
|
||||
usbDevice = glDeviceList[devNum];
|
||||
rStatus = libusb_get_device_descriptor (usbDevice, &deviceDesc);
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in getting device descriptor for device-%d... Libusb Error is %d \n", devNum, rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
if ((deviceDesc.idVendor != vidPid.vid) || (deviceDesc.idProduct != vidPid.pid)){
|
||||
continue;
|
||||
}
|
||||
(*deviceCount)++;
|
||||
if (index > infoListLength){
|
||||
continue;
|
||||
}
|
||||
rStatus = libusb_open (usbDevice, &devHandle);
|
||||
if (rStatus == LIBUSB_ERROR_ACCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Insufficient permission ... Libusb error is %d \n", rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_ACCESS_DENIED;
|
||||
}
|
||||
else if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Opening the Device ...Error is %d \n", rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
deviceNumber[index] = devNum;
|
||||
index++;
|
||||
deviceInfo->vidPid.vid = deviceDesc.idVendor;
|
||||
deviceInfo->vidPid.pid = deviceDesc.idProduct;
|
||||
// Get all the index of the String descriptors so that it can be used
|
||||
// to retrieve the string descriptor info.
|
||||
iManufacturer = deviceDesc.iManufacturer;
|
||||
iProduct = deviceDesc.iProduct;
|
||||
iSerial = deviceDesc.iSerialNumber;
|
||||
//Get the Device handle so that we can communicate with the device retreiving
|
||||
// descriptor info
|
||||
//Initialise manufacturer, product and serial names
|
||||
deviceInfo->manufacturerName[0] = '\0';
|
||||
deviceInfo->productName[0] = '\0';
|
||||
deviceInfo->serialNum[0] = '\0';
|
||||
if (iManufacturer > 0) {
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iManufacturer, deviceInfo->manufacturerName, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Error in Getting Manufacturer name Error is <%d> \n",rStatus);
|
||||
}
|
||||
}
|
||||
if (iProduct > 0){
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iProduct, deviceInfo->productName, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Error in Getting product name Error is <%d> \n", rStatus);
|
||||
}
|
||||
}
|
||||
if (iSerial > 0){
|
||||
rStatus = libusb_get_string_descriptor_ascii (devHandle, iSerial, deviceInfo->serialNum, 256);
|
||||
if (rStatus <= LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_INFO ("CY:Error in Getting Serial name <%d>\n", rStatus);
|
||||
}
|
||||
}
|
||||
CY_DEBUG_PRINT_INFO ("Manufacturer name <%s> \nProduct Name <%s> \nserial number <%s> \n",
|
||||
deviceInfo->manufacturerName,deviceInfo->productName,deviceInfo->serialNum);
|
||||
rStatus = libusb_get_config_descriptor (usbDevice, 0, &configDesc);
|
||||
if (rStatus == LIBUSB_SUCCESS){
|
||||
int index_i = 0;
|
||||
const struct libusb_interface *interfaceDesc;
|
||||
numInterfaces = configDesc->bNumInterfaces;
|
||||
deviceInfo->numInterfaces = numInterfaces;
|
||||
interfaceDesc = configDesc->interface;
|
||||
while ((numInterfaces) && (index_i < CY_MAX_DEVICE_INTERFACE)){
|
||||
deviceInfo->deviceClass[index_i] = (CY_DEVICE_CLASS)interfaceDesc->altsetting->bInterfaceClass;
|
||||
if (deviceInfo->deviceClass[index_i] == CY_CLASS_VENDOR)
|
||||
deviceInfo->deviceType[index_i] = (CY_DEVICE_CLASS)interfaceDesc->altsetting->bInterfaceSubClass;
|
||||
else
|
||||
deviceInfo->deviceType[index_i] = CY_TYPE_DISABLED;
|
||||
|
||||
index_i++;
|
||||
numInterfaces--;
|
||||
interfaceDesc++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CY_DEBUG_PRINT_ERROR ("CY: Error in Getting config descriptor ... Libusb Error is %d\n", rStatus);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DEVICE_INFO_FETCH_FAILED;
|
||||
}
|
||||
libusb_free_config_descriptor (configDesc);
|
||||
libusb_close (devHandle);
|
||||
}
|
||||
if ((*deviceCount) == 0)
|
||||
rStatus = CY_ERROR_DEVICE_NOT_FOUND;
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return rStatus;
|
||||
}
|
||||
/*
|
||||
This API will claim the interface in the device
|
||||
To make sure only claimed application speaks to device.
|
||||
*/
|
||||
CY_RETURN_STATUS CySelectInterface (
|
||||
CY_HANDLE handle,
|
||||
UINT8 interfaceNum
|
||||
)
|
||||
{
|
||||
UINT32 rStatus, numEP;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
libusb_device *usbDev;
|
||||
struct libusb_config_descriptor *configDesc;
|
||||
const struct libusb_interface *interfaceDesc;
|
||||
const struct libusb_endpoint_descriptor *epDesc;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
usbDev = libusb_get_device (devHandle);
|
||||
if (usbDev == NULL){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Invalide handle ..function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
//Get the config descriptor and parse it to get the
|
||||
//interface and endpoint descriptor
|
||||
rStatus = libusb_get_config_descriptor (usbDev, 0, &configDesc);
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Getting Config Desc ...function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
interfaceDesc = configDesc->interface;
|
||||
//Interface Number should be a valid one and should not exceed
|
||||
// total number of interfaces
|
||||
if (interfaceNum >= configDesc->bNumInterfaces){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Interface Number not valid... \n");
|
||||
libusb_free_config_descriptor (configDesc);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (libusb_kernel_driver_active (devHandle, interfaceNum)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Kernel driver active on the interface number %d \n", interfaceNum);;
|
||||
//User can uncomment this section if needed.
|
||||
#ifdef CY_DETACH_KERNEL_DRIVER
|
||||
if (!libusb_detach_kernel_driver (devHandle, interfaceNum)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Kernel driver detach failed %d\n", interfaceNum);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
#else
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
#endif
|
||||
}
|
||||
rStatus = libusb_claim_interface (devHandle, interfaceNum);
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in claiming interface -interface num %d... Libusb error is %d \n", interfaceNum, rStatus);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
device->interfaceNum = interfaceNum;
|
||||
while (interfaceNum--)
|
||||
interfaceDesc++;
|
||||
|
||||
epDesc = interfaceDesc->altsetting->endpoint;
|
||||
numEP = interfaceDesc->altsetting->bNumEndpoints;
|
||||
device->numEndpoints = numEP;
|
||||
// Check the total number of endpoints interface has
|
||||
// and get all the endpoint add
|
||||
CY_DEBUG_PRINT_INFO ("CY:Info The total number of endpoints are %d \n", numEP);
|
||||
while (numEP){
|
||||
if (epDesc->bmAttributes == 0x2){ //Bulk EP checking
|
||||
if (epDesc->bEndpointAddress & 0x80)
|
||||
device->inEndpoint = epDesc->bEndpointAddress;
|
||||
else
|
||||
device->outEndpoint = epDesc->bEndpointAddress;
|
||||
}
|
||||
else if (epDesc->bmAttributes == 0x3) //Interrupt EP checking (We have only one interrupt EP)
|
||||
device->interruptEndpoint = epDesc->bEndpointAddress;
|
||||
epDesc++;
|
||||
numEP--;
|
||||
}
|
||||
CY_DEBUG_PRINT_INFO ("CY:Info The Endpoints are in %d and out %d and interrup %d\n",
|
||||
device->inEndpoint, device->outEndpoint, device->interruptEndpoint);
|
||||
libusb_free_config_descriptor (configDesc);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* This API selects the type of the device
|
||||
*/
|
||||
void CySelectDeviceType (CY_DEVICE *device, libusb_device *libUsbdev, unsigned char interfaceNum)
|
||||
{
|
||||
int rStatus, numInterfaces;
|
||||
struct libusb_config_descriptor *configDesc;
|
||||
int index = 0;
|
||||
const struct libusb_interface *interfaceDesc;
|
||||
device->deviceType = CY_TYPE_DISABLED;
|
||||
|
||||
rStatus = libusb_get_config_descriptor (libUsbdev, 0, &configDesc);
|
||||
if (0 == rStatus){
|
||||
interfaceDesc = configDesc->interface;
|
||||
numInterfaces = configDesc->bNumInterfaces;
|
||||
if (interfaceNum >= numInterfaces)
|
||||
return;
|
||||
while (index != interfaceNum) {
|
||||
index++;
|
||||
interfaceDesc++;
|
||||
}
|
||||
if (interfaceDesc->altsetting->bInterfaceClass == CY_CLASS_VENDOR)
|
||||
device->deviceType = (CY_DEVICE_CLASS)interfaceDesc->altsetting->bInterfaceSubClass;
|
||||
libusb_free_config_descriptor (configDesc);
|
||||
}
|
||||
CY_DEBUG_PRINT_INFO ("CY:Info The device type is %d \n", device->deviceType);
|
||||
}
|
||||
/*
|
||||
The Api Gets the handle for the specified device number
|
||||
(refer to usage guide and example for usage)
|
||||
and this handle should be called for further communication
|
||||
with the device
|
||||
*/
|
||||
CY_RETURN_STATUS CyOpen (
|
||||
unsigned char deviceNumber,
|
||||
unsigned char interfaceNum,
|
||||
CY_HANDLE *handle
|
||||
)
|
||||
{
|
||||
libusb_device_handle *devHandle;
|
||||
libusb_device *dev;
|
||||
CY_DEVICE *device;
|
||||
UINT32 rStatus;
|
||||
|
||||
if (glDriverInit == false){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error Library not initialised ...function is %s\n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
pthread_mutex_lock (&criticalSection);
|
||||
if (glDriverInit == true){
|
||||
if (deviceNumber >= glNumDevices){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error ... Invalid device number ... \n");
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
dev = glDeviceList [deviceNumber];
|
||||
rStatus = libusb_open (dev, &devHandle);
|
||||
if (rStatus == LIBUSB_ERROR_ACCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in opening the device ..Access denied \n");
|
||||
handle = NULL;
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_ACCESS_DENIED;
|
||||
}
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in Opening the Device ...Error is %d \n", rStatus);
|
||||
handle = NULL;
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
device = (CY_DEVICE *)malloc(sizeof (CY_DEVICE));
|
||||
if (device == NULL){
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
device->devHandle = devHandle;
|
||||
(*handle) = device;
|
||||
rStatus = CySelectInterface (device, interfaceNum);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
libusb_close (devHandle);
|
||||
free (device);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
CySelectDeviceType (device, dev, interfaceNum);
|
||||
if (device->deviceType == CY_TYPE_UART) {
|
||||
CyUartSetRts (*handle);
|
||||
CyUartSetDtr (*handle);
|
||||
if (!CyUartSetHwFlowControl (*handle, CY_UART_FLOW_CONTROL_DISABLE))
|
||||
device->uartFlowControlMode = CY_UART_FLOW_CONTROL_DISABLE;
|
||||
}
|
||||
//initialising structure elements
|
||||
device->spiThreadId = (pthread_t)0;
|
||||
device->uartThreadId = (pthread_t)0;
|
||||
device->spiCancelEvent = false;
|
||||
device->uartCancelEvent = false;
|
||||
device->spiTransfer = NULL;
|
||||
device->uartTransfer = NULL;
|
||||
if (pthread_mutex_init (&device->readLock, NULL)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error initializing the read mutex .. Function is %s \n", __func__);
|
||||
libusb_close (devHandle);
|
||||
free (device);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
if (pthread_mutex_init (&device->writeLock, NULL)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error initializing the write mutex .. Function is %s \n", __func__);
|
||||
libusb_close (devHandle);
|
||||
free (device);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
if (pthread_mutex_init (&device->notificationLock, NULL)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error initializing the write mutex .. Function is %s \n", __func__);
|
||||
libusb_close (devHandle);
|
||||
free (device);
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
pthread_mutex_unlock (&criticalSection);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
else{
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error iniitalise library by calling CyLibraryInit()....function is %s\n", __func__);
|
||||
return CY_ERROR_DRIVER_OPEN_FAILED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
The Api Closes the handle and needs to be called only if CyGetNumDevices
|
||||
or CyOpen is called
|
||||
*/
|
||||
CY_RETURN_STATUS CyClose (
|
||||
CY_HANDLE handle
|
||||
)
|
||||
{
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
if (device->deviceType == CY_TYPE_UART) {
|
||||
CyUartClearRts (handle);
|
||||
CyUartClearDtr (handle);
|
||||
CyUartSetHwFlowControl (handle, CY_UART_FLOW_CONTROL_DISABLE);
|
||||
}
|
||||
if (glDriverInit == true){
|
||||
if (device->deviceType == CY_TYPE_SPI || device->deviceType == CY_TYPE_UART){
|
||||
if (device->spiThreadId != 0 || device->uartThreadId != 0){
|
||||
CyAbortEventNotification(handle);
|
||||
}
|
||||
}
|
||||
if (pthread_mutex_destroy (&device->readLock)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error de initializing the read mutex .. Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (pthread_mutex_destroy (&device->writeLock)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error de initializing the write mutex .. Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
if (pthread_mutex_destroy (&device->notificationLock)){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error de initializing the write mutex .. Function is %s \n", __func__);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
libusb_close ((libusb_device_handle*)devHandle);
|
||||
free (device);
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
This Api will reset the pipe and clears the endpoint
|
||||
*/
|
||||
CY_RETURN_STATUS CyResetPipe (
|
||||
CY_HANDLE handle,
|
||||
UINT8 endPointAddress
|
||||
)
|
||||
{
|
||||
UINT32 rStatus;
|
||||
CY_DEVICE *device;
|
||||
libusb_device_handle *devHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return CY_ERROR_INVALID_HANDLE;
|
||||
device = (CY_DEVICE *)handle;
|
||||
devHandle = device->devHandle;
|
||||
|
||||
rStatus = libusb_clear_halt ((libusb_device_handle *)devHandle, endPointAddress);
|
||||
if (rStatus != LIBUSB_SUCCESS){
|
||||
CY_DEBUG_PRINT_ERROR ("CY:Error in resetting the pipe ... \n");
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
/*
|
||||
This Api will get the library version,patch
|
||||
and build number
|
||||
*/
|
||||
CY_RETURN_STATUS CyGetLibraryVersion (
|
||||
CY_HANDLE handle,
|
||||
PCY_LIBRARY_VERSION version
|
||||
)
|
||||
{
|
||||
version->majorVersion = CY_US_VERSION_MAJOR;
|
||||
version->minorVersion = CY_US_VERSION_MINOR;
|
||||
version->patch = CY_US_VERSION_PATCH;
|
||||
version->buildNumber = CY_US_VERSION_BUILD;
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
1
CyUSBSerial_SDK_Linux/linux/library/libcyusbserial.so
Normal file
1
CyUSBSerial_SDK_Linux/linux/library/libcyusbserial.so
Normal file
@@ -0,0 +1 @@
|
||||
libcyusbserial.so.1
|
||||
BIN
CyUSBSerial_SDK_Linux/linux/library/libcyusbserial.so.1
Executable file
BIN
CyUSBSerial_SDK_Linux/linux/library/libcyusbserial.so.1
Executable file
Binary file not shown.
5
CyUSBSerial_SDK_Linux/linux/testUtility/90-cyusb.rules
Normal file
5
CyUSBSerial_SDK_Linux/linux/testUtility/90-cyusb.rules
Normal file
@@ -0,0 +1,5 @@
|
||||
# Cypress USB driver for FX2 and FX3 (C) Cypress Semiconductor Corporation / ATR-LABS
|
||||
# Rules written by V. Radhakrishnan ( rk@atr-labs.com )
|
||||
# Cypress USB vendor ID = 0x04b4
|
||||
KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTR{idVendor}=="04b4", MODE="666", TAG="cyusb_dev", RUN+="/usr/bin/CyUSBSerial.sh A"
|
||||
KERNEL=="*", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="remove", TAG=="cyusb_dev", RUN+="/usr/bin/CyUSBSerial.sh R"
|
||||
7
CyUSBSerial_SDK_Linux/linux/testUtility/CyUSBSerial.sh
Normal file
7
CyUSBSerial_SDK_Linux/linux/testUtility/CyUSBSerial.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
pid=`pidof CyUSBSerialTestUtility`
|
||||
|
||||
if [ "$pid" ]; then
|
||||
kill -s SIGUSR1 $pid
|
||||
fi
|
||||
|
||||
BIN
CyUSBSerial_SDK_Linux/linux/testUtility/CyUSBSerialTestUtility
Executable file
BIN
CyUSBSerial_SDK_Linux/linux/testUtility/CyUSBSerialTestUtility
Executable file
Binary file not shown.
11
CyUSBSerial_SDK_Linux/linux/testUtility/Makefile
Normal file
11
CyUSBSerial_SDK_Linux/linux/testUtility/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
all:
|
||||
gcc -g -o CyUSBSerialTestUtility Test_Utility.c -lcyusbserial -w
|
||||
cp 90-cyusb.rules /etc/udev/rules.d
|
||||
cp CyUSBSerialTestUtility /usr/bin
|
||||
cp CyUSBSerial.sh /usr/bin
|
||||
chmod 777 /usr/bin/CyUSBSerial.sh
|
||||
clean:
|
||||
rm -f CyUSBSerialTestUtility
|
||||
help:
|
||||
@echo 'make would compile and create the library and create a link'
|
||||
@echo 'make clean would remove the library and the soft link to the library (soname)'
|
||||
137
CyUSBSerial_SDK_Linux/linux/testUtility/README.txt
Normal file
137
CyUSBSerial_SDK_Linux/linux/testUtility/README.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
================================================================================
|
||||
Cypress Semiconductor Corporation
|
||||
CyUSB Serial DVK test utility for I2C/SPI
|
||||
================================================================================
|
||||
|
||||
This utility is used for testing I2C/SPI master mode functionality on the
|
||||
Cypress CyUSBSerial DVK.
|
||||
|
||||
The utility writes to I2C/SPI flash devices on the DVK, reads the data back
|
||||
and verifies the data read for integrity.
|
||||
|
||||
Release components:
|
||||
================================================================================
|
||||
1. Test_Utility.c ==> Source file of the command line test utility
|
||||
2. 90-cyusb.rules ==> udev rules for changing the mode of usb device node.
|
||||
3. CyUSBSerial.sh ==> Script file for implementing hotplug feature in linux.
|
||||
4. Makefile ==> make file for compiling and installing the application.
|
||||
================================================================================
|
||||
|
||||
|
||||
Pre-requisites:
|
||||
================================================================================
|
||||
1. libusb-1.0.9 is required for compilation and functioning of the APIs in the
|
||||
USB Serial library.
|
||||
2. The CyUSBSerial library (libcyusbserial.so) should be compiled and installed
|
||||
on the test machine.
|
||||
3. GNU Make and the GCC tool-chain are used for the build process.
|
||||
================================================================================
|
||||
|
||||
Installation steps:
|
||||
================================================================================
|
||||
1. Change to the folder where the utility source files are extracted.
|
||||
2. Invoke 'make' to build compile the utility, and to install the configuration
|
||||
files at the appropriate locations. This should be done from a super-user
|
||||
(sudo) shell, because the configuration files need to be copied into system
|
||||
folders (/usr/local/bin).
|
||||
3. Use the CyUSBSerial command to start the test utility.
|
||||
|
||||
Note:
|
||||
The udev daemon needs to be restarted to reflect the udev rule changes that
|
||||
are installed as part of the make command.
|
||||
================================================================================
|
||||
|
||||
Using the test utility:
|
||||
================================================================================
|
||||
1. On starting the utility, the Cypress USB Serial devices that are connected
|
||||
are listed along with their device numbers, interface numbers and
|
||||
functionalities (SPI or I2C).
|
||||
|
||||
$ CyUSBSerial
|
||||
----------------------------------------------------------------------
|
||||
Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY
|
||||
----------------------------------------------------------------------
|
||||
0 |4b4 |a | 0 | VENDOR_I2C
|
||||
0 |4b4 |a | 1 | VENDOR_SPI
|
||||
0 |4b4 |a | 2 | NA
|
||||
----------------------------------------------------------------------
|
||||
|
||||
2. A menu providing the various operations is also printed:
|
||||
----------------------------------------------------------------------
|
||||
1: Print list of devices
|
||||
2: Select device...No device selected !!
|
||||
3: Enter I2C/SPI Flash page address and length to write/read.
|
||||
4: Verify data
|
||||
5: Exit
|
||||
----------------------------------------------------------------------
|
||||
|
||||
3. On selecting option 2, the utility prompts for the device and interface
|
||||
number to be selected for testing.
|
||||
|
||||
-----------------------------------
|
||||
Enter Device number to select:
|
||||
0
|
||||
Enter interface number:
|
||||
1
|
||||
-----------------------------------
|
||||
|
||||
Once the selections are made, the menu will be updated with the details.
|
||||
----------------------------------------------------------------------
|
||||
1: Print list of devices
|
||||
2: Change device selection--selected device: [Device number 0] : [Interface No 1] : SPI
|
||||
3: Enter I2C/SPI Flash page address and length to write/read.
|
||||
4: Verify data
|
||||
5: Exit
|
||||
----------------------------------------------------------------------
|
||||
|
||||
4. Option 3 can be selected now to do data read/write to the I2C/SPI flash
|
||||
device. The utility prompts for the page address to be written as well as
|
||||
the length of data to be written.
|
||||
|
||||
------------------------------------------------
|
||||
Enter Page address ... (less than 65536)
|
||||
1234
|
||||
Enter length to read/write ... (less than 256)
|
||||
32
|
||||
------------------------------------------------
|
||||
|
||||
Length needs to be less than or equal to 256 bytes in the case of SPI access,
|
||||
and less than or equal to 64 bytes in the case of I2C access. Page address
|
||||
needs to be less than 65536 in case of SPI and 256 in case of I2C.
|
||||
|
||||
Once the values are selected, the menu is updated with the details as below:
|
||||
-------------------------------------------------------------------
|
||||
1: Print list of devices
|
||||
2: Change device selection--selected device: [Device number 0] : [Interface No 1] : SPI
|
||||
3: Change Flash page address and length ...Entered is page address 1234 and length 123
|
||||
4: Verify data
|
||||
5: Exit
|
||||
-------------------------------------------------------------------
|
||||
|
||||
5. Selecting option 4 causes the utility to write a randomly generated data
|
||||
sequence to the flash device, read it back, and verify the data read back.
|
||||
|
||||
The data pattern written and read back will be displayed as shown below:
|
||||
--------------------------------------------------------------------
|
||||
67 c6 69 73 51 ff 4a ec 29 cd ba ab f2 fb e3 46 7c c2 54 f8 1b e8 e7 8d 76 5a 2e 63 33 9f c9 9a
|
||||
--------------------------------------------------------------------
|
||||
Data Read back is:
|
||||
---------------------------------------------------------------------
|
||||
67 c6 69 73 51 ff 4a ec 29 cd ba ab f2 fb e3 46 7c c2 54 f8 1b e8 e7 8d 76 5a 2e 63 33 9f c9 9a
|
||||
---------------------------------------------------------------------
|
||||
Data verified successfully
|
||||
-------------------------------------------------------------------
|
||||
|
||||
6. The utility runs through these menu options until the user selects the
|
||||
exit option (5).
|
||||
|
||||
7. If a new Cypress USB Serial device is attached or an existing device is
|
||||
removed while the utility is running, a notification is printed on the
|
||||
console.
|
||||
|
||||
---------------------------------------
|
||||
Device of interest Removed/Added
|
||||
---------------------------------------
|
||||
================================================================================
|
||||
|
||||
EOF
|
||||
605
CyUSBSerial_SDK_Linux/linux/testUtility/Test_Utility.c
Normal file
605
CyUSBSerial_SDK_Linux/linux/testUtility/Test_Utility.c
Normal file
@@ -0,0 +1,605 @@
|
||||
/*
|
||||
* Test utility
|
||||
* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../../common/header/CyUSBSerial.h"
|
||||
#define CY_MAX_DEVICES 30
|
||||
#define CY_MAX_INTERFACES 4
|
||||
|
||||
typedef struct _CY_DEVICE_STRUCT {
|
||||
int deviceNumber;
|
||||
int interfaceFunctionality[CY_MAX_INTERFACES];
|
||||
bool isI2c;
|
||||
bool isSpi;
|
||||
int numInterface;
|
||||
}CY_DEVICE_STRUCT;
|
||||
|
||||
CY_DEVICE_STRUCT *glDevice;
|
||||
int i2cDeviceIndex[CY_MAX_DEVICES][CY_MAX_INTERFACES];
|
||||
unsigned char *deviceNumber = NULL;
|
||||
int cyDevices, i2cDevices = 0, numDevices = 0;
|
||||
int selectedDeviceNum = -1, selectedInterfaceNum = -1;
|
||||
bool exitApp = false;
|
||||
unsigned short pageAddress = -1;
|
||||
short readWriteLength = -1;
|
||||
bool deviceAddedRemoved = false;
|
||||
int getUserInput()
|
||||
{
|
||||
char userInput[6], x;
|
||||
int output,i = 0;
|
||||
bool isDigit = true;
|
||||
x = getchar();
|
||||
while (x != '\n'){
|
||||
if (i < 5){
|
||||
userInput[i] = x;
|
||||
i++;
|
||||
}
|
||||
if (!isdigit(x))
|
||||
isDigit = false;
|
||||
|
||||
x = getchar();
|
||||
}
|
||||
userInput[i] = '\0';
|
||||
if (isDigit == false)
|
||||
return -1;
|
||||
output = atoi(userInput);
|
||||
return output;
|
||||
}
|
||||
void deviceHotPlug () {
|
||||
|
||||
CY_RETURN_STATUS rStatus;
|
||||
deviceAddedRemoved = true;
|
||||
selectedDeviceNum = -1;
|
||||
selectedInterfaceNum = -1;
|
||||
printf ("Device of interest Removed/Added \n");
|
||||
rStatus = CyGetListofDevices (&numDevices);
|
||||
if (rStatus != CY_SUCCESS) {
|
||||
printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
printListOfDevices (false);
|
||||
}
|
||||
|
||||
int main (int argc, char **agrv)
|
||||
{
|
||||
int index = 0, i, j, userInput;
|
||||
int tempSelectedDeviceNum, tempSelectedInterfaceNum, tempPageAddress, tempLength;
|
||||
CY_RETURN_STATUS rStatus;
|
||||
signal (SIGUSR1, deviceHotPlug);
|
||||
glDevice = (CY_DEVICE_STRUCT *)malloc (CY_MAX_DEVICES *sizeof (CY_DEVICE_STRUCT));
|
||||
if (glDevice == NULL){
|
||||
printf ("Memory allocation failed ...!! \n");
|
||||
return -1;
|
||||
}
|
||||
rStatus = CyLibraryInit ();
|
||||
if (rStatus != CY_SUCCESS) {
|
||||
printf ("CY:Error in Doing library init Error NO:<%d> \n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
rStatus = CyGetListofDevices (&numDevices);
|
||||
if (rStatus != CY_SUCCESS) {
|
||||
printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus);
|
||||
return rStatus;
|
||||
}
|
||||
printListOfDevices(true);
|
||||
do {
|
||||
|
||||
printf ("-------------------------------------------------------------------\n");
|
||||
printf ("1: Print list of devices \n");
|
||||
if (selectedDeviceNum != -1 && selectedInterfaceNum != -1){
|
||||
printf ("2: Change device selection--selected device: [Device number %d] : [Interface No %d]",\
|
||||
selectedDeviceNum, selectedInterfaceNum);
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C)
|
||||
printf (" : I2C\n");
|
||||
else if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI)
|
||||
printf (" : SPI\n");
|
||||
else
|
||||
printf (" : NA\n");
|
||||
|
||||
}
|
||||
else
|
||||
printf ("2: Select device...No device selected !!\n");
|
||||
|
||||
if (readWriteLength != -1 && pageAddress != -1){
|
||||
printf ("3: Change Flash page address and length ...Entered is page address %d and length %d\n", pageAddress, readWriteLength);
|
||||
printf ("4: Verify data\n5: Exit\n");
|
||||
}
|
||||
else
|
||||
printf ("3: Enter I2C/SPI Flash page address and length to write/read.\n4: Verify data\n5: Exit\n");
|
||||
printf ("-------------------------------------------------------------------\n");
|
||||
|
||||
userInput = getUserInput();
|
||||
if (userInput < 1 || userInput > 5){
|
||||
printf ("Wrong selection code ... Enter again \n");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (userInput){
|
||||
|
||||
case 1:
|
||||
printListOfDevices(true);
|
||||
break;
|
||||
case 2:
|
||||
if (cyDevices == 0) {
|
||||
printf ("No device of interest connected ...!!\n");
|
||||
continue;
|
||||
}
|
||||
printf ("Enter Device number to be selected.. \n");
|
||||
tempSelectedDeviceNum = getUserInput();
|
||||
//printf ("Selected device number is %d \n",tempSelectedDeviceNum);
|
||||
if (tempSelectedDeviceNum >= cyDevices || tempSelectedDeviceNum == -1){
|
||||
printf ("Wrong device selection \n");
|
||||
continue;
|
||||
}
|
||||
printf ("Enter interface number..\n");
|
||||
tempSelectedInterfaceNum = getUserInput();
|
||||
//printf ("Selected device number is %d %d\n",tempSelectedInterfaceNum, glDevice[tempSelectedDeviceNum].numInterface);
|
||||
|
||||
if (tempSelectedInterfaceNum >= glDevice[tempSelectedDeviceNum].numInterface ||
|
||||
tempSelectedInterfaceNum == -1) {
|
||||
printf ("Wrong interface Selection selection \n");
|
||||
continue;
|
||||
}
|
||||
if ((glDevice[tempSelectedDeviceNum].interfaceFunctionality[tempSelectedInterfaceNum] == -1)){
|
||||
printf ("Selected device does not have I2C or SPI !!! \n");
|
||||
continue;
|
||||
}
|
||||
if (deviceAddedRemoved == true) {
|
||||
printf ("Device of interest was added/removed .... Print and select from new list\n");
|
||||
continue;
|
||||
}
|
||||
selectedDeviceNum = tempSelectedDeviceNum;
|
||||
selectedInterfaceNum = tempSelectedInterfaceNum;
|
||||
//pageAddress = -1;
|
||||
//readWriteLength = -1;
|
||||
break;
|
||||
case 3:
|
||||
if (selectedDeviceNum == -1) {
|
||||
printf ("Select proper device!!! \n");
|
||||
continue;
|
||||
}
|
||||
if (selectedDeviceNum >= cyDevices){
|
||||
printf ("Select proper device!!! \n");
|
||||
continue;
|
||||
}
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C){
|
||||
printf ("Enter Page address... (less than 256)\n");
|
||||
tempPageAddress = getUserInput();
|
||||
printf ("Enter length to read/write...(less than 64)\n");
|
||||
tempLength = getUserInput();
|
||||
if (deviceAddedRemoved == true) {
|
||||
printf ("Device of interest was added/removed .... Print and select from new list\n");
|
||||
continue;
|
||||
}
|
||||
if (tempPageAddress > 256){
|
||||
printf ("Invalid page address ..Enter page address less than 256 (1 bytes len)\n");
|
||||
continue;
|
||||
}
|
||||
if (tempLength < 0 || tempLength > 64){
|
||||
printf ("Invalid Length ..Enter length less than 64 bytes\n");
|
||||
continue;
|
||||
}
|
||||
pageAddress = tempPageAddress;
|
||||
readWriteLength = tempLength;
|
||||
break;
|
||||
}
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI){
|
||||
printf ("Enter Page address... (less than 65536)\n");
|
||||
tempPageAddress = getUserInput();
|
||||
printf ("Enter length to read/write...(less than 256)\n");
|
||||
tempLength = getUserInput();
|
||||
if (deviceAddedRemoved == true) {
|
||||
printf ("Device of interest was added/removed .... Print and select from new list\n");
|
||||
continue;
|
||||
}
|
||||
if (tempPageAddress > 65536){
|
||||
printf ("Invalid page address ..Enter page address less than 65536 (1 bytes len)\n");
|
||||
continue;
|
||||
}
|
||||
if (tempLength < 0 || tempLength > 256){
|
||||
printf ("Invalid Length ..Enter length less than 256 bytes\n");
|
||||
continue;
|
||||
}
|
||||
pageAddress = tempPageAddress;
|
||||
readWriteLength = tempLength;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
if (selectedDeviceNum == -1) {
|
||||
printf ("Select proper device!!! \n");
|
||||
continue;
|
||||
}
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == -1){
|
||||
printf ("Selected device does not have I2C or SPI !!! \n");
|
||||
continue;
|
||||
}
|
||||
if ((pageAddress == -1) || (readWriteLength == -1)){
|
||||
printf ("Select proper page address and length !!! \n");
|
||||
continue;
|
||||
}
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C){
|
||||
if (pageAddress > 256){
|
||||
printf ("Invalid Page address for I2C .. need to be less than 256\n");
|
||||
continue;
|
||||
}
|
||||
if (readWriteLength > 64){
|
||||
printf ("Invalid read write length for I2C .. need to be less than 64\n");
|
||||
continue;
|
||||
}
|
||||
printf ("Calling I2C \n");
|
||||
i2cVerifyData(glDevice[selectedDeviceNum].deviceNumber, selectedInterfaceNum);
|
||||
}
|
||||
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI){
|
||||
spiVerifyData(glDevice[selectedDeviceNum].deviceNumber, selectedInterfaceNum);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
exitApp = true;
|
||||
CyLibraryExit ();
|
||||
break;
|
||||
}
|
||||
}while (exitApp == false);
|
||||
free (glDevice);
|
||||
}
|
||||
int spiWriteEnable (CY_HANDLE handle)
|
||||
{
|
||||
unsigned char wr_data,rd_data;
|
||||
CY_RETURN_STATUS status = CY_SUCCESS;
|
||||
CY_DATA_BUFFER writeBuf;
|
||||
CY_DATA_BUFFER readBuf;
|
||||
|
||||
writeBuf.buffer = &wr_data;
|
||||
writeBuf.length = 1;
|
||||
|
||||
readBuf.buffer = &rd_data;
|
||||
readBuf.length = 1;
|
||||
|
||||
wr_data = 0x06; /* Write enable */
|
||||
status = CySpiReadWrite (handle, &readBuf, &writeBuf, 5000);
|
||||
if (status != CY_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
//Helper functions for doing data transfer to/from SPI flash
|
||||
int spiWaitForIdle (CY_HANDLE handle)
|
||||
{
|
||||
char rd_data[2], wr_data[2];
|
||||
CY_DATA_BUFFER writeBuf, readBuf;
|
||||
writeBuf.length = 2;
|
||||
writeBuf.buffer = (unsigned char *)wr_data;
|
||||
int timeout = 0xFFFF;
|
||||
CY_RETURN_STATUS status;
|
||||
|
||||
readBuf.length = 2;
|
||||
readBuf.buffer = (unsigned char *)rd_data;
|
||||
do
|
||||
{
|
||||
wr_data[0] = 0x05; /* Status */
|
||||
status = CySpiReadWrite (handle, &readBuf, &writeBuf, 5000);
|
||||
if (status != CY_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
timeout--;
|
||||
if (timeout == 0)
|
||||
{
|
||||
status = CY_ERROR_IO_TIMEOUT;
|
||||
return status;
|
||||
}
|
||||
} while (rd_data[1] & 0x01);
|
||||
return status;
|
||||
}
|
||||
|
||||
int spiVerifyData (int deviceNumber, int interfaceNum)
|
||||
{
|
||||
CY_DATA_BUFFER dataBufferWrite,dataBufferRead;
|
||||
CY_HANDLE handle;
|
||||
bool isVerify = true;
|
||||
unsigned char wbuffer[256 + 4], rbuffer[256 + 4];
|
||||
int rStatus, length;
|
||||
|
||||
memset (rbuffer, 0x00, 256);
|
||||
memset (wbuffer, 0x00, 256);
|
||||
|
||||
rStatus = CyOpen (deviceNumber, interfaceNum, &handle);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
printf ("CY_SPI: Open failed \n");
|
||||
return rStatus;
|
||||
}
|
||||
dataBufferWrite.buffer = wbuffer;
|
||||
dataBufferRead.buffer = rbuffer;
|
||||
|
||||
rStatus = spiWaitForIdle (handle);
|
||||
if (rStatus){
|
||||
printf("Error in Waiting for EEPOM active state %d \n", rStatus);
|
||||
CyClose (handle);
|
||||
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
printf ("Calling spi write enable \n");
|
||||
rStatus = spiWriteEnable (handle);
|
||||
if (rStatus){
|
||||
printf("Error in setting Write Enable %d \n", rStatus);
|
||||
CyClose (handle);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
//Write SPI write command
|
||||
wbuffer[0] = 0x02;
|
||||
//SPI flash address
|
||||
wbuffer[1] = (pageAddress >> 8);
|
||||
wbuffer[2] = (pageAddress) & 0x00FF;
|
||||
wbuffer[3] = 0;
|
||||
|
||||
printf ("The Data written is ...\n");
|
||||
printf ("\n--------------------------------------------------------------------\n");
|
||||
for (rStatus = 4; rStatus < (readWriteLength + 4); rStatus++){
|
||||
wbuffer[rStatus] = rand() % 256;
|
||||
printf ("%x ",wbuffer[rStatus]);
|
||||
}
|
||||
printf ("\n--------------------------------------------------------------------\n");
|
||||
|
||||
dataBufferRead.length = (4 + readWriteLength);
|
||||
dataBufferWrite.length = (4 + readWriteLength);
|
||||
|
||||
rStatus = CySpiReadWrite (handle , &dataBufferRead, &dataBufferWrite, 5000);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
CyClose (handle);
|
||||
printf ("Error in doing SPI data write data Write is %d data read is %d\n" , dataBufferWrite.transferCount,dataBufferRead.transferCount);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
|
||||
spiWaitForIdle (handle);
|
||||
//Write SPI read command
|
||||
wbuffer[0] = 0x03;
|
||||
dataBufferRead.length = (4 + readWriteLength);
|
||||
dataBufferWrite.length = (4 + readWriteLength);
|
||||
|
||||
rStatus = CySpiReadWrite (handle, &dataBufferRead, &dataBufferWrite, 5000);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
CyClose (handle);
|
||||
printf ("The Error is %d \n", rStatus);
|
||||
printf ("Error in doing SPI data write data Write is %d data read is %d\n" , dataBufferWrite.transferCount,dataBufferRead.transferCount);
|
||||
return CY_ERROR_REQUEST_FAILED;
|
||||
}
|
||||
printf ("Data Read back is \n");
|
||||
printf ("\n---------------------------------------------------------------------\n");
|
||||
for (rStatus = 4; rStatus < (readWriteLength + 4); rStatus++){
|
||||
printf ("%x ",rbuffer[rStatus]);
|
||||
if (rbuffer[rStatus] != wbuffer[rStatus]){
|
||||
isVerify = false;
|
||||
}
|
||||
}
|
||||
printf ("\n---------------------------------------------------------------------\n");
|
||||
if (isVerify)
|
||||
printf ("Data verified successfully \n");
|
||||
else
|
||||
printf ("Data corruption occured!!\n");
|
||||
|
||||
CyClose (handle);
|
||||
return CY_SUCCESS;
|
||||
}
|
||||
|
||||
int i2cVerifyData (int deviceNumber, int interfaceNum)
|
||||
{
|
||||
CY_DATA_BUFFER dataBufferWrite, dataBufferRead;
|
||||
CY_HANDLE handle;
|
||||
int length = 0;
|
||||
bool isVerify = true;
|
||||
int loopCount = 100, i;
|
||||
CY_RETURN_STATUS rStatus;
|
||||
unsigned char bytesPending = 0, address[2], wbuffer[66], rbuffer[66];
|
||||
CY_I2C_DATA_CONFIG i2cDataConfig;
|
||||
|
||||
memset (wbuffer, 0, 66);
|
||||
memset (rbuffer, 0, 66);
|
||||
|
||||
i2cDataConfig.isStopBit = true;
|
||||
i2cDataConfig.slaveAddress = 0x51;
|
||||
|
||||
rStatus = CyOpen (deviceNumber, interfaceNum, &handle);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
printf("CY_I2C: Open failed \n");
|
||||
return rStatus;
|
||||
}
|
||||
loopCount = 100;
|
||||
length = readWriteLength;
|
||||
wbuffer[0]= pageAddress;
|
||||
wbuffer[1] = 0;
|
||||
dataBufferWrite.buffer = wbuffer;
|
||||
i2cDataConfig.isStopBit = true;
|
||||
dataBufferWrite.length = (length + 2);
|
||||
printf ("\n Data that is written on to i2c ...\n");
|
||||
printf ("\n-----------------------------------------------------------------\n");
|
||||
for (i = 2; i < (length +2); i++){
|
||||
wbuffer[i] = rand() % 256;
|
||||
printf ("%x ", wbuffer[i]);
|
||||
}
|
||||
printf ("\n-----------------------------------------------------------------\n");
|
||||
rStatus = CyI2cWrite (handle, &i2cDataConfig, &dataBufferWrite, 5000);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
printf ("Error in doing i2c write \n");
|
||||
CyClose (handle);
|
||||
return -1;
|
||||
}
|
||||
//We encountered a error in I2C read repeat the procedure again
|
||||
//Loop here untill Read vendor command passes
|
||||
i2cDataConfig.isStopBit = false;
|
||||
dataBufferWrite.length = 2;
|
||||
|
||||
do {
|
||||
rStatus = CyI2cWrite (handle, &i2cDataConfig, &dataBufferWrite, 5000);
|
||||
loopCount--;
|
||||
}while (rStatus != CY_SUCCESS && loopCount != 0);
|
||||
|
||||
if (loopCount == 0 && rStatus != CY_SUCCESS){
|
||||
printf ("Error in sending read command \n");
|
||||
CyClose (handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dataBufferRead.buffer = rbuffer;
|
||||
rbuffer[0]= address[0];
|
||||
rbuffer[1] = 0;
|
||||
i2cDataConfig.isStopBit = true;
|
||||
i2cDataConfig.isNakBit = true;
|
||||
dataBufferRead.length = length;
|
||||
dataBufferRead.buffer = rbuffer;
|
||||
|
||||
memset (rbuffer, 0, 64);
|
||||
|
||||
rStatus = CyI2cRead (handle, &i2cDataConfig, &dataBufferRead, 5000);
|
||||
if (rStatus != CY_SUCCESS){
|
||||
printf ("Error in doing i2c read ... Error is %d \n", rStatus);
|
||||
CyClose (handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf ("\n Data that is read from i2c ...\n");
|
||||
printf ("\n-----------------------------------------------------------------\n");
|
||||
for (rStatus = 0; rStatus < length; rStatus++){
|
||||
printf ("%x ", rbuffer[rStatus]);
|
||||
if (rbuffer[rStatus] != wbuffer[rStatus + 2]){
|
||||
isVerify = false;
|
||||
}
|
||||
}
|
||||
printf ("\n-----------------------------------------------------------------\n");
|
||||
if (!isVerify)
|
||||
printf ("Data corruption occured ..!!!\n");
|
||||
else
|
||||
printf ("Data verified successfully \n");
|
||||
|
||||
CyClose (handle);
|
||||
}
|
||||
bool isCypressDevice (int deviceNum) {
|
||||
CY_HANDLE handle;
|
||||
unsigned char interfaceNum = 0;
|
||||
unsigned char sig[6];
|
||||
CY_RETURN_STATUS rStatus;
|
||||
rStatus = CyOpen (deviceNum, interfaceNum, &handle);
|
||||
if (rStatus == CY_SUCCESS){
|
||||
rStatus = CyGetSignature (handle, sig);
|
||||
if (rStatus == CY_SUCCESS){
|
||||
CyClose (handle);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
CyClose (handle);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
void printListOfDevices (bool isPrint)
|
||||
{
|
||||
int index_i = 0, index_j = 0, i, j, countOfDevice = 0, devNum;
|
||||
int length, index = 0, numInterfaces, interfaceNum;
|
||||
bool set1 = false;
|
||||
|
||||
unsigned char deviceID[CY_MAX_DEVICES];
|
||||
unsigned char functionality[64];
|
||||
CY_DEVICE_INFO deviceInfo;
|
||||
CY_DEVICE_CLASS deviceClass[CY_MAX_INTERFACES];
|
||||
CY_DEVICE_TYPE deviceType[CY_MAX_INTERFACES];
|
||||
CY_RETURN_STATUS rStatus;
|
||||
|
||||
deviceAddedRemoved = false;
|
||||
CyGetListofDevices (&numDevices);
|
||||
//printf ("The number of devices is %d \n", numDevices);
|
||||
for (i = 0; i < numDevices; i++){
|
||||
for (j = 0; j< CY_MAX_INTERFACES; j++)
|
||||
glDevice[i].interfaceFunctionality[j] = -1;
|
||||
}
|
||||
if (isPrint){
|
||||
printf ("\n\n---------------------------------------------------------------------------------\n");
|
||||
printf ("Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY \n");
|
||||
printf ("---------------------------------------------------------------------------------\n");
|
||||
}
|
||||
cyDevices = 0;
|
||||
for (devNum = 0; devNum < numDevices; devNum++){
|
||||
rStatus = CyGetDeviceInfo (devNum, &deviceInfo);
|
||||
interfaceNum = 0;
|
||||
if (!rStatus)
|
||||
{
|
||||
if (!isCypressDevice (devNum)){
|
||||
continue;
|
||||
}
|
||||
strcpy (functionality, "NA");
|
||||
numInterfaces = deviceInfo.numInterfaces;
|
||||
glDevice[index].numInterface = numInterfaces;
|
||||
cyDevices++;
|
||||
|
||||
while (numInterfaces){
|
||||
if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_VENDOR)
|
||||
{
|
||||
glDevice[index].deviceNumber = devNum;
|
||||
switch (deviceInfo.deviceType[interfaceNum]){
|
||||
case CY_TYPE_I2C:
|
||||
glDevice[index].interfaceFunctionality[interfaceNum] = CY_TYPE_I2C;
|
||||
strcpy (functionality, "VENDOR_I2C");
|
||||
glDevice[index].isI2c = true;
|
||||
break;
|
||||
case CY_TYPE_SPI:
|
||||
glDevice[index].interfaceFunctionality[interfaceNum] = CY_TYPE_SPI;
|
||||
strcpy (functionality, "VENDOR_SPI");
|
||||
glDevice[index].isSpi = true;
|
||||
break;
|
||||
default:
|
||||
strcpy (functionality, "NA");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_CDC){
|
||||
strcpy (functionality, "NA");
|
||||
}
|
||||
if (isPrint) {
|
||||
printf ("%d |%x |%x | %d | %s\n", \
|
||||
index, \
|
||||
deviceInfo.vidPid.vid, \
|
||||
deviceInfo.vidPid.pid, \
|
||||
interfaceNum, \
|
||||
functionality \
|
||||
);
|
||||
}
|
||||
interfaceNum++;
|
||||
numInterfaces--;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (isPrint){
|
||||
printf ("---------------------------------------------------------------------------------\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user