commit a7f62e5d7ef4fed690acb2e1e379a1571fd5e542 Author: Ryan Malloy Date: Fri Jan 30 10:31:39 2026 -0700 Add Silicon Labs CP210x manufacturing library source - Library source from AN721SW (cp210xmanufacturing_1.0.tar.gz) - Manufacturing tool source (cp210xsmt) - Builds 64-bit shared library with: make LIB_ARCH=64 - Datasheets and app notes in docs/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a137c73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Large binary archives - download from Silicon Labs as needed +# See CLAUDE.md for links +docs/app-notes/*.zip +docs/software/*.tar + +# Build artifacts +build/ +*.o +*.a + +# 32-bit Eclipse GUI (doesn't run on 64-bit, too heavy for git) +AN721SW/Linux/customizer/ +AN721SW/Mac/ +AN721SW/Windows/ + +# Compressed source tarballs (we extract these) +AN721SW/Linux/LibrarySourcePackages/*.tar.gz +AN721SW/Linux/ManufacturingTool/*.tar.gz + +# Editor/IDE +*.swp +*.swo +*~ +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Python +__pycache__/ +*.pyc +.venv/ +*.egg-info/ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/Makefile b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/Makefile new file mode 100644 index 0000000..4681153 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/Makefile @@ -0,0 +1,126 @@ +########################################### +# Makefile for libcp210xmanufacturing +# using libusb-1.0 +# +# Silicon Labs +# Modified July 11th, 2016 +########################################### + +# This file gets put into the source package and is used to build the actual library. + +# it will produce .so and .a + +LIB_ARCH?=$(shell uname -m | sed s/x86_//) + +BUILD?=./build +BUILDPATH?=$(BUILD)/lib/x86_$(LIB_ARCH) +OBJPATH?=$(BUILD)/obj/x86_$(LIB_ARCH) + +INSTALLPATH?=/usr/local + +# required packages +PKG_CONFIG_DEPENDENCIES = libusb-1.0 + +# Library Variables + +LIB_BASE_NAME = cp210xmanufacturing +LIB_NAME = lib$(LIB_BASE_NAME) +LIB_VER = 1.0 +LIB_SOVER = 1 + +SONAME=$(LIB_NAME).so.$(LIB_SOVER) +LIBFULLNAME=$(LIB_NAME).so.$(LIB_VER) + +LIBFULLPATH=$(BUILDPATH)/$(LIBFULLNAME) +ARCHIVE_FULL_PATH=$(BUILDPATH)/$(LIB_NAME).a + +ARCHFLAG=-m$(LIB_ARCH) + +PUBLICHEADERSPATH=./$(LIB_BASE_NAME)/include + +# sources + +CSRCS = +CPPSRCS =CP210xDevice.cpp +CPPSRCS+=CP2101Device.cpp +CPPSRCS+=CP2102Device.cpp +CPPSRCS+=CP2102NDevice.cpp +CPPSRCS+=CP2103Device.cpp +CPPSRCS+=CP2104Device.cpp +CPPSRCS+=CP2105Device.cpp +CPPSRCS+=CP2108Device.cpp +CPPSRCS+=CP2109Device.cpp +CPPSRCS+=CP210xSupportFunctions.cpp +CPPSRCS+=CP210xManufacturing.cpp + +COBJS=$(CSRCS:%.c=%.o) +CPPOBJS=$(CPPSRCS:%.cpp=%.o) + +OBJFILES = $(COBJS) $(CPPOBJS) + +OBJFULLPATHS=$(addprefix $(OBJPATH)/, $(OBJFILES)) + + +INCLUDES ?= -I$(PUBLICHEADERSPATH) -I./common/include/ -I./common/linux/ + +INCLUDES += $(foreach depcflgs,$(PKG_CONFIG_DEPENDENCIES), `pkg-config $(depcflgs) --cflags`) + +LIBS += $(foreach deplib,$(PKG_CONFIG_DEPENDENCIES), `pkg-config --libs $(deplib)`) + +VPATH+=$(LIB_BASE_NAME)/src + +# targets: build clean install + +CC ?= gcc +CFLAGS ?= -Wall -fPIC -g $(ARCHFLAG) $(INCLUDES) + +CXX ?= g++ +CXXFLAGS ?= -Wall -fPIC -g $(ARCHFLAG) $(INCLUDES) + +AR ?= ar +ARFLAGS ?= rcs + +all: $(LIBFULLPATH) $(ARCHIVE_FULL_PATH) + +$(OBJPATH)/%.o: %.c + $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@ + +$(OBJPATH)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $(INCLUDES) $< -o $@ + +$(OBJPATH): + mkdir -p $@ + +$(BUILDPATH): + mkdir -p $@ + +$(LIBFULLPATH): $(OBJPATH) $(BUILDPATH) $(OBJFULLPATHS) + $(CXX) $(ARCHFLAG) -shared -Wl,-soname,$(SONAME) -o $@ $(OBJFULLPATHS) $(LIBS) + cd $(BUILDPATH) && \ + ln -sf $(LIBFULLNAME) $(SONAME) && \ + ln -sf $(SONAME) $(LIB_NAME).so + + +$(ARCHIVE_FULL_PATH): $(OBJFULLPATHS) + $(AR) $(ARFLAGS) $(BUILDPATH)/$(LIB_NAME).a $(OBJFULLPATHS) + +debug: + echo $(OBJFULLPATHS) + +clean: + rm -rf $(BUILDPATH) + rm -rf $(OBJPATH) + rm -rf $(BUILD) + +install: + mkdir -p $(INSTALLPATH)/include + mkdir -p $(INSTALLPATH)/lib + cp $(PUBLICHEADERSPATH)/*.h $(INSTALLPATH)/include + cp $(LIBFULLPATH) $(INSTALLPATH)/lib + cd $(INSTALLPATH)/lib && \ + ln -sf $(LIBFULLNAME) $(SONAME) && \ + ln -sf $(SONAME) $(LIB_NAME).so + @echo "Installed at: "$(INSTALLPATH) + +.PHONY: all clean install debug + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CSerialPort.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CSerialPort.h new file mode 100644 index 0000000..95e4ba3 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CSerialPort.h @@ -0,0 +1,105 @@ +// Copyright (c) 2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#ifndef __SERIAL_PORT_H__ +#define __SERIAL_PORT_H__ + +#include +#include +#include +#include +#ifndef TRACE +#error Define TRACE before including this. E.g., #define TRACE printf +#endif + +class CWinApiErr // thrown any time a Windows API fails +{ +public: + CWinApiErr( char *ApiName ) + { + TRACE( "%s: LastError %d\n", ApiName, ::GetLastError()); + } +}; + +//--------------------------------------------------------------------- +// Serial port primitives needed for the tests +// Throws CWinApiErr when unexpected happens. +//--------------------------------------------------------------------- +class CSerialPort +{ + HANDLE m_hSer; +public: + CSerialPort( const std::string ComName) + { + m_hSer = ::CreateFile( std::string( "\\\\.\\" + ComName).c_str(), + GENERIC_READ | GENERIC_WRITE, 0 /*share*/, + NULL /*security*/, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (m_hSer == INVALID_HANDLE_VALUE) { + throw CWinApiErr( "CreateFile"); + } + } + ~CSerialPort() + { + if( m_hSer != INVALID_HANDLE_VALUE) { + ::CloseHandle( m_hSer); + } + } + void Mode( const std::string Mode ) + { + DCB Dcb = { 0 }; + Dcb.DCBlength = sizeof( Dcb); + if (!::BuildCommDCB( Mode.c_str(), &Dcb)) { + throw CWinApiErr( "BuildCommDCB"); + } + if( !::SetCommState( m_hSer, &Dcb)) { + throw CWinApiErr( "SetCommState"); + } + } + DWORD Write( std::vector Data) + { + DWORD CbWritten = 0; + if( !::WriteFile( m_hSer, Data.data(), Data.size(), &CbWritten, NULL)) { + throw CWinApiErr( "WriteFile"); + } + TRACE( "Wrote %x bytes\n", CbWritten); + if( CbWritten != Data.size()) { + TRACE( "ERROR: was asked to write %x bytes\n", Data.size()); + } + return CbWritten; + } + void SetCommMask( DWORD Mask) + { + if( !::SetCommMask( m_hSer, Mask )) { + throw CWinApiErr( "SetCommMask"); + } + } + DWORD WaitCommEvent() + { + DWORD Events; + if( !::WaitCommEvent( m_hSer, &Events, NULL)) { + throw CWinApiErr( "WaitCommEvent"); + } + TRACE( "Received Events %x\n", Events); + return Events; + } + void GetSerialStatus( SERIAL_STATUS &s) + { + DWORD CbReturned = 0; + if( !::DeviceIoControl( m_hSer, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, + &s, sizeof( s), &CbReturned, NULL)) { + throw CWinApiErr( "DeviceIoControl"); + } else if( CbReturned != sizeof( s)) { + ::SetLastError( ERROR_SUCCESS); + throw CWinApiErr( "unexpected IOCTL_SERIAL_GET_COMMSTATUS size"); + } else { + TRACE( "AmountInOutQueue %x\n", s.AmountInOutQueue); + } + } +}; + +#endif // __SERIAL_PORT_H__ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CriticalSectionLock.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CriticalSectionLock.h new file mode 100644 index 0000000..1919f37 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/CriticalSectionLock.h @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////// +// CCriticalSectionLock.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CRITICAL_SECTION_LOCK_H +#define CRITICAL_SECTION_LOCK_H + +#if defined(_WIN32) +#include "Types.h" +#elif defined(__APPLE__) +#include +#include +#include "Types.h" +#elif defined(__linux__) +#include "Types.h" +#include +#include +#include +#else + #error "error: Unsupported OS type" +#endif + +#include "silabs_sal.h" + +class CCriticalSectionLock +{ + // Constructor/Destructor +public: + inline CCriticalSectionLock() throw() + { +#if defined(_WIN32) + InitializeCriticalSection(&m_cs); +#else + pthread_mutexattr_t attr; + + // Create a mutex object with recursive behavior + // + // This means that you can call pthread_mutex_lock() + // more than once from the same thread before calling + // pthread_mutex_unlock(). + // + // Doing the same using the default mutex attributes + // would cause deadlock. + // + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_cs, &attr); + pthread_mutexattr_destroy(&attr); +#endif + } + inline ~CCriticalSectionLock() throw() + { +#if defined(_WIN32) + DeleteCriticalSection(&m_cs); +#else + pthread_mutex_destroy(&m_cs); +#endif + } + + // Public Methods +public: +#pragma warning(suppress: 26135) // The _Acquires_lock_() annotation seems like it is correct, but clearly isn't as Warning 26135 is still generated. TODO: resolve. + _Acquires_lock_(m_cs) + inline void Lock() throw() + { +#if defined(_WIN32) + EnterCriticalSection(&m_cs); +#else + pthread_mutex_lock(&m_cs); +#endif + } +#pragma warning(suppress: 26135) // The _Acquires_lock_() annotation seems like it is correct, but clearly isn't as Warning 26135 is still generated. TODO: resolve. + _Releases_lock_(m_cs) + inline void Unlock() throw() + { +#if defined(_WIN32) + LeaveCriticalSection(&m_cs); +#else + pthread_mutex_unlock(&m_cs); +#endif + } + + // Protected Members +protected: +#if defined(_WIN32) + CRITICAL_SECTION m_cs; +#else + pthread_mutex_t m_cs; +#endif +}; + +#endif // CRITICAL_SECTION_LOCK_H diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/DeviceList.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/DeviceList.h new file mode 100644 index 0000000..cc903e7 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/DeviceList.h @@ -0,0 +1,155 @@ +#pragma once + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "OsDep.h" +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// CDeviceList Class +///////////////////////////////////////////////////////////////////////////// + +template +class CDeviceList +{ + // Constructor/Destructor +public: + CDeviceList(); + ~CDeviceList(); + + // Public Methods +public: + BOOL Validate(T* object); + T* Construct(); + void Add(T* object); + void Destruct(T* object); + + // Protected Members +protected: + std::vector m_list; + CCriticalSectionLock m_lock; +}; + +///////////////////////////////////////////////////////////////////////////// +// CDeviceList Class - Constructor/Destructor +///////////////////////////////////////////////////////////////////////////// + +template +CDeviceList::CDeviceList() +{ + +} + +template +CDeviceList::~CDeviceList() +{ + // Enter critical section + m_lock.Lock(); + + // Deallocate all device objects + // (Destructor closes the devices) + for (DWORD i = 0; i < m_list.size(); i++) + { + delete m_list[i]; + } + + // Remove all device references + m_list.clear(); + + // Leave critical section + m_lock.Unlock(); +} + +///////////////////////////////////////////////////////////////////////////// +// CDeviceList Class - Public Methods +///////////////////////////////////////////////////////////////////////////// + +// Make sure that a T pointer is valid + +template +BOOL CDeviceList::Validate(T* object) +{ + BOOL retVal = FALSE; + + // Enter critical section + m_lock.Lock(); + + if (std::find(m_list.begin(), m_list.end(), object) != m_list.end()) + { + retVal = TRUE; + } + + // Unlock critical section + m_lock.Unlock(); + + return retVal; +} + +// Create a new T object on the heap +// and call the T constructor +// and track memory usage in m_list + +template +T* CDeviceList::Construct() +{ + // Create the object memory on the heap + // Call the T constructor + T* object = new T(); + + // Enter critical section + m_lock.Lock(); + + m_list.push_back(object); + + // Leave critical section + m_lock.Unlock(); + + return object; +} + +// Add a T object in m_list + +template +void CDeviceList::Add(T* object) +{ + // Enter critical section + m_lock.Lock(); + + m_list.push_back(object); + + // Leave critical section + m_lock.Unlock(); +} + +// Remove the object pointer from the m_list +// vector and call the T destructor by +// deallocating the object + +template +void CDeviceList::Destruct(T* object) +{ + // Enter critical section + m_lock.Lock(); + + if (Validate(object)) + { + // Find the object pointer in the vector and return an iterator + typename std::vector::iterator iter = std::find(m_list.begin(), m_list.end(), object); + + // Remove the pointer from the vector if it exists + if (iter != m_list.end()) + { + m_list.erase(iter); + } + + // Call the T destructor + // Free the object memory on the heap + delete object; + } + + // Leave critical section + m_lock.Unlock(); +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/OsDep.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/OsDep.h new file mode 100644 index 0000000..4f92f38 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/OsDep.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////// +// CCriticalSectionLock +///////////////////////////////////////////////////////////////////////////// + +#ifndef __OS_DEP_H__ +#define __OS_DEP_H__ + +#if defined(_WIN32) +#include "Types.h" +#else +#if defined(__APPLE__) +#include +#include +#include "Types.h" +#elif defined(__linux__) +#include "Types.h" +#include +#include +#include +#else + #error "error: Unsupported OS type" +#endif + +DWORD GetTickCount(); +void Sleep(DWORD msec); + +#endif // defined(_WIN32) + +#include "CriticalSectionLock.h" + +#endif // __OS_DEP_H__ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/ReportQueue.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/ReportQueue.h new file mode 100644 index 0000000..a440819 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/ReportQueue.h @@ -0,0 +1,21 @@ +#ifndef REPORT_QUEUE_H +#define REPORT_QUEUE_H + +#include "OsDep.h" +#include + +class CReportQueue +{ +public: + void Clear(); + void Reserve(DWORD count); + void Enqueue(const BYTE* data, DWORD size); + void Dequeue(BYTE* data, DWORD size, DWORD* bytesDequeued); + DWORD Size(); + +protected: + std::vector m_queue; + CCriticalSectionLock m_Lock; +}; + +#endif // REPORT_QUEUE_H diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/Types.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/Types.h new file mode 100644 index 0000000..d3e9c43 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/Types.h @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////// +// Types.h +//////////////////////////////////////////////////////////////////////////////// + +#ifndef HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C +#define HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C + +#if defined(_WIN32) + +#include + +#else + +//////////////////////////////////////////////////////////////////////////////// +// Typedefs +//////////////////////////////////////////////////////////////////////////////// + +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned int UINT; +#if defined(__APPLE__) +typedef unsigned long DWORD; +typedef unsigned long long ULONGLONG; +#else +typedef unsigned int DWORD; +typedef unsigned int ULONG; +#define ULONGLONG int64_t +#endif + +typedef char *LPSTR; +typedef const char *LPCSTR; +typedef BOOL *LPBOOL; +typedef BYTE *LPBYTE; +typedef WORD *LPWORD; +typedef UINT *LPUINT; +typedef DWORD *LPDWORD; +typedef void *LPVOID; + +typedef void *HANDLE; +typedef HANDLE *LPHANDLE; + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#define INFINITE 0xFFFFFFFF + +#if !defined(FALSE) +#define FALSE (0) +#endif +#if !defined(TRUE) +#define TRUE (1) // TODO: or !FALSE? +#endif + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +// TODO: Delete these. Use host_common/silabs_utils.h::SILABS_MAKEWORD(), SILABS_LOBYTE() & SILABS_HIBYTE() +#define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((BYTE)(w)) +#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) + +#endif // defined(_WIN32) + +#endif // HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_defs.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_defs.h new file mode 100644 index 0000000..891345d --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_defs.h @@ -0,0 +1,163 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_defs.h + +Abstract: + + A top-level, across-all-repos, collection of some "useful" defines/enums + +Environment: + + User or kernel mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_DEFS_H_INCLUDED_BVHHTNCO7E +#define HOST_COMMON_INCLUDE_SILABS_DEFS_H_INCLUDED_BVHHTNCO7E + +#include "silabs_sal.h" + +#if ! defined(__cplusplus) +#define bool BOOLEAN +#endif // ! defined(__cplusplus) + +#if defined(DEFINE_GUID) +DEFINE_GUID(GUID_DEVINTERFACE_SILABS_CP210x, + 0xa2a39220, 0x39f4, 0x4b88, 0xae, 0xcb, 0x3d, 0x86, 0xa3, 0x5d, 0xc7, 0x48); + +// USBXpress +// {3C5E1462-5695-4e18-876B-F3F3D08AAF18} +DEFINE_GUID(GUID_DEVINTERFACE_SILABS_USBXPRESS_BRIDGE, +0x3c5e1462, 0x5695, 0x4e18, 0x87, 0x6b, 0xf3, 0xf3, 0xd0, 0x8a, 0xaf, 0x18); +#endif // DEFINE_GUID + +#define SILABS_TEST_FILL 0xa5 // 10100101 + + +// Company Vendor ID (VID) +typedef enum _SILABS_VID { + SILABS_VID_10C4 = ((unsigned short)(0xFFFF & 0x10C4)) // Decimal 4292; VID aquired via Cygnal. + , SILABS_VID_1BA4 = ((unsigned short)(0xFFFF & 0x1BA4)) // Decimal 7076; VID aquired via Ember. + , SILABS_VID_2544 = ((unsigned short)(0xFFFF & 0x2544)) // Decimal 9540; VID aquired via Energy Micro. +} SILABS_VID, *PSILABS_VID; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_VID ( _In_ const SILABS_VID _v ) { return (SILABS_VID_10C4 == _v); } + +// Device Product IDs (PIDs) +typedef enum _SILABS_PID { + SILABS_PID_UNKNOWN = ((unsigned short)(0xFFFF & 0x0000)) + , SILABS_PID_CP210SINGLEPORT = ((unsigned short)(0xFFFF & 0xEA60)) + , SILABS_PID_CP210SINGLEPORTII = ((unsigned short)(0xFFFF & 0xEA63)) + , SILABS_PID_CP2101 = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP2102 = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP2102N = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP2103 = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP2104 = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP210DUALPORT = ((unsigned short)(0xFFFF & 0xEA70)) + , SILABS_PID_CP210DUALPORTII = ((unsigned short)(0xFFFF & 0xEA7A)) + , SILABS_PID_CP2105 = SILABS_PID_CP210DUALPORT + , SILABS_PID_CP2105II = SILABS_PID_CP210DUALPORTII + , SILABS_PID_CP210QUADPORT = ((unsigned short)(0xFFFF & 0xEA71)) + , SILABS_PID_CP210QUADPORTII = ((unsigned short)(0xFFFF & 0xEA7B)) + , SILABS_PID_CP2108 = SILABS_PID_CP210QUADPORT + , SILABS_PID_CP2108II = SILABS_PID_CP210QUADPORTII + , SILABS_PID_CP2109 = SILABS_PID_CP210SINGLEPORT + , SILABS_PID_CP2110 = ((unsigned short)(0xFFFF & 0xEA80)) + , SILABS_PID_CP2111 = SILABS_PID_CP2110 + , SILABS_PID_CP2112 = ((unsigned short)(0xFFFF & 0xEA90)) + , SILABS_PID_CP2114 = ((unsigned short)(0xFFFF & 0xEAB0)) + , SILABS_PID_CP2130 = ((unsigned short)(0xFFFF & 0x87A0)) + , SILABS_PID_USBXPress = ((unsigned short)(0xFFFF & 0xEA61)) +} SILABS_PID, *PSILABS_PID; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_PID(_In_ const SILABS_PID _p) { +#pragma warning ( push ) +#pragma warning ( disable : 6287 ) // warning C6287: redundant code: the left and right sub-expressions are identical + return ((SILABS_PID_CP210SINGLEPORT == _p) || (SILABS_PID_CP210SINGLEPORTII == _p) + || (SILABS_PID_CP210DUALPORT == _p) || (SILABS_PID_CP210DUALPORTII == _p) + || (SILABS_PID_CP210QUADPORT == _p) || (SILABS_PID_CP210QUADPORTII == _p) + || (SILABS_PID_CP2101 == _p) || (SILABS_PID_CP2102 == _p) || (SILABS_PID_CP2102N == _p) || (SILABS_PID_CP2103 == _p) + || (SILABS_PID_CP2104 == _p) + || (SILABS_PID_CP2105 == _p) || (SILABS_PID_CP2105II == _p) + || (SILABS_PID_CP2108 == _p) || (SILABS_PID_CP2108II == _p) + || (SILABS_PID_CP2109 == _p) + || (SILABS_PID_CP2110 == _p) || (SILABS_PID_CP2111 == _p) || (SILABS_PID_CP2112 == _p) || (SILABS_PID_CP2114 == _p) + || (SILABS_PID_CP2130 == _p) || (SILABS_PID_USBXPress == _p)); +#pragma warning ( pop ) +} +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidCP210X_PID(_In_ const SILABS_PID _p) { +#pragma warning ( push ) +#pragma warning ( disable : 6287 ) // warning C6287: redundant code: the left and right sub-expressions are identical + return ((SILABS_PID_CP210SINGLEPORT == _p) || (SILABS_PID_CP210SINGLEPORTII == _p) + || (SILABS_PID_CP210DUALPORT == _p) || (SILABS_PID_CP210DUALPORTII == _p) + || (SILABS_PID_CP210QUADPORT == _p) || (SILABS_PID_CP210QUADPORTII == _p) + || (SILABS_PID_CP2101 == _p) || (SILABS_PID_CP2102 == _p) || (SILABS_PID_CP2102N == _p) || (SILABS_PID_CP2103 == _p) + || (SILABS_PID_CP2104 == _p) + || (SILABS_PID_CP2105 == _p) || (SILABS_PID_CP2105II == _p) + || (SILABS_PID_CP2108 == _p) || (SILABS_PID_CP2108II == _p) + || (SILABS_PID_CP2109 == _p)); +#pragma warning ( pop ) +} + +// Device Part Numbers +typedef enum _CP210X_PARTNUM { + CP210x_PARTNUM_UNKNOWN = ((BYTE)(0xFF & 0x00)) + , CP210x_PARTNUM_CP2101 = ((BYTE)(0xFF & 0x01)) + , CP210x_PARTNUM_CP2102 = ((BYTE)(0xFF & 0x02)) + , CP210x_PARTNUM_CP2103 = ((BYTE)(0xFF & 0x03)) + , CP210x_PARTNUM_CP2104 = ((BYTE)(0xFF & 0x04)) + , CP210x_PARTNUM_CP2105 = ((BYTE)(0xFF & 0x05)) + , CP210x_PARTNUM_CP2108 = ((BYTE)(0xFF & 0x08)) + , CP210x_PARTNUM_CP2109 = ((BYTE)(0xFF & 0x09)) + , CP210x_PARTNUM_CP2102N_QFN28 = ((BYTE)(0xFF & 0x20)) + , CP210x_PARTNUM_CP2102N_QFN24 = ((BYTE)(0xFF & 0x21)) + , CP210x_PARTNUM_CP2102N_QFN20 = ((BYTE)(0xFF & 0x22)) + , CP210x_PARTNUM_USBXPRESS_F3XX = ((BYTE)(0xFF & 0x80)) + , CP210x_PARTNUM_USBXPRESS_EFM8 = ((BYTE)(0xFF & 0x80)) + , CP210x_PARTNUM_USBXPRESS_EFM32 = ((BYTE)(0xFF & 0x81)) +} CP210X_PARTNUM, *PCP210X_PARTNUM; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidCP210X_PARTNUM(_In_ const CP210X_PARTNUM _v) { + return (((CP210x_PARTNUM_CP2101 <= _v) && (_v <= CP210x_PARTNUM_CP2105)) || (CP210x_PARTNUM_CP2108 == _v) || (CP210x_PARTNUM_CP2109 == _v) || ((CP210x_PARTNUM_CP2102N_QFN28 <= _v) && (_v <= CP210x_PARTNUM_CP2102N_QFN20)) || (CP210x_PARTNUM_USBXPRESS_F3XX == _v)); +} +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsOTPCP210X_PARTNUM(_In_ const CP210X_PARTNUM _v) { + return ((CP210x_PARTNUM_CP2104 == _v) || (CP210x_PARTNUM_CP2105 == _v) || (CP210x_PARTNUM_CP2109 == _v)); +} +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsOTP(_In_ const SILABS_PID _p, _In_ const CP210X_PARTNUM _v) { + return IsValidCP210X_PID(_p) ? IsOTPCP210X_PARTNUM(_v) : ((SILABS_PID_CP2110 == _v) || (SILABS_PID_CP2112 == _v) || (SILABS_PID_CP2114 == _v) || (SILABS_PID_CP2130 == _v)); +} + +// Return Codes ??Of what?? API DLLs? +typedef enum _SILABS_STATUS { + SILABS_STATUS_SUCCESS = ((BYTE)(0xFF & 0x00)) + , SILABS_STATUS_TBD = ((BYTE)(0xFF & 0x01)) + , SILABS_STATUS_UNKNOWN_ERROR = ((BYTE)(0xFF & 0xFF)) +} SILABS_STATUS, *PSILABS_STATUS; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_STATUS(_In_ const SILABS_STATUS _s) { + return (((SILABS_STATUS_SUCCESS <= _s) && (_s <= SILABS_STATUS_TBD)) || (SILABS_STATUS_UNKNOWN_ERROR == _s)); +} +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsSuccessSILABS_STATUS(_In_ const SILABS_STATUS _s) { return SILABS_STATUS_SUCCESS == _s; } + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_DEFS_H_INCLUDED_BVHHTNCO7E) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sal.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sal.h new file mode 100644 index 0000000..9d763d3 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sal.h @@ -0,0 +1,77 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_sal.h + +Abstract: + + A top-level, across all repos, authoritative, Master include file for + older IDEs that do not support the SAL-annotations that our API Header files use. + +Environment: + + User mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT +#define HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT + +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_In_opt_) +#define _In_opt_ +#endif // ! defined(_In_opt_) +#if ! defined(_Out_) +#define _Out_ +#endif // ! defined(_Out_) +#if ! defined(_In_range_) +#define _In_range_(lb,ub) +#endif // ! defined(_In_range_) +#if ! defined(_Out_range_) +#define _Out_range_(lb,ub) +#endif // ! defined(_Out_range_) +#if ! defined(_In_reads_bytes_) +#define _In_reads_bytes_(n) +#endif // ! defined(_In_reads_bytes_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Out_writes_bytes_opt_) +#define _Out_writes_bytes_opt_(n) +#endif // ! defined(_Out_writes_bytes_opt_) +#if ! defined(_Inout_updates_bytes_opt_) +#define _Inout_updates_bytes_opt_(n) +#endif // ! defined(_Inout_updates_bytes_opt_) +#if ! defined(_Printf_format_string_) +#define _Printf_format_string_ +#endif // ! defined(_Printf_format_string_) +#if ! defined(_Use_decl_annotations_) +#define _Use_decl_annotations_ +#endif // ! defined(_Use_decl_annotations_) +#if ! defined(_Acquires_lock_) +#define _Acquires_lock_(arg) +#endif // ! defined(_Acquires_lock_) +#if ! defined(_Releases_lock_) +#define _Releases_lock_(arg) +#endif // !defined(_Releases_lock_) + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sdkddkversion.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sdkddkversion.h new file mode 100644 index 0000000..96d99d7 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_sdkddkversion.h @@ -0,0 +1,88 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_sdkddkversion.h + +Abstract: + + A top-level, across all repos, authoritative, Master include file for versioning Windows SDK/DDK. + +Environment: + + User or kernel mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_SDKDDKVERSION_H_INCLUDED_BVHHTNCO7E +#define HOST_COMMON_INCLUDE_SILABS_SDKDDKVERSION_H_INCLUDED_BVHHTNCO7E + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. +// "If you define NTDDI_VERSION, you must also define _WIN32_WINNT." -- MSDN +#include + +#if ! defined(_WIN32_WINNT) +#if defined(_M_ARM) +#define _WIN32_WINNT _WIN32_WINNT_WIN10 +#else +#define _WIN32_WINNT _WIN32_WINNT_WIN7 +#endif +#endif // ! defined(_WIN32_WINNT) +#if ! defined(WINVER) +#define WINVER _WIN32_WINNT +#endif // ! defined(WINVER) +#if ! defined(NTDDI_VERSION) +#if defined(_M_ARM) +#define NTDDI_VERSION NTDDI_WIN10 +#else +#define NTDDI_VERSION NTDDI_WIN7 +#endif +#endif // ! defined(NTDDI_VERSION) + +#if WINVER != _WIN32_WINNT +#error "Unexpected: WINVER and _WIN32_WINNT expected to be the same" +#endif // defined(NTDDI_VERSION) && ! defined(_WIN32_WINNT) + +// "If you define NTDDI_VERSION, you must also define _WIN32_WINNT." -- MSDN +#if defined(NTDDI_VERSION) && ! defined(_WIN32_WINNT) +#error "If you define NTDDI_VERSION, you must also define _WIN32_WINNT." +#endif // defined(NTDDI_VERSION) && ! defined(_WIN32_WINNT) + +#include + +#include + +// On x86 and x64, Windows 7 is the minimum target operating system. +// Note: For historical reasons, x64 is defined as AMD64, not to be confused with ARM64 :( +// _WIN32_WINNT and WINVER == _WIN32_WINNT_WIN7; NTDDI_VERSION == NTDDI_WIN7 +// On ARM, Windows 10 is the minimum target operating system +// _WIN32_WINNT and WINVER == _WIN32_WINNT_WIN10; NTDDI_VERSION == NTDDI_WIN10 +#if defined(i386) || defined(_X86_) || defined(AMD64) || defined(_AMD64_) || defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) +#if ! ((_WIN32_WINNT == _WIN32_WINNT_WIN7) && (WINVER == _WIN32_WINNT_WIN7)) +//#error "On x86 and x64, Windows 7 is the minimum target operating system" +#pragma message("Fix me: On x86 and x64, Windows 7 is the minimum target operating system") +#endif // ! ((_WIN32_WINNT == _WIN32_WINNT_WIN7) && (WINVER == _WIN32_WINNT_WIN7)) +#if NTDDI_VERSION != NTDDI_WIN7 +//#error "On x86 and x64, Windows 7 is the minimum target operating system" +#pragma message("Fix me: On x86 and x64, Windows 7 is the minimum target operating system") +#endif // NTDDI_VERSION != NTDDI_WIN7 +#elif defined(ARM) || defined(_ARM_) || defined(ARM64) || defined(_ARM64_) || defined(_M_ARM) +#if (_WIN32_WINNT != _WIN32_WINNT_WIN10) && (WINVER != _WIN32_WINNT_WIN10) +#error "On ARM, Windows 10 is the minimum target operating system" +#endif // (_WIN32_WINNT != _WIN32_WINNT_WIN10) && (WINVER != _WIN32_WINNT_WIN10) +#if NTDDI_VERSION != NTDDI_WIN10 +#error "On ARM, Windows 10 is the minimum target operating system" +#endif // NTDDI_VERSION != NTDDI_WIN10 +#else +#error "Unexpected/unhandled CPU architecture" +#endif + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_SDKDDKVERSION_H_INCLUDED_BVHHTNCO7E) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_usb.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_usb.h new file mode 100644 index 0000000..8faa65d --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_usb.h @@ -0,0 +1,413 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_usb.h + +Abstract: + + A top-level, across-all-repos, collection of some "useful" USB-related defines/enums + +Environment: + + User or kernel mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E +#define HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E + +#include "silabs_sal.h" + +#if ! defined(__cplusplus) +#define bool BOOLEAN +#endif // ! defined(__cplusplus) + +// USB Descriptors +typedef enum _SILABS_USB_DESCRIPTORS_LENGTH { // Aret hese absolutes? maxs? Or mins? + SILABS_USB_DESCRIPTORS_LENGTH_DEVICE_DESCRIPTOR = ((BYTE)12) + , SILABS_USB_DESCRIPTORS_LENGTH_CONFIGURATION_DESCRIPTOR = ((BYTE)9) // not fixed size? + , SILABS_USB_DESCRIPTORS_LENGTH_STRING_DESCRIPTOR = ((BYTE)8) + , SILABS_USB_DESCRIPTORS_LENGTH_INTERFACE_DESCRIPTOR = ((BYTE)9) // not fixed size? + , SILABS_USB_DESCRIPTORS_LENGTH_ENDPOINT_DESCRIPTOR = ((BYTE)7) +} SILABS_USB_DESCRIPTORS_LENGTH, *PSILABS_USB_DESCRIPTORS_LENGTH; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_DESCRIPTORS_LENGTH(_In_ const SILABS_USB_DESCRIPTORS_LENGTH _l) { + return ((SILABS_USB_DESCRIPTORS_LENGTH_ENDPOINT_DESCRIPTOR <= _l) || (SILABS_USB_DESCRIPTORS_LENGTH_DEVICE_DESCRIPTOR >= _l)); +} +typedef enum _SILABS_USB_DESCRIPTORS_TYPE { + SILABS_USB_DESCRIPTORS_TYPE_DEVICE_DESCRIPTOR = ((BYTE)0x01) + , SILABS_USB_DESCRIPTORS_TYPE_CONFIGURATION_DESCRIPTOR = ((BYTE)0x02) + , SILABS_USB_DESCRIPTORS_TYPE_STRING_DESCRIPTOR = ((BYTE)0x03) + , SILABS_USB_DESCRIPTORS_TYPE_INTERFACE_DESCRIPTOR = ((BYTE)0x04) + , SILABS_USB_DESCRIPTORS_TYPE_ENDPOINT_DESCRIPTOR = ((BYTE)0x05) +} SILABS_USB_DESCRIPTORS_TYPE, *PSILABS_USB_DESCRIPTORS_TYPE; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_DESCRIPTORS_TYPE(_In_ const SILABS_USB_DESCRIPTORS_TYPE _t) { + return ((SILABS_USB_DESCRIPTORS_TYPE_DEVICE_DESCRIPTOR <= _t) && (SILABS_USB_DESCRIPTORS_TYPE_ENDPOINT_DESCRIPTOR >= _t)); +} + +// Device Descriptor +// Configuration Descriptor +// String Descriptor +// Maximum String Lengths (in characters (not bytes required to store those characters (for multi-byte encodings)); not including any nul-termination, if present) +// Maximum Number of Characters Per String Descriptor: +// Product Manufacturer Serial Number Interface +// CP2101 126 12 63 N / A +// CP2102 126 29 63 N / A +// CP2102N 128 64 64 N / A +// CP2103 126 29 63 N / A Note: All number are *character* counts +// CP2104 126 29 63 N / A Note: Device stores strings as 16-bit UCS-2 character strings (I.e. two bytes per character) +// CP2105 47 12 16 32 +// CP2108 126 126 126 126 +// CP2109 126 12 63 N / A + +// Product String +typedef enum _SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX { + SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X = 126 + , SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 128 + , SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 47 +} SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l)); +} +typedef enum _SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX { + SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP210X = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X + , SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2102N = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N + , SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105 +} SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l)); +} + +// Manufacturer String +typedef enum _SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_MAX_IN_CHARS { + SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2101 = 12 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102 = 29 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 128 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2103 = 29 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2104 = 29 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 12 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126 + , SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2109 = 12 +} SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX _l) { +#pragma warning ( push ) +#pragma warning ( disable : 6287 ) // warning C6287: redundant code: the left and right sub-expressions are identical + return ((SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2101 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102 == _l) + || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2103 == _l) + || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2104 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l) + || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2109 == _l)); +#pragma warning ( pop ) +} + +// Serial Number String +typedef enum _SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX { + SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X = 63 + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 64 + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 16 + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126 +} SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l) + || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l)); +} +typedef enum _SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX { + SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP210X = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2102N = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105 + , SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2108 = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108 +} SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2102N == _l) + || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2108 == _l)); +} + +// Interface String +typedef enum _SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX { + SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 32 + , SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126 +} SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l)); +} +typedef enum _SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX { + SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105 + , SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2108 = 2 * SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108 +} SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX _l) { + return ((SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2108 == _l)); +} + +// Interface Descriptor +// Endpoint Descriptor + +// RequestType - defined in Table 9.2 of section 9.3 of the Universal Serial Bus(USB) specification (www.usb.org). +// The RequestType field will determine the direction of the request, type of request and designated recipient. +// Data Transfer Direction +typedef enum _SILABS_USB_REQUESTTYPE_DIRECTION { + SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE = ((BYTE)0x00) + , SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST = ((BYTE)(0x01 << 7)) +} SILABS_USB_REQUESTTYPE_DIRECTION, *PSILABS_USB_REQUESTTYPE_DIRECTION; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_REQUESTTYPE_DIRECTION(_In_ const SILABS_USB_REQUESTTYPE_DIRECTION _d) { + return ((SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE == _d) || (SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST == _d)); +} +// Bits 6-5 of RequestType indicate the type of the request (Standard, Class, or Vendor). +// Standard requests are common to all USB devices. +// Class requests are common to classes of drivers. For example, all devices conforming to the HID class will have a common set of class specific requests. +typedef enum _SILABS_USB_REQUESTTYPE_TYPE { + SILABS_USB_REQUESTTYPE_TYPE_STANDARD = ((BYTE)0x00) + , SILABS_USB_REQUESTTYPE_TYPE_CLASS = ((BYTE)(0x01 << 5)) + , SILABS_USB_REQUESTTYPE_TYPE_VENDOR = ((BYTE)(0x02 << 5)) + , SILABS_USB_REQUESTTYPE_TYPE_RESERVED = ((BYTE)(0x03 << 5)) +} SILABS_USB_REQUESTTYPE_TYPE, *PSILABS_USB_REQUESTTYPE_TYPE; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_REQUESTTYPE_TYPE(_In_ const SILABS_USB_REQUESTTYPE_TYPE _t) { + return ((SILABS_USB_REQUESTTYPE_TYPE_STANDARD == _t) || (SILABS_USB_REQUESTTYPE_TYPE_CLASS == _t) + ||(SILABS_USB_REQUESTTYPE_TYPE_VENDOR == _t) || (SILABS_USB_REQUESTTYPE_TYPE_RESERVED == _t)); +} +// The lowest two bits of RequestType indicate the recipient of the request (device, interface, endpoint or other). +// If the recipient is the device, the lowest two bits of RequestType value must be 0. +// If the recipient is an interface, the lowest two bits of RequestType value must be 0x01. +// If the recipient is an endpoint, the lowest two bits of RequestType value must be 0x02. +typedef enum _SILABS_USB_REQUESTTYPE_RECIPIENT { + SILABS_USB_REQUESTTYPE_RECIPIENT_HOST = ((BYTE)0x00) + , SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE = ((BYTE)0x00) + , SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE = ((BYTE)0x01) + , SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT = ((BYTE)0x02) + , SILABS_USB_REQUESTTYPE_RECIPIENT_OTHER = ((BYTE)0x03) +} SILABS_USB_REQUESTTYPE_RECIPIENT, *PSILABS_USB_REQUESTTYPE_RECIPIENT; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_REQUESTTYPE_RECIPIENT(_In_ const SILABS_USB_REQUESTTYPE_RECIPIENT _r) { + return ((SILABS_USB_REQUESTTYPE_RECIPIENT_HOST <= _r) && (_r <= SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT)); +} + +#define SILABS_USB_REQUESTTYPE_MAKE(_direction, _type, _recipient) ((BYTE)((_direction) | (_type) | (_recipient))) +typedef enum _SILABS_USB_REQUESTTYPE { + SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_DEVICE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE) + , SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_INTERFACE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE) + , SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_ENDPOINT = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT) + , SILABS_USB_REQUESTTYPE_STANDARD_DEVICE_TO_HOST = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST) + + , SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_DEVICE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE) + , SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_INTERFACE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE) + , SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_ENDPOINT = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT) + , SILABS_USB_REQUESTTYPE_CLASS_DEVICE_TO_HOST = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST) + + , SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_DEVICE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE) + , SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_INTERFACE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE) + , SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_ENDPOINT = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT) + , SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST) + , SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST_INTERFACE = SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE) +} SILABS_USB_REQUESTTYPE, *PSILABS_USB_REQUESTTYPE; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_REQUESTTYPE(_In_ const SILABS_USB_REQUESTTYPE _r) { + return ((SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_INTERFACE == _r) + || (SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_STANDARD_DEVICE_TO_HOST == _r) + || (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_INTERFACE == _r) + || (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_CLASS_DEVICE_TO_HOST == _r) + || (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_INTERFACE == _r) + || (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST_INTERFACE == _r)); +} + + + +// Request - defined in Table 9.3 of section 9.4 of the Universal Serial Bus(USB) specification (www.usb.org). +typedef enum _SILABS_USB_REQUEST { + _XXX = 0x00 + + // http://www.beyondlogic.org/usbnutshell/usb6.shtml + // There are currently eight Standard Device requests: + , SILABS_USB_REQUEST_STANDARD_DEVICE_GET_STATUS = 0x00 + , SILABS_USB_REQUEST_STANDARD_DEVICE_CLEAR_FEATURE = 0x01 + , SILABS_USB_REQUEST_STANDARD_DEVICE_SET_FEATURE = 0x03 + , SILABS_USB_REQUEST_STANDARD_DEVICE_SET_ADDRESS = 0x05 + , SILABS_USB_REQUEST_STANDARD_DEVICE_GET_DESCRIPTOR = 0x06 + , SILABS_USB_REQUEST_STANDARD_DEVICE_SET_DESCRIPTOR = 0x07 + , SILABS_USB_REQUEST_STANDARD_DEVICE_GET_CONFIGURATION = 0x08 + , SILABS_USB_REQUEST_STANDARD_DEVICE_SET_CONFIGURATION = 0x09 + + // The specification currently defines five Standard Interface requests: + , SILABS_USB_REQUEST_STANDARD_INTERFACE_GET_STATUS = 0x00 + , SILABS_USB_REQUEST_STANDARD_INTERFACE_CLEAR_FEATURE = 0x01 + , SILABS_USB_REQUEST_STANDARD_INTERFACE_SET_FEATURE = 0x03 + , SILABS_USB_REQUEST_STANDARD_INTERFACE_GET_INTERFACE = 0x0A + , SILABS_USB_REQUEST_STANDARD_INTERFACE_SET_INTERFACE = 0x11 + + // Standard Endpoint requests come in four varieties: + , SILABS_USB_REQUEST_STANDARD_ENDPOINT_GET_STATUS = 0x00 + , SILABS_USB_REQUEST_STANDARD_ENDPOINT_CLEAR_FEATURE = 0x01 + , SILABS_USB_REQUEST_STANDARD_ENDPOINT_SET_FEATURE = 0x03 + , SILABS_USB_REQUEST_STANDARD_ENDPOINT_SYNCH_FRAME = 0x12 + + // HID Class-specific requests + , SILABS_USB_REQUEST_HID_CLASS_GET_REPORT = 0x01 + , SILABS_USB_REQUEST_HID_CLASS_GET_IDLE = 0x02 + , SILABS_USB_REQUEST_HID_CLASS_GET_PROTOCOL = 0x03 + // 0x04-0x08 Reserved + , SILABS_USB_REQUEST_HID_CLASS_SET_REPORT = 0x09 + , SILABS_USB_REQUEST_HID_CLASS_SET_IDLE = 0x0A + , SILABS_USB_REQUEST_HID_CLASS_SET_PROTOCOL = 0x0B + + // + // Vendor-specific bRequest definitions CP210X + // + , SILABS_USB_REQUEST_VENDOR_SILABS_IFC_ENABLE = 0x00 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_BAUDDIV = 0x01 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_LINE_CTL = 0x03 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_BREAK = 0x05 + , SILABS_USB_REQUEST_VENDOR_SILABS_IMM_CHAR = 0x06 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_MHS = 0x07 + , SILABS_USB_REQUEST_VENDOR_SILABS_GET_MDMSTS = 0x08 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_XON = 0x09 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_XOFF = 0x0A + , SILABS_USB_REQUEST_VENDOR_SILABS_GET_PROPS = 0x0F + , SILABS_USB_REQUEST_VENDOR_SILABS_GET_COMMSTS = 0x10 + , SILABS_USB_REQUEST_VENDOR_SILABS_RESET = 0x11 + , SILABS_USB_REQUEST_VENDOR_SILABS_PURGE = 0x12 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_FLOW = 0x13 + , SILABS_USB_REQUEST_VENDOR_SILABS_EMBED_EVENTS = 0x15 + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_CHARS = 0x19 + , SILABS_USB_REQUEST_VENDOR_SILABS_GET_BAUDRATE = 0x1D + , SILABS_USB_REQUEST_VENDOR_SILABS_SET_BAUDRATE = 0x1E + + // + // Vendor-specific bRequest definitions USBXPRESS + // + , SILABS_USB_REQUEST_VENDOR_SILABS_USBXPRESS_REQUEST = 0x02 + + // + // Vendor-specific bRequest definitions SLAB_USP_SPI CP213X + // + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_RESET_DEVICE = 0x10 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_RO_VERSION = 0x11 + + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_GPIO_VALUES = 0x20 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_GPIO_VALUES = 0x21 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_GPIO_MODE_AND_LEVEL = 0x22 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_GPIO_MODE_AND_LEVEL = 0x23 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_CHIP_SELECT = 0x24 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_CHIP_SELECT = 0x25 + + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SPI_CONTROL_BYTES = 0x30 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SPI_CONTROL_BYTE = 0x31 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SPI_DELAY = 0x32 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SPI_DELAY = 0x33 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_FULL_THRESHOLD = 0x34 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_FULL_THRESHOLD = 0x35 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_RTR_STOP = 0x36 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_RTR_STOP = 0x37 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MULTI_MASTER_STATE = 0x38 + //#define SET_MULTI_MASTER_STATE 0x39 // Not supported + //#define GET_MULTI_MASTER_CTL 0x40 // Not supported + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MULTIMASTER_CONTROL = 0x41 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MULTIMASTER_CONFIG = 0x42 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MULTIMASTER_CONFIG = 0x43 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_EVENT_COUNTER = 0x44 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_EVENT_COUNTER = 0x45 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_CLOCK_DIVIDER = 0x46 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_CLOCK_DIVIDER = 0x47 + + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_USB_CONFIG = 0x60 // All customizable data that's not strings + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_USB_CONFIG = 0x61 // All customizable data that's not strings + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MANU1 = 0x62 // Get Set Manufacturing String 1 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MANU1 = 0x63 // Get Set Manufacturing String 1 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MANU2 = 0x64 // Get Set Manufacturing String 2 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MANU2 = 0x65 // Get Set Manufacturing String 2 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROD1 = 0x66 // Get Set Product String 1 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROD1 = 0x67 // Get Set Product String 1 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROD2 = 0x68 // Get Set Product String 2 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROD2 = 0x69 // Get Set Product String 2 + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SERIAL = 0x6A // Get Set Serial String + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SERIAL = 0x6B // Get Set Serial String + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PIN_CONFIG = 0x6C // GPIO configuration + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PIN_CONFIG = 0x6D // GPIO configuration + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_LOCK_BYTE = 0x6E // Get Set Lock Byte + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_LOCK_BYTE = 0x6F // Get Set Lock Byte + + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROM_CONFIG = 0x70 // Get EPROM all configuration + , SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROM_CONFIG = 0x71 // Set EPROM all configuration + + , SILABS_USB_REQUEST_VENDOR_SPECIFIC = 0xFF // Meaning the Request is in Value? +} SILABS_USB_REQUEST, *PSILABS_USB_REQUEST; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_REQUEST(_In_ const SILABS_USB_REQUEST _r) { + return ((0 <= _r) && (_r <= 0xFF)); +} + +// Request - defined in Table 9.3 of section 9.4 of the Universal Serial Bus(USB) specification (www.usb.org). +// Value - varies according to the request. For an explanation of this member, see the Universal Serial Bus(USB) specification (www.usb.org). +typedef enum _SILABS_USB_VALUE { + SILABS_USB_VALUE_XXX = 0x00 + + // + // Vendor-specific bValue definitions USBXPRESS + // + , SILABS_USB_VALUE_CP210X_SET_VID = 0x3701 // Set Vid command + , SILABS_USB_VALUE_CP210X_SET_PID = 0x3702 // Set Vid command + , SILABS_USB_VALUE_CP210X_SET_PRODUCT_STRING = 0x3703 // Set Product String command + , SILABS_USB_VALUE_CP210X_SET_SERIAL_NUMBER = 0x3704 // Set Serial Number command + , SILABS_USB_VALUE_CP210X_SET_POWER_USE_ATTRIBUTES = 0x3705// Set Power Use Attributes + , SILABS_USB_VALUE_CP210X_SET_MAX_POWER = 0x3706 // Set Max. Power + , SILABS_USB_VALUE_CP210X_SET_DEVICE_VERSION = 0x3707 // Set Device Version + , SILABS_USB_VALUE_CP210X_RESET = 0x3708 // Reset command + , SILABS_USB_VALUE_CP210X_GET_BAUD_RATE = 0x3709 // get baud rate command + , SILABS_USB_VALUE_CP210X_LOCK = 0x370A // Lock Custom Data Command + , SILABS_USB_VALUE_CP210X_GET_PART_NUMBER = 0x370B // Get Part num -- USBXpress? + , SILABS_USB_VALUE_CP210X_GET_PORT_CONFIG = 0x370C // Get Port Config + , SILABS_USB_VALUE_CP210X_FLUSH_BUFFER = 0x370D // Flush Buffer Command + , SILABS_USB_VALUE_CP210X_GET_CONFIG = 0x370e // Get Config + , SILABS_USB_VALUE_CP210X_SET_CONFIG = 0x370F // Set Config + , SILABS_USB_VALUE_CP210X_GET_FIRMWARE_VERSION = 0x3710 // Get Firmware Version + , SILABS_USB_VALUE_CP210X_GET_DEVICE_MODE = 0x3711 // Get Device Mode Command + + , SILABS_USB_VALUE_CP210X_SET_MANUFACTURER_STRING = 0x3714 // Set Manufacturer String command + + , SILABS_USB_VALUE_CP210X_UPDATE_FIRMWARE = 0x37FF // Update Firmware + + // + // Vendor-specific bValue definitions USBXPRESS + // + , SILABS_USB_VALUE_USBXPRESS_FLUSH_BUFFERS = ((unsigned short)(0xFFFF & 0x0001)) + , SILABS_USB_VALUE_USBXPRESS_CLEAR_TO_SEND = ((unsigned short)(0xFFFF & 0x0002)) + , SILABS_USB_VALUE_USBXPRESS_NOT_CLEAR_TO_SEND = ((unsigned short)(0xFFFF & 0x0004)) + , SILABS_USB_VALUE_USBXPRESS_GET_PART_NUM = ((unsigned short)(0xFFFF & 0x0008)) +} SILABS_USB_VALUE, *PSILABS_USB_VALUE; +_Check_return_ +_Success_(return == TRUE) +__inline static bool IsValidSILABS_USB_VALUE(_In_ const SILABS_USB_VALUE _v) { + return ( (SILABS_USB_VALUE_USBXPRESS_FLUSH_BUFFERS <= _v) && (_v <= SILABS_USB_VALUE_CP210X_UPDATE_FIRMWARE)); +} + + + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_utils.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_utils.h new file mode 100644 index 0000000..9cacd81 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_utils.h @@ -0,0 +1,285 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_utils.h + +Abstract: + + A top-level, across-all-repos, collection of some "useful" constructs + +Environment: + + User or kernel mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_UTILS_H_INCLUDED_DL027EJB47 +#define HOST_COMMON_INCLUDE_SILABS_UTILS_H_INCLUDED_DL027EJB47 + +#include "silabs_sal.h" +#if defined(__APPLE__) +#include +#include +#endif + +#include "OsDep.h" + +// Pointedly, specifically, lose higher bits during conversion to smaller types +// (pointedly, specifically, identifying that this is not a loss of (meaningful) data)) +#define SILABS_CONVERT_LARGER_TO_8BITS(i) ((BYTE)(0xFF & (i))) +#define SILABS_CONVERT_LARGER_TO_16BITS(i) ((unsigned short)(0xFFFF & (i))) +#define SILABS_CONVERT_INT_TO_BYTE(i) SILABS_CONVERT_LARGER_TO_8BITS(i) +#define SILABS_CONVERT_BOOL_TO_BYTE(i) SILABS_CONVERT_INT_TO_BYTE(i) +#define SILABS_CONVERT_INT_TO_WORD(i) SILABS_CONVERT_LARGER_TO_16BITS(i) + +#define SILABS_MAKEWORD(l, h) ((WORD)(((SILABS_CONVERT_LARGER_TO_8BITS(h)) << 8) | (SILABS_CONVERT_LARGER_TO_8BITS(l)))) +#define SILABS_LOBYTE(w) (SILABS_CONVERT_LARGER_TO_8BITS(w)) +#define SILABS_HIBYTE(w) (SILABS_CONVERT_LARGER_TO_8BITS((w) >> 8)) + +#if !defined(SIZEOF_ARRAY) +#define SIZEOF_ARRAY( _a ) (sizeof( (_a) ) / sizeof( (_a)[0])) +#endif + + +// HANDLE validation helpers +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +#if defined(_WIN32) +static inline BOOL SiLabs_Utils_IsInvalidHandle (_In_opt_ const HANDLE h) { return (INVALID_HANDLE_VALUE == h) || ((const HANDLE) 0 == h); } +#else +static inline BOOL SiLabs_Utils_IsInvalidHandle (_In_opt_ const HANDLE h) { return ((const HANDLE) 0 == h); } +#endif +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidHandle (_In_opt_ const HANDLE h) { return ! SiLabs_Utils_IsInvalidHandle(h); } + +// Now minus start time gives elapsed time, validate now is post-StartTime, etc. +static inline ULONGLONG SiLabs_Utils_GetStartTime(void) +{ +#if defined(_WIN32) +#if (_WIN32_WINNT >= 0x0600) + return GetTickCount64(); +#else + return (ULONGLONG) GetTickCount(); +#endif +#elif defined(__APPLE__) + mach_timebase_info_data_t info; + + mach_timebase_info(&info); + + return (ULONGLONG) ((mach_absolute_time() * info.numer / info.denom) / 1000000); +#else + return GetTickCount(); +#endif // defined(_WIN32) +} + +// Now minus start time gives elapsed time, validate now is post-StartTime, etc. +static inline ULONGLONG SiLabs_Utils_ElapsedTimeSince(_In_ const ULONGLONG StartTime) +{ + const ULONGLONG NowTime = SiLabs_Utils_GetStartTime(); + + return StartTime < NowTime ? NowTime - StartTime : 0; +} + + + +// "ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread +// is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, +// in C++ code, you should return from your thread function." -- MSDN +static inline DWORD SiLabs_Utils_ExitThread(_In_ const DWORD dwExitCode) +{ + // " If a thread returns STILL_ACTIVE (259) as an error code, applications that test for this value could + // interpret it to mean that the thread is still running and continue to test for the completion of the thread + // after the thread has terminated, which could put the application into an infinite loop." -- MSDN + if (259 == dwExitCode) + { + } + +#if ! defined(__cplusplus) + ExitThread(dwExitCode); +#endif // defined(__cplusplus) + + return dwExitCode; +} + +#ifdef __cplusplus // These overloaded IsValidParam functions won't/don't work in C. They are C++ only +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(LPDWORD) +// +// Checks validity of an LPDWORD pointer value. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPDWORD lpdwPointer) +{ + DWORD temp = 0; + + if (!lpdwPointer) return FALSE; + + try + { + temp = *lpdwPointer; + } + catch(...) + { + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(LPWORD) +// +// Checks validity of an LPWORD pointer value. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPWORD lpwPointer) +{ + WORD temp = 0; + + if (!lpwPointer) return FALSE; + + try + { + temp = *lpwPointer; + } + catch(...) + { + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(LPBYTE) +// +// Checks validity of an LPBYTE pointer value. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPBYTE lpbPointer) +{ + BYTE temp = 0; + + if (!lpbPointer) return FALSE; + + try + { + temp = *lpbPointer; + } + catch(...) + { + return FALSE; + } + return TRUE; +} + + +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(LPVOID) +// +// Checks validity of an LPVOID pointer value. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPVOID lpVoidPointer) +{ + BYTE temp = 0; + + if (!lpVoidPointer) return FALSE; + + try + { + temp = *((BYTE*)lpVoidPointer); + } + catch(...) + { + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(HANDLE*, BOOL) +// +// Checks validity of an HANDLE* pointer value. If BOOL is true, also check validity of HANDLE. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(HANDLE* lpHandle, _In_ const BOOL bVerifyIsValidHandle = TRUE) +{ + HANDLE temp = 0; + + if (!lpHandle) return FALSE; + + try + { + temp = *lpHandle; + } + catch(...) + { + return FALSE; + } + return bVerifyIsValidHandle ? SiLabs_Utils_IsValidHandle(*lpHandle) : TRUE; +} + +//------------------------------------------------------------------------ +// ValidParam(LPVOID, LPBYTE) +// +// Checks validity of LPVOID, LPBYTE pair of pointer values. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPVOID lpVoidPointer, LPBYTE lpbPointer) +{ + return SiLabs_Utils_IsValidParam(lpVoidPointer) && SiLabs_Utils_IsValidParam(lpbPointer); +} + +//------------------------------------------------------------------------ +// SiLabs_Utils_IsValidParam(LPVOID, LPDWORD) +// +// Checks validity of LPVOID, LPDWORD pair of pointer values. +//------------------------------------------------------------------------ +_Check_return_ +_Ret_range_(FALSE,TRUE) +_Success_(return == TRUE) +static inline BOOL SiLabs_Utils_IsValidParam(LPVOID lpVoidPointer, LPDWORD lpdwPointer) +{ + return SiLabs_Utils_IsValidParam(lpVoidPointer) && SiLabs_Utils_IsValidParam(lpdwPointer); +} +#endif // __cplusplus + +#if defined(_WIN32) +#include +#include +static inline void SiLabs_Utils_DebugPrint(_In_ _Printf_format_string_ const char *pszFormat, ...) +{ + va_list ap; + char s[256]; + va_start(ap, pszFormat); + (void) vsnprintf_s(s, (sizeof(s) / sizeof(s[0])) - 1, _TRUNCATE, pszFormat, ap); + va_end(ap); + OutputDebugStringA(s); + + return; // void +} +#endif // defined(_WIN32) + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_UTILS_H_INCLUDED_DL027EJB47) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_version.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_version.h new file mode 100644 index 0000000..80895f3 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/include/silabs_version.h @@ -0,0 +1,82 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_version.h + +Abstract: + + A top-level, authoritative, definition of some common across-all-repos/products items + + Versioning based on http://semver.org/ three-field version number, but extended to Microsoft's + four-field version number. Semver's MAJOR.MINOR.PATCH extended to MAJOR.MINOR.PATCH.BUILD. Such that + 1.MAJOR version when you make incompatible API changes, + 2.MINOR version when you add functionality in a backwards-compatible manner, + 3.PATCH version when you make backwards-compatible bug fixes, and + 4.BUILD is Jenkins's BUILD_NUMBER. + + Notice too, that this file contains the "Product"-level version. Each build artifact within the + "product" will have it's own, independent, "File"-level version number. + + Beyond a Version number, this file contains attributes that go into a Windows .RC VERSION resource (such as + company name, copyright verbiage, etc.) + +Environment: + + User or kernel mode + +--*/ +// +#ifndef HOST_COMMON_INCLUDE_SILABS_VERSION_H_INCLUDED_I1WFULXDGP +#define HOST_COMMON_INCLUDE_SILABS_VERSION_H_INCLUDED_I1WFULXDGP + +#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) + +#define VER_COMPANYNAME_LEGAL_STR "Silicon Laboratories Inc." +#define VER_COMPANYNAME_SHORT_STR "Silicon Labs" +#define VER_COMPANYNAME_ABBR_STR "SiLabs" + +#define VER_LEGALCOPYRIGHT_STR "Copyright © 2016 " VER_COMPANYNAME_LEGAL_STR ", All Rights Reserved." + +#define VER_PRODUCTNAME_STR VER_COMPANYNAME_SHORT_STR " USBXpress Software Portfolio" + +// Stringize an int +#define XSTRINGIFY2(x) #x +#define STRINGIFY(x) XSTRINGIFY2(x) +#define STR(x) XSTRINGIFY2(x) // obsolete, don't use STR() any more + +// Jenkins will pass in the BUILD_NUMBER. If not, use 0. +// Some futzing necessary to detect BUILD_NUMBER= which makes BUILD_NUMBER defined but to have no value, which breaks. +#if ! defined(BUILD_NUMBER) || (7-BUILD_NUMBER-7 == 14) +#undef BUILD_NUMBER // undefine it, lest it be defined as no value (otherwise the next line throws a warning about a redefine) +#define BUILD_NUMBER (0) +#endif + + +#define VER_PRODUCTVERSION_MAJOR 6 +#define VER_PRODUCTVERSION_MINOR 7 +#define VER_PRODUCTVERSION_PATCH 4 +#define VER_PRODUCTVERSION_BUILD BUILD_NUMBER + +#define VER_PRODUCTVERSION VER_PRODUCTVERSION_MAJOR,VER_PRODUCTVERSION_MINOR,VER_PRODUCTVERSION_PATCH,VER_PRODUCTVERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIFY(VER_PRODUCTVERSION_MAJOR) "." STRINGIFY(VER_PRODUCTVERSION_MINOR) "." STRINGIFY(VER_PRODUCTVERSION_PATCH) "." STRINGIFY(VER_PRODUCTVERSION_BUILD) + +#define RELEASE_TAG VER_PRODUCTVERSION_STR + +// Pointedly UNdefine Internal- and Original-filename so that it MUST be defined in +// respective files' .rc files. +// Original File Name - "Original name of the file, not including a path" -- MSDN +// Internal File Name - "original filename, without extension" -- MSDN +// For example, Original file name is "fubar.exe", giving an Internal file name of "fubar". +#undef VER_ORIGINALFILENAME_STR +#undef VER_INTERNALFILENAME_STR + +// Pointedly UNdefine the FileVersion so that it MUST be defined in +// respective files' .rc files. +#undef VER_FILEVERSION +#undef VER_FILEVERSION_STR + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_VERSION_H_INCLUDED_I1WFULXDGP) + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/OsDep.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/OsDep.cpp new file mode 100644 index 0000000..60c7427 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/OsDep.cpp @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////// +// This is a Linux version of the O/S abstraction layer which implements +// O/S-dependent primitives and can help write portable apps. +///////////////////////////////////////////////////////////////////////////// + +#include "OsDep.h" +#include +#include // for usleep + +// Get system tick count in milliseconds +DWORD GetTickCount() +{ + DWORD count; + timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts)) + { + return 0; + } + + count = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + + return count; +} + +void Sleep( DWORD msec) +{ + usleep( msec * 1000); +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/Profiler.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/Profiler.h new file mode 100644 index 0000000..b9a2a9e --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/linux/Profiler.h @@ -0,0 +1,239 @@ +#pragma once + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// Custom User Options +///////////////////////////////////////////////////////////////////////////// + +// Enable or disable the profiler: TRUE or FALSE +#define ENABLE_PROFILER TRUE + +// CProfiler object symbol name used in DECLARE_PROFILER() +// Add this to your watch window to view timing information +// while in debug mode +#define PROFILER_NAME profiler + +// double total elapsed time used in DECLARE_TOTAL() +// Add this to your watch window to view total elapsed time +// while in debug mode +#define TOTAL_NAME total + +// Units of time: TIME_SECONDS, TIME_MILLISECONDS, or TIME_MICROSECONDS +#define TIME_UNITS TIME_SECONDS + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define TIME_SECONDS 1 +#define TIME_MILLISECONDS 1000 +#define TIME_MICROSECONDS 1000000 + +///////////////////////////////////////////////////////////////////////////// +// Macros +///////////////////////////////////////////////////////////////////////////// + +// START() - Reset the CProfiler object and record starting time +// LAP(expression) - Execute the specified expression +// - Record time elapsed from previous LAP() or START() call +// STOP(expression) - Execute the specified expression +// - Record time elapsed from previous LAP() or START() call +// and return the total elapsed time +// DUMP(filename) - Dump profiler information to the specified file + +#if (ENABLE_PROFILER) +#define START() PROFILER_NAME.Start("Start"); +#define LAP(expression) expression; PROFILER_NAME.Lap(#expression); +#define STOP(expression) expression; TOTAL_NAME = PROFILER_NAME.Stop(#expression); +#define DUMP(filename) PROFILER_NAME.Dump(filename); + +#define DECLARE_PROFILER() CProfiler PROFILER_NAME; +#define DECLARE_TOTAL() double TOTAL_NAME = 0.0f; +#else +#define START() +#define LAP(expression) expression; +#define STOP(expression) expression; +#define DUMP(filename) + +#define DECLARE_PROFILER() +#define DECLARE_TOTAL() +#endif + +///////////////////////////////////////////////////////////////////////////// +// Structures +///////////////////////////////////////////////////////////////////////////// + +struct ProfilerTimestamp +{ + double elapsed; + std::string comment; + double time; + + ProfilerTimestamp(double t, double e, std::string c) + : time(t) + { + elapsed = e; + comment = c; + } +}; + +///////////////////////////////////////////////////////////////////////////// +// CProfiler Class +///////////////////////////////////////////////////////////////////////////// + +class CProfiler +{ + // Constructor +public: + + CProfiler() + { + // Get the resolution of the system clock + clock_getres(CLOCK_MONOTONIC, &m_resolution); + + // Set initial capacity to 1000 to reduce time variations + // due to memory copy + m_timestamps.reserve(1000); + } + + // Public Methods +public: + + void Start(std::string comment = "") + { + m_timestamps.clear(); + + m_timestamps.push_back(ProfilerTimestamp(GetTime(), 0, comment)); + } + + // Return total time from Start to Stop + + double Stop(std::string comment = "") + { + double total; + + Lap(comment); + total = m_timestamps.back().time - m_timestamps.front().time; + + return total; + } + + // Return total time from Start to Stop + + double Elapsed() + { + double total; + + total = m_timestamps.back().time - m_timestamps.front().time; + + return total; + } + + // Return elapsed time from last Lap or Start + + double Lap(std::string comment = "") + { + double time = GetTime(); + double elapsed = time - m_timestamps.back().time; + + m_timestamps.push_back(ProfilerTimestamp(time, elapsed, comment)); + + return elapsed; + } + + // System uptime + + double GetTime() + { + double time; + timespec tp; + + clock_gettime(CLOCK_MONOTONIC, &tp); + + time = ((double)TIME_UNITS * (tp.tv_sec + (tp.tv_nsec / 1000000000.0f))); + + return time; + } + + void Dump(std::string filename) + { + std::fstream file; + + // Determine the unit string + std::string timeUnits; + +#if (TIME_UNITS == TIME_SECONDS) + timeUnits = "s"; +#elif (TIME_UNITS == TIME_MILLISECONDS) + timeUnits = "ms"; +#elif (TIME_UNITS == TIME_MICROSECONDS) + timeUnits = "us"; +#endif + + // Open the file for output + file.open(filename.c_str(), std::fstream::out); + + double resolution = (double)m_resolution.tv_sec + (m_resolution.tv_nsec / 1000000000.0f); + + // Log profiler header text + file << "Profiler Dump" << std::endl; + file << "-------------" << std::endl << std::endl; + file << "High Performance Counter Precision: " << ((double) TIME_UNITS * resolution) << " " << timeUnits << std::endl; + file << std::endl; + + size_t longestString = 0; + + // Get the length of the longest comment string + for (size_t i = 0; i < m_timestamps.size(); i++) + { + longestString = MAX(longestString, m_timestamps[i].comment.size()); + } + + // Set the number of digits to display after the decimal point + // to display up to nanoseconds + file.setf(std::ios::fixed); +#if (TIME_UNITS == TIME_SECONDS) + file.precision(9); +#elif (TIME_UNITS == TIME_MILLISECONDS) + file.precision(6); +#elif (TIME_UNITS == TIME_MICROSECONDS) + file.precision(3); +#endif + + // Output the comment and elapsed time for each timestamp entry + for (size_t i = 0; i < m_timestamps.size(); i++) + { + file << "Timestamp " << std::setw(5) << i << ": "; + + file << "Elapsed: " << std::setw(13) << m_timestamps[i].elapsed << " " << timeUnits << " "; + + // Display the line comment and space all elapsed times exactly 3 characters after the longest string + file << "Line: \"" << m_timestamps[i].comment << "\""; + + file << std::endl; + } + + // Display the total time elapsed + if (m_timestamps.size() > 0) + { + file << std::endl; + file << "Total Time: " << (m_timestamps.back().time - m_timestamps.front().time) << " " << timeUnits << std::endl; + } + + file.close(); + } + +public: + timespec m_resolution; + std::vector m_timestamps; +}; diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/src/ReportQueue.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/src/ReportQueue.cpp new file mode 100644 index 0000000..88e16e2 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/common/src/ReportQueue.cpp @@ -0,0 +1,64 @@ +#include "ReportQueue.h" + +void CReportQueue::Clear() +{ + m_Lock.Lock(); + + m_queue.clear(); + + m_Lock.Unlock(); +} + +void CReportQueue::Reserve(DWORD count) +{ + m_Lock.Lock(); + + m_queue.reserve(count); + + m_Lock.Unlock(); +} + +void CReportQueue::Enqueue(const BYTE* data, DWORD size) +{ + m_Lock.Lock(); + + for (DWORD i = 0; i < size; i++) + { + m_queue.push_back(data[i]); + } + + m_Lock.Unlock(); +} + +void CReportQueue::Dequeue(BYTE* data, DWORD size, DWORD* bytesDequeued) +{ + m_Lock.Lock(); + + // Figure out how many bytes to dequeue + DWORD num = (size < m_queue.size()) ? size : static_cast(m_queue.size()); + + // Copy the bytes to the user buffer + for (DWORD i = 0; i < num; i++) + { + data[i] = m_queue[i]; + } + + // Remove the bytes from the queue + m_queue.erase(m_queue.begin(), m_queue.begin() + num); + + // Return the number of bytes dequeued + *bytesDequeued = num; + + m_Lock.Unlock(); +} + +DWORD CReportQueue::Size() +{ + m_Lock.Lock(); + + DWORD size = static_cast(m_queue.size()); + + m_Lock.Unlock(); + + return size; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturing.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturing.h new file mode 100644 index 0000000..f8e18a7 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturing.h @@ -0,0 +1,16 @@ +///////////////////////////////////////////////////////////////////////////// +// CP210xManufacturing.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CP210x_MANUFACTURING_H +#define CP210x_MANUFACTURING_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" + +#include "CP210xManufacturingDLL.h" + +#endif // CP210x_MANUFACTURING_H diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturingDLL.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturingDLL.h new file mode 100644 index 0000000..f9da029 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/include/CP210xManufacturingDLL.h @@ -0,0 +1,865 @@ +#ifndef HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK +#define HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK + +#ifdef _WIN32 +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the CP210xDLL_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// CP210xDLL_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#ifdef CP210xDLL_EXPORTS +#define CP210xDLL_API +#else +#define CP210xDLL_API __declspec(dllimport) +#pragma comment (lib, "CP210xManufacturing.lib") +#endif +#else // !_WIN32 +#define CP210xDLL_API +#define WINAPI +#endif // !_WIN32 + +#if ! defined(_PREFAST_) +// For SAL annotations used below in this header file, for each annotation used, add a suitable "if not defined" no-op +// definition for it here so that the SAL annotations do not break builds in IDEs that do not have SAL-annotation support. +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Pre_defensive_) +#define _Pre_defensive_ +#endif // ! defined(_Pre_defensive_) +#endif // ! defined(_PREFAST_) + +// GetProductString() function flags +#define CP210x_RETURN_SERIAL_NUMBER 0x00 +#define CP210x_RETURN_DESCRIPTION 0x01 +#define CP210x_RETURN_FULL_PATH 0x02 + +// GetDeviceVersion() return codes +#define CP210x_CP2101_VERSION 0x01 +#define CP210x_CP2102_VERSION 0x02 +#define CP210x_CP2103_VERSION 0x03 +#define CP210x_CP2104_VERSION 0x04 +#define CP210x_CP2105_VERSION 0x05 +#define CP210x_CP2108_VERSION 0x08 +#define CP210x_CP2109_VERSION 0x09 +#define CP210x_CP2102N_QFN28_VERSION 0x20 +#define CP210x_CP2102N_QFN24_VERSION 0x21 +#define CP210x_CP2102N_QFN20_VERSION 0x22 + +// Return codes +#define CP210x_SUCCESS 0x00 +#define CP210x_DEVICE_NOT_FOUND 0xFF +#define CP210x_INVALID_HANDLE 0x01 +#define CP210x_INVALID_PARAMETER 0x02 +#define CP210x_DEVICE_IO_FAILED 0x03 +#define CP210x_FUNCTION_NOT_SUPPORTED 0x04 +#define CP210x_GLOBAL_DATA_ERROR 0x05 +#define CP210x_FILE_ERROR 0x06 +#define CP210x_COMMAND_FAILED 0x08 +#define CP210x_INVALID_ACCESS_TYPE 0x09 + +// Type definitions +typedef int CP210x_STATUS; + +// Buffer size limits +// +// +// CP2101/2/3/4/9 +#define CP210x_MAX_DEVICE_STRLEN 256 +#define CP210x_MAX_MANUFACTURER_STRLEN 45 + +#define CP210x_MAX_PRODUCT_STRLEN 126 +#define CP210x_MAX_SERIAL_STRLEN 63 +// +// CP2105 +#define CP2105_MAX_MANUFACTURER_STRLEN 12 +#define CP2105_MAX_PRODUCT_STRLEN 47 +#define CP2105_MAX_SERIAL_STRLEN 16 +#define CP2105_MAX_INTERFACE_STRLEN 32 +// +// CP2108 +#define CP2108_MAX_MANUFACTURER_STRLEN 126 +#define CP2108_MAX_PRODUCT_STRLEN 126 +#define CP2108_MAX_SERIAL_STRLEN 126 +#define CP2108_MAX_INTERFACE_STRLEN 126 +// +// CP2102N +#define CP2102N_MAX_ +// Type definitions +typedef char CP210x_DEVICE_STRING[CP210x_MAX_DEVICE_STRLEN]; +typedef char CP210x_MANUFACTURER_STRING[CP210x_MAX_MANUFACTURER_STRLEN]; +typedef char CP210x_PRODUCT_STRING[CP210x_MAX_PRODUCT_STRLEN]; +typedef char CP210x_SERIAL_STRING[CP210x_MAX_SERIAL_STRLEN]; +typedef char CP2105_INTERFACE_STRING[CP2105_MAX_INTERFACE_STRLEN]; +typedef char CP2108_INTERFACE_STRING[CP2108_MAX_INTERFACE_STRLEN]; + +#define CP210x_MAX_MAXPOWER 250 + + +// Baud Rate Aliasing definitions +// +#define NUM_BAUD_CONFIGS 32 +// +// Baud Config Structure +typedef struct +{ + WORD BaudGen; + WORD Timer0Reload; + BYTE Prescaler; + DWORD BaudRate; +} BAUD_CONFIG; +// +// Size of the Baud Config Structure +#define BAUD_CONFIG_SIZE 10 +// +// Array of all Baud Rate Configurations +typedef BAUD_CONFIG BAUD_CONFIG_DATA[NUM_BAUD_CONFIGS]; +// + + +// Flush Buffer definitions +// +// CP2104 +#define FC_OPEN_TX 0x01 // When these bits are set, the device will flush that buffer +#define FC_OPEN_RX 0x02 +#define FC_CLOSE_TX 0x04 +#define FC_CLOSE_RX 0x08 +// +// CP2105 - Standard Port +#define FC_OPEN_TX_SCI FC_OPEN_TX +#define FC_OPEN_RX_SCI FC_OPEN_RX +#define FC_CLOSE_TX_SCI FC_CLOSE_TX +#define FC_CLOSE_RX_SCI FC_CLOSE_RX +// +// CP2105 - Enhanced Port +#define FC_OPEN_TX_ECI 0x10 +#define FC_OPEN_RX_ECI 0x20 +#define FC_CLOSE_TX_ECI 0x40 +#define FC_CLOSE_RX_ECI 0x80 +// +// CP2108 +#define FC_OPEN_TX_IFC0 0x0001 +#define FC_OPEN_RX_IFC0 0x0002 +#define FC_CLOSE_TX_IFC0 0x0004 +#define FC_CLOSE_RX_IFC0 0x0008 +#define FC_OPEN_TX_IFC1 0x0010 +#define FC_OPEN_RX_IFC1 0x0020 +#define FC_CLOSE_TX_IFC1 0x0040 +#define FC_CLOSE_RX_IFC1 0x0080 +#define FC_OPEN_TX_IFC2 0x0100 +#define FC_OPEN_RX_IFC2 0x0200 +#define FC_CLOSE_TX_IFC2 0x0400 +#define FC_CLOSE_RX_IFC2 0x0800 +#define FC_OPEN_TX_IFC3 0x1000 +#define FC_OPEN_RX_IFC3 0x2000 +#define FC_CLOSE_TX_IFC3 0x4000 +#define FC_CLOSE_RX_IFC3 0x8000 + +// +//Port Config definitions +// + +// +// CP2103/4 Port Config Structure +// +typedef struct +{ + WORD Mode; // Push-Pull = 1, Open-Drain = 0 + WORD Reset_Latch; // Logic High = 1, Logic Low = =0 + WORD Suspend_Latch; // Logic High = 1, Logic Low = =0 + unsigned char EnhancedFxn; +} PORT_CONFIG; +// +// Define bit locations for Mode/Latch for Reset and Suspend structures +#define PORT_RI_ON 0x0001 +#define PORT_DCD_ON 0x0002 +#define PORT_DTR_ON 0x0004 +#define PORT_DSR_ON 0x0008 +#define PORT_TXD_ON 0x0010 +#define PORT_RXD_ON 0x0020 +#define PORT_RTS_ON 0x0040 +#define PORT_CTS_ON 0x0080 +// +#define PORT_GPIO_0_ON 0x0100 +#define PORT_GPIO_1_ON 0x0200 +#define PORT_GPIO_2_ON 0x0400 +#define PORT_GPIO_3_ON 0x0800 +// +#define PORT_SUSPEND_ON 0x4000 // Can't configure latch value +#define PORT_SUSPEND_BAR_ON 0x8000 // Can't configure latch value +// +// Define bit locations for EnhancedFxn +#define EF_GPIO_0_TXLED 0x01 // Under device control +#define EF_GPIO_1_RXLED 0x02 // Under device control +#define EF_GPIO_2_RS485 0x04 // Under device control +#define EF_RS485_INVERT 0x08 // RS485 Invert bit +#define EF_WEAKPULLUP 0x10 // Weak Pull-up on +#define EF_RESERVED_1 0x20 // Reserved, leave bit 5 cleared +#define EF_SERIAL_DYNAMIC_SUSPEND 0x40 // For 8 UART/Modem signals +#define EF_GPIO_DYNAMIC_SUSPEND 0x80 // For 4 GPIO signals +// + + +// +// CP2105 Dual Port Config Structure +// +typedef struct +{ + WORD Mode; // Push-Pull = 1, Open-Drain = 0 + WORD Reset_Latch; // Logic High = 1, Logic Low = =0 + WORD Suspend_Latch; // Logic High = 1, Logic Low = =0 + unsigned char EnhancedFxn_ECI; + unsigned char EnhancedFxn_SCI; + unsigned char EnhancedFxn_Device; +} DUAL_PORT_CONFIG; +// +// CP2105 Define bit locations for Mode/Latch for Reset and Suspend structures +#define PORT_RI_SCI_ON 0x0001 +#define PORT_DCD_SCI_ON 0x0002 +#define PORT_DTR_SCI_ON 0x0004 +#define PORT_DSR_SCI_ON 0x0008 +#define PORT_TXD_SCI_ON 0x0010 +#define PORT_RXD_SCI_ON 0x0020 +#define PORT_RTS_SCI_ON 0x0040 +#define PORT_CTS_SCI_ON 0x0080 +#define PORT_GPIO_0_SCI_ON 0x0002 +#define PORT_GPIO_1_SCI_ON 0x0004 +#define PORT_GPIO_2_SCI_ON 0x0008 +#define PORT_SUSPEND_SCI_ON 0x0001 // Can't configure latch value +// +#define PORT_RI_ECI_ON 0x0100 +#define PORT_DCD_ECI_ON 0x0200 +#define PORT_DTR_ECI_ON 0x0400 +#define PORT_DSR_ECI_ON 0x0800 +#define PORT_TXD_ECI_ON 0x1000 +#define PORT_RXD_ECI_ON 0x2000 +#define PORT_RTS_ECI_ON 0x4000 +#define PORT_CTS_ECI_ON 0x8000 +#define PORT_GPIO_0_ECI_ON 0x0400 +#define PORT_GPIO_1_ECI_ON 0x0800 +#define PORT_SUSPEND_ECI_ON 0x0100 // Can't configure latch value +// +// CP2105 Define bit locations for EnhancedFxn_ECI +#define EF_GPIO_0_TXLED_ECI 0x01 // Under device control +#define EF_GPIO_1_RXLED_ECI 0x02 // Under device control +#define EF_GPIO_1_RS485_ECI 0x04 // Under device control +#define EF_RS485_INVERT 0x08 // Under device control +#define EF_INVERT_SUSPEND_ECI 0x10 // RS485 Invert bit +#define EF_DYNAMIC_SUSPEND_ECI 0x40 // For GPIO signals +// +// CP2105 Define bit locations for EnhancedFxn_SCI +#define EF_GPIO_0_TXLED_SCI 0x01 // Under device control +#define EF_GPIO_1_RXLED_SCI 0x02 // Under device control +#define EF_INVERT_SUSPEND_SCI 0x10 // RS485 Invert bit +#define EF_DYNAMIC_SUSPEND_SCI 0x40 // For GPIO signals +// +// CP2105 Define bit locations for EnhancedFxn_Device +#define EF_WEAKPULLUP 0x10 // Weak Pull-up on +// + +// +// CP2108 Quad Port Config Structure +// +typedef struct +{ + WORD Mode_PB0; + WORD Mode_PB1; + WORD Mode_PB2; + WORD Mode_PB3; + WORD Mode_PB4; + + WORD LowPower_PB0; + WORD LowPower_PB1; + WORD LowPower_PB2; + WORD LowPower_PB3; + WORD LowPower_PB4; + + WORD Latch_PB0; + WORD Latch_PB1; + WORD Latch_PB2; + WORD Latch_PB3; + WORD Latch_PB4; +} QUAD_PORT_STATE; + +typedef struct +{ + QUAD_PORT_STATE Reset_Latch; + QUAD_PORT_STATE Suspend_Latch; + BYTE IPDelay_IFC0; + BYTE IPDelay_IFC1; + BYTE IPDelay_IFC2; + BYTE IPDelay_IFC3; + BYTE EnhancedFxn_IFC0; + BYTE EnhancedFxn_IFC1; + BYTE EnhancedFxn_IFC2; + BYTE EnhancedFxn_IFC3; + BYTE EnhancedFxn_Device; + BYTE ExtClk0Freq; + BYTE ExtClk1Freq; + BYTE ExtClk2Freq; + BYTE ExtClk3Freq; +} QUAD_PORT_CONFIG; + +// +// CP2108 Define bit locations for Mode/Latch for Reset and Suspend structures +// PB0 +#define PORT_TX0 0x0001 +#define PORT_RX0 0x0002 +#define PORT_RTS0 0x0004 +#define PORT_CTS0 0x0008 +#define PORT_DTR0 0x0010 +#define PORT_DSR0 0x0020 +#define PORT_DCD0 0x0040 +#define PORT_RI0 0x0080 +#define PORT_TX1 0x0100 +#define PORT_RX1 0x0200 +#define PORT_RTS1 0x0400 +#define PORT_CTS1 0x0800 +#define PORT_DTR1 0x1000 +#define PORT_DSR1 0x2000 +#define PORT_DCD1 0x4000 +#define PORT_RI1 0x8000 + +// PB1 +#define PORT_GPIO_0 0x0001 // (1<<0) +#define PORT_GPIO_1 0x0002 // (1<<1) +#define PORT_GPIO_2 0x0004 // (1<<2) +#define PORT_GPIO_3 0x0008 // etc. +#define PORT_GPIO_4 0x0010 +#define PORT_GPIO_5 0x0020 +#define PORT_GPIO_6 0x0040 +#define PORT_GPIO_7 0x0080 +#define PORT_GPIO_8 0x0100 +#define PORT_GPIO_9 0x0200 +#define PORT_GPIO_10 0x0400 +#define PORT_GPIO_11 0x0800 +#define PORT_GPIO_12 0x1000 +#define PORT_GPIO_13 0x2000 +#define PORT_GPIO_14 0x4000 +#define PORT_GPIO_15 0x8000 + +// PB2 +#define PORT_SUSPEND 0x0001 +#define PORT_SUSPEND_BAR 0x0002 +#define PORT_DTR2 0x0004 +#define PORT_DSR2 0x0008 + +// PB3 +#define PORT_TX2 0x0001 +#define PORT_RX2 0x0002 +#define PORT_RTS2 0x0004 +#define PORT_CTS2 0x0008 +#define PORT_DCD2 0x0010 +#define PORT_RI2 0x0020 +#define PORT_DTR3 0x0040 +#define PORT_DSR3 0x0080 +#define PORT_DCD3 0x0100 +#define PORT_RI3 0x0200 + +// PB4 +#define PORT_RTS3 0x0001 +#define PORT_CTS3 0x0002 +#define PORT_TX3 0x0004 +#define PORT_RX3 0x0008 + +// +// CP2108 Define bit locations for EnhancedFxn_IFCx +#define EF_IFC_GPIO_TXLED 0x01 +#define EF_IFC_GPIO_RXLED 0x02 +#define EF_IFC_GPIO_RS485 0x04 +// If the next bit is clear, GPIO1 is low while sending UART data. +// If it is set, GPIO1 is high while sending UART data, and low otherwise +#define EF_IFC_GPIO_RS485_LOGIC 0x08 +#define EF_IFC_GPIO_CLOCK 0x10 +#define EF_IFC_DYNAMIC_SUSPEND 0x40 + +// +// CP2108 Define bit locations for EnhancedFxn_Device +#define EF_DEVICE_WEAKPULLUP_RESET 0x10 +#define EF_DEVICE_WEAKPULLUP_SUSPEND 0x20 +#define EF_DEVICE_DYNAMIC_SUSPEND 0x40 +// +typedef unsigned char uint8_t; +// Firmware version structure. Not writeable by OEMs or end-users. +// Automatically populated by build infrastructure +typedef struct { + uint8_t major; + uint8_t minor; + uint8_t build; +} firmware_t, *pFirmware_t; + +#ifdef __cplusplus +extern "C" { +#endif + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetNumDevices( + _Out_writes_bytes_(4) _Pre_defensive_ LPDWORD lpdwNumDevices + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetProductString( + _In_ _Pre_defensive_ const DWORD dwDeviceNum, + LPVOID lpvDeviceString, + _In_ _Pre_defensive_ const DWORD dwFlags + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_Open( + _In_ _Pre_defensive_ DWORD dwDevice, + HANDLE* cyHandle + ); + +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_Close( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetPartNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(1) LPBYTE lpbPartNum + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetVid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wVid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetPid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wPid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetManufacturerString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvManufacturer, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetProductString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvProduct, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetInterfaceString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bInterfaceNumber, + _In_ _Pre_defensive_ LPVOID lpvInterface, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode + ); + +/// @brief Reprogram the Serial Number String in the device's USB Serial Number String Descriptor +/// @param cyHandle is an open handle to the device +/// @param lpvSerialNumber points at a buffer containing the Serial Number String to be reprogrammed to the device +/// @param bLength is the total number of characters in the Serial Number String +/// @param bConvertToUnicode is a true or false value indicating whether the Serial Number String is an 8-bit character ascii string needing converting to 16-bit UCS-2 characters (true) to not (false). +/// @note OTP parts can not often/indefinitely have configuration data (re-)written to them +/// @returns Returns CP210x_SUCCESS on success, another CP210x_STATUS if there is an error: +/// CP210x_INVALID_HANDLE -- cyHandle is invalid +/// CP210x_INVALID_PARAMETER -- lpvSerialNumber or bLength are unexpected values +/// CP210x_FUNCTION_NOT_SUPPORTED -- the device does not support setting of the Serial Number string +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetSerialNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvSerialNumber, + _In_ _Pre_defensive_ const BYTE bLengthInChars, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetSelfPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BOOL bSelfPower + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetMaxPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bMaxPower + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetFlushBufferConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wFlushBufferConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDeviceMode( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bDeviceModeECI, + _In_ _Pre_defensive_ const BYTE bDeviceModeSCI + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDeviceVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wVersion + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetBaudRateConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ BAUD_CONFIG* baudConfigData + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ PORT_CONFIG* PortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDualPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ DUAL_PORT_CONFIG* DualPortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetQuadPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ QUAD_PORT_CONFIG* QuadPortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetLockValue( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceVid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(2) LPWORD lpwVid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDevicePid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(2) LPWORD lpwPid + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceManufacturerString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpManufacturer, + LPBYTE lpbLength, + _In_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceProductString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpProduct, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceInterfaceString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bInterfaceNumber, + LPVOID lpInterface, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceSerialNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpSerialNumber, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetSelfPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBOOL lpbSelfPower + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetMaxPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbPower + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetFlushBufferConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPWORD lpwFlushBufferConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceMode( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbDeviceModeECI, + LPBYTE lpbDeviceModeSCI + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPWORD lpwVersion + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetBaudRateConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + BAUD_CONFIG* pBaudConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + PORT_CONFIG* pPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDualPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + DUAL_PORT_CONFIG* pDualPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetQuadPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + QUAD_PORT_CONFIG* pQuadPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetLockValue( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbLockValue + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_Reset( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_CreateHexFile( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPCSTR lpvFileName + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetFirmwareVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + pFirmware_t lpVersion + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbConfig, + WORD bLength + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPBYTE lpbConfig, + _In_ _Pre_defensive_ const WORD bLength + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_UpdateFirmware( + _In_ _Pre_defensive_ const HANDLE cyHandle); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetGeneric( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbGeneric, + _In_ _Pre_defensive_ const WORD bLength + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetGeneric( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbGeneric, + _In_ _Pre_defensive_ const WORD bLength + ); + +#ifdef __cplusplus +} +#endif + +#endif // !HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.cpp new file mode 100644 index 0000000..1110f2a --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.cpp @@ -0,0 +1,92 @@ +/* + * CP2101Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2101Device.h" +#include "CP210xSupportFunctions.h" + +CCP2101Device::CCP2101Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x01; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2101Device::GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::GetLockValue(LPBYTE lpbLockValue) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetManufacturerString(LPVOID lpvManufacturer, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2101Device::SetLockValue() { + return CP210x_FUNCTION_NOT_SUPPORTED; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.h new file mode 100644 index 0000000..3b50380 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2101Device.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////// +// CP2101Device.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CP2101_DEVICE_H +#define CP2101_DEVICE_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2101Device : public CCP210xDevice { + // Public Methods +public: + + CCP2101Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE lpbLength, BOOL bConvertToASCII = true); + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetManufacturerString(LPVOID lpvManufacturer, BYTE bLength, BOOL bConvertToUnicode = true); + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + +#endif diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.cpp new file mode 100644 index 0000000..23f7c77 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.cpp @@ -0,0 +1,165 @@ +/* + * CP2102Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2102Device.h" +#include "CP210xSupportFunctions.h" + +CCP2102Device::CCP2102Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x02; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2102Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x3709, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + BAUD_CONFIG* currentBaudConfig; + currentBaudConfig = baudConfigData; + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + currentBaudConfig->BaudGen = (setup[i] << 8) + setup[i + 1]; + currentBaudConfig->Timer0Reload = (setup[i + 2] << 8) + setup[i + 3]; + currentBaudConfig->Prescaler = setup[i + 4]; + //setup[i+5] reserved for later use + currentBaudConfig->BaudRate = setup[i + 6] + (setup[i + 7] << 8) + (setup[i + 8] << 16) + (setup[i + 9] << 24); + + currentBaudConfig++; + } + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2102Device::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2102Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BAUD_CONFIG* currentBaudConfig; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + currentBaudConfig = baudConfigData; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + setup[i] = (currentBaudConfig->BaudGen & 0xFF00) >> 8; + setup[i + 1] = currentBaudConfig->BaudGen & 0x00FF; + setup[i + 2] = (currentBaudConfig->Timer0Reload & 0xFF00) >> 8; + setup[i + 3] = currentBaudConfig->Timer0Reload & 0x00FF; + setup[i + 4] = currentBaudConfig->Prescaler; + setup[i + 5] = 0x00; //reserved for later + setup[i + 6] = (BYTE) (currentBaudConfig->BaudRate & 0x000000FF); + setup[i + 7] = (BYTE) ((currentBaudConfig->BaudRate & 0x0000FF00) >> 8); + setup[i + 8] = (BYTE) ((currentBaudConfig->BaudRate & 0x00FF0000) >> 16); + setup[i + 9] = (BYTE) ((currentBaudConfig->BaudRate & 0xFF000000) >> 24); + + currentBaudConfig++; + } + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3709, 0, setup, transferSize + 2, 0) == transferSize + 2) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2102Device::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.h new file mode 100644 index 0000000..330e75b --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102Device.h @@ -0,0 +1,52 @@ +/* + * CP2102Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2102DEVICE_H_ +#define CP2102DEVICE_H_ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2102Device : public CCP210xDevice { + // Public Methods +public: + + CCP2102Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + + +#endif /* CP2102DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.cpp new file mode 100644 index 0000000..49c4959 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.cpp @@ -0,0 +1,328 @@ +/* + * CP2102NDevice.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2102NDevice.h" +#include "CP210xSupportFunctions.h" + +CCP2102NDevice::CCP2102NDevice(libusb_device_handle* h, BYTE partNum) { + m_handle = h; + m_partNumber = partNum; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2102NDevice::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetLockValue(LPBYTE lpbLockValue) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetFlushBufferConfig(WORD wFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::SetLockValue() { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2102NDevice::GetFirmwareVersion( pFirmware_t lpVersion) +{ + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, + 0xC0, // bmRequestType + 0xFF, // bRequest + 0x10, // wValue + 0, // WIndex + setup, // data + 3, // data size + 0) == 3) + { + lpVersion->major = setup[0]; + lpVersion->minor = setup[1]; + lpVersion->build = setup[2]; + status = CP210x_SUCCESS; + } + else + { + lpVersion->major = 0x0; + lpVersion->minor = 0x0; + lpVersion->build = 0x0; + status = CP210x_DEVICE_IO_FAILED; + } + return status; +} + +CP210x_STATUS CCP2102NDevice::GetConfig( LPBYTE lpbConfig, WORD bLength) +{ + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + // 8 bytes are taken by setup packet, rest of buffer can be config data + if (bLength > (CP210x_MAX_SETUP_LENGTH-8)) + { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_control_transfer(m_handle, + 0xC0, + 0xFF, + 0xe, // wValue + 0, // WIndex + setup, // data + bLength, // data size + 0) == bLength) + { + memcpy((BYTE*)lpbConfig, (BYTE*)&(setup[ 0]), bLength); + status = CP210x_SUCCESS; + } + else + { + status = CP210x_DEVICE_IO_FAILED; + } + return status; +} + +CP210x_STATUS CCP2102NDevice::SetConfig(LPBYTE lpbConfig, WORD bLength) +{ + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // 8 bytes are taken by setup packet, rest of buffer can be config data + if (bLength > (CP210x_MAX_SETUP_LENGTH-8)) + { + return CP210x_INVALID_PARAMETER; + } + + memcpy( (BYTE*)&(setup[0]), (BYTE*) lpbConfig, bLength); + + if (libusb_control_transfer(m_handle, + 0x40, + 0xFF, + 0x370F, // wValue + 0, // WIndex + setup, // data + bLength, // data size + 0) == bLength) + { + status = CP210x_SUCCESS; + } + else + { + status = CP210x_DEVICE_IO_FAILED; + } + return status; +} + +CP210x_STATUS CCP2102NDevice::UpdateFirmware() +{ + (void) libusb_control_transfer(m_handle, + 0x40, + 0xFF, + 0x37FF, // wValue + 0, // WIndex + NULL, // data + 0, // data size + 0); + + // SendSetup will always fail because the device + // will get reset - so the USB request doesn't get completed + // properly. Because of this we will always return success + return CP210x_SUCCESS; +} + +CP210x_STATUS CCP2102NDevice::GetGeneric( LPBYTE lpbGeneric, WORD bLength) +{ + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE data[CP210x_MAX_SETUP_LENGTH]; + + if (bLength > (CP210x_MAX_SETUP_LENGTH)) + { + return CP210x_INVALID_PARAMETER; + } + if (bLength < 8) + { + return CP210x_INVALID_PARAMETER; + } + uint8_t bmRequestType = lpbGeneric[ 0]; + uint8_t bRequest = lpbGeneric[ 1]; + uint16_t wValue = lpbGeneric[ 2] | (lpbGeneric[ 3] << 8); + uint16_t wIndex = lpbGeneric[ 4] | (lpbGeneric[ 5] << 8); + uint16_t wLength = bLength - 8; + + memcpy((BYTE*)&data[0], (BYTE*)lpbGeneric + 8, wLength); + + if (libusb_control_transfer(m_handle, + bmRequestType, + bRequest, + wValue, + wIndex, + data, // data + wLength, // data size + 0) == wLength) + { + memcpy((BYTE*)lpbGeneric + 8, (BYTE*)&(data[0]), wLength); + status = CP210x_SUCCESS; + } + else + { + status = CP210x_DEVICE_IO_FAILED; + } + return status; +} + +CP210x_STATUS CCP2102NDevice::SetGeneric( LPBYTE lpbGeneric, WORD bLength) +{ + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE data[CP210x_MAX_SETUP_LENGTH]; + + if (bLength > (CP210x_MAX_SETUP_LENGTH)) + { + return CP210x_INVALID_PARAMETER; + } + if (bLength < 8) + { + return CP210x_INVALID_PARAMETER; + } + uint8_t bmRequestType = lpbGeneric[ 0]; + uint8_t bRequest = lpbGeneric[ 1]; + uint16_t wValue = lpbGeneric[ 2] | (lpbGeneric[ 3] << 8); + uint16_t wIndex = lpbGeneric[ 4] | (lpbGeneric[ 5] << 8); + uint16_t wLength = bLength - 8; + + memcpy((BYTE*)&data[0], (BYTE*)lpbGeneric + 8, wLength); + + if (libusb_control_transfer(m_handle, + bmRequestType, + bRequest, + wValue, + wIndex, + data, // data + wLength, // data size + 0) == wLength) + { + status = CP210x_SUCCESS; + } + else + { + status = CP210x_DEVICE_IO_FAILED; + } + return status; +} + +#if 0 +//=================================================================== +CP210x_GetBaudRateConfig( const HANDLE cyHandle, BAUD_CONFIG* baudConfigData) +{ + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + DWORD dwBytesSent = 0; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + setup[0] = 0xC0; // p1 // read + setup[1] = 0xFF; // p2 // + setup[2] = 0x09; // p3L // get baud rate command + setup[3] = 0x37; // p3H // always 0x37 + setup[4] = 0x00; // + setup[5] = 0x00; // + setup[6] = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE) & 0x00FF; // Descriptor length, low byte, only want the first 2 bytes (0x03 and length) + setup[7] = ((NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE) & 0xFF00) >> 8; // Descriptor length, high byte + + status = GetSetup(cyHandle, setup, (8 + (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE)), &dwBytesSent); + if (status == CP210x_SUCCESS) + { + BAUD_CONFIG* currentBaudConfig; + currentBaudConfig = baudConfigData; + + for (DWORD i = 8; i < dwBytesSent; i += BAUD_CONFIG_SIZE) + { + currentBaudConfig->BaudGen = (setup[i] << 8) + setup[i+1]; + currentBaudConfig++; +GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, + 0xC0, + 0xFF, + 0x3709, // wValue + 0, // WIndex + setup, // data + transferSize, // size + 0) == transferSize) + { + status = CP210x_SUCCESS; + BAUD_CONFIG* currentBaudConfig; + currentBaudConfig = baudConfigData; + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + currentBaudConfig->BaudGen = (setup[i] << 8) + setup[i + 1]; + currentBaudConfig++; +} +//=================================================================== +#endif diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.h new file mode 100644 index 0000000..65ef64c --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2102NDevice.h @@ -0,0 +1,58 @@ +/* + * CP2102Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2102NDEVICE_H_ +#define CP2102NDEVICE_H_ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2102NDevice : public CCP210xDevice { + // Public Methods +public: + + CCP2102NDevice(libusb_device_handle* h, BYTE partNum); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + + virtual CP210x_STATUS GetFirmwareVersion( pFirmware_t lpVersion); + virtual CP210x_STATUS GetConfig( LPBYTE lpbConfig, WORD bLength); + virtual CP210x_STATUS SetConfig(LPBYTE lpbConfig, WORD bLength); + virtual CP210x_STATUS UpdateFirmware(); + virtual CP210x_STATUS GetGeneric( LPBYTE lpbGeneric, WORD bLength); + virtual CP210x_STATUS SetGeneric( LPBYTE lpbGeneric, WORD bLength); +}; + + + +#endif /* CP2102NDEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.cpp new file mode 100644 index 0000000..ff082b6 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.cpp @@ -0,0 +1,224 @@ +/* + * CP2103Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2103Device.h" +#include "CP210xSupportFunctions.h" + +CCP2103Device::CCP2103Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x03; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2103Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x3709, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + BAUD_CONFIG* currentBaudConfig; + currentBaudConfig = baudConfigData; + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + currentBaudConfig->BaudGen = (setup[i] << 8) + setup[i + 1]; + currentBaudConfig->Timer0Reload = (setup[i + 2] << 8) + setup[i + 3]; + currentBaudConfig->Prescaler = setup[i + 4]; + //setup[i+5] reserved for later use + currentBaudConfig->BaudRate = setup[i + 6] + (setup[i + 7] << 8) + (setup[i + 8] << 16) + (setup[i + 9] << 24); + + currentBaudConfig++; + } + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2103Device::GetPortConfig(PORT_CONFIG* PortConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = 13; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + PortConfig->Mode = (setup[0] << 8) + setup[1]; + //PortConfig->Reset.LowPower = (setup[10] << 8) + setup[11]; + PortConfig->Reset_Latch = (setup[4] << 8) + setup[5]; + //PortConfig->Suspend.Mode = (setup[14] << 8) + setup[15]; + //PortConfig->Suspend.LowPower = (setup[16] << 8) + setup[17]; + PortConfig->Suspend_Latch = (setup[10] << 8) + setup[11]; + PortConfig->EnhancedFxn = setup[12]; + + // Mask out reserved bits in EnhancedFxn + PortConfig->EnhancedFxn &= ~(EF_SERIAL_DYNAMIC_SUSPEND | EF_RESERVED_1); + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2103Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2103Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BAUD_CONFIG* currentBaudConfig; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + currentBaudConfig = baudConfigData; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + setup[i] = (currentBaudConfig->BaudGen & 0xFF00) >> 8; + setup[i + 1] = currentBaudConfig->BaudGen & 0x00FF; + setup[i + 2] = (currentBaudConfig->Timer0Reload & 0xFF00) >> 8; + setup[i + 3] = currentBaudConfig->Timer0Reload & 0x00FF; + setup[i + 4] = currentBaudConfig->Prescaler; + setup[i + 5] = 0x00; //reserved for later + setup[i + 6] = (BYTE) (currentBaudConfig->BaudRate & 0x000000FF); + setup[i + 7] = (BYTE) ((currentBaudConfig->BaudRate & 0x0000FF00) >> 8); + setup[i + 8] = (BYTE) ((currentBaudConfig->BaudRate & 0x00FF0000) >> 16); + setup[i + 9] = (BYTE) ((currentBaudConfig->BaudRate & 0xFF000000) >> 24); + + currentBaudConfig++; + } + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3709, 0, setup, transferSize + 2, 0) == transferSize + 2) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2103Device::SetPortConfig(PORT_CONFIG* PortConfig) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE Temp_EnhancedFxn; + int transferSize = 13; + + // Change user Port_Config structure to match firmware, and check reserved bits are zero + if (PortConfig->EnhancedFxn & (EF_SERIAL_DYNAMIC_SUSPEND | EF_RESERVED_1)) + return CP210x_INVALID_PARAMETER; + + Temp_EnhancedFxn = PortConfig->EnhancedFxn; // save user settings into temp variable to send out + + if (Temp_EnhancedFxn & EF_WEAKPULLUP) { + Temp_EnhancedFxn |= 0x30; // Set both Weak Pullup bits + } else { + Temp_EnhancedFxn &= ~0x30; // Clear both Weak Pullup bits + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + setup[0] = (PortConfig->Mode & 0xFF00) >> 8; + setup[1] = (PortConfig->Mode & 0x00FF); + setup[2] = 0x00; //(PortConfig->Reset.LowPower & 0xFF00) >> 8; + setup[3] = 0x00; //(PortConfig->Reset.LowPower & 0x00FF); + setup[4] = (PortConfig->Reset_Latch & 0xFF00) >> 8; + setup[5] = (PortConfig->Reset_Latch & 0x00FF); + setup[6] = (PortConfig->Mode & 0xFF00) >> 8; + setup[7] = (PortConfig->Mode & 0x00FF); + setup[8] = 0x00; //(PortConfig->Suspend.LowPower & 0xFF00) >> 8; + setup[9] = 0x00; //(PortConfig->Suspend.LowPower & 0x00FF); + setup[10] = (PortConfig->Suspend_Latch & 0xFF00) >> 8; + setup[11] = (PortConfig->Suspend_Latch & 0x00FF); + setup[12] = Temp_EnhancedFxn; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2103Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2103Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.h new file mode 100644 index 0000000..a7756e9 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2103Device.h @@ -0,0 +1,52 @@ +/* + * CP2103Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2103DEVICE_H_ +#define CP2103DEVICE_H_ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2103Device : public CCP210xDevice { + // Public Methods +public: + + CCP2103Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + + +#endif /* CP2103DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.cpp new file mode 100644 index 0000000..e9210b3 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.cpp @@ -0,0 +1,198 @@ +/* + * CP2104Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2104Device.h" +#include "CP210xSupportFunctions.h" + +CCP2104Device::CCP2104Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x04; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2104Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpwFlushBufferConfig)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370D, 0, setup, 1, 0) == 1) { + *lpwFlushBufferConfig = setup[0]; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2104Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::GetPortConfig(PORT_CONFIG* PortConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = 13; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + PortConfig->Mode = (setup[0] << 8) + setup[1]; + //PortConfig->Reset.LowPower = (setup[10] << 8) + setup[11]; + PortConfig->Reset_Latch = (setup[4] << 8) + setup[5]; + //PortConfig->Suspend.Mode = (setup[14] << 8) + setup[15]; + //PortConfig->Suspend.LowPower = (setup[16] << 8) + setup[17]; + PortConfig->Suspend_Latch = (setup[10] << 8) + setup[11]; + PortConfig->EnhancedFxn = setup[12]; + + // Mask out reserved bits in EnhancedFxn + PortConfig->EnhancedFxn &= ~(EF_SERIAL_DYNAMIC_SUSPEND | EF_RESERVED_1); + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2104Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2104Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370D, wFlushBufferConfig, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2104Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::SetPortConfig(PORT_CONFIG* PortConfig) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE Temp_EnhancedFxn; + int transferSize = 13; + + // Change user Port_Config structure to match firmware, and check reserved bits are zero + if (PortConfig->EnhancedFxn & (EF_SERIAL_DYNAMIC_SUSPEND | EF_RESERVED_1)) + return CP210x_INVALID_PARAMETER; + + Temp_EnhancedFxn = PortConfig->EnhancedFxn; // save user settings into temp variable to send out + + if (Temp_EnhancedFxn & EF_WEAKPULLUP) { + Temp_EnhancedFxn |= 0x30; // Set both Weak Pullup bits + } else { + Temp_EnhancedFxn &= ~0x30; // Clear both Weak Pullup bits + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + setup[0] = (PortConfig->Mode & 0xFF00) >> 8; + setup[1] = (PortConfig->Mode & 0x00FF); + setup[2] = 0x00; //(PortConfig->Reset.LowPower & 0xFF00) >> 8; + setup[3] = 0x00; //(PortConfig->Reset.LowPower & 0x00FF); + setup[4] = (PortConfig->Reset_Latch & 0xFF00) >> 8; + setup[5] = (PortConfig->Reset_Latch & 0x00FF); + setup[6] = (PortConfig->Mode & 0xFF00) >> 8; + setup[7] = (PortConfig->Mode & 0x00FF); + setup[8] = 0x00; //(PortConfig->Suspend.LowPower & 0xFF00) >> 8; + setup[9] = 0x00; //(PortConfig->Suspend.LowPower & 0x00FF); + setup[10] = (PortConfig->Suspend_Latch & 0xFF00) >> 8; + setup[11] = (PortConfig->Suspend_Latch & 0x00FF); + setup[12] = Temp_EnhancedFxn; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2104Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2104Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.h new file mode 100644 index 0000000..5eaeefd --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2104Device.h @@ -0,0 +1,52 @@ +/* + * CP2104Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2104DEVICE_H_ +#define CP2104DEVICE_H_ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2104Device : public CCP210xDevice { + // Public Methods +public: + + CCP2104Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + + +#endif /* CP2104DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.cpp new file mode 100644 index 0000000..7b9a138 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.cpp @@ -0,0 +1,320 @@ +/* + * CP2105Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2105Device.h" +#include "CP210xSupportFunctions.h" + +CCP2105Device::CCP2105Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x05; + maxSerialStrLen = CP2105_MAX_SERIAL_STRLEN; + maxProductStrLen = CP2105_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2105Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE pCchStr, BOOL bConvertToASCII) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + int length; + int index; + + // Validate parameter + if (!ValidParam(lpInterface, pCchStr)) { + return CP210x_INVALID_PARAMETER; + } + + if ((bInterfaceNumber != 0x00) && + (bInterfaceNumber != 0x01)) { + return CP210x_INVALID_PARAMETER; + } + + // We will only be obtaining interface strings from CP2105 and they are in + // string 3 and 4, so we will simply add our interface index (0 or 1) to determine + // which one we want from the interface + index = 3 + bInterfaceNumber; + + if (bConvertToASCII) { + length = libusb_get_string_descriptor_ascii(m_handle, index, (unsigned char*) lpInterface, CP210x_MAX_DEVICE_STRLEN); + if (length > 0) { + *pCchStr = (BYTE) (length & 0xFF); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = GetUnicodeString( index, (LPBYTE) lpInterface, CP210x_MAX_DEVICE_STRLEN, pCchStr); + } + + return status; +} + +CP210x_STATUS CCP2105Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpwFlushBufferConfig)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370D, 0, setup, 1, 0) == 1) { + *lpwFlushBufferConfig = setup[0]; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = 2; + + // Validate parameter + if (!ValidParam(lpbDeviceModeECI)) { + return CP210x_INVALID_PARAMETER; + } + + // Validate parameter + if (!ValidParam(lpbDeviceModeSCI)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x3711, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + *lpbDeviceModeECI = setup[0]; + *lpbDeviceModeSCI = setup[1]; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; + +} + +CP210x_STATUS CCP2105Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = 15; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + DualPortConfig->Mode = (setup[0] << 8) + setup[1]; + //PortConfig->Reset.LowPower = (setup[10] << 8) + setup[11]; + DualPortConfig->Reset_Latch = (setup[4] << 8) + setup[5]; + //PortConfig->Suspend.Mode = (setup[14] << 8) + setup[15]; + //PortConfig->Suspend.LowPower = (setup[16] << 8) + setup[17]; + DualPortConfig->Suspend_Latch = (setup[10] << 8) + setup[11]; + DualPortConfig->EnhancedFxn_SCI = setup[12]; + DualPortConfig->EnhancedFxn_ECI = setup[13]; + DualPortConfig->EnhancedFxn_Device = setup[14]; + + // Mask out reserved bits in EnhancedFxn + //DualPortConfig->EnhancedFxnECI &= ~EF_DYNAMIC_SUSPEND_ECI; + //DualPortConfig->EnhancedFxnSCI &= ~EF_DYNAMIC_SUSPEND_SCI; + DualPortConfig->EnhancedFxn_Device &= ~EF_RESERVED_1; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE length = bLength; + int transferSize; + + // Validate parameter + if (!ValidParam(lpvInterface)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if ((bLength > CP2105_MAX_INTERFACE_STRLEN) || (bLength < 1)) { + return CP210x_INVALID_PARAMETER; + } + + if (((bInterfaceNumber == 0x00) || + (bInterfaceNumber == 0x01))) { + BYTE bSetupCmd = 0x00; + // Copy string will alter the length if the string has to be converted to unicode. + CopyToString(setup, lpvInterface, &length, bConvertToUnicode); + + if (bInterfaceNumber == 0x00) { + bSetupCmd = 0x0F; // Set Interface 0 String command + } + if (bInterfaceNumber == 0x01) { + bSetupCmd = 0x10; // Set Interface 1 String command + } + + transferSize = length + 2; + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3700 | bSetupCmd, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = CP210x_INVALID_PARAMETER; + } + + return status; +} + +CP210x_STATUS CCP2105Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370D, wFlushBufferConfig, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = 4; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + setup[0] = bDeviceModeECI; + setup[1] = bDeviceModeSCI; + setup[2] = 0; + setup[3] = 0; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3711, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE Temp_EnhancedFxn_ECI, Temp_EnhancedFxn_SCI, Temp_EnhancedFxn_Device; + int transferSize = 15; + + // Change user Port_Config structure to match firmware, and check reserved bits are zero + if ((DualPortConfig->EnhancedFxn_Device & EF_RESERVED_1) /*|| + (DualPortConfig->EnhancedFxn_ECI & EF_DYNAMIC_SUSPEND_ECI) || + (DualPortConfig->EnhancedFxn_SCI & EF_DYNAMIC_SUSPEND_SCI)*/) + return CP210x_INVALID_PARAMETER; + + Temp_EnhancedFxn_ECI = DualPortConfig->EnhancedFxn_ECI; // save user settings into temp variable to send out + Temp_EnhancedFxn_SCI = DualPortConfig->EnhancedFxn_SCI; + Temp_EnhancedFxn_Device = DualPortConfig->EnhancedFxn_Device; + + if (Temp_EnhancedFxn_Device & EF_WEAKPULLUP) { + Temp_EnhancedFxn_Device |= 0x30; // Set both Weak Pullup bits + } else { + Temp_EnhancedFxn_Device &= ~0x30; // Clear both Weak Pullup bits + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + setup[0] = (DualPortConfig->Mode & 0xFF00) >> 8; + setup[1] = (DualPortConfig->Mode & 0x00FF); + setup[2] = 0x00; + setup[3] = 0x00; + setup[4] = (DualPortConfig->Reset_Latch & 0xFF00) >> 8; + setup[5] = (DualPortConfig->Reset_Latch & 0x00FF); + setup[6] = (DualPortConfig->Mode & 0xFF00) >> 8; + setup[7] = (DualPortConfig->Mode & 0x00FF); + setup[8] = 0x00; + setup[9] = 0x00; + setup[10] = (DualPortConfig->Suspend_Latch & 0xFF00) >> 8; + setup[11] = (DualPortConfig->Suspend_Latch & 0x00FF); + setup[12] = Temp_EnhancedFxn_SCI; + setup[13] = Temp_EnhancedFxn_ECI; + setup[14] = Temp_EnhancedFxn_Device; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370C, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2105Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2105Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.h new file mode 100644 index 0000000..fc511f2 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2105Device.h @@ -0,0 +1,52 @@ +/* + * CP2105Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2105DEVICE_H_ +#define CP2105DEVICE_H_ + + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2105Device : public CCP210xDevice { + // Public Methods +public: + + CCP2105Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + +#endif /* CP2105DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.cpp new file mode 100644 index 0000000..d347e02 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.cpp @@ -0,0 +1,232 @@ +/* + * CP2108Device.cpp + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2108Device.h" +#include "CP210xSupportFunctions.h" + +CCP2108Device::CCP2108Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x08; + maxSerialStrLen = CP2108_MAX_SERIAL_STRLEN; + maxProductStrLen = CP2108_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2108Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE pCchStr, BOOL bConvertToASCII) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + int length; + int index; + + // Validate parameter + if (!ValidParam(lpInterface, pCchStr)) { + return CP210x_INVALID_PARAMETER; + } + + if ((bInterfaceNumber != 0x00) && + (bInterfaceNumber != 0x01) && + (bInterfaceNumber != 0x02) && + (bInterfaceNumber != 0x03)) { + return CP210x_INVALID_PARAMETER; + } + + // We will only be obtaining interface strings from CP2108 and they are in + // string 3 4 5and 6, so we will simply add our interface index (0 or 1) to determine + // which one we want from the interface + index = 3 + bInterfaceNumber; + + if (bConvertToASCII) { + length = libusb_get_string_descriptor_ascii(m_handle, index, (unsigned char*) lpInterface, CP210x_MAX_DEVICE_STRLEN); + if (length > 0) { + *pCchStr = (BYTE) (length & 0xFF); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = GetUnicodeString( index, (LPBYTE) lpInterface, CP210x_MAX_DEVICE_STRLEN, pCchStr); + } + + return status; +} + +CP210x_STATUS CCP2108Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpwFlushBufferConfig)) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370D, 0, setup, 2, 0) == 2) { + *lpwFlushBufferConfig = setup[0] | (setup[1] << 8); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2108Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + int transferSize = 73; + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370C, 0, (BYTE*) QuadPortConfig, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2108Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2108Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE length = bLength; + int transferSize; + + // Validate parameter + if (!ValidParam(lpvInterface)) { + return CP210x_INVALID_PARAMETER; + } + + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if ((bLength > CP2108_MAX_INTERFACE_STRLEN) || (bLength < 1)) { + return CP210x_INVALID_PARAMETER; + } + + if (((bInterfaceNumber == 0x00) || + (bInterfaceNumber == 0x01) || + (bInterfaceNumber == 0x02) || + (bInterfaceNumber == 0x03))) { + BYTE bSetupCmd = 0x00; + // Copy string will alter the length if the string has to be converted to unicode. + CopyToString(setup, lpvInterface, &length, bConvertToUnicode); + + if (bInterfaceNumber == 0x00) { + bSetupCmd = 0x0F; // Set Interface 0 String command + } + if (bInterfaceNumber == 0x01) { + bSetupCmd = 0x10; // Set Interface 1 String command + } + if (bInterfaceNumber == 0x02) { + bSetupCmd = 0x12; // Set Interface 2 String command + } + if (bInterfaceNumber == 0x03) { + bSetupCmd = 0x13; // Set Interface 3 String command + } + + transferSize = length + 2; + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3700 | bSetupCmd, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = CP210x_INVALID_PARAMETER; + } + + return status; +} + +CP210x_STATUS CCP2108Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370D, wFlushBufferConfig, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2108Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2108Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + int transferSize = 73; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370C, 0, (BYTE*) QuadPortConfig, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2108Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.h new file mode 100644 index 0000000..de3e9cf --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2108Device.h @@ -0,0 +1,52 @@ +/* + * CP2108Device.h + * + * Created on: Oct 29, 2012 + * Author: strowlan + */ + +#ifndef CP2108DEVICE_H_ +#define CP2108DEVICE_H_ + + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2108Device : public CCP210xDevice { + // Public Methods +public: + + CCP2108Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + +#endif /* CP2108DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.cpp new file mode 100644 index 0000000..3dda60a --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.cpp @@ -0,0 +1,173 @@ +/* + * CP2109Device.cpp + * + * Created on: Jan 8, 2013 + * Author: pfick + */ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP2109Device.h" +#include "CP210xSupportFunctions.h" + +CCP2109Device::CCP2109Device(libusb_device_handle* h) { + m_handle = h; + m_partNumber = 0x09; + maxSerialStrLen = CP210x_MAX_SERIAL_STRLEN; + maxProductStrLen = CP210x_MAX_PRODUCT_STRLEN; +} + +CP210x_STATUS CCP2109Device::GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetFlushBufferConfig(LPWORD lpwFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x3709, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + BAUD_CONFIG* currentBaudConfig; + currentBaudConfig = baudConfigData; + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + currentBaudConfig->BaudGen = (setup[i] << 8) + setup[i + 1]; + currentBaudConfig->Timer0Reload = (setup[i + 2] << 8) + setup[i + 3]; + currentBaudConfig->Prescaler = setup[i + 4]; + //setup[i+5] reserved for later use + currentBaudConfig->BaudRate = setup[i + 6] + (setup[i + 7] << 8) + (setup[i + 8] << 16) + (setup[i + 9] << 24); + + currentBaudConfig++; + } + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2109Device::GetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::GetLockValue(LPBYTE lpbLockValue) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + + // Validate parameter + if (!ValidParam(lpbLockValue)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + if (libusb_control_transfer(m_handle, 0xC0, 0xFF, 0x370A, 0, setup, 1, 0) == 1) { + if (setup[0] == 0xFF) + *lpbLockValue = 0x00; + else + *lpbLockValue = 0x01; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2109Device::SetManufacturerString(LPVOID lpvManufacturer, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetFlushBufferConfig(WORD wFlushBufferConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetBaudRateConfig(BAUD_CONFIG* baudConfigData) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BAUD_CONFIG* currentBaudConfig; + int transferSize = (NUM_BAUD_CONFIGS * BAUD_CONFIG_SIZE); + currentBaudConfig = baudConfigData; + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + for (int i = 0; i < transferSize; i += BAUD_CONFIG_SIZE) { + setup[i] = (currentBaudConfig->BaudGen & 0xFF00) >> 8; + setup[i + 1] = currentBaudConfig->BaudGen & 0x00FF; + setup[i + 2] = (currentBaudConfig->Timer0Reload & 0xFF00) >> 8; + setup[i + 3] = currentBaudConfig->Timer0Reload & 0x00FF; + setup[i + 4] = currentBaudConfig->Prescaler; + setup[i + 5] = 0x00; //reserved for later + setup[i + 6] = (BYTE) (currentBaudConfig->BaudRate & 0x000000FF); + setup[i + 7] = (BYTE) ((currentBaudConfig->BaudRate & 0x0000FF00) >> 8); + setup[i + 8] = (BYTE) ((currentBaudConfig->BaudRate & 0x00FF0000) >> 16); + setup[i + 9] = (BYTE) ((currentBaudConfig->BaudRate & 0xFF000000) >> 24); + + currentBaudConfig++; + } + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3709, 0, setup, transferSize + 2, 0) == transferSize + 2) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP2109Device::SetPortConfig(PORT_CONFIG* PortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig) { + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +CP210x_STATUS CCP2109Device::SetLockValue() { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x370A, 0xF0, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.h new file mode 100644 index 0000000..55f3608 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP2109Device.h @@ -0,0 +1,54 @@ +/* + * CP2109Device.h + * + * Created on: Jan 8, 2013 + * Author: pfick + */ + +#ifndef CP2109DEVICE_H_ +#define CP2109DEVICE_H_ + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" +#include "CP210xDevice.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP2109Device : public CCP210xDevice { + // Public Methods +public: + + CCP2109Device(libusb_device_handle* h); + + virtual CP210x_STATUS GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE lpbLength, BOOL bConvertToASCII = true); + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII); + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig); + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI, LPBYTE lpbDeviceModeSCI); + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue); + + + virtual CP210x_STATUS SetManufacturerString(LPVOID lpvManufacturer, BYTE bLength, BOOL bConvertToUnicode = true); + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode); + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig); + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI); + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData); + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig); + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig); + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig); + virtual CP210x_STATUS SetLockValue(); + +}; + + + +#endif /* CP2109DEVICE_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.cpp new file mode 100644 index 0000000..f6f1376 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.cpp @@ -0,0 +1,770 @@ +///////////////////////////////////////////////////////////////////////////// +// CP210xDevice.cpp +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP210xDevice.h" +#include "CP2101Device.h" +#include "CP2102Device.h" +#include "CP2102NDevice.h" +#include "CP2103Device.h" +#include "CP2104Device.h" +#include "CP2105Device.h" +#include "CP2108Device.h" +#include "CP2109Device.h" +#include "CP210xSupportFunctions.h" +#include "CP210xManufacturing.h" + +#include "silabs_defs.h" + +#define SIZEOF_ARRAY( a ) (sizeof( a ) / sizeof( a[0])) + +//////////////////////////////////////////////////////////////////////////////// +// constructor is called after the executable is loaded, before main() +// destructor is called before the executable is unloaded, after main() +//////////////////////////////////////////////////////////////////////////////// + +static libusb_context* libusbContext; + +__attribute__((constructor)) +static void Initializer() +{ + libusb_init(&libusbContext); +} + +__attribute__((destructor)) +static void Finalizer() +{ + libusb_exit(libusbContext); +} + +static bool IsCP210xCandidateDevice(libusb_device *pdevice) +{ + bool bIsCP210xCandidateDevice = true; /* innocent til proven guilty */ + + libusb_device_descriptor devDesc; + if (0 == libusb_get_device_descriptor(pdevice, &devDesc)) { + bIsCP210xCandidateDevice = false; + switch (devDesc.bDeviceClass) { + case LIBUSB_CLASS_PER_INTERFACE: /* CP2102, CP2112, */ + if ((1 == devDesc.iManufacturer) && (2 == devDesc.iProduct) && (3 <= devDesc.iSerialNumber)) { + libusb_config_descriptor *pconfigDesc; + bIsCP210xCandidateDevice = true; + if (0 == libusb_get_config_descriptor(pdevice, 0, &pconfigDesc)) { + if (pconfigDesc->bNumInterfaces && pconfigDesc->interface->num_altsetting) { + if (LIBUSB_CLASS_VENDOR_SPEC != pconfigDesc->interface->altsetting->bInterfaceClass) { + bIsCP210xCandidateDevice = false; + } + } + libusb_free_config_descriptor(pconfigDesc); + pconfigDesc = (libusb_config_descriptor *) NULL; + } + } + break; + + default: + bIsCP210xCandidateDevice = false; + break; +#if defined(DEBUG) + case LIBUSB_CLASS_COMM: /* */ + /* FALLTHROUGH */ + case LIBUSB_CLASS_HID: /* */ + bIsCP210xCandidateDevice = false; + break; + + case 0xef: + /* FALLTHROUGH */ + case LIBUSB_CLASS_VENDOR_SPEC: + /* FALLTHROUGH */ + case LIBUSB_CLASS_PRINTER: /* */ + /* FALLTHROUGH */ + case LIBUSB_CLASS_HUB: + bIsCP210xCandidateDevice = false; + break; +#endif + } + } + + return bIsCP210xCandidateDevice; +} +static bool IsCP210xCandidateDevice(libusb_device_handle *pdevice_handle) +{ + bool bIsCP210xCandidateDevice = true; /* innocent til proven guilty */ + + return bIsCP210xCandidateDevice; +} + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class - Static Methods +///////////////////////////////////////////////////////////////////////////// + +CP210x_STATUS CCP210xDevice::GetNumDevices(LPDWORD lpdwNumDevices) +{ + if (!lpdwNumDevices) { + return CP210x_INVALID_PARAMETER; + } + + // Enumerate all USB devices, returning the number + // of USB devices and a list of those devices + libusb_device** list; + const ssize_t NumOfUSBDevices = libusb_get_device_list(libusbContext, &list); + + // A negative count indicates an error + if (NumOfUSBDevices < 0) { + return CP210x_GLOBAL_DATA_ERROR; + } + + size_t NumOfCP210xDevices = 0; + for (ssize_t i = 0; i < NumOfUSBDevices; i++) { + libusb_device *device = list[i]; + + if (IsCP210xCandidateDevice(device)) { + libusb_device_handle* h; + + if ((0 == libusb_open(list[i], &h)) && IsCP210xCandidateDevice(h)) { + BYTE partNum; + if( CCP210xDevice::GetDevicePartNumber(h, &partNum) == CP210x_SUCCESS) { + if (IsValidCP210X_PARTNUM((CP210X_PARTNUM)partNum)) { + NumOfCP210xDevices++; + } + } + + libusb_close(h); + h = (libusb_device_handle *)NULL; + } + } + } + *lpdwNumDevices = static_cast( NumOfCP210xDevices); + libusb_free_device_list(list, 1); // Unreference all devices to free the device list + return CP210x_SUCCESS; +} + +// 0-based counting. I.e. dwDevice = 0 gives first CP210x device +CP210x_STATUS CCP210xDevice::Open(const DWORD dwDevice, CCP210xDevice** devObj) +{ + if (!devObj) { + return CP210x_INVALID_PARAMETER; + } + + *devObj = NULL; + + // Enumerate all USB devices, returning the number + // of USB devices and a list of those devices + libusb_device** list; + const ssize_t NumOfUSBDevices = libusb_get_device_list(libusbContext, &list); + + // A negative count indicates an error + if (NumOfUSBDevices < 0) { + return CP210x_GLOBAL_DATA_ERROR; + } + + if (dwDevice >= static_cast(NumOfUSBDevices)) { + return CP210x_DEVICE_NOT_FOUND; + } + + size_t NumOfCP210xDevices = 0; + for (ssize_t i = 0; i < NumOfUSBDevices; i++) { + libusb_device *device = list[i]; + + if (IsCP210xCandidateDevice(device)) { + libusb_device_handle* h; + + if ((0 == libusb_open(list[i], &h)) && IsCP210xCandidateDevice(h)) { + BYTE partNum; + + if( CCP210xDevice::GetDevicePartNumber( h, &partNum) == CP210x_SUCCESS) { + if (IsValidCP210X_PARTNUM((CP210X_PARTNUM)partNum)) { + if (dwDevice == NumOfCP210xDevices++) { + BOOL bFound = TRUE; + + switch (partNum) { + case CP210x_CP2101_VERSION: + *devObj = (CCP210xDevice*)new CCP2101Device(h); + break; + case CP210x_CP2102_VERSION: + *devObj = (CCP210xDevice*)new CCP2102Device(h); + break; + case CP210x_CP2103_VERSION: + *devObj = (CCP210xDevice*)new CCP2103Device(h); + break; + case CP210x_CP2104_VERSION: + *devObj = (CCP210xDevice*)new CCP2104Device(h); + break; + case CP210x_CP2105_VERSION: + *devObj = (CCP210xDevice*)new CCP2105Device(h); + break; + case CP210x_CP2108_VERSION: + *devObj = (CCP210xDevice*)new CCP2108Device(h); + break; + case CP210x_CP2109_VERSION: + *devObj = (CCP210xDevice*)new CCP2109Device(h); + break; + + case CP210x_CP2102N_QFN28_VERSION: + /* FALLTHROUGH */ + case CP210x_CP2102N_QFN24_VERSION: + /* FALLTHROUGH */ + case CP210x_CP2102N_QFN20_VERSION: + *devObj = (CCP210xDevice*)new CCP2102NDevice(h, partNum); + break; + + default: + bFound = FALSE; + break; + } + + // We've found the Nth (well, dwDevice'th) CP210x device. Break from the for()-loop purposefully + // NOT closing handle-h (after all, this in an open() function, we want to return that open handle + if (bFound) { + if( !(*devObj)) { + libusb_close(h); + } + break; + } + } + } + } + + libusb_close(h); + h = (libusb_device_handle *)NULL; + } + } + } // for + libusb_free_device_list(list, 1); // Unreference all devices to free the device list + return (*devObj) ? CP210x_SUCCESS : CP210x_DEVICE_NOT_FOUND; +} + +#if 0 +CP210x_STATUS CCP210xDevice::OldOpen(const DWORD dwDevice, CCP210xDevice** devObj) { + CP210x_STATUS status = CP210x_INVALID_PARAMETER; + + if (!devObj) { + return CP210x_INVALID_PARAMETER; + } + + // Enumerate all USB devices, returning the number + // of devices and a list of devices + libusb_device** list; + const ssize_t count = libusb_get_device_list(libusbContext, &list); + + *devObj = NULL; + + // A negative count indicates an error + if (count > 0) { + if (dwDevice < (DWORD) count) { + const libusb_device *device = list[dwDevice]; + + if (IsCP210xCandidateDevice(device)) { + libusb_device_handle* h; + + if (0 == libusb_open(list[dwDevice], &h)) { + if (IsCP210xCandidateDevice(h)) { + BYTE partNum; + + status = CCP210xDevice::GetDevicePartNumber(h, &partNum); + if (status == CP210x_SUCCESS) { + switch (partNum) { + case CP210x_CP2101_VERSION: + *devObj = (CCP210xDevice*)new CCP2101Device(h); + break; + case CP210x_CP2102_VERSION: + *devObj = (CCP210xDevice*)new CCP2102Device(h); + break; + case CP210x_CP2103_VERSION: + *devObj = (CCP210xDevice*)new CCP2103Device(h); + break; + case CP210x_CP2104_VERSION: + *devObj = (CCP210xDevice*)new CCP2104Device(h); + break; + case CP210x_CP2105_VERSION: + *devObj = (CCP210xDevice*)new CCP2105Device(h); + break; + case CP210x_CP2108_VERSION: + *devObj = (CCP210xDevice*)new CCP2108Device(h); + break; + case CP210x_CP2109_VERSION: + *devObj = (CCP210xDevice*)new CCP2109Device(h); + break; + + case CP210x_CP2102N_QFN28_VERSION: + /* FALLTHROUGH */ + case CP210x_CP2102N_QFN24_VERSION: + /* FALLTHROUGH */ + case CP210x_CP2102N_QFN20_VERSION: + *devObj = (CCP210xDevice*)new CCP2102NDevice(h, partNum); + break; + + default: + status = CP210x_DEVICE_NOT_FOUND; + break; + } + } else { + // return the status that GetDevicePartNumber failed with (was: status = CP210x_DEVICE_NOT_FOUND;) + } + } else { + // no error, simply not a IsCP210xCandidateDevice() + } + } else { + status = 0x77 ; // CP210x_DEVICE_NOT_FOUND; // libusb_open + } + } else { + // no error, simply not a IsCP210xCandidateDevice() + } + } else { + status = CP210x_DEVICE_NOT_FOUND; // dwDevice out of range + } + } else { + status = CP210x_GLOBAL_DATA_ERROR; // libusb_get_device_list failed + } + + // Unreference all devices to free the device list + libusb_free_device_list(list, 1); + + return status; +} +#endif + +CP210x_STATUS CCP210xDevice::GetDevicePartNumber(libusb_device_handle* h, LPBYTE lpbPartNum) +{ + if (!h || !lpbPartNum || !ValidParam(lpbPartNum)) { + return CP210x_INVALID_PARAMETER; + } + + const int ret = libusb_control_transfer(h, 0xC0, 0xFF, 0x370B, 0x0000, lpbPartNum, 1, 7000); + if (1 == ret) { + return CP210x_SUCCESS; + } + if( ret == LIBUSB_ERROR_TIMEOUT) { + return CP210x_DEVICE_IO_FAILED; + } + + libusb_config_descriptor* configDesc; + + CP210x_STATUS status = CP210x_DEVICE_IO_FAILED; + if (libusb_get_config_descriptor(libusb_get_device(h), 0, &configDesc) == 0) { + // Looking for a very particular fingerprint to conclude the device is a CP2101 + if ((configDesc->bNumInterfaces > 0) && + (configDesc->interface[0].altsetting->bNumEndpoints > 1) && + ((configDesc->interface[0].altsetting->endpoint[0].bEndpointAddress & 0x0F) == 0x03) && + ((configDesc->interface[0].altsetting->endpoint[1].bEndpointAddress & 0x0F) == 0x03)) { + *lpbPartNum = CP210x_CP2101_VERSION; + status = CP210x_SUCCESS; + } + libusb_free_config_descriptor(configDesc); + } + return status; +} + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class - Public Methods +///////////////////////////////////////////////////////////////////////////// + +CP210x_STATUS CCP210xDevice::Reset() { + libusb_reset_device(m_handle); + return CP210x_SUCCESS; +} + +CP210x_STATUS CCP210xDevice::Close() { + libusb_close(m_handle); + m_handle = NULL; + return CP210x_SUCCESS; +} + +HANDLE CCP210xDevice::GetHandle() { + return this; +} + +CP210x_STATUS CCP210xDevice::GetPartNumber(LPBYTE lpbPartNum) { + // Validate parameter + if (!ValidParam(lpbPartNum)) { + return CP210x_INVALID_PARAMETER; + } + + if (lpbPartNum) *lpbPartNum = m_partNumber; + + return CP210x_SUCCESS; +} + +CP210x_STATUS CCP210xDevice::SetVid(WORD wVid) { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3701, wVid, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetPid(WORD wPid) { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3702, wPid, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetProductString(LPVOID lpvProduct, BYTE bLength, BOOL bConvertToUnicode) { + CP210x_STATUS status; + BYTE str[CP210x_MAX_DEVICE_STRLEN]; + BYTE length = bLength; + int transferSize; + + // Validate parameter + if (!ValidParam(lpvProduct)) { + return CP210x_INVALID_PARAMETER; + } + + if ((bLength > maxProductStrLen) || (bLength < 1)) { + return CP210x_INVALID_PARAMETER; + } + + CopyToString(str, lpvProduct, &length, bConvertToUnicode); + + transferSize = length + 2; + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3703, 0, str, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetSerialNumber(LPVOID lpvSerialNumber, BYTE bLength, BOOL bConvertToUnicode) { + CP210x_STATUS status; + BYTE str[CP210x_MAX_DEVICE_STRLEN]; + BYTE length = bLength; + int transferSize; + + // Validate parameter + if (!ValidParam(lpvSerialNumber)) { + return CP210x_INVALID_PARAMETER; + } + + if ((bLength > maxProductStrLen) || (bLength < 1)) { + return CP210x_INVALID_PARAMETER; + } + + CopyToString(str, lpvSerialNumber, &length, bConvertToUnicode); + + transferSize = length + 2; + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3704, 0, str, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetSelfPower(BOOL bSelfPower) { + CP210x_STATUS status; + BYTE bPowerAttrib = 0x80; + + if (bSelfPower) + bPowerAttrib |= 0x40; // Set the self-powered bit. + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3705, bPowerAttrib, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetMaxPower(BYTE bMaxPower) { + CP210x_STATUS status; + if (bMaxPower > CP210x_MAX_MAXPOWER) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3706, bMaxPower, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::SetDeviceVersion(WORD wVersion) { + CP210x_STATUS status; + + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3707, wVersion, NULL, 0, 0) == 0) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetVid(LPWORD lpwVid) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_device_descriptor devDesc; + + // Validate parameter + if (!ValidParam(lpwVid)) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc) == 0) { + *lpwVid = devDesc.idVendor; + + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetPid(LPWORD lpwPid) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_device_descriptor devDesc; + + // Validate parameter + if (!ValidParam(lpwPid)) { + return CP210x_INVALID_PARAMETER; + } + + if (libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc) == 0) { + *lpwPid = devDesc.idProduct; + + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +struct UsbStrDesc +{ + BYTE TotalBytes; // including this 2-byte prefix + BYTE Type; // always 3 + BYTE Data[ 0]; +}; + +CP210x_STATUS CCP210xDevice::GetUnicodeString( uint8_t desc_index, LPBYTE pBuf, int CbBuf, LPBYTE pCchStr) +{ + CP210x_STATUS status; + const int CbReturned = libusb_get_string_descriptor(m_handle, desc_index, 0x0000 /*desc_type*/, pBuf, CbBuf); + if( CbReturned > 0) { + if( CbReturned > 1) { // at least have the prefix + const struct UsbStrDesc *pDesc = (struct UsbStrDesc *) pBuf; + if( pDesc->TotalBytes <= CbReturned && pDesc->Type == 3) { + const BYTE CbStr = pDesc->TotalBytes - 2; // minus the 2-byte prefix + // Careful! Pulling up the data by 2 bytes, overwriting the 2-byte prefix + for( BYTE i = 0; i < CbStr; i++) { + pBuf[ i] = pBuf[ i + 2]; + } + *pCchStr = CbStr / 2; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; // Incomplete or malformed descriptor returned + } + } else { + status = CP210x_DEVICE_IO_FAILED; // Incomplete or malformed descriptor returned + } + } else { + status = CP210x_DEVICE_IO_FAILED; // USB I/O failed + } + return status; +} + +CP210x_STATUS CCP210xDevice::GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE pCchStr, BOOL bConvertToASCII) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_device_descriptor devDesc; + int length; + int index; + + // Validate parameter + if (!ValidParam(lpManufacturer, pCchStr)) { + return CP210x_INVALID_PARAMETER; + } + + // Get descriptor that contains the index of the USB_STRING_DESCRIPTOR containing the Product String + if (libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc) == 0) { + index = devDesc.iManufacturer; + } + + if (bConvertToASCII) { + length = libusb_get_string_descriptor_ascii(m_handle, index, (unsigned char*) lpManufacturer, CP210x_MAX_DEVICE_STRLEN); + if (length > 0) { + *pCchStr = (BYTE) (length & 0xFF); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = GetUnicodeString( index, (LPBYTE) lpManufacturer, CP210x_MAX_DEVICE_STRLEN, pCchStr); + } + + return status; +} +CP210x_STATUS CCP210xDevice::SetManufacturerString(LPVOID lpvManufacturer, BYTE CchStr, BOOL bConvertToUnicode) { + CP210x_STATUS status; + BYTE setup[CP210x_MAX_SETUP_LENGTH]; + BYTE length = CchStr; + int transferSize; + + // Validate parameter + if (!ValidParam(lpvManufacturer)) { + return CP210x_INVALID_PARAMETER; + } + + if ((CchStr > CP210x_MAX_MANUFACTURER_STRLEN) || (CchStr < 1)) { + return CP210x_INVALID_PARAMETER; + } + + memset(setup, 0, CP210x_MAX_SETUP_LENGTH); + + CopyToString(setup, lpvManufacturer, &length, bConvertToUnicode); + + transferSize = length + 2; + if (libusb_control_transfer(m_handle, 0x40, 0xFF, 0x3714, 0, setup, transferSize, 0) == transferSize) { + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetDeviceProductString(LPVOID lpProduct, LPBYTE pCchStr, BOOL bConvertToASCII) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE index = 2; // Our "best guess", lest libusb_get_device_descriptor() fails, and we choose to continue anyway + + // Validate parameter + if (!ValidParam(lpProduct, pCchStr)) { + return CP210x_INVALID_PARAMETER; + } + + // Get descriptor that contains the index of the USB_STRING_DESCRIPTOR containing the Product String + libusb_device_descriptor devDesc; + if (0 == libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc)) { + index = devDesc.iProduct; + } + + if (bConvertToASCII) { + const int length = libusb_get_string_descriptor_ascii(m_handle, index, (unsigned char*) lpProduct, CP210x_MAX_DEVICE_STRLEN); + if (length > 0) { + *pCchStr = (BYTE) (length & 0xFF); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = GetUnicodeString( index, (LPBYTE) lpProduct, CP210x_MAX_DEVICE_STRLEN, pCchStr); + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetDeviceSerialNumber(LPVOID lpSerial, LPBYTE pCchStr, BOOL bConvertToASCII) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + BYTE index = 3; // Our "best guess", lest libusb_get_device_descriptor() fails, and we choose to continue anyway + + // Validate parameter + if (!ValidParam(lpSerial, pCchStr)) { + return CP210x_INVALID_PARAMETER; + } + + libusb_device_descriptor devDesc; + if (0 == libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc)) { + index = devDesc.iSerialNumber; + } + + if (bConvertToASCII) { + const int length = libusb_get_string_descriptor_ascii(m_handle, index, (unsigned char*) lpSerial, CP210x_MAX_DEVICE_STRLEN); + if (length > 0) { + *pCchStr = (BYTE) (length & 0xFF); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + } else { + status = GetUnicodeString(index, (LPBYTE) lpSerial, CP210x_MAX_DEVICE_STRLEN, pCchStr); + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetSelfPower(LPBOOL lpbSelfPower) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_config_descriptor* configDesc; + + // Validate parameter + if (!ValidParam(lpbSelfPower)) { + return CP210x_INVALID_PARAMETER; + } + + // Get descriptor that contains the index of the USB_STRING_DESCRIPTOR containing the Product String + if (libusb_get_config_descriptor(libusb_get_device(m_handle), 0, &configDesc) == 0) { + if (configDesc->bmAttributes & 0x40) + *lpbSelfPower = TRUE; + else + *lpbSelfPower = FALSE; + libusb_free_config_descriptor(configDesc); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetMaxPower(LPBYTE lpbMaxPower) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_config_descriptor* configDesc; + + // Validate parameter + if (!ValidParam(lpbMaxPower)) { + return CP210x_INVALID_PARAMETER; + } + + // Get descriptor that contains the index of the USB_STRING_DESCRIPTOR containing the Product String + if (libusb_get_config_descriptor(libusb_get_device(m_handle), 0, &configDesc) == 0) { + *lpbMaxPower = configDesc->MaxPower; + libusb_free_config_descriptor(configDesc); + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + +CP210x_STATUS CCP210xDevice::GetDeviceVersion(LPWORD lpwVersion) { + CP210x_STATUS status = CP210x_INVALID_HANDLE; + libusb_device_descriptor devDesc; + + // Validate parameter + if (!ValidParam(lpwVersion)) { + return CP210x_INVALID_PARAMETER; + } + + // Get descriptor that contains the index of the USB_STRING_DESCRIPTOR containing the Product String + if (libusb_get_device_descriptor(libusb_get_device(m_handle), &devDesc) == 0) { + *lpwVersion = devDesc.bcdDevice; + status = CP210x_SUCCESS; + } else { + status = CP210x_DEVICE_IO_FAILED; + } + + return status; +} + + + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.h new file mode 100644 index 0000000..2988f3c --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xDevice.h @@ -0,0 +1,97 @@ +///////////////////////////////////////////////////////////////////////////// +// CP210xDevice.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CP210x_DEVICE_H +#define CP210x_DEVICE_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "libusb.h" +#include "CP210xManufacturing.h" + +///////////////////////////////////////////////////////////////////////////// +// CCP210xDevice Class +///////////////////////////////////////////////////////////////////////////// + +class CCP210xDevice +{ +// Static Methods +public: + static CP210x_STATUS GetNumDevices(LPDWORD lpdwNumDevices); + static CP210x_STATUS Open(DWORD dwDevice, CCP210xDevice** devObj); + + virtual ~CCP210xDevice() {} + +private: + static CP210x_STATUS GetDevicePartNumber(libusb_device_handle* h, LPBYTE lpbPartNum); + +// Public Methods +public: + CP210x_STATUS Reset(); + CP210x_STATUS Close(); + HANDLE GetHandle(); + + CP210x_STATUS GetPartNumber(LPBYTE lpbPartNum); + + CP210x_STATUS SetVid(WORD wVid); + CP210x_STATUS SetPid(WORD wPid); + CP210x_STATUS SetProductString(LPVOID lpvProduct, BYTE bLength, BOOL bConvertToUnicode = true); + CP210x_STATUS SetSerialNumber(LPVOID lpvSerialNumber, BYTE bLength, BOOL bConvertToUnicode = true); + CP210x_STATUS SetSelfPower(BOOL bSelfPower); + CP210x_STATUS SetMaxPower(BYTE bMaxPower); + CP210x_STATUS SetDeviceVersion(WORD wVersion); + + CP210x_STATUS GetVid(LPWORD wVid); + CP210x_STATUS GetPid(LPWORD wPid); + CP210x_STATUS GetProductString(DWORD dwDeviceNum, LPVOID lpvDeviceString, DWORD dwFlags); + CP210x_STATUS GetDeviceProductString(LPVOID lpProduct, LPBYTE lpbLength, BOOL bConvertToASCII = true); + CP210x_STATUS GetDeviceSerialNumber(LPVOID lpSerial, LPBYTE lpbLength, BOOL bConvertToASCII = true); + CP210x_STATUS GetSelfPower(LPBOOL lpbSelfPower); + CP210x_STATUS GetMaxPower(LPBYTE lpbMaxPower); + CP210x_STATUS GetDeviceVersion(LPWORD lpwVersion); + + + // virtual functions + virtual CP210x_STATUS GetDeviceManufacturerString(LPVOID lpManufacturer, LPBYTE lpbLength, BOOL bConvertToASCII = true); + virtual CP210x_STATUS GetDeviceInterfaceString(BYTE bInterfaceNumber, LPVOID lpInterface, LPBYTE lpbLength, BOOL bConvertToASCII)=0; + virtual CP210x_STATUS GetFlushBufferConfig(LPWORD lpwFlushBufferConfig)=0; + virtual CP210x_STATUS GetDeviceMode(LPBYTE lpbDeviceModeECI,LPBYTE lpbDeviceModeSCI)=0; + virtual CP210x_STATUS GetBaudRateConfig(BAUD_CONFIG* baudConfigData)=0; + virtual CP210x_STATUS GetPortConfig(PORT_CONFIG* PortConfig)=0; + virtual CP210x_STATUS GetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig)=0; + virtual CP210x_STATUS GetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig)=0; + virtual CP210x_STATUS GetLockValue(LPBYTE lpbLockValue)=0; + + + virtual CP210x_STATUS SetManufacturerString(LPVOID lpvManufacturer, BYTE bLength, BOOL bConvertToUnicode = true); + virtual CP210x_STATUS SetInterfaceString(BYTE bInterfaceNumber, LPVOID lpvInterface, BYTE bLength, BOOL bConvertToUnicode)=0; + virtual CP210x_STATUS SetFlushBufferConfig(WORD wFlushBufferConfig)=0; + virtual CP210x_STATUS SetDeviceMode(BYTE bDeviceModeECI, BYTE bDeviceModeSCI)=0; + virtual CP210x_STATUS SetBaudRateConfig(BAUD_CONFIG* baudConfigData)=0; + virtual CP210x_STATUS SetPortConfig(PORT_CONFIG* PortConfig)=0; + virtual CP210x_STATUS SetDualPortConfig(DUAL_PORT_CONFIG* DualPortConfig)=0; + virtual CP210x_STATUS SetQuadPortConfig(QUAD_PORT_CONFIG* QuadPortConfig)=0; + virtual CP210x_STATUS SetLockValue()=0; + + virtual CP210x_STATUS GetFirmwareVersion( pFirmware_t lpVersion) { return CP210x_FUNCTION_NOT_SUPPORTED; } + virtual CP210x_STATUS GetConfig( LPBYTE lpbConfig, WORD bLength) { return CP210x_FUNCTION_NOT_SUPPORTED; } + virtual CP210x_STATUS SetConfig(LPBYTE lpbConfig, WORD bLength) { return CP210x_FUNCTION_NOT_SUPPORTED; } + virtual CP210x_STATUS UpdateFirmware() { return CP210x_FUNCTION_NOT_SUPPORTED; } + virtual CP210x_STATUS GetGeneric( LPBYTE lpbGeneric, WORD bLength) { return CP210x_FUNCTION_NOT_SUPPORTED; } + virtual CP210x_STATUS SetGeneric( LPBYTE lpbGeneric, WORD bLength) { return CP210x_FUNCTION_NOT_SUPPORTED; } + +// Protected Members +protected: + CP210x_STATUS GetUnicodeString( uint8_t desc_index, LPBYTE pBuf, int CbBuf, LPBYTE pCchStr); + + libusb_device_handle* m_handle; + BYTE m_partNumber; + + BYTE maxSerialStrLen; + BYTE maxProductStrLen; +}; + +#endif // CP210x_DEVICE_H diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xManufacturing.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xManufacturing.cpp new file mode 100644 index 0000000..1ae1ead --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xManufacturing.cpp @@ -0,0 +1,957 @@ +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "CP210xManufacturing.h" +#include "DeviceList.h" +#include "CP210xDevice.h" +#include "CP2103Device.h" +#include "OsDep.h" + +///////////////////////////////////////////////////////////////////////////// +// Global Variables +///////////////////////////////////////////////////////////////////////////// + +// Each time Construct()/Destruct() are called +// DeviceList will be updated to track the use +// of heap memory (stores object pointers) +// +// The CDeviceList destructor will automatically +// free any remaining devices +static CDeviceList DeviceList; + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions +///////////////////////////////////////////////////////////////////////////// + +CP210x_STATUS CP210x_GetNumDevices( + LPDWORD lpdwNumDevices + ) { + CP210x_STATUS status; + + // Check parameters + if (lpdwNumDevices) { + status = CCP210xDevice::GetNumDevices(lpdwNumDevices); + } else { + status = CP210x_INVALID_PARAMETER; + } + + return status; +} + +CP210x_STATUS CP210x_Open( + DWORD dwDevice, + HANDLE* cyHandle + ) { + CP210x_STATUS status; + + // Check parameters + if (cyHandle) { + *cyHandle = NULL; + + // Create a new device object and add it to the device list + CCP210xDevice* dev = NULL; + + status = CCP210xDevice::Open(dwDevice, &dev); + + if (status == CP210x_SUCCESS) { + DeviceList.Add(dev); + *cyHandle = dev->GetHandle(); + } else { + if (dev) { + // Close the handle + dev->Close(); + + // Delete the device object and + // remove the device reference from the device list + DeviceList.Destruct(dev); + } + } + } else { + status = CP210x_INVALID_PARAMETER; + } + + return status; +} + +CP210x_STATUS CP210x_Close( + HANDLE cyHandle + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Close the device + status = dev->Close(); + + // Deallocate the device object, remove the device reference + // from the device list + DeviceList.Destruct(dev); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetPartNumber( + HANDLE cyHandle, + LPBYTE lpbPartNum + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpbPartNum) { + status = dev->GetPartNumber(lpbPartNum); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS CP210x_GetProductString( + DWORD dwDeviceNum, + LPVOID lpvDeviceString, + DWORD dwFlags + ) { + //TODO - fill out all flagged strings + HANDLE h; + if (CP210x_Open(dwDeviceNum, &h) == CP210x_SUCCESS) { + BYTE length; + return CP210x_GetDeviceSerialNumber(h, lpvDeviceString, &length, true); + } + + return CP210x_DEVICE_NOT_FOUND; +} + +CP210x_STATUS +CP210x_SetVid( + HANDLE cyHandle, + WORD wVid + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetVid(wVid); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetPid( + HANDLE cyHandle, + WORD wPid + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetPid(wPid); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetManufacturerString( + HANDLE cyHandle, + LPVOID lpvManufacturer, + BYTE bLength, + BOOL bConvertToUnicode + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetManufacturerString(lpvManufacturer, bLength, bConvertToUnicode); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetProductString( + HANDLE cyHandle, + LPVOID lpvProduct, + BYTE bLength, + BOOL bConvertToUnicode + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetProductString(lpvProduct, bLength, bConvertToUnicode); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetInterfaceString( + HANDLE cyHandle, + BYTE bInterfaceNumber, + LPVOID lpvInterface, + BYTE bLength, + BOOL bConvertToUnicode + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetInterfaceString(bInterfaceNumber, lpvInterface, bLength, bConvertToUnicode); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetSerialNumber( + HANDLE cyHandle, + LPVOID lpvSerialNumber, + BYTE bLength, + BOOL bConvertToUnicode + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetSerialNumber(lpvSerialNumber, bLength, bConvertToUnicode); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetSelfPower( + HANDLE cyHandle, + BOOL bSelfPower + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetSelfPower(bSelfPower); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetMaxPower( + HANDLE cyHandle, + BYTE bMaxPower + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetMaxPower(bMaxPower); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetFlushBufferConfig( + HANDLE cyHandle, + WORD wFlushBufferConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetFlushBufferConfig(wFlushBufferConfig); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetDeviceMode( + HANDLE cyHandle, + BYTE bDeviceModeECI, + BYTE bDeviceModeSCI + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetDeviceMode(bDeviceModeECI, bDeviceModeSCI); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetDeviceVersion( + HANDLE cyHandle, + WORD wVersion + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetDeviceVersion(wVersion); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetBaudRateConfig( + HANDLE cyHandle, + BAUD_CONFIG* baudConfigData + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetBaudRateConfig(baudConfigData); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetPortConfig( + HANDLE cyHandle, + PORT_CONFIG* PortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetPortConfig(PortConfig); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetDualPortConfig( + HANDLE cyHandle, + DUAL_PORT_CONFIG* DualPortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetDualPortConfig(DualPortConfig); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetQuadPortConfig( + HANDLE cyHandle, + QUAD_PORT_CONFIG* QuadPortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetQuadPortConfig(QuadPortConfig); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_SetLockValue( + HANDLE cyHandle + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->SetLockValue(); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceVid( + HANDLE cyHandle, + LPWORD lpwVid + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpwVid) { + status = dev->GetVid(lpwVid); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDevicePid( + HANDLE cyHandle, + LPWORD lpwPid + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpwPid) { + status = dev->GetPid(lpwPid); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceManufacturerString( + HANDLE cyHandle, + LPVOID lpManufacturer, + LPBYTE lpbLength, + BOOL bConvertToASCII + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpManufacturer) { + status = dev->GetDeviceManufacturerString(lpManufacturer, lpbLength, bConvertToASCII); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceProductString( + HANDLE cyHandle, + LPVOID lpProduct, + LPBYTE lpbLength, + BOOL bConvertToASCII + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpProduct) { + status = dev->GetDeviceProductString(lpProduct, lpbLength, bConvertToASCII); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceInterfaceString( + HANDLE cyHandle, + BYTE bInterfaceNumber, + LPVOID lpInterface, + LPBYTE lpbLength, + BOOL bConvertToASCII + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpInterface) { + status = dev->GetDeviceInterfaceString(bInterfaceNumber, lpInterface, lpbLength, bConvertToASCII); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceSerialNumber( + HANDLE cyHandle, + LPVOID lpSerialNumber, + LPBYTE lpbLength, + BOOL bConvertToASCII + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpSerialNumber) { + status = dev->GetDeviceSerialNumber(lpSerialNumber, lpbLength, bConvertToASCII); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetSelfPower( + HANDLE cyHandle, + LPBOOL lpbSelfPower + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpbSelfPower) { + status = dev->GetSelfPower(lpbSelfPower); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetMaxPower( + HANDLE cyHandle, + LPBYTE lpbPower + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpbPower) { + status = dev->GetMaxPower(lpbPower); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetFlushBufferConfig( + HANDLE cyHandle, + LPWORD lpwFlushBufferConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpwFlushBufferConfig) { + status = dev->GetFlushBufferConfig(lpwFlushBufferConfig); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceMode( + HANDLE cyHandle, + LPBYTE lpbDeviceModeECI, + LPBYTE lpbDeviceModeSCI + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpbDeviceModeECI && lpbDeviceModeSCI) { + status = dev->GetDeviceMode(lpbDeviceModeECI, lpbDeviceModeSCI); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDeviceVersion( + HANDLE cyHandle, + LPWORD lpwVersion + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpwVersion) { + status = dev->GetDeviceVersion(lpwVersion); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetBaudRateConfig( + HANDLE cyHandle, + BAUD_CONFIG* baudConfigData + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (baudConfigData) { + status = dev->GetBaudRateConfig(baudConfigData); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetPortConfig( + HANDLE cyHandle, + PORT_CONFIG* PortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (PortConfig) { + status = dev->GetPortConfig(PortConfig); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetDualPortConfig( + HANDLE cyHandle, + DUAL_PORT_CONFIG* DualPortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (DualPortConfig) { + status = dev->GetDualPortConfig(DualPortConfig); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetQuadPortConfig( + HANDLE cyHandle, + QUAD_PORT_CONFIG* QuadPortConfig + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (QuadPortConfig) { + status = dev->GetQuadPortConfig(QuadPortConfig); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_GetLockValue( + HANDLE cyHandle, + LPBYTE lpbLockValue + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + // Check pointers + if (lpbLockValue) { + status = dev->GetLockValue(lpbLockValue); + } else { + status = CP210x_INVALID_PARAMETER; + } + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_Reset( + HANDLE cyHandle + ) { + CP210x_STATUS status; + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + + // Check device object + if (DeviceList.Validate(dev)) { + status = dev->Reset(); + } else { + status = CP210x_INVALID_HANDLE; + } + + return status; +} + +CP210x_STATUS +CP210x_CreateHexFile( + HANDLE cyHandle, + LPCSTR lpvFileName + ) { + //TODO + return CP210x_FUNCTION_NOT_SUPPORTED; +} + +//------------------------------------------------------------------------ +// CP210x_GetFirmwareVersion() +// +// Retrieves the on-board firmware version. +// +//------------------------------------------------------------------------ + +CP210x_STATUS +CP210x_GetFirmwareVersion( HANDLE cyHandle, + pFirmware_t lpVersion) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + if( !lpVersion) { + return CP210x_INVALID_PARAMETER; + } + return dev->GetFirmwareVersion( lpVersion); +} + +//------------------------------------------------------------------------ +// CP210x_GetConfig() +// +// Retrieves the on-board config block from the device. Caller must read first 2 bytes +// to determine size of config block, then request the full config. +// +//------------------------------------------------------------------------ +CP210x_STATUS +CP210x_GetConfig( HANDLE cyHandle, + LPBYTE lpbConfig, + WORD bLength) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + if( !lpbConfig) { + return CP210x_INVALID_PARAMETER; + } + return dev->GetConfig( lpbConfig, bLength); +} + +//------------------------------------------------------------------------ +// CP210x_SetConfig() +// +// Writes the on-board config block from the device. Caller must verify any checksum +// before calling. +// +//------------------------------------------------------------------------ +CP210x_STATUS +CP210x_SetConfig( HANDLE cyHandle, + LPBYTE lpbConfig, + WORD bLength) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + if( !lpbConfig) { + return CP210x_INVALID_PARAMETER; + } + return dev->SetConfig( lpbConfig, bLength); +} + +//------------------------------------------------------------------------ +// CP210x_updateFirmware() +// +// Requests device enter Bootloader mode. Separate application will upload firmware. +// Unsure what will happen with USB interface when device resets. Specific to CP2102N. +// +//------------------------------------------------------------------------ + +CP210x_STATUS +CP210x_UpdateFirmware( HANDLE cyHandle) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + return dev->UpdateFirmware(); +} + +// This function allows the caller to create a generic USB command to read. +// For this function, lpbGeneric and bLength must include the 8 bytes +// of the setup packet. Use with caution. Overwrites lpbGeneric with +// retrieved data, including 8 bytes of setup packet. NOT intended for long term use +// - once a new feature has been debugged, add it to the DLL! +CP210x_STATUS +CP210x_GetGeneric( HANDLE cyHandle, + LPBYTE lpbGeneric, + WORD bLength) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + if( !lpbGeneric) { + return CP210x_INVALID_PARAMETER; + } + return dev->GetGeneric( lpbGeneric, bLength); +} + +// This function allows the caller to create a generic USB command to write +// For this function, lpbGeneric and bLength must include the 8 bytes +// of the setup packet. Use with caution. NOT intended for long term use +// - once a new feature has been debugged, add it to the DLL! +CP210x_STATUS +CP210x_SetGeneric( HANDLE cyHandle, + LPBYTE lpbGeneric, + WORD bLength) +{ + CCP210xDevice* dev = (CCP210xDevice*) cyHandle; + if (!DeviceList.Validate(dev)) { + return CP210x_INVALID_HANDLE; + } + if( !lpbGeneric) { + return CP210x_INVALID_PARAMETER; + } + return dev->SetGeneric( lpbGeneric, bLength); +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.cpp b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.cpp new file mode 100644 index 0000000..a1e841e --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.cpp @@ -0,0 +1,120 @@ +/* + * CP210xSupportFunctions.cpp + * + * Created on: Oct 30, 2012 + * Author: strowlan + */ + + +#include "CP210xSupportFunctions.h" + +//------------------------------------------------------------------------ +// ValidParam(LPVOID) +// +// Checks validity of an LPVOID pointer value. +//------------------------------------------------------------------------ + +BOOL _CP210x_ValidParam(LPVOID lpVoidPointer) { + BYTE temp = 0; + + try { + temp = *((BYTE*) lpVoidPointer); + } catch (...) { + return false; + } + return true; +} + +//------------------------------------------------------------------------ +// ValidParam(LPBYTE) +// +// Checks validity of an LPBYTE pointer value. +//------------------------------------------------------------------------ + +BOOL _CP210x_ValidParam(LPBYTE lpbPointer) { + BYTE temp = 0; + + if (!lpbPointer) return FALSE; + + try { + temp = *((BYTE*) lpbPointer); + } catch (...) { + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------ +// ValidParam(LPWORD) +// +// Checks validity of an LPWORD pointer value. +//------------------------------------------------------------------------ + +BOOL _CP210x_ValidParam(LPWORD lpwPointer) { + WORD temp = 0; + + try { + temp = *lpwPointer; + } catch (...) { + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------ +// ValidParam(LPVOID, LPBYTE) +// +// Checks validity of LPVOID, LPBYTE pair of pointer values. +//------------------------------------------------------------------------ + +BOOL _CP210x_ValidParam(LPVOID lpVoidPointer, LPBYTE lpbPointer) { + if (ValidParam(lpVoidPointer)) + if (ValidParam(lpbPointer)) + return TRUE; + + return FALSE; +} + +//------------------------------------------------------------------------ +// CopyToString() +// +// Copies string into the remaining part of a setup buffer. The first +// byte is the length and the second byte is 0x03. This leaves 246 bytes +// for the string. If it is not already unicode, the string must be +// converted to unicode when copied. +//------------------------------------------------------------------------ + +void _CP210x_CopyToString(BYTE* setup, LPVOID string, BYTE* bLength, BOOL bConvertToUnicode) { + BYTE length = *bLength; + + // If not already unicode it will require twice as many bytes as bLength parameter. + if (bConvertToUnicode) { + ConvertToUnicode(&setup[2], (BYTE*) string, length); + length = length * 2; + } else { + length = length * 2; + memcpy(&setup[2], string, length); + } + + setup[0] = length + 2; + setup[1] = 0x03; // Indicates a string + + // return the possibly modified length value + *bLength = length; +} + + +//------------------------------------------------------------------------ +// ConvertToUnicode() +// +// Copy ASCII character to the low byte and '0' to the high byte to +// convert string to unicode. +// bLength is the length in bytes of the unicode buffer. +//------------------------------------------------------------------------ + +void _CP210x_ConvertToUnicode(BYTE* dest, BYTE* source, BYTE bLength) { + for (int i = 0; i < bLength; i++) { + dest[i * 2] = source[i]; + dest[i * 2 + 1] = 0; + } +} diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.h b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.h new file mode 100644 index 0000000..474f109 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/cp210xmanufacturing/src/CP210xSupportFunctions.h @@ -0,0 +1,28 @@ +/* + * CP210xSupportFunctions.h + * + * Created on: Oct 30, 2012 + * Author: strowlan + */ + +#ifndef CP210XSUPPORTFUNCTIONS_H_ +#define CP210XSUPPORTFUNCTIONS_H_ + +#include +#include "Types.h" + +#define CP210x_MAX_SETUP_LENGTH 1024 + +BOOL _CP210x_ValidParam(LPVOID lpVoidPointer); +BOOL _CP210x_ValidParam(LPWORD lpwPointer); +BOOL _CP210x_ValidParam(LPBYTE lpbPointer); +BOOL _CP210x_ValidParam(LPVOID lpVoidPointer); +BOOL _CP210x_ValidParam(LPVOID lpVoidPointer, LPBYTE lpbPointer); +void _CP210x_CopyToString(BYTE* setup, LPVOID string, BYTE* bLength, BOOL bConvertToUnicode); +void _CP210x_ConvertToUnicode(BYTE* dest, BYTE* source, BYTE bLength); + +#define ValidParam _CP210x_ValidParam +#define CopyToString _CP210x_CopyToString +#define ConvertToUnicode _CP210x_ConvertToUnicode + +#endif /* CP210XSUPPORTFUNCTIONS_H_ */ diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/FAQ.txt b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/FAQ.txt new file mode 100644 index 0000000..91a0706 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/FAQ.txt @@ -0,0 +1,96 @@ +cp210xmanufacturing library and Linux FAQ +================================================== + +This document provides information on how to build and use the +CP210xManufacturing library for linux. + +This document describes procedures that apply to Ubuntu Linux distributions. +Exact procedures and commands may differ for your specific distribution. + +FAQ +--- + +Q?: How do I link to the cp210xmanufacturing library? + +A?: The library is installed (by default) in /usr/local/lib. Therefore you can add + these two flags to your compiler command: + -L/usr/local/lib -lcp210xmanufacturing + + This will link your executable with the cp210xmanufacturing library + and will allow g++ to find the library. + +Q?: Why is my device not recognized when calling CP210x_GetNumDevices()? + +A?: It could be a permissions problem. Try running your program as root. + If the device is recognized when your program is run as root but not when + run with normal permissions, the SiliconLabs.rules file may not be + installed properly. + + root should always have read/write permissions to USB device files. + + To automatically grant global read/write permissions to all USB devices with the + Silicon Labs Vendor ID (0x10c4), copy the SiliconLabs.rules file to + /etc/udev/rules.d/: + + $ sudo cp SiliconLabs.rules /etc/udev/rules.d/ + + Refer to SiliconLabs.rules for more information. Also it may be necessary to + create your own udev rules file by modifying SiliconLabs.rules to include + your own Vendor ID and optionally Product ID. + + A8:3 The udev rules file may not have been applied. udev should monitor the + /etc/udev/rules.d/ directory for new rules file, but this does not always work. + You may need to unplug/replug your device and possibly reboot for the udev + rule to take affect. + +Q1: Why does the + + +Q?: Why do I get the following error when trying to build libcp210xmanufacturing? + +Package libusb-1.0 was not found in the pkg-config search path. + +A2: The libslabhidtouart library requires libusb-1.0-0.dev to be installed. +This will copy the libusb-1.0 library and include files and register the +package with pkg-config. + +On Ubuntu, install libusb-1.0-0-dev: +$ sudo apt-get install libusb-1.0-0-dev + + +Q3: Why do I get the following error when trying to build libcp210xmanufacturing? + +g++: not found + +A3: The libslabhidtouart library requires gcc, g++, and ld to compile and build +the library. + +On Ubuntu, install g++: +$ sudo apt-get install g++ + +- or - + +To install a g++ package with support for 32-bit and 64-bit builds: +$ sudo apt-get install g++-multilib + + +Q12: How can I tell if a binary is built for 32-bit or 64-bit? + + To specify which x86 architecture to build, use the following: + make LIB_ARCH=32 + - or - + make LIB_ARCH=64 + +A12: Use the file command to display the binary format + +$ file libslabhidtouart.so.1.0 + + +Q13: I've done everything here and I still can't build using make + +A13: Sometimes you might need to rebuild the project after installing new +header files and libraries or to rebuild object files. + +$ make clean +$ make + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/ReadMe.txt b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/ReadMe.txt new file mode 100644 index 0000000..41784ee --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/ReadMe.txt @@ -0,0 +1,75 @@ +CP210xManufacturing Library for CP210x +-------------------------------------- + +Silicon Labs provides a source package for building +the CP210xManufacturing library for linux. + + +Uncompressing the source package +-------------------------------- + +$ tar -xf cp210xmanufacturing_1.0.tar.gz + +Source Package Contents +----------------------- + +- /common/ - OS abstraction +- /cp210xmanufacturing/include/ - Header files that declare the interface for the CP210xManufacturing library +- /cp210xmanufacturing/src/ - Source files for the manufacturing library +- /Makefile/ - Used to create the library. +- /doc/ - library documentation and rules file. + +Dependencies +------------ + +1. libusb-1.0 + +On Ubuntu: + + $ sudo apt-get install libusb-1.0-0-dev + +2. g++ + +On Ubuntu: + + $ sudo apt-get install g++ + +Building libcp210xmanufacturing +------------------------------- + +To create the CP210x manufacturing library for the current architecture (either x86_32 or x86_64): + $ make + +To install it at the default location (/usr/local): + $ sudo make install + +Configure Your System to Allow libusb to Access Your Device +----------------------------------------------------------- + +CP210xManufacturing uses libusb-1.0 to communicate with the CP210x devices over +USB. In order for CP210xManufacturing to recognize your device, you must first +copy a udev file to /etc/udev/rules.d/. This udev file will automatically +enable read and write permissions for a device with the specified USB vendor +ID. Unplug and replug your device after copying a udev file for the permissions +to take effect. On some systems, it may be necessary to reboot the machine +before the new rules are applied. + +CP2101 (VID: 0x10c4 PID: 0xea60): +- Copy SiliconLabs.rules to /etc/udev/rules.d/ + +Other: +- Modify an existing udev rules file for the required vendor ID + + SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", MODE="0666" + SUBSYSTEM=="usb_device", ATTRS{idVendor}=="10c4", MODE="0666" + + - or - (optionally add a required product ID) + + SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea80", MODE="0666" + SUBSYSTEM=="usb_device", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea80", MODE="0666" + +- SiliconLabs.rules does not specify the product ID and will therefore allow + read/write access to all Silicon Labs USB devices with the Silicon Labs VID (0x10c4). + The product ID is optional and will further restrict which devices the rules file + will affect. + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SharedObjectLibraryUsage.txt b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SharedObjectLibraryUsage.txt new file mode 100644 index 0000000..d084971 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SharedObjectLibraryUsage.txt @@ -0,0 +1,18 @@ +See more details at http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html + +To link against a shared object library (.so) using -l: +1. Install the library to /usr/local/lib: + + $ sudo make install + +To run an executable that was built against the shared object library (.so): +1. Set the library path to /usr/local/lib before running the executable + example: export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH + +To list the dependencies of an object file or binary: +example: ldd main + +To view a list of exported symbols from an object file or library: +example: nm -D libcp210xmanufacturing.so.1.0 +example (paginate displayed results): nm -D libcp210xmanufacturing.so.1.0 | less + diff --git a/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SiliconLabs.rules b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SiliconLabs.rules new file mode 100644 index 0000000..117c863 --- /dev/null +++ b/AN721SW/Linux/LibrarySourcePackages/cp210xmanufacturing/doc/SiliconLabs.rules @@ -0,0 +1,34 @@ +# This is a udev rules file for all USB devices with a Silicon Labs Vendor ID +# of 0x10c4. +# +# This file is based on the sample udev file from HIDAPI (using libusb-1.0). +# +# NOTE: This udev file will grant read and write access to ALL users, +# include non-privileged users, for ALL USB devices that have a matching +# Vendor ID according to the rules below. If this is not desirable and you +# would like to put more restrictions on access to these devices, then read +# http://reactivated.net/writing_udev_rules.html for more information. + +# This is a sample udev file for HIDAPI devices which changes the permissions +# to 0666 (world readable/writable) for a specified device on Linux systems. + +# If you are using the libusb implementation of hidapi (hid-libusb.c), then +# use something like the following line, substituting the VID and PID with +# those of your device. Note that for kernels before 2.6.24, you will need +# to substitute "usb" with "usb_device". It shouldn't hurt to use two lines +# (one each way) for compatibility with older systems. + +# HIDAPI/libusb +SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", MODE="0666" +SUBSYSTEM=="usb_device", ATTRS{idVendor}=="10c4", MODE="0666" + +# Once done, optionally rename this file for your device, and drop it into +# /etc/udev/rules.d and unplug and re-plug your device. This is all that is +# necessary to see the new permissions. Udev does not have to be restarted. + +# If you think permissions of 0666 are too loose, then see: +# http://reactivated.net/writing_udev_rules.html for more information on finer +# grained permission setting. For example, it might be sufficient to just +# set the group or user owner for specific devices (for example the plugdev +# group on some systems). + diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturing.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturing.h new file mode 100644 index 0000000..f8e18a7 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturing.h @@ -0,0 +1,16 @@ +///////////////////////////////////////////////////////////////////////////// +// CP210xManufacturing.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CP210x_MANUFACTURING_H +#define CP210x_MANUFACTURING_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" + +#include "CP210xManufacturingDLL.h" + +#endif // CP210x_MANUFACTURING_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturingDLL.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturingDLL.h new file mode 100644 index 0000000..f9da029 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP210xManufacturingDLL.h @@ -0,0 +1,865 @@ +#ifndef HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK +#define HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK + +#ifdef _WIN32 +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the CP210xDLL_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// CP210xDLL_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#ifdef CP210xDLL_EXPORTS +#define CP210xDLL_API +#else +#define CP210xDLL_API __declspec(dllimport) +#pragma comment (lib, "CP210xManufacturing.lib") +#endif +#else // !_WIN32 +#define CP210xDLL_API +#define WINAPI +#endif // !_WIN32 + +#if ! defined(_PREFAST_) +// For SAL annotations used below in this header file, for each annotation used, add a suitable "if not defined" no-op +// definition for it here so that the SAL annotations do not break builds in IDEs that do not have SAL-annotation support. +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Pre_defensive_) +#define _Pre_defensive_ +#endif // ! defined(_Pre_defensive_) +#endif // ! defined(_PREFAST_) + +// GetProductString() function flags +#define CP210x_RETURN_SERIAL_NUMBER 0x00 +#define CP210x_RETURN_DESCRIPTION 0x01 +#define CP210x_RETURN_FULL_PATH 0x02 + +// GetDeviceVersion() return codes +#define CP210x_CP2101_VERSION 0x01 +#define CP210x_CP2102_VERSION 0x02 +#define CP210x_CP2103_VERSION 0x03 +#define CP210x_CP2104_VERSION 0x04 +#define CP210x_CP2105_VERSION 0x05 +#define CP210x_CP2108_VERSION 0x08 +#define CP210x_CP2109_VERSION 0x09 +#define CP210x_CP2102N_QFN28_VERSION 0x20 +#define CP210x_CP2102N_QFN24_VERSION 0x21 +#define CP210x_CP2102N_QFN20_VERSION 0x22 + +// Return codes +#define CP210x_SUCCESS 0x00 +#define CP210x_DEVICE_NOT_FOUND 0xFF +#define CP210x_INVALID_HANDLE 0x01 +#define CP210x_INVALID_PARAMETER 0x02 +#define CP210x_DEVICE_IO_FAILED 0x03 +#define CP210x_FUNCTION_NOT_SUPPORTED 0x04 +#define CP210x_GLOBAL_DATA_ERROR 0x05 +#define CP210x_FILE_ERROR 0x06 +#define CP210x_COMMAND_FAILED 0x08 +#define CP210x_INVALID_ACCESS_TYPE 0x09 + +// Type definitions +typedef int CP210x_STATUS; + +// Buffer size limits +// +// +// CP2101/2/3/4/9 +#define CP210x_MAX_DEVICE_STRLEN 256 +#define CP210x_MAX_MANUFACTURER_STRLEN 45 + +#define CP210x_MAX_PRODUCT_STRLEN 126 +#define CP210x_MAX_SERIAL_STRLEN 63 +// +// CP2105 +#define CP2105_MAX_MANUFACTURER_STRLEN 12 +#define CP2105_MAX_PRODUCT_STRLEN 47 +#define CP2105_MAX_SERIAL_STRLEN 16 +#define CP2105_MAX_INTERFACE_STRLEN 32 +// +// CP2108 +#define CP2108_MAX_MANUFACTURER_STRLEN 126 +#define CP2108_MAX_PRODUCT_STRLEN 126 +#define CP2108_MAX_SERIAL_STRLEN 126 +#define CP2108_MAX_INTERFACE_STRLEN 126 +// +// CP2102N +#define CP2102N_MAX_ +// Type definitions +typedef char CP210x_DEVICE_STRING[CP210x_MAX_DEVICE_STRLEN]; +typedef char CP210x_MANUFACTURER_STRING[CP210x_MAX_MANUFACTURER_STRLEN]; +typedef char CP210x_PRODUCT_STRING[CP210x_MAX_PRODUCT_STRLEN]; +typedef char CP210x_SERIAL_STRING[CP210x_MAX_SERIAL_STRLEN]; +typedef char CP2105_INTERFACE_STRING[CP2105_MAX_INTERFACE_STRLEN]; +typedef char CP2108_INTERFACE_STRING[CP2108_MAX_INTERFACE_STRLEN]; + +#define CP210x_MAX_MAXPOWER 250 + + +// Baud Rate Aliasing definitions +// +#define NUM_BAUD_CONFIGS 32 +// +// Baud Config Structure +typedef struct +{ + WORD BaudGen; + WORD Timer0Reload; + BYTE Prescaler; + DWORD BaudRate; +} BAUD_CONFIG; +// +// Size of the Baud Config Structure +#define BAUD_CONFIG_SIZE 10 +// +// Array of all Baud Rate Configurations +typedef BAUD_CONFIG BAUD_CONFIG_DATA[NUM_BAUD_CONFIGS]; +// + + +// Flush Buffer definitions +// +// CP2104 +#define FC_OPEN_TX 0x01 // When these bits are set, the device will flush that buffer +#define FC_OPEN_RX 0x02 +#define FC_CLOSE_TX 0x04 +#define FC_CLOSE_RX 0x08 +// +// CP2105 - Standard Port +#define FC_OPEN_TX_SCI FC_OPEN_TX +#define FC_OPEN_RX_SCI FC_OPEN_RX +#define FC_CLOSE_TX_SCI FC_CLOSE_TX +#define FC_CLOSE_RX_SCI FC_CLOSE_RX +// +// CP2105 - Enhanced Port +#define FC_OPEN_TX_ECI 0x10 +#define FC_OPEN_RX_ECI 0x20 +#define FC_CLOSE_TX_ECI 0x40 +#define FC_CLOSE_RX_ECI 0x80 +// +// CP2108 +#define FC_OPEN_TX_IFC0 0x0001 +#define FC_OPEN_RX_IFC0 0x0002 +#define FC_CLOSE_TX_IFC0 0x0004 +#define FC_CLOSE_RX_IFC0 0x0008 +#define FC_OPEN_TX_IFC1 0x0010 +#define FC_OPEN_RX_IFC1 0x0020 +#define FC_CLOSE_TX_IFC1 0x0040 +#define FC_CLOSE_RX_IFC1 0x0080 +#define FC_OPEN_TX_IFC2 0x0100 +#define FC_OPEN_RX_IFC2 0x0200 +#define FC_CLOSE_TX_IFC2 0x0400 +#define FC_CLOSE_RX_IFC2 0x0800 +#define FC_OPEN_TX_IFC3 0x1000 +#define FC_OPEN_RX_IFC3 0x2000 +#define FC_CLOSE_TX_IFC3 0x4000 +#define FC_CLOSE_RX_IFC3 0x8000 + +// +//Port Config definitions +// + +// +// CP2103/4 Port Config Structure +// +typedef struct +{ + WORD Mode; // Push-Pull = 1, Open-Drain = 0 + WORD Reset_Latch; // Logic High = 1, Logic Low = =0 + WORD Suspend_Latch; // Logic High = 1, Logic Low = =0 + unsigned char EnhancedFxn; +} PORT_CONFIG; +// +// Define bit locations for Mode/Latch for Reset and Suspend structures +#define PORT_RI_ON 0x0001 +#define PORT_DCD_ON 0x0002 +#define PORT_DTR_ON 0x0004 +#define PORT_DSR_ON 0x0008 +#define PORT_TXD_ON 0x0010 +#define PORT_RXD_ON 0x0020 +#define PORT_RTS_ON 0x0040 +#define PORT_CTS_ON 0x0080 +// +#define PORT_GPIO_0_ON 0x0100 +#define PORT_GPIO_1_ON 0x0200 +#define PORT_GPIO_2_ON 0x0400 +#define PORT_GPIO_3_ON 0x0800 +// +#define PORT_SUSPEND_ON 0x4000 // Can't configure latch value +#define PORT_SUSPEND_BAR_ON 0x8000 // Can't configure latch value +// +// Define bit locations for EnhancedFxn +#define EF_GPIO_0_TXLED 0x01 // Under device control +#define EF_GPIO_1_RXLED 0x02 // Under device control +#define EF_GPIO_2_RS485 0x04 // Under device control +#define EF_RS485_INVERT 0x08 // RS485 Invert bit +#define EF_WEAKPULLUP 0x10 // Weak Pull-up on +#define EF_RESERVED_1 0x20 // Reserved, leave bit 5 cleared +#define EF_SERIAL_DYNAMIC_SUSPEND 0x40 // For 8 UART/Modem signals +#define EF_GPIO_DYNAMIC_SUSPEND 0x80 // For 4 GPIO signals +// + + +// +// CP2105 Dual Port Config Structure +// +typedef struct +{ + WORD Mode; // Push-Pull = 1, Open-Drain = 0 + WORD Reset_Latch; // Logic High = 1, Logic Low = =0 + WORD Suspend_Latch; // Logic High = 1, Logic Low = =0 + unsigned char EnhancedFxn_ECI; + unsigned char EnhancedFxn_SCI; + unsigned char EnhancedFxn_Device; +} DUAL_PORT_CONFIG; +// +// CP2105 Define bit locations for Mode/Latch for Reset and Suspend structures +#define PORT_RI_SCI_ON 0x0001 +#define PORT_DCD_SCI_ON 0x0002 +#define PORT_DTR_SCI_ON 0x0004 +#define PORT_DSR_SCI_ON 0x0008 +#define PORT_TXD_SCI_ON 0x0010 +#define PORT_RXD_SCI_ON 0x0020 +#define PORT_RTS_SCI_ON 0x0040 +#define PORT_CTS_SCI_ON 0x0080 +#define PORT_GPIO_0_SCI_ON 0x0002 +#define PORT_GPIO_1_SCI_ON 0x0004 +#define PORT_GPIO_2_SCI_ON 0x0008 +#define PORT_SUSPEND_SCI_ON 0x0001 // Can't configure latch value +// +#define PORT_RI_ECI_ON 0x0100 +#define PORT_DCD_ECI_ON 0x0200 +#define PORT_DTR_ECI_ON 0x0400 +#define PORT_DSR_ECI_ON 0x0800 +#define PORT_TXD_ECI_ON 0x1000 +#define PORT_RXD_ECI_ON 0x2000 +#define PORT_RTS_ECI_ON 0x4000 +#define PORT_CTS_ECI_ON 0x8000 +#define PORT_GPIO_0_ECI_ON 0x0400 +#define PORT_GPIO_1_ECI_ON 0x0800 +#define PORT_SUSPEND_ECI_ON 0x0100 // Can't configure latch value +// +// CP2105 Define bit locations for EnhancedFxn_ECI +#define EF_GPIO_0_TXLED_ECI 0x01 // Under device control +#define EF_GPIO_1_RXLED_ECI 0x02 // Under device control +#define EF_GPIO_1_RS485_ECI 0x04 // Under device control +#define EF_RS485_INVERT 0x08 // Under device control +#define EF_INVERT_SUSPEND_ECI 0x10 // RS485 Invert bit +#define EF_DYNAMIC_SUSPEND_ECI 0x40 // For GPIO signals +// +// CP2105 Define bit locations for EnhancedFxn_SCI +#define EF_GPIO_0_TXLED_SCI 0x01 // Under device control +#define EF_GPIO_1_RXLED_SCI 0x02 // Under device control +#define EF_INVERT_SUSPEND_SCI 0x10 // RS485 Invert bit +#define EF_DYNAMIC_SUSPEND_SCI 0x40 // For GPIO signals +// +// CP2105 Define bit locations for EnhancedFxn_Device +#define EF_WEAKPULLUP 0x10 // Weak Pull-up on +// + +// +// CP2108 Quad Port Config Structure +// +typedef struct +{ + WORD Mode_PB0; + WORD Mode_PB1; + WORD Mode_PB2; + WORD Mode_PB3; + WORD Mode_PB4; + + WORD LowPower_PB0; + WORD LowPower_PB1; + WORD LowPower_PB2; + WORD LowPower_PB3; + WORD LowPower_PB4; + + WORD Latch_PB0; + WORD Latch_PB1; + WORD Latch_PB2; + WORD Latch_PB3; + WORD Latch_PB4; +} QUAD_PORT_STATE; + +typedef struct +{ + QUAD_PORT_STATE Reset_Latch; + QUAD_PORT_STATE Suspend_Latch; + BYTE IPDelay_IFC0; + BYTE IPDelay_IFC1; + BYTE IPDelay_IFC2; + BYTE IPDelay_IFC3; + BYTE EnhancedFxn_IFC0; + BYTE EnhancedFxn_IFC1; + BYTE EnhancedFxn_IFC2; + BYTE EnhancedFxn_IFC3; + BYTE EnhancedFxn_Device; + BYTE ExtClk0Freq; + BYTE ExtClk1Freq; + BYTE ExtClk2Freq; + BYTE ExtClk3Freq; +} QUAD_PORT_CONFIG; + +// +// CP2108 Define bit locations for Mode/Latch for Reset and Suspend structures +// PB0 +#define PORT_TX0 0x0001 +#define PORT_RX0 0x0002 +#define PORT_RTS0 0x0004 +#define PORT_CTS0 0x0008 +#define PORT_DTR0 0x0010 +#define PORT_DSR0 0x0020 +#define PORT_DCD0 0x0040 +#define PORT_RI0 0x0080 +#define PORT_TX1 0x0100 +#define PORT_RX1 0x0200 +#define PORT_RTS1 0x0400 +#define PORT_CTS1 0x0800 +#define PORT_DTR1 0x1000 +#define PORT_DSR1 0x2000 +#define PORT_DCD1 0x4000 +#define PORT_RI1 0x8000 + +// PB1 +#define PORT_GPIO_0 0x0001 // (1<<0) +#define PORT_GPIO_1 0x0002 // (1<<1) +#define PORT_GPIO_2 0x0004 // (1<<2) +#define PORT_GPIO_3 0x0008 // etc. +#define PORT_GPIO_4 0x0010 +#define PORT_GPIO_5 0x0020 +#define PORT_GPIO_6 0x0040 +#define PORT_GPIO_7 0x0080 +#define PORT_GPIO_8 0x0100 +#define PORT_GPIO_9 0x0200 +#define PORT_GPIO_10 0x0400 +#define PORT_GPIO_11 0x0800 +#define PORT_GPIO_12 0x1000 +#define PORT_GPIO_13 0x2000 +#define PORT_GPIO_14 0x4000 +#define PORT_GPIO_15 0x8000 + +// PB2 +#define PORT_SUSPEND 0x0001 +#define PORT_SUSPEND_BAR 0x0002 +#define PORT_DTR2 0x0004 +#define PORT_DSR2 0x0008 + +// PB3 +#define PORT_TX2 0x0001 +#define PORT_RX2 0x0002 +#define PORT_RTS2 0x0004 +#define PORT_CTS2 0x0008 +#define PORT_DCD2 0x0010 +#define PORT_RI2 0x0020 +#define PORT_DTR3 0x0040 +#define PORT_DSR3 0x0080 +#define PORT_DCD3 0x0100 +#define PORT_RI3 0x0200 + +// PB4 +#define PORT_RTS3 0x0001 +#define PORT_CTS3 0x0002 +#define PORT_TX3 0x0004 +#define PORT_RX3 0x0008 + +// +// CP2108 Define bit locations for EnhancedFxn_IFCx +#define EF_IFC_GPIO_TXLED 0x01 +#define EF_IFC_GPIO_RXLED 0x02 +#define EF_IFC_GPIO_RS485 0x04 +// If the next bit is clear, GPIO1 is low while sending UART data. +// If it is set, GPIO1 is high while sending UART data, and low otherwise +#define EF_IFC_GPIO_RS485_LOGIC 0x08 +#define EF_IFC_GPIO_CLOCK 0x10 +#define EF_IFC_DYNAMIC_SUSPEND 0x40 + +// +// CP2108 Define bit locations for EnhancedFxn_Device +#define EF_DEVICE_WEAKPULLUP_RESET 0x10 +#define EF_DEVICE_WEAKPULLUP_SUSPEND 0x20 +#define EF_DEVICE_DYNAMIC_SUSPEND 0x40 +// +typedef unsigned char uint8_t; +// Firmware version structure. Not writeable by OEMs or end-users. +// Automatically populated by build infrastructure +typedef struct { + uint8_t major; + uint8_t minor; + uint8_t build; +} firmware_t, *pFirmware_t; + +#ifdef __cplusplus +extern "C" { +#endif + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetNumDevices( + _Out_writes_bytes_(4) _Pre_defensive_ LPDWORD lpdwNumDevices + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetProductString( + _In_ _Pre_defensive_ const DWORD dwDeviceNum, + LPVOID lpvDeviceString, + _In_ _Pre_defensive_ const DWORD dwFlags + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_Open( + _In_ _Pre_defensive_ DWORD dwDevice, + HANDLE* cyHandle + ); + +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_Close( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS WINAPI CP210x_GetPartNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(1) LPBYTE lpbPartNum + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetVid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wVid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetPid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wPid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetManufacturerString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvManufacturer, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetProductString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvProduct, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetInterfaceString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bInterfaceNumber, + _In_ _Pre_defensive_ LPVOID lpvInterface, + _In_ _Pre_defensive_ const BYTE bLength, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode + ); + +/// @brief Reprogram the Serial Number String in the device's USB Serial Number String Descriptor +/// @param cyHandle is an open handle to the device +/// @param lpvSerialNumber points at a buffer containing the Serial Number String to be reprogrammed to the device +/// @param bLength is the total number of characters in the Serial Number String +/// @param bConvertToUnicode is a true or false value indicating whether the Serial Number String is an 8-bit character ascii string needing converting to 16-bit UCS-2 characters (true) to not (false). +/// @note OTP parts can not often/indefinitely have configuration data (re-)written to them +/// @returns Returns CP210x_SUCCESS on success, another CP210x_STATUS if there is an error: +/// CP210x_INVALID_HANDLE -- cyHandle is invalid +/// CP210x_INVALID_PARAMETER -- lpvSerialNumber or bLength are unexpected values +/// CP210x_FUNCTION_NOT_SUPPORTED -- the device does not support setting of the Serial Number string +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetSerialNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPVOID lpvSerialNumber, + _In_ _Pre_defensive_ const BYTE bLengthInChars, + _In_ _Pre_defensive_ const BOOL bConvertToUnicode = TRUE + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetSelfPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BOOL bSelfPower + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetMaxPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bMaxPower + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetFlushBufferConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wFlushBufferConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDeviceMode( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bDeviceModeECI, + _In_ _Pre_defensive_ const BYTE bDeviceModeSCI + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDeviceVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const WORD wVersion + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetBaudRateConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ BAUD_CONFIG* baudConfigData + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ PORT_CONFIG* PortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetDualPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ DUAL_PORT_CONFIG* DualPortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetQuadPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ QUAD_PORT_CONFIG* QuadPortConfig + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetLockValue( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceVid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(2) LPWORD lpwVid + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDevicePid( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _Out_writes_bytes_(2) LPWORD lpwPid + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceManufacturerString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpManufacturer, + LPBYTE lpbLength, + _In_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceProductString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpProduct, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceInterfaceString( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ const BYTE bInterfaceNumber, + LPVOID lpInterface, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceSerialNumber( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPVOID lpSerialNumber, + LPBYTE lpbLength, + _In_ _Pre_defensive_ const BOOL bConvertToASCII = TRUE + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetSelfPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBOOL lpbSelfPower + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetMaxPower( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbPower + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetFlushBufferConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPWORD lpwFlushBufferConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceMode( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbDeviceModeECI, + LPBYTE lpbDeviceModeSCI + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDeviceVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPWORD lpwVersion + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetBaudRateConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + BAUD_CONFIG* pBaudConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + PORT_CONFIG* pPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetDualPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + DUAL_PORT_CONFIG* pDualPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetQuadPortConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + QUAD_PORT_CONFIG* pQuadPortConfig + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetLockValue( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbLockValue + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_Reset( + _In_ _Pre_defensive_ const HANDLE cyHandle + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_CreateHexFile( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPCSTR lpvFileName + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetFirmwareVersion( + _In_ _Pre_defensive_ const HANDLE cyHandle, + pFirmware_t lpVersion + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbConfig, + WORD bLength + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetConfig( + _In_ _Pre_defensive_ const HANDLE cyHandle, + _In_ _Pre_defensive_ LPBYTE lpbConfig, + _In_ _Pre_defensive_ const WORD bLength + ); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_UpdateFirmware( + _In_ _Pre_defensive_ const HANDLE cyHandle); + +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_GetGeneric( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbGeneric, + _In_ _Pre_defensive_ const WORD bLength + ); + +_Check_return_ +_Ret_range_(CP210x_SUCCESS, CP210x_DEVICE_NOT_FOUND) +_Success_(return == CP210x_SUCCESS) +CP210xDLL_API +CP210x_STATUS +WINAPI +CP210x_SetGeneric( + _In_ _Pre_defensive_ const HANDLE cyHandle, + LPBYTE lpbGeneric, + _In_ _Pre_defensive_ const WORD bLength + ); + +#ifdef __cplusplus +} +#endif + +#endif // !HOST_APPLICATIONS_DLLS_MANUFACTURINGDLL_CP210XMANUFACTURINGDLL_H_INCLUDED_XF3N9QM3BK diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP2114_Common.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP2114_Common.h new file mode 100644 index 0000000..1b2583b --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CP2114_Common.h @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------- +// CP2114_Common.h +//----------------------------------------------------------------------------- +// Copyright 2012 Silicon Laboratories, Inc. +// http://www.silabs.com +// +// Program Description: +// +// Header file shared by both CP2114 firmware and the Configurator. +// +// +// How To Test: See Readme.txt +// +// +// Target: C8051F381/T627 +// Tool chain: Keil C51 +// Silicon Laboratories IDE +// Command Line: See Readme.txt +// Project Name: CP2114 +// +//----------------------------------------------------------------------------- +#ifndef _CP2114_DATA_COMMON_H_ +#define _CP2114_DATA_COMMON_H_ + +//----------------------------------------------------------------------------- +// PART NUMBER AND VERSION INFO +//----------------------------------------------------------------------------- +#define PART_NUMBER 0x0E // 0x0E = 14, i.e. CP2114 + +// Versioning for CP-2114 Firmware, Device API and Configuration Block format. +// These elements are used to verify compatibility between the device and the +// Configurator. If API change is significant enough to require the Configurator +// to change, the firmware API version and the Configurator API version (the integer +// part) must be changed at the same time. Otherwise, Configurator won't connect to +// the device. +// +// Device FIRMWARE_VERSION DEV_API_VERSION CFG_FMT_VERSION +// ---------------------------------------------------------------------------- +// CP2114-B01-GM 0x07 0x05 0x01 +// CP2114-B02-GM 0x08 0x06 0x02 + +#define FIRMWARE_VERSION 0x08 // CP2114-B01: 0x07, CP2114-B02: 0x08 +#define DEV_API_VERSION 0x06 // CP2114-B01: 0x05, CP2114-B02: 0x06 +#define CFG_FMT_VERSION 0x02 // CP2114-B01: 0x01, CP2114-B02: 0x02 +// +// END OF VERSION INFO +// + +//-------------------------- +// Locations +//-------------------------- +// Locations must match settings of 'Project -> Toolchain -> Linker cmd line args' +#define DEFAULTDATA_ADDRESS 0x6600 +#define USERDATA_ADDRESS 0x6800 + +#define CUSTOM_DATA_SIZE (6*1024) + +// Global errors & status +// NOTE:Any changes to the following definitions must also be made in the firmware 'CP2114_Common.h' file. + +// Config errors +#define kInvalidConfigNumber 0x20 // Requested config number >= MAX_CONFIGS +#define kBootIndicesDepleted 0x21 // All Dev boot indexes have been used +#define kRequestedConfigNotPresent 0x22 // Pointer to requested Dev config is 0xFFFF +#define kRequestedConfigInvalid 0x23 // Config is invalid or not supported +#define kConfigPointersDepleted 0x24 // All Config pointer slots have been used +#define kConfigSpaceDepleted 0x25 // Not enough space to save the new config +#define kBootIndexUnchanged 0x26 // The user-specified boot index is already the current boot index +#define kConfigUnchanged 0x27 // The Config is already as the user requested +#define kConfigInvalidConfigIdentifier 0x28 // Identifier was not INBAND_IDENTIFIER_INIT/SUSPEND/ACTIVE +#define kConfigSettingsInvalid 0x29 // Configuration contains invalid setting(s) +#define kUnsupportedConfigFormat 0x2A // The config format version is not supported by library/firmware + +// 'Set Parameters for Next Get' errors +#define kInvalidNumberOfCachedParams 0x40 // Specified tSetParamsForNextGet.params > MAX_CACHED_PARAMS +#define kUnexpectedCacheData 0x41 // Something in tSetParamsForNextGet was not as expected + +// I2C errors +#define kI2cBusy 0x50 +#define kI2cTimeout 0x51 +#define kI2cInvalidToken 0x52 +#define kI2cInvalidWriteLength 0x53 +#define kI2cInvalidConfigLength 0x54 +#define kI2cSclStuckLow 0x55 +#define kI2cSdaStuckLow 0x56 + +//------------------------------------------------------- +// CP2114 Capabilities +//------------------------------------------------------- +typedef struct +{ + U8 availableBootIndices; + U8 availableOtpConfigs; + U8 currentBootConfig; + U8 availableOtpConfigSpace_LSB; + U8 availableOtpConfigSpace_MSB; +}tDeviceCaps; + +#define SIZE_DEVICE_CAPS (sizeof(tDeviceCaps)) + +// Returned by CP2114_GetVersions in config_version +#define CP2114_CONFIG_VERSION_B01 1 +#define CP2114_CONFIG_VERSION_B02 2 + +// NOTE: The firmware and this library code assumes that RAMConfig fits in +// one packet. Since byte[0] is the report ID, the maximum RAMConfig size +// (not including the 2-byte length) is 61 bytes. +#define MAX_RAM_CONFIG_SIZE (2 + 61) +#define RAM_CONFIG_SIZE_B01 30 // if config_version == CP2114_CONFIG_VERSION_B01 +#define RAM_CONFIG_SIZE_B02 50 // if config_version == CP2114_CONFIG_VERSION_B02 + +struct _RAM_CONFIG_STRUCT +{ + U16 Length; + U8 configData[MAX_RAM_CONFIG_SIZE]; +}; + +// Configuration Report ID's + +#define RESET_DEVICE 0x40 // Reset Device +#define GETSET_UART_ENABLE 0x41 // Get Set Receive Status +#define GET_UART_STATUS 0x42 // Get UART Status +#define PURGE_FIFOS 0x43 // Purge FIFOs +#define GET_GPIO_VALUES 0x44 // Get GPIO Values +#define SET_GPIO_VALUES 0x45 // Set GPIO Values +#define GET_VER_INFO 0x46 // Get Version Information +#define GETSET_LOCK_BYTE 0x47 // Get Set Lock Byte + +#define GETSET_UART_CONFIG 0x50 // Get Set UART Config +#define TRANS_LINE_BREAK 0x51 // Transmit Line Break +#define STOP_LINE_BREAK 0x52 // Stop Line Break + +#define GETSET_USB_CONFIG 0x60 // All customizable data that's not strings +#define GETSET_MANU1 0x61 // Get Set Manufacturing String 1 +#define GETSET_MANU2 0x62 // Get Set Manufacturing String 2 +#define GETSET_PROD1 0x63 // Get Set Product String 1 +#define GETSET_PROD2 0x64 // Get Set Product String 2 +#define GETSET_SERSTR 0x65 // Get Set Serial String +#define GETSET_PIN_CONFIG 0x66 // GPIO configuration + +// 2114 Specific commands Parameter Description +#define GET_DEVICE_STATUS 0x70 // none 1 byte sticky status, cleared in firmware on a read +#define GET_DEVICE_CAPS 0x71 // none Gets CP2114 capabilities +#define GET_RAM_CONFIG 0x72 // none Get current CP2114 Config from RAM +#define SET_RAM_CONFIG 0x73 // config till DAC pairs Set CP2114 Configuration to RAM +#define SET_DAC_REGISTERS 0x74 // register values Set DAC Config +#define GET_DAC_REGISTERS 0x75 // register addr/count Get DAC registers +#define GET_OTP_CONFIG 0x76 // index Return CP2114 OTP Config based on the current index +#define GET_DEVICE_VERSIONS 0x77 // none Return API version and firmware version +#define CREATE_OTP_CONFIG 0x78 // config block Create New Configuration Block for CP2114 +#define SET_BOOT_CONFIG 0x79 // index Set CP2114 Boot Configuration +#define SET_PARAMS_FOR_NEXT_GET 0x7A // Parameters to be used for subsequent Get +#define GET_OTP_ALLCONFIG 0x7B // Get OTP all configuration +#define SET_OTP_ALLCONFIG 0x7C // Set OTP all configuration +#define I2C_WRITE_DATA 0x7D // SLA,nWrite,data I2C Write operation +#define I2C_READ_DATA 0x7E // (Sent in Params block) I2C Read operation + +#define BUTTON_EVENT 0x80 // Report button status + +enum +{ + INBAND_IDENTIFIER_INIT = 0xF9, + INBAND_IDENTIFIER_SUSPEND = 0xFA, + INBAND_IDENTIFIER_ACTIVE = 0xFB, + INBAND_COMMAND_START = 0xFC, + INBAND_COMMAND_REENUMERATE = INBAND_COMMAND_START, + INBAND_COMMAND_DELAY_US = 0xFD, + INBAND_COMMAND_SET_GPIO = 0xFE, + INBAND_COMMAND_DELAY_MS = 0xFF, +}; + +#endif // _CP2114_COMMON_H_ + +//----------------------------------------------------------------------------- +// End Of File +//----------------------------------------------------------------------------- diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/CriticalSectionLock.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CriticalSectionLock.h new file mode 100644 index 0000000..1919f37 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/CriticalSectionLock.h @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////// +// CCriticalSectionLock.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef CRITICAL_SECTION_LOCK_H +#define CRITICAL_SECTION_LOCK_H + +#if defined(_WIN32) +#include "Types.h" +#elif defined(__APPLE__) +#include +#include +#include "Types.h" +#elif defined(__linux__) +#include "Types.h" +#include +#include +#include +#else + #error "error: Unsupported OS type" +#endif + +#include "silabs_sal.h" + +class CCriticalSectionLock +{ + // Constructor/Destructor +public: + inline CCriticalSectionLock() throw() + { +#if defined(_WIN32) + InitializeCriticalSection(&m_cs); +#else + pthread_mutexattr_t attr; + + // Create a mutex object with recursive behavior + // + // This means that you can call pthread_mutex_lock() + // more than once from the same thread before calling + // pthread_mutex_unlock(). + // + // Doing the same using the default mutex attributes + // would cause deadlock. + // + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_cs, &attr); + pthread_mutexattr_destroy(&attr); +#endif + } + inline ~CCriticalSectionLock() throw() + { +#if defined(_WIN32) + DeleteCriticalSection(&m_cs); +#else + pthread_mutex_destroy(&m_cs); +#endif + } + + // Public Methods +public: +#pragma warning(suppress: 26135) // The _Acquires_lock_() annotation seems like it is correct, but clearly isn't as Warning 26135 is still generated. TODO: resolve. + _Acquires_lock_(m_cs) + inline void Lock() throw() + { +#if defined(_WIN32) + EnterCriticalSection(&m_cs); +#else + pthread_mutex_lock(&m_cs); +#endif + } +#pragma warning(suppress: 26135) // The _Acquires_lock_() annotation seems like it is correct, but clearly isn't as Warning 26135 is still generated. TODO: resolve. + _Releases_lock_(m_cs) + inline void Unlock() throw() + { +#if defined(_WIN32) + LeaveCriticalSection(&m_cs); +#else + pthread_mutex_unlock(&m_cs); +#endif + } + + // Protected Members +protected: +#if defined(_WIN32) + CRITICAL_SECTION m_cs; +#else + pthread_mutex_t m_cs; +#endif +}; + +#endif // CRITICAL_SECTION_LOCK_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/Makefile b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Makefile new file mode 100644 index 0000000..8a0f0b7 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Makefile @@ -0,0 +1,72 @@ +########################################### +# Makefile for cp210xsmtsmt +# Requires libusb-1.0 +# Requires libuuid +# Requires libcp210xmanufacturing, libslabhidtouart +# libslabhidtosmbus, libslabhiddevice, libslab_usb_spi +# +# Silicon Labs +# Modified July 11th, 2016 +########################################### + +LIB_ARCH?=32 + +ARCHFLAG=-m$(LIB_ARCH) + +BUILD ?=../build +BUILDPATH ?=$(BUILD)/bin/x86_$(LIB_ARCH) +OBJPATH ?=$(BUILD)/obj/x86_$(LIB_ARCH) + +# required packages +PKG_CONFIG_DEPENDENCIES = libusb-1.0 + +CSRCS = +CPPSRCS = cp210xsmt.cpp +CPPSRCS += smt.cpp +CPPSRCS += util.cpp +CPPSRCS += OsDep.cpp + +COBJS=$(CSRCS:%.c=%.o) +CPPOBJS=$(CPPSRCS:%.cpp=%.o) + +OBJFILES = $(COBJS) $(CPPOBJS) + +OBJFULLPATHS=$(addprefix $(OBJPATH)/, $(OBJFILES)) + +EXENAME = cp210xsmt +EXEFULLPATH = $(BUILDPATH)/$(EXENAME) + +LIBS += -lcp210xmanufacturing +LIBS += -lslabhidtouart +LIBS += -lslabhidtosmbus +LIBS += -lslabhiddevice +LIBS += -lslab_usb_spi +LIBS += -luuid +LIBS += $(foreach deplib,$(PKG_CONFIG_DEPENDENCIES), `pkg-config --libs $(deplib)`) + + +CC ?= gcc +CFLAGS ?= -Wall -fPIC -g $(ARCHFLAG) $(INCLUDES) + +CXX ?= g++ +CXXFLAGS ?= -Wall -fPIC -g $(ARCHFLAG) $(INCLUDES) + +all: $(OBJPATH) $(BUILDPATH) $(EXEFULLPATH) + +$(OBJPATH): + mkdir -p $@ + +$(BUILDPATH): + mkdir -p $@ + +$(OBJPATH)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $(INCLUDES) $< -o $@ + +$(EXEFULLPATH): $(OBJFULLPATHS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ $(LIBS) $(LIBPATHS) -o $@ + + +clean: + rm -rf $(BUILD) + + diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.cpp b/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.cpp new file mode 100644 index 0000000..60c7427 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.cpp @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////// +// This is a Linux version of the O/S abstraction layer which implements +// O/S-dependent primitives and can help write portable apps. +///////////////////////////////////////////////////////////////////////////// + +#include "OsDep.h" +#include +#include // for usleep + +// Get system tick count in milliseconds +DWORD GetTickCount() +{ + DWORD count; + timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts)) + { + return 0; + } + + count = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + + return count; +} + +void Sleep( DWORD msec) +{ + usleep( msec * 1000); +} diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.h new file mode 100644 index 0000000..4f92f38 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/OsDep.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////// +// CCriticalSectionLock +///////////////////////////////////////////////////////////////////////////// + +#ifndef __OS_DEP_H__ +#define __OS_DEP_H__ + +#if defined(_WIN32) +#include "Types.h" +#else +#if defined(__APPLE__) +#include +#include +#include "Types.h" +#elif defined(__linux__) +#include "Types.h" +#include +#include +#include +#else + #error "error: Unsupported OS type" +#endif + +DWORD GetTickCount(); +void Sleep(DWORD msec); + +#endif // defined(_WIN32) + +#include "CriticalSectionLock.h" + +#endif // __OS_DEP_H__ diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/Profiler.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Profiler.h new file mode 100644 index 0000000..b9a2a9e --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Profiler.h @@ -0,0 +1,239 @@ +#pragma once + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// Custom User Options +///////////////////////////////////////////////////////////////////////////// + +// Enable or disable the profiler: TRUE or FALSE +#define ENABLE_PROFILER TRUE + +// CProfiler object symbol name used in DECLARE_PROFILER() +// Add this to your watch window to view timing information +// while in debug mode +#define PROFILER_NAME profiler + +// double total elapsed time used in DECLARE_TOTAL() +// Add this to your watch window to view total elapsed time +// while in debug mode +#define TOTAL_NAME total + +// Units of time: TIME_SECONDS, TIME_MILLISECONDS, or TIME_MICROSECONDS +#define TIME_UNITS TIME_SECONDS + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define TIME_SECONDS 1 +#define TIME_MILLISECONDS 1000 +#define TIME_MICROSECONDS 1000000 + +///////////////////////////////////////////////////////////////////////////// +// Macros +///////////////////////////////////////////////////////////////////////////// + +// START() - Reset the CProfiler object and record starting time +// LAP(expression) - Execute the specified expression +// - Record time elapsed from previous LAP() or START() call +// STOP(expression) - Execute the specified expression +// - Record time elapsed from previous LAP() or START() call +// and return the total elapsed time +// DUMP(filename) - Dump profiler information to the specified file + +#if (ENABLE_PROFILER) +#define START() PROFILER_NAME.Start("Start"); +#define LAP(expression) expression; PROFILER_NAME.Lap(#expression); +#define STOP(expression) expression; TOTAL_NAME = PROFILER_NAME.Stop(#expression); +#define DUMP(filename) PROFILER_NAME.Dump(filename); + +#define DECLARE_PROFILER() CProfiler PROFILER_NAME; +#define DECLARE_TOTAL() double TOTAL_NAME = 0.0f; +#else +#define START() +#define LAP(expression) expression; +#define STOP(expression) expression; +#define DUMP(filename) + +#define DECLARE_PROFILER() +#define DECLARE_TOTAL() +#endif + +///////////////////////////////////////////////////////////////////////////// +// Structures +///////////////////////////////////////////////////////////////////////////// + +struct ProfilerTimestamp +{ + double elapsed; + std::string comment; + double time; + + ProfilerTimestamp(double t, double e, std::string c) + : time(t) + { + elapsed = e; + comment = c; + } +}; + +///////////////////////////////////////////////////////////////////////////// +// CProfiler Class +///////////////////////////////////////////////////////////////////////////// + +class CProfiler +{ + // Constructor +public: + + CProfiler() + { + // Get the resolution of the system clock + clock_getres(CLOCK_MONOTONIC, &m_resolution); + + // Set initial capacity to 1000 to reduce time variations + // due to memory copy + m_timestamps.reserve(1000); + } + + // Public Methods +public: + + void Start(std::string comment = "") + { + m_timestamps.clear(); + + m_timestamps.push_back(ProfilerTimestamp(GetTime(), 0, comment)); + } + + // Return total time from Start to Stop + + double Stop(std::string comment = "") + { + double total; + + Lap(comment); + total = m_timestamps.back().time - m_timestamps.front().time; + + return total; + } + + // Return total time from Start to Stop + + double Elapsed() + { + double total; + + total = m_timestamps.back().time - m_timestamps.front().time; + + return total; + } + + // Return elapsed time from last Lap or Start + + double Lap(std::string comment = "") + { + double time = GetTime(); + double elapsed = time - m_timestamps.back().time; + + m_timestamps.push_back(ProfilerTimestamp(time, elapsed, comment)); + + return elapsed; + } + + // System uptime + + double GetTime() + { + double time; + timespec tp; + + clock_gettime(CLOCK_MONOTONIC, &tp); + + time = ((double)TIME_UNITS * (tp.tv_sec + (tp.tv_nsec / 1000000000.0f))); + + return time; + } + + void Dump(std::string filename) + { + std::fstream file; + + // Determine the unit string + std::string timeUnits; + +#if (TIME_UNITS == TIME_SECONDS) + timeUnits = "s"; +#elif (TIME_UNITS == TIME_MILLISECONDS) + timeUnits = "ms"; +#elif (TIME_UNITS == TIME_MICROSECONDS) + timeUnits = "us"; +#endif + + // Open the file for output + file.open(filename.c_str(), std::fstream::out); + + double resolution = (double)m_resolution.tv_sec + (m_resolution.tv_nsec / 1000000000.0f); + + // Log profiler header text + file << "Profiler Dump" << std::endl; + file << "-------------" << std::endl << std::endl; + file << "High Performance Counter Precision: " << ((double) TIME_UNITS * resolution) << " " << timeUnits << std::endl; + file << std::endl; + + size_t longestString = 0; + + // Get the length of the longest comment string + for (size_t i = 0; i < m_timestamps.size(); i++) + { + longestString = MAX(longestString, m_timestamps[i].comment.size()); + } + + // Set the number of digits to display after the decimal point + // to display up to nanoseconds + file.setf(std::ios::fixed); +#if (TIME_UNITS == TIME_SECONDS) + file.precision(9); +#elif (TIME_UNITS == TIME_MILLISECONDS) + file.precision(6); +#elif (TIME_UNITS == TIME_MICROSECONDS) + file.precision(3); +#endif + + // Output the comment and elapsed time for each timestamp entry + for (size_t i = 0; i < m_timestamps.size(); i++) + { + file << "Timestamp " << std::setw(5) << i << ": "; + + file << "Elapsed: " << std::setw(13) << m_timestamps[i].elapsed << " " << timeUnits << " "; + + // Display the line comment and space all elapsed times exactly 3 characters after the longest string + file << "Line: \"" << m_timestamps[i].comment << "\""; + + file << std::endl; + } + + // Display the total time elapsed + if (m_timestamps.size() > 0) + { + file << std::endl; + file << "Total Time: " << (m_timestamps.back().time - m_timestamps.front().time) << " " << timeUnits << std::endl; + } + + file.close(); + } + +public: + timespec m_resolution; + std::vector m_timestamps; +}; diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2110.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2110.h new file mode 100644 index 0000000..850787d --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2110.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////// +// SLABCP2110.h +// For SLABHIDtoUART.dll +// and Silicon Labs CP2110 HID to UART +///////////////////////////////////////////////////////////////////////////// +#ifndef SLAB_CP2110_H +#define SLAB_CP2110_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "SLABHIDtoUART.h" + +///////////////////////////////////////////////////////////////////////////// +// Pin Definitions +///////////////////////////////////////////////////////////////////////////// + +// Pin Config Mode Array Indices +#define CP2110_INDEX_GPIO_0_CLK 0 +#define CP2110_INDEX_GPIO_1_RTS 1 +#define CP2110_INDEX_GPIO_2_CTS 2 +#define CP2110_INDEX_GPIO_3_RS485 3 +#define CP2110_INDEX_GPIO_4_TX_TOGGLE 4 +#define CP2110_INDEX_GPIO_5_RX_TOGGLE 5 +#define CP2110_INDEX_GPIO_6 6 +#define CP2110_INDEX_GPIO_7 7 +#define CP2110_INDEX_GPIO_8 8 +#define CP2110_INDEX_GPIO_9 9 +#define CP2110_INDEX_TX 10 +#define CP2110_INDEX_SUSPEND 11 +#define CP2110_INDEX_SUSPEND_BAR 12 +// Size of the above array pointed to by pinConfig parameter in HidUart_SetPinConfig and HidUart_GetPinConfig +#define CP2110_PIN_CONFIG_SIZE 13 + +// Pin Bitmasks +#define CP2110_MASK_GPIO_0_CLK 0x0001 +#define CP2110_MASK_GPIO_1_RTS 0x0002 +#define CP2110_MASK_GPIO_2_CTS 0x0004 +#define CP2110_MASK_GPIO_3_RS485 0x0008 +#define CP2110_MASK_TX 0x0010 +#define CP2110_MASK_RX 0x0020 +#define CP2110_MASK_GPIO_4_TX_TOGGLE 0x0040 +#define CP2110_MASK_GPIO_5_RX_TOGGLE 0x0080 +#define CP2110_MASK_SUSPEND_BAR 0x0100 +// NA +#define CP2110_MASK_GPIO_6 0x0400 +#define CP2110_MASK_GPIO_7 0x0800 +#define CP2110_MASK_GPIO_8 0x1000 +#define CP2110_MASK_GPIO_9 0x2000 +#define CP2110_MASK_SUSPEND 0x4000 + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions +///////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// HidUart_SetPinConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetPinConfig(HID_UART_DEVICE device, BYTE* pinConfig, BOOL useSuspendValues, WORD suspendValue, WORD suspendMode, BYTE rs485Level, BYTE clkDiv); + +// HidUart_GetPinConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetPinConfig(HID_UART_DEVICE device, BYTE* pinConfig, BOOL* useSuspendValues, WORD* suspendValue, WORD* suspendMode, BYTE* rs485Level, BYTE* clkDiv); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SLAB_CP2110_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2112.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2112.h new file mode 100644 index 0000000..e7b660b --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2112.h @@ -0,0 +1,447 @@ +///////////////////////////////////////////////////////////////////////////// +// SLABCP2112.h +// For SLABHIDtoSMBus.dll version 1.4 +// and Silicon Labs CP2112 HID to SMBus +///////////////////////////////////////////////////////////////////////////// +#ifndef SLAB_CP2112_H +#define SLAB_CP2112_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" + +///////////////////////////////////////////////////////////////////////////// +// Tool-chain-dependent hacks +///////////////////////////////////////////////////////////////////////////// +#ifdef _WIN32 +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the HID_TO_SMBUS_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// HID_TO_SMBUS_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#if defined(HID_TO_SMBUS_EXPORTS) +#define HID_TO_SMBUS_API __declspec(dllexport) +#else +#define HID_TO_SMBUS_API __declspec(dllimport) +#pragma comment(lib, "SLABHIDtoSMBus.lib") +#endif // defined(HID_TO_SMBUS_EXPORTS) +#else // !_WIN32 +#define HID_TO_SMBUS_API +#define WINAPI +#endif // !_WIN32 + +// This is needed for any tool chain that doesn't have Microsoft code analysis +#if ! defined(_PREFAST_) +#if ! defined(_Use_decl_annotations_) +#define _Use_decl_annotations_ +#endif // ! defined(_Use_decl_annotations_) +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_In_opt_) +#define _In_opt_ +#endif // ! defined(_In_opt_) +#if ! defined(_Out_) +#define _Out_ +#endif // ! defined(_Out_) +#if ! defined(_In_range_) +#define _In_range_(lb,ub) +#endif // ! defined(_In_range_) +#if ! defined(_Out_range_) +#define _Out_range_(lb,ub) +#endif // ! defined(_Out_range_) +#if ! defined(_In_reads_bytes_) +#define _In_reads_bytes_(n) +#endif // ! defined(_In_reads_bytes_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Out_writes_bytes_opt_) +#define _Out_writes_bytes_opt_(n) +#endif // ! defined(_Out_writes_bytes_opt_) +#if ! defined(_Printf_format_string_) +#define _Printf_format_string_ +#endif // ! defined(_Printf_format_string_) +#endif // ! defined(_Check_return_) + +///////////////////////////////////////////////////////////////////////////// +// Return Code Definitions +///////////////////////////////////////////////////////////////////////////// + +// HID_SMBUS_STATUS +typedef int HID_SMBUS_STATUS; + +// HID_SMBUS_STATUS Return Codes +#define HID_SMBUS_SUCCESS 0x00 +#define HID_SMBUS_DEVICE_NOT_FOUND 0x01 +#define HID_SMBUS_INVALID_HANDLE 0x02 +#define HID_SMBUS_INVALID_DEVICE_OBJECT 0x03 +#define HID_SMBUS_INVALID_PARAMETER 0x04 +#define HID_SMBUS_INVALID_REQUEST_LENGTH 0x05 + +#define HID_SMBUS_READ_ERROR 0x10 +#define HID_SMBUS_WRITE_ERROR 0x11 +#define HID_SMBUS_READ_TIMED_OUT 0x12 +#define HID_SMBUS_WRITE_TIMED_OUT 0x13 +#define HID_SMBUS_DEVICE_IO_FAILED 0x14 +#define HID_SMBUS_DEVICE_ACCESS_ERROR 0x15 +#define HID_SMBUS_DEVICE_NOT_SUPPORTED 0x16 + +#define HID_SMBUS_UNKNOWN_ERROR 0xFF + +// HID_SMBUS_TRANSFER_S0 +typedef BYTE HID_SMBUS_S0; + +#define HID_SMBUS_S0_IDLE 0x00 +#define HID_SMBUS_S0_BUSY 0x01 +#define HID_SMBUS_S0_COMPLETE 0x02 +#define HID_SMBUS_S0_ERROR 0x03 + +// HID_SMBUS_TRANSFER_S1 +typedef BYTE HID_SMBUS_S1; + +// HID_SMBUS_TRANSFER_S0 = HID_SMBUS_S0_BUSY +#define HID_SMBUS_S1_BUSY_ADDRESS_ACKED 0x00 +#define HID_SMBUS_S1_BUSY_ADDRESS_NACKED 0x01 +#define HID_SMBUS_S1_BUSY_READING 0x02 +#define HID_SMBUS_S1_BUSY_WRITING 0x03 + +// HID_SMBUS_TRANSFER_S0 = HID_SMBUS_S0_ERROR +#define HID_SMBUS_S1_ERROR_TIMEOUT_NACK 0x00 +#define HID_SMBUS_S1_ERROR_TIMEOUT_BUS_NOT_FREE 0x01 +#define HID_SMBUS_S1_ERROR_ARB_LOST 0x02 +#define HID_SMBUS_S1_ERROR_READ_INCOMPLETE 0x03 +#define HID_SMBUS_S1_ERROR_WRITE_INCOMPLETE 0x04 +#define HID_SMBUS_S1_ERROR_SUCCESS_AFTER_RETRY 0x05 + +///////////////////////////////////////////////////////////////////////////// +// String Definitions +///////////////////////////////////////////////////////////////////////////// + +// Product String Types +#define HID_SMBUS_GET_VID_STR 0x01 +#define HID_SMBUS_GET_PID_STR 0x02 +#define HID_SMBUS_GET_PATH_STR 0x03 +#define HID_SMBUS_GET_SERIAL_STR 0x04 +#define HID_SMBUS_GET_MANUFACTURER_STR 0x05 +#define HID_SMBUS_GET_PRODUCT_STR 0x06 + +// String Lengths +#define HID_SMBUS_DEVICE_STRLEN 260 + +// HID_SMBUS_DEVICE_STR +typedef char HID_SMBUS_DEVICE_STR[HID_SMBUS_DEVICE_STRLEN]; + +///////////////////////////////////////////////////////////////////////////// +// SMBUS Definitions +///////////////////////////////////////////////////////////////////////////// + +// SMbus Configuration Limits +#define HID_SMBUS_MIN_BIT_RATE 1 +#define HID_SMBUS_MIN_TIMEOUT 0 +#define HID_SMBUS_MAX_TIMEOUT 1000 +#define HID_SMBUS_MAX_RETRIES 1000 +#define HID_SMBUS_MIN_ADDRESS 0x02 +#define HID_SMBUS_MAX_ADDRESS 0xFE + +// Read/Write Limits +#define HID_SMBUS_MIN_READ_REQUEST_SIZE 1 +#define HID_SMBUS_MAX_READ_REQUEST_SIZE 512 +#define HID_SMBUS_MIN_TARGET_ADDRESS_SIZE 1 +#define HID_SMBUS_MAX_TARGET_ADDRESS_SIZE 16 +#define HID_SMBUS_MAX_READ_RESPONSE_SIZE 61 +#define HID_SMBUS_MIN_WRITE_REQUEST_SIZE 1 +#define HID_SMBUS_MAX_WRITE_REQUEST_SIZE 61 + +///////////////////////////////////////////////////////////////////////////// +// GPIO Definitions +///////////////////////////////////////////////////////////////////////////// + +// GPIO Pin Direction Bit Value +#define HID_SMBUS_DIRECTION_INPUT 0 +#define HID_SMBUS_DIRECTION_OUTPUT 1 + +// GPIO Pin Mode Bit Value +#define HID_SMBUS_MODE_OPEN_DRAIN 0 +#define HID_SMBUS_MODE_PUSH_PULL 1 + +// GPIO Function Bitmask +#define HID_SMBUS_MASK_FUNCTION_GPIO_7_CLK 0x01 +#define HID_SMBUS_MASK_FUNCTION_GPIO_0_TXT 0x02 +#define HID_SMBUS_MASK_FUNCTION_GPIO_1_RXT 0x04 + +// GPIO Function Bit Value +#define HID_SMBUS_GPIO_FUNCTION 0 +#define HID_SMBUS_SPECIAL_FUNCTION 1 + +// GPIO Pin Bitmask +#define HID_SMBUS_MASK_GPIO_0 0x01 +#define HID_SMBUS_MASK_GPIO_1 0x02 +#define HID_SMBUS_MASK_GPIO_2 0x04 +#define HID_SMBUS_MASK_GPIO_3 0x08 +#define HID_SMBUS_MASK_GPIO_4 0x10 +#define HID_SMBUS_MASK_GPIO_5 0x20 +#define HID_SMBUS_MASK_GPIO_6 0x40 +#define HID_SMBUS_MASK_GPIO_7 0x80 + +///////////////////////////////////////////////////////////////////////////// +// Part Number Definitions +///////////////////////////////////////////////////////////////////////////// + +// Part Numbers +#define HID_SMBUS_PART_CP2112 0x0C + +///////////////////////////////////////////////////////////////////////////// +// User Customization Definitions +///////////////////////////////////////////////////////////////////////////// + +// User-Customizable Field Lock Bitmasks +#define HID_SMBUS_LOCK_VID 0x01 +#define HID_SMBUS_LOCK_PID 0x02 +#define HID_SMBUS_LOCK_POWER 0x04 +#define HID_SMBUS_LOCK_POWER_MODE 0x08 +#define HID_SMBUS_LOCK_RELEASE_VERSION 0x10 +#define HID_SMBUS_LOCK_MFG_STR 0x20 +#define HID_SMBUS_LOCK_PRODUCT_STR 0x40 +#define HID_SMBUS_LOCK_SERIAL_STR 0x80 + +// Field Lock Bit Values +#define HID_SMBUS_LOCK_UNLOCKED 1 +#define HID_SMBUS_LOCK_LOCKED 0 + +// Power Max Value (500 mA) +#define HID_SMBUS_BUS_POWER_MAX 0xFA + +// Power Modes +#define HID_SMBUS_BUS_POWER 0x00 +#define HID_SMBUS_SELF_POWER_VREG_DIS 0x01 +#define HID_SMBUS_SELF_POWER_VREG_EN 0x02 + +// USB Config Bitmasks +#define HID_SMBUS_SET_VID 0x01 +#define HID_SMBUS_SET_PID 0x02 +#define HID_SMBUS_SET_POWER 0x04 +#define HID_SMBUS_SET_POWER_MODE 0x08 +#define HID_SMBUS_SET_RELEASE_VERSION 0x10 + +// USB Config Bit Values +#define HID_SMBUS_SET_IGNORE 0 +#define HID_SMBUS_SET_PROGRAM 1 + +// String Lengths +#define HID_SMBUS_CP2112_MFG_STRLEN 30 +#define HID_SMBUS_CP2112_PRODUCT_STRLEN 30 +#define HID_SMBUS_CP2112_SERIAL_STRLEN 30 + +// HID_SMBUS_MFG_STR +typedef char HID_SMBUS_CP2112_MFG_STR[HID_SMBUS_CP2112_MFG_STRLEN]; + +// HID_SMBUS_PRODUCT_STR +typedef char HID_SMBUS_CP2112_PRODUCT_STR[HID_SMBUS_CP2112_PRODUCT_STRLEN]; + +// HID_SMBUS_SERIAL_STR +typedef char HID_SMBUS_CP2112_SERIAL_STR[HID_SMBUS_CP2112_SERIAL_STRLEN]; + +///////////////////////////////////////////////////////////////////////////// +// Typedefs +///////////////////////////////////////////////////////////////////////////// + +typedef void* HID_SMBUS_DEVICE; + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions +///////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// HidSmbus_GetNumDevices +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetNumDevices(DWORD* numDevices, WORD vid, WORD pid); + +// HidSmbus_GetString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetString(DWORD deviceNum, WORD vid, WORD pid, char* deviceString, DWORD options); + +// HidSmbus_GetOpenedString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetOpenedString(HID_SMBUS_DEVICE device, char* deviceString, DWORD options); + +// HidSmbus_GetIndexedString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetIndexedString(DWORD deviceNum, WORD vid, WORD pid, DWORD stringIndex, char* deviceString); + +// HidSmbus_GetOpenedIndexedString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetOpenedIndexedString(HID_SMBUS_DEVICE device, DWORD stringIndex, char* deviceString); + +// HidSmbus_GetAttributes +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetAttributes(DWORD deviceNum, WORD vid, WORD pid, WORD* deviceVid, WORD* devicePid, WORD* deviceReleaseNumber); + +// HidSmbus_GetOpenedAttributes +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetOpenedAttributes(HID_SMBUS_DEVICE device, WORD* deviceVid, WORD* devicePid, WORD* deviceReleaseNumber); + +// HidSmbus_Open +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_Open(HID_SMBUS_DEVICE* device, DWORD deviceNum, WORD vid, WORD pid); + +// HidSmbus_Close +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_Close(HID_SMBUS_DEVICE device); + +// HidSmbus_IsOpened +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_IsOpened(HID_SMBUS_DEVICE device, BOOL* opened); + +// HidSmbus_ReadRequest +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_ReadRequest(HID_SMBUS_DEVICE device, BYTE slaveAddress, WORD numBytesToRead); + +// HidSmbus_AddressReadRequest +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_AddressReadRequest(HID_SMBUS_DEVICE device, BYTE slaveAddress, WORD numBytesToRead, BYTE targetAddressSize, BYTE targetAddress[16]); + +// HidSmbus_ForceReadResponse +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_ForceReadResponse(HID_SMBUS_DEVICE device, WORD numBytesToRead); + +// HidSmbus_ForceReadResponse +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetReadResponse(HID_SMBUS_DEVICE device, HID_SMBUS_S0* status, BYTE* buffer, BYTE bufferSize, BYTE* numBytesRead); + +// HidSmbus_WriteRequest +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_WriteRequest(HID_SMBUS_DEVICE device, BYTE slaveAddress, BYTE* buffer, BYTE numBytesToWrite); + +// HidSmbus_TransferStatusRequest +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_TransferStatusRequest(HID_SMBUS_DEVICE device); + +// HidSmbus_GetTransferStatusResponse +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetTransferStatusResponse(HID_SMBUS_DEVICE device, HID_SMBUS_S0* status, HID_SMBUS_S1* detailedStatus, WORD* numRetries, WORD* bytesRead); + +// HidSmbus_CancelTransfer +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_CancelTransfer(HID_SMBUS_DEVICE device); + +// HidSmbus_CancelIo +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_CancelIo(HID_SMBUS_DEVICE device); + +// HidSmbus_SetTimeouts +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetTimeouts(HID_SMBUS_DEVICE device, DWORD responseTimeout); + +// HidSmbus_GetTimeouts +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetTimeouts(HID_SMBUS_DEVICE device, DWORD* responseTimeout); + +// HidSmbus_SetSmbusConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetSmbusConfig(HID_SMBUS_DEVICE device, DWORD bitRate, BYTE address, BOOL autoReadRespond, WORD writeTimeout, WORD readTimeout, BOOL sclLowTimeout, WORD transferRetries); + +// HidSmbus_GetSmbusConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetSmbusConfig(HID_SMBUS_DEVICE device, DWORD* bitRate, BYTE* address, BOOL* autoReadRespond, WORD* writeTimeout, WORD* readTimeout, BOOL* sclLowtimeout, WORD* transferRetries); + +// HidSmbus_Reset +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_Reset(HID_SMBUS_DEVICE device); + +// HidSmbus_SetGpioConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetGpioConfig(HID_SMBUS_DEVICE device, BYTE direction, BYTE mode, BYTE function, BYTE clkDiv); + +// HidSmbus_GetGpioConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetGpioConfig(HID_SMBUS_DEVICE device, BYTE* direction, BYTE* mode, BYTE* function, BYTE* clkDiv); + +// HidSmbus_ReadLatch +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_ReadLatch(HID_SMBUS_DEVICE device, BYTE* latchValue); + +// HidSmbus_WriteLatch +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_WriteLatch(HID_SMBUS_DEVICE device, BYTE latchValue, BYTE latchMask); + +// HidSmbus_GetPartNumber +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetPartNumber(HID_SMBUS_DEVICE device, BYTE* partNumber, BYTE* version); + +// HidSmbus_GetLibraryVersion +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetLibraryVersion(BYTE* major, BYTE* minor, BOOL* release); + +// HidSmbus_GetHidLibraryVersion +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetHidLibraryVersion(BYTE* major, BYTE* minor, BOOL* release); + +// HidSmbus_GetHidGuid +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetHidGuid(void* guid); + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions - Device Customization +///////////////////////////////////////////////////////////////////////////// + +// HidSmbus_SetLock +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetLock(HID_SMBUS_DEVICE device, BYTE lock); + +// HidSmbus_GetLock +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetLock(HID_SMBUS_DEVICE device, BYTE* lock); + +// HidSmbus_SetUsbConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetUsbConfig(HID_SMBUS_DEVICE device, WORD vid, WORD pid, BYTE power, BYTE powerMode, WORD releaseVersion, BYTE mask); + +// HidSmbus_GetUsbConfig +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetUsbConfig(HID_SMBUS_DEVICE device, WORD* vid, WORD* pid, BYTE* power, BYTE* powerMode, WORD* releaseVersion); + +// HidSmbus_SetManufacturingString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetManufacturingString(HID_SMBUS_DEVICE device, char* manufacturingString, BYTE strlen); + +// HidSmbus_GetManufacturingString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetManufacturingString(HID_SMBUS_DEVICE device, char* manufacturingString, BYTE* strlen); + +// HidSmbus_SetProductString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetProductString(HID_SMBUS_DEVICE device, char* productString, BYTE strlen); + +// HidSmbus_GetProductString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetProductString(HID_SMBUS_DEVICE device, char* productString, BYTE* strlen); + +// HidSmbus_SetSerialString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_SetSerialString(HID_SMBUS_DEVICE device, char* serialString, BYTE strlen); + +// HidSmbus_GetSerialString +HID_TO_SMBUS_API HID_SMBUS_STATUS WINAPI +HidSmbus_GetSerialString(HID_SMBUS_DEVICE device, char* serialString, BYTE* strlen); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SLAB_CP2112_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2114.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2114.h new file mode 100644 index 0000000..e56593d --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABCP2114.h @@ -0,0 +1,213 @@ +///////////////////////////////////////////////////////////////////////////// +// SLABCP2114.h +// For SLABHIDtoUART.dll +// and Silicon Labs CP2114 HID to UART +///////////////////////////////////////////////////////////////////////////// +#ifndef SLAB_CP2114_H +#define SLAB_CP2114_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "SLABHIDtoUART.h" +#include "CP2114_Common.h" + +///////////////////////////////////////////////////////////////////////////// +// Return Code Definitions +///////////////////////////////////////////////////////////////////////////// + +// Errors associated with Config +#define HID_UART_INVALID_CONFIG_NUMBER kInvalidConfigNumber // Requested config number >= MAX_CONFIGS +#define HID_UART_BOOT_INDEXES_DEPLETED kBootIndicesDepleted // All boot indices have been used +#define HID_UART_REQUESTED_CONFIG_NOT_PRESENT kRequestedConfigNotPresent // Pointer to requested config is 0xFFFF +#define HID_UART_CONFIG_INVALID kRequestedConfigInvalid // Specified config consists of invalid parameters +#define HID_UART_CONFIG_POINTERS_DEPLETED kConfigPointersDepleted // All Config pointer slots have been used +#define HID_UART_CONFIG_SPACE_DEPLETED kConfigSpaceDepleted // Not enough space to save the new config +#define HID_UART_BOOT_INDEX_UNCHANGED kBootIndexUnchanged // The user-specified boot index is already the current boot index +#define HID_UART_CONFIG_UNCHANGED kConfigUnchanged // The Config is already as the user requested +#define HID_UART_INVALID_CONFIG_SEQUENCE_IDENTIFIER kConfigInvalidConfigIdentifier // Invalid Config string ID +#define HID_UART_INVALID_CONFIG_SETTINGS kConfigSettingsInvalid // Configuration contains invalid setting(s) +#define HID_UART_UNSUPPORTED_CONFIG_FORMAT kUnsupportedConfigFormat // The config format version is not supported by library/firmware + +// 'Set Parameters for Next Get' errors +#define HID_UART_INVALID_NUMBER_OF_CACHED_PARAMS kInvalidNumberOfCachedParams// Specified tSetParamsForNextGet.params > MAX_CACHED_PARAMS +#define HID_UART_UNEXPECTED_CACHE_DATA kUnexpectedCacheData // Something in tSetParamsForNextGet was not as expected + +// I2C Errors +#define HID_UART_I2C_BUSY kI2cBusy // I2C bus is busy +#define HID_UART_I2C_TIMEOUT kI2cTimeout // Timeout waiting for I2C event (start, ACK, etc.) +#define HID_UART_I2C_INVALID_TOKEN kI2cInvalidToken // I2C interpreter detected invalid token +#define HID_UART_I2C_INVALID_WRITE_LENGTH kI2cInvalidWriteLength // Specified number of bytes to write is 0 or too large +#define HID_UART_I2C_INVALID_CONFIG_LENGTH kI2cInvalidConfigLength // Specified configuration length is invalid +#define HID_UART_I2C_SCL_STUCK_LOW kI2cSclStuckLow // SCL line is stuck low +#define HID_UART_I2C_SDA_STUCK_LOW kI2cSdaStuckLow // SDA line is stuck low + + +///////////////////////////////////////////////////////////////////////////// +// Pin Definitions +///////////////////////////////////////////////////////////////////////////// + +// Pin Config Mode Array Indices +#define CP2114_INDEX_GPIO_0 0 +#define CP2114_INDEX_GPIO_1 1 +#define CP2114_INDEX_GPIO_2 2 +#define CP2114_INDEX_GPIO_3 3 +#define CP2114_INDEX_GPIO_4 4 +#define CP2114_INDEX_GPIO_5 5 +#define CP2114_INDEX_GPIO_6 6 +#define CP2114_INDEX_GPIO_7 7 +#define CP2114_INDEX_GPIO_8 8 +#define CP2114_INDEX_GPIO_9 9 +#define CP2114_INDEX_TX 10 +#define CP2114_INDEX_RX 11 +#define CP2114_INDEX_SUSPEND 12 +#define CP2114_INDEX_SUSPEND_BAR 13 +// Size of the above array pointed to by pinConfig parameter in CP2114_SetPinConfig and CP2114_GetPinConfig +#define CP2114_PIN_CONFIG_SIZE 14 + +// Pin Bitmasks +#define CP2114_MASK_GPIO_0 0x0001 +#define CP2114_MASK_GPIO_1 0x0002 +#define CP2114_MASK_GPIO_2 0x0004 +#define CP2114_MASK_GPIO_3 0x0008 +#define CP2114_MASK_GPIO_4 0x0010 +#define CP2114_MASK_GPIO_5 0x0020 +#define CP2114_MASK_GPIO_6 0x0040 +#define CP2114_MASK_GPIO_7 0x0080 +#define CP2114_MASK_GPIO_8 0x0100 +#define CP2114_MASK_GPIO_9 0x0200 +#define CP2114_MASK_TX 0x0400 +#define CP2114_MASK_RX 0x0800 +#define CP2114_MASK_SUSPEND 0x1000 +#define CP2114_MASK_SUSPEND_BAR 0x2000 + +///////////////////////////////////////////////////////////////////////////// +// DAC Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_DAC_CONFIG_SIZE (2*512 - sizeof(CP2114_RAM_CONFIG_STRUCT)) + +// 60 is the largest common multiple of 2, 3 and 4. This ensures that +// an I2C transactions contained in the SET/GET_DAC_REGISTERS payload +// will not be split across multiple frames. +#define DAC_REGISTERS_PAYLOAD_MAX_LEN 60 + +///////////////////////////////////////////////////////////////////////////// +// Typedefs +///////////////////////////////////////////////////////////////////////////// + +typedef tDeviceCaps CP2114_CAPS_STRUCT, *PCP2114_CAPS_STRUCT; +typedef _RAM_CONFIG_STRUCT CP2114_RAM_CONFIG_STRUCT, *PCP2114_RAM_CONFIG_STRUCT; + +///////////////////////////////////////////////////////////////////////////// +// DAC Structures +///////////////////////////////////////////////////////////////////////////// + +typedef union _CP2114_OTP_CONFIG +{ + struct // if config_version == CP2114_CONFIG_VERSION_B01 + { + BYTE RemConfig[ RAM_CONFIG_SIZE_B01]; + BYTE DacConfig[ MAX_DAC_CONFIG_SIZE]; + } CP2114_B01; + struct // if config_version == CP2114_CONFIG_VERSION_B02 + { + BYTE PemConfig[ RAM_CONFIG_SIZE_B02]; + BYTE DacConfig[ MAX_DAC_CONFIG_SIZE]; + } CP2114_B02; + BYTE Other[ 0xffff]; // Max size that can be specified in 2 bytes +} CP2114_OTP_CONFIG, *PCP2114_OTP_CONFIG; + +typedef struct _CP2114_OTP_CONFIG_GET +{ + U16 Length; + CP2114_OTP_CONFIG OtpConfig; +} CP2114_OTP_CONFIG_GET, *PCP2114_OTP_CONFIG_GET; + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions +///////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +// CP2114_GetVersions +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetVersions(_In_ HID_UART_DEVICE device, _Out_writes_bytes_(1) BYTE* api_version, _Out_writes_bytes_(1) BYTE* fw_version, _Out_writes_bytes_(1) BYTE* config_version); + +// CP2114_SetPinConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_SetPinConfig(HID_UART_DEVICE device, BYTE* pinConfig, BOOL useSuspendValues, WORD suspendValue, WORD suspendMode, BYTE clkDiv); + +// CP2114_GetPinConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetPinConfig(HID_UART_DEVICE device, BYTE* pinConfig, BOOL* useSuspendValues, WORD* suspendValue, WORD* suspendMode, BYTE* clkDiv); + +// CP2114_GetDeviceStatus +// This function shouldn't be called in normal conditions. The other APIs call this function. +// However, due to possible reenumeration after HidUart_SetRamConfig, getCP2114Status can't be called +// immediately after HidUart_SetRamConfig, this can be used to clear possible ConfigUnchanged status +// prior to the next command. + +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetDeviceStatus(HID_UART_DEVICE device, BYTE *pCP2114Status); + +// CP2114_GetDeviceCaps +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetDeviceCaps(HID_UART_DEVICE device, PCP2114_CAPS_STRUCT pCP2114CapsStruct); + +// CP2114_SetRamConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_SetRamConfig(HID_UART_DEVICE device, PCP2114_RAM_CONFIG_STRUCT pCP2114RamConfigStruct); + +// CP2114_GetRamConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetRamConfig(HID_UART_DEVICE device, PCP2114_RAM_CONFIG_STRUCT pCP2114RamConfigStruct); + +// CP2114_SetDacRegisters +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_SetDacRegisters(HID_UART_DEVICE device, BYTE* pDacConfigBuffer, BYTE dacConfigBufferLength); + +// CP2114_GetDacRegisters +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetDacRegisters(HID_UART_DEVICE device, BYTE dacStartAddress, BYTE dacRegistersToRead, BYTE* pDacConfigBuffer); + +// CP2114_GetOtpConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_GetOtpConfig(HID_UART_DEVICE device, BYTE cp2114ConfigNumber, PCP2114_OTP_CONFIG_GET pCP2114ConfigStruct); + +// CP2114_CreateOtpConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_CreateOtpConfig(HID_UART_DEVICE device, WORD configBufferLength, BYTE* pConfigBuffer); + +// CP2114_SetBootConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_SetBootConfig(HID_UART_DEVICE device, BYTE cp2114ConfigNumber); + +// CP2114_ReadOTP +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_ReadOTP(HID_UART_DEVICE device, UINT cp2114Address ,BYTE* pReadBuffer, UINT ReadLength); + +// CP2114_WriteOTP +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_WriteOTP(HID_UART_DEVICE device, UINT cp2114Address ,BYTE* pWriteBuffer, UINT writeLength); + +// CP2114_I2cWriteData +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_I2cWriteData(HID_UART_DEVICE device, BYTE slaveAddress, BYTE* pWriteBuffer, BYTE writeLength); + +// CP2114_I2cReadData +HID_TO_UART_API HID_UART_STATUS WINAPI +CP2114_I2cReadData(HID_UART_DEVICE device, BYTE slaveAddress, BYTE* pWriteBuffer, BYTE WriteLength, BYTE* pReadBuffer, BYTE ReadLength); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SLAB_CP2114_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABHIDtoUART.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABHIDtoUART.h new file mode 100644 index 0000000..2246170 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLABHIDtoUART.h @@ -0,0 +1,465 @@ +///////////////////////////////////////////////////////////////////////////// +// SLABHIDtoUART.h +// For SLABHIDtoUART.dll +// and Silicon Labs CP2110/CP2114 HID to UART +///////////////////////////////////////////////////////////////////////////// +#ifndef SLAB_HID_TO_UART_H +#define SLAB_HID_TO_UART_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" + +///////////////////////////////////////////////////////////////////////////// +// Tool-chain-dependent hacks +///////////////////////////////////////////////////////////////////////////// +#ifdef _WIN32 +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the HID_TO_UART_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// HID_TO_UART_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#if defined(HID_TO_UART_EXPORTS) +#define HID_TO_UART_API __declspec(dllexport) +#else +#define HID_TO_UART_API __declspec(dllimport) +#pragma comment(lib, "SLABHIDtoUART.lib") +#endif // defined(HID_TO_UART_EXPORTS) +#else // !_WIN32 +#define HID_TO_UART_API +#define WINAPI +#endif // !_WIN32 + +// This is needed for any tool chain that doesn't have Microsoft code analysis +#if ! defined(_PREFAST_) +#if ! defined(_Use_decl_annotations_) +#define _Use_decl_annotations_ +#endif // ! defined(_Use_decl_annotations_) +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_In_opt_) +#define _In_opt_ +#endif // ! defined(_In_opt_) +#if ! defined(_Out_) +#define _Out_ +#endif // ! defined(_Out_) +#if ! defined(_In_range_) +#define _In_range_(lb,ub) +#endif // ! defined(_In_range_) +#if ! defined(_Out_range_) +#define _Out_range_(lb,ub) +#endif // ! defined(_Out_range_) +#if ! defined(_In_reads_bytes_) +#define _In_reads_bytes_(n) +#endif // ! defined(_In_reads_bytes_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Out_writes_bytes_opt_) +#define _Out_writes_bytes_opt_(n) +#endif // ! defined(_Out_writes_bytes_opt_) +#if ! defined(_Printf_format_string_) +#define _Printf_format_string_ +#endif // ! defined(_Printf_format_string_) +#endif // ! defined(_Check_return_) + +///////////////////////////////////////////////////////////////////////////// +// Return Code Definitions +///////////////////////////////////////////////////////////////////////////// + +// HID_UART_STATUS +typedef int HID_UART_STATUS; + +// Return Codes +#define HID_UART_SUCCESS 0x00 +#define HID_UART_DEVICE_NOT_FOUND 0x01 +#define HID_UART_INVALID_HANDLE 0x02 +#define HID_UART_INVALID_DEVICE_OBJECT 0x03 +#define HID_UART_INVALID_PARAMETER 0x04 +#define HID_UART_INVALID_REQUEST_LENGTH 0x05 + +#define HID_UART_READ_ERROR 0x10 +#define HID_UART_WRITE_ERROR 0x11 +#define HID_UART_READ_TIMED_OUT 0x12 +#define HID_UART_WRITE_TIMED_OUT 0x13 +#define HID_UART_DEVICE_IO_FAILED 0x14 +#define HID_UART_DEVICE_ACCESS_ERROR 0x15 +#define HID_UART_DEVICE_NOT_SUPPORTED 0x16 +#define HID_UART_INVALID_CONFIG_VERSION 0x17 + +#define HID_UART_UNKNOWN_ERROR 0xFF + +///////////////////////////////////////////////////////////////////////////// +// String Definitions +///////////////////////////////////////////////////////////////////////////// + +// Product String Types +#define HID_UART_GET_VID_STR 0x01 +#define HID_UART_GET_PID_STR 0x02 +#define HID_UART_GET_PATH_STR 0x03 +#define HID_UART_GET_SERIAL_STR 0x04 +#define HID_UART_GET_MANUFACTURER_STR 0x05 +#define HID_UART_GET_PRODUCT_STR 0x06 + +// String Lengths +#define HID_UART_DEVICE_STRLEN 260 + +// HID_UART_DEVICE_STR +typedef char HID_UART_DEVICE_STR[HID_UART_DEVICE_STRLEN]; + +///////////////////////////////////////////////////////////////////////////// +// UART Definitions +///////////////////////////////////////////////////////////////////////////// + +// Error Status +#define HID_UART_PARITY_ERROR 0x01 +#define HID_UART_OVERRUN_ERROR 0x02 + +// Line Break Status +#define HID_UART_LINE_BREAK_INACTIVE 0x00 +#define HID_UART_LINE_BREAK_ACTIVE 0x01 + +// Data Bits +#define HID_UART_FIVE_DATA_BITS 0x00 +#define HID_UART_SIX_DATA_BITS 0x01 +#define HID_UART_SEVEN_DATA_BITS 0x02 +#define HID_UART_EIGHT_DATA_BITS 0x03 + +// Parity +#define HID_UART_NO_PARITY 0x00 +#define HID_UART_ODD_PARITY 0x01 +#define HID_UART_EVEN_PARITY 0x02 +#define HID_UART_MARK_PARITY 0x03 +#define HID_UART_SPACE_PARITY 0x04 + +// Stop Bits +// Short = 1 stop bit +// Long = 1.5 stop bits (5 data bits) +// = 2 stop bits (6-8 data bits) +#define HID_UART_SHORT_STOP_BIT 0x00 +#define HID_UART_LONG_STOP_BIT 0x01 + +// Flow Control +#define HID_UART_NO_FLOW_CONTROL 0x00 +#define HID_UART_RTS_CTS_FLOW_CONTROL 0x01 + +// Read/Write Limits +#define HID_UART_MIN_READ_SIZE 1 +#define HID_UART_MAX_READ_SIZE 32768 +#define HID_UART_MIN_WRITE_SIZE 1 +#define HID_UART_MAX_WRITE_SIZE 4096 + +///////////////////////////////////////////////////////////////////////////// +// Part Number Definitions +///////////////////////////////////////////////////////////////////////////// + +// Part Numbers +#define HID_UART_PART_CP2110 0x0A +#define HID_UART_PART_CP2114 0x0E + +///////////////////////////////////////////////////////////////////////////// +// User Customization Definitions +///////////////////////////////////////////////////////////////////////////// + +// User-Customizable Field Lock Bitmasks +#define HID_UART_LOCK_PRODUCT_STR_1 0x0001 +#define HID_UART_LOCK_PRODUCT_STR_2 0x0002 +#define HID_UART_LOCK_SERIAL_STR 0x0004 +#define HID_UART_LOCK_PIN_CONFIG 0x0008 +#define HID_UART_LOCK_VID 0x0100 +#define HID_UART_LOCK_PID 0x0200 +#define HID_UART_LOCK_POWER 0x0400 +#define HID_UART_LOCK_POWER_MODE 0x0800 +#define HID_UART_LOCK_RELEASE_VERSION 0x1000 +#define HID_UART_LOCK_FLUSH_BUFFERS 0x2000 +#define HID_UART_LOCK_MFG_STR_1 0x4000 +#define HID_UART_LOCK_MFG_STR_2 0x8000 + +// Field Lock Bit Values +#define HID_UART_LOCK_UNLOCKED 1 +#define HID_UART_LOCK_LOCKED 0 + +// Power Max Value (500 mA) +#define HID_UART_BUS_POWER_MAX 0xFA + +// Power Modes +#define HID_UART_BUS_POWER 0x00 +#define HID_UART_SELF_POWER_VREG_DIS 0x01 +#define HID_UART_SELF_POWER_VREG_EN 0x02 + +// Flush Buffers Bitmasks +#define HID_UART_FLUSH_TX_OPEN 0x01 +#define HID_UART_FLUSH_TX_CLOSE 0x02 +#define HID_UART_FLUSH_RX_OPEN 0x04 +#define HID_UART_FLUSH_RX_CLOSE 0x08 + +// USB Config Bitmasks +#define HID_UART_SET_VID 0x01 +#define HID_UART_SET_PID 0x02 +#define HID_UART_SET_POWER 0x04 +#define HID_UART_SET_POWER_MODE 0x08 +#define HID_UART_SET_RELEASE_VERSION 0x10 +#define HID_UART_SET_FLUSH_BUFFERS 0x20 + +// USB Config Bit Values +#define HID_UART_SET_IGNORE 0 +#define HID_UART_SET_PROGRAM 1 + +// String Lengths +#define HID_UART_MFG_STRLEN 62 +#define HID_UART_PRODUCT_STRLEN 62 +#define HID_UART_SERIAL_STRLEN 30 + +// HID_UART_MFG_STR +typedef char HID_UART_MFG_STR[HID_UART_MFG_STRLEN]; + +// HID_UART_PRODUCT_STR +typedef char HID_UART_PRODUCT_STR[HID_UART_PRODUCT_STRLEN]; + +// HID_UART_SERIAL_STR +typedef char HID_UART_SERIAL_STR[HID_UART_SERIAL_STRLEN]; + +///////////////////////////////////////////////////////////////////////////// +// Pin Definitions +///////////////////////////////////////////////////////////////////////////// + +// Pin Config Modes +#define HID_UART_GPIO_MODE_INPUT 0x00 +#define HID_UART_GPIO_MODE_OUTPUT_OD 0x01 +#define HID_UART_GPIO_MODE_OUTPUT_PP 0x02 +#define HID_UART_GPIO_MODE_FUNCTION1 0x03 +#define HID_UART_GPIO_MODE_FUNCTION2 0x04 + +// Suspend Value Bit Values +#define HID_UART_VALUE_SUSPEND_LO 0 +#define HID_UART_VALUE_SUSPEND_HI 1 + +// Suspend Mode Bit Values +#define HID_UART_MODE_SUSPEND_OD 0 +#define HID_UART_MODE_SUSPEND_PP 1 + +// RS485 Active Levels +#define HID_UART_MODE_RS485_ACTIVE_LO 0x00 +#define HID_UART_MODE_RS485_ACTIVE_HI 0x01 + +///////////////////////////////////////////////////////////////////////////// +// Typedefs +///////////////////////////////////////////////////////////////////////////// + +typedef void* HID_UART_DEVICE; +typedef unsigned char U8; +typedef unsigned short U16; + +///////////////////////////////////////////////////////////////////////////// +// Exported Library Functions +///////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// HidUart_GetNumDevices +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetNumDevices(DWORD* numDevices, _In_ const WORD vid, _In_ const WORD pid); + +// HidUart_GetString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetString(DWORD deviceNum, WORD vid, WORD pid, char* deviceString, DWORD options); + +// HidUart_GetOpenedString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetOpenedString(HID_UART_DEVICE device, char* deviceString, DWORD options); + +// HidUart_GetIndexedString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetIndexedString(DWORD deviceNum, WORD vid, WORD pid, DWORD stringIndex, char* deviceString); + +// HidUart_GetOpenedIndexedString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetOpenedIndexedString(HID_UART_DEVICE device, DWORD stringIndex, char* deviceString); + +// HidUart_GetAttributes +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetAttributes(DWORD deviceNum, WORD vid, WORD pid, WORD* deviceVid, WORD* devicePid, WORD* deviceReleaseNumber); + +// HidUart_GetOpenedAttributes +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetOpenedAttributes(HID_UART_DEVICE device, WORD* deviceVid, WORD* devicePid, WORD* deviceReleaseNumber); + +// HidUart_Open +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_Open(HID_UART_DEVICE* device, DWORD deviceNum, WORD vid, WORD pid); + +// HidUart_Close +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_Close(HID_UART_DEVICE device); + +// HidUart_IsOpened +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_IsOpened(HID_UART_DEVICE device, BOOL* opened); + +// HidUart_SetUartEnable +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetUartEnable(HID_UART_DEVICE device, BOOL enable); + +// HidUart_GetUartEnable +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetUartEnable(HID_UART_DEVICE device, BOOL* enable); + +// HidUart_Read +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_Read(HID_UART_DEVICE device, BYTE* buffer, DWORD numBytesToRead, DWORD* numBytesRead); + +// HidUart_Write +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_Write(HID_UART_DEVICE device, BYTE* buffer, DWORD numBytesToWrite, DWORD* numBytesWritten); + +// HidUart_FlushBuffers +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_FlushBuffers(HID_UART_DEVICE device, BOOL flushTransmit, BOOL flushReceive); + +// HidUart_CancelIo +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_CancelIo(HID_UART_DEVICE device); + +// HidUart_SetTimeouts +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetTimeouts(HID_UART_DEVICE device, DWORD readTimeout, DWORD writeTimeout); + +// HidUart_GetTimeouts +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetTimeouts(HID_UART_DEVICE device, DWORD* readTimeout, DWORD* writeTimeout); + +// HidUart_GetUARTStatus +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetUartStatus(HID_UART_DEVICE device, WORD* transmitFifoSize, WORD* receiveFifoSize, BYTE* errorStatus, BYTE* lineBreakStatus); + +// HidUart_SetUARTConfig +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetUartConfig(_In_ HID_UART_DEVICE device, _In_ const DWORD baudRate, _In_ const BYTE dataBits, _In_ const BYTE parity, _In_ const BYTE stopBits, _In_ const BYTE flowControl); + +// HidUart_GetUARTConfig +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetUartConfig(HID_UART_DEVICE device, DWORD* baudRate, BYTE* dataBits, BYTE* parity, BYTE* stopBits, BYTE* flowControl); + +// HidUart_StartBreak +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_StartBreak(HID_UART_DEVICE device, BYTE duration); + +// HidUart_StopBreak +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_StopBreak(HID_UART_DEVICE device); + +// HidUart_Reset +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_Reset(HID_UART_DEVICE device); + +// HidUart_ReadLatch +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_ReadLatch(_In_ HID_UART_DEVICE device, WORD* latchValue); + +// HidUart_WriteLatch +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_WriteLatch(_In_ HID_UART_DEVICE device, _In_ const WORD latchValue, _In_ const WORD latchMask); + +// HidUart_GetPartNumber +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetPartNumber(HID_UART_DEVICE device, BYTE* partNumber, BYTE* version); + +// HidUart_GetLibraryVersion +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetLibraryVersion(_Out_writes_bytes_(1) BYTE* major, _Out_writes_bytes_(1) BYTE* minor, _Out_writes_bytes_(sizeof(BOOL)) BOOL* release); + +// HidUart_GetHidLibraryVersion +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetHidLibraryVersion(_Out_writes_bytes_(1) BYTE* major, _Out_writes_bytes_(1) BYTE* minor, _Out_writes_bytes_(sizeof(BOOL)) BOOL* release); + +// HidUart_GetHidGuid +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetHidGuid(_Out_ void* guid); + +// HidUart_SetLock +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetLock(HID_UART_DEVICE device, WORD lock); + +// HidUart_GetLock +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetLock(HID_UART_DEVICE device, WORD* lock); + +// HidUart_SetUsbConfig +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetUsbConfig(_In_ HID_UART_DEVICE device, _In_ const WORD vid, _In_ const WORD pid, _In_ const BYTE power, _In_ const BYTE powerMode, _In_ const WORD releaseVersion, _In_ const BYTE flushBuffers, _In_ const BYTE mask); + +// HidUart_GetUsbConfig +_Check_return_ +_Ret_range_(HID_UART_SUCCESS, HID_UART_UNKNOWN_ERROR) +_Success_(return == HID_UART_SUCCESS) +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetUsbConfig(HID_UART_DEVICE device, WORD* vid, WORD* pid, BYTE* power, BYTE* powerMode, WORD* releaseVersion, BYTE* flushBuffers); + +// HidUart_SetManufacturingString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetManufacturingString(HID_UART_DEVICE device, char* manufacturingString, BYTE strlen); + +// HidUart_GetManufacturingString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetManufacturingString(HID_UART_DEVICE device, char* manufacturingString, BYTE* strlen); + +// HidUart_SetProductString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetProductString(HID_UART_DEVICE device, char* productString, BYTE strlen); + +// HidUart_GetProductString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetProductString(HID_UART_DEVICE device, char* productString, BYTE* strlen); + +// HidUart_SetSerialString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_SetSerialString(HID_UART_DEVICE device, char* serialString, BYTE strlen); + +// HidUart_GetSerialString +HID_TO_UART_API HID_UART_STATUS WINAPI +HidUart_GetSerialString(HID_UART_DEVICE device, char* serialString, BYTE* strlen); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SLAB_HID_TO_UART_H diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLAB_USB_SPI.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLAB_USB_SPI.h new file mode 100644 index 0000000..e9981f7 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/SLAB_USB_SPI.h @@ -0,0 +1,610 @@ +//----------------------------------------------------------------------------- +// SLAB_USB_SPI.h +//----------------------------------------------------------------------------- +// Copyright 2012-2016 Silicon Laboratories Inc. +// http://www.silabs.com +//----------------------------------------------------------------------------- + +/// @file SLAB_USB_SPI.h +/// This file defines the API of the CP2130 Interface Library + +#ifndef SLAB_USB_SPI_H +#define SLAB_USB_SPI_H + +///////////////////////////////////////////////////////////////////////////// +// Includes +///////////////////////////////////////////////////////////////////////////// + +#include "Types.h" + +///////////////////////////////////////////////////////////////////////////// +// Variable types +///////////////////////////////////////////////////////////////////////////// +/// @name Variable type definitions +/// @{ +typedef void* CP213x_DEVICE; +typedef int USB_SPI_STATUS; +/// @} + +///////////////////////////////////////////////////////////////////////////// +// Definitions specific to USB SPI code +///////////////////////////////////////////////////////////////////////////// +/// @name Definitions specific to USB SPI code +/// @{ + +//#define LIBVERSION_MAJOR 1 +//#define LIBVERSION_MINOR 0 +//#define LIBVERSION_ISRELEASE true +#define LANGIDENG 0x0409 + + + +#define BULK_PACKETSIZE 64 +#define EP_BUFSIZE BULK_PACKETSIZE +#define CMD_SIZE 8 +#define CMD_TIMEOUT_MS 1000 // Timeout for completion of SPI command (i.e. first packet) +#define STRING_DESCRIPTOR_SIZE 256 +#define SIZE_PIN_CONFIG 20 + + +// Maximum block size for WriteRead +#define WRITEREAD_MAX_BLOCKSIZE 256 // Matches size of firmware Read buffer + +// Number of GPIO/CS pins +#define CP213x_NUM_GPIO 11 + +// Chip Select Mode: 0: Idle, 1: Active, 2: Active; all other channels idle +#define CSMODE_IDLE 0 +#define CSMODE_ACTIVE 1 +#define CSMODE_ACTIVE_OTHERS_IDLE 2 + +// Mode definitions for GPIO/CS/SpecialFunction pins +#define GPIO_MODE_INPUT 0 +#define GPIO_MODE_OUTPUT_OD 1 +#define GPIO_MODE_OUTPUT_PP 2 +#define GPIO_MODE_CHIPSELECT 3 // Chip select mode + +#define GPIO_MODE__RTR_ACTLOW 4 +#define GPIO_MODE__RTR_ACTHIGH 5 + +#define GPIO_MODE__EVTCNTR_RISING 4 +#define GPIO_MODE__EVTCNTR_FALLING 5 +#define GPIO_MODE__EVTCNTR_NEGPULSE 6 +#define GPIO_MODE__EVTCNTR_POSPULSE 7 + +#define GPIO_MODE__CLK_OUT 4 +#define GPIO_MODE__SPI_ACTIVITY 4 +#define GPIO_MODE__SUSPEND 4 +#define GPIO_MODE__SUSPENDBAR 4 + +// End of GPIO Mode definitions + + +// String Buffer Definitions +#define SHORT_STRING_LEN 60 +#define LONG_STRING_LEN_1 61 +#define LONG_STRING_LEN_2 63 +/// @} + +//////////////////////////////////////////////////////////////////////////////// +// SPI Command and Subcommand definitions +//////////////////////////////////////////////////////////////////////////////// + +/// @name SPI Data Transfer command and subcommands +/// @{ +#define CMD_TRANSFER_DATA 0x0000 + // Subcommand definitions for TRANSFER_DATA command + #define SUBCMD_READ 0 + #define SUBCMD_WRITE 1 + #define SUBCMD_WRITEREAD 2 + #define SUBCMD_RTREAD 4 + #define SUBCMD_MSB_RELEASE_BUS 0x80 +/// @} + +/// @name SPI Control Word bitfield definitions +/// @{ +// Bits 7-6: Not assigned + +// Bit 5: Clock phase (CPHA) +#define SPICTL_CPHA_SHIFT 5 +#define SPICTL_CPHA_MASK 0x20 +#define SPICTL_CPHA_LEADING_EDGE 0 +#define SPICTL_CPHA_TRAILING_EDGE 1 + +// Bit 4: Clock polarity (CPOL) +#define SPICTL_CPOL_SHIFT 4 +#define SPICTL_CPOL_MASK 0x10 +#define SPICTL_CPOL_ACTIVE_HIGH 0 +#define SPICTL_CPOL_ACTIVE_LOW 1 + +// Bit 3: Chip Select Mode +#define SPICTL_CSMODE_SHIFT 3 +#define SPICTL_CSMODE_MASK 0x08 +#define SPICTL_CSMODE_OPENDRAIN 0 +#define SPICTL_CSMODE_PUSHPULL 1 + +// Bit 2-0: Clock rate +#define SPICTL_CLKRATE_SHIFT 0 +#define SPICTL_CLKRATE_MASK 0x07 +#define SPICTL_CLKRATE_12M 0 // 12 MHz +#define SPICTL_CLKRATE_6M 1 // 6 MHz +#define SPICTL_CLKRATE_3M 2 // 3 MHz +#define SPICTL_CLKRATE_1M5 3 // 1.5 MHz +#define SPICTL_CLKRATE_750K 4 // 750 kHz +#define SPICTL_CLKRATE_375K 5 // 375 kHz +#define SPICTL_CLKRATE_187K5 6 // 187.5 kHz +#define SPICTL_CLKRATE_93K75 7 // 93.75 kHz +/// @} + +///////////////////////////////////////////////////////////////////////////// +// Error Definitions +///////////////////////////////////////////////////////////////////////////// + +/// @name Return values for BOOL-returning functions +/// @{ +#define bRESULT_PASS TRUE +#define bRESULT_FAIL FALSE +/// @} + +#define USB_SPI_ERRCODE_SYSTEM_ERROR 0xFFFFFFFE + +/// @name CP2130 General Errors +/// @{ + +#define USB_SPI_ERRCODE_SUCCESS 0x00 /// The function returned successfully. +#define USB_SPI_ERRCODE_ALLOC_FAILURE 0x01 /// Allocation error. +#define USB_SPI_ERRCODE_INVALID_ENUM_VALUE 0x02 /// Invalid enumeration value. +#define USB_SPI_ERRCODE_NULL_POINTER 0x03 /// Null pointer. +#define USB_SPI_ERRCODE_INVALID_CHANNEL_INDEX 0x04 /// Channel index is not in range. +#define USB_SPI_ERRCODE_INVALID_GPIO_MODE 0x05 /// Mode != INPUT, OUTPUT_OD, or OUTPUT_PP. + +#define USB_SPI_ERRCODE_UNKNOWN_ERROR 0xFFFFFFFF /// Unknown/unspecified error. +/// @} + +// +// API Errors +// +/// @name CP2130 API Errors +/// @{ +#define USB_SPI_ERRCODE_INVALID_PARAMETER 0x10 /// Invalid function parameter. + +#define USB_SPI_ERRCODE_INVALID_DEVICE_OBJECT 0x11 /// The specified device object pointer is invalid. +/// @} + +// +// Device Errors +// +/// @name CP2130 Device Errors +/// @{ +// The specified USB device could not be found. +#define USB_SPI_ERRCODE_DEVICE_NOT_FOUND 0x20 + +// The current USB device is not opened. +#define USB_SPI_ERRCODE_USB_DEVICE_NOT_OPENED 0x21 + +// The handle is invalid. +#define USB_SPI_ERRCODE_INVALID_HANDLE 0x22 +/// @} + +// +// Device Hardware Interface Errors +// +/// @name CP2130 Device Hardware Interface Errors +/// @{ +// An error occurred while communicating with the device or while retrieving device information. +#define USB_SPI_ERRCODE_HWIF_DEVICE_ERROR 0x30 + +// A control transfer operation timed out. +#define USB_SPI_ERRCODE_HWIF_TRANSFER_TIMEOUT 0x31 +/// @} + +/// @name CP2130 Data Transfer Errors +/// @{ + +#define USB_SPI_ERRCODE_CONTROL_TRANSFER_ERROR 0x50 +#define USB_SPI_ERRCODE_INVALID_TRANSFER_SIZE 0x51 + +#define USB_SPI_ERRCODE_PIPE_INIT_FAIL 0x60 +#define USB_SPI_ERRCODE_PIPE_QUERY_FAIL 0x61 +#define USB_SPI_ERRCODE_PIPE_WRITE_FAIL 0x62 +#define USB_SPI_ERRCODE_PIPE_READ_FAIL 0x63 +#define USB_SPI_ERRCODE_PIPE_ABORT_FAIL 0x64 +#define USB_SPI_ERRCODE_PIPE_FLUSH_FAIL 0x65 +#define USB_SPI_ERRCODE_PIPE_INVALID_ID 0x66 + +#define USB_SPI_ERRCODE_READ_THREAD_CREATE_FAILURE 0x70 +#define USB_SPI_ERRCODE_READ_THREAD_NOT_RUNNING 0x71 +#define USB_SPI_ERRCODE_READ_THREAD_START_FAILURE 0x72 + +#define USB_SPI_ERRCODE_DEVICE_RETURNED_TOO_MUCH_DATA 0x80 +/// @} + +/// @name CP213x Customization Masks +/// @{ +// User-Customizable Field Lock Bitmasks +#define CP213x_LOCK_PRODUCT_STR_1 0x0001 +#define CP213x_LOCK_PRODUCT_STR_2 0x0002 +#define CP213x_LOCK_SERIAL_STR 0x0004 +#define CP213x_LOCK_PIN_CONFIG 0x0008 + +#define CP213x_LOCK_VID 0x0100 +#define CP213x_LOCK_PID 0x0200 +#define CP213x_LOCK_POWER 0x0400 +#define CP213x_LOCK_POWER_MODE 0x0800 +#define CP213x_LOCK_RELEASE_VERSION 0x1000 +#define CP213x_LOCK_MFG_STR_1 0x2000 +#define CP213x_LOCK_MFG_STR_2 0x4000 +#define CP213x_LOCK_TRANSFER_PRIORITY 0x8000 + +// USB Config Bitmasks +#define CP213x_SET_VID 0x01 +#define CP213x_SET_PID 0x02 +#define CP213x_SET_POWER 0x04 +#define CP213x_SET_POWER_MODE 0x08 +#define CP213x_SET_RELEASE_VERSION 0x10 +#define CP213x_SET_TRANSFER_PRIORITY 0x80 + +// String Lengths +#define MFG_STRLEN 62 +#define PRODUCT_STRLEN 62 +#define SERIAL_STRLEN 30 +// MFG_STR +typedef char MFG_STR[MFG_STRLEN]; +// PRODUCT_STR +typedef char PRODUCT_STR[PRODUCT_STRLEN]; +// SERIAL_STR +typedef char SERIAL_STR[SERIAL_STRLEN]; + +///////////////////////////////////////////////////////////////////////////// +// Enumerations +///////////////////////////////////////////////////////////////////////////// + +enum SET_STATUS {SET_SUCCESS, SET_FAIL, SET_VERIFY_FAIL}; + +///////////////////////////////////////////////////////////////////////////// +// Pin Definitions +///////////////////////////////////////////////////////////////////////////// + +// Pin Config Mode Array Indices +#define CP213x_INDEX_GPIO_0 0 +#define CP213x_INDEX_GPIO_1 1 +#define CP213x_INDEX_GPIO_2 2 +#define CP213x_INDEX_GPIO_3 3 +#define CP213x_INDEX_GPIO_4 4 +#define CP213x_INDEX_GPIO_5 5 +#define CP213x_INDEX_GPIO_6 6 +#define CP213x_INDEX_GPIO_7 7 +#define CP213x_INDEX_GPIO_8 8 +#define CP213x_INDEX_GPIO_9 9 +#define CP213x_INDEX_GPIO_10 10 + +// Pin Bitmasks +#define CP213x_MASK_SCK 0x0001 +#define CP213x_MASK_MISO 0x0002 +#define CP213x_MASK_MOSI 0x0004 +#define CP213x_MASK_GPIO_0 0x0008 +#define CP213x_MASK_GPIO_1 0x0010 +#define CP213x_MASK_GPIO_2 0x0020 +#define CP213x_MASK_GPIO_3 0x0040 +#define CP213x_MASK_GPIO_4 0x0080 +#define CP213x_MASK_GPIO_5 0x0100 +#define CP213x_MASK_GPIO_6 0x0400 +#define CP213x_MASK_GPIO_7 0x0800 +#define CP213x_MASK_GPIO_8 0x1000 +#define CP213x_MASK_GPIO_9 0x2000 +#define CP213x_MASK_GPIO_10 0x4000 + +/// @} + +//////////////////////////////////////////////////////////////////////////////// +// Structures +//////////////////////////////////////////////////////////////////////////////// + +/// @name Type and structure definitions +/// @{ + +/// This struct has the same format as _USB_DEVICE_DESCRIPTOR, as defined in Windows usb100.h. +/// Using this typedef enables portable application code. +typedef struct DEVICE_DESCRIPTOR +{ + BYTE bLength; + BYTE bDescriptorType; + WORD bcdUSB; + BYTE bDeviceClass; + BYTE bDeviceSubClass; + BYTE bDeviceProtocol; + BYTE bMaxPacketSize0; + WORD idVendor; + WORD idProduct; + WORD bcdDevice; + BYTE iManufacturer; + BYTE iProduct; + BYTE iSerialNumber; + BYTE bNumConfigurations; +} DEVICE_DESCRIPTOR, *PDEVICE_DESCRIPTOR; + +/// SPI Command Word +typedef struct SPI_CMD +{ + WORD Cmd; + WORD SubCmd; + DWORD Len; + DWORD blockSize; + DWORD timeoutMs; + DWORD res; +} SPI_CMD, *PSPI_CMD; + + +// Bitfield masks for delay_mode structure element +#define SPI_INTERBYTE_DELAY_MASK 0x01 +#define SPI_CS_POSTASSERT_DELAY_MASK 0x02 +#define SPI_CS_PREDEASSERT_DELAY_MASK 0x04 +#define SPI_CS_TOGGLE_MASK 0x08 + +/// @} + +///////////////////////////////////////////////////////////////////////////// +// Exported API Functions +///////////////////////////////////////////////////////////////////////////// + +/// @name Exported API Functions +/// @{ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +USB_SPI_STATUS +CP213x_GetLibraryVersion( BYTE* major, BYTE* minor, BOOL* release ); + +// +// CP2130 Device Management +// +/// @name CP2130 Device Management +/// @{ + + +USB_SPI_STATUS +CP213x_GetNumDevices ( DWORD* numDevices, DWORD VID, DWORD PID ); + + +USB_SPI_STATUS +CP213x_Open ( DWORD deviceIndex, CP213x_DEVICE* phDevice, DWORD VID, DWORD PID ); + +USB_SPI_STATUS +CP213x_Close ( CP213x_DEVICE hDevice ); + +BOOL +CP213x_IsOpened ( CP213x_DEVICE hDevice); + +USB_SPI_STATUS +CP213x_Reset ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_GetDeviceVersion ( CP213x_DEVICE hDevice, BYTE* majorVersion, BYTE* minorVersion ); + +USB_SPI_STATUS +CP213x_GetDeviceDescriptor ( CP213x_DEVICE hDevice, + PDEVICE_DESCRIPTOR pDescriptor ); + +USB_SPI_STATUS +CP213x_GetStringDescriptor ( CP213x_DEVICE hDevice, + BYTE index, + BYTE stringDescriptor[STRING_DESCRIPTOR_SIZE] ); + +USB_SPI_STATUS +CP213x_GetUsbConfig ( CP213x_DEVICE hDevice, + WORD* vid, + WORD* pid, + BYTE* power, + BYTE* powerMode, + WORD* releaseVersion, + BYTE* transferPriority ); + + +USB_SPI_STATUS +CP213x_SetUsbConfig ( CP213x_DEVICE hDevice, + WORD vid, + WORD pid, + BYTE power, + BYTE powerMode, + WORD releaseVersion, + BYTE transferPriority, + BYTE mask ); + + +USB_SPI_STATUS +CP213x_GetManufacturingString ( CP213x_DEVICE hDevice, LPSTR manufacturingString, BYTE* strlen ); + +USB_SPI_STATUS +CP213x_SetManufacturingString ( CP213x_DEVICE hDevice, LPCSTR manufacturingString, BYTE strlen ); + +USB_SPI_STATUS +CP213x_GetProductString ( CP213x_DEVICE hDevice, LPSTR productString, BYTE* strlen ); + +USB_SPI_STATUS +CP213x_SetProductString ( CP213x_DEVICE hDevice, LPCSTR productString, BYTE strlen ); + +USB_SPI_STATUS +CP213x_GetSerialString ( CP213x_DEVICE hDevice, LPSTR serialString, BYTE* strlen ); + +USB_SPI_STATUS +CP213x_SetSerialString ( CP213x_DEVICE hDevice, LPCSTR serialString, BYTE strlen ); + +USB_SPI_STATUS +CP213x_GetPinConfig ( CP213x_DEVICE hDevice, BYTE pinConfig[SIZE_PIN_CONFIG] ); + +USB_SPI_STATUS +CP213x_SetPinConfig ( CP213x_DEVICE hDevice, BYTE pinConfig[SIZE_PIN_CONFIG] ); + +USB_SPI_STATUS +CP213x_GetLock ( CP213x_DEVICE hDevice, WORD* lockValue ); + +USB_SPI_STATUS +CP213x_SetLock ( CP213x_DEVICE hDevice, WORD lockValue ); + +USB_SPI_STATUS +CP213x_ReadProm ( CP213x_DEVICE hDevice, BYTE pReadBuf[] ); + +USB_SPI_STATUS +CP213x_WriteProm ( CP213x_DEVICE hDevice, BYTE pWriteBuf[] ); +/// @} + +// +// CP2130 SPI Configuration and Transfer Operations +// +/// @name CP2130 SPI Configuration and Transfer Operations +/// @{ + +USB_SPI_STATUS +CP213x_GetSpiControlBytes ( CP213x_DEVICE hDevice, BYTE controlBytes[CP213x_NUM_GPIO] ); + +USB_SPI_STATUS +CP213x_SetSpiControlByte ( CP213x_DEVICE hDevice, BYTE channel, BYTE controlByte ); + +USB_SPI_STATUS +CP213x_GetSpiDelay ( CP213x_DEVICE hDevice, + BYTE channel, + BYTE* delayMode, + WORD* interByteDelay, + WORD* postAssertDelay, + WORD* preDeassertDelay ); + +USB_SPI_STATUS +CP213x_SetSpiDelay ( CP213x_DEVICE hDevice, + BYTE channel, + BYTE delayMode, + WORD interByteDelay, + WORD postAssertDelay, + WORD preDeassertDelay ); +//not tested +USB_SPI_STATUS +CP213x_GetChipSelect ( CP213x_DEVICE hDevice, + WORD* channelCsEnable, + WORD* pinCsEnable ); +//not tested +USB_SPI_STATUS +CP213x_SetChipSelect ( CP213x_DEVICE hDevice, BYTE channel, BYTE mode ); +//not tested +USB_SPI_STATUS +CP213x_TransferWrite ( CP213x_DEVICE hDevice, + BYTE pWriteBuf[], + DWORD length, + BOOL releaseBusAfterTransfer, + DWORD timeoutMs, + DWORD* pBytesActuallyWritten ); +//not tested +USB_SPI_STATUS +CP213x_TransferWriteRead ( CP213x_DEVICE hDevice, + BYTE pWriteBuf[], + BYTE pReadBuf[], + DWORD length, + BOOL releaseBusAfterTransfer, + DWORD timeoutMs, + DWORD* pBytesActuallyTransferred ); +//not tested +USB_SPI_STATUS +CP213x_TransferReadAsync ( CP213x_DEVICE hDevice, + DWORD totalSize, + DWORD blockSize, + BOOL releaseBusAfterTransfer ); + +USB_SPI_STATUS +CP213x_TransferReadSync ( CP213x_DEVICE hDevice, + BYTE pReadBuf[], + DWORD length, + BOOL releaseBusAfterTransfer, + DWORD timeoutMs, + DWORD* pBytesActuallyRead ); + +USB_SPI_STATUS +CP213x_TransferReadRtrAsync ( CP213x_DEVICE hDevice, + DWORD totalSize, + DWORD blockSize, + BOOL releaseBusAfterTransfer ); + +USB_SPI_STATUS +CP213x_TransferReadRtrSync ( CP213x_DEVICE hDevice, + BYTE pReadBuf[], + DWORD totalSize, + DWORD blockSize, + BOOL releaseBusAfterTransfer, + DWORD timeoutMs, + DWORD* pBytesActuallyRead ); + +USB_SPI_STATUS +CP213x_GetRtrState ( CP213x_DEVICE hDevice, BYTE* isStopped ); + +USB_SPI_STATUS +CP213x_SetRtrStop ( CP213x_DEVICE hDevice, BYTE stopRtr ); + +USB_SPI_STATUS +CP213x_ReadPoll ( CP213x_DEVICE hDevice, + BYTE pReadBuf[], + DWORD maxLength, + DWORD* pBytesActuallyRead ); + +USB_SPI_STATUS +CP213x_ReadAbort ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_AbortInputPipe ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_FlushInputPipe ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_AbortOutputPipe ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_FlushOutputPipe ( CP213x_DEVICE hDevice ); + +USB_SPI_STATUS +CP213x_GetFifoFullThreshold ( CP213x_DEVICE hDevice, BYTE* pFifoFullThreshold ); + +USB_SPI_STATUS +CP213x_SetFifoFullThreshold ( CP213x_DEVICE hDevice, BYTE fifoFullThreshold ); + +/// @} + +// +// CP2130 GPIO and Auxiliary-Function Pins +// +/// @name CP2130 GPIO and Auxiliary-Function Pins +/// @{ + +USB_SPI_STATUS +CP213x_GetGpioModeAndLevel ( CP213x_DEVICE hDevice, BYTE channel, BYTE* mode, BYTE* level ); + +USB_SPI_STATUS +CP213x_SetGpioModeAndLevel ( CP213x_DEVICE hDevice, BYTE channel, BYTE mode, BYTE level ); + +USB_SPI_STATUS +CP213x_GetGpioValues ( CP213x_DEVICE hDevice, WORD* gpioValues ); + +USB_SPI_STATUS +CP213x_SetGpioValues ( CP213x_DEVICE hDevice, WORD mask, WORD gpioValues ); + +USB_SPI_STATUS +CP213x_GetEventCounter ( CP213x_DEVICE hDevice, BYTE* mode, WORD* eventCount ); + +USB_SPI_STATUS +CP213x_SetEventCounter ( CP213x_DEVICE hDevice, BYTE mode, WORD eventCount ); + +USB_SPI_STATUS +CP213x_GetClockDivider ( CP213x_DEVICE hDevice, BYTE* clockDivider ); + +USB_SPI_STATUS +CP213x_SetClockDivider ( CP213x_DEVICE hDevice, BYTE clockDivider ); + +/// @} + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SLAB_USB_SPI_H + +///////////////////////////////////////////////////////////////////////////// +// End of file +///////////////////////////////////////////////////////////////////////////// diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/Types.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Types.h new file mode 100644 index 0000000..d3e9c43 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/Types.h @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////// +// Types.h +//////////////////////////////////////////////////////////////////////////////// + +#ifndef HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C +#define HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C + +#if defined(_WIN32) + +#include + +#else + +//////////////////////////////////////////////////////////////////////////////// +// Typedefs +//////////////////////////////////////////////////////////////////////////////// + +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned int UINT; +#if defined(__APPLE__) +typedef unsigned long DWORD; +typedef unsigned long long ULONGLONG; +#else +typedef unsigned int DWORD; +typedef unsigned int ULONG; +#define ULONGLONG int64_t +#endif + +typedef char *LPSTR; +typedef const char *LPCSTR; +typedef BOOL *LPBOOL; +typedef BYTE *LPBYTE; +typedef WORD *LPWORD; +typedef UINT *LPUINT; +typedef DWORD *LPDWORD; +typedef void *LPVOID; + +typedef void *HANDLE; +typedef HANDLE *LPHANDLE; + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#define INFINITE 0xFFFFFFFF + +#if !defined(FALSE) +#define FALSE (0) +#endif +#if !defined(TRUE) +#define TRUE (1) // TODO: or !FALSE? +#endif + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +// TODO: Delete these. Use host_common/silabs_utils.h::SILABS_MAKEWORD(), SILABS_LOBYTE() & SILABS_HIBYTE() +#define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((BYTE)(w)) +#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) + +#endif // defined(_WIN32) + +#endif // HOST_COMMON_INCLUDE_TYPES_H_INCLUDED_37C49TY24C + diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/cp210xsmt.cpp b/AN721SW/Linux/ManufacturingTool/cp210xsmt/cp210xsmt.cpp new file mode 100644 index 0000000..e02ee66 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/cp210xsmt.cpp @@ -0,0 +1,1080 @@ +// Copyright (c) 2015-2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#pragma comment (lib, "CP210xManufacturing.lib") +#include "CP210xManufacturingDLL.h" +#else +#include "OsDep.h" +#include "CP210xManufacturing.h" +#endif +#include "stdio.h" +#include "util.h" +#include "smt.h" + +void AbortOnErr( CP210x_STATUS status, std::string funcName) +{ + if( status != CP210x_SUCCESS) + { + char msg[ 128]; + sprintf( msg, /*SIZEOF_ARRAY( msg),*/ "%s returned 0x%x", funcName.c_str(), status); + throw CDllErr( msg); + } +} + +//--------------------------------------------------------------------------------- +DWORD LibSpecificNumDevices( const CVidPid &, const CVidPid &) +{ + DWORD DevCnt; + AbortOnErr( CP210x_GetNumDevices( &DevCnt ), "CP210x_GetNumDevices"); + return DevCnt; +} +//--------------------------------------------------------------------------------- +class CCP210xDev +{ +public: + CCP210xDev( const CVidPid &FilterVidPid, DWORD devIndex); + ~CCP210xDev(); + HANDLE handle() const { return m_H; } + bool isLocked() const; + void lock() const; + void reset() const; + CDevType getDevType() const; + CVidPid getVidPid() const; + BYTE getPowerMode() const; + BYTE getMaxPower() const; + WORD getDevVer() const; + WORD getFlushBufCfg() const; + std::vector getSerNum( bool isAscii) const; + std::vector getManufacturer( bool isAscii) const; + std::vector getProduct( bool isAscii) const; + void setVidPid( WORD vid, WORD pid) const; + void setPowerMode( BYTE val) const; + void setMaxPower( BYTE val) const; + void setDevVer( WORD val) const; + void setFlushBufCfg( WORD val) const; + void setSerNum( const std::vector &str, bool isAscii) const; + void setManufacturer( const std::vector &str, bool isAscii) const; + void setProduct( const std::vector &str, bool isAscii) const; + + HANDLE m_H; +}; +CCP210xDev::CCP210xDev( const CVidPid &, DWORD devIndex) +{ + AbortOnErr( CP210x_Open( devIndex, &m_H), "CP210x_Open"); +} +CCP210xDev::~CCP210xDev() +{ + CP210x_STATUS status = CP210x_Close( m_H); + if( status != CP210x_SUCCESS) + { + std::cerr << "CP210x_Close failed\n"; + } +} +bool CCP210xDev::isLocked() const +{ + BYTE lock; + AbortOnErr( CP210x_GetLockValue( m_H, &lock), "CP210x_GetLockValue"); + return lock != 0; +} +void CCP210xDev::lock() const +{ + AbortOnErr( CP210x_SetLockValue( m_H), "CP210x_SetLockValue"); +} +void CCP210xDev::reset() const +{ + AbortOnErr( CP210x_Reset( m_H), "CP210x_Reset"); +} +CDevType CCP210xDev::getDevType() const +{ + BYTE partNum; + AbortOnErr( CP210x_GetPartNumber( m_H, &partNum ), "CP210x_GetPartNumber"); + return CDevType( partNum); +} +CVidPid CCP210xDev::getVidPid() const +{ + WORD vid, pid; + AbortOnErr( CP210x_GetDeviceVid( m_H, &vid ), "CP210x_GetDeviceVid"); + AbortOnErr( CP210x_GetDevicePid( m_H, &pid ), "CP210x_GetDevicePid"); + return CVidPid( vid, pid); +} +BYTE CCP210xDev::getPowerMode() const +{ + BOOL SelfPower; + AbortOnErr( CP210x_GetSelfPower( m_H, &SelfPower), "CP210x_GetSelfPower"); + return SelfPower ? 1 : 0; +} +BYTE CCP210xDev::getMaxPower() const +{ + BYTE MaxPower; + AbortOnErr( CP210x_GetMaxPower( m_H, &MaxPower), "CP210x_GetMaxPower"); + return MaxPower; +} +WORD CCP210xDev::getDevVer() const +{ + WORD devVer; + AbortOnErr( CP210x_GetDeviceVersion( m_H, &devVer), "CP210x_GetDeviceVersion"); + return devVer; +} +WORD CCP210xDev::getFlushBufCfg() const +{ + WORD flushBufCfg; + AbortOnErr( CP210x_GetFlushBufferConfig( m_H, &flushBufCfg), "CP210x_GetFlushBufferConfig"); + return flushBufCfg; +} +std::vector CCP210xDev::getSerNum( bool isAscii) const +{ + std::vector str( MAX_UCHAR); + BYTE CchStr = 0; + AbortOnErr( CP210x_GetDeviceSerialNumber( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceSerialNumber"); + str.resize( CchStr * (isAscii ? 1 : 2)); + return str; +} +std::vector CCP210xDev::getManufacturer( bool isAscii) const +{ + std::vector str( MAX_UCHAR); + BYTE CchStr = 0; + AbortOnErr( CP210x_GetDeviceManufacturerString( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceManufacturerString"); + str.resize( CchStr * (isAscii ? 1 : 2)); + return str; +} +std::vector CCP210xDev::getProduct( bool isAscii) const +{ + std::vector str( MAX_UCHAR); + BYTE CchStr = 0; + AbortOnErr( CP210x_GetDeviceProductString( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceProductString"); + str.resize( CchStr * (isAscii ? 1 : 2)); + return str; +} +void CCP210xDev::setVidPid( WORD vid, WORD pid) const +{ + AbortOnErr( CP210x_SetVid( m_H, vid), "CP210x_SetVid"); + AbortOnErr( CP210x_SetPid( m_H, pid), "CP210x_SetPid"); +} +void CCP210xDev::setPowerMode( BYTE val) const +{ + AbortOnErr( CP210x_SetSelfPower( m_H, val ? TRUE : FALSE ), "CP210x_SetSelfPower"); +} +void CCP210xDev::setMaxPower( BYTE val) const +{ + AbortOnErr( CP210x_SetMaxPower( m_H, val), "CP210x_SetMaxPower"); +} +void CCP210xDev::setDevVer( WORD val) const +{ + AbortOnErr( CP210x_SetDeviceVersion( m_H, val), "CP210x_SetDeviceVersion"); +} +void CCP210xDev::setFlushBufCfg( WORD val) const +{ + AbortOnErr( CP210x_SetFlushBufferConfig( m_H, val), "CP210x_SetFlushBufferConfig"); +} +void CCP210xDev::setSerNum( const std::vector &str, bool isAscii) const +{ + BYTE CchStr = static_cast ( str.size() / (isAscii ? 1 : 2)); + AbortOnErr( CP210x_SetSerialNumber( m_H, const_cast( str.data()), CchStr, isAscii), "CP210x_SetSerialNumber"); +} +void CCP210xDev::setManufacturer( const std::vector &str, bool isAscii) const +{ + BYTE CchStr = static_cast ( str.size() / (isAscii ? 1 : 2)); + AbortOnErr( CP210x_SetManufacturerString( m_H, const_cast( str.data()), CchStr, isAscii), "CP210x_SetManufacturerString"); +} +void CCP210xDev::setProduct( const std::vector &str, bool isAscii) const +{ + BYTE CchStr = static_cast ( str.size() / (isAscii ? 1 : 2)); + AbortOnErr( CP210x_SetProductString( m_H, const_cast( str.data()), CchStr, isAscii), "CP210x_SetProductString"); +} + +//--------------------------------------------------------------------------------- +// CP2102N has non-standard get/set lock functions. + +#pragma pack(push, 1) +// The original complete copy of the below struct is called Config_t in the CP2102N repo. +// "Used to store default settings and customized values passed from host PC." +union CCP2102NConfig { + struct { // just the top of it, as far as we need + WORD configSize; + BYTE configVersion; + // Allows Bootloader entry from VCP vendor command/HID report. Bootloader always runs + // if flash address 0x0 is 0xFF. + BYTE enableBootloader; + // Allows configuration updates. If a bad burn happens, this will become + // 0xff allowing a recovery. + BYTE enableConfigUpdate; + } Fields; + BYTE Raw[ 0x2a6]; +}; +#pragma pack(pop) + +#define CP2102N_CONFIG_VERSION 1 +#define CP2102N_CONFIG_UNLOCKED 0xff + +class CCP2102NDev : public CCP210xDev +{ +public: + CCP2102NDev( const CVidPid &FilterVidPid, DWORD devIndex) : CCP210xDev( FilterVidPid, devIndex) {} + bool isLocked() const; + void lock() const; +}; +bool CCP2102NDev::isLocked() const +{ + CCP2102NConfig Config = {0}; + AbortOnErr( CP210x_GetConfig( m_H, &Config.Raw[0], static_cast( sizeof( Config))), "CP210x_GetConfig"); + if( Config.Fields.configVersion != CP2102N_CONFIG_VERSION) + { + throw CCustErr( "CP2102N returned unknown config version"); + } + if( Config.Fields.configSize < sizeof( Config.Fields)) + { + throw CCustErr( "CP2102N returned invalid config size"); + } + return Config.Fields.enableConfigUpdate != CP2102N_CONFIG_UNLOCKED; +} +void CCP2102NDev::lock() const +{ + CCP2102NConfig Config; + AbortOnErr( CP210x_GetConfig( m_H, &Config.Raw[0], static_cast( sizeof( Config))), "CP210x_GetConfig"); + Config.Fields.enableConfigUpdate = 0; + AbortOnErr( CP210x_SetConfig( m_H, &Config.Raw[0], static_cast( sizeof( Config))), "CP210x_SetConfig"); + + CCP2102NConfig finalConfig; + AbortOnErr( CP210x_GetConfig( m_H, &finalConfig.Raw[0], static_cast( sizeof( finalConfig))), "CP210x_GetConfig"); + if( memcmp( &Config.Raw[0], &finalConfig.Raw[0], sizeof( finalConfig))) + { + throw CCustErr( "CP2102N config verification failed after locking"); + } +} + +//--------------------------------------------------------------------------------- +// Here is a bunch of customization parametersfound in cp210x devices. They are included +// into each individual cp210x device that supports the parameter. +//--------------------------------------------------------------------------------- +struct CFlushBufferConfig +{ + CFlushBufferConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + WORD m_Config; +}; +bool CFlushBufferConfig::readParm( const std::string &parmName) +{ + if( parmName == "FlushBufferConfig") + { + setSpecified( m_Specified, parmName); + m_Config = readUshortParm(); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CFlushBufferConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + dev.setFlushBufCfg( m_Config); +} +void CFlushBufferConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + if( m_Config != dev.getFlushBufCfg()) + { + throw CCustErr( "Failed FlushBufferConfig verification"); + } +} +//--------------------------------------------------------------------------------- +struct CDeviceMode +{ + CDeviceMode() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + BYTE m_ModeECI; + BYTE m_ModeSCI; +}; +bool CDeviceMode::readParm( const std::string &parmName) +{ + if( parmName == "DeviceMode") + { + setSpecified( m_Specified, parmName); + m_ModeECI = readUcharParm(); + m_ModeSCI = readUcharParm(); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CDeviceMode::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetDeviceMode( dev.handle(), m_ModeECI, m_ModeSCI), "CP210x_SetDeviceMode"); +} +void CDeviceMode::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + BYTE ModeECI; + BYTE ModeSCI; + AbortOnErr( CP210x_GetDeviceMode( dev.handle(), &ModeECI, &ModeSCI), "CP210x_GetDeviceMode"); + if( m_ModeECI != ModeECI || m_ModeSCI != ModeSCI) + { + throw CCustErr( "Failed DeviceMode verification"); + } +} +//--------------------------------------------------------------------------------- +struct CInterfaceString +{ + CInterfaceString() { m_Specified = false; } + bool readParm( BYTE ifc, const std::string &parmName); + void program( BYTE ifc, const CCP210xDev &dev) const; + void verify( BYTE ifc, const CCP210xDev &dev) const; +private: + bool m_Specified; + bool m_IsAscii; + std::vector m_str; +}; +bool CInterfaceString::readParm( BYTE ifc, const std::string &parmName) +{ + char ifcDigit = '0' + ifc; + if( parmName == std::string( "InterfaceStringAscii") + ifcDigit) + { + setSpecified( m_Specified, parmName); + m_IsAscii = true; + readByteArrayParm( m_str, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + return true; + } + else if( parmName == std::string("InterfaceStringUnicode") + ifcDigit) + { + setSpecified( m_Specified, parmName); + m_IsAscii = false; + readByteArrayParm( m_str, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CInterfaceString::program( BYTE ifc, const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + BYTE CchStr = static_cast ( m_str.size() / (m_IsAscii ? 1 : 2)); + AbortOnErr( CP210x_SetInterfaceString( dev.handle(), ifc, const_cast( m_str.data()), CchStr, m_IsAscii), "CP210x_SetInterfaceString"); +} +void CInterfaceString::verify( BYTE ifc, const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + std::vector str( MAX_UCHAR); + BYTE CchStr = 0; + AbortOnErr( CP210x_GetDeviceInterfaceString( dev.handle(), ifc, str.data(), &CchStr, m_IsAscii), "CP210x_GetDeviceInterfaceString"); + str.resize( CchStr * (m_IsAscii ? 1 : 2)); + if( m_str != str) + { + throw CCustErr( "Failed InterfaceString verification"); + } +} +//--------------------------------------------------------------------------------- +struct CBaudRateConfig +{ + CBaudRateConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + BAUD_CONFIG m_Config[ NUM_BAUD_CONFIGS]; +}; +bool CBaudRateConfig::readParm( const std::string &parmName) +{ + if( parmName == "BaudRateConfig") + { + setSpecified( m_Specified, parmName); + readKeyword( "{"); + for( DWORD i = 0; i < SIZEOF_ARRAY( m_Config); i++) + { + m_Config[ i].BaudGen = readUshort(); + m_Config[ i].Timer0Reload = readUshort(); + m_Config[ i].Prescaler = readUchar(); + m_Config[ i].BaudRate = readUlong(); + } + readKeyword( "}"); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CBaudRateConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetBaudRateConfig( dev.handle(), const_cast(&m_Config[ 0])), "CP210x_SetBaudRateConfig"); +} +void CBaudRateConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + BAUD_CONFIG Config[ NUM_BAUD_CONFIGS]; + AbortOnErr( CP210x_GetBaudRateConfig( dev.handle(), &Config[ 0]), "CP210x_GetBaudRateConfig"); + for( DWORD i = 0; i < SIZEOF_ARRAY( m_Config); i++) + { +// printf("verify %d\n", Config[ i].BaudRate); // TODO remove + if( m_Config[ i].BaudGen != Config[ i].BaudGen || + m_Config[ i].Timer0Reload != Config[ i].Timer0Reload || + m_Config[ i].Prescaler != Config[ i].Prescaler || + m_Config[ i].BaudRate != Config[ i].BaudRate) + { + throw CCustErr( "Failed BaudRateConfig verification"); + } + } +} +//--------------------------------------------------------------------------------- +struct CPortConfig +{ + CPortConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + PORT_CONFIG m_PortCfg; +}; +bool CPortConfig::readParm( const std::string &parmName) +{ + if( parmName == "PortConfig") + { + setSpecified( m_Specified, parmName); + readKeyword( "{"); + m_PortCfg.Mode = readUshort(); + m_PortCfg.Reset_Latch = readUshort(); + m_PortCfg.Suspend_Latch = readUshort(); + m_PortCfg.EnhancedFxn = readUchar(); + readKeyword( "}"); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CPortConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetPortConfig( dev.handle(), const_cast(&m_PortCfg)), "CP210x_SetPortConfig"); +} +void CPortConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + PORT_CONFIG PortCfg; + AbortOnErr( CP210x_GetPortConfig( dev.handle(), &PortCfg), "CP210x_GetPortConfig"); + if( m_PortCfg.Mode != PortCfg.Mode || + m_PortCfg.Reset_Latch != PortCfg.Reset_Latch || + m_PortCfg.Suspend_Latch != PortCfg.Suspend_Latch || + m_PortCfg.EnhancedFxn != PortCfg.EnhancedFxn) + { + throw CCustErr( "Failed PortConfig verification"); + } +} +//--------------------------------------------------------------------------------- +struct CDualPortConfig +{ + CDualPortConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + DUAL_PORT_CONFIG m_PortCfg; +}; +bool CDualPortConfig::readParm( const std::string &parmName) +{ + if( parmName == "DualPortConfig") + { + setSpecified( m_Specified, parmName); + readKeyword( "{"); + m_PortCfg.Mode = readUshort(); + m_PortCfg.Reset_Latch = readUshort(); + m_PortCfg.Suspend_Latch = readUshort(); + m_PortCfg.EnhancedFxn_ECI = readUchar(); + m_PortCfg.EnhancedFxn_SCI = readUchar(); + m_PortCfg.EnhancedFxn_Device = readUchar(); + readKeyword( "}"); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CDualPortConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetDualPortConfig( dev.handle(), const_cast(&m_PortCfg)), "CP210x_SetDualPortConfig"); +} +void CDualPortConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + DUAL_PORT_CONFIG PortCfg; + AbortOnErr( CP210x_GetDualPortConfig( dev.handle(), &PortCfg), "CP210x_GetDualPortConfig"); + if( m_PortCfg.Mode != PortCfg.Mode || + m_PortCfg.Reset_Latch != PortCfg.Reset_Latch || + m_PortCfg.Suspend_Latch != PortCfg.Suspend_Latch || + m_PortCfg.EnhancedFxn_ECI != PortCfg.EnhancedFxn_ECI || + m_PortCfg.EnhancedFxn_SCI != PortCfg.EnhancedFxn_SCI || + m_PortCfg.EnhancedFxn_Device != PortCfg.EnhancedFxn_Device) + { + throw CCustErr( "Failed DualPortConfig verification"); + } +} +//--------------------------------------------------------------------------------- +struct CQuadPortConfig +{ + CQuadPortConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + QUAD_PORT_CONFIG m_PortCfg; +}; +void readQuadPortState( QUAD_PORT_STATE &qps) +{ + qps.Mode_PB0 = readUshort(); + qps.Mode_PB1 = readUshort(); + qps.Mode_PB2 = readUshort(); + qps.Mode_PB3 = readUshort(); + qps.Mode_PB4 = readUshort(); + qps.LowPower_PB0 = readUshort(); + qps.LowPower_PB1 = readUshort(); + qps.LowPower_PB2 = readUshort(); + qps.LowPower_PB3 = readUshort(); + qps.LowPower_PB4 = readUshort(); + qps.Latch_PB0 = readUshort(); + qps.Latch_PB1 = readUshort(); + qps.Latch_PB2 = readUshort(); + qps.Latch_PB3 = readUshort(); + qps.Latch_PB4 = readUshort(); +} +bool CQuadPortConfig::readParm( const std::string &parmName) +{ + if( parmName == "QuadPortConfig") + { + setSpecified( m_Specified, parmName); + readKeyword( "{"); + readQuadPortState( m_PortCfg.Reset_Latch); + readQuadPortState( m_PortCfg.Suspend_Latch); + m_PortCfg.IPDelay_IFC0 = readUchar(); + m_PortCfg.IPDelay_IFC1 = readUchar(); + m_PortCfg.IPDelay_IFC2 = readUchar(); + m_PortCfg.IPDelay_IFC3 = readUchar(); + m_PortCfg.EnhancedFxn_IFC0 = readUchar(); + m_PortCfg.EnhancedFxn_IFC1 = readUchar(); + m_PortCfg.EnhancedFxn_IFC2 = readUchar(); + m_PortCfg.EnhancedFxn_IFC3 = readUchar(); + m_PortCfg.EnhancedFxn_Device = readUchar(); + m_PortCfg.ExtClk0Freq = readUchar(); + m_PortCfg.ExtClk1Freq = readUchar(); + m_PortCfg.ExtClk2Freq = readUchar(); + m_PortCfg.ExtClk3Freq = readUchar(); + readKeyword( "}"); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +void CQuadPortConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetQuadPortConfig( dev.handle(), const_cast(&m_PortCfg)), "CP210x_SetQuadPortConfig"); +} +bool isEqualQuadPortState( const QUAD_PORT_STATE &qps1, const QUAD_PORT_STATE &qps2) +{ + if( qps1.Mode_PB0 != qps2.Mode_PB0 || + qps1.Mode_PB1 != qps2.Mode_PB1 || + qps1.Mode_PB2 != qps2.Mode_PB2 || + qps1.Mode_PB3 != qps2.Mode_PB3 || + qps1.Mode_PB4 != qps2.Mode_PB4 || + qps1.LowPower_PB0 != qps2.LowPower_PB0 || + qps1.LowPower_PB1 != qps2.LowPower_PB1 || + qps1.LowPower_PB2 != qps2.LowPower_PB2 || + qps1.LowPower_PB3 != qps2.LowPower_PB3 || + qps1.LowPower_PB4 != qps2.LowPower_PB4 || + qps1.Latch_PB0 != qps2.Latch_PB0 || + qps1.Latch_PB1 != qps2.Latch_PB1 || + qps1.Latch_PB2 != qps2.Latch_PB2 || + qps1.Latch_PB3 != qps2.Latch_PB3 || + qps1.Latch_PB4 != qps2.Latch_PB4) + { + return false; + } + return true; +} +void CQuadPortConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + QUAD_PORT_CONFIG PortCfg; + AbortOnErr( CP210x_GetQuadPortConfig( dev.handle(), &PortCfg), "CP210x_GetQuadPortConfig"); + if( !isEqualQuadPortState( m_PortCfg.Reset_Latch, PortCfg.Reset_Latch ) || + !isEqualQuadPortState( m_PortCfg.Suspend_Latch, PortCfg.Suspend_Latch ) || + m_PortCfg.IPDelay_IFC0 != PortCfg.IPDelay_IFC0 || + m_PortCfg.IPDelay_IFC1 != PortCfg.IPDelay_IFC1 || + m_PortCfg.IPDelay_IFC2 != PortCfg.IPDelay_IFC2 || + m_PortCfg.IPDelay_IFC3 != PortCfg.IPDelay_IFC3 || + m_PortCfg.EnhancedFxn_IFC0 != PortCfg.EnhancedFxn_IFC0 || + m_PortCfg.EnhancedFxn_IFC1 != PortCfg.EnhancedFxn_IFC1 || + m_PortCfg.EnhancedFxn_IFC2 != PortCfg.EnhancedFxn_IFC2 || + m_PortCfg.EnhancedFxn_IFC3 != PortCfg.EnhancedFxn_IFC3 || + m_PortCfg.EnhancedFxn_Device != PortCfg.EnhancedFxn_Device || + m_PortCfg.ExtClk0Freq != PortCfg.ExtClk0Freq || + m_PortCfg.ExtClk1Freq != PortCfg.ExtClk1Freq || + m_PortCfg.ExtClk2Freq != PortCfg.ExtClk2Freq || + m_PortCfg.ExtClk3Freq != PortCfg.ExtClk3Freq) + { + throw CCustErr( "Failed QuadPortConfig verification"); + } +} +//--------------------------------------------------------------------------------- +struct CConfig +{ + CConfig() { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const CCP210xDev &dev) const; + void verify( const CCP210xDev &dev) const; +private: + bool m_Specified; + CCP2102NConfig m_Config; +}; +bool CConfig::readParm( const std::string &parmName) +{ + if( parmName == "Config") + { + setSpecified( m_Specified, parmName); + + // Jeff said it's best to always write the whole thing, hence "Exact" read + std::vector Config; + readByteArrayParmExact( Config, sizeof( m_Config)); + readKeyword( "}"); // end of parameter list + std::memcpy( &m_Config.Raw[0], &Config[0], sizeof( m_Config)); // Copy into the formatted storage + + // Few sanity checks + if( m_Config.Fields.configVersion != CP2102N_CONFIG_VERSION) + { + throw CUsageErr( "CP2102N Config::configVersion is invalid"); + } + if( m_Config.Fields.configSize != sizeof(CCP2102NConfig)) + { + throw CUsageErr( "CP2102N Config::configSize is invalid"); + } + if( m_Config.Fields.enableConfigUpdate != CP2102N_CONFIG_UNLOCKED) + { + // The user isn't trying to lock the config by enableConfigUpdate. We don't allow this, + // we lock it explicitly after verification, by writing same data with enableConfigUpdate + // clear. + throw CUsageErr( "CP2102N Config::enableConfigUpdate attempts to lock, use --lock instead"); + } + return true; + } + return false; +} +void CConfig::program( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + AbortOnErr( CP210x_SetConfig( dev.handle(), const_cast( &m_Config.Raw[0]), static_cast( sizeof( m_Config.Raw))), "CP210x_SetConfig"); +} +void CConfig::verify( const CCP210xDev &dev) const +{ + if( !m_Specified) { return; } + CCP2102NConfig readConfig; + AbortOnErr( CP210x_GetConfig( dev.handle(), &readConfig.Raw[0], static_cast( sizeof( readConfig.Raw))), "CP210x_GetConfig"); + + // A little hack to workaround locked configurations. + // If the Config on the chip is locked, the dumb array comparison will fail because of enableConfigUpdate. + // But it wouldn't be a valid failure. So, hack the "unlocked" value into it before comparing. + ASSERT( m_Config.Fields.enableConfigUpdate == CP2102N_CONFIG_UNLOCKED); + readConfig.Fields.enableConfigUpdate = CP2102N_CONFIG_UNLOCKED; + + if( memcmp( &readConfig.Raw[0], &m_Config.Raw[0], sizeof( readConfig))) + { + throw CCustErr( "Failed Config verification"); + } +} +//--------------------------------------------------------------------------------- +// Base class for all cp210x devices, contains ommmon customization parameters +//--------------------------------------------------------------------------------- +template< class TDev > +struct CCP210xParms : public CDevParms +{ + virtual bool supportsUnicode() const { return true; } + virtual void readParm( const std::string &parmName); + void program( const TDev &dev, const std::vector *pSerNum) const; + void verify( const TDev &dev, CSerNumSet &serNumSet) const; +}; +template< class TDev > +void CCP210xParms::readParm( const std::string &parmName) +{ + CDevParms::readParm( parmName); +} +template< class TDev > +void CCP210xParms::program( const TDev &dev, const std::vector *pSerNum) const +{ +#if 0 // TODO remove + if( pSerNum) { + std::vector sn = *pSerNum; + sn.push_back( 0); + printf( "program serial num: %s\n", sn.data()); + sn.pop_back(); + } +#endif + CDevParms::program( dev, pSerNum); + if( CDevParms::m_VidPidSpecified) + { + dev.setVidPid( CDevParms::m_Vid, CDevParms::m_Pid); + } + if( CDevParms::m_PowerModeSpecified) + { + dev.setPowerMode( CDevParms::m_PowerMode); + } + if( CDevParms::m_MaxPowerSpecified) + { + dev.setMaxPower( CDevParms::m_MaxPower); + } + if( CDevParms::m_DevVerSpecified) + { + dev.setDevVer( CDevParms::m_DevVer); + } +} +template< class TDev > +void CCP210xParms::verify( const TDev &dev, CSerNumSet &serNumSet) const +{ + CDevParms::verify( dev, serNumSet); +} +//--------------------------------------------------------------------------------- +struct CCP2101Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +}; +void CCP2101Parms::readParm( const std::string &parmName) +{ + CCP210xParms::readParm( parmName); +} +void CCP2101Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); +} +void CCP2101Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); +} +//--------------------------------------------------------------------------------- +struct CCP2102Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CBaudRateConfig m_BaudRateCfg; +}; +void CCP2102Parms::readParm( const std::string &parmName) +{ + if( m_BaudRateCfg.readParm( parmName)) + { + return; + } + CCP210xParms::readParm( parmName); +} +void CCP2102Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_BaudRateCfg.program( dev); +} +void CCP2102Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_BaudRateCfg.verify( dev); +} +//--------------------------------------------------------------------------------- +struct CCP2102NParms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP2102NDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP2102NDev &dev, CSerNumSet &serNumSet) const; +private: + CConfig m_Cfg; +}; +void CCP2102NParms::readParm( const std::string &parmName) +{ + if( m_Cfg.readParm( parmName)) + { + return; + } + CCP210xParms::readParm( parmName); +} +void CCP2102NParms::program( const CCP2102NDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_Cfg.program( dev); +} +void CCP2102NParms::verify( const CCP2102NDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_Cfg.verify( dev); +} +//--------------------------------------------------------------------------------- +struct CCP2103Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CBaudRateConfig m_BaudRateCfg; + CPortConfig m_PortCfg; +}; +void CCP2103Parms::readParm( const std::string &parmName) +{ + if( m_PortCfg.readParm( parmName)) + { + return; + } + if( m_BaudRateCfg.readParm( parmName)) + { + return; + } + CCP210xParms::readParm( parmName); +} +void CCP2103Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_BaudRateCfg.program( dev); + m_PortCfg.program( dev); +} +void CCP2103Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_BaudRateCfg.verify( dev); + m_PortCfg.verify( dev); +} +//--------------------------------------------------------------------------------- +struct CCP2104Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CPortConfig m_PortCfg; + CFlushBufferConfig m_FlushBufferConfig; +}; +void CCP2104Parms::readParm( const std::string &parmName) +{ + if( m_PortCfg.readParm( parmName)) + { + return; + } + if( m_FlushBufferConfig.readParm( parmName)) + { + return; + } + CCP210xParms::readParm( parmName); +} +void CCP2104Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_PortCfg.program( dev); + m_FlushBufferConfig.program( dev); +} +void CCP2104Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_PortCfg.verify( dev); + m_FlushBufferConfig.verify( dev); +} +//--------------------------------------------------------------------------------- +struct CCP2105Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CFlushBufferConfig m_FlushBufferConfig; + CDeviceMode m_DeviceMode; + CDualPortConfig m_PortCfg; + CInterfaceString m_IfcStr[ 2]; +}; +void CCP2105Parms::readParm( const std::string &parmName) +{ + if( m_FlushBufferConfig.readParm( parmName)) + { + return; + } + if( m_DeviceMode.readParm( parmName)) + { + return; + } + if( m_PortCfg.readParm( parmName)) + { + return; + } + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + if( m_IfcStr[ i].readParm( i, parmName)) + { + return; + } + } + CCP210xParms::readParm( parmName); +} +void CCP2105Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_FlushBufferConfig.program( dev); + m_DeviceMode.program( dev); + m_PortCfg.program( dev); + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + m_IfcStr[ i].program( i, dev); + } +} +void CCP2105Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_FlushBufferConfig.verify( dev); + m_DeviceMode.verify( dev); + m_PortCfg.verify( dev); + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + m_IfcStr[ i].verify( i, dev); + } +} +//--------------------------------------------------------------------------------- +struct CCP2108Parms : public CCP210xParms +{ + CCP2108Parms() : m_ManufStr( true /*supportsUnicode*/) {} + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CFlushBufferConfig m_FlushBufferConfig; + CManufacturerString m_ManufStr; + CQuadPortConfig m_PortCfg; + CInterfaceString m_IfcStr[ 4]; +}; + +void CCP2108Parms::readParm( const std::string &parmName) +{ + if( m_FlushBufferConfig.readParm( parmName)) + { + return; + } + if( m_ManufStr.readParm( parmName)) + { + return; + } + if( m_PortCfg.readParm( parmName)) + { + return; + } + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + if( m_IfcStr[ i].readParm( i, parmName)) + { + return; + } + } + CCP210xParms::readParm( parmName); +} +void CCP2108Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_FlushBufferConfig.program( dev); + m_ManufStr.program( dev); + m_PortCfg.program( dev); + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + m_IfcStr[ i].program( i, dev); + } +} +void CCP2108Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_FlushBufferConfig.verify( dev); + m_ManufStr.verify( dev); + m_PortCfg.verify( dev); + for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++) + { + m_IfcStr[ i].verify( i, dev); + } +} +//--------------------------------------------------------------------------------- +struct CCP2109Parms : public CCP210xParms +{ + virtual void readParm( const std::string &parmName); + virtual void program( const CCP210xDev &dev, const std::vector *pSerNum) const; + virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const; +private: + CBaudRateConfig m_BaudRateCfg; +}; +void CCP2109Parms::readParm( const std::string &parmName) +{ + if( m_BaudRateCfg.readParm( parmName)) + { + return; + } + CCP210xParms::readParm( parmName); +} +void CCP2109Parms::program( const CCP210xDev &dev, const std::vector *pSerNum) const +{ + CCP210xParms::program( dev, pSerNum); + m_BaudRateCfg.program( dev); +} +void CCP2109Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const +{ + CCP210xParms::verify( dev, serNumSet); + m_BaudRateCfg.verify( dev); +} +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- +void LibSpecificMain( const CDevType &devType, const CVidPid &vidPid, int argc, const char * argv[]) +{ + if( devType.Value() == CP210x_CP2101_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2102_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2102N_QFN28_VERSION || + devType.Value() == CP210x_CP2102N_QFN24_VERSION || + devType.Value() == CP210x_CP2102N_QFN20_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2103_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2104_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2105_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2108_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else if( devType.Value() == CP210x_CP2109_VERSION) + { + DevSpecificMain ( devType, vidPid, argc, argv); + } + else + { + throw CSyntErr( "Unsupported PartNum"); + } +} diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/silabs_sal.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/silabs_sal.h new file mode 100644 index 0000000..9d763d3 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/silabs_sal.h @@ -0,0 +1,77 @@ + /*++ + + VER_LEGALCOPYRIGHT_STR + +Module Name: + + silabs_sal.h + +Abstract: + + A top-level, across all repos, authoritative, Master include file for + older IDEs that do not support the SAL-annotations that our API Header files use. + +Environment: + + User mode + +--*/ +// +#if (_MSC_VER > 1000) +#pragma once +#endif + +#ifndef HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT +#define HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT + +#if ! defined(_Check_return_) +#define _Check_return_ +#endif // ! defined(_Check_return_) +#if ! defined(_Ret_range_) +#define _Ret_range_(lb,ub) +#endif // ! defined(_Ret_range_) +#if ! defined(_Success_) +#define _Success_(expr) +#endif // ! defined(_Success_) +#if ! defined(_In_) +#define _In_ +#endif // ! defined(_In_) +#if ! defined(_In_opt_) +#define _In_opt_ +#endif // ! defined(_In_opt_) +#if ! defined(_Out_) +#define _Out_ +#endif // ! defined(_Out_) +#if ! defined(_In_range_) +#define _In_range_(lb,ub) +#endif // ! defined(_In_range_) +#if ! defined(_Out_range_) +#define _Out_range_(lb,ub) +#endif // ! defined(_Out_range_) +#if ! defined(_In_reads_bytes_) +#define _In_reads_bytes_(n) +#endif // ! defined(_In_reads_bytes_) +#if ! defined(_Out_writes_bytes_) +#define _Out_writes_bytes_(n) +#endif // ! defined(_Out_writes_bytes_) +#if ! defined(_Out_writes_bytes_opt_) +#define _Out_writes_bytes_opt_(n) +#endif // ! defined(_Out_writes_bytes_opt_) +#if ! defined(_Inout_updates_bytes_opt_) +#define _Inout_updates_bytes_opt_(n) +#endif // ! defined(_Inout_updates_bytes_opt_) +#if ! defined(_Printf_format_string_) +#define _Printf_format_string_ +#endif // ! defined(_Printf_format_string_) +#if ! defined(_Use_decl_annotations_) +#define _Use_decl_annotations_ +#endif // ! defined(_Use_decl_annotations_) +#if ! defined(_Acquires_lock_) +#define _Acquires_lock_(arg) +#endif // ! defined(_Acquires_lock_) +#if ! defined(_Releases_lock_) +#define _Releases_lock_(arg) +#endif // !defined(_Releases_lock_) + +#endif // !defined(HOST_COMMON_INCLUDE_SILABS_SAL_H_INCLUDED_VASIQW4TVT) + diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.cpp b/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.cpp new file mode 100644 index 0000000..bd3766a --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.cpp @@ -0,0 +1,427 @@ +// Copyright (c) 2015-2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#include +#include +#include +#include +#include +#include "util.h" +#include "smt.h" +#include +#include + +void printProgDesc() +{ + printf( +"Name\n" +" Standalone Manufacturing Tool. Version 1.0.\n" +"Synopsis\n" +" smt option1 option1_argument option2 option2_argument ...\n" +"Description\n" +" SMT is a standalone executable tool that provides command line\n" +" capability to flash Silicon Labs fixed function devices with\n" +" desired configuration values. The tool takes as input\n" +" a configuration file in text format that was created using the\n" +" Xpress Family configuration tools provided in Simplicity Studio.\n" +" All devices must be of the same device model (e.g. CP2102N).\n" + ); +} + +void printCmdLineHelp() +{ + printf( +"Options\n" +"--help\n" +" Output this page.\n" +"--verbose\n" +" Shows the location of a syntax error in the configuration file.\n" +"--device-count \n" +" Mandatory. Specifies how many devices are connected. Programming\n" +" process will not start if it finds a different number of devices\n" +" or fails to open them. Verification process will endlessly retry\n" +" until it can verify this number of devices.\n" +"--reset config_file_name\n" +" Performs soft reset of all connected devices identified by the\n" +" configuration file, equivalent to a USB disconnect/reconnect.\n" +"--set-config config_file_name\n" +" Programs each device using the configuration provided in the\n" +" configuration file. Prints the list of serial numbers programmed.\n" +" You must save this list to pass later to --verify-config.\n" +"--verify-config config_file_name\n" +" Verifies each device using the configuration provided in the\n" +" configuration file. \"--serial-nums GUID\" can't be used with this\n" +" option; you must specify the numbers reported earlier by the\n" +" programming command. Fails if device is locked.\n" +"--lock\n" +" Legal only together with verification. If all devices are successfully\n" +" verified, permanently locks them so they can't be customized anymore.\n" +" Be sure you want to do this!\n" +"--verify-locked-config config_file_name\n" +" Same as --verify-config, but will also verify locked devices\n" +"--set-and-verify-config config_file_name\n" +" Programs and verifies each device using the configuration provided in\n" +" the configuration file. Prints the list of serial numbers programmed.\n" +"--serial-nums { X Y Z ... } | GUID\n" +" Specifies that serial numbers should be written to the devices.\n" +" If omitted, serial numbers are not programmed.\n" +" { X Y Z } - List of strings to be used as serial numbers. The\n" +" number of strings must be equal to the number of connected\n" +" devices. There must be spaces between the strings and braces.\n" +" The strings can't contain space characters.\n" +" GUID - SMT will automatically generate unique serial numbers\n" +" to be written to connected devices, using a platform-supplied\n" +" UUID generation function.\n" +"--list config_file_name\n" +" Displays a list of all connected devices identified by the\n" +" configuration file.\n" +"\nNormal usage example\n" +" The following command will program, verify and permanently lock the\n" +" customizable parameters of all 3 connected devices. (Serial numbers\n" +" will be automatically generated.)\n" +"\n smt --device-count 3 --set-and-verify-config my_config.txt --serial-nums GUID --lock\n" +"\nExample for custom commands\n" +" If you need to insert your own custom steps between programming and\n" +" verification, use the following commands to separate steps. (Serial\n" +" numbers are provided by the user to write to the device and provided\n" +" again by the user for verification.)\n" +"\n smt --device-count 3 --set-config my_config.txt --serial-nums { 20 21 22 23 }\n" +" smt --device-count 3 --reset\n" +" smt --device-count 3 --verify-config my_config.txt --serial-nums { 20 21 22 23 }\n" + ); +} + +CDevType readDevType() +{ + readKeyword( "FilterPartNumByte"); + readKeyword( "{"); // start of parameter list + BYTE partNum = readUcharParm(); + readKeyword( "}"); // end of parameter list + return CDevType( partNum); +} + +CVidPid readVidPid() +{ + readKeyword( "FilterVidPid"); + readKeyword( "{"); // start of parameter list + WORD vid = readUshortParm(); + WORD pid = readUshortParm(); + readKeyword( "}"); // end of parameter list + return CVidPid( vid, pid); +} + +bool isSpecified( int argc, const char * argv[], const std::string &parmName, std::string &fName) +{ + for( int i = 0; i < argc; i++) + { + if( std::string( argv[ i]) == parmName) + { + i++; + if( i < argc) + { + fName = argv[ i]; + return true; + } + throw CUsageErr( std::string( "file name is missing after ") + parmName + " command line option"); + } + } + return false; +} + +void redirStdinToCfgFile( int argc, const char * argv[]) +{ + std::string cfgFileName; + int fileNameCnt = 0; + if( isSpecified( argc, argv, "--set-and-verify-config", cfgFileName)) + { + fileNameCnt++; + } + if( isSpecified( argc, argv, "--set-config", cfgFileName)) + { + fileNameCnt++; + } + if( isSpecified( argc, argv, "--verify-config", cfgFileName)) + { + fileNameCnt++; + } + if( isSpecified( argc, argv, "--verify-locked-config", cfgFileName)) + { + fileNameCnt++; + } + if( isSpecified( argc, argv, "--reset", cfgFileName)) + { + fileNameCnt++; + } + if( isSpecified( argc, argv, "--list", cfgFileName)) + { + fileNameCnt++; + } + if( fileNameCnt == 1) + { + FILE * fp = freopen( cfgFileName.c_str(), "r", stdin); + if( !fp) + { + char msg[ 128]; + sprintf( msg, /*SIZEOF_ARRAY( msg),*/ "configuration file open error %d", errno); + throw CCustErr( msg); + } + } + else + { + throw CUsageErr( "command line must specify 1 configuration file"); + } +} + +int main( int argc, const char * argv[]) +{ + if( argc == 1 || isSpecified( argc, argv, "--help")) + { + printProgDesc(); + printCmdLineHelp(); + return 0; + } + + int rc = 1; + try + { + g_EchoParserReads = isSpecified( argc, argv, "--verbose"); + redirStdinToCfgFile( argc, argv); + const CDevType devType = readDevType(); + const CVidPid vidPid = readVidPid(); + LibSpecificMain( devType, vidPid, argc, argv); + rc = 0; + } + catch( const CDllErr e) + { + std::cerr << "ERROR: library: " << e.msg() << "\n"; + } + catch( const CCustErr e) + { + std::cerr << "ERROR: Manufacturing process: " << e.msg() << "\n"; + } + catch( const CUsageErr e) + { + std::cerr << e.msg() << "\n\n"; + printCmdLineHelp(); + } + catch( const CSyntErr ) + { + } + catch( const std::bad_alloc& ba) + { + std::cerr << "P: " << ba.what() << "\n"; + } + return rc; +} +//--------------------------------------------------------------------------------- +extern "C" +{ +#ifdef WIN32 +#include +#pragma comment (lib, "Rpcrt4.lib") +#else +// TODO USER_GUIDE "apt-get install uuid-dev" +// libuuid is part of the util-linux package since version 2.15. +#include +#endif +} + +// asks OS to generate a UUID, then converts to a byte vector with each element containing an ASCII character +std::vector< BYTE> generateUuidAscii() +{ +#ifdef WIN32 + UUID uuid; + RPC_STATUS rpcRc = UuidCreate( &uuid); + if( rpcRc != RPC_S_OK) + { + char msg[ 128]; + sprintf( msg, /*SIZEOF_ARRAY( msg),*/ "RPC failed to generate UUID, error 0x%x", rpcRc); + throw CDllErr( msg); + } +#else + uuid_t uuid; + uuid_generate_random ( uuid ); +#endif + BYTE *pByteUuid = reinterpret_cast(&uuid); + + std::vector< BYTE> v; + for( size_t i = 0; i < sizeof( uuid); i++) + { + char byteStr[ 3]; + sprintf( byteStr, /*SIZEOF_ARRAY( byteStr),*/ "%02x", pByteUuid[ i ]); + v.push_back( byteStr[ 0]); + v.push_back( byteStr[ 1]); + } + return v; +} + +// converts a zero-term char string to a byte vector with each element containing an ASCII character +std::vector< BYTE> toAscii( const char *sz) +{ + std::vector< BYTE> v; + for( size_t i = 0; i < strlen( sz); i++) + { + v.push_back( reinterpret_cast( sz[ i])); + } + return v; +} + +CSerNumSet::CSerNumSet( int argc, const char * argv[], bool mayAutoGen, DWORD requiredCnt) +{ + m_AreNeeded = false; + for( int i = 0; i < argc; i++) + { + if( std::string( argv[ i]) == "--serial-nums") + { + m_AreNeeded = true; + i++; + if( i < argc) + { + if( std::string( argv[ i]) == "{") + { + // SNs are specified in the command line + i++; + for( ; i < argc; i++) + { + if( std::string( argv[ i]) == "}") + { + if( m_SN.size() != requiredCnt) + { + throw CCustErr( "Serial number count is different from --device-count"); + } + assertUniquness(); + return; + } + m_SN.push_back( toAscii( argv[ i])); + } + throw CUsageErr( "Invalid serial number command line option"); + } + else if( std::string( argv[ i]) == "GUID") + { + // User requests SN aotu-generation + if( mayAutoGen) + { + ASSERT( m_SN.empty()); + for( DWORD j = 0; j < requiredCnt; j++) + { + m_SN.push_back( generateUuidAscii()); + } + assertUniquness(); + return; + } + else + { + throw CUsageErr( "GUID option is illegal"); + } + } + } + throw CUsageErr( "Invalid serial number command line option"); + } + } + ASSERT( !m_AreNeeded); +} +void CSerNumSet::assertUniquness() const +{ + ASSERT( m_AreNeeded); + if( !m_SN.size()) + { + return; + } + for( size_t i = 0; i < m_SN.size() - 1; i++) + { + for( size_t j = i + 1; j < m_SN.size(); j++) + { + if( m_SN[ i] == m_SN[ j]) + { + throw CUsageErr( "Identical serial numbers"); + } + } + } +} +void CSerNumSet::write() const +{ + if( m_SN.empty()) + { + return; + } + printf( "--- new serial numbers ---\n"); + for( size_t i = 0; i < m_SN.size(); i++) + { + for( size_t j = 0; j < m_SN[ i].size(); j++) + { + printf( "%c", m_SN[ i][ j]); + } + printf( "\n"); + } + printf( "--------------------------\n"); +} +bool CSerNumSet::findAndErase( const std::vector< BYTE> &sN) +{ + for (std::vector< std::vector< BYTE> >::iterator it = m_SN.begin() ; it != m_SN.end(); ++it) + { + if( *it == sN) + { + m_SN.erase( it); + return true; + } + } + return false; +} +//--------------------------------------------------------------------------------- +bool isSpecified( int argc, const char * argv[], const std::string &parmName) +{ + for( int i = 0; i < argc; i++) + { + if( std::string( argv[ i]) == parmName) + { + return true; + } + } + return false; +} +DWORD decimalParm( int argc, const char * argv[], const std::string &parmName) +{ + for( int i = 0; i < argc; i++) + { + if( std::string( argv[ i]) == parmName) + { + i++; + if( i < argc) + { + unsigned long rc = strtoul( argv[ i], NULL, 10); + if( rc && rc != ULONG_MAX) + { + return rc; + } + } + } + } + throw CUsageErr( std::string( "Invalid or missing ") + parmName + " command line option"); +} +//--------------------------------------------------------------------------------- +void waitForTotalDeviceCount( const CVidPid &oldVidPid, const CVidPid &newVidPid, DWORD expectedCount) +{ +#ifdef _WIN32 +#pragma warning(suppress : 4127) + while (true) +#else + while (true) +#endif + { + const DWORD NumDevs = LibSpecificNumDevices( oldVidPid, newVidPid); + if( NumDevs == expectedCount) + { + printf( "waiting 3 sec...\n"); + delayMsec( 3000); // TODO - either this or extra retry messages on screen + return; + } + std::cerr << "INFO: Waiting. " << NumDevs << " devices found, need " << expectedCount << "\n"; + delayMsec( 1000); + } + throw CCustErr( "devices failed to reboot after reset"); // dead code +} diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.h new file mode 100644 index 0000000..ffd0b9b --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/smt.h @@ -0,0 +1,540 @@ +// Copyright (c) 2015-2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#ifndef __SLABSMT_H__ +#define __SLABSMT_H__ 1 + +#ifdef _WIN32 +#include +#pragma warning(disable : 4996) // TODO - I'd be happy to use never functions if everybody upgraded to VS2015 +#else +#include "OsDep.h" +#endif +#include // for errno +#include "stdio.h" + +inline void delayMsec( DWORD msec) +{ + Sleep( msec); +} + +struct CErrMsg +{ + CErrMsg( const char *msg) : m_Msg( msg) {} + CErrMsg( const std::string msg ) : m_Msg( msg) {} + const std::string &msg() const { return m_Msg; } +private: + const std::string m_Msg; +}; +struct CDllErr : public CErrMsg // thrown any time a call to the DLL fails +{ + CDllErr( const char *msg) : CErrMsg( msg) {} +}; +struct CCustErr : public CErrMsg // thrown any time the customization process goes wrong +{ + CCustErr( const char *msg) : CErrMsg( msg) {} +}; +struct CUsageErr : public CErrMsg // thrown any time a parameter is specified wrong +{ + CUsageErr( const std::string msg ) : CErrMsg( msg) {} +}; + +// Just to save 3 lines each time this needs to be done +inline void setSpecified( bool &specified, const std::string &parmName) +{ + if( specified) + { + throw CSyntErr( std::string( "multiple occurence of ") + parmName); + } + specified = true; +} + +//----------------------------------------------------------------------- +// ctor reads SNs from command line or auto-generates if command line says so + +struct CSerNumSet +{ + // analyzes the command line; if requested, creates a set of SNs + CSerNumSet( int argc, const char * argv[], bool mayAutoGen, DWORD requiredCnt); + void write() const; + size_t size() const { return m_SN.size(); } + bool empty() const { return m_SN.empty(); } + const std::vector< BYTE>& at( DWORD index) const { return m_SN[ index ]; } + // if the set contains the gives SN, removes it and returns true + bool findAndErase( const std::vector< BYTE> &sN); +private: + void assertUniquness() const; + bool m_AreNeeded; + std::vector< std::vector< BYTE> > m_SN; +}; + +//----------------------------------------------------------------------- +// check if one of command line arguments is equal to the string +bool isSpecified( int argc, const char * argv[], const std::string &parmName); +// find a command line argument equal to the string and convert the next one to DWORD, throw CUsageErr otherwise +DWORD decimalParm( int argc, const char * argv[], const std::string &parmName); + +//----------------------------------------------------------------------- +// Identifies a specific device within a family of devices supported by the same customization lib. + +struct CDevType +{ + CDevType( BYTE partNum) : m_PartNum( partNum) {} + BYTE Value() const { return m_PartNum; } +private: + const BYTE m_PartNum; +}; + +//----------------------------------------------------------------------- +struct CVidPid +{ + CVidPid( WORD vid, WORD pid) : m_Vid( vid), m_Pid( pid ) {} + const WORD m_Vid; + const WORD m_Pid; +}; + +//----------------------------------------------------------------------- +// These functions must be implemented in the library-specific module +// +DWORD LibSpecificNumDevices( const CVidPid &oldVidPid, const CVidPid &newVidPid); +// This func must call the templated DevSpecificMain with device-specific types +void LibSpecificMain( const CDevType &devType, const CVidPid &vidPid, int argc, const char * argv[]); + +//--------------------------------------------------------------------------------- +// A helper class for CDevSet, to associate a dtor with the vector of device pointers, that deletes +// all devices. This can't be done in CDevSet dtor because it won't be called if ctor throws. +// If I could use C++ 11 and emplace_back() were not broken in VS2015, I'd simply use a vector of objects +// instead of vectror of pointers. +template< class TDev > +struct CDevVector : public std::vector< TDev*> +{ + ~CDevVector() + { + for( size_t i = 0; i < std::vector< TDev*>::size(); i++) + { + delete std::vector::at( i); + } + } +}; + +//--------------------------------------------------------------------------------- +// Set of opened devices. Not all devices exposed by the +// customization lib are included, but only those matching FilterVidPid. + +template< class TDev > +class CDevSet +{ +public: + CDevSet( const CDevType &FilterDevType, const CVidPid &FilterVidPid, bool allowLocked = false); + DWORD size() const { return static_cast( m_DevSet.size()); } + const TDev& at( size_t i) const { return *m_DevSet[ i]; } + void printDevInfo() const; +private: + CDevVector m_DevSet; +}; +template< class TDev > +CDevSet::CDevSet( const CDevType &FilterDevType, const CVidPid &FilterVidPid, bool allowLocked) +{ + DWORD NumDevs = LibSpecificNumDevices( FilterVidPid, FilterVidPid); + + ASSERT( m_DevSet.empty()); + for( DWORD i = 0; i < NumDevs; i++) + { + TDev *pDev = new TDev( FilterVidPid, i); + const CDevType devType = pDev->getDevType(); + const CVidPid vidPid = pDev->getVidPid(); + if( FilterDevType.Value() == devType.Value() && + ( FilterVidPid.m_Vid == vidPid.m_Vid) && + ( FilterVidPid.m_Pid == vidPid.m_Pid)) + { + if( pDev->isLocked() && !allowLocked) + { + delete pDev; + throw CCustErr( "Locked device found"); + } + m_DevSet.push_back( pDev); + } + else + { + delete pDev; + } + } +} +template< class TDev > +void CDevSet::printDevInfo() const +{ + for( size_t i = 0; i < size(); i++) + { + const CVidPid vidPid = at( i).getVidPid(); + printf( "VID: %04x PID: %04x ", vidPid.m_Vid, vidPid.m_Pid); + printf( "Prod Str: %s ", toString( at( i).getProduct( true)).c_str()); + printf( "Ser #: %s", toString( at( i).getSerNum( true)).c_str()); + printf( "\n"); + } +} +//--------------------------------------------------------------------------------- +// Manufacturer string customization availability varies by device, so it's extracted into a class +// of its own, then included by each individual device type that supports it. + +template< class TDev > +struct CManufacturerString +{ + CManufacturerString( bool supportsUnicode) : m_SupportsUnicode( supportsUnicode) { m_Specified = false; } + bool readParm( const std::string &parmName); + void program( const TDev &dev) const; + void verify( const TDev &dev) const; +private: + const bool m_SupportsUnicode; + bool m_Specified; + bool m_IsAscii; + std::vector m_str; +}; +template< class TDev > +bool CManufacturerString::readParm( const std::string &parmName) +{ + if( parmName == "ManufacturerStringAscii") + { + setSpecified( m_Specified, parmName); + m_IsAscii = true; + readByteArrayParm( m_str, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + return true; + } + else if( parmName == "ManufacturerStringUnicode" && m_SupportsUnicode) + { + setSpecified( m_Specified, parmName); + m_IsAscii = false; + readByteArrayParm( m_str, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + return true; + } + return false; +} +template< class TDev > +void CManufacturerString::program( const TDev &dev) const +{ + if( !m_Specified) { return; } + dev.setManufacturer( m_str, m_IsAscii); +} +template< class TDev > +void CManufacturerString::verify( const TDev &dev) const +{ + if( !m_Specified) { return; } + if( m_str != dev.getManufacturer( m_IsAscii)) + { + throw CCustErr( "Failed ManufacturerString verification"); + } +} +//--------------------------------------------------------------------------------- +// Common parameters for all devices +// WARNING: program() doesn't program all items readParm() and verify() handle. +// The rest of them is left to device-specific Parms::program(). + +template< class TDev > +struct CDevParms +{ + CDevParms() + { + m_VidPidSpecified = false; + m_ProdStrSpecified = false; + m_PowerModeSpecified = false; + m_MaxPowerSpecified = false; + m_DevVerSpecified = false; + } + void read() + { + std::string parmName; + while( readWord( parmName)) + { + readKeyword( "{"); // start of parameter list + readParm( parmName); + } + } + virtual bool supportsUnicode() const { return false; } + virtual void readParm( const std::string &parmName); + virtual void program( const TDev &dev, const std::vector *pSerNum) const; + virtual void verify( const TDev &dev, CSerNumSet &serNumSet) const; + bool m_VidPidSpecified; + WORD m_Vid; + WORD m_Pid; + bool m_ProdStrSpecified; + bool m_ProdStrIsAscii; + std::vector m_ProdStr; + bool m_PowerModeSpecified; + BYTE m_PowerMode; + bool m_MaxPowerSpecified; + BYTE m_MaxPower; + bool m_DevVerSpecified; + WORD m_DevVer; + + void resetAll( const CDevSet &devSet) const; + void programAll( const CDevSet &devSet, const CSerNumSet &serNumSet) const; + void verifyAll( const CDevSet &devSet, CSerNumSet sSerNumSet) const; + void lockAll( const CDevSet &devSet) const; +}; + +void waitForTotalDeviceCount( const CVidPid &oldVidPid, const CVidPid &newVidPid, DWORD expectedCount); + +template< class TDev > +void CDevParms::readParm( const std::string &parmName) +{ + if( parmName == "VidPid") + { + setSpecified( m_VidPidSpecified, parmName); + m_Vid = readUshortParm(); + m_Pid = readUshortParm(); + readKeyword( "}"); // end of parameter list + } + else if( parmName == "PowerMode") + { + setSpecified( m_PowerModeSpecified, parmName); + m_PowerMode = readUcharParm(); + readKeyword( "}"); // end of parameter list + } + else if( parmName == "MaxPower") + { + setSpecified( m_MaxPowerSpecified, parmName); + m_MaxPower = readUcharParm(); + readKeyword( "}"); // end of parameter list + } + else if( parmName == "DeviceVersion") + { + setSpecified( m_DevVerSpecified, parmName); + m_DevVer = readUshortParm(); + readKeyword( "}"); // end of parameter list + } + else if( parmName == "ProductStringAscii") + { + setSpecified( m_ProdStrSpecified, parmName); + m_ProdStrIsAscii = true; + readByteArrayParm( m_ProdStr, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + } + else if( parmName == "ProductStringUnicode" && supportsUnicode()) + { + setSpecified( m_ProdStrSpecified, parmName); + m_ProdStrIsAscii = false; + readByteArrayParm( m_ProdStr, MAX_UCHAR); + readKeyword( "}"); // end of parameter list + } + else + { + throw CSyntErr( std::string( "unknown customization parameter ") + parmName); + } +} +template< class TDev > +void CDevParms::program( const TDev &dev, const std::vector *pSerNum) const +{ + if( pSerNum) + { + dev.setSerNum( *pSerNum, true /*isAscii*/); + } + if( m_ProdStrSpecified) + { + dev.setProduct( m_ProdStr, m_ProdStrIsAscii); + } +} +template< class TDev > +void CDevParms::verify( const TDev &dev, CSerNumSet &serNumSet) const +{ + if( !serNumSet.empty()) + { + if( !serNumSet.findAndErase( dev.getSerNum( true /*isAscii*/))) + { + throw CCustErr( "Failed serial number verification"); + } + } + if( m_VidPidSpecified) + { + CVidPid devVidPid = dev.getVidPid(); + if( devVidPid.m_Vid != m_Vid || devVidPid.m_Pid != m_Pid) + { + throw CCustErr( "Failed VidPid verification"); + } + } + if( m_PowerModeSpecified) + { + if( m_PowerMode != dev.getPowerMode()) + { + throw CCustErr( "Failed PowerMode verification"); + } + } + if( m_MaxPowerSpecified) + { + if( m_MaxPower != dev.getMaxPower()) + { + throw CCustErr( "Failed MaxPower verification"); + } + } + if( m_DevVerSpecified) + { + if( m_DevVer != dev.getDevVer()) + { + throw CCustErr( "Failed DeviceVersion verification"); + } + } + if( m_ProdStrSpecified) + { + if( m_ProdStr != dev.getProduct( m_ProdStrIsAscii)) + { + throw CCustErr( "Failed ProductString verification"); + } + } +} +template< class TDev > +void CDevParms::resetAll( const CDevSet &devSet) const +{ + for( size_t i = 0; i < devSet.size(); i++) + { + devSet.at( i).reset(); + } +} +template< class TDev > +void CDevParms::programAll( const CDevSet &devSet, const CSerNumSet &serNumSet) const +{ + for( DWORD i = 0; i < devSet.size(); i++) + { + program( devSet.at( i), !serNumSet.empty() ? &serNumSet.at( i) : NULL); + } +} +template< class TDev > +void CDevParms::verifyAll( const CDevSet &devSet, CSerNumSet serNumSet) const +{ + for( DWORD i = 0; i < devSet.size(); i++) + { + verify( devSet.at( i), serNumSet); + } + ASSERT( serNumSet.empty()); +} +template< class TDev > +void CDevParms::lockAll( const CDevSet &devSet) const +{ + for( DWORD i = 0; i < devSet.size(); i++) + { + devSet.at( i).lock(); + } +} +//--------------------------------------------------------------------------------- +template< class TDev, class TDevParms > +void DevSpecificMain( const CDevType &devType, const CVidPid &FilterVidPid, int argc, const char * argv[]) +{ + TDevParms devParms; + devParms.read(); + + // If the cfg file doesn't specify a new vid-pid, it's not changing; + // so the new vid-pid is the same as filter vid-pid. + const CVidPid NewFilterVidPid( devParms.m_VidPidSpecified ? devParms.m_Vid : FilterVidPid.m_Vid, + devParms.m_VidPidSpecified ? devParms.m_Pid : FilterVidPid.m_Pid); + + if( isSpecified( argc, argv, "--reset")) + { + const CDevSet oldDevSet( devType, FilterVidPid, true /*allowLocked*/); + devParms.resetAll( oldDevSet); + if( FilterVidPid.m_Vid != NewFilterVidPid.m_Vid || FilterVidPid.m_Pid != NewFilterVidPid.m_Pid) + { + const CDevSet newDevSet( devType, NewFilterVidPid, true /*allowLocked*/); + devParms.resetAll( newDevSet); + } + return; + } + + if( isSpecified( argc, argv, "--list")) + { + const CDevSet oldDevSet( devType, FilterVidPid, true /*allowLocked*/); + printf( "--- devices --------------\n"); + oldDevSet.printDevInfo(); + if( FilterVidPid.m_Vid != NewFilterVidPid.m_Vid || FilterVidPid.m_Pid != NewFilterVidPid.m_Pid) + { + const CDevSet newDevSet( devType, NewFilterVidPid, true /*allowLocked*/); + newDevSet.printDevInfo(); + } + printf( "--------------------------\n"); + return; + } + + const bool program = isSpecified( argc, argv, "--set-and-verify-config") || + isSpecified( argc, argv, "--set-config") ; + const bool verify = isSpecified( argc, argv, "--set-and-verify-config") || + isSpecified( argc, argv, "--verify-config") || + isSpecified( argc, argv, "--verify-locked-config") ; + const bool lock = isSpecified( argc, argv, "--lock"); + if( lock && !verify) + { + throw CUsageErr( "--lock must be combined with one of \"verify\" commands"); + } + const DWORD custNumDevices = decimalParm( argc, argv, "--device-count"); + + const CSerNumSet serNumSet( argc, argv, program, custNumDevices); + + const DWORD startNumDevices = LibSpecificNumDevices( FilterVidPid, FilterVidPid); + if( program) + { + const CDevSet devSet( devType, FilterVidPid); + if( devSet.size() != custNumDevices) + { + char msg[ 128]; + sprintf( msg, "programming step: expected %d devices, found %d", custNumDevices, devSet.size()); + throw CCustErr( msg); + } + serNumSet.write(); + devParms.programAll( devSet, serNumSet); + if( verify) + { + devParms.resetAll( devSet); + } + printf( "programmed %u devices: OK\n", devSet.size()); + } + if( verify) + { +#if 0 + printf( "*** unplug now ***\n"); + delayMsec( 2000); +#endif + // retry verification until it succeeds, the user can press ^C to cancel +#ifdef _WIN32 +#pragma warning(suppress : 4127) +#endif + while( true) + { + try // catch the exceptions that mignt go away on retry + { + if( program) + { + waitForTotalDeviceCount( FilterVidPid, NewFilterVidPid, startNumDevices); + } + const bool allowLocked = !program && !lock && isSpecified( argc, argv, "--verify-locked-config"); + const CDevSet devSet( devType, NewFilterVidPid, allowLocked); + if( devSet.size() != custNumDevices) + { + char msg[ 128]; + sprintf( msg, "verification step: expected %d devices, found %d", custNumDevices, devSet.size()); + throw CCustErr( msg); + } + devParms.verifyAll( devSet, serNumSet); // gets a copy of serNumSet + printf( "verified %d devices: OK\n", devSet.size()); + if( lock) + { + devParms.lockAll( devSet); + printf( "locked %d devices: OK\n", devSet.size()); + } + break; + } + catch( const CDllErr e) + { + std::cerr << "WARNING: library: " << e.msg() << "\n"; + } + catch( const CCustErr e) + { + std::cerr << "WARNING: Manufacturing process: " << e.msg() << "\n"; + } + delayMsec( 1000); + std::cerr << "Retrying verification...\n"; + } + } +} +#endif // __SLABSMT_H__ diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.cpp b/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.cpp new file mode 100644 index 0000000..10a3841 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.cpp @@ -0,0 +1,257 @@ +// Copyright (c) 2015-2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#include +#include +#include +#include +#include "util.h" +#include +#include + +bool g_EchoParserReads = false; + +// convenience wrappers for output +void writeFuncName( std::string funcName) +{ + printf( "\n%s", funcName.c_str()); +} +void writeStr( std::string s) +{ + printf( " %s", s.c_str()); +} +void writeUlong( int val) +{ + printf( " %08x", (DWORD) val); +} +void writeUlong( DWORD val) +{ + printf( " %08x", val); +} +void writeUlongParm( DWORD val) +{ + printf( " { %08x }", val); +} +void writeUshort( WORD val) +{ + printf( " %04x", val); +} +void writeUshortParm( WORD val) +{ + printf( " { %04x }", val); +} +void writeUchar( BYTE val) +{ + printf( " %02x", val); +} +void writeUcharParm( BYTE val) +{ + printf( " { %02x }", val); +} +void writeByteArray( const std::vector &arr) +{ + for( size_t i = 0; i < arr.size(); i++) + { + writeUchar( arr[ i]); + } +} +void writeByteArray( DWORD CbArr, const BYTE *arr) +{ + for( DWORD i = 0; i < CbArr; i++) + { + writeUchar( arr[ i]); + } +} +void writeByteArrayParm( const std::vector &arr) +{ + writeStr( "{"); + writeByteArray( arr); + writeStr( "}"); +} + +// read from stdin any word, that is, a sequence without spaces +bool readWord( std::string &word ) +{ + word.clear(); + int last = 0; + while( (last = std::cin.get()) != EOF) + { + if( !isspace( last)) + { + // entered the word + word += static_cast( last); + while( (last = std::cin.get()) != EOF) + { + if( isspace( last)) + { + if( g_EchoParserReads) + { + printf( "%s%c", word.c_str(), last); + } + return true; // exited the word + } + word += static_cast( last); + } + return true; // end of parameter list + } + } + return false; // couldn't read a word +} + +// read from stdin a specific word +void readKeyword( const std::string &keyWord ) +{ + std::string word; + if( !readWord( word) || word != keyWord) + { + throw CSyntErr( std::string( "expected ") + keyWord); + } +} + +void AssertHex( const std::string &valStr, const DWORD digitCnt) +{ + if( valStr.size() != digitCnt) + { + throw CSyntErr( "invalid hex number size"); + } + for( DWORD i = 0; i < digitCnt; i++) + { + if( !isxdigit( valStr[i])) + { + throw CSyntErr( "invalid hex number size"); + } + } +} + +// read from stdin a hex ulong +DWORD readUlong() +{ + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex ulong"); + } + AssertHex( valStr, 8); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} +DWORD readUlongParm() +{ + readKeyword( "{"); + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex ulong"); + } + readKeyword( "}"); + AssertHex( valStr, 8); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} + +// read from stdin a hex ushort +WORD readUshort() +{ + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex ushort"); + } + AssertHex( valStr, 4); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} +WORD readUshortParm() +{ + readKeyword( "{"); + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex ushort"); + } + AssertHex( valStr, 4); + readKeyword( "}"); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} + +// read from stdin a hex uchar +BYTE readUchar() +{ + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex uchar"); + } + AssertHex( valStr, 2); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} +BYTE readUcharParm() +{ + readKeyword( "{"); + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( "expected hex uchar"); + } + AssertHex( valStr, 2); + readKeyword( "}"); + return static_cast( strtoul(valStr.c_str(), NULL, 16)); +} + +// read from stdin a byte given as 2 hex digits, else the terminator +bool readUcharElseTerm( BYTE &val, const std::string &terminator) +{ + std::string valStr; + if( !readWord( valStr)) + { + throw CSyntErr( std::string( "expected hex byte or ") + terminator); + } + if( valStr == std::string( terminator)) + { + return false; + } + if( valStr.size() != 2 || !isxdigit( valStr[0]) || !isxdigit( valStr[1])) + { + throw CSyntErr( std::string( "expected hex byte or ") + terminator); + } + val = static_cast( strtoul(valStr.c_str(), NULL, 16)); + return true; +} + +// read from stdin a variable-size byte array in braces +void readByteArrayParm( std::vector &arr, size_t max) +{ + readKeyword( "{"); + arr.clear(); + BYTE b; + while( readUcharElseTerm( b, "}")) + { + if( max && arr.size() == max) + { + throw CSyntErr( "byte array too large"); + } + arr.push_back( b); + } +} + +// read from stdin an exact-size byte array in braces +void readByteArrayParmExact( std::vector &arr, size_t CeRequired) +{ + readByteArrayParm( arr, CeRequired); + if( arr.size() != CeRequired) + { + throw CSyntErr( "byte array too small"); + } +} + +std::string toString( const std::vector &a) +{ + std::string s; + for( size_t i = 0; i < a.size(); i++) + { + s += a[ i]; + } + return s; +} \ No newline at end of file diff --git a/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.h b/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.h new file mode 100644 index 0000000..c0b07f4 --- /dev/null +++ b/AN721SW/Linux/ManufacturingTool/cp210xsmt/util.h @@ -0,0 +1,73 @@ +// Copyright (c) 2015-2016 by Silicon Laboratories Inc. All rights reserved. +// The program contained in this listing is proprietary to Silicon Laboratories, +// headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright +// protection, including protection under the United States Copyright Act of 1976 +// as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII +// of the United States code. Unauthorized copying, adaptation, distribution, +// use, or display is prohibited by this law. + +#ifndef __SLABUTIL_H__ +#define __SLABUTIL_H__ 1 + +#ifdef _WIN32 +#include +#else +#include "OsDep.h" +#endif + +#ifdef _DEBUG +#define ASSERT(_exp) \ + ((!(_exp)) ? \ + (printf("%s(%d): Assertion failed\n Expression: %s\n", __FILE__, __LINE__, #_exp),FALSE) : \ + TRUE) +#else +#define ASSERT( exp ) ((void) 0) +#endif + +#define SIZEOF_ARRAY( a ) (sizeof( a ) / sizeof( a[0])) +#define MAX_UCHAR 0xff +#define MAX_USHORT 0xffff +#define MAX_ULONG 0xffffffff + +class CSyntErr // thrown any time the program can't continue processing input +{ +public: + CSyntErr( const std::string msg ) + { + std::cerr << "ERROR: syntax: " << msg << "\n"; + } +}; + +// convenience wrappers for output +void writeFuncName( std::string funcName); +void writeStr( std::string s); +void writeUlong( int val); +void writeUlong( DWORD val); +void writeUlongParm( DWORD val); +void writeUshort( WORD val); +void writeUshortParm( WORD val); +void writeUchar( BYTE val); +void writeUcharParm( BYTE val); +void writeByteArray( const std::vector &arr); +void writeByteArray( DWORD CbArr, const BYTE *arr); +void writeByteArrayParm( const std::vector &arr); + +bool readWord( std::string &word ); +void readKeyword( const std::string &keyWord ); +void AssertHex( const std::string &valStr, const DWORD digitCnt); +DWORD readUlong(); +DWORD readUlongParm(); +WORD readUshort(); +WORD readUshortParm(); +BYTE readUchar(); +BYTE readUcharParm(); +bool readUcharElseTerm( BYTE &val, const std::string &terminator); +void readByteArrayParm( std::vector &arr, size_t max); +void readByteArrayParmExact( std::vector &arr, size_t CeRequired); + +extern bool g_EchoParserReads; + +// misc +std::string toString( const std::vector &a); + +#endif // __SLABUTIL_H__ diff --git a/AN721SW/Linux/customizer/about.html b/AN721SW/Linux/customizer/about.html new file mode 100644 index 0000000..ebffd99 --- /dev/null +++ b/AN721SW/Linux/customizer/about.html @@ -0,0 +1,20 @@ + + + +About + + + +

About This Content

+ +

February 22, 2006

+

License

+ +

This directory contains third-party libraries that are required by the Eclipse launcher. Refer below for further information.

+ +

Cairo for Linux

+ +

Refer to the file about_cairo.html for licensing details about "Cairo for Linux".

+ + + diff --git a/docs/app-notes/AN197-serial-communications-guide.pdf b/docs/app-notes/AN197-serial-communications-guide.pdf new file mode 100644 index 0000000..b0cd209 Binary files /dev/null and b/docs/app-notes/AN197-serial-communications-guide.pdf differ diff --git a/docs/datasheets/CP2102-9-datasheet.pdf b/docs/datasheets/CP2102-9-datasheet.pdf new file mode 100644 index 0000000..3e33e47 Binary files /dev/null and b/docs/datasheets/CP2102-9-datasheet.pdf differ diff --git a/docs/datasheets/CP2102B-errata.pdf b/docs/datasheets/CP2102B-errata.pdf new file mode 100644 index 0000000..186eba4 Binary files /dev/null and b/docs/datasheets/CP2102B-errata.pdf differ