From d5f9c52f036335f882ecb765c35495b73c0e994b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristjan=20Komlo=C5=A1i=20=40=20Home?= Date: Tue, 15 Aug 2017 15:14:00 +0200 Subject: [PATCH] repairing... just repairing... --- autobuilder | 16 +- configutility/README.txt | 36 + configutility/common/header/CyUSBBootloader.h | 447 +++ configutility/common/header/CyUSBSerial.h | 1845 +++++++++++++ .../license/license.txt | 1006 +++---- configutility/linux/library/90-cyusb.rules | 5 + configutility/linux/library/CyUSBCommon.h | 219 ++ configutility/linux/library/Makefile | 20 + configutility/linux/library/cyboot.c | 668 +++++ .../linux/library}/cyi2c.c | 1376 +++++----- .../linux/library}/cyjtag.c | 495 ++-- .../linux/library}/cymisc.c | 1175 ++++---- .../linux/library}/cyphdc.c | 260 +- .../linux/library}/cyspi.c | 1288 ++++----- .../linux/library}/cyuart.c | 1177 ++++---- .../linux/library}/cyusb.c | 1281 ++++----- configutility/linux/library/libcyusbserial.so | 1 + .../linux/library/libcyusbserial.so.1 | Bin 0 -> 109320 bytes .../linux/testUtility/90-cyusb.rules | 5 + .../linux/testUtility/Command_Utility.c | 667 +++-- .../linux/testUtility}/CyUSBBootloader.h | 0 .../linux/testUtility/CyUSBSerial.sh | 7 + .../testUtility/CyUSBSerialCommandUtility | Bin 0 -> 26424 bytes configutility/linux/testUtility/Makefile | 12 + .../linux/testUtility}/README.txt | 52 +- configutility/linux/testUtility/jbiexprt.h | 224 ++ configutility/linux/testUtility/jbiport.h | 43 + cy-config.o | Bin 11312 -> 0 bytes cylib | 1 + cylib/CMakeLists.txt | 142 - cylib/Doxyfile | 2437 ----------------- cylib/README.md | 38 - cylib/appveyor.yml | 23 - cylib/build/CMakeCache.txt | 415 --- .../CMakeFiles/3.7.2/CMakeCCompiler.cmake | 68 - .../3.7.2/CMakeDetermineCompilerABI_C.bin | Bin 8568 -> 0 bytes .../build/CMakeFiles/3.7.2/CMakeSystem.cmake | 15 - .../3.7.2/CompilerIdC/CMakeCCompilerId.c | 561 ---- .../build/CMakeFiles/3.7.2/CompilerIdC/a.out | Bin 8728 -> 0 bytes .../CMakeDirectoryInformation.cmake | 16 - cylib/build/CMakeFiles/CMakeError.log | 55 - cylib/build/CMakeFiles/CMakeOutput.log | 227 -- cylib/build/CMakeFiles/Makefile.cmake | 58 - cylib/build/CMakeFiles/Makefile2 | 199 -- cylib/build/CMakeFiles/TargetDirectories.txt | 26 - cylib/build/CMakeFiles/cmake.check_cache | 1 - cylib/build/CMakeFiles/feature_tests.bin | Bin 8528 -> 0 bytes cylib/build/CMakeFiles/feature_tests.c | 34 - cylib/build/CMakeFiles/progress.marks | 1 - cylib/build/Makefile | 210 -- cylib/build/cmake_install.cmake | 52 - .../CMakeDirectoryInformation.cmake | 16 - cylib/build/include/CMakeFiles/progress.marks | 1 - cylib/build/include/Makefile | 182 -- cylib/build/include/cmake_install.cmake | 38 - cylib/build/install_manifest.txt | 4 - .../CMakeDirectoryInformation.cmake | 16 - .../CMakeFiles/cyusbserial.dir/C.includecache | 80 - .../cyusbserial.dir/DependInfo.cmake | 35 - .../lib/CMakeFiles/cyusbserial.dir/build.make | 280 -- .../cyusbserial.dir/cmake_clean.cmake | 17 - .../lib/CMakeFiles/cyusbserial.dir/cyi2c.c.o | Bin 9264 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cyjtag.c.o | Bin 3128 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cymisc.c.o | Bin 8216 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cyphdc.c.o | Bin 2200 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cyspi.c.o | Bin 9072 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cyuart.c.o | Bin 5936 -> 0 bytes .../lib/CMakeFiles/cyusbserial.dir/cyusb.c.o | Bin 11240 -> 0 bytes .../cyusbserial.dir/depend.internal | 38 - .../CMakeFiles/cyusbserial.dir/depend.make | 38 - .../lib/CMakeFiles/cyusbserial.dir/flags.make | 10 - .../lib/CMakeFiles/cyusbserial.dir/link.txt | 1 - .../CMakeFiles/cyusbserial.dir/progress.make | 9 - cylib/build/lib/CMakeFiles/progress.marks | 1 - cylib/build/lib/Makefile | 408 --- cylib/build/lib/cmake_install.cmake | 67 - cylib/build/lib/libcyusbserial.so | 1 - cylib/build/lib/libcyusbserial.so.1 | Bin 46456 -> 0 bytes .../CMakeDirectoryInformation.cmake | 16 - .../cyusbserialtest.dir/C.includecache | 36 - .../cyusbserialtest.dir/DependInfo.cmake | 22 - .../CMakeFiles/cyusbserialtest.dir/build.make | 115 - .../cyusbserialtest.dir/cmake_clean.cmake | 10 - .../cyusbserialtest.dir/cyusbserialtest.c.o | Bin 18848 -> 0 bytes .../cyusbserialtest.dir/depend.internal | 6 - .../cyusbserialtest.dir/depend.make | 6 - .../CMakeFiles/cyusbserialtest.dir/flags.make | 10 - .../CMakeFiles/cyusbserialtest.dir/link.txt | 1 - .../cyusbserialtest.dir/progress.make | 3 - cylib/build/tools/CMakeFiles/progress.marks | 1 - cylib/build/tools/Makefile | 228 -- cylib/build/tools/cmake_install.cmake | 54 - cylib/build/tools/cyusbserialtest | Bin 22624 -> 0 bytes cylib/cmake/helpers/libusb_version.c | 46 - .../cmake/modules/FindLibPThreadsWin32.cmake | 97 - cylib/cmake/modules/FindLibUSB.cmake | 168 -- cylib/include/CMakeLists.txt | 9 - cylib/include/CyUSBSerial.h | 1622 ----------- cylib/lib/CMakeLists.txt | 156 -- cylib/lib/CyUSBCommon.h | 255 -- cylib/libcyusbserial-master/.gitignore | 32 - cylib/libcyusbserial-master/.travis.yml | 72 - cylib/tools/CMakeLists.txt | 23 - cylib/tools/cyusbserialtest.c | 603 ---- cylib/windows/gettimeofday.c | 119 - cylib/windows/include/c99/inttypes.h | 309 --- cylib/windows/include/c99/stdbool.h | 47 - cylib/windows/include/sys/time.h | 3 - cylib/windows/usleep.c | 14 - docs/newmanual.md | 168 +- {tinio/flash => flash}/3-3cs_decrypted.cyusbd | Bin {tinio => flash}/5-5_decrypted.cyusbd | Bin package.zip | Bin 180542 -> 0 bytes tinio.o | Bin 16128 -> 0 bytes tinio/Makefile | 14 +- tinio/cy-config | Bin 18616 -> 0 bytes tinio/flash/5-5_decrypted.cyusbd | Bin 528 -> 0 bytes tinio/include/CyUSBSerial.h | 1622 ----------- tinio/tinio.cpp | 2 +- tool | 1 + 120 files changed, 8120 insertions(+), 15916 deletions(-) create mode 100644 configutility/README.txt create mode 100644 configutility/common/header/CyUSBBootloader.h create mode 100644 configutility/common/header/CyUSBSerial.h rename cylib/COPYING.LESSER.txt => configutility/license/license.txt (97%) create mode 100644 configutility/linux/library/90-cyusb.rules create mode 100644 configutility/linux/library/CyUSBCommon.h create mode 100644 configutility/linux/library/Makefile create mode 100644 configutility/linux/library/cyboot.c rename {cylib/lib => configutility/linux/library}/cyi2c.c (81%) rename {cylib/lib => configutility/linux/library}/cyjtag.c (88%) rename {cylib/lib => configutility/linux/library}/cymisc.c (86%) rename {cylib/lib => configutility/linux/library}/cyphdc.c (95%) rename {cylib/lib => configutility/linux/library}/cyspi.c (91%) rename {cylib/lib => configutility/linux/library}/cyuart.c (90%) rename {cylib/lib => configutility/linux/library}/cyusb.c (87%) create mode 100644 configutility/linux/library/libcyusbserial.so create mode 100755 configutility/linux/library/libcyusbserial.so.1 create mode 100644 configutility/linux/testUtility/90-cyusb.rules rename tinio/cy-config.c => configutility/linux/testUtility/Command_Utility.c (90%) rename {tinio/include => configutility/linux/testUtility}/CyUSBBootloader.h (100%) create mode 100644 configutility/linux/testUtility/CyUSBSerial.sh create mode 100755 configutility/linux/testUtility/CyUSBSerialCommandUtility create mode 100644 configutility/linux/testUtility/Makefile rename {cylib/tools => configutility/linux/testUtility}/README.txt (65%) create mode 100644 configutility/linux/testUtility/jbiexprt.h create mode 100644 configutility/linux/testUtility/jbiport.h delete mode 100644 cy-config.o create mode 120000 cylib delete mode 100644 cylib/CMakeLists.txt delete mode 100644 cylib/Doxyfile delete mode 100644 cylib/README.md delete mode 100644 cylib/appveyor.yml delete mode 100644 cylib/build/CMakeCache.txt delete mode 100644 cylib/build/CMakeFiles/3.7.2/CMakeCCompiler.cmake delete mode 100755 cylib/build/CMakeFiles/3.7.2/CMakeDetermineCompilerABI_C.bin delete mode 100644 cylib/build/CMakeFiles/3.7.2/CMakeSystem.cmake delete mode 100644 cylib/build/CMakeFiles/3.7.2/CompilerIdC/CMakeCCompilerId.c delete mode 100755 cylib/build/CMakeFiles/3.7.2/CompilerIdC/a.out delete mode 100644 cylib/build/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 cylib/build/CMakeFiles/CMakeError.log delete mode 100644 cylib/build/CMakeFiles/CMakeOutput.log delete mode 100644 cylib/build/CMakeFiles/Makefile.cmake delete mode 100644 cylib/build/CMakeFiles/Makefile2 delete mode 100644 cylib/build/CMakeFiles/TargetDirectories.txt delete mode 100644 cylib/build/CMakeFiles/cmake.check_cache delete mode 100755 cylib/build/CMakeFiles/feature_tests.bin delete mode 100644 cylib/build/CMakeFiles/feature_tests.c delete mode 100644 cylib/build/CMakeFiles/progress.marks delete mode 100644 cylib/build/Makefile delete mode 100644 cylib/build/cmake_install.cmake delete mode 100644 cylib/build/include/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 cylib/build/include/CMakeFiles/progress.marks delete mode 100644 cylib/build/include/Makefile delete mode 100644 cylib/build/include/cmake_install.cmake delete mode 100644 cylib/build/install_manifest.txt delete mode 100644 cylib/build/lib/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/C.includecache delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/DependInfo.cmake delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/build.make delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cmake_clean.cmake delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyi2c.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyjtag.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cymisc.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyphdc.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyspi.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyuart.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/cyusb.c.o delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/depend.internal delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/depend.make delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/flags.make delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/link.txt delete mode 100644 cylib/build/lib/CMakeFiles/cyusbserial.dir/progress.make delete mode 100644 cylib/build/lib/CMakeFiles/progress.marks delete mode 100644 cylib/build/lib/Makefile delete mode 100644 cylib/build/lib/cmake_install.cmake delete mode 120000 cylib/build/lib/libcyusbserial.so delete mode 100755 cylib/build/lib/libcyusbserial.so.1 delete mode 100644 cylib/build/tools/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/C.includecache delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/DependInfo.cmake delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/build.make delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/cmake_clean.cmake delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/cyusbserialtest.c.o delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/depend.internal delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/depend.make delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/flags.make delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/link.txt delete mode 100644 cylib/build/tools/CMakeFiles/cyusbserialtest.dir/progress.make delete mode 100644 cylib/build/tools/CMakeFiles/progress.marks delete mode 100644 cylib/build/tools/Makefile delete mode 100644 cylib/build/tools/cmake_install.cmake delete mode 100755 cylib/build/tools/cyusbserialtest delete mode 100644 cylib/cmake/helpers/libusb_version.c delete mode 100644 cylib/cmake/modules/FindLibPThreadsWin32.cmake delete mode 100644 cylib/cmake/modules/FindLibUSB.cmake delete mode 100644 cylib/include/CMakeLists.txt delete mode 100644 cylib/include/CyUSBSerial.h delete mode 100644 cylib/lib/CMakeLists.txt delete mode 100644 cylib/lib/CyUSBCommon.h delete mode 100644 cylib/libcyusbserial-master/.gitignore delete mode 100644 cylib/libcyusbserial-master/.travis.yml delete mode 100644 cylib/tools/CMakeLists.txt delete mode 100644 cylib/tools/cyusbserialtest.c delete mode 100644 cylib/windows/gettimeofday.c delete mode 100644 cylib/windows/include/c99/inttypes.h delete mode 100644 cylib/windows/include/c99/stdbool.h delete mode 100644 cylib/windows/include/sys/time.h delete mode 100644 cylib/windows/usleep.c rename {tinio/flash => flash}/3-3cs_decrypted.cyusbd (100%) rename {tinio => flash}/5-5_decrypted.cyusbd (100%) delete mode 100644 package.zip delete mode 100644 tinio.o delete mode 100755 tinio/cy-config delete mode 100755 tinio/flash/5-5_decrypted.cyusbd delete mode 100644 tinio/include/CyUSBSerial.h create mode 120000 tool diff --git a/autobuilder b/autobuilder index 2c3c665..5dcbd49 100755 --- a/autobuilder +++ b/autobuilder @@ -25,24 +25,30 @@ echo " --------------------------" #fancy banner! echo " Autobuilder for TinI/O 0.1" echo " --------------------------" echo " Verifying main directory..." -[ -d cylib ] && [ -d tinio ] && proceed=1 #check if we're in the right dir +[ -d configutility ] && [ -d tinio ] && proceed=1 #check if we're in the right dir proceed #error check echo " DONE!" echo " Entering the library directory..." -cd cylib/build && proceed=1 #cd to the lib dir +cd cylib && proceed=1 #cd to the lib dir proceed #error check echo " DONE!" echo " Compiling and installing the library..." -cmake .. && make && sudo make install && proceed=1 #compiles the lib - #according to the lib docs +make && proceed=1 #compiles the lib according to the lib docs proceed echo " DONE!" echo " Library installation complete." echo " Going back..." -cd ../.. && proceed=1 #goes from cylib/build to cylib then to main dir +cd .. && proceed=1 #to main dir proceed echo " DONE!" sleep 1 # sleep for 1 sec to let the user see the output echo " Entering the TinI/O build directory" cd tinio && proceed=1 echo " DONE!" +proceed +echo " Compiling TinI/O..." +cd tinio && make && make install && proceed=1 +proceed +echo " DONE!" +echo " Compiling the flasher tool" +cd ../tool && make && proceed=1 diff --git a/configutility/README.txt b/configutility/README.txt new file mode 100644 index 0000000..96450c3 --- /dev/null +++ b/configutility/README.txt @@ -0,0 +1,36 @@ +======================================================================================== + 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 the library source files are extracted and goto ./linux/library + +2.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.Go to ./linux/testUtility (I2C/SPI test utility program) and type 'sudo make'. +This will generate CyUSBSerialTestUtility binary (Refer to README in testUtility folder). + +4.User can launch the application and test the communication with Cypress USB-Serial DVk in vendor mode. + +Changing USB device node permission: + +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). + +*** IMPORTANT: +Some distribution of linux have libusb (older version) as part of their package. Uninstall +the older version and update it with libusb-1.0.9. + +**Note: +Refer to ./common/doc/CyUSBSerial API documentation.pdf for description of all +the vendor mode APIs. The header file of the library is in ./common/header/CyUSBSerial.h. diff --git a/configutility/common/header/CyUSBBootloader.h b/configutility/common/header/CyUSBBootloader.h new file mode 100644 index 0000000..f68f7d7 --- /dev/null +++ b/configutility/common/header/CyUSBBootloader.h @@ -0,0 +1,447 @@ +/* +## Cypress USB Serial Library header file (CyUSBSerial.h) +## =========================== +## +## Copyright Cypress Semiconductor Corporation, 2012-2013, +## All Rights Reserved +## UNPUBLISHED, LICENSED SOFTWARE. +## +## CONFIDENTIAL AND PROPRIETARY INFORMATION +## WHICH IS THE PROPERTY OF CYPRESS. +## +## Use of this file is governed +## by the license agreement included in the file +## +## /license/license.txt +## +## where is the Cypress software +## installation root directory path. +## +## =========================== +*/ + +#ifndef _INCLUDED_CYUSBBOOTLOADER_H_ +#define _INCLUDED_CYUSBBOOTLOADER_H_ + +/*This is to export windows API*/ +#ifdef CYWINEXPORT +#undef CYWINEXPORT +#endif +#ifdef WIN32 + +#ifdef CYUSBSERIAL_EXPORTS + #define CYWINEXPORT extern "C" __declspec(dllexport) + #define WINCALLCONVEN + #else + #define CYWINEXPORT extern "C" __declspec(dllimport) + #define WINCALLCONVEN + #endif +#else /*Linux and MAC*/ + #define CYWINEXPORT + #define WINCALLCONVEN + #ifndef BOOL + typedef bool BOOL; + #endif +#endif + + + +#include "CyUSBSerial.h" + +/* Summary +Enumeration defining return status of USB serial library APIs + +Description +The enumeration CY_RETURN_STATUS holds the different return status of all the +APIs supported by USB Serial library. +*/ + /*API Failed because the SPI/UART status monitor thread already exists*/ +/* +Summary +Structure to hold Boot mode data buffer information. + +Description +This strucuture is used by boot mode data transaction API to perform read, write +operations. + +Before using a variable of this strucutre users need to initialize various members appropriately. + buffer - Need to be initialized to pre-allocated memory only, and user is + expected to deallocate the memory in his application. + length - Contains total length the buffer to be used while performing + read/write operations. + bytesReturned - Specifies the number of bytes actually read/written. + address - Address from where the data need to written/read + +See Also +CyReadFlash +CyProgFlash +CyVerifyFlash +CyReadMemory +CyWriteMemory + +CY_BOOTLOADER_VERSION +*/ +typedef struct _CY_BOOTLD_BUFFER { + + UCHAR *buffer; /*Address of the buffer*/ + UINT32 length; /*total length to be read/written */ + UINT32 *bytesReturned; /*Total length of bytes that was written/read*/ + UINT32 address; /*Address from where data needs to be written/read in device*/ + +} CY_BOOTLD_BUFFER,*PCY_BOOTLD_BUFFER; + +/* +Summary +This structure is used to hold Boot loader version. + +Description +This data type holds the information of version of the bootloader in device. It has major version, +minor version and patch number. + +See Also +CY_BOOTLD_BUFFER +*/ +typedef struct _CY_BOOTLOADER_VERSION { + + UCHAR majorVersion; /*Major version of BootLoader*/ + UCHAR minorVersion; /*Minor version of the BootLoader*/ + UINT16 patchNumber; /*Patch Number of the BootLoader*/ + +} CY_BOOTLOADER_VERSION; + + +/*************************************************************************************/ +/****************************BOOTLOADER API'S*****************************************/ +/*************************************************************************************/ + +/*@@BOOTLoader API + +These APIs provide an interface for configuring the device when it is in BOOT mode. + +The API's under this group gives user to option to configure the device when the device is in BOOT +mode. The APIs include support for device configuration, SCB level configuration, USB interface +configuration, checksum, firmware download. + +*/ + + +/* +Summary +This API retrieves the BootLoader version. + +Description +This API gets the bootloader version of the USB Serial device. + + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyGetSiliconID + +CY_BOOTLOADER_VERSION +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyGetBootLoaderVersion ( + CY_HANDLE handle, /*Valid device handle*/ + CY_BOOTLOADER_VERSION *bootLoaderVersion /*Boot Loader version.*/ + ); +/* +Summary +This API retrieves the silicon ID. + +Description +This API gets the silicon ID of the USB Serial device into the argument siliconID. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyGetBootLoaderVersion + +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyGetSiliconID ( + CY_HANDLE handle, /*Valid device handle*/ + UINT32 *siliconID /*Boot Loader version.*/ + ); + +/* +Summary +This API can be used to change the device operational mode from device firmware to bootloader. + +Description +This API changes the device operational mode from device firmware to bootloader or +Manufacturing mode. + +Call the API GetSignature to identify the current operational mode. This API should be called only +when the device is in firmware mode. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyGetSignature + +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyJumpToMfgMode ( + CY_HANDLE handle); + +/* +Summary +This API can be used to read device configuration + +Description +This API reads the device configuration from the device configuration table. It fills the device +configuration as a series of bytes in the argument deviceConfig + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyWriteDeviceConfig +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyReadDeviceConfig ( + CY_HANDLE handle, /* Valid device handle*/ + UCHAR *deviceConfig /* Device configuration value.*/ + ); + +/* +Summary +This API can be used to update the device configuration table. + +Description; +This API updates the device configuration in the configuration table of device. The device +configuration must be supplied as an array of bytes. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyReadDeviceConfig + +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyWriteDeviceConfig ( + CY_HANDLE handle, /*Valid Device handle*/ + UCHAR *deviceConfig /*Device configuration value */ + ); + +/* +Summary +This API can be used to read the content of flash from specified address. + +Description +The readBuffer structure must be filled and with address to be read from, appropriate buffer +and number of bytes to be read. + +The actual bytes read will be available in bytesReturned member of CY_BOOTLD_BUFFER. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CY_BOOTLD_BUFFER +CyProgFlash +CyVerifyFlash +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyReadFlash ( + CY_HANDLE handle, /*Valid device handle*/ + CY_BOOTLD_BUFFER *readBuffer, /*Buffer pointer containing buffer address, length and address of flash*/ + UINT32 timeout /*API timeout value*/ + ); + +/* +Summary +This API can be used to program the flash at specified address. + +Description +The writeBuffer structure must be filled and with address to be written to, appropriate buffer location +and number of bytes to be written. + +The actual bytes written will be available in bytesReturned member of CY_BOOTLD_BUFFER. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CY_BOOTLD_BUFFER +CyReadFlash +CyVerifyFlash +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyProgFlash ( + CY_HANDLE handle, /*Valid device handle*/ + CY_BOOTLD_BUFFER *writeBuffer, /*Buffer pointer containing the address of buffer pointer, length and address of flash*/ + UINT32 timeout /*API timeout value*/ + ); +/* +Summary +This API can be used to read the memory content of SRAM from specified address. + +Description +This API reads the content of flash in USB Serial device. The argument readBuffer need to be +initialized with address, number of bytes to be read and buffer location before invoking +this API. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CY_BOOTLD_BUFFER +CyWriteMemory + +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyReadMemory ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + CY_BOOTLD_BUFFER *readBuffer, /*Bootloader read buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* +Summary +This API can be used to write content to SRAM at specified address. + +Description +This API writes the buffer content to SRAM. The argument writeBuffer need to be initialized with +target address, number of bytes to be written and buffer location before invoking this API. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CY_BOOTLD_BUFFER +CyReadMemory +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyWriteMemory ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + CY_BOOTLD_BUFFER *writeBuffer, /*Bootloader write buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* +Summary +This API can be used calculate the checksum of the firmware loaded and compares it with the checksum in +device configuration table. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyUpdateChecksum +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyValidateChecksum ( + CY_HANDLE handle /*Valid handle to communicate with device*/ + ); +/* +Summary +This API can be used to read boot configuration. + +Description +This API reads the boot configuration from the boot configuration table of device. The bootConfig +need to be parsed to obtain actual configuration values. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyWriteBootConfig + +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyReadBootConfig ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + UCHAR *bootConfig /*Current Boot configuration value read back*/ + ); +/* +Summary +This API updates the device boot configuration table. + +Description; +This API updates the boot configuration in the boot configuration table of device. +The bootConfig is pointer to an array of bytes contain the configuration. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyReadBootConfig +*/ + +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyWriteBootConfig ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + UCHAR *bootConfig /*Boot configuration value to be updated*/ + ); +/* +Summary +This API can be used to download firmware on to USB Serial device. + +Description; +This API downloads the firmware specified in filePath on to flash of the USB Serial device. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyReadBootConfig +CyWriteBootConfig +CyReadFlash +CyProgFlash +CyReadMemory +CyWriteMemory +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyDownloadFirmware ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + CHAR *filePath /*Path of Firmware file*/ + ); + +/* +Summary +This API can be used enable flash configuration on USB Serial device. + +Description; +This API configures the the firmware and allows user to enable/diable flash changes. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyReadBootConfig +CyWriteBootConfig +CyReadFlash +CyProgFlash +CyReadMemory +CyWriteMemory +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyFlashConfigEnable ( + CY_HANDLE handle, /*Valid handle to communicate with device*/ + BOOL enable /*Set to TRUE to enable flash configuration + FALSE to disable flash configuration */ + ); + +/* +Summary +This API can be used to obtain the Silicon Serial No. + +Description; +This API can be used to obtain the Silicon Serial No. + +Return Value +CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + +See Also +CyReadBootConfig +CyWriteBootConfig +CyReadFlash +CyProgFlash +CyReadMemory +CyWriteMemory +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetSiliconSerialID ( + CY_HANDLE handle, /*Valid device handle*/ + UCHAR buffer[8] /*Buffer to contain 8 bytes of data.*/ + ); + +#endif /* _INCLUDED_CYUSBBOOTLOADER_H_ */ diff --git a/configutility/common/header/CyUSBSerial.h b/configutility/common/header/CyUSBSerial.h new file mode 100644 index 0000000..138ad40 --- /dev/null +++ b/configutility/common/header/CyUSBSerial.h @@ -0,0 +1,1845 @@ +/* +## Cypress USB Serial Library header file (CyUSBSerial.h) +## =========================== +## +## Copyright Cypress Semiconductor Corporation, 2012-2013, +## All Rights Reserved +## UNPUBLISHED, LICENSED SOFTWARE. +## +## CONFIDENTIAL AND PROPRIETARY INFORMATION +## WHICH IS THE PROPERTY OF CYPRESS. +## +## Use of this file is governed +## by the license agreement included in the file +## +## /license/license.txt +## +## where is the Cypress software +## installation root directory path. +## +## =========================== +*/ +#ifndef _INCLUDED_CYUSBSERIAL_H_ +#define _INCLUDED_CYUSBSERIAL_H_ + +#ifdef __cplusplus + #define CppCALLCONVEN extern "C" +#else + #define CppCALLCONVEN +#endif + +/*This is to export Windows API*/ +#ifdef WIN32 + #ifdef CYUSBSERIAL_EXPORTS + #define CYWINEXPORT CppCALLCONVEN __declspec(dllexport) + #define WINCALLCONVEN + #define LINUXCALLCONVEN + #else + #define CYWINEXPORT CppCALLCONVEN __declspec(dllimport) + #define WINCALLCONVEN + #define LINUXCALLCONVEN + #endif +#else /*Linux and MAC*/ + #define CYWINEXPORT CppCALLCONVEN + #define WINCALLCONVEN + #define LINUXCALLCONVEN + #ifndef BOOL + typedef bool BOOL; + #endif +#endif +/*************************************************************************************/ +/*******************************Constants*********************************************/ +/*************************************************************************************/ + +/*@@Constants +This section contains details of the all the constants +that are part of Cypress USB Serial driver library. +*/ +#define CY_STRING_DESCRIPTOR_SIZE 256 /*String descriptor size */ +#define CY_MAX_DEVICE_INTERFACE 5 /*Maximum number of interfaces */ + +/* +Summary +This section contains USB Serial library version information. +*/ + +/* Major version number for library. */ +#define CY_US_VERSION_MAJOR (1) + +/* Minor version number for library. */ +#define CY_US_VERSION_MINOR (0) + +/* Patch version number for library. */ +#define CY_US_VERSION_PATCH (0) + +/* Version number for the device. */ +#define CY_US_VERSION ((CY_US_VERSION_MAJOR) | \ + (CY_US_VERSION_MINOR << 8) | \ + (CY_US_VERSION_PATCH << 16)) +/* Library build number. */ +#define CY_US_VERSION_BUILD (59) + + +/*************************************************************************************/ +/****************************Data Type Definitions************************************/ +/*************************************************************************************/ + +/*@@Data Types +This section defines the data types that are used by +Cypress USB Serial driver library. +*/ +#ifndef UINT32 + typedef unsigned int UINT32; +#endif +#ifndef UINT8 + typedef unsigned char UINT8; +#endif +#ifndef UINT16 + typedef unsigned short UINT16; +#endif +#ifndef CHAR + typedef char CHAR; +#endif +#ifndef UCHAR + typedef unsigned char UCHAR; +#endif + +/* Summary + CyUSB Device Handle. + + Description + The handle is used by application to communicate with USB serial device. + The handle is obtained by calling CyOpen. + + See Also + * CyOpen +*/ +typedef void* CY_HANDLE; + +/* +Summary +Function pointer for getting async error/success notification on UART/SPI + +Description +This function pointer that will be passed to CySetEventNotification and get +a callback with a 2 byte value bit map that reports error/events triggered during UART/SPI transaction. +The bit map is defined in CY_CALLBACK_EVENTS. + +See also +* CY_CALLBACK_EVENTS +*/ +typedef void (*CY_EVENT_NOTIFICATION_CB_FN)(UINT16 eventsNotified); + +/* +Summary +This structure is used to hold VID and PID of USB device + +Description +This Strucuture holds the VID and PID of a USB device. + +See Also +* CY_DEVICE_INFO +* CyGetDeviceInfoVidPid +*/ +typedef struct _CY_VID_PID { + + UINT16 vid; /*Holds the VID of the device*/ + UINT16 pid; /*Holds the PID of the device*/ + +} CY_VID_PID, *PCY_VID_PID; + +/* Summary +This structure is used to hold version information of the library. + +Description +This structure can be used to retrive the version information of the library. + +See Also +* CyGetLibraryVersion +*/ +typedef struct _CY_LIBRARY_VERSION { + + UINT8 majorVersion; /*The major version of the library*/ + UINT8 minorVersion; /*The minor version of the library*/ + UINT16 patch; /*The patch number of the library*/ + UINT8 buildNumber; /*The build number of the library*/ + +} CY_LIBRARY_VERSION, *PCY_LIBRARY_VERSION; + +/* +Summary +This structure is used to hold firmware version of the USB Serial device. + +Description +This structure holds the version information of the USB serial device. +It has major version, minor version, patch number and build number. + +See Also +* CyGetFirmwareVersion +*/ +typedef struct _CY_FIRMWARE_VERSION { + + UINT8 majorVersion; /*Major version of the Firmware*/ + UINT8 minorVersion; /*Minor version of the Firmware*/ + UINT16 patchNumber; /*Patch Number of the Firmware*/ + UINT32 buildNumber; /*Build Number of the Firmware*/ + +} CY_FIRMWARE_VERSION, *PCY_FIRMWARE_VERSION; + +/* Summary +Enumeration defining list of USB device classes supported by USB Serial device. + +Description +This is the list of USB device classes supported by USB Serial device. + +See Also +* CY_DEVICE_INFO +* CyGetDeviceInfo +* CyGetDeviceInfoVidPid +*/ +typedef enum _CY_DEVICE_CLASS{ + + CY_CLASS_DISABLED = 0, /*None or the interface is disabled */ + CY_CLASS_CDC = 0x02, /*CDC ACM class*/ + CY_CLASS_PHDC = 0x0F, /*PHDC class */ + CY_CLASS_VENDOR = 0xFF /*VENDOR specific class*/ + +} CY_DEVICE_CLASS; + +/* Summary +Enumeration defining list of device types supported by USB Serial device in each interface. + +Description +This is the list of device types supported by USB Serial device when the interface type is +configured as CY_CLASS_VENDOR. The interface type can be queried from the device by using CyGetDeviceInfo +and CyGetDeviceInfoVidPid APIs. + +The member of CY_DEVICE_INFO structure contains the interface type. + +See Also +* CY_DEVICE_INFO +* CyGetDeviceInfo +* CyGetDeviceInfoVidPid +*/ +typedef enum _CY_DEVICE_TYPE { + + CY_TYPE_DISABLED = 0, /*Invalid device type or interface is not CY_CLASS_VENDOR*/ + CY_TYPE_UART, /*Interface of device is of type UART*/ + CY_TYPE_SPI, /*Interface of device is of type SPI */ + CY_TYPE_I2C, /*Interface of device is of type I2C */ + CY_TYPE_JTAG, /*Interface of device is of type JTAG*/ + CY_TYPE_MFG /*Interface of device is in Manufacturing mode*/ + +} CY_DEVICE_TYPE; + +/* Summary +This enumeration type defines the available device serial blocks. + +Description +USB Serial device has up to two configurable serial blocks. UART, SPI, I2C or JTAG functionality can be +configured and used in these serial block. Windows driver binds to a serial block rather than the entire device. +So, it is essential to find out which serial block to which current communications are directed. These enumeration +structure provides the possible SERIAL BLOCK Options. + +This enumration data type is a member of CY_DEVICE_INFO structure. + +This data type information doesn't apply for non-windows operating system. + +See Also +CY_DEVICE_INFO +CyGetDeviceInfo +CyGetDeviceInfoVidPid +*/ + +typedef enum _CY_DEVICE_SERIAL_BLOCK +{ + SerialBlock_SCB0 = 0, /*Serial Block Number 0*/ + SerialBlock_SCB1, /*Serial Block Number 1*/ + SerialBlock_MFG /*Serial Block Manufacturing Interface.*/ + +} CY_DEVICE_SERIAL_BLOCK; + +/* Summary +Structure to hold information of the device connected to host. + +Description +The structure holds the information about device currently connected to host. The information +can be obtained by using CyGetDeviceInfo and CyGetDeviceInfoVidPid APIs. + +The information includes VID, PID, number of interfaces, string descriptors, device type +and device class supported by each interface. Device type is valid only if the interface is CY_CLASS_VENDOR. + +See Also +CY_VID_PID +CY_DEVICE_CLASS +CY_DEVICE_TYPE +CyGetDeviceInfo +CyGetDeviceInfoVidPid +*/ +typedef struct _CY_DEVICE_INFO { + + CY_VID_PID vidPid; /*VID and PID*/ + UCHAR numInterfaces; /*Number of interfaces supported*/ + UCHAR manufacturerName [CY_STRING_DESCRIPTOR_SIZE]; /*Manufacturer name*/ + UCHAR productName [CY_STRING_DESCRIPTOR_SIZE]; /*Product name*/ + UCHAR serialNum [CY_STRING_DESCRIPTOR_SIZE]; /*Serial number*/ + UCHAR deviceFriendlyName [CY_STRING_DESCRIPTOR_SIZE]; /*Device friendly name : Windows only*/ + CY_DEVICE_TYPE deviceType [CY_MAX_DEVICE_INTERFACE]; /*Type of the device each interface has(Valid only + for USB Serial Device) and interface in vendor class*/ + CY_DEVICE_CLASS deviceClass [CY_MAX_DEVICE_INTERFACE]; /*Interface class of each interface*/ + +#ifdef WIN32 + CY_DEVICE_SERIAL_BLOCK deviceBlock; /* On Windows, each USB Serial device interface is associated with a + separate driver instance. This variable represents the present driver + interface instance that is associated with a serial block. */ +#else + UINT8 busNumber; /*Bus number of the device*/ + UINT8 deviceAddress; /*Unigue Identification number of the device*/ +#endif + +} CY_DEVICE_INFO,*PCY_DEVICE_INFO; + +/* Summary +This structure is used to hold data buffer information. + +Description +This strucuture is used by all the data transaction APIs in the library to perform read, write +operations. +Before using a variable of this strucutre users need to initialize various members appropriately. + +See Also +* CyUartRead +* CyUartWrite +* CyI2cRead +* CyI2cWrite +* CySpiReadWrite +* CyJtagWrite +* CyJtagRead +*/ +typedef struct _CY_DATA_BUFFER { + + UCHAR *buffer; /*Pointer to the buffer from where the data is read/written */ + UINT32 length; /*Length of the buffer */ + UINT32 transferCount; /*Number of bytes actually read/written*/ + +} CY_DATA_BUFFER,*PCY_DATA_BUFFER; + +/* Summary +Enumeration defining return status of USB serial library APIs + +Description +The enumeration CY_RETURN_STATUS holds the different return status of all the +APIs supported by USB Serial library. +*/ +typedef enum _CY_RETURN_STATUS{ + + CY_SUCCESS = 0, /*API returned successfully without any errors.*/ + CY_ERROR_ACCESS_DENIED, /*Access of the API is denied for the application */ + CY_ERROR_DRIVER_INIT_FAILED, /*Driver initialisation failed*/ + CY_ERROR_DEVICE_INFO_FETCH_FAILED, /*Device information fetch failed */ + CY_ERROR_DRIVER_OPEN_FAILED, /*Failed to open a device in the library */ + CY_ERROR_INVALID_PARAMETER, /*One or more parameters sent to the API was invalid*/ + CY_ERROR_REQUEST_FAILED, /*Request sent to USB Serial device failed */ + CY_ERROR_DOWNLOAD_FAILED, /*Firmware download to the device failed */ + CY_ERROR_FIRMWARE_INVALID_SIGNATURE, /*Invalid Firmware signature in firmware file*/ + CY_ERROR_INVALID_FIRMWARE, /*Invalid firmware */ + CY_ERROR_DEVICE_NOT_FOUND, /*Device disconnected */ + CY_ERROR_IO_TIMEOUT, /*Timed out while processing a user request*/ + CY_ERROR_PIPE_HALTED, /*Pipe halted while trying to transfer data*/ + CY_ERROR_BUFFER_OVERFLOW, /*OverFlow of buffer while trying to read/write data */ + CY_ERROR_INVALID_HANDLE, /*Device handle is invalid */ + CY_ERROR_ALLOCATION_FAILED, /*Error in Allocation of the resource inside the library*/ + CY_ERROR_I2C_DEVICE_BUSY, /*I2C device busy*/ + CY_ERROR_I2C_NAK_ERROR, /*I2C device NAK*/ + CY_ERROR_I2C_ARBITRATION_ERROR, /*I2C bus arbitration error*/ + CY_ERROR_I2C_BUS_ERROR, /*I2C bus error*/ + CY_ERROR_I2C_BUS_BUSY, /*I2C bus is busy*/ + CY_ERROR_I2C_STOP_BIT_SET, /*I2C master has sent a stop bit during a transaction*/ + CY_ERROR_STATUS_MONITOR_EXIST /*API Failed because the SPI/UART status monitor thread already exists*/ +} CY_RETURN_STATUS; + +/* Summary +This structure is used to store configuration of I2C module. + +Description +The structure contains parameters that are used in configuring I2C module of +Cypress USB Serial device. CyGetI2cConfig and CySetI2cConfig APIs can be used to +retrieve and configure I2C module respectively. + +See Also +* CyGetI2cConfig +* CySetI2cConfig +*/ +typedef struct _CY_I2C_CONFIG{ + + UINT32 frequency; /* I2C clock frequency 1KHz to 400KHz*/ + UINT8 slaveAddress; /* Slave address of the I2C module, when it is configured as slave*/ + BOOL isMaster; /* true- Master , false- slave*/ + BOOL isClockStretch; /* true- Stretch clock in case of no data availability + (Valid only for slave mode) + false- Do not Stretch clock*/ +} CY_I2C_CONFIG,*PCY_I2C_CONFIG; + +/* Summary +This structure is used to configure each I2C data transaction. + +Description +This structure defines parameters that are used for configuring +I2C module during each data transaction. Which includes setting slave address +(when device is in I2C slave mode), stopbit (to enable or disable) and +Nak bit (to enable or disable). + +See Also +* CyI2cWrite +* CyI2cRead +*/ +typedef struct _CY_I2C_DATA_CONFIG +{ + UCHAR slaveAddress; /*Slave address the master will communicate with*/ + BOOL isStopBit; /*Set when stop bit is used*/ + BOOL isNakBit; /*Set when I2C master wants to NAK the slave after read + Applicable only when doing I2C read*/ +} CY_I2C_DATA_CONFIG, *PCY_I2C_DATA_CONFIG; + +/* Summary +Enumeration defining SPI protocol types supported by USB Serial SPI module. + +Description +These are the different protocols supported by USB-Serial SPI module. + +See Also +* CY_SPI_CONFIG +* CyGetSpiConfig +* CySetSpiConfig +*/ +typedef enum _CY_SPI_PROTOCOL { + + CY_SPI_MOTOROLA = 0, /*In master mode, when not transmitting data (SELECT is inactive), SCLK is stable at CPOL. + In slave mode, when not selected, SCLK is ignored; i.e. it can be either stable or clocking. + In master mode, when there is no data to transmit (TX FIFO is empty), SELECT is inactive. + */ + CY_SPI_TI, /*In master mode, when not transmitting data, SCLK is stable at '0'. + In slave mode, when not selected, SCLK is ignored - i.e. it can be either stable or clocking. + In master mode, when there is no data to transmit (TX FIFO is empty), SELECT is inactive - + i.e. no pulse is generated. + *** It supports only mode 1 whose polarity values are + CPOL = 0 + CPHA = 1 + */ + CY_SPI_NS /*In master mode, when not transmitting data, SCLK is stable at '0'. In slave mode, + when not selected, SCLK is ignored; i.e. it can be either stable or clocking. + In master mode, when there is no data to transmit (TX FIFO is empty), SELECT is inactive. + *** It supports only mode 0 whose polarity values are + CPOL = 0 + CPHA = 0 + */ +} CY_SPI_PROTOCOL; + +/* Summary +This structure is used to configure the SPI module of USB Serial device. + +Description +This structure defines configuration parameters that are used for configuring the SPI module . + +See Also +* CY_SPI_PROTOCOL +* CY_SPI_DATA_TRANSFER_MODE +* CyGetSpiConfig +* CySetSpiConfig +*/ +typedef struct _CY_SPI_CONFIG +{ + + UINT32 frequency; /*SPI clock frequency. + ** IMPORTANT: The frequency range supported by SPI module is + 1000(1KHz) to 3000000(3MHz) + */ + + UCHAR dataWidth; /*Data width in bits. The valid values are from 4 to 16.*/ + + CY_SPI_PROTOCOL protocol ; /*SPI Protocols to be used as defined in CY_SPI_PROTOCOL*/ + + BOOL isMsbFirst; /*false -> least significant bit is sent out first + true -> most significant bit is sent out first */ + + BOOL isMaster; /*false --> Slave mode selected: + true --> Master mode selected*/ + + BOOL isContinuousMode; /*true - Slave select line is not asserted i.e + de-asserted for every word. + false- Slave select line is always asserted*/ + + BOOL isSelectPrecede; /*Valid only in TI mode. + true - The start pulse precedes the first data + false - The start pulse is in sync with first data. */ + + BOOL isCpha; /*false - Clock phase is 0; true - Clock phase is 1. */ + + BOOL isCpol; /*false - Clock polarity is 0;true - Clock polarity is 1.*/ + +}CY_SPI_CONFIG,*PCY_SPI_CONFIG; + +/* Summary +Enumeration defines UART baud rates supported by UART module of USB Serial device. + +Description +The enumeration lists the various baud rates supported by the UART when it is in UART +vendor mode. + +See Also +* CY_UART_CONFIG +* CySetUartConfig +* CyGetUartConfig +*/ +typedef enum _CY_UART_BAUD_RATE +{ + CY_UART_BAUD_300 = 300, /* Baud rate of 300. */ + CY_UART_BAUD_600 = 600, /* Baud rate of 600. */ + CY_UART_BAUD_1200 = 1200, /* Baud rate of 1200. */ + CY_UART_BAUD_2400 = 2400, /* Baud rate of 2400. */ + CY_UART_BAUD_4800 = 4800, /* Baud rate of 4800. */ + CY_UART_BAUD_9600 = 9600, /* Baud rate of 9600. */ + CY_UART_BAUD_14400 = 14400, /* Baud rate of 14400. */ + CY_UART_BAUD_19200 = 19200, /* Baud rate of 19200. */ + CY_UART_BAUD_38400 = 38400, /* Baud rate of 38400. */ + CY_UART_BAUD_56000 = 56000, /* Baud rate of 56000. */ + CY_UART_BAUD_57600 = 57600, /* Baud rate of 57600. */ + CY_UART_BAUD_115200 = 115200, /* Baud rate of 115200. */ + CY_UART_BAUD_230400 = 230400, /* Baud rate of 230400. */ + CY_UART_BAUD_460800 = 460800, /* Baud rate of 460800. */ + CY_UART_BAUD_921600 = 921600, /* Baud rate of 921600. */ + CY_UART_BAUD_1000000 = 1000000, /* Baud rate of 1000000. */ + CY_UART_BAUD_3000000 = 3000000, /* Baud rate of 3000000. */ + +}CY_UART_BAUD_RATE; + +/* +Summary +Enumeration defines the different parity modes supported by UART module of USB Serial device. + +Description +This enumeration defines the different parity modes of USB Serial UART module. +It supports odd, even, mark and space parity modes. + +See Also +* CY_UART_CONFIG +* CySetUartConfig +* CyGetUartConfig +*/ +typedef enum _CY_UART_PARITY_MODE { + + CY_DATA_PARITY_DISABLE = 0, /*Data parity disabled*/ + CY_DATA_PARITY_ODD, /*Odd Parity*/ + CY_DATA_PARITY_EVEN, /*Even Parity*/ + CY_DATA_PARITY_MARK, /*Mark parity*/ + CY_DATA_PARITY_SPACE /*Space parity*/ + +} CY_UART_PARITY_MODE; + +/* +Summary +Enumeration defines the different stop bit values supported by UART module of USB Serial device. + +See Also +* CY_UART_CONFIG +* CySetUartConfig +* CyGetUartConfig +*/ +typedef enum _CY_UART_STOP_BIT { + + CY_UART_ONE_STOP_BIT = 1, /*One stop bit*/ + CY_UART_TWO_STOP_BIT /*Two stop bits*/ + +} CY_UART_STOP_BIT; + +/* +Summary +Enumeration defines flow control modes supported by UART module of USB Serial device. + +Description +The list provides the various flow control modes supported by USB Serial device. + +See Also +* CyUartSetHwFlowControl +* CyUartGetHwFlowControl +*/ +typedef enum _CY_FLOW_CONTROL_MODES { + + CY_UART_FLOW_CONTROL_DISABLE = 0, /*Disable Flow control*/ + CY_UART_FLOW_CONTROL_DSR, /*Enable DSR mode of flow control*/ + CY_UART_FLOW_CONTROL_RTS_CTS, /*Enable RTS CTS mode of flow control*/ + CY_UART_FLOW_CONTROL_ALL /*Enable RTS CTS and DSR flow control */ + +} CY_FLOW_CONTROL_MODES; + +/* +Summary +Structure holds configuration of UART module of USB Serial device. + +Description +This structure defines parameters used for configuring the UART module. +CySetUartConfig and CyGetUartConfig APIs are used to configure and retrieve +the UART configuration information. + +See Also +* CySetUartConfig +* CyGetUartConfig +*/ +typedef struct _CY_UART_CONFIG { + + CY_UART_BAUD_RATE baudRate; /*Baud rate as defined in CY_UART_BAUD_RATE*/ + UINT8 dataWidth; /*Data width: valid values 7 or 8*/ + CY_UART_STOP_BIT stopBits; /*Number of stop bits to be used 1 or 2*/ + CY_UART_PARITY_MODE parityMode; /*UART parity mode as defined in CY_UART_PARITY_MODE*/ + BOOL isDropOnRxErrors; /*Whether to ignore framing as well as parity errors and receive data */ + +} CY_UART_CONFIG,*PCY_UART_CONFIG; + +/* +Summary +Enumeration defining UART/SPI transfer error or status bit maps. + +Description +Enumeration lists the bit maps that are used to report error or status during +UART/SPI transfer. + +See Also +* CySetEventNotification +*/ +typedef enum _CY_CALLBACK_EVENTS { + + CY_UART_CTS_BIT = 0x01, /*CTS pin notification bit*/ + CY_UART_DSR_BIT = 0x02, /*State of transmission carrier. This signal + corresponds to V.24 signal 106 and RS-232 signal DSR.*/ + CY_UART_BREAK_BIT = 0x04, /*State of break detection mechanism of the device */ + CY_UART_RING_SIGNAL_BIT = 0x08, /*State of ring signal detection of the device*/ + CY_UART_FRAME_ERROR_BIT = 0x10, /*A framing error has occurred*/ + CY_UART_PARITY_ERROR_BIT = 0x20, /*A parity error has occured*/ + CY_UART_DATA_OVERRUN_BIT = 0x40, /*Received data has been discarded due to overrun in + the device*/ + CY_UART_DCD_BIT = 0x100, /*State of receiver carrier detection mechanism of + device. This signal corresponds to V.24 signal 109 + and RS-232 signal DCD*/ + CY_SPI_TX_UNDERFLOW_BIT = 0x200, /*Notification sent when SPI fifo is empty*/ + CY_SPI_BUS_ERROR_BIT = 0x400, /*Spi bus error has been detected*/ + CY_ERROR_EVENT_FAILED_BIT = 0x800 /*Event thread failed*/ + +} CY_CALLBACK_EVENTS; + +/*************************************************************************************/ +/*********************USB Initialization APIs************************************/ +/*************************************************************************************/ + +/*@@USB Initialization API +This section has all the APIs that handle device initialization and +fetching information about the device connected. +*/ + +/* + Summary + This API is used to initialize the library. + + Description + The API is used to initialize the underlying libusb library and + is expected to be called when the application is being started. + + Note: The API is used only in Linux and Mac OS. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_DRIVER_INIT_FAILED on failure + (Failure could be because of not calling CyLibraryExit previously) + + See Also + * CyOpen + * CyLibraryExit +*/ +CYWINEXPORT CY_RETURN_STATUS LINUXCALLCONVEN CyLibraryInit (); + +/* + Summary + This API is used to free the library. + + Description + The API is used to free the library and should be called + when exiting the application. + + Note: This API is used only in Linux and Mac library. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_REQUEST_FAILED on failure + + See Also + * CyOpen + * CyClose + * CyLibraryInit +*/ +CYWINEXPORT CY_RETURN_STATUS LINUXCALLCONVEN CyLibraryExit (); + +/* + Summary + This API retrieves number of USB devices connected to the host. + + Description + This API retrieves the number of devices connected to the host. + In Windows family of operating systems the API retrieves only the number of devices that are attached + to CyUSB3.SYS driver. For other operating systems, it retrieves the total number of USB devices present + on the bus. It includes both USB Serial device as well as other devices. + + Note: In case of Linux and Mac apart from providing number of devices connected, it builds the + device list which is used for opening the device and obtaining device handle. Thus the API should be + called during device discovery in the application. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_DEVICE_NOT_FOUND if there are no devices attached. + * CY_ERROR_REQUEST_FAILED if library was not initialized. + + See Also + * CyGetDeviceInfo + * CyGetDeviceInfoVidPid + * CyOpen + * CyClose +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetListofDevices ( + UINT8* numDevices /*Number of Devices connected*/ + ); + +/* + Summary + This API retrieves the device information of a USB device. + + Description + This API retrieves information about a device connected to host. In order to + get the device information on particular device user needs to provide the device number. + To identify the device of interest, the application needs to loop through all devices connected + and obtain the information. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_REQUEST_FAILED if library is not initialized (Only for Linux and Mac). + * CY_ERROR_INVALID_PARAMETER if the input parameters are invalid. + * CY_ERROR_DEVICE_INFO_FETCH_FAILED if failed to fetch device information. + * CY_ERROR_ACCESS_DENIED if access is denied by operating system. + * CY_ERROR_DEVICE_NOT_FOUND if specified device number is invalid. + + See Also + * CY_DEVICE_INFO + * CY_DEVICE_TYPE + * CY_DEVICE_CLASS + * CyGetListofDevices + * CyGetDeviceInfoVidPid + * CyOpen + * CyClose +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetDeviceInfo( + UINT8 deviceNumber, /*Device number of the device of interest*/ + CY_DEVICE_INFO *deviceInfo /*Info of device returned*/ + ); + +/* + Summary + This API is used to retrieve the information of all devices with specified Vendor ID and Product ID. + + Description + For a given VID and PID, the API returns deviceIdList and deviceInfoList. + The deviceIdList contains the device numbers of all the devices with specified VID and PID. + Using deviceInfoList application can identify the device of interest. + Information that is provided includes interface number, string descriptor, deviceType and deviceClass. + + + Return Value + * CY_SUCCESS on success else error codes as defined in the enumeration CY_RETURN_STATUS. + * CY_ERROR_REQUEST_FAILED on if library is not initialized (Only for Linux and Mac) + * CY_ERROR_INVALID_PARAMETER if the input parameters are invalid. + * CY_ERROR_DEVICE_INFO_FETCH_FAILED if failed to fetch device information. + * CY_ERROR_ACCESS_DENIED if access is denied by operating system. + * CY_ERROR_DEVICE_NOT_FOUND if specified device number is invalid. + + See Also + * CY_DEVICE_INFO + * CY_DEVICE_CLASS + * CY_DEVICE_TYPE + * CyGetListofDevices + * CyGetDeviceInfo + * CyOpen + * CyClose +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetDeviceInfoVidPid ( + CY_VID_PID vidPid, /*VID and PID of device of interest*/ + UINT8 *deviceIdList, /*Array of device ID's returned*/ + CY_DEVICE_INFO *deviceInfoList, /*Array of pointers to device info list*/ + UINT8 *deviceCount, /*Count of devices with specified VID PID*/ + UINT8 infoListLength /*Total length of the deviceInfoList allocated + (Size of deviceInfoList array)*/ + ); + +/* + Summary + This API is used to open the USB Serial device. + + Description + This API is used to open USB Serial device based on the device number. + + Note: The argument interfaceNum is used on Linux and Mac OS while obtaining handle for specific + interface. In Windows family of operating systems, this argument should be set to zero. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_REQUEST_FAILED on if library is not initialized (Only for Linux and Mac) + * CY_ERROR_INVALID_PARAMETER if the input parameters are invalid. + * CY_ERROR_DRIVER_OPEN_FAILED if open was unsuccessful. + * CY_ERROR_ACCESS_DENIED if access is denied by operating system. + * CY_ERROR_ALLOCATION_FAILED if memory allocation was failed. + * CY_ERROR_DEVICE_NOT_FOUND if specified device number is invalid. + + See Also + * CyGetListofDevices + * CyGetDeviceInfoVidPid + * CyGetDeviceInfo + * CyClose +*/ +CYWINEXPORT CY_RETURN_STATUS CyOpen ( + UINT8 deviceNumber, /*Device number of device that needs to be opened*/ + UINT8 interfaceNum, /*Interface Number*/ + CY_HANDLE *handle /*Handle returned by the API*/ + ); + +/* + Summary + This API closes the specified device handle and releases all resources associated with it. + + Description + This API closes the device handle and releases all the resources allocated internally in the + library. This API should be invoked using a valid device handle and upon successful return + of CyOpen. + + Return Value + * CY_SUCCESS on success. + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if handle is invalid in case of Windows. + * CY_ERROR_REQUEST_FAILED on error in case of library being not initialized (Only for Linux and Mac). + + See Also + * CyOpen +*/ +CYWINEXPORT CY_RETURN_STATUS CyClose ( + CY_HANDLE handle /*Handle of the device that needs to be closed*/ + ); + +/* + Summary + This API is used to power cycle the host port. + + Description + This API will power cycle the upstream port. It will reenumerate the device after the power cycle. + + Note: This API is not supported on Linux and Mac + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if handle is invalid in case of Windows. + * CY_ERROR_REQUEST_FAILED on error if request was failed by driver. + + See Also + * CyResetDevice +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyCyclePort ( + CY_HANDLE handle /*Valid device handle */ + ); + +/*************************************************************************************/ +/********************************Common APIs*********************************************/ +/*************************************************************************************/ + +/*@@Common APIs + + These APIs provide an interface for accessing GPIO pins, error status notification on UART/SPI, + getting library and firmware version and signature. +*/ + +/* + Summary + This API sets the value of a GPIO. + + Description + This API is used to set the value of a GPIO. It can only set the value of a + GPIO that is configured as an output. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED on error when request is failed by USB Serial device. + + See Also + * CyGetGpioValue +*/ +CYWINEXPORT CY_RETURN_STATUS CySetGpioValue ( + CY_HANDLE handle, /*Valid device handle*/ + UINT8 gpioNumber, /*GPIO number*/ + UINT8 value /*Value that needs to be set*/ + ); + +/* + Summary + This API retrieves the value of a GPIO. + + Description + This API retrieves the value of a GPIO. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range and + also when handle is invalid in case of Windows. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + + See Also + * CySetGpioValue +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetGpioValue ( + CY_HANDLE handle, /*Valid device handle*/ + UINT8 gpioNumber, /*GPIO number*/ + UINT8 *value /*Current state of the GPIO*/ + ); + + +/* + Summary + This API is used to register a callback for error/event notifications + during UART/SPI data transfers. + + Description + The API is used to register a callback for error/event notifications while + doing data transfer on UART or SPI. A callback will be issued based on the + error/events sent by the device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_STATUS_MONITOR_EXIST if notification callback is already registered. + + See Also + * CY_CALLBACK_EVENTS + * CY_EVENT_NOTIFICATION_CB_FN + * CyAbortEventNotification +*/ +CYWINEXPORT CY_RETURN_STATUS CySetEventNotification( + CY_HANDLE handle, /*Valid device handle*/ + CY_EVENT_NOTIFICATION_CB_FN notificationCbFn /*Callback function pointer*/ + ); + +/* + Summary + The API is used to unregister the event callback. + + Description + The API is used to unregister the event callback. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_REQUEST_FAILED if API is called before registering callback. + + See Also + * CySetEventNotification +*/ +CYWINEXPORT CY_RETURN_STATUS CyAbortEventNotification( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API retrieves the version of USB Serial library. + + Description + This API retrieves the version of USB Serial library. + + Return Value + * CY_SUCCESS + + See Also + * CyGetFirmwareVersion +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetLibraryVersion ( + CY_HANDLE handle, /*Valid device handle*/ + PCY_LIBRARY_VERSION version /*Library version of the current library*/ + ); + +/* + Summary + This API retrieves the firmware version of the USB Serial device. + + Description + This API retrieves the firmware version of the USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + + See Also + * CyGetLibraryVersion +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetFirmwareVersion ( + CY_HANDLE handle, /*Valid device handle*/ + PCY_FIRMWARE_VERSION firmwareVersion /*Firmware version.*/ + ); + +/* + Summary + This API resets the device by sending a vendor request. + + Description + The API will reset the device by sending a vendor request to the firmware. The device + will be re-enumerated. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + + See Also + * CyCyclePort +*/ +CYWINEXPORT CY_RETURN_STATUS CyResetDevice ( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + The API writes to the user flash area on the USB Serial device. + + Description + The API programs user flash area. The total space available is 512 bytes. + The flash area address offset is from 0x0000 to 0x00200 and should be written + page wise (page size is 128 bytes). + On return, transferCount parameter in CY_DATA_BUFFER will specify the number of bytes actually + programmed. + + Note: Length and page address needs to be 128 bytes aligned. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + + See Also + * CyReadUserFlash +*/ +CYWINEXPORT CY_RETURN_STATUS 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 timeout /*Timeout value of the API*/ + ); + +/* + Summary + The API reads from the flash address specified. + + Description + Read from user flash area.The total space available is 512 bytes. + The flash area address offset is from 0x0000 to 0x00200 and should be read + page wise (page size is 128 bytes). + On return transferCount parameter in CY_DATA_BUFFER will specify the number of bytes actually + read. + + Note: Length and page address needs to be 128 bytes aligned. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + + See Also + * CyProgUserFlash +*/ +CYWINEXPORT CY_RETURN_STATUS CyReadUserFlash ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER *readBuffer, /*data buffer containing buffer address, length to read*/ + UINT32 flashAddress, /*Address from which the data is read*/ + UINT32 timeout /*Timeout value of the API*/ + ); + +/* + Summary + This API retrieves the signature of the device firmware. + + Description + This API retrieves the signature of the device firmware. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device. + */ +CYWINEXPORT CY_RETURN_STATUS CyGetSignature ( + CY_HANDLE handle, /*Valid device handle*/ + UCHAR *pSignature /*Signature returned*/ + ); + +/****************************************************************************************/ +/********************************UART API's**********************************************/ +/****************************************************************************************/ + +/*@@UART API + APIs used to communicate with UART module of the USB Serial device. + These APIs provide support for configuration, data transfer and flow control. +*/ + +/* + Summary + This API retrieves the UART configuration from the USB Serial device. + + Description + This API retrieves the UART configuration from the USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CY_UART_CONFIG + * CySetUartConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetUartConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_UART_CONFIG *uartConfig /*UART configuration value read back*/ + ); + +/* + Summary + This API sets the UART configuration of USB Serial device. + + Description + This API sets the UART configuration of USB Serial device. + + Note: Using this API during an active transaction of UART may result in data loss. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CY_UART_CONFIG + * CyGetUartConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CySetUartConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_UART_CONFIG *uartConfig /*UART configuration value */ + ); + +/* + Summary + This API reads data from UART device. + + Description + This API is used to read data from UART device. User needs to initialize the readBuffer with buffer pointer, + number of bytes to read before invoking this API. + On return the transferCount parameter in CY_DATA_BUFFER will contain the number of bytes read. + + Return Value + * CY_SUCCESS on success. + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if input parameters were invalid. + * CY_ERROR_REQUEST_FAILED if the device type is not UART. + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_PIPE_HALTED if pipe was stalled during data transfer. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + * CY_ERROR_ALLOCATION_FAILED if transaction transmit buffer allocation was failed (Only in Windows). + + See Also + * CY_DATA_BUFFER + * CyUartWrite +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartRead ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER* readBuffer, /*Read buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* + Summary + This API writes the data to UART device. + + Description + This API writes the data to UART device. User need to initialize the + writeBuffer with buffer pointer, number of bytes to write before invoking the API. + On return the transferCount parameter in CY_DATA_BUFFER will contain the number + of bytes written. + + Return Value + * CY_SUCCESS on success. + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if input parameters were invalid. + * CY_ERROR_REQUEST_FAILED if the device type is not UART. + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_PIPE_HALTED if pipe was stalled during data transfer. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + * CY_ERROR_ALLOCATION_FAILED if transaction transmit buffer allocation was failed (Only in Windows). + + See Also + * CY_DATA_BUFFER + * CyUartRead +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartWrite ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER* writeBuffer, /*Write buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* + Summary + This API enables hardware flow control. + + Description + This API enables hardware flow control. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE on error if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER on error if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT on error if request was timed out. + * CY_ERROR_REQUEST_FAILED on error if request was failed by device or if device type + is not UART. + + See Also + * CyUartGetHwFlowControl +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartSetHwFlowControl( + CY_HANDLE handle, /*Valid device handle*/ + CY_FLOW_CONTROL_MODES mode /*Flow control mode*/ + ); + +/* + Summary + This API retrieves the current hardware flow control status. + + Description + This API retrieves the current hardware flow control status. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartSetHwFlowControl +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartGetHwFlowControl( + CY_HANDLE handle, /*Valid device handle*/ + CY_FLOW_CONTROL_MODES *mode /*Flow control mode*/ + ); + +/* + Summary + This API sets RTS signal in UART module. + + Description + This API is used to set the RTS pin to logical low.. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartClearRts + * CyUartSetDtr + * CyUartClearDtr +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartSetRts( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API can be used to clear RTS signal in UART module. + + Description + This API used clear the RTS. It sets the RTS pin to logical high. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartSetRts + * CyUartSetDtr + * CyUartClearDtr +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartClearRts( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API sets DTR signal in UART. + + Description + This API used set the DTR. It sets the DTR pin to logical low. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartClearRts + * CyUartSetRts + * CyUartClearDtr +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartSetDtr( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API can be used to clear DTR signal in UART. + + Description + This API can be used clear the DTR. It sets the DTR pin to logical high. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartSetRts + * CyUartSetDtr + * CyUartClearRts +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartClearDtr( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API can be used to set break timeout value . + + Description + This API can be used to set break timeout value . + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not UART. + + See Also + * CyUartSetFlowControl +*/ +CYWINEXPORT CY_RETURN_STATUS CyUartSetBreak( + CY_HANDLE handle, /*Valid device handle*/ + UINT16 timeout /*Break timeout value in milliseconds */ + ); + +/***********************************************************************************************/ +/**********************************I2C API's****************************************************/ +/***********************************************************************************************/ + +/*@@I2C API + + These set of APIs provide an interface to configure I2C module and do + read/write on the I2C device connected to USB Serial device. +*/ + +/* + Summary + This API retrieves the configuration of I2C module of USB Serial device. + + Description + This API retrieves the configuration of I2C module of USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not I2C. + + See Also + * CY_I2C_CONFIG + * CySetI2cConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetI2cConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_I2C_CONFIG *i2cConfig /*I2C configuration value read back*/ + ); + +/* + Summary + This API configures the I2C module of USB Serial device. + + Description + This API configures the I2C module of USB Serial device. + + Note: Using this API during an active transaction of I2C may result in data loss. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not I2C. + + See Also + * CY_I2C_CONFIG + * CySetI2cConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CySetI2cConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_I2C_CONFIG *i2cConfig /*I2C configuration value*/ + ); + +/* + Summary + This API reads data from the USB Serial I2C module. + + Description + This API provides an interface to read data from the I2C device + connected to USB Serial. + + The readBuffer parameter needs to be initialized with buffer pointer, number of bytes to be read + before invoking the API. On return, the transferCount field will contain the number of bytes + read back from device. + CY_I2C_DATA_CONFIG structure specifies parameters such as setting stop bit, NAK and + slave address of the I2C device. + + Return Value + * CY_SUCCESS on success. + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if input parameters were invalid. + * CY_ERROR_REQUEST_FAILED if the device type is not I2C + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + * CY_ERROR_ALLOCATION_FAILED if transaction transmit buffer allocation was failed (Only in Windows). + * CY_ERROR_I2C_DEVICE_BUSY if I2C device was busy processing previous request. + * CY_ERROR_I2C_NAK_ERROR if request was nacked by I2C device. + * CY_ERROR_I2C_ARBITRATION_ERROR if a I2C bus arbitration error occured. + * CY_ERROR_I2C_BUS_ERROR if there was any I2C bus error while an on going transaction. + * CY_ERROR_I2C_STOP_BIT_SET if stop bit was set by I2C master. + + See Also + * CY_DATA_BUFFER + * CY_DATA_CONFIG + * CyI2cCWrite +*/ +CYWINEXPORT CY_RETURN_STATUS CyI2cRead ( + CY_HANDLE handle, /*Valid device handle*/ + CY_I2C_DATA_CONFIG *dataConfig, /*I2C data config*/ + CY_DATA_BUFFER *readBuffer, /*Read buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* + Summary + This API writes data to USB Serial I2C module . + + Description + This API provides an interface to write data to the I2C device + connected to USB Serial. + The writeBuffer parameter needs to be initialized with buffer pointer, number of bytes to be written + before invoking the API. On return, transferCount field contains number of bytes actually written to the device. + CY_I2C_DATA_CONFIG structure specifies parameter such as setting stop bit, Nak and slave address + of the I2C device being communicated when USB Serial is master. + + Return Value + * CY_SUCCESS on success. + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if input parameters were invalid. + * CY_ERROR_REQUEST_FAILED if the device type is not I2C + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_PIPE_HALTED if pipe was stalled during data transfer. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + * CY_ERROR_ALLOCATION_FAILED if transaction transmit buffer allocation was failed (Only in Windows). + * CY_ERROR_I2C_DEVICE_BUSY if I2C device was busy processing previous request. + * CY_ERROR_I2C_NAK_ERROR if request was nacked by I2C device. + * CY_ERROR_I2C_ARBITRATION_ERROR if a I2C bus arbitration error occured. + * CY_ERROR_I2C_BUS_ERROR if there was any I2C bus error while an on going transaction. + * CY_ERROR_I2C_STOP_BIT_SET if stop bit was set by I2C master. + + See Also + * CY_DATA_BUFFER + * CY_DATA_CONFIG + * CyI2cRead +*/ +CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyI2cWrite ( + CY_HANDLE handle, /*Valid device handle*/ + CY_I2C_DATA_CONFIG *dataConfig, /*I2C Slave address */ + CY_DATA_BUFFER *writeBuffer, /*Write buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* + Summary + This API resets the I2C module in USB Serial device. + + Description + This API resets the I2C module whenever there is an error in data transaction. + + If resetMode = 0 the I2C read module will be reset. + If resetMode = 1 the I2C write module will be reset. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not I2C. + + See Also + * CyI2CRead + * CyI2CWrite +*/ +CYWINEXPORT CY_RETURN_STATUS CyI2cReset( + CY_HANDLE handle, /*Valid device handle*/ + BOOL resetMode /*Reset mode*/ + ); + +/***********************************************************************************************/ +/**********************************SPI APIs****************************************************/ +/***********************************************************************************************/ + +/*@@SPI API + These set of APIs provide an interface to configure SPI module and perform + read/write operations with the SPI device connected to USB Serial device. +*/ + +/* + Summary + This API retrieves the configuration of SPI module of USB Serial device. + + Description + This API retrieves the configuration of SPI module of USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not SPI. + + See Also + * CY_SPI_CONFIG + * CySetSpiConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CyGetSpiConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_SPI_CONFIG *spiConfig /*SPI configuration structure value read back*/ + ); + +/* + Summary + This API sets the configuration of the SPI module on USB Serial device. + + Description; + This API sets the configuration of the SPI module in USB Serial device. + + NOTE: Using this API during an active transaction of SPI may result in data loss. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if the request is timed out. + * CY_ERROR_REQUEST_FAILED when request is failed by USB Serial device or when device type is + not SPI. + + See Also + * CY_SPI_CONFIG + * CyGetSpiConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CySetSpiConfig ( + CY_HANDLE handle, /*Valid device handle*/ + CY_SPI_CONFIG *spiConfig /*SPI configuration structure value*/ + ); + +/* + Summary + This API reads and writes data to SPI device connected to USB Serial device. + + Description + This API provides an interface to do data transfer with the SPI slave/master + connected to USB Serial device. + To perform read only operation, pass NULL as argument for writeBuffer and to perform + write only operation pass NULL as an argument for readBuffer. + On return, the transferCount field will contain the number of bytes read and/or written. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_REQUEST_FAILED if the device type is not SPI or when libusb reported + unknown error in case of Linux/Mac. + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_PIPE_HALTED if pipe was stalled during data transfer. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + + See Also + * CY_DATA_BUFFER + * CyGetSpiConfig + * CySetSpiConfig +*/ +CYWINEXPORT CY_RETURN_STATUS CySpiReadWrite ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER* readBuffer, /*Read data buffer*/ + CY_DATA_BUFFER* writeBuffer, /*Write data buffer*/ + UINT32 timeout /*Time out value of the API*/ + ); + +/**************************************************************************************/ +/*****************************************JTAG APIs***********************************/ +/**************************************************************************************/ + +/*@@JTAG API + These set of APIs can be used to enable or disable JTAG module on the USB Serial device. + Once the JTAG is enabled, read and write operations can be performed. + When JTAG is enabled other modules in the USB Serial device cannot be used. +*/ + +/* + Summary + This API enables JTAG module. + + Description + This API enables JTAG module in USB Serial device and the function disables all other functionality + till CyJtagDisable is invoked. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if request was timed out. + * CY_ERROR_REQUEST_FAILED if request was failed by device or if device type + is not JTAG. + + See Also + * CyJtagDisable +*/ +CYWINEXPORT CY_RETURN_STATUS CyJtagEnable ( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API disables JTAG module. + + Description + This API disables Jtag interface in USB Serial device. This API must be invoked before exiting the + application if CyJtagEnable was previously invoked. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_IO_TIMEOUT if request was timed out. + * CY_ERROR_REQUEST_FAILED if request was failed by device or if device type + is not JTAG. + + See Also + * CyJtagEnable +*/ +CYWINEXPORT CY_RETURN_STATUS CyJtagDisable ( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API can be used to write data to JTAG module. + + Description + This API provides an interface to write data to JTAG device connected to USB Serial device. + The writeBuffer need to be initialized with buffer and length of data to be written before invoking + the API. Upon return, transferCount field in CY_DATA_BUFFER is updated with actual number of bytes written. + + Note: CyJtagEnable must be called before invoking this API. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_REQUEST_FAILED if device type is not JTAG or when encountered + unknown libusb errors in Linux/Mac. + * CY_ERROR_PIPE_HALTED if there was any pipe error during transaction. + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + + See Also + * CY_DATA_BUFFER + * CyJtagRead + * CyJtagEnable +*/ +CYWINEXPORT CY_RETURN_STATUS CyJtagWrite ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER *writeBuffer, /*Write buffer details*/ + UINT32 timeout /*API timeout value*/ + ); + +/* + Summary + This API reads data from JTAG device. + + Description + This API provides an interface to read data from JTAG device. + The readBuffer need to be initialized with buffer and length of data to be written before invoking + the API. Upon return, transferCount field in CY_DATA_BUFFER structure + is updated with actual number of bytes read. + + Note: CyJtagEnable must be called before invoking this API. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle is invalid in case of Linux/Mac. + * CY_ERROR_INVALID_PARAMETER if specified parameters are invalid or out of range. + * CY_ERROR_REQUEST_FAILED if device type is not JTAG or when encountered + unknown libusb errors in Linux/Mac. + * CY_ERROR_IO_TIMEOUT if transfer was timed out. + * CY_ERROR_DEVICE_NOT_FOUND if device was disconnected. + * CY_ERROR_BUFFER_OVERFLOW if data received from USB Serial device is more than requested. + + See Also + * CY_DATA_BUFFER + * CyJtagWrite + * CyJtagEnable +*/ +CYWINEXPORT CY_RETURN_STATUS CyJtagRead ( + CY_HANDLE handle, /*Valid device handle*/ + CY_DATA_BUFFER *readBuffer, /*Read buffer parameters*/ + UINT32 timeout /*API timeout value*/ + ); + +/**************************************************************************************/ +/*****************************************PHDC APIs***********************************/ +/**************************************************************************************/ + +/*@@PHDC API + Set of PHDC class request APIs. The PHDC class requests include set, clear feature and + PHDC get status. +*/ + +/* + Summary + This API sends a PHDC clear feature command. + + Description + This API sends a PHDC clear feature command. + + Note: Meta data feature is not supported by USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle was invalid. + * CY_ERROR_IO_TIMEOUT if request timed out. + * CY_ERROR_REQUEST_FAILED if request was failed by device. + + See Also + * CyPhdcSetFeature + * CyPhdcGetStatus +*/ +CYWINEXPORT CY_RETURN_STATUS CyPhdcClrFeature ( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API sends a PHDC set feature command. + + Description + This API sends a PHDC set feature command. + + Note: Meta data feature is not supported by USB Serial device. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle was invalid. + * CY_ERROR_IO_TIMEOUT if request timed out. + * CY_ERROR_REQUEST_FAILED if request was failed by device. + + See Also + * CyPhdcClrFeature + * CyPhdcGetStatus +*/ +CYWINEXPORT CY_RETURN_STATUS CyPhdcSetFeature ( + CY_HANDLE handle /*Valid device handle*/ + ); + +/* + Summary + This API retrieves the endpoint status of PHDC transaction. + + Description + The API retrieves the status of PHDC transaction. It returns 2 bytes of data pending bit map + which is defined as per PHDC spec. + + Return Value + * CY_SUCCESS on success + * CY_ERROR_INVALID_HANDLE if handle was invalid. + * CY_ERROR_IO_TIMEOUT if request timed out. + * CY_ERROR_REQUEST_FAILED if request was failed by device. + + See Also + * CyPhdcClrFeature + * CyPhdcSetFeature +*/ +CYWINEXPORT CY_RETURN_STATUS CyPhdcGetStatus ( + CY_HANDLE handle, /*Valid device handle*/ + UINT16 *dataStatus /*Data pending status bit map*/ + ); + +#endif /*_INCLUDED_Cypress USB Serial_H_*/ diff --git a/cylib/COPYING.LESSER.txt b/configutility/license/license.txt similarity index 97% rename from cylib/COPYING.LESSER.txt rename to configutility/license/license.txt index 4362b49..5faba9d 100644 --- a/cylib/COPYING.LESSER.txt +++ b/configutility/license/license.txt @@ -1,502 +1,504 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/configutility/linux/library/90-cyusb.rules b/configutility/linux/library/90-cyusb.rules new file mode 100644 index 0000000..21cbba2 --- /dev/null +++ b/configutility/linux/library/90-cyusb.rules @@ -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" diff --git a/configutility/linux/library/CyUSBCommon.h b/configutility/linux/library/CyUSBCommon.h new file mode 100644 index 0000000..211b632 --- /dev/null +++ b/configutility/linux/library/CyUSBCommon.h @@ -0,0 +1,219 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../common/header/CyUSBSerial.h" +#pragma pack(1) +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 0x17 +#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 + diff --git a/configutility/linux/library/Makefile b/configutility/linux/library/Makefile new file mode 100644 index 0000000..4e67473 --- /dev/null +++ b/configutility/linux/library/Makefile @@ -0,0 +1,20 @@ +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 -fPIC -g -Wall -o libcyboot.o -c cyboot.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 libcyboot.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 libcyboot.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)' diff --git a/configutility/linux/library/cyboot.c b/configutility/linux/library/cyboot.c new file mode 100644 index 0000000..d8e2bd0 --- /dev/null +++ b/configutility/linux/library/cyboot.c @@ -0,0 +1,668 @@ +#include "CyUSBCommon.h" +#include "CyUSBBootloader.h" +/* + CyReadFlash will read the content of flash from the + specified address + */ + +UINT32 fmVersion; +UINT32 fmChecksum; +UINT32 firmwareSize = 0; +UINT32 firmwareEntry; +UINT32 firmwareStart; +typedef enum CY_BOOT_VENDOR_CMDS +{ + CY_CMD_GET_VERSION = 0xB0, /* Get the version of the boot-loader. + value = 0, index = 0, length = 4; + data_in = 32 bit version. */ + CY_BOOT_CMD_GET_SILICON_ID= 0xB1, /* Get the silicon ID for the device. + value = 0, index = 0, length = 4; + data_in = 32 bit silicon id. */ + CY_BOOT_CMD_READ_FLASH, /* Read flash content: + value = MS word of address, + index = LS word of address(4 byte aligned), + length = length of read (4 byte multiple); + data_in = requested data from flash. */ + CY_BOOT_CMD_PROG_FLASH, /* Program data into flash: + value = MS word of address, + index = LS word of address(128 byte aligned), + length = length of write (128 byte multiple); + data_out = data to be written to flash. */ + CY_BOOT_CMD_RESERVED_0, /* Reserved*/ + CY_BOOT_CMD_READ_CONFIG = 0xB5, /* Read the device configuration table: + value = 0, index = 0, length = 512; + data_in = device configuration table. */ + CY_BOOT_CMD_PROG_CONFIG = 0xB6, /* Program the device configuration table: + value = 0, index = 0, length = 512; + data_out = device configuration table. */ + CY_BOOT_CMD_READ_BOOT_CONFIG, /* Read the boot-loader configuration table; + value = 0, index = 0, length = 256; + data_in = boot-loader configuration table. */ + CY_BOOT_CMD_PROG_BOOT_CONFIG, /* Program the boot-loader configuration table; + value = 0, index = 0, length = 256; + data_out = boot-loader configuration table. */ + CY_BOOT_CMD_RESERVED_1, /* RESERVED */ + CY_BOOT_CMD_VALIDATE_CHECKSUM = 0xBA,/* Calculate checksum and compare against the + content of the device configuration table. */ + CY_BOOT_CMD_READ_MEM, /* Read from the SRAM memory: + index = LS word of address(4 byte aligned), + length = length of read (4 byte multiple); + data_in = requested data from SRAM. */ + CY_BOOT_CMD_WRITE_MEM, /* Program data into SRAM memory: + value = MS word of address, + index = LS word of address(4 byte aligned), + length = length of write (4 byte multiple); + data_out = data to be written to SRAM. */ + CY_VENDOR_GET_SIGNATURE, /*Get the signature of the firmware + It is suppose to be 'CYUS' for normal firmware + and 'CYBL' for Bootloader.*/ + CY_BOOT_CMD_MFG_JUMP, /*Jump to bootloader mode*/ + + CY_VENDOR_ENTER_MFG_MODE = 0xE2 /* Enter the configuration mode. This needs to be invoked to enter + the manufacturing mode. If this is not set, then the device shall + not allow any of the configuration requests (B0 to BF) to go through. + Value = ~"CY" = 0xA6BC, index = ~"OF" = 0xB9B0: for disable, + Value = ~"CY" = 0xA6BC, ~"ON" = 0xB1B0: for enable, + Length = 0. */ + +} CY_BOOT_VENDOR_CMDS; + +#define CY_DEVICE_CONFIG_SIZE 512 +#define CY_GET_SILICON_ID_LEN 4 +#define CY_USB_SERIAL_TIMEOUT 0 + +CY_RETURN_STATUS CyReadFlash ( + CY_HANDLE handle, + PCY_BOOTLD_BUFFER readBuffer, + UINT32 ioTimeout + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (readBuffer == NULL || readBuffer->buffer == NULL || readBuffer->length == 0) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; + bmRequest = CY_BOOT_CMD_READ_FLASH; + wValue = ((readBuffer->address & 0xFFFF0000 ) >> 16); + wIndex = (readBuffer->address & 0x0000FFFF ); + + wLength = (readBuffer->length); + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, readBuffer->buffer, wLength, ioTimeout); + if (rStatus > 0){ + *(readBuffer->bytesReturned) = rStatus; + CY_DEBUG_PRINT_ERROR ("CY:The Length is %d\n", rStatus); + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY:Device Timed out.. \n"); + *(readBuffer->bytesReturned) = 0; + return CY_ERROR_IO_TIMEOUT; + } + else { + CY_DEBUG_PRINT_ERROR ("CY:Error in process the request.. libusb error is %d \n", rStatus); + *(readBuffer->bytesReturned) = 0; + return CY_ERROR_REQUEST_FAILED; + } +} +/* + CyProgFlash will write the content of flash from the + specified address + */ +CY_RETURN_STATUS CyProgFlash ( + CY_HANDLE handle, + PCY_BOOTLD_BUFFER writeBuffer, + UINT32 ioTimeout + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (writeBuffer == NULL || writeBuffer->buffer == NULL || writeBuffer->length == 0) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_PROG_FLASH; + wValue = ((writeBuffer->address & 0xFFFF0000 ) >> 16); + wIndex = (writeBuffer->address & 0x0000FFFF ); + + wLength = (writeBuffer->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, writeBuffer->buffer, wLength, ioTimeout); + if (rStatus > 0){ + *(writeBuffer->bytesReturned) = rStatus; + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY:Device Timed out.. \n"); + *(writeBuffer->bytesReturned) = 0; + return CY_ERROR_IO_TIMEOUT; + } + else { + CY_DEBUG_PRINT_ERROR ("CY:Error in process the request..libusb error is %d \n", rStatus); + *(writeBuffer->bytesReturned) = 0; + return CY_ERROR_REQUEST_FAILED; + } +} +/* CyReadMemory will read the content of SRAM from the + specified address + */ +CY_RETURN_STATUS CyReadMemory ( + CY_HANDLE handle, + PCY_BOOTLD_BUFFER readBuffer, + UINT32 ioTimeout + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (readBuffer == NULL || readBuffer->buffer == NULL || readBuffer->length == 0) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; + bmRequest = CY_BOOT_CMD_READ_MEM; + wValue = ((readBuffer->address & 0xFFFF0000 ) >> 16); + wIndex = (readBuffer->address & 0x0000FFFF ); + wLength = (readBuffer->length); + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, readBuffer->buffer, wLength, ioTimeout); + if (rStatus > 0){ + *(readBuffer->bytesReturned) = rStatus; + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY:Device Timed out.. \n"); + *(readBuffer->bytesReturned) = 0; + return CY_ERROR_IO_TIMEOUT; + } + else { + CY_DEBUG_PRINT_ERROR ("CY:Error in processing the request.. libusb error is %d \n", rStatus); + *(readBuffer->bytesReturned) = 0; + return CY_ERROR_REQUEST_FAILED; + } +} +/* + CyWriteMemory will write the content to specified address + in SRAM + */ +CY_RETURN_STATUS CyWriteMemory ( + CY_HANDLE handle, + PCY_BOOTLD_BUFFER writeBuffer, + UINT32 ioTimeout + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (writeBuffer == NULL || writeBuffer->buffer == NULL || writeBuffer->length == 0) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_WRITE_MEM; + wValue = ((writeBuffer->address & 0xFFFF0000 ) >> 16); + wIndex = (writeBuffer->address & 0x0000FFFF ); + wLength = (writeBuffer->length); + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, writeBuffer->buffer, wLength, ioTimeout); + if (rStatus > 0){ + *(writeBuffer->bytesReturned) = rStatus; + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY:Device Timed out.. \n"); + *(writeBuffer->bytesReturned) = 0; + return CY_ERROR_IO_TIMEOUT; + } + else { + CY_DEBUG_PRINT_ERROR ("CY:Error in process the request..libusb error is %d \n", rStatus); + *(writeBuffer->bytesReturned) = 0; + return CY_ERROR_REQUEST_FAILED; + } +} +/* + This function will update the checksum value in device configuration table. + */ +CY_RETURN_STATUS CyValidateChecksum ( + CY_HANDLE handle + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 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_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_VALIDATE_CHECKSUM; + wValue = 0x00; + wIndex = 0x00; + wLength = 0; + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, NULL, wLength, ioTimeout); + if (rStatus >= 0){ + return CY_SUCCESS; + } + else { + CY_DEBUG_PRINT_ERROR ("CY:Validate Checksum Failed..libusb error is %d \n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* + CyReadBootConfig will read the entire boot configuration table + */ +CY_RETURN_STATUS CyReadBootConfig ( + CY_HANDLE handle, + UINT8 *bootConfig + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (bootConfig == NULL) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; + bmRequest = CY_BOOT_CMD_READ_BOOT_CONFIG; + wValue = 0x00; + wIndex = 0x00; + wLength = CY_BOOT_CONFIG_SIZE; + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, bootConfig, wLength, ioTimeout); + if (rStatus == CY_BOOT_CONFIG_SIZE){ + CY_DEBUG_PRINT_INFO ("CY:Successfully read Boot loader configuration ... \n"); + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY: There was a Time out error in Reading Boot config .. \n"); + return CY_ERROR_IO_TIMEOUT; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY: There was an error in Reading Boot config... libusb error is %d \n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* + CyWriteBootConfig will write the entire boot configuration table + */ +CY_RETURN_STATUS CyWriteBootConfig ( + CY_HANDLE handle, + UINT8 *bootConfig + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (bootConfig == NULL) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_PROG_BOOT_CONFIG; + wValue = 0x00; + wIndex = 0x00; + wLength = CY_BOOT_CONFIG_SIZE; + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, bootConfig, wLength, ioTimeout); + + if (rStatus == CY_BOOT_CONFIG_SIZE){ + CY_DEBUG_PRINT_INFO ("CY:Successfully wrote boot configuration \n"); + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY: There was a Time out error in Writing Boot config .. \n"); + return CY_ERROR_IO_TIMEOUT; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY: There was an error in Writing Boot config ..libusb error is %d \n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* + This Api will download the firmware on to Cy USB serial device + */ +CY_RETURN_STATUS CyDownloadFirmware ( + CY_HANDLE handle, + CHAR *filePath + ) +{ + UINT32 fd, bytesRead, totalLength, bytesRemaining, ioTimeout = CY_USB_SERIAL_TIMEOUT, rStatus; + UINT32 address, *tempAdd; + UINT32 checkStart = 0; + UCHAR buffer[CY_FIRMWARE_BREAKUP_SIZE]; + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + if (filePath == NULL) + return CY_ERROR_INVALID_PARAMETER; + fd = open (filePath, O_RDONLY); + if (fd < 0){ + CY_DEBUG_PRINT_ERROR ("CY:Error in Opening the File ... \n"); + return CY_ERROR_DOWNLOAD_FAILED; + } + bytesRead = read (fd, buffer, 4); + if (bytesRead != 4){ + CY_DEBUG_PRINT_ERROR ("CY: Error in Read Length ... \n"); + close (fd); + return CY_ERROR_INVALID_FIRMWARE; + } + if (strncmp ((char*)buffer, "CYUS", 4)){ + CY_DEBUG_PRINT_ERROR ("CY:Not a valid image,no valid signature .... \n"); + close (fd); + return CY_ERROR_FIRMWARE_INVALID_SIGNATURE; + } + // Read off the Version before reading the length of the section + bytesRead = read (fd, buffer, 4); + if (bytesRead != 4){ + CY_DEBUG_PRINT_ERROR ("CY: Error in Reading firmware version... \n"); + close (fd); + return CY_ERROR_INVALID_FIRMWARE; + } + tempAdd = (UINT32 *)buffer; + fmVersion = *tempAdd; + CY_DEBUG_PRINT_ERROR ("CY:The firmware version is %d \n", fmVersion); + while (1){ + bytesRead = read (fd, buffer, 4); + if (bytesRead != 4){ + CY_DEBUG_PRINT_ERROR ("CY: Error in reading firmware Length ... \n"); + close (fd); + return CY_ERROR_DOWNLOAD_FAILED;; + + } + tempAdd = (UINT32 *)buffer; + totalLength = (totalLength * 4); + firmwareSize = firmwareSize + totalLength; + bytesRead = read(fd, buffer, 4); + if (bytesRead != 4){ + CY_DEBUG_PRINT_ERROR ("CY: Error in reading Address ... \n"); + close (fd); + return CY_ERROR_DOWNLOAD_FAILED; + } + tempAdd = (UINT32 *)buffer; + address = *tempAdd; + bytesRemaining = totalLength; + if (checkStart == 0){ + // Get the Firmware Start Address so that + // it is updated in the device configuration table + firmwareStart = address; + CY_DEBUG_PRINT_INFO ("CY: The firmware start address is %x \n", firmwareStart); + checkStart++; + } + if (bytesRemaining == 0){ + break; + } + else { + while (bytesRemaining >= CY_FIRMWARE_BREAKUP_SIZE) { + bytesRead = read(fd, buffer, CY_FIRMWARE_BREAKUP_SIZE); + bytesRemaining -= bytesRead; + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_PROG_FLASH; + wIndex = (address & 0x0000FFFF); + wValue = ((address & 0xFFFF0000) >> 16); + wLength = bytesRead; + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, buffer, wLength, ioTimeout); + if (rStatus <= LIBUSB_SUCCESS){ + CY_DEBUG_PRINT_ERROR ("CY: Error in programming device %d... \n", rStatus); + close (fd); + return CY_ERROR_DOWNLOAD_FAILED; + } + else { + CY_DEBUG_PRINT_INFO ("CY:The number of bytes is %d \n",rStatus); + } + address += CY_FIRMWARE_BREAKUP_SIZE; + } + if (bytesRemaining != 0){ + bytesRead = read(fd, buffer, bytesRemaining); + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_PROG_FLASH; + wIndex = (address & 0x0000FFFF); + wValue = ( (address & 0xFFFF0000) >> 16 ); + wLength = bytesRead; + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, buffer, wLength, ioTimeout); + if (rStatus <= LIBUSB_SUCCESS){ + CY_DEBUG_PRINT_ERROR ("CY: Error in programming device %d... \n", rStatus); + close (fd); + return CY_ERROR_DOWNLOAD_FAILED; + } + } + } + } + CY_DEBUG_PRINT_INFO ("Firmware Size is %d \n", firmwareSize); + // Reading firmwareEntry so that it is updated in device configuration + // Table. + firmwareSize = (firmwareSize / 4); + firmwareEntry = address; + CY_DEBUG_PRINT_INFO ("CY: Firmare entry %p ...\n", firmwareEntry); + bytesRead = read (fd,buffer, 4); + tempAdd = (UINT32*)buffer; + // Get the firmware checksum. + fmChecksum = *tempAdd; + CY_DEBUG_PRINT_INFO ("CY:The Checksum value is %x \n",(*tempAdd)); + close (fd); + return CY_SUCCESS; +} +/* + This API is used to Read the Silicon ID + */ +CY_RETURN_STATUS CyGetSiliconID( + CY_HANDLE handle, + UINT32 *siliconID + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 rStatus, ioTimeout = CY_USB_SERIAL_TIMEOUT; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (siliconID == NULL) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; + bmRequest = CY_BOOT_CMD_GET_SILICON_ID; + wValue = 0x00; + wIndex = 0x00; + wLength = CY_GET_SILICON_ID_LEN; + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, (UINT8 *)siliconID, wLength, ioTimeout); + + if (rStatus > 0){ + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY: There was a Time out error in Reading SiliconID .. \n"); + return CY_ERROR_IO_TIMEOUT; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY: There was an error doing read of silicon ID..Libusb error is %d\n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* + This API reads the SCB configurations and can be + used only at the time of manufacturing and programming + the device + */ +CY_RETURN_STATUS CyReadDeviceConfig ( + CY_HANDLE handle, + UINT8 *deviceConfig + ) +{ + + UINT8 bmRequestType, bmRequest; + UINT16 wValue, wIndex, wLength; + CY_DEVICE *device; + libusb_device_handle *devHandle; + UINT32 rStatus, timeout = CY_USB_SERIAL_TIMEOUT; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (deviceConfig == NULL) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + + bmRequestType = CY_VENDOR_REQUEST_DEVICE_TO_HOST; + bmRequest = CY_BOOT_CMD_READ_CONFIG; + wValue = 0x00; + wIndex = 0x00; + wLength = CY_DEVICE_CONFIG_SIZE; + + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, deviceConfig, wLength, timeout); + if (rStatus == CY_DEVICE_CONFIG_SIZE){ + CY_DEBUG_PRINT_INFO ("CY:Successfully Read the configuration ... \n"); + return CY_SUCCESS; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY:Error in reading Device configuration... Libusb error is %d\n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* + This Api writes the device configuration on to the device table of CY Usb Serial + It is used only when the device is in bootloader mode and at the time of configuring the + device + */ +CY_RETURN_STATUS CyWriteDeviceConfig ( + CY_HANDLE handle, + UINT8 *deviceConfig + ) +{ + UINT8 bmRequestType, bmRequest; + UINT16 wValue, wIndex, wLength; + UINT32 rStatus, timeout = CY_USB_SERIAL_TIMEOUT; + CY_DEVICE *device; + libusb_device_handle *devHandle; + + if (handle == NULL) + return CY_ERROR_INVALID_HANDLE; + if (deviceConfig == NULL) + return CY_ERROR_INVALID_PARAMETER; + device = (CY_DEVICE *)handle; + devHandle = device->devHandle; + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_BOOT_CMD_PROG_CONFIG; + wValue = 0x00; + wIndex = 0x00; + + wLength = CY_DEVICE_CONFIG_SIZE; + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, deviceConfig, wLength, timeout); + if (rStatus == CY_DEVICE_CONFIG_SIZE){ + CY_DEBUG_PRINT_INFO ("CY:Successfully wrote the configuration ... \n"); + return CY_SUCCESS; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY: Error in Writing Device config ... Libusb error is %d\n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} +/* Flash config enable will enable reading/writing on flash*/ +CY_RETURN_STATUS CyFlashConfigEnable ( + CY_HANDLE handle, + BOOL isEnable + ) +{ + UINT16 wValue, wIndex, wLength; + UINT8 bmRequestType, bmRequest; + UINT32 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; + if (isEnable){ + wValue = 0xA6BC; + wIndex = 0xB1B0; //ON + } + else{ + wValue = 0xA6B6; + wIndex = 0xB9B0; //OFF + } + bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; + bmRequest = CY_VENDOR_ENTER_MFG_MODE; + wLength = 0; + rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest, + wValue, wIndex, NULL, wLength, 5000); + if (rStatus >= 0){ + return CY_SUCCESS; + } + else if (rStatus == LIBUSB_ERROR_TIMEOUT){ + CY_DEBUG_PRINT_ERROR ("CY: There was a Time out error in Flash config enable .. \n"); + return CY_ERROR_IO_TIMEOUT; + } + else{ + CY_DEBUG_PRINT_ERROR ("CY: There was an error in Flash config enable..Libusb error is %d\n", rStatus); + return CY_ERROR_REQUEST_FAILED; + } +} + diff --git a/cylib/lib/cyi2c.c b/configutility/linux/library/cyi2c.c similarity index 81% rename from cylib/lib/cyi2c.c rename to configutility/linux/library/cyi2c.c index af6a4eb..10d52fe 100644 --- a/cylib/lib/cyi2c.c +++ b/configutility/linux/library/cyi2c.c @@ -1,686 +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 { - 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; - } - pthread_mutex_unlock (&device->writeLock); - 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 (glContext, &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]); - //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]); - 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){ - 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; - } -} +/* + * 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; + } +} diff --git a/cylib/lib/cyjtag.c b/configutility/linux/library/cyjtag.c similarity index 88% rename from cylib/lib/cyjtag.c rename to configutility/linux/library/cyjtag.c index 0ec81fa..f286a70 100644 --- a/cylib/lib/cyjtag.c +++ b/configutility/linux/library/cyjtag.c @@ -1,248 +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; - - 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; - } - - bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE; - bmRequest = CY_JTAG_READ_CMD; - wValue = readBuffer->length; - wIndex = 0; - wLength = 0; - - 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; - } -} +/* + * 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; + } +} diff --git a/cylib/lib/cymisc.c b/configutility/linux/library/cymisc.c similarity index 86% rename from cylib/lib/cymisc.c rename to configutility/linux/library/cymisc.c index dd72904..0321e39 100644 --- a/cylib/lib/cymisc.c +++ b/configutility/linux/library/cymisc.c @@ -1,591 +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 (glContext, &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); - pthread_join (device->uartThread, NULL); - device->uartThreadRunning = false; - 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; - UINT16 spiStatus = 0; - unsigned char spiStatusBuffer[2] = {0, 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, spiStatusBuffer, 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 (glContext, &time); - } - transferCompleted = 0; - spiStatus = (spiStatusBuffer[1] << 8) | spiStatusBuffer[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){ - pthread_join (device->spiThread, NULL); - device->spiThreadRunning = false; - 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; - - 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->spiThreadRunning) { - CY_DEBUG_PRINT_ERROR ("CY:Error already notification thread exists ... Function is %s \n", __func__); - free (args); - pthread_mutex_unlock (&device->notificationLock); - return CY_ERROR_STATUS_MONITOR_EXIST; - } - ret = pthread_create (&device->spiThread, NULL, spiSetEventNotifcation, (void *) args); - if (ret == 0){ - device->spiThreadRunning = true; - pthread_mutex_unlock (&device->notificationLock); - return CY_SUCCESS; - } - else { - pthread_join (device->spiThread, NULL); - device->spiThreadRunning = false; - 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->uartThreadRunning) { - CY_DEBUG_PRINT_ERROR ("CY:Error already notification thread exists ... Function is %s \n", __func__); - free (args); - pthread_mutex_unlock (&device->notificationLock); - return CY_ERROR_STATUS_MONITOR_EXIST; - } - ret = pthread_create (&device->uartThread, NULL, uartSetEventNotifcation, (void *) args); - if (ret == 0){ - device->uartThreadRunning = true; - pthread_mutex_unlock (&device->notificationLock); - return CY_SUCCESS; - } - else { - pthread_join (device->uartThread, NULL); - device->uartThreadRunning = false; - 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__); - free (args); - 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->uartThreadRunning){ - 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->uartThread, NULL); - device->uartThreadRunning = false; - device->uartCancelEvent = false; - pthread_mutex_unlock (&device->notificationLock); - return CY_SUCCESS; - } - else if (device->deviceType == CY_TYPE_SPI){ - if (!device->spiThreadRunning){ - 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->spiThread, NULL); - device->spiThreadRunning = false; - 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) - 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; - } -} +/* + * 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; + } +} diff --git a/cylib/lib/cyphdc.c b/configutility/linux/library/cyphdc.c similarity index 95% rename from cylib/lib/cyphdc.c rename to configutility/linux/library/cyphdc.c index a5a6434..9dd44b9 100644 --- a/cylib/lib/cyphdc.c +++ b/configutility/linux/library/cyphdc.c @@ -1,130 +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; - } -} +/* + * 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; + } +} diff --git a/cylib/lib/cyspi.c b/configutility/linux/library/cyspi.c similarity index 91% rename from cylib/lib/cyspi.c rename to configutility/linux/library/cyspi.c index e33a479..56beee5 100644 --- a/cylib/lib/cyspi.c +++ b/configutility/linux/library/cyspi.c @@ -1,644 +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 -#include -#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 reserved[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(glContext, &time, &readCompleted); - if (r < 0) { - if (r == LIBUSB_ERROR_INTERRUPTED) - continue; - libusb_cancel_transfer(readTransfer); - while (!readCompleted) - if (libusb_handle_events_completed(glContext, &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; - 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; -} +/* + * 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 +#include +#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; +} diff --git a/cylib/lib/cyuart.c b/configutility/linux/library/cyuart.c similarity index 90% rename from cylib/lib/cyuart.c rename to configutility/linux/library/cyuart.c index 01d05a7..f6ecb04 100644 --- a/cylib/lib/cyuart.c +++ b/configutility/linux/library/cyuart.c @@ -1,588 +1,589 @@ -/* - * 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() -//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; -} -/* - 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 (&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; - - 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; - } - //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, buffer, length, - &transferCount, newIoTimeout); - elapsedTime = getUartLapsedTime(startTime); - //Get the new timeout. - newIoTimeout = newIoTimeout - elapsedTime; - //Initialise totalRead to initially read + bytes returned now - totalRead += transferCount; - //length will initial length - transferCount - length = (length - transferCount); - - }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 > 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; - } -} +/* + * 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() +//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; +} +/* + 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 (&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; + + 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; + } + //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, buffer, length, + &transferCount, newIoTimeout); + elapsedTime = getUartLapsedTime(startTime); + //Get the new timeout. + newIoTimeout = newIoTimeout - elapsedTime; + //Initialise totalRead to initially read + bytes returned now + totalRead += transferCount; + //length will initial length - transferCount + length = (length - transferCount); + + }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; + } +} diff --git a/cylib/lib/cyusb.c b/configutility/linux/library/cyusb.c similarity index 87% rename from cylib/lib/cyusb.c rename to configutility/linux/library/cyusb.c index b3ddada..eb6010d 100644 --- a/cylib/lib/cyusb.c +++ b/configutility/linux/library/cyusb.c @@ -1,638 +1,643 @@ -/* - * 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" - -libusb_context *glContext = NULL; -static bool glDriverInit = false; -static libusb_device **glDeviceList; -static int glNumDevices; -/*The API initializes the Libusb library -*/ -pthread_mutex_t criticalSection; -CY_RETURN_STATUS CyLibraryInit () -{ - int rStatus = LIBUSB_SUCCESS; - - if (!glContext) - rStatus = libusb_init (&glContext); - - 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 (glContext, &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); - if (glContext) { - libusb_exit (glContext); - glContext = 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 (glContext, &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; - int rStatus; - UINT32 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_TYPE)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; - int rStatus = CY_ERROR_DRIVER_INIT_FAILED; - UINT32 numInterfaces, index = 0; - int devNum; - UINT8 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_TYPE)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_TYPE)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; - int 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->spiThreadRunning = false; - device->uartThreadRunning = false; - 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->spiThreadRunning || device->uartThreadRunning){ - 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; -} +/* + * 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); + 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__); + printf("\n rstatus10= %d",rStatus); + 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); + printf("\n rstatus11= %d",rStatus); + 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); +printf("\n rstatus12= %d",rStatus); + return CY_ERROR_REQUEST_FAILED; + } +#else + printf("\n rstatus13= %d",rStatus); + 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); + printf("\n rstatus14= %d",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); + printf("rstatus1 %d", 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); +printf("rstatus2 %d", rStatus); + 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); +printf("rstatus3 %d", rStatus); + 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); +printf("rstatus4 %d", rStatus); + 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); +printf("rstatus5 %d", rStatus); + 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__); +printf("rstatus6 %d", rStatus); + 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; +} diff --git a/configutility/linux/library/libcyusbserial.so b/configutility/linux/library/libcyusbserial.so new file mode 100644 index 0000000..09240c7 --- /dev/null +++ b/configutility/linux/library/libcyusbserial.so @@ -0,0 +1 @@ +libcyusbserial.so.1 \ No newline at end of file diff --git a/configutility/linux/library/libcyusbserial.so.1 b/configutility/linux/library/libcyusbserial.so.1 new file mode 100755 index 0000000000000000000000000000000000000000..2490c93821358c52daa17b382f8a92e5521933c0 GIT binary patch literal 109320 zcmeFa33yaR7B+lucRK0rEFBTL8$sx>gvAXUMHJ8|G)5&FkszZeYmjJIgakoBq5(}N z;)EHU!5MVG6}K@eVsuagBH$kPsOUswG;Pp{j!RS||NEY*d;4}s9G&rd{^xtXx!PTI zPF0;c=hXh*>aaXIZmi2R4eN0mCmN($1}ILBPN=vwo+rl`ZloAFMjsmOva~PE93#;S}KIc3axTyqa5}8sZXZPI9}J+nO`>O`m9i!Ber#g z3^zWfo>^cl8?d=_^}Jm}K71m{`1`p@dEq`8`&h+je2&D2e(~XR*fDnufk^L`sYckn zVp6p+v!P2Q?3$aFRPt=v)TAb(?`gl=QkLuT=cG;Q_1c8UwxrZKSO5CT!$PMIA3APs zj+?TE;4>5-K1bv8D}0W@XBa-m;d25$d`93iQep;rnPHrSPYyn(;6uImjKSwrd`>5U zCl8;q@Hv|Vp7HpcBQf<=fM6m%=ixIMp9}Gsh7X_V_{_xTB7A1!Q-sePeCFeGDL&S- z0Fe@lK)3{-%Qbxk!ln2u!)LkXU8Tcvge&k_iBBayUBY{w{rfxnmVNu~DA&9>cRiR_ zy!z7SyRQoVY4qEZE*XC7B~RTsyvNReJ=dY$#p7BiH*Y6+nxcA1;mPzHGy!OwGhQlwu@x2ibT@$`5{PC-I zJ@mV(FZ-_xo^n~Px5xRXA2erXWVdLiei;sC@*OP+}o^y8Is;|EtHU91Ls;wtJdv(L5lX~|4`!k+5&b|CSxV+QnSX^R}1F56@gD_A!;s+r+(t-SboydQ$6Zv03Mo03qFpxXqFYiRotWNSj)k%I% z=N-x4(+R&{Cw_=^VlTuP9r@>`PV7Cb6FEaW(dQ;iv>oXmO6izCtrPi6I`P}-kZ;Y& zP}zRI=%n6ZnCv^s-=&j!W02U9{sTIZ^Ij+QuIfb2#7_Knc_;i=I+1fe_z`^CKPPtL zw+A}W^JoZ&v=;*U)=tK04bnRD&p7b=bRef!Cw6V`L?0LY+>!kEq`lINNyAkoTvPbG z3wsYT!p8htBSKqkeZBZ0&Bz)hY~y3-!RHYzXYFW3zpVnJN$O2Aj+?I-dv*Sy@B`&H zwv&Ig&i_6aFg(wzz&Jztd780ev0{9x`R{7}c~>gN^_ss%{G4Wd!Un}N3HtG=)A>ho zk;4jn1fpZ?v4jQxxMJ?YFTAyBKN4DT5V1r0oi5{p;K5f2#JwiyR<$ z9#w(tH7KWLpknCmV%(zh59Y=S&yl*`IofYOj8Oc3n*S%=Ui);tR(oY>ed^lj^E8UH z-l>C>9BbdTR{QhVOB8>lmLEgC><`uL6|WD!=tTLi_o5mnqH{I^lfHzm%IV zJol@>FtoirhbqQ{y54hSJxVjGR%*V^U!v`8(fU~SHtF^{g&RaXO)4<9Y54;dDaIvQ zew)_kPQB@SQs=)|%WrKbKdk-JYr4w#mRp4Zg!E^V?*HXl&QvHyendMsS=T#9>yvS^ z%J{y{f34fiVvu`%jLRue-aEqve#G zrZTdh@tLRFaqhW_zEJCVknRsN%M`y>=f7UdxgbyRpSI*^{z!e8m;ihDxHSK;sGcg<@F#KU?dW%)<$u9QihkD>eUxNs1BD^={DZ*h?QgtoaiM zZRsat7O4DhX?<>j9qd0b-5>OHX50vUGL4Xtd22-1sDf&(|J_B3zD~<|PV+0~D*hH- z>O!sOSgpV1hl{kmBd<{zZ`1iVNWEdhxGkbNDmYmC^PI7Y)@BeKTm0W*0s~;a*a?zZ5bEhmUnYN&0$`oVDtfIL^#+1`0Q!VBQkwa%y48I8-uk))=XAVY`gQ^JZMq zj#WBWm{L>~I&JQ(d6pp#ft5IKe&Jjz&Wuo^XzoSO*~&O&+QJz{Mb0cU z=FOc|1I6;GR=hjK(-^F4}q4v>An#$hhvtd?;2j z%SyPUaKYTd;wdv16fG)TFl8FraS??pF-rb~CG*KTix$qARty&z)DWx!^s;jbOU9Qh zj1yx@7Q~6%%f=SZyKMBlxoDDNu+i~EcNQF7TsUn(yr__>@X6EXEhvdDDx6z#=Dd=k zS?FQ9ca1MxSXh!@1a)-#&!CJcv!@l8K)AHGbiav(3l_3J!fMtuZrc2Xg)=7<%_$_O z1mV0{GpFe;BC1GB*g}=MQ%V+0o4asUA%^3@$Nb*iug=v~aE{tq40!!M|w}(LAn(emQJ5jRB`}&#B_fAbNE)A36|5D3FQ1D>9TY)qv#0Qhz|9gGGpGH`Nf4Lg`H%J zCtDTkb`bH((WMKE3k&BP3#n8wr-CulN~Xo@SDCEFow1;B8al5`bZH(4SH9?}xc05s6<OG|EgrKsH`kKq{v4rp8}7M^?po~M%_TgpL%mdA{M_) z^SyfCYVj>P|1T;(w$%o<`t~!)!PiiTq)m13^^rsPvmJbWR1p4r2mdHrx?wDK@bet} zG6#RUgJ0p`U+LgiJNPpl{51}~-cn2IItTw$NB#{C{y`3Yjf1bD8A+{m@bew{>l}RR zEXL%W4*qOM{(1+$pM&4v;16){8y$Row2;&$2cOue^|Uzn8e)^ARtH~0RKgFhi%5v$ zl)V2E0$&japYQstXP|>`9Zi@v#KCut&EXC{jy(30Gl&)2G%`?ciHul4)xk z{HT=~;W`H&6M_9~aPa*$*Dz`v{8R_O*1=D6@ar7>bO(Q@gP-Bx*E{%^I`|C^zJ`(| zwb8*3IPy0+_|_Sp$t@0kt|Nb|gFnZ?H`YglqK~^sOnrIRM7GA-}7{ z)K_?YL?YyOlbHI7tdB^9{Gi0t*TD4=iI5+XnED#BJ|YqFfri-6@bwXiliyup>MLh` zL?YyC2uA4K^$`ilzd&N@D}Q}NBIFlJOnpsSACU<8he%9)OCrEroLvck4S|4 zSrSuU^VdftLViz)sjtQBBN8G1P>HFpvh@*(kl#yU>Z@XXL?Yz(mYDjgULTPN`6?!) zv1YxZ$j?$N`Chj^A|d&GB&NPLtdB^9d<_K(U9&zSA^CkJroL*|Mmw49f0)G7SL^zSM94o}V){$3@8loh;OCa__2yQ2p1C4o)#dMf!;ZYk(QMy*4T!pzn`=TQL%cVU8Fgc$LfUs4kBlB3XjzY{RL@G z#j$lle?r;J*3k~X9|5QX-;7=L+C$|=2R4G*$+nl-;w4N6l)avH>9~0h}8>y zHEB*Qu{xnIC(S7(RwMKR(ws_S>x90TbT`t~LQf~nsUub<^m(K?WyIzSJ)ShDir7@4 zPbbYOB9<@oDWne}og?%Kq&bvhLxet>G>2*|BJ^O=hmy_|x({g%&6pwdA*4AZV=X_> z{w|~=q#K3yljabN)eG$+&7l{o6Z*T$L33!uYJ~oRG`BFZbwYnannNj8E%a{E973@& zq2D1rfb@K!UnR|<5t}OXbEG*WV);UECC#l$EJx_aNpon#h6w!-X%2~4MCf}+b11|z zg}#+Ew=OY5=s%I>mNeF~PuidK5Yml8|AsWT5V3lpuO`hcV60B)%Sm%f6{`_?0qJ8% zuM_%W(#Mjn7J54AVWi81K94lF9I^RAk0(8x^i-iwCruPOmM`=vq)#B7BlHQRN01&O z^wFe8l8y*HnDi*pnL>A295H59gO(?E)u`^skh{vmpdfcpYi{K~a?4vY7InjPapGla zy6|1l);KHBdkof|r#VZ^Ix^6Eg;oCTB`kmJs|ZkjKg(~~@6N4k$=%X)Qm(l@_m%x6 zVF+8Ig{3KBs(gESWutC_9HVqVZuzK-Pyiw;|51{bTQ%xp@S8@Vg_?5lb-{Med@#&^ z9jMRx66jNYl2Mu(yAU~*-l+fcMaq~MMYh#nAoB;~m>V;nqBTvQp+{6k_XRe2dO~=4 zi@Bn%WNi7eeMU)2EvLNZ6Je+iNh!-Q^9>zp4(9L_^k`NBXOWk%w=V=qTHcMU4}f&ox5eX zJJ+nwt%5J3O}VQI>Y#E{ZsnVFZ67vPbWi!RJw^$oy~Az-{&(L&nyg>vLR#R_f}JR| zZdPR`qR**lzALaP`cg&oLj*5ZM0X>ouZVuY#O*mA=#8+VGI@_2=vAuVD4Eyf)z5)^4Ouo@{IP7?R7DeQ14%8dJO*q-Oquen z)KRuME6xi_etMbSCOB@l-#Nu^wVfd^Oc}l&`ih*E6`xkbyaz-xmRsT zg0__tDlp!`DFA0HIaOn-(?+#Hd}*I}!Q_O3bO8!_n}hM9_zlh8(p*Kmh)eDh&el-krV{i$zc#H?Eo5qH-iyY!r9 zHi_i8S>?D==eUJASiLnYwv|;bTZ?f~om*K@kz1KpHm0(!BD!WrbRWCSj_8-noVz2s zjv)rljpzmm17{I>YT2?i_PF6aKMbU5qa*`C1tuy4Wp?tZOswV%<_Um$8 z$8GS08dguUV?A0>8+bIjcGmG*11m36jK{&aMHsWdpq7|iR^^+FRb*m}tr-#hGH~@c zCax-22ewt`AHQNhXPs&+1$3Q9u}(C)5jzWoY?WH(E3-3gm3YOus^CkAtcJBPu_CiP z`lU%N!D~>1|8W(S!T)4M^kr!DR7Lb91Zc7snWzVULwxWv3fX9)m(@UR&;#{lkG z)J@8OvSlx+@rPX2Kz%78<0>oTi;j$_00Wg8#3jyD8R4i6;Mdy&b*b$t4AhsP*^cO5 zeAC?fiCqS2gBqw1Ap^BB_8XP8F=4DWRORi>o$+kqaBZk60Q1!YMr?o7q>Jkj z8!v7TT6COfTtMQu-HUPC%5mF>aocK?^eJDqHz{!aER0(Yc2Adis&$WsrD`-5&^V6Q zd0)zSUdOl_@#duJX0sYIfLY}^1AXTBXiMPgHmnOMz|Oa#t~3Qhk%tQier&E1{5DEr zCbNd{-h3>zwUsRu(Tx~twH#`4nplO72RWEXXfHoGy%EPa!UqbBhkl@O?pjvQLR^ny zlUPWtQ}H(2`7d_w7s{8tfId_eeW7wYc4^}Z3`3@pra?$nrFmHg;_Iw=m2o!e3DJ$0 z9WDu|_hMwXgoJD%d%m!Qya7G1cy6SgYDhPr1gJ)GEArjV9+@=J?>DZ>Z>uQS2seF- zbWY&9<|a+rJ<6W?8)sGK`rPE)66mx}a54gmXFvdg;wbt)rhWr)99oo^$u+pux}trS+9qwO>F3GZonzc9cE9 zC?2#yBRKIk7y~Jl(Y@$vM(G@+AXSD0jHYAs3I|=IFN}ybEjz8*S02@?i{kAo{R~;@ zBjomsY%2}NNoycfRFR~FP)} zOsk&l4{f1azARt%@>qavW9{>B0Amw|ekJkm4wu zuM5v-VJt#MjJFz}dKj^$>%haPX~L*!GGyb_N9R6;xdY5SAGvd@qye$p%I^(_)`LbI zt4IL{V3X?Df00I|_D0F6mfJu1r}TE@-qCcV#63@4tbFu$=xJ%+dbXwg-N>ZW{08Gs z)qu?lYRRp9iBe|MJdjn=y~>`NN_1{=KT_*fzch21fMt=#U)I z4=7LAVq7Jh6m8Nh&DIqTz!tVNT@y!fKg&(5H12Oyhr?m9?l`*bJ5+&meL&>e$)qVv z`g=ms36dmjz{ITyiH9N)lhuxbpgp{$5&CmzM zKF_Uu4z<@~vc*m;+Gx9fKMc?_OMUL3t+|!;MRiS>F0uKP2}ZPjC3n!4+{a)3=9~}j z`13Y&hn>0Ke3HB6yA;N@w4S8O!M3UbtctB>J?2kzEZZgd+)hCC8XTc24mOPK(Khbr z;~R^w*y!cUYV1w@9@Ps_i0cbK(!pdAwmVpf-eEkdGPiK`1>%qd@#gmE$93DIAJt){ zYTMEnn1y5UtR2zaK>l}Nmxayxvc@sk3-1m*nzsk7@DX;KACFs=SBJ`)#=wS?^UsY| z!dp9<4&^v2-qn)nFr8CCBd?PQuac>abQ*nePR))27n6SfXd& zNQeQ2GS$fQ$o}T1yXa&NIj4(;s4-Z>m3n0IB00fH+`C8v4jDQ}RgPDWjv7SETU}O$ zPk+SAPG_Uyo`=k_jo4q*}bhMCPSyD3jK?|7VRsd;!o&S5#3H^ zRZdz(bf-?v#D?Z)G}m1AXGe3Tbm;CJd%slhf*PiJX4_AfaQj*kLjCnz(BL~RQ}yCT z3(R>_xvqXk4sm!6!iM&P8@%|mW%botbh+GBi`ilndU7Ru2CB+r3HaR%Y-*{>djV9- z$(7HZR@pkH@)h>Pg>as=Vbf-f$L{T0Ofg(Qo1-AUDUHOXK&G|f4SkGximEpEMy^&A z;roK-E+F=S@RMlQC8t`WwzA+peQd9a-p2vy9J(8=ekl&CaX5^f4O6u4jJ$mfb;wkc zAjdYxGd?o58<`q+XMAg6x$bl=0gl4tVjbbp#q8d7G>jz30-*xpwO}N-TR)|;Hi>IX$zW&cgwh5F;n zUIJ*P1;@=|9MKpnJ=l@P0~X*1Bw*9tRT2umtjtf7o){~KtC8|;=|PSZX}@ByzbWOa zS%Z^13LvHoVMErcMdHkVSPeM}*;^B&NRwuRy)S_+jmuS3i%pz)I23kPmTtquh|aHP zXf*Lo``Gu8XuQpBO&hm@hBP?s$0ldJ+AhW%k%c*8YE^XGEMIg#3d%$c_$)ptbH>FO z-_0p`52ob()|8CgO_+*LehgI_dP2SqtsEcW#u8l-4Q#0@*jAaJDvs7uE4MC{rHwEM zn`^xmp9reaMv;fG5^M0rr#UUQ3sPIF@;L)ER;sz%URsswT42YIc<-j4f}2ugq&4gXM2rWnM!?bT6kEtVAt1%`=M0Z*N7ukJ0TpemBFag0NZ-n6D8C04FVQ zn=13Uz>u2>?m!*KUL-$KZO>Dgm8})gePw*f7gUR7mFLa#A_f=2{eK4})79eUYi<*` zahN8;@_Wkw6a`lN2JW7MT8k}W*Jp>NU~w=f(Gb3Jad&d@-=$mv8%o38`%mxRjHkitnAiq z!)}OIsb`|+|DLlw`u;O<&+mdA?}#-GnE-X$pRmr{#j!|j6HZv-TGZ~*M=V5>amLyn zeFm?DmNjtW^$s>(yWsElaTfl&J_|QulHVIY3m^2p)q1a&FMB-``zbn>M~c^-ZSs0& zZ8FvB$bca>ROa38XqwN&q?fE_+8+Hhv5nTF9nfeS)WK|npM6#@FX7lHGm?t_&aRzU1;&otQJRhw)XAqx7&xZL&=C` zo9`=4kh_j@dA^95kV`F=B&3(w^?rciqVHQkWmL97AAxD1Is&6nv3PKhz!x|H-%gbh zPQaH!9L{G-&I%#w<$!j3`Lf%wq2Cd`oyv$eidcv8-b+;lx96_P<9kPR1_7`iecSdM zuSy^%V4Fwr>hsaMK|GFcz;fH1p%XNXz;@_eD34=e%n!3r-M5KusYI%r$zz`=b-oF# z_UE||j zfZ%MH!tvgMew;ACvG!pG{)h__(8P`gdY#-GLLwWMr&_=YlGib!_sNK60;v-(_y`JeZ(>%lxkB`yx9CV@Odc@NM zYQ&?J^@!J?7hlmfB@Fp1ArJGP60}-~2B2Dlq8rPXZImIukyeVkIOMf^U#-IH-c@<8 zf`jfMLw?&EB8fR=$k(bN|Ee|QYpo&A1WHmnZrkGxP6sjk$CjZy8sWhpyHh*&hwBseayoH#M&19`q}0y`fP%t0Xks zfHVMy`!J)@5AF9`O=`Jb`6{aB#Sy{Y!aJg`^9?TY*UaMagNtbkYQcoWS(5(29tl^m z@?OcUDy2q^Rm<)>7iez7x#L!)k8h*29Zk3MMKpFNOeeh@qYs;(!z}t`&{q6IYGBnT zeLi+2YQ!eA4hk^bc{IZ2gSe{(9IW)tLn(9&2yN1)QeIUKj%$IH&mup1<14u6aXv$P zt{!7ky^wDOhdYY3*tcLqkcw#y-IY^R4XP%?@T0@a)~3%K|XIP+d!A zRqGXSeCgQAF{)n!JC+Q24cyrb+VRWa%$L=4gG+B%GBQgq=@`C{V3rm1&WFX2**oX!Y<=GBVOb2)~Dba(}AsbjnLucpef9u^Co$2&0Z(>9I z0dqBY2YUBjm6-@g0vuAe{RkTlxz@_VH_T=!uA9iq-GgwGjyK$DFrR12#jaAm)*_i9 zkO?P+nDuH88$-@GM>-0Jt-=swl?#tM)aVc_hS3T7p$(Q z?jdOG<;Nhf9KPCvc{px$^j`0A<)sdfPu6+K9$~8-F2yQ`6HFpR7$0rVTl*H|ag4VA zXuqhnu=DAScnf%S z`jn}*0$ZPjHhgPc&X5}Uj6I*^^eZ9Df*i+xzuvANiT z%bKEmPPme&NS!(oiLy7s8CB6eu}{%4RPL))R&0#ql2%hy2c@QUIksVDxKqICxp2gAvLtL)wDsN3L?X>7tN70XVqA0f~%_rGvmULRO!cp=*mh1@R zkm1FCWe+ik=QJDdS~L~a!4TDBL$&tByf9U^I^D~%L^R1SD%bgDL<;%Wdv4U z1C^W4c#3!3njYJMYFEh}5ojzw`uJK&BU(^;knI0UyQ+@McTQ^Y*@#&AvduLO2v5OtYGgRkAfz_7A9WN7LP?K{PJdSDD{a#ab)#!}h*@TNymF24lM#0A@vH z-U=KJH_$B@>eyW18&1Oa*V66R*jHtKPgIe=Rl)@v{#MDl{d5KSRZ&R%3B%z`WS&)? z_nliL$-Sy-v;^j3Zh)#4GFs}HRbKereyK&WRK&AXIJ5i!JmouE5&jm6_M#K3^O&rD4kfRdC@l}KnsD|Ncm{8qT2NKvY`&G#7k$`7ce1z3%FiD`8S**<3$Fq{ z2SKhHf_-2Q>z8*PrDsxU3mBH4jM0p0&8aF_kz17q=dc~5+kIZgp2ps4i+*W~beh<+ zn3I%Xyr~VWtV7#7L@Bq6kF4rc>#|cz3!%d^3J>BvTvc=h?g(Lqslj54Q3gn(+gB$< z;`btlOPA*h7NdkeC$iN!3F?KhnD7?qauLbbI*YfrVoLQE7fy(6}r z6ZZ(yr#s3F7yG3WYC(hBXb`)A?s@AFA?RD<)AL`7l zQAc`T*SW9P<4p@^72N;sz}GJBZw~Y|(A_$Rzx6f2LUb&Lr?32PJbgze8dFE>q?Bac zth)mGe(!r8EVS)F=uh@N0y+2-~!{^IaBHESL)#1k7)BM5x28*j(g*c&OW z{gIYzy#V~k)*HDv8EkGpu(octoFQx65?!~Ri?9iv&jp|LRuW)UY;m*LhH;PZOBY$E$b&ag<~ zEZ=z7$#+1wPb`~^jv8SUJm;7vetILQ(+3-YH__M#ufn0&7GvMd%f(@c)wF~XMHGTq^IG+bYyeWi9eCNr#2T*&v>{qyt<~)Os9Gp3QA&$90 zfR9E!lQlTAs3Y&}M___FMk7~2eQsrb2y0qBpo9^a4l#voFMENj&vr%wkJdv(Q{`K2 z^|2GxY}tq{9^aR;Q{rrmMWU3|)L)D%g3ERibnKx)$49?c-eM{zt-MW~wA4@Wd;ds9 z&$1DBMAso;xWRr^y3Pg<`@jl}EgV#VB8Z1r2>?DU!Z{Glu8E(?$=eaOIku$ov+2L# z(yL6DO+y~WC5S`|m3NzubEpQXv^QD(Q2c0;_~EepSh!tbpqtLTft9b|uNEm#Q;e_Q z2xrIvXh&1mhcFYqzl(;3ZfKkxO}%TZzee@d zgKcg4Ph}0k7;nH*R}WLMmx0NA`2Z{@1MwJdGODJ~7k=xN_fbNRe)|W+C&MRC@iJ7? zU65||A`Eck&4dc*R5I4Rh}#DVS77D+tW(V+{F!qJA*z;KTkK#6s|`|@0;w8*MMyAw z!U~H9J79$mkkR_Z;6T)cxdn16^9Ll#dk0RCo*$EI9wdJc#;!wj}5>TnoNP+6+2%Aw)7J3$?6 z@t0cSV=1c7;0GSbJfWi_v zM$9C8iO0Wy_2&~7S0}k9>_6GG_2a6%JT!cQL&IL|8E_@K^q=7K=c7C0+fe#fZ8PLA ztX+9fRly#X2I8g+9EkU8-e?{;WG<2R{(s(s`d`Gd;w@ctN_QDHEM?ucm%}|9m0dKTGbjtW-ur*2JJ>t^_RG6t z;ywR&x`Vv~rUSaR-=Sf)tYwW8tJ|44NAp2dv*CY^YEkXwaocBko>E6**XH=%K6FYh+Z`Q zEA7#bKC1n%wD0+hDGkGRW(R{Tw%m7VIQ~pcBa*1JCRh<6*<5< z6RcVvTpQbu<7@7!mGL60jva(WfcwAWZ#x_U#ohD)F~HI#9d;h1)59Bju$~i)f;}Ert7BxmBL~4~-c7OCkGA+#m7$ z1ym=pmmVma_A1$OaZ)+O))l|3#KjU^X~3-#{OONOh_7a4_?sR08=EcoV|~1Rz<(Au zwifz13^JrYuq9GdrI^;SeQQ0w4UB!f|heQF&ysN1kX-HHt= zFqG0A<5cUydkxs9I)0>C4BxA*+h$%)Db=l3c&lYoH)wVh{thdYxoTN!8?NC8u00n= zWTp2~AS5`E#kIz}awt3z#nA%4tg2h!1&6AEm2LQ=$fz0hZCbC@Z7!;Yga6(G4mP$l zxhmP3uYlqK+EYh1{T^4>(cN!_41#Ly+K&aNhy+#D8LSEoWdT3>uVMTWvkn&Xj~;A4 z>&P{&12N@}Ut`_^zbhBX-W4wysVV<(Pp5z^&rzMu_}8K|7A4I1`j2QY;rPova8aV_ zkF;0aaQ!G|PxLXqA^i}3)v8~GS0Wgt){Nf{LH=bF<_y2-zf$<xF$a4>qTfl9vtpY97N z62RLUgf|1ytVOs5$aDk34R}@1im(!|Il>;p_z>Z6gnz{=rb!5|dmQBvPQ^>XH3&!I z4Q(yLZg_3ofUpW-E5hdyhOs#Q3vcF!BRu0Nlt);Gs}hS5cHN5d2!FtR##)4RxVYMY za64|?wj%r+?lp(8ct=qdeYy#1IZgxTy){5x#|RF~X-mL3xCG z5Y{66+g_AMxZ^XFM|gA#%H!DC?{kz#c+eLpkMK!^ixIx~FO)~P>r0eJ*!&gBBmC}b zlt)8b+5ynMW2F3vQ2 zq@{SPu_X2bzb8KRH?_63ppO|DnPW4;rw39m^OhMW9Wr9@uln_2QI;Qr&zhUt+Tcq2 zVcE&}RNvCpHlN&+GcvDnjZRN?U4j~v?4@8gBK_=y^l^6jTJR70OIsV?_{Ga#XQyul z`)Z_zsGlX@-NnreJ;BGLF6?Awg=fk-cRrn|1R%kM&Z71HJ3vbOE(W!JwC>DT|Ytxf*TX*>O5JH037sP{0( z^h3V5{=Mz=kx2glbI->K>AUUp$w=RTIp~7~{dU>CY#m zZ@1GoBmGRwY40bbzip@QLV6nJy4MrZU$)ctA-xXi>?gK;uD9&;o@m#lcp><9Li+1= z`beZ7i#c>rLi(k4`edY6Aw9>LeuX4U`z=NKy-1gTTiy15U)z6ck^V5|t@Ea1+e`}}jLwX73_89Zo_3yF!Z%?cZqn_$~{ES3;Bj)zx z1o@^de=^dyKi$^$Rf7I4w*E_z{^xCNZCTFr$#MUzMfzH#Pe41x^*hVO96iC>jP&~L zo%??m(zADT?*DyAAB*(P{NEF6+nGDt+Ad76@7K0{Bawa`*0NB7eqC(+CL_HZYuZOn z`&=Ky?MM1)FZ_u8NIxCvlM>{gW6R%+^sBKpHYLda(3Zc86;SD zKWLXF(G}YoxU0A z6W{N=|Lj8gxk%reVBg2KefyB!7ki#8r+mlw>xp%`AJX4)mS&*YV zkbWZeWc&l&wtTnWu74lWkH8+Sv-F+lze75&FxvIIDsBCj zB7JtVhOBJ+AG6cfB0U*`6OIABpsRNWU$i{4G+Rtp7d#^T7W+@IMdy&jbJS!2dk(KM(xBMr(*v<`#oRxi}nsk?x#3G9cJrrm=4G4aH0-p>2Q$_uhHQjba_mkhsphQ{W{Fn;V>PJ)!{@P&eGu`9bTiuKj`pI9d6R$b{)Q{!;f_MwGNZB zb^SWb*5NQ6j@98r9nR9>A{}0%!$0WoP91L2;dULqsl$(S__Yp`2k82Bn61NMIvlIR zi8`F6!$ms0Mu&gU;hj3%q{Hnxd{c+sTO(58siQ}q5E(e8aC*_SxshQ<9&_Z7BZdxA zk;u_Qh8{QMxFN^LKR~Yrwi=!-1C_F^0Ts6YJ{$~}@dAF+uJShxS2a#rkml;~FHk5SQ~<}%c?%}5XgRUJbX=lkdgE$ z3k*itU+jlAO|dMSFbH=j}T>l(C% z>o+Oz$4HJ3@1yWgrtgepkmtJyabF&zhA*4(Ga2`yqDcr{Ub4<&)Y}&h80ee)J>tGU zqEg?56mR&p!^gfUeDj~=dym^GjBy`y5GSGKkf8;xufA+$+?0PT{J_c6!t`u%x3<=+I4ouZf$0Dn=-T=e( z5Yx)2B?fI7WTw$g=UO>TBk(Zd{zJ@D5d^Z~NPiFMT7fY6Jxz)YJi>UE$}^C82B|!U zkUv=RxKa>L9m46wbsy?U9eM_$Ugq$o9rq3b-+HK=cD!=ai;$9b0^><=F6DP+o^EAm z+%DZNT|%Vz$Dwni-y;IN{sAQJ7sBrs@6`yA=06PXOMh6(WT0U|Y!V{i zUrK3@36bglnu=}~;vl12DZCv?-)0^Ujg<}CB}v=xybz{;G{wClgv);ee3Sl;5N`jI zB;FGhlKfxNhDJ$A_V=KvdxS{wU&Cx43*q%|rwYyHiKsKve>>gtnY2;ZNTM%Oykk*a zx6cqAnEti-nXOu@l-H{LAcW~Zi`5t|I^N}n3ygHP5N`i=nw=sN`0MDz z3?Y*J{3D6!U4%&SS23lV5MKZFs5!m6>tCX$D1E4lN{5xw5f}SJ#7G(gUW%74>~=6r z%S_L9Wub2WTNF0Pm5sRJe~rZ9QpAf@M2gU~Zk6a>1JjRjJ@fX5F>1PSy^&diM=SZEIsy)ti zns%NxEyYVif;X{UA9uZrcn0IagIMJ=uDxV19(o_blP;q7KX6S#TZc=)HM$poy}bL? z_`b3`4?xShe}N)PyVt|#S9Jdpx?bMB8sAI0H$tJs-E+aetow@)u&DcRIIOh$9Y`(d z&Nsw2FE>ISRG!3%DZPuE-7tI;3K-#=QGpr06%(~9%!@njFkek1g-h}62@eA&+30ow za;BwEbU%x7{(IQ#Cb=of@Ykbw`uRd6`Mc593*9urYXl#lp~dbuK&5!!#rGjx;Ct{3 zjJ*iD-3dK&(o5X8p)!Ar?q4Kv!~Yu+OWf?5x-%_xbJFqo!#EbFFBih^pT@>4m+I40 z_18)DnM%vwy6M-hO3NFB2>ZW+L(T9RY5}WV*<;8#ZQ4kqPqw z$j_L52D$%&b24TN_iBv7j8bagJri{%WmIRu_(K;J%``H8_bx;mht6mG_l&y?*ICGv zaU);wcncsqIb&TB^81cL#*AC*ncp{`72U?T>6^=%ZkMvYB5*S9AV0})9ZbdUDnZ#4 z@8S6F)dYt0kc^$Tfew#{Z;Wsdxn1EuqS8S4A8=ip;fk^3%N#Df&VyrAnZ^%U=1aD2 z_+fC(@O3cE6+RZ7!X3U9S|o)}M%VEeuJe(c5&J9h_r41fk4ef1nb)8KKlcC`-A&qW z_+N*UGY&C7qPBhyHSZz0Jdv?bETg9)%*Yt}<4{GpB1tUOOHuAfAsx}%`~$LhlOogU ziY)U^P(70(yat{z(4;qpBt^bvD-059Xp)h}T3JdK*ft}L#<85xNT-7~#p&Qfuq@+n z^E0r6532Y}NKWyR6FMJWQC>RJoDb)PCxL5(&qEF~oQLeL@V8)N>_Pjaa0uU?@WJp> za`<4_ni5_E?Y!X=QOXxS92|f6DhNmocY}Rt;koS5;TP$Z@U{33gwKJ5%>w)AplOklvM+Xne8{9+*XsQ2t(5h!&Rm?`o2|Ri)(>JZ)gUa_ITmp}E<+ zS^Z?oUS+`rVu5>g&2pvlg_h3Qx6q;~CU=dl)su`t{MEeq8aw>2k5IbHeNWN-+%ASO zmg$#dmZpD$Del!}%Ll&$zWL@>j3xK#)++}e&#w5EN^Jp2I~v%x-K#5> zXMMrC-~9)MoO|`U&XR`E)a)#AyryPmy~!S_si|2!N|^6)-{M~V)bcE9 zZIMqd&zeYmb?Ot#vpyvGzUpl`S<<|JXY0CGuUVcYWEDWAi!L(9l6Qa6lK*p{ER1CFO!Gm0UXx$dmHmEajB7 z%LhxP7coV25FcHvd{m=-bcyoO1mz=56)Qg!tC`~*YZTL8ia_o%H6?vb#;J+_q%?u`XugL@M|*x=q`NVCDc3J^B9cLlQ9 z;NEQ@Y;cc+4epV!!95ZkgL~A?2KTN0oC9r5yoYvX{$G z8e5TSr(c5zxok?|-ePgvfqUdz;GV>rP!8Z8-S^ye|E5J3N#jC-LCVK+el{bw<% z5J3NA910Wy=)aIUC%-1}Ift!k%uA3}nph)%{xWK5A%OJdDl3OZ z08$;;R30LLse@D=;(MusC66G0X@USM*f0G!j|cuB z?3aGL@(p3X^b;6Qf=3%sxGVE?Bi@nmjH@T&f_(%9`(VC|4_p=Ch6MWv7of!QuwWly z!9K!*eS`)32n+TR7VIM|*hg5fkFa1LVZlDaf_;QF_7N29gH4jr#l4Ny2=);Y>?0)D zM@X=bkYFDn!9GF?`{*v%N5(|=wI6+|_8BXjY!-;)lluPvr z`^dOXs#n-Y#&6y9tHM4qZV*CY9~o=J7KMFe{MmgQvMKB%;}-YZ&_-b&8MjIqg?(h) z;r=^PMnd^aSeUG^54w^#T+eGD!f?HUF&H?C@SGC{2~4K91O^GjVUWP|vE&j43B+NL zKq-|uR6qrm3N#YU4GE|a;s7;60xE&Pk%@XXf|d_lkgVxY_Fp1e097p2dc;CaIST zhqtM|USqmp$?4MTKGg*VL`J+RMsF`<8JQVI?>UI%oDwj4zY7Wc$8wBrN26H4<(dV3g0G-} zQt%+xahStGXS2T0xyWLMzD3*>>JJI-&>qB-jBc+Yf1tZ71zCgrAW@a==OWq{x)_OO z=qBWM8QuCLH899EnmGl$5H}2S{gF8Zya)++5fbnsq`-@A1TO-kTyv1A`=v0pYhaw~ z3lRRhVRGP17oBMMzoQmsxl-ZcB!5rT7swY4y#8aMX5efwCC&c=4IS^|ILI`*&7ndQ z-PlFa@bT?#45%w}96 zC7A;lS4c_bK*kkPk~xTRg_L9t9?Pl(DakyH4pK--=HZ-`6jG9T1mg-R$vl!XlR`=| zkK!V$kdn+Hj4Pxhb10V}g_L9-&A38JGJnOmLP|1^;TYCPN#?Ljc;nE2!RgYdnJb@x zFG5d(t_l4S{(2%*1LxL-{tAC@2@L~hYbXZ|@pPyw@@xyuM(Q)6!H91U4FP{g==W%| zouO;Me>U_I;?IR{MvFWjs)vLZLSqoG4?O}ouY~@HJgN1oS0S0l9{)B^t7p&j7A z6Z#08cSDauW@G3!e18z?iSG}MNTwOQ7~6dxJBJyPzTqo^0%lmchL8Qk?9RBy$8KUC z!g#W83s0Xt7*FxNhbqjTjC+00Fwdck`+QfD--~g-FNg8ojHmiOWnB@*(|jo$CRvQ9 z`?@jShw%&_A#$@X;{n5UF%$aHnOXf=c7TgB*4okRUa(OGIOH9bZWw(8CK~7>KHy$m zyS%TP798dZf_AN*+xI#Ou*eC0e+wtsQiE2bpo}PEm^Qvi1L`t^a;A zQGZvW{uZhAw@9tOJ5hg&)cPkS>Ti)+e@~+R$+rGkNo>J4MDx8TE0tfjHNP86o$~yf z?KFSeOz^x#YRxTDYyOVO7Pmcbky`V2WxHm3-XgW;yUYa7zh_#W&lHBx=4XuKB_Ad4*^` zI!CGeysh~W=(^i01Cq8+Gqrm1v1YYD+9qTXKD(B^IeI`E8;l7O5?% zPPAmTZArfooKxnBB{5kR@T+v&l4Z6f^TiU3mp(GVTxv22aG-Kji55Q_qlt5T)_6)C zBT{A428kcoQu8pDm4Bjf|A^SJCQHZtb9$nGEK>W&BDH_cNc4|IYX6K&^p8bq|Kuh5 z=S6e_2kzBt zmk*GM>MJ!*6%UY!>1#DQCJm5z=^HgT@(1vJr`gIaBf8^&-_oC&nmOQm>ZGZu1GYM- zF$1{0G{03f}-Aw!bLM)_&LD5zZA)&vQ+>NyGhY`v$`FS>?=Gr@L z3m>6{zyPz~WcE!okVv-J_o%XOv$pSVs`kmszRk+M*~-2rlzn(DFqsqlrL6Y)6I8YH zY{y=O;iVkAz;^6Rnz@iEbnF0GJr=1cY{CFpJTx_afUF&w${!$0$7Oo{8Xzl&rY5TP zSgiCNH{cjnv4qPm{iD>sTu)v~{VVj`H9(e_rB?IYM_ZPuD(1nj+}8Dfh|-49z)Ox- z2FlOo#jn$mrVKnT(ZJ#RWdK+Pjz}<2Q`$gHX#+2N1n7Kynh+2%_B z%SkZsqeoGpW1?f&|7) zTEVCj#!QOCm`VQz#`Jt{!T4csDd#)t&A%e)AKFk3dZz&$GCzqJ>N5~ zU`)?G#ubd|`GIi-V|w;8u3$`$VUkcVrpFXQ!I&PG5DLchB$;s-)01oxLQ^oN$1BsM zf-ya5LMRy1lVQ$>Xa!?>x|m}@C>YaousH#Qf-yZ^%{Ywd37c^k)01UhfouxK^b9g@ z1EF9{&tM@GjOjT{2nAz$4i`efm>%aHMbA;9n}RVtLrn*a>Ctx-J!@?k({pni#`N4m za}|u~xs`46-@%xk5dv2VjOiJv;!Tk1=@`aLzDEE{-cd}xSE7V5lkbx#Va$}yVa${s zHjL@*<7x+E`i^JQXA;KrohoJ##`KMoC}B)rKBEaRraum2`W-N)-w9);I$+GyIEVPp*9WZ994P&OpVa(JxjF}pT zF;jm8#!UUUFlL$q#!Pd-m}w3eGtB{Gra55DGzW~C?tn2f;xJ~01IEng0LJuU{*&XY znPQ&c0rc=%80{In2;XL~FK`xDFotip5hCDeKI0mTOagdzvjI=@0~ha%1pki!p51J~ z)9m8rWx${So>cKBC#v)LFr&;3WxDde8TqJP?c$!YY({uu!rW5cqoq(r# zom8&?Ptyr_nohveTqCw9z|(XBp5`rXHB=zJ34mu` zFn&3}^AC^~6u>hmfM-wu&!7OFK><9234rG`ewc!o6K*#tei&&T-l21?CWp`*V7 zqb_inNuvz^uaOd1Y#s|D$=`@E7+7Mm!94!OBrX>s*$7?Ae9O#g2d;4!Fx$B+gd zdn1#D1&#-b^B-b??06Oy$hd_CGHzjkj9XYB;~imv)Y-xUIbba;kZ}tOc}ut0Wi z8w)Hz#ZD~HkF_x0Dvy zbH2mTmt2QPmlJHy)kAumkKNDJlksF<1@rV~JjHhc%SIUY`qnW|7UMqOa^~qv@qQzX z9k3kH^lQ)&ab@y$CibI)df&wnN$1u=z3D4JkPGU8a zgvMF54-e5cS=@)mAJ?y4Pop$|z&lgYk1gp9qXb^uGQoF@U(4{`F(iYw#hU5@Vsr46Z`PMZIcuF z@Tlw>rbW%|BMo?*Zm`)##AF)bi7Wy!uFFlo&=?!y$}40^;te`w_>~syrF!ggQ}x)W zYVa~MVJuu_T4O;P{AyD*c(H15i=3bu+#<*KkwIyZr>OQXm(>t}v1)&doT%D=g_b;5 z&_vftwZ5&sqz|zy*EM1T#xHt1m&au9E;MGpW7&g0qr*y0Qx1!{RS3`leXhTB`F~n- zMSt;Ei*nbx<^2iFxjt9kTC=>rcP^~rcPJZXew8!zac?=O`Vy2D23k5l|$}V%3OI5Pn*2IE3@vs3C_IF za;6x1zh$Vj$zPRelhN$lY4tmm-F`X^ymzeFWyoJA6a#nL2F^${aAu-`7pWR1C<8S$ zUKyyVd}ZKlW#GB0eKa*uZpgZdlttr|xfk2!ih-9T7+9lXx1$ zM3BWF%z(TNb-7j>S@JUF&vF?4|JwT!IJv4S?^ji!d7VHK=p@aWu1?4TNOyJ+S<-9L z>D6A6bU=#g?n+fbcU46S(bQA;!XBZOKA3Amf zo%zHGF7vtY{m*h=y;og5fa3yA3exZ1^X_uax#!+{?z!jQ=id+ZeI3KbJd1oq)K>U; z`0tRdu<+dWn`p8)ZY!ko%*SnoP!5mV3Xj_gt>d=B-%wnFQrI!C@2Gxl*?A+(Mq zbJ_}*E;~bQ^@}Eb_aN!AQ2?xE^Us1Bv+QapCotxf1GMNKu?EfuXvw0#_mNAX*cQL2 zwng>_e3VUt^XB`IY|&#}qCKBHx)yzvmrf^%)$wZ_IeGpDO7O0(k;U`hM+kg}Bd1v93n<;wzK4OW$F?{QlwQ=f*p5WTwsIQ`UQ)`7!n0|yb6P1msrZ)@{4C2)h59R^C=-Ux z%B!&k7DMMsdT+6#qyHRQ1I=USM*k|ZQl3zHgw{H%DO@53&^2P{WCQ40F?8Monf9M6 zhED1S{_`k2zqEv^JfFe~N^c3eoFn8GDD~4jI)o_3q4^sB#r0wwTA+r~=dWLJh^jr=Ph2NEz{*r4WBHAF zs(!_<34uj^^0}o`fnqIM?Ef{2CsQd~PES#*S%+AfPGxj)Hgm<(RCbx4mbCu;*NDZ( zL}M%1;;=;RVmrjNWTJb;v}B^&#g?>G6Ss*i$wXV!FjQjGh;z;ojII8|zIkEd7Ip%$ z#G#+>K#r`2mk~~f*_(g~T0rrytD$L748P^ANNt)lrWt)%<7N09&L5-|6$T;C{9Db*!Mf zKK!>SlG|61gPH$b%AJ_tY@!1zo+56T=%5vxrubgQz4j`>{TX?H`#T*|=H5K+TwT;h z@5o>z9K6P)Yy|&3AwIHf7+C{QD;3#a<% zReon-^)*!8k7$_ww>^^ms8h;`Ft@GYasNj&?voeyS{DBQ5VOtpwcK+5SA^{9wLDDx zSWRJTx#K@4rm)VnY&g|e$67X=YOHN7TS_&yb1hp+HP*eBErvf)gW6hdF}C6o39DBU z^6w(#A5%*je@O!b_zsY*P>_GOApbWvtXV_+dJny!ZY~(!E@gKMh8pV>3^mpv7`|U^ zg@U2RcCP&}75V|1El9S7K_3(bwFrX_co_5{!yqQ+!!+xG7$J00svw_2QVmx>M8m}E ziNM4zX%@Pgf_}aO{{UN^5ZLJ@u**x}PEQkPOq)Ps+622Kr8a@ax`n{qUIKeP60pZZ z;1wPMuk;Z321DTLpAu=WqnC|4g`~W3^K6VqYuLE?IyG*tW#gtgHV&?3tGc_0%AnO0?9iQaBjagxgUgPFlyvEJ9c#WIadySjd zdySjddyShnc#WGk93fX?rX%BK;U$yJG(C}Vv)J8?FVhh+kavU( zxE&$s*V%*NOcVVaB}+@${;7V31Uue zFT$)>VpFT?$!!kO@M7m(9__r#qwRKiEOIU57|PRY87XM4Wu!12%I?BbuVtj5xt8%~ z2 zUdza7=ukGUWu!E&YZ=X5jE~~2-o;3%tx~y*k-~H+`=fZhgwpV#Y+Ok9U4#n`W#d9R z^7{IHAIipsbZ?_-Uhbi6TuAp2@|g?isCAtS=~x8Jg>*!O9?HgrbdMrdV$-GNXM7WX z&ZIv8d>0S#QN)FGw?mNGM-dm&QP{bV?gQY`OSq7ZCCyw&N7XwQ(h>ii3+X80Tu4W> zI2Y2r18F8P<=R!Kl<6KDh5xgNEMLH|4K8nQ3&j2hwif+fmh53`%o(t(3QKDaN zp`&W^$FCPYeI}HEmwx3kasJ%&!ZzREQvt8AbJMu(jP8}p9~fS^#s3S!^S?bX zjN8t>ibUqNGaq&PBYt#G*BRcIcH0@Xj=AlO!sfO!3Y*)`C~R&!qp-Q{tPu@lZaX8K z&248S#OAg$3Y*)`NO;X{XLL(~x$TU?=C(5$vCM5}6gIb=QP|veMuMPzdyBTrgVwwJ zHPC&0VQSwuM1d53_sRqM9NpwrLCX_g_?tk0mM0Zgae8_~%6O30AijYo@YcV-JIJSo zG}am9Q$rf-2=b|+$QL=~t{|;Jd>Y#sq&1I^J=1aKF-U5=FZuwd91PM5$QP3vh^`Lu znVLAU19k)I{|J@X)QZbn3A0Oyl8^5d67F#*xdjFdq2y9SiJ-pKgSy5Pb&Vdpjz%l^$ZWH8dFp?rl_9jK~-al>RBFC z&-QS6xd+t>gR1piEWPGgPl1Q3Fn z?=e5FFdtW#k1Nc75QSN;ZEmEQde*hgzYB#~j_)kI+;;`$bUwbbu!h63v{_i|qsdl| z?<}n22p!*{S)K1ITG$}^taE$^dN-Y*c?Ig-L!i*3cVA9;zL?&<6p4)9z5S1`cN5Nk z6ur9{73cS~7u|w`BCqVbbC$o8bk)z2FmApU{Rcn(ATyr61D|tL>wAs9T0#3YzWeA6 zEfOkNp}(J`Kd}FkH;A^MGkPfN_lLfSw9x29zkg6P&kj-19};c$8d+UvEGDZ9jqR1y z#pfhtLRJ?V8$=(Y({&{_$=vc$B4wCJ`FNZuvH085Ov>9~7#7w0jSeY%J44D#O4>`x zh>)WC{-}_mOO-KIqJ@-kL9kOu(O8F&qOmq1T%6vpuM4Oi|@Mez-XcsudnogC0~X4XV}?Sdq@Nt^*Hs zk+b`3S>!x0C>$O*S)RMGJmp2s@#_(eyF9~2bKK?mxXbf#m*?ZxBm9Y8kKo>Vc=?yW z`rn9IbkT$;U{R=HXQc4wOmb4N?2kY@uovC)DMa|YH;e8S55-|dHq zYT)nQEc&|&!13Lik0SG;9F>;e=~(pij}d=4zSIvOy>stEHPk9|?*fILdl#rm=iUX1 z(87&;In2Ea{|{l$y$jz)_E+G&3pGH?KH~9Q7`%o+j`$s9)uK@5Z z`vRK5zbsOLm&;B@TiMGl#^1%uK7_x)WxJ4O>v9W!aX;q2(8Irc72a6$mLH{u?KnBp z2aJA8CuedmH5VvQ*j%7MVRL~3h0O&D6fSmw0`cMx<>X9q>Rg~e?949+7vJ(4tV3SW zPR{n(Xi8k7@OmIBe#@uvRU4&00^H9&%(%0i68X<0Vk-WUf~)-0E8aMccE@j89$2@m zhRz*iFSylyDu(u%f+sKw4QUNo$tOvrn|_(p=f%^<1b9q60>FEDwx zjS5}=>5%t*hrBO3)vDtRWVcl#(Kc{;Pxc&`$3Wo0e(fjzh@iQaagaj3sl+)ItK zh&`|CQ&RO|hlYKNfCBqwOA7u34PWAM3KvV##z%ww5=X6q)2WJ6hloU(@@%^}xh_#B z*R7T8X}pwMgHG00@~s}rv?&vnd~ZiNd()B!Xyr!Y*J(=r?#jmr_tTZ$t5-I()m#2% z-wDb|>zrjoaj6epxcsY>2Uz=gqKj|xC^i1JmF#c3z(=phS+&Hb?zHMWD&o;Qk@Lb~ z$^P#Scm5jtldG9KoPa(U#5Y#@A0yia@n#M4N~8DRz_*6VTR7tL1(yEDrSEj`1(yD= ziZAB&HH_Rpi3>9B3B``K{|Oqc0{id1Va?ysEcrF6o-AN%m`ndmF30peo;A#*e<2@J zn84OBkDe5fP!`SeEmn?LCz0B59|~gUq*80`lT`EU}hZH6?{pkIMu6rt8r8K287aW=LM$OzGcGY8l-NvbvMn@&lBRt_9)yL;WAp z@tN-rH8Htf)5PR@O~1P3?&AAHO>8IMuj>EsKeG$<4r!Z7u{*U0_osAV7VaNZPguS_ z)PDyF0NM$nKvO8ouWJKpnEY4bAoQrpu0LuvR6rONI4Mf`A8GIP(=1Lrr2vtv0vrEUSo>= zYJ)vHk84bO{u&Q0YYp>DY+AvXYaEQZFz@Ni<5vC}hoJWwhoJWwhoJWwhoJWwhoJWw zhoJWwhhX6~4pm^#Jd3U@SDWT2x-dCz6n?(`12EVhcie!;9e3P-#2k0rK!-W*xWONw z|0{HgFxaIr;d9%L(#aMy|#bnp3eOFsfE=K(PpvdE8MLR#MxirZY1dQnBW#h z$ZP+_Jv%PJRQ+;Xp-)8m68k4W$Kw$FEEV(0bBJyQS{}y?`he(*I%fP7xr}4RTG*m~ zONVG`Gvg3VVdD@@VdD@@VdD@@;bIQag!3QDF@waxafm)272EHJiWFSjJxqKcU2O5r zZAfGBG5p25Xw%s)-5LaZHziqI`Wp)O68tm>3U5lEy#k;sZo=yldn5iX--KnEkKdIB zesKpf;J3UQseGlBp)~NE0p5t(ee(r)i2=4!$^`;^-T>cDz>@^{D+QkYQ&c2ZTAv(- zovM5a@w>~r@%Pi^CHVWd z8UL?9CmF)pkk6O(lQTT-vSULRF1RNr0DQBE4P8!jkPTfiHcbd zU(F_tz*@p)Jtrzg4tzwLP%>sc-<$pF3xIYaxvv-?v2=o~dCo z8E#WrerVo9xsX}x>Km#snm)Q(`TY$#B`z^@)g=$N>7Vi(PpAzru6Oh($njr zhnQ6H1ey)skfPT4#=b&&=yF79owWt@oLfN81zvhgROzYm(qp1ZkBN4$naNk}#dw{; zSg2j^rPf3Tt%_TTl3)6WlCzYOhn$vq*U5&GU-?MRxMjXYJ?YnQ_0g8$lM1+WfWA2UqraF;Q)qfS1mBhEA*EV(KwtOv%8FLc;w4dHN1~3p1It z$+%K-dnkC6D7nr@?_e$pt=Kz&Z=?7`&g&~r4dShdZmqnXiZ{{0%Cm`YCK{7YVWL+G z(C?hn~N^K{~UE z<04r;4`Sjl>2qJX*+-HZ*ni&*Y`FHB_`NrXz)bk0%Zgpnx6dbCmaa0TQ%Wb%%uMc_ zD{lo4U%IrFFuo}^)?`7MI+ zBA+~c2Yv&@`8HVJzv}F^ioFG&8o`)@T^_y?*LRp&n@r1m(XHaA|9=}y?gFJg}{*4Fuk9(2-qz8G8De@Xq9%Y*!6iSlaSpBZxN}#F^_Y9>iO{hg`Kh=We5ancn6@#NS%HNYFL>R8CU8A)jm!D36#R@=$0yqVuxpiu}FJEt2zFr*Ky^yh9>Y#Q4RkTbiN3qbF=P}w%Wk8(Y zp0*a1o&_{c=K!>gGnV?+oK6|fJb{Zlix9;oK5DXsRYcNqS3%5y3a<48Q*O}30XPy? z=1KA6`rsA$=;fyqU}cr>^3%B~PFQn#QyI0-*3;fs%Xpk~g2NX|x~f>x_e#>$c@|RA zHHZ?=1^h(V+#d4}F=7n#zpse-^3JIT%EneaC=0uNvIRn$HS}tvZ{Er30Ed~|&R*;bObk}D@Hj3-n3G-|QskYJJcEs=nK9JNYG!Kw)y0HH1$d2D z+}7rWpN1gMEa$1~ydrh|ZxSi@@bi0|vHqKutMIm5(A#qP$;>;%9B(64V}EyA#ql=! zAFMq7Koh*9`8ka>TgMA}=W??E(Yc(acGt>a<$R5v0t*O+qbbV&-crPCzF+t>~j>a z&Zbkw z0yFWUNWQ#;rc)^Hj1rWQ0&Q0}-qTgv6-mXzg8*O|$$&bh0RaA$`kz}Xp}<+beUBcF zjo5?srP;AP8=LR4FP+TJjP?dfs}5zeM@DAsOa14T{fOd$Qv1{+Q`yOxBQsO>gxwpP zIXL}bHaj{oJx!4*{2#TSjrv!X(?2^qIdV9ctF~wC3IB?vc5icYV05?TpXV#tTM}6C z;XvsFf4x69Gn$(rSa0B@D*MnkZaFd)o8mOMl6#&%Q<9y^&OB&0+gYxG-`J;?*h`On z#Z)=dOh}9YiG1a!YvsNEm1Xv{f7KFupQrYP56q0@0-w3zsjXB?U^vJH?PV96B~~hn9x#=YeGCGz}o$s-TimyOW> zdq#4Hdbil++3dt2yE!&O4VueNOiuLr{pgBy+&TaJPoZ;$Q<>jq@6=w0ZvKbpr_WrZ z{dBd@zSS~I_r(+}(d-7>m zxF0AvBpvIM2tcTsk4{mpn0>|m>B-4y|CS{&&9|V+-ZZqeH3*D?xa8V68>98fBkTBCD0!Fi;>dx2ZI9Q{s&4X@t_eR zmyJzLMW;rhQ+5`A@c$^|v+r12pPK@o@oXe-3nTeq^f^IQTN_?r4n7R!oKXmjUUX(fMxf{KU zyV2X{?nZOXG=IDqu;?7;OemnFe>}dSzo17!`pxtNip_k7naIp{6!gq@NaoCUc_<0a2_=6ijC50?7u-1PLsWNtE-!^ppH^pZ!S_T?AYmtOXj zNz8OB%luo*rf+dVm#w?)t`Yukd=EzN|B8;7PB)W{a{r-@vwwPentKGvE(z$*_enyQ zdJ=B6x;V;6y2J$@dRl49y$Rkw9(V;N9+mAbQ7^7 z#}4{0DvKSPiXFQHU31IQN2Ae^*t9(nwf7x9whu3+?9U*bU1^scyW-er^!btK^P|s? z3y$-v>}wAdtqW+{SwhstR5URim#R>lyS59LJ`#(LI<>tuMpaEoRk33uv14P$#z#<- zpQahRJvx$|q$%p?6sU+s?doXEe@R(v4^2q)&iy9pzpMht<&~~cON;-&ym~}Im~M#hp1Lx$tO$h8lkxupE#!3 z?J@3_@BI_&mg(X6tG8RGKe%7Y|uEGX1DS!pYIfW+ndC5H~WqL?)A0D$LL?zNL#-d)mjrO@@C z^GGmF#1P;;y_+GxfznIt4WlIA(}zc<{Fg7u+0FhnW!2CPqt#H2n{KN-mJ4KW4lK+} zAIlwl=vXc{!hb$>EO%&>5bWLf^I64n&)IBm$UmVi?$589rQ~pIpm1&lRc3B|b*v@LrMQ7|-{;04k%yX_qoNjNV`Eord}tPI z&&Hp-U|W_%kxmBcb)fi9qhYVfgrfzc^Q*35%|&2=Gkgz2@gZ#*vo{TJq_{wFE()a? zzxp~eM9?5YS`3Z2G%`o0DK`|BYF$f|=~@E0HuKP3Eax1Vcrdt(C-?tm>H4bFxrgHE z!hzvcrgWRrm9v!Y-;7-HQ`7%3Q*T)cz10X4jU9kpw3Nq$&Gwa)Fb8e4d13-dS?*{a z*t6O0AjJ{sC#Z}i@rlV%GtZOmczNy{*GwFmhD~JuUDGpH_%|<^iA~S!5&iM53H#X0 zEz?JHM+1FTf#vp&a}MQt*GsPE_`V!x8;R!jAY1SAcxtx8vBR<4E!mkvM+4!iK!v?y z<%7A8J%1~&3GB+l(>c5PQ5(*%E6SodyYe6^Uvba_8YR%UUCAVDJTw7~nR84Wvzv2> zO>uO@M91t(TF2X=tSpN&CAldcUbCNSPGdD4orK0eHeHY=TRcr^m51v~nCskwT3$>& ze$`B;eaYnS)%a7eK&2k}J2lO+t+p0K3?|9gECyUskBx6);Hx;Dve}4(46f7YA(zhg$CFwWl#Y zpaTDEm&7LT3?wpvC10Mj_Z!&MWZ(^%!1+NtddQx>>nQi6-dUA%Z$MxB1uaz_}>B0)zsBBbah!n;cJqqosm>Jo=jNj_;ryGayBFehLbRO z)C>%yBIz{4Ni9@ce<+?#hK9ra*G4j-fk?VP6(7zdQ&uQ+Z9Fkx)%9u(P3@uXrq+h` zo^EUdY>Q;-BO~$tNK;~Oa%X&?BR*hlYwHQttzRG9QnjgSU2wy?^%t(YaNVZh1w)x^ zB64XolE6knKceAOf9z81%v`VqFQdT=_I5PYSs@g^A+$aO(+oB?LROy?-<9pF8w>;I zP)Perh&DYy6=g_=M*{s{6-bTH;)z zsdy$5>IrS(adqKDe`K&>B$CKTyAp}Xy+Urj6Si zkY^mK47JrXi_Cxxk;F(m1zFVggfwT8z{ZLvj8t0K0+ZUT5fP-mCgRyhc+kS`SzC6f z4=keQhU8o;+!C4ZYQ5&2#-sJ< z0ETEt7WW%B*^sns8vV-@*xgyv)fv)1hwES%@)@s6D+&3%NH8TW+G#uwAI%?pd8I6$T$)i z2ttskOT*5SaBvqSn%b?_@K{H36s%2U($XKKS*de-F>Y$xS<})~AL^*-tZ6l`93F6i zgxYn9@DLEg>@&zMM<|De2O+cJ{!ErSLnIN+#2iMaQW$U`wSrMscTIOsSE#kUt*IMB zTf^?Au5K%fy_m+qQe3RN z18S$@F@uD`BYDF~4Bce8&eK7H9NJ#fLSpB#k>Ui8zK!=}>7)TDzO3 zgrRsMKY;+9o^&7Hq9g9bz+;&nfi@=gT9IMyFAm98Pg7g>`Yjg3%;6R$k;oYJe>1ai zJvwlf)AtG*(w+ zFw&plF@<>Q%8Ri|n+h{&uhmEWfak$3%$)1YD5)cmnSa2yy@TOsdPBY-6{q%&hBh-8 zInB%ieILrmcV_f#2OD&49{#LQmIjuA4W{jcyta15Fkcysut1mo^rCs0SqRoekYRooylMaaJffI1ozi-HTk9@qlwZ zkM0;yy2cazF{3~94b@~aDY!OdB55mgT?jHm!O;lj#=&GF8stAf%^LM^)Jqz01&uu& zB)h~dnU>MSL@E!U^)hzXL#s(-L1ZSIilj{Q%Y<21j~Ol$9>gGL#ams;RA}mwS)SLF z^oB8reciamxD(JYn#@8=%Eku=w5bb)Gv5k?DEfkE4~5CVMT|X0PGm5q>gooQ&^6E} z++CeS!X*WudG=i1+1(YY>&77DBy^Oa@W6TyJ{*R?@MEJqHpyeN6-on5m(XZ8X>96j z-Br`sKySKwL}x@$`;tl)$E-L;T1<%9R5(M*qzJvY35`DJ(L`xd>+0#~Xz%2f9io9c z1Pz25g2n}QNNF;?nx+_5s?f$lJ>O`Ql&8s}ShoTM4Tf|!{>!14U?u+AB#NjN<0Pg~qQxGHL%&5N#UG7U90bk}V+ zLu_AXWG~h;F~){EC5;`bN=iRr5lLl-^K8$f0}hj3SvTH397)h5m!NG2;W;tD(a*v1rL|y~J>3M|aIOlgbD}sJ}0?m&T6xU?h>G zxndxVR>uV1=MisFIw88@RMhIJ+g{VD4dCf?Xc`)+QK7K4zI|6)OM6Yd5s3T?S&8M< zYpexn5$&Bjoau!WdRaN<=ONP0KzO}QfKJgE;oIwKy3yxMt=iKZO@;==`VcLX6Uj_` zF9s$Wl(^?Qr5IUJ!ICCGV~9kG!Xj0(vXsw<5xS-mQq(CZ$Vg4ynI{h;W5gl|X=qzR zH?0dBo3@4OTI(&W1XEb%b%Xz*bfh1$4^u)9giG4OqJf3WkvvoiM{8?(>O&hZ+O%$+ zHLBu-S5&wo>s)@iAKiqjU+;173hBjIX8f@xox@%}1)70G?YOlw9Fy52SGecGm`GU3p zVK@IEGhm>wxwC<>1&666xLmOxSbamCkvC?c7jZMj)Agz3aC@S2tbrCh`2{>Pc>Vg# z#1(k65Ed=rVQ7QYRMx2Uj(Cz{)B&gi(dw8g6G_iw02nEVoek&~)aHs}0XqTBleTHg zx{F-R(caboeNYA~nx=pZHlI8>)^8$N$c%&x7r45fE-a}UVaM2RYVPQ4-xewWJHo20 zr)8G6^bH%=QSoHT*%cqaDiJM1LOK`;r#j)5D^ZAUE#}t(30VJH;^A-@8o@X(5mRGL z2~2I7j^rQ%nQ5+;R}m#J@vVSQnX%4DCN*x}df3b&X;>N32lIB2-9ksIG#)lq-kn3!sTXAJ;p68&BB9uQO+}rx#w>B%@>kf zQxoeDAiV8_-a=S0iM!B41l>`mcN43)|I1391g$Te9q5F061BlN=&C(3m=|S~N#hc8 zEnlwKGDu$p|8R70>B_g9uj?5dra#wlnhV_Iu>{P?G(ZCnX)yn z=Fnd1jCy(TaE&*L=Poi`QW>TJT%)@}^K2E;&=}iC-Giq?u@?-(5D!vL|I|sqOy#nY z%8(vz#3Mh1Y({ew4Ct?=76MKz@uH>juu$9H-XhAZwhoM$P;Y3U!+@frs@Op(eV4aU zHqgkx^Hvi~m%KnR>PmhBCevqaPfN2U>j|V3fl}28%E(}dRUlFgLxw;yZV(#6<9HgY zw*G6oGPs-@DiKubWU5Qdu6^TJ>~+IkbCZj76e&UDw%mm zp@l&-!f9yi#i?-C$ecnPlzO|+&xvI ziq?g9WWE;Sq!eZu(Cm(5p4YZBjTOr9{sj$md8*PzVOC~g5Hsmj+v~tKEUdK-<{EM{*W!uc zY^Eceg2@ar=2-K&2lQnJVIMUsHqgVFh9ahSQ~9kZ9<5S?X6Z@ez0^S@0&CcId8TpT zNJU~f99PK{tF%)+mL0%`Boz6Q!!n?x^Oizp2jXHLMW4Z9AZ8y6|%}x$Y)u>_IYWGBf+f)$^-v zyaO&^`H?~5b%UwK2=1HvIa>)hlN2>^ex->JDM`*womhYrVSKP-7eM zFO`h;U`S}hrX&-B7)aAN&hp_V{`>R~Fd&;cqBkYyE zFoALc_VZ;y27hM>5DT2UK4rR$LNNG6AzX&vM2Ab*w4z!lrp;Vc|G2t;81bMT0gzA3 zk+vs-q04l)pj~*gn9wBvX)UDVH-Wd%o3}UAHFx#2A}<6xjt&>8i$(gcO~dk%jt|EB zlL??k_K}V-Ep=RFu$D}AySj1ih^>*KB-SFVenW}y);pO+;CLaBHwL*f!0_NE zSk9ak{~N$z*Du4BweS~!V!e0P~Sl@g`Ar#k{;VkPr z&nyN%(Ym`R9A7M3UMzj7b!25R_067XUuZpB6u!v1 z`mM#%z{8Xd_3R*}YK_*t_HVK_cGQsfulPuqE4khspXe)57Bid*df@L99@ zMwt8Ywy@m^LxQiMd9zl3!k;v+Wl^2j6M!Be71bj>tf|kbNbo+^Z|y?9tZvba9rRx zYg~Ft%UN8|ufNCe+2g}606!J{`S@Nc5BHeM1OBW6Hz!97{0xOR?v#XU84p}isPNr- z8v05t=R$^S#P!%Y2Rt?hJfr0=tdT;#qh;NsaQkurd{^PO&r!}a;6Y8}emtV(6n+Hm zX@wuClhj|=Og~n5;TQd0PN-=|3Kq0{%kr{2<_`V7$8fjv&9l49dU%qwwbxZpN|C0#5SzaIK{KmZtxEhHJ$2 zcuLC|)^bew-=8D>Pv(Fx0RmL-c_AtM8;XC0!tYTz-=uYKWVj0v4YrzcE)+nOmeT_` z@!{bDJR_QZURctfq3JVol>a_0=f;9^J~Bu8`?dVXc1!u?+U{SPBmIn~@4Z0M{{#3% zzh5fc96)}THOkNdYi!Ct^Da% zc;Oe%#sDWin=d^8ZT{WL={4ed+&%}Kz8ps7T%vq7<=m(6Ckpug2$yq`wfR~p{1(OY zNrgYYLE!gk-9G?4sA2cxXPW*JoqxNvz2=vQe17^|Nxfe)ovmG)Ltd! zJfrykaE|nT+=3s}H15YTz=_X4su$>1eYsNMm)t6VI~9JR!V5oA+Nkh-8zte#0`hES zxMp@eBAWgUQ32ko@3IOvr=g4-()W7^&o{J6LNky2#T@0|sp)_HI!S+y^7&H=uRTxT z<%;L$6khlt;v;|uC8_7{e`@-|uUgE*hki(|rc|zsER_LH_@A|2iuttSvr5zdO4FPE zwNcYA@00Y070+5t|8zn5U7X&7B1f*%a;`pC-s!Mn{h7k+whG+H?fVp7_<@CwD!lMp zt@kLr@Wb0*V7Qd+{`-BvSGWNhelN>y5xdO-;@j+Bkl`oI`Wyj$;GFne_@UK{=O~9h z;#{nJc&}#C88|Ay$tD!qQP&CIPMm28!7ncriNdWEzG<1E5O#AD@V17dUosROO!nan z#Q;uer9=&!?q=1N*KQ$C;3A3OgO`Yh!l_hv9FCG?|JzI3f}w%z(9k%txMJ8G zk7qnd%{_HE29-ZP;5ifJaTj;IhRl6GFS7HF4bxfXe6w%n&g$K=q)mVn?D4d{?(Bg% zn^MjO5A6%gD!teSf@AX!g>=uTtsd(&93H?~IdxMG)%Uj5w9?tN5RSfu8sM19 zTTR>RaR?#Q-C7sYOxs%8Yin9U?TwA(7t+m6XfOm9?8OPdwObc0+y!8a6ZFae_T_4%HbsM(Y>p~l$c6D4pJnmFpe~@%0mFOQD_7)Oq>TZSa zrx8rhNMhN|JA-rVc}ZRDyu~gygNPZ+f-}ipFQd{PcMokW z^kJL>@SYDCfOB9fIquEPXqwGeFr>wMa04vJ&{pzZIQ8PpE->B+0UWC(TDev9ghsD-E4xGts(DTND8vxEno5JC$B^F_`ytm1BA8$ z^VJ)VA)&^I8J{^4ip8xe6vf4#baE4;QK+aB4Ks<(LgY_hdXK8OSTw+X$#SN&*!G+98~v!PzfiN517~d@QzE?UmCkc9Qz9Ey^MsR!#QjJxNTy2+rDg(+_b< zFH8~jj_gIYu1u+VswOo~=veIX4`Ceh4@`2Q?}8Qpfd21lM?eXcAHZP!TY7jjZ}EkBYmG)6C*+TN$|> zKOJ}FZut%E7zuT%s>8<+pyx2}K_d6=x*}VjT()ZmUygBT6&OJ1jA&jaWo|7L1Kp4& zR?9G{+0)s+At*pD1`!WjBI#0gp3^X>2~go^P#edN2|x&|9pk^!O0Y+TfW<$unj`a65@q;cnQ|(!n4T4)^uZwFmkJ*JMXb7~Gk?7W!=?1dMSCcp6uFwe*Ig)UnyEblx&GJj*~<<$SMR$!jb(FQGk1g533$qx$~|F+^U zm2K)beg@|G6_bHeOBovE$9DXE!G*u^M=;MNx;{7fn|jQ%2l;>F%5VG@%rnTf%*J2A z)&K%Tn<>xuH<+i{Pciiyat!?m&0nhp8b1j0d;)e~`cZ!D+RftM7+^#q%%A)-{u1Vi zPtAFL+B^;{jgULP@vCs2264?{>>%cOeL;TXe_@`6UQ=OV{H+D~&3?Uk{#fl|CcmlI z#NSbn-}rNwC(JvZUm^YP()_0VjNgZOW<0rP%ijkJ@*DpU^E_Y*)^ZB#|9C-u$B*Rg zlHp3&S=_%u{(S~7@!3F@4@zhJO?H2XVtILySUzsb`5a#0^Q}&P(S@`z^{*vsP{Kn5^So1%v{nzl#;BDmKX5@9(Z~S38Cb@X)Zh1I=O@8yF zeOz~b$8Tmzve*UfXY!fn_X_eG{~G%a%`Xq_UFz(# z^x2bQ`G>X$^lsD8T1;WuiaGM1y-ia7&6_=}%$) F{}2B-0=EDF literal 0 HcmV?d00001 diff --git a/configutility/linux/testUtility/90-cyusb.rules b/configutility/linux/testUtility/90-cyusb.rules new file mode 100644 index 0000000..4494809 --- /dev/null +++ b/configutility/linux/testUtility/90-cyusb.rules @@ -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" diff --git a/tinio/cy-config.c b/configutility/linux/testUtility/Command_Utility.c similarity index 90% rename from tinio/cy-config.c rename to configutility/linux/testUtility/Command_Utility.c index f64abb8..01ef543 100644 --- a/tinio/cy-config.c +++ b/configutility/linux/testUtility/Command_Utility.c @@ -30,8 +30,8 @@ #include #include -#include "include/CyUSBSerial.h" -#include "include/CyUSBBootloader.h" +#include "../../common/header/CyUSBSerial.h" +#include "../../common/header/CyUSBBootloader.h" #define CY_MAX_DEVICES 30 #define CY_MAX_INTERFACES 4 @@ -41,7 +41,7 @@ typedef struct _CY_DEVICE_STRUCT { int interfaceFunctionality[CY_MAX_INTERFACES]; bool isI2c; bool isSpi; - int numInterface; + int numInterface; }CY_DEVICE_STRUCT; CY_DEVICE_STRUCT *glDevice; @@ -54,7 +54,331 @@ unsigned short pageAddress = -1; short readWriteLength = -1; bool deviceAddedRemoved = false; unsigned char read_buffer[512]; +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; +} + + +unsigned int GetCheckSum(unsigned int *buff, unsigned int length) +{ + unsigned int i,val; + unsigned int checkSum =0; + + for (i = 0; i < length; i++) // start at 12th byte + { + checkSum += buff[i]; + } + + return checkSum; +} + + +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 **argv) +{ + int index = 0, i, j, userInput; + int output; + int count=0,h=0,cnt; + int size_buffer,size_checksum; + FILE *fp=NULL; + CY_HANDLE handle; + unsigned char buff[516]; + int silicon_id; + int tempSelectedDeviceNum, tempSelectedInterfaceNum; + CY_RETURN_STATUS rStatus; + signal (SIGUSR1, deviceHotPlug); + char src_file[100]; + char id[4]; + + memset(buff,0,sizeof(buff)); + + + 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 if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_UART) + printf ("UART : \n"); + else + printf (" : NA\n"); + + } + else + printf ("2: Select device...No device selected !!\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 (deviceAddedRemoved == true) { + printf ("Device of interest was added/removed .... Print and select from new list\n"); + continue; + } + selectedDeviceNum = tempSelectedDeviceNum; + selectedInterfaceNum = tempSelectedInterfaceNum; + + + rStatus = CyOpen (selectedDeviceNum,selectedInterfaceNum , &handle); + //printf("return status = %d", rStatus); + if (rStatus == CY_SUCCESS){ + //printf("device opened \n"); + } + else + { + printf("fail \n"); + } + + + + // printf("Please enter file to be opened"); + + fp = fopen(argv[1],"rb+"); + // printf("%s", src_file); + rStatus = CyFlashConfigEnable(handle,1); + + if (rStatus == CY_SUCCESS){ + // printf("Flash is configured"); + } + else + { + printf("Manufacturing mode of FLASH is not configured"); + } + // printf("status %d",rStatus); + + if(fp == NULL) + { + printf("\n fopen() Error!!!\n"); + return 1; + } + printf("\n File opened successfully\n"); + if(sizeof(buff) != fread(buff,1,516,fp)) + { + printf("\n fread() failed\n"); + return 1; + } + printf("\n Bytes successfully read \n"); + // printf("reached here"); + + // silicon_id = *(unsigned int *)buff; + + rStatus=CyGetSiliconID(handle,&silicon_id); + if (rStatus == CY_SUCCESS){ + // printf(" Correct silicon id"); + + } + else + { + printf("Not correct ID"); + } + + // printf("silicon id %04x,%d",silicon_id,sizeof(silicon_id)); + id[0]= (silicon_id); + id[1]= ((silicon_id >> 8) & 0xFF); + id[2]= ((silicon_id >> 16) & 0xFF); + id[3]= ((silicon_id >> 24) & 0xFF); + + + + rStatus=CyReadDeviceConfig(handle,&read_buffer); + if (rStatus == CY_SUCCESS){ + // printf(" Got the data"); + + } + else + { + printf("Not done"); + } + + /*printf (" 0 %02x, %02x \r \n", id[0],read_buffer[0]); + printf (" 1 %02x, %02x \r \n", id[1],read_buffer[1]); + printf (" 2 %02x, %02x \r \n", id[2],read_buffer[2]); + printf (" 3 %02x, %02x\r \n", id[3],read_buffer[3]);*/ + + size_buffer = sizeof(read_buffer); + //printf("The size is %d, buff %d", size_buffer,sizeof(buff)); + + /*for (i = 4; i < 516; i +=16) + { + printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8], + buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]); + } + for (i = 0; i < 512; i +=16) + { + printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + read_buffer[i], read_buffer[i+1], read_buffer[i+2], read_buffer[i+3], read_buffer[i+4], read_buffer[i+5], read_buffer[i+6], + read_buffer[i+7], read_buffer[i+8], + read_buffer[i+9], read_buffer[i+10], read_buffer[i+11], read_buffer[i+12], read_buffer[i+13], read_buffer[i+14], read_buffer[i+15]); + }*/ + memcpy (&buff[4], read_buffer, 28); + + size_checksum= GetCheckSum((unsigned int *)(&buff[16]), 125); + // printf("The checksum size is %d",size_checksum); + + buff[12]= (size_checksum & 0xFF); + buff[13]= ((size_checksum >> 8) & 0xFF); + buff[14]= ((size_checksum >> 16) & 0xFF); + buff[15]= ((size_checksum >> 24) & 0xFF); + + // printf("checksum 0x%08x\n", size_checksum); + /* for (i = 4; i < 516; i +=16) + { + printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8], + buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]); + }*/ + + // if(((id[0] == ffffffA1) || (id[0] == ffffffA2) || (id[0] == ffffffA3)) && (id[1] == 08)) + if((silicon_id == 0x08A1) || (silicon_id == 0x08A2) || (silicon_id == 0x08A3)) + { + + rStatus= CyWriteDeviceConfig(handle,&buff[4]); + if (rStatus == CY_SUCCESS){ + printf(" Programming Flash is done"); + } + else + { + printf("Not done"); + } + } + else + { + printf("wrong silicon id"); + } + + fclose(fp); + + printf("\n File stream closed \n"); + + + + rStatus= CyClose(handle); + if (rStatus == CY_SUCCESS){ + //printf("Device closed"); + } + else + { + printf("Not closed"); + } + + + break; + case 3: + exitApp = true; + CyLibraryExit (); + break; + } + }while (exitApp == false); + free (glDevice); +} +bool isCypressDevice (int deviceNum) { + CY_HANDLE handle; + unsigned char interfaceNum = 0; + unsigned char sig[6]; +int op; + CY_RETURN_STATUS rStatus; + rStatus = CyOpen (deviceNum, interfaceNum, &handle); + //op= libusb_detach_kernel_driver(handle,0); + 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; @@ -62,15 +386,15 @@ void printListOfDevices (bool isPrint) bool set1 = false; unsigned char deviceID[CY_MAX_DEVICES]; - char functionality[64]; + 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 ((UINT8 *)&numDevices); - //printf ("The number of devices is %d \n", numDevices); + 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; @@ -111,14 +435,14 @@ void printListOfDevices (bool isPrint) break; default: strcpy (functionality, "NA"); - break; + break; } } else if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_CDC){ strcpy (functionality, "NA"); } if (isPrint) { - printf ("%d |%x |%x | %d | %s\n", \ + printf ("%d |%x |%x | %d | %s\n", \ index, \ deviceInfo.vidPid.vid, \ deviceInfo.vidPid.pid, \ @@ -138,328 +462,3 @@ void printListOfDevices (bool isPrint) printf("Cydevices %d",cyDevices); } -void deviceHotPlug () { - - CY_RETURN_STATUS rStatus; - deviceAddedRemoved = true; - selectedDeviceNum = -1; - selectedInterfaceNum = -1; - printf ("Device of interest Removed/Added \n"); - rStatus = CyGetListofDevices ((UINT8 *)&numDevices); - if (rStatus != CY_SUCCESS) { - printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus); - return; - } - printListOfDevices (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; -} - - -unsigned int GetCheckSum(unsigned int *buff, unsigned int length) -{ - unsigned int i,val; - unsigned int checkSum =0; - - for (i = 0; i < length; i++) // start at 12th byte - { - checkSum += buff[i]; - } - - return checkSum; -} - - -int main (int argc, char **argv) -{ - int index = 0, i, j, userInput; - int output; - int count=0,h=0,cnt; - int size_buffer,size_checksum; - FILE *fp=NULL; - CY_HANDLE handle; - unsigned char buff[516]; - int silicon_id; - int tempSelectedDeviceNum, tempSelectedInterfaceNum; - CY_RETURN_STATUS rStatus; - //signal (SIGUSR1, deviceHotPlug); - char src_file[100]; - char id[4]; - - memset(buff,0,sizeof(buff)); - - - 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 ((UINT8 *)&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 if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_UART) - printf ("UART : \n"); - else - printf (" : NA\n"); - - } - else - printf ("2: Select device...No device selected !!\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 (deviceAddedRemoved == true) { - printf ("Device of interest was added/removed .... Print and select from new list\n"); - continue; - } - selectedDeviceNum = tempSelectedDeviceNum; - selectedInterfaceNum = tempSelectedInterfaceNum; - - - rStatus = CyOpen (selectedDeviceNum,selectedInterfaceNum , &handle); - //printf("return status = %d", rStatus); - if (rStatus == CY_SUCCESS){ - //printf("device opened \n"); - } - else - { - printf("fail \n"); - } - - - - // printf("Please enter file to be opened"); - - fp = fopen(argv[1],"rb+"); - // printf("%s", src_file); - rStatus = CyFlashConfigEnable(handle,1); - - if (rStatus == CY_SUCCESS){ - // printf("Flash is configured"); - } - else - { - printf("Manufacturing mode of FLASH is not configured"); - } - // printf("status %d",rStatus); - - if(fp == NULL) - { - printf("\n fopen() Error!!!\n"); - return 1; - } - printf("\n File opened successfully\n"); - if(sizeof(buff) != fread(buff,1,516,fp)) - { - printf("\n fread() failed\n"); - return 1; - } - printf("\n Bytes successfully read \n"); - // printf("reached here"); - - // silicon_id = *(unsigned int *)buff; - - rStatus=CyGetSiliconID(handle,(UINT32 *)&silicon_id); - if (rStatus == CY_SUCCESS){ - // printf(" Correct silicon id"); - - } - else - { - printf("Not correct ID"); - } - - // printf("silicon id %04x,%d",silicon_id,sizeof(silicon_id)); - id[0]= (silicon_id); - id[1]= ((silicon_id >> 8) & 0xFF); - id[2]= ((silicon_id >> 16) & 0xFF); - id[3]= ((silicon_id >> 24) & 0xFF); - - - - rStatus=CyReadDeviceConfig(handle, (UCHAR *)&read_buffer); - if (rStatus == CY_SUCCESS){ - // printf(" Got the data"); - - } - else - { - printf("Not done"); - } - - /*printf (" 0 %02x, %02x \r \n", id[0],read_buffer[0]); - printf (" 1 %02x, %02x \r \n", id[1],read_buffer[1]); - printf (" 2 %02x, %02x \r \n", id[2],read_buffer[2]); - printf (" 3 %02x, %02x\r \n", id[3],read_buffer[3]);*/ - - size_buffer = sizeof(read_buffer); - //printf("The size is %d, buff %d", size_buffer,sizeof(buff)); - - /*for (i = 4; i < 516; i +=16) - { - printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8], - buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]); - } - for (i = 0; i < 512; i +=16) - { - printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - read_buffer[i], read_buffer[i+1], read_buffer[i+2], read_buffer[i+3], read_buffer[i+4], read_buffer[i+5], read_buffer[i+6], - read_buffer[i+7], read_buffer[i+8], - read_buffer[i+9], read_buffer[i+10], read_buffer[i+11], read_buffer[i+12], read_buffer[i+13], read_buffer[i+14], read_buffer[i+15]); - }*/ - memcpy (&buff[4], read_buffer, 28); - - size_checksum= GetCheckSum((unsigned int *)(&buff[16]), 125); - // printf("The checksum size is %d",size_checksum); - - buff[12]= (size_checksum & 0xFF); - buff[13]= ((size_checksum >> 8) & 0xFF); - buff[14]= ((size_checksum >> 16) & 0xFF); - buff[15]= ((size_checksum >> 24) & 0xFF); - - // printf("checksum 0x%08x\n", size_checksum); - /* for (i = 4; i < 516; i +=16) - { - printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8], - buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]); - }*/ - - // if(((id[0] == ffffffA1) || (id[0] == ffffffA2) || (id[0] == ffffffA3)) && (id[1] == 08)) - if((silicon_id == 0x08A1) || (silicon_id == 0x08A2) || (silicon_id == 0x08A3)) - { - - rStatus= CyWriteDeviceConfig(handle,&buff[4]); - if (rStatus == CY_SUCCESS){ - printf(" Programming Flash is done"); - } - else - { - printf("Not done"); - } - } - else - { - printf("wrong silicon id"); - } - - fclose(fp); - - printf("\n File stream closed \n"); - - - - rStatus= CyClose(handle); - if (rStatus == CY_SUCCESS){ - //printf("Device closed"); - } - else - { - printf("Not closed"); - } - - - break; - case 3: - exitApp = true; - CyLibraryExit (); - break; - } - }while (exitApp == false); - free (glDevice); -} -bool isCypressDevice (int deviceNum) { - CY_HANDLE handle; - unsigned char interfaceNum = 0; - unsigned char sig[6]; -int op; - CY_RETURN_STATUS rStatus; - rStatus = CyOpen (deviceNum, interfaceNum, &handle); - //op= libusb_detach_kernel_driver(handle,0); - if (rStatus == CY_SUCCESS){ - rStatus = CyGetSignature (handle, sig); - if (rStatus == CY_SUCCESS){ - CyClose (handle); - return true; - } - else { - CyClose (handle); - return false; - } - } - else - return false; -} diff --git a/tinio/include/CyUSBBootloader.h b/configutility/linux/testUtility/CyUSBBootloader.h similarity index 100% rename from tinio/include/CyUSBBootloader.h rename to configutility/linux/testUtility/CyUSBBootloader.h diff --git a/configutility/linux/testUtility/CyUSBSerial.sh b/configutility/linux/testUtility/CyUSBSerial.sh new file mode 100644 index 0000000..b2a4265 --- /dev/null +++ b/configutility/linux/testUtility/CyUSBSerial.sh @@ -0,0 +1,7 @@ +#!/bin/bash +pid=`pidof CyUSBSerialTestUtility` + +if [ "$pid" ]; then + kill -s SIGUSR1 $pid +fi + diff --git a/configutility/linux/testUtility/CyUSBSerialCommandUtility b/configutility/linux/testUtility/CyUSBSerialCommandUtility new file mode 100755 index 0000000000000000000000000000000000000000..eebd671f3c1ad83e5baf9c197a1e521d66351477 GIT binary patch literal 26424 zcmeHwdwf*Ywf{adnJ{^f1d>5s%HbJ6$O8}%Me~|CqalfTAgFklWG2Z-l1b+g2#RtI zv7{-M_$qDfmDb+=w6(YNrPiRvatqk@*HWvNwzQ?K*hFYcE48T9-0#|tnKMJC{rx`u zGh;^P&@e)!9VZ#IwD?U<>_)bc`laf!xXQg5)R`sL0(XT<)FEOq_9t9N>Err@s zVK1d~bb>C9y#mcttoUvQAL;r38ge9Ioh&bzT@u?xR+kmF`g z@yfjy<<3bY2HcWFpZ@?phfQPWiu5?H=Qw^k)31uhKP~Zz^j`t@WR}4WWWx z-<%$gXXy9MJ&{mT$QSf`+R@>e;ci%Gczr=%t3MR>1sm3tw+A|X4W6cUA2W>BjzFgo z3VVWK!(hgZ-A0|HD{uFNLcWk-AD6kjr>4u-$&40%r=OMg+~5mW_`3bgK6htJ0C1JR zDd-9IxI6t}Kqxfii(#GHfHlBKdEl(~w|08Mksy)W67+|CLR5L6v&G-4NZS3)flhY? zz)C3BCNiC!ye3>q6>1o05v(DQ)%iT$I6-6`8U$CemH_DRR+4joVf>i~AhqGM4N2KUL~Uw;8gkJXbg2m8B_Tp$V_%dcqf(@aFrW)h4|8exSsJkKW=y zj?08swj=qqCOjG@8a9~l<{@LV37;9IW~|MG&obe=O!#aQewzue?olXvrwKpFM8DgF zH;=1(O?aB)RoG|3(>;g^`%QRisYKp(w@JRm+eyHh%@K*|SQJBDjt6M^BC+ z%wJ3}x!&k84$mQ&y2j`*ho=)vE;xFC!;=Xn*Bjl>;dFv+1n=drgv|CV6tf}OG&;?SLC( zfsWiDZPVDv7EZtE5Vd+sLH4X&ygZ1U#QCpE7yKU*|H~g*UHxZWFOOXB(hj?R{9$-1 zg#Bi=5SA%~3I0TRJJ-H~GFc?w)w}jtFhHgLQ{hb4z}g3aADIY?kGOEzblA2Z2<@GV z_3_L?Ilb4jNXF-;jr^>+Q^fC9~;~496Rmo z-EltU-bn+_^R9i_&oqwhZm_-G>pZWGY=z-n1I(5EV&j-gd)1{K%YK$+KRZ01!4La} zBPkHWMm$2y&K+avk#BJ!hbwGvv+QS_f9pM~?HUeGcn<1~ou2I4<9yrIe`Mq&82X)O z2b^bLImGqq-!al3c~h!(#Cd@g|Yq@u0=&${og7=B(;v#;T$o#jyOkn zyyvQ0pwCOxJ4ed64t>L5dOihWUgQ)oOBym>a#=wVAd-IDQ5_9DV0)P&SbGZedjTRw zc78B6#!Wi<1B@R+yP06=cfQ%X<4qR6V!-((ugzCMEwcB31=!KgfB|BfAadkqz+J>L zFUoSOWT7$YB^u|1q@M^0yGW70z0b{gkkY4-9}5k(ewf;M2gkFxd+RNR-+d)^wE zgqj?nvIAfreGElF#zS02V{#eSnPgZZS&$JT8COEa>DwTnjtj_3F5vH1#FWsufU8Ns z+wVcZbckC{&va-II!|?H;PdN+Nm+M5C{v{Rf;Ud(T_K z3sA@GU0(&F_q>+f_dF7&cDM;s$>qO8wz*5j~H5qJljCoXOy?dU+s)N7o_sbn}s)%%ztY0$X|9Ik#0BLmK( zFOoYGveG1mGqw+?!Fp;WCmELZ>G)-F)^VOZ?u$plyb!R z8r}4(D)tViJU^2xxaTUT8u)Vbs($CO0q3#ZeLo;AoX5C=|5v4< z-4A7&RQnO7d7ajN4s%R+x&%H?z(ff=0U+WQHF$)^QCIJGQe6GqT=Srabc{$Y%=HD( z3UhtzUG&I#K<$pAwi1er`l%?&3lt=ekm+5N-m`WOGDk86{wU#Vkyg&P00j3%xfdYk zbnaoBZ3ZSHQS4kObXwaB&;RpujEyuQX7>&8@y_;pU`XKOf0e_7oL_p+6!q^oao9Nq z=U)e#oydM>7_NVoyZ+aC>E|(Lvq%|KJ&PPntGxF2Lr_1aNXpCQd651&l1}b;8h0lk z2kHS;;AtDzGCHr(nsER5-F=zp>_?n$f{7h*o)pmu5uK&zu=5w}ux%Ffr;d<|c;sV{ zspjr-IS-yL!f>G>m*(pNc{eOQ=U zZ!T_$NA5YtTP8s1ph!PK=@z7q*d7KSg(FTr3y*Gq?+!T6aU(ub1WB+KjL^f4^_rZc zdw0CXvilYZH>W%9mLsgX^l*sYViFKRhbVqaE%xFnq^+@-u}NW(NKPW9@}4!> z&-N{&hJ5xYQsf8O&mME_d4Vi35E(&}y8GWN?LW)!O`b+acn*rQk-EQ-XO3vS9cSR3 zXV7BBxGnB=p4EDt=WtIl1)5(C@A~+sFcPVwIQ9i_&hy|L$+cMhRZNS=J^ z)#R#vg`4K)26ZSnBoqygJzgp?u>SXD}EDf=tJeB^M5Bb`C&7}C!r6LL4 zMb;YqHc@lEGt$xI3+nT|n{*)EWXKjzvrn%M5RL)qURF*~eXW}{mew^ONnmv;l~>P8 zkV0V=aK)940%y;LYCPN$48TTFrS#^2*GIP0om8ssX~klu4$7DibJJp(wiC5c<_Dc% zi?2sGpf~ws89py$Gf`@sR@9V|n|ltgurNeH0h1iD98pPPis?=jk|mp!-0BJG9`e1y zpzuVhUx92gPp4N(&|89m4!zU2l{X_Jx6)a#=}M9czw>lPpb}QD$)`HVN+_eUsuqhYR4q`BD_3bjPq+k1$bR+d36 zd>M$cp0Fqj&`7ef}8=Q5OrR7e& zx^Z2Zvkn=Rjn(B1?wab-DtE(19sCJ0|8&Ef9(+jN~@5TVoYJS6B*kB5J~ z-~G5#QPDSM@&Jjy=vR*n6@oPn~^!ezE_)&LwLGJ zKYnIxOm+bxPeRYI2SL!=p(~ZevT`c3rrwyHvDLnlT|fPr#mmJ`0FqmQUl-)!wl^B6 ztlRP1hq~<}Y-v``{g(2Hsg{SJk&t~i&^f4cxjFwHp3QZA4EW{9?=a_E+M@gif!~Sz z&9q9Y8{Gm$`9oGBpgPS&y|>{($cHp5 z%gXtLr7Uae16F62z9*$DYvIRjuB@W_Q(alBdnc^RDhXz-F3l<`&01KNrGpOiWm$G^ zUoW*0ucUtT976lYwygAwnq@9q}Z?y2?pE8;ayxeYpfH6DV!D7kw|K=xHSFcOiM)_Gfx)l$M2y?JrG0v$Rs+ZGZa&k)(Yeh1kwh zIw$RQ6kvOg(o@sQP$%2_l-ASM5$^|-UYO>Boop8pV&(|<=LSU9jD{r99siuMsm-<FX({SbGR1{1?lh#<&{E%=?kBvWds3PLJBZ4%AfJV^rz1Z;>@VOG%dY0NL!{srvS` zH^?xbZvr}prP^tXOSMyja+y>OE|aiS0LMO|u(>R&1fsH^BF(PR2%kMnrny$6zXdtA zwLG0_e+{s(-5i;#JkcgZwpyu`}p8PeW*=s2Ym;We?1m}KL z6|)_Jcx6l2ggdE#_rRF8R3m)$`;;!=Y5P53w5P8+2z=V_QQh>bNg_)dKn>E@P&x$~ zeG=J|i6(;-`Y94zxW=+qz}+*ZYe#^}wnJ{l4Bn{OcSCN*OpQ8S_DZ6eEojn-W|5$w zvNINQn%tCipqyBEH)@?nFW#A!_iLn?C2td`SV~@qB75Ez@Uxt}Zd{q3w*`_}Ngf}2 zb~=thf6ZZoT`Z2La7}T{#np~+!mS8>T~JPylnx zMbhF(MP9b!uegpe%gcx|e?)b=>^WQn&q){Y>;udk7F;#QF3$NbG`2c^OtKvlk+w0* zw~?JWnv3kI52N@MDVdjPrvasZ2m@tK(@0~M{%HcHYo7v;lD>+HoWZGV({>U6OaW-q zXs21`~;ABT}o2AUCrr$0hwT%y$zdKB6Vn^bFuK;zg7<(VUlhSnU} z5NvU1ptCwwBQwQuB``L}y&y?-Oao?uV<$ATJC>j(X^uz1o9=jzig!$)x;aKbKhZ(E zv9cUr!8O~_j%$wNSD>8axB|SB9hIQWb*x1?&+!&&=5SPlW(u4BHj2q?)$&n}eHGF( zwfw1|O7kPFEo{P-rR9*KiwK>Pb}O#hV(!vu7D``9X-8T<(JUeQsVsw{g~;T_u`&xy zdfL(-p^TYlp}1D)LS~v(FV>MkqXQ9hF0bOcT=LHRG%*xabB2=Tf?+1tuJ{3tv`3|o zzt4OfwbPc725HuXGHYfoC>1hCA!|XSka-GuAF(eN>?86WU^9QoBbRo&q8S{*C~#_Sh3>gjusGd5=btt%DaL`WZB|wv&%emca&nJJm&j zwX^*(pndk8F`!NV8I__4tMrH&^v*sUpM94VS!RPMHe}t^t{X8aD$&}{~QwBEr^_VG^<72H~j(#ZtiBb)B$eIxJ#P413VP8$MSH`FADdF!rSBJ z7kEkOn`zcuEt$(XD=}{c^8#Myn<)u{Ea3f!lcOGs(JuAGN^R7QkH`d+f0mlIL1eU{ z3Y03O&jdAoXA^zgh!*r4(vmmnHI#&_E#AhoYxpz4U?872@3q3Po2gKlZp%MJLf6vR zVHs>?MZ_Q-kZF^&`B}Lc)~p#>leEbba&TL1nZm4DYcj6MaO2|%>pYf`aUJq8O~@pC z$CeE&%uW$eO<2Gvvgc~ntc(oe)c~eVj0#!}>U0U(+_?m1Xqr2h$TDYxxe%C%s$k4{ zxnR8(YZlongbXlUKaCJM5`l6BV$y6>XYwkpKyHdg3MmEh7J_*un$E!!C<0HNR=cPh z>2O&JS2)HomDj)q3LB|5&7?BKOqU8m8QcJvcscP*vt|~ob6n0V2EHo_wCksFo7(cH zk(o=TK3X=73YcY!R*yLJSZxWM4Un`&c?8ah<>I?(vrKnxoYZ+SK5R^g5@zI2OCVez zi-*mqfP7hi1Q$v%02x~p%VTVDEQk26j1}R|rAAr;BwHH8#%Wg&!^af*q_9U}EH6RT zB61fBD{few5lTiAwuHohQsr~$<8AfqvioipK{ zf@Y}6LSbwqYAL{oi~Yp-GBkuFY6P@DfFwpdR6r#m+VBN~v@1-IMLLo63Oamu8t5WC zc*NJKA|3X3_>e+pmnr0z_cYd*)r${(+Za5Of0Zie(N8UEtg&9L?TXygTiE(am1RzD zm37;F*7TOgzY;mcEGgRBW&hcY*!mz{>|R2p-kAE)wZ(mr#~&X$)oR~ZbgI}M={~;O zKE>W=&m9`t{|b=1C}-F2hlV)Ao2jSl$1TfqzkMq%&o0B|TUS|op0{QcyzmMqXi04y zy3PL3saqc(x^?J#9Q8C%w+?-ur!5O6r?w5<_LZSq2OqM`$=mX>{ha-}E%qthL;Hs; z3-gBdzhv)iw@(>5b!x=EvE4r1niIAkw|{PMXvmuJJeP13SIg1V@7sr3$CiI!O)s!J z4!(E_B8no9FJ54uZC_jXpVjsUp>*re)}d|0v$4otXum09O}jC2a1aP9zgU(`;sS3Z zfvG-`PCbC44n96)AB;Tl&MTJrxo>T>AGFNNwZCOql52kjR=rgvir%^2-g@rgk6ahD zESi3k)wt0*_uomBwU#83ZLQ1S96V_6wOHZhh7o9KF~Y1l5Wx&>xa+Z5tE-I}p|(IU z+!SeH{t(|o2w&LlGn(6c&09i|4rY{ZG%B3y-Q`ZBzM-zMyg}rL8Ft2rt!^RK66xd{ z3h^m&xQB^7L}Gsxl@sd1&OvO8G@NyH*r{9Ryt&a?-(Xahx~rTOLK=#1fyZ}wT7B4~ zi9MSk)>!T;tpj_FvCJsOr_1OOL3}n27{o@CC*))JxEz}+=@RKA2ga^8S{5UX>zoaZ zb=AA%7(xfX@oGj^9J1j%Y zhws%(ySk(q`Ic3=e-&z02yw6iZN}rDa+68$ZTJ>6t+0G$(2t6?_f&g2@Bw%W_WX4Q z7#{3vasLC2aDNtT2fp3Y8j>8YK)AL&(kf~JZJ5y<2^!6T_DBalT<4oPecq^wXjxF! z7+dM%d7~>FWJaLfOWs9avvYTfZxDZ{*SF2MGb%|KnZz_=!(H*pSXFt;L&q+1C|*d1 zC%6TkLBm@o8NVF+9qWw>cYSFYc~5hX5Efz>%J4tFed-%(YK<~?gHi8npz}ra^5Wuz z)m?pQM>x{yTic3FkwJemKu@r_ZLK)OL|@vva0vMSvE2nkWmm!7NRa^>Rj&X${J}1?5d24FRiMoDKDiBh^oU7 z5B4k?*s&NRQ-10yt*)qYGGTEX5`bn3dAf0Y0QDCzHf)5`(|+9;Yek)Vy%QVgp}#63 zTDlTjTUuAT&WXK|Fzh2Qr-8E` zzAfJ2R#-0Pe*jlA`_BI_z|h~-z*+)`atQ;N|}49!Ma zAkc2g7LHO=>x}whbll|!Sny*lXbXK!^k57aA+Z*5s}E#Lw)71TGidpfs>2~8Er!rKk(K#pMZ@>Xp9k6N6ztNTOsU374U*VEJP zZ*2?53~%bs)MHEQFlf|?UdJb`m=P$OhJD_fF|xLX+aTAytXZ~qgY?C1V&LZ;k-<@$ zV#|-@HFc4Lrbbe(PR`p z6YvgB5by3Z(eW9a9MPab2lFG{1(FuR#cN&gal`2Hc#B1Z9!t=25v>r>RSb8aa@)Bt zC}tECB8Gk{#fWsGhj^D!M<>-$)o!jOP17`|qrm#c@^WWAO~dt(t}fuvM&1yIyz~HF=u1M7qT2Wf})~4TzQd@Qn?nCMTu_sxG}r&dbs2iqC{F zT<|^U2ByMjH>-@hd+9Vy#;`$ndnZk!{6rNpuc$e@VcE$c16* zGBktH=NPftm2wMU9IJL?*7~Ob_iNGf(9FbGG>x7k7LT{GFrESugB5r2>V3O8&x%`k z^`1Q*pBjB1ACI5F)O+iAyq&4{-SPM|rrx8+BWMqSbIM?F8(s6&aa7=gXd(qbR3VL#*UARM`h)DaXkGDGZ;-<`L6UR z7)@B&<bz&15fhRejB2ta6f(;yVxK81Niakm8`zc zaygTkJ_iX?_%71p*?~yLlmBDRn|qNT{+7$R*xyb|dUfs+2XXn3Cob+6lTZPTcEu$4 zTR!lUVV?uCf2rYV6~`;7v6#-On*{r-mnHytpmXPRnKnn)L!gdx&l3H-1N4*4gfe|E z@FZWoUZNFj3cHige3~mquzf3PjWd5ip4`jkNT?jWazX!9O3xb_^<5qMiM!r9G}G! z->+TZa;7u&0#V7CfMv7s?CD5?U&QfQtVH$~pRB^wN$A%BPxe%=BUQP-1YZv7n|SV@ zA?ekdN=08T>!r?ly;7DNmii>V-`XYRs8^O?=Yd|)k5}LS!|A6p^+HzlyKhSQi7!*W z13c-Ucs}6|lgR(2l&{{^s(Ot``HAnv{*Xit2G4Q*Ef4td>a{QleoYd5X%hU+z>`0p zPZ&Qp0k2Ejnxm~mPyW1IsKQbQj&h70_-KSX41CPlNoP44-hk2C9%%Bk8{Tjr7&1JOZFp4c=xX=jYu$pC zSFfZejd6(hA&-V981(eu2{|0ZiHP{B)Mt1j9UVPjF+u!P$2ii9m&^^LlGZK^91}pt zPIARnnm)*mvg28%Vqd66;Gw z1Fc9=30Qw`Hkv~bUJ-r_V@ZiRZ;_5xR119n=(J2aCNiEY`Z&+O)Q!(eIM-4h`X~;P zjHl#}B`xtd^P+`1JyRS_8BZ5mYZFTwaZ8gIoj)1ROAp;)k34}AYoxSZ5KkfAK*ZzB z>%s90s|kmR;&C!y$TcQ$jAl$w@rt58$VcijzEJ3Xu<}MODE_OC$;tw>*-#E}i)JKhC+MqHW~zfdHb* zyQWh>rOT*uPVv+$R0)YkUHW5vyVb4v1C#l1`2t z_vqKC>BZt$)coRD*SJGa<4cV@IW?BGoUwvXPY0Hk5Ql>zZc{0~DA2_U@HM@!ptQ`r zH0)`W5MBWmG)4S4=NgL#1q8L>WLQ?qyWi+)&RgTE%+4hgKi73T1uz47WmrasMqF&5CsWVF@6aSmAYzI`eUn~gKA{C}h9 zIgO?;bss^yswk*feMca$f>xy|o{JwgLPYr+B)^JvMeBK^V`m6O86|a`$cxlRmy8n?Nt44yBI26BHmr?O%%+nNTTMyYu@zWb}3hVJB z62-5+r%>^)Q<%-N&oAEMfgam8;}Ek-)FM z_fau6U&V#Q`adQ4Rr?Lg=NA>%s)mzN67~OD0)LJ!2vzKrd@4#T|0QIQ{Z;vDeNM%6 z-nls>mj4Pe>Csbmv*)@p=U5a0=_Z?dbB!Z$7Pz+Z1-ynljRQzgP z@c2LBSMuIMf_zu;tMx|p(vq9MA56_SMi?`_@nDU zl2P?vB|!11_2nraFd{kw|-0 z68@1A!EpYc@Rv&d#Co1A7yJVW1Bfc$948dP8N1dAemWnO!W{fo;HTQ3#&QZIKHByi fBQE*|5xIthvK_(yLS6jccf2_XA#9i_ei literal 0 HcmV?d00001 diff --git a/configutility/linux/testUtility/Makefile b/configutility/linux/testUtility/Makefile new file mode 100644 index 0000000..7369bcd --- /dev/null +++ b/configutility/linux/testUtility/Makefile @@ -0,0 +1,12 @@ +all: + # gcc -g -o CyUSBSerialTestUtility Test_Utility.c -lcyusbserial -w + gcc -g -o CyUSBSerialCommandUtility Command_Utility.c -lcyusbserial + cp 90-cyusb.rules /etc/udev/rules.d + cp CyUSBSerialCommandUtility /usr/bin + cp CyUSBSerial.sh /usr/bin + chmod 777 /usr/bin/CyUSBSerial.sh +clean: + rm -f CyUSBSerialCommandUtility +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)' diff --git a/cylib/tools/README.txt b/configutility/linux/testUtility/README.txt similarity index 65% rename from cylib/tools/README.txt rename to configutility/linux/testUtility/README.txt index 1f15f81..c255cd4 100644 --- a/cylib/tools/README.txt +++ b/configutility/linux/testUtility/README.txt @@ -9,6 +9,37 @@ 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: ================================================================================ @@ -18,7 +49,7 @@ Using the test utility: $ CyUSBSerial ---------------------------------------------------------------------- - Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY + Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY ---------------------------------------------------------------------- 0 |4b4 |a | 0 | VENDOR_I2C 0 |4b4 |a | 1 | VENDOR_SPI @@ -27,7 +58,7 @@ Using the test utility: 2. A menu providing the various operations is also printed: ---------------------------------------------------------------------- - 1: Print list of devices + 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 @@ -46,7 +77,7 @@ Using the test utility: Once the selections are made, the menu will be updated with the details. ---------------------------------------------------------------------- - 1: Print list of devices + 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 @@ -70,7 +101,7 @@ Using the test utility: Once the values are selected, the menu is updated with the details as below: ------------------------------------------------------------------- - 1: Print list of devices + 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 @@ -82,18 +113,25 @@ Using the test utility: 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 + 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 + 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 + 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 diff --git a/configutility/linux/testUtility/jbiexprt.h b/configutility/linux/testUtility/jbiexprt.h new file mode 100644 index 0000000..9b38b4c --- /dev/null +++ b/configutility/linux/testUtility/jbiexprt.h @@ -0,0 +1,224 @@ +/********************************************************************************/ +/* */ +/* Module: jbiexprt.h */ +/* */ +/* Copyright (C) Altera Corporation 1998-2001 */ +/* */ +/* Description: Jam STAPL ByteCode Player Export Header File */ +/* */ +/* Revisions: */ +/* */ +/********************************************************************************/ + +#ifndef INC_JBIEXPRT_H +#define INC_JBIEXPRT_H + +/********************************************************************************/ +/* */ +/* Return codes from most JBI functions */ +/* */ +/********************************************************************************/ + +#define JBI_RETURN_TYPE int + +#define JBIC_SUCCESS 0 +#define JBIC_OUT_OF_MEMORY 1 +#define JBIC_IO_ERROR 2 +/* #define JAMC_SYNTAX_ERROR 3 */ +#define JBIC_UNEXPECTED_END 4 +#define JBIC_UNDEFINED_SYMBOL 5 +/* #define JAMC_REDEFINED_SYMBOL 6 */ +#define JBIC_INTEGER_OVERFLOW 7 +#define JBIC_DIVIDE_BY_ZERO 8 +#define JBIC_CRC_ERROR 9 +#define JBIC_INTERNAL_ERROR 10 +#define JBIC_BOUNDS_ERROR 11 +/* #define JAMC_TYPE_MISMATCH 12 */ +/* #define JAMC_ASSIGN_TO_CONST 13 */ +/* #define JAMC_NEXT_UNEXPECTED 14 */ +/* #define JAMC_POP_UNEXPECTED 15 */ +/* #define JAMC_RETURN_UNEXPECTED 16 */ +/* #define JAMC_ILLEGAL_SYMBOL 17 */ +#define JBIC_VECTOR_MAP_FAILED 18 +#define JBIC_USER_ABORT 19 +#define JBIC_STACK_OVERFLOW 20 +#define JBIC_ILLEGAL_OPCODE 21 +/* #define JAMC_PHASE_ERROR 22 */ +/* #define JAMC_SCOPE_ERROR 23 */ +#define JBIC_ACTION_NOT_FOUND 24 + +/********************************************************************************/ +/* */ +/* Macro Definitions */ +/* */ +/********************************************************************************/ + +/* +* For DOS port, program data is stored in a set of 16K pages, accessed +* through a pointer table. For 32-bit version, the buffer is continuous. +* The macro GET_BYTE gets a single byte for either case. +*/ +#if PORT==DOS +#define PROGRAM_PTR unsigned char ** +#else +#define PROGRAM_PTR unsigned char * +#endif + +#if PORT==DOS +#define GET_BYTE(x) (jbi_program[(x) >> 14L][(x) & 0x3fffL]) +#else +#define GET_BYTE(x) (program[x]) +#endif + +#define GET_WORD(x) \ + (((((unsigned short) GET_BYTE(x)) << 8) & 0xFF00) | \ + (((unsigned short) GET_BYTE((x)+1)) & 0x00FF)) + +#define GET_DWORD(x) \ + (((((unsigned long) GET_BYTE(x)) << 24L) & 0xFF000000L) | \ + ((((unsigned long) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \ + ((((unsigned long) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \ + (((unsigned long) GET_BYTE((x)+3)) & 0x000000FFL)) + +/********************************************************************************/ +/* */ +/* Structured Types */ +/* */ +/********************************************************************************/ + +typedef struct JBI_PROCINFO_STRUCT +{ + char *name; + unsigned char attributes; + struct JBI_PROCINFO_STRUCT *next; +} +JBI_PROCINFO; + +/********************************************************************************/ +/* */ +/* Global Data Prototypes */ +/* */ +/********************************************************************************/ + +#if PORT==DOS +extern unsigned char jbi_aca_out_buffer[8192 + 1024]; +#endif + +extern PROGRAM_PTR jbi_program; + +extern char *jbi_workspace; + +extern long jbi_workspace_size; + +/********************************************************************************/ +/* */ +/* Function Prototypes */ +/* */ +/********************************************************************************/ + +JBI_RETURN_TYPE jbi_execute +( + PROGRAM_PTR program, + long program_size, + char *workspace, + long workspace_size, + char *action, + char **init_list, + int reset_jtag, + long *error_address, + int *exit_code, + int *format_version +); + +JBI_RETURN_TYPE jbi_get_note +( + PROGRAM_PTR program, + long program_size, + long *offset, + char *key, + char *value, + int length +); + +JBI_RETURN_TYPE jbi_check_crc +( + PROGRAM_PTR program, + long program_size, + unsigned short *expected_crc, + unsigned short *actual_crc +); + +JBI_RETURN_TYPE jbi_get_file_info +( + PROGRAM_PTR program, + long program_size, + int *format_version, + int *action_count, + int *procedure_count +); + +JBI_RETURN_TYPE jbi_get_action_info +( + PROGRAM_PTR program, + long program_size, + int index, + char **name, + char **description, + JBI_PROCINFO **procedure_list +); + +int jbi_jtag_io +( + int tms, + int tdi, + int read_tdo +); + +void jbi_message +( + char *message_text +); + +void jbi_export_integer +( + char *key, + long value +); + +void jbi_export_boolean_array +( + char *key, + unsigned char *data, + long count +); + +void jbi_delay +( + long microseconds +); + +int jbi_vector_map +( + int signal_count, + char **signals +); + +int jbi_vector_io +( + int signal_count, + long *dir_vect, + long *data_vect, + long *capture_vect +); + +void *jbi_malloc +( + unsigned int size +); + +void jbi_free +( + void *ptr +); + +#endif /* INC_JBIEXPRT_H */ diff --git a/configutility/linux/testUtility/jbiport.h b/configutility/linux/testUtility/jbiport.h new file mode 100644 index 0000000..f57533e --- /dev/null +++ b/configutility/linux/testUtility/jbiport.h @@ -0,0 +1,43 @@ +/****************************************************************************/ +/* */ +/* Module: jbiport.h */ +/* */ +/* Copyright (C) Altera Corporation 2000-2001 */ +/* */ +/* Description: Defines porting macros */ +/* */ +/****************************************************************************/ + +#ifndef INC_JBIPORT_H +#define INC_JBIPORT_H + +/* +* PORT defines the target platform: DOS, WINDOWS, UNIX, or EMBEDDED +* +* PORT = DOS means a 16-bit DOS console-mode application +* +* PORT = WINDOWS means a 32-bit WIN32 console-mode application for +* Windows 95, 98, 2000, ME or NT. On NT this will use the +* DeviceIoControl() API to access the Parallel Port. +* +* PORT = UNIX means any UNIX system. BitBlaster access is support via +* the standard ANSI system calls open(), read(), write(). +* The ByteBlaster is not supported. +* +* PORT = EMBEDDED means all DOS, WINDOWS, and UNIX code is excluded. +* Remaining code supports 16 and 32-bit compilers. +* Additional porting steps may be necessary. See readme +* file for more details. +*/ + +#define DOS 2 +#define WINDOWS 3 +#define UNIX 4 +#define EMBEDDED 5 + +#ifndef PORT +/* change this line to build a different port */ +#define PORT EMBEDDED +#endif + +#endif /* INC_JBIPORT_H */ diff --git a/cy-config.o b/cy-config.o deleted file mode 100644 index fe6253aa5a271f14b1e7929bfbc79b17d37d8491..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11312 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