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/
This commit is contained in:
Ryan Malloy 2026-01-30 10:31:39 -07:00
commit a7f62e5d7e
68 changed files with 13175 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -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/

View File

@ -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

View File

@ -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 <string>
#include <vector>
#include <Windows.h>
#include <ntddser.h>
#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<BYTE> 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__

View File

@ -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 <CoreServices/CoreServices.h>
#include <pthread.h>
#include "Types.h"
#elif defined(__linux__)
#include "Types.h"
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#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

View File

@ -0,0 +1,155 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Includes
/////////////////////////////////////////////////////////////////////////////
#include "OsDep.h"
#include <vector>
#include <algorithm>
/////////////////////////////////////////////////////////////////////////////
// CDeviceList Class
/////////////////////////////////////////////////////////////////////////////
template <class T>
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<T*> m_list;
CCriticalSectionLock m_lock;
};
/////////////////////////////////////////////////////////////////////////////
// CDeviceList Class - Constructor/Destructor
/////////////////////////////////////////////////////////////////////////////
template <class T>
CDeviceList<T>::CDeviceList()
{
}
template <class T>
CDeviceList<T>::~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 <class T>
BOOL CDeviceList<T>::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 <class T>
T* CDeviceList<T>::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 <class T>
void CDeviceList<T>::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 <class T>
void CDeviceList<T>::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<T*>::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();
}

View File

@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////
// CCriticalSectionLock
/////////////////////////////////////////////////////////////////////////////
#ifndef __OS_DEP_H__
#define __OS_DEP_H__
#if defined(_WIN32)
#include "Types.h"
#else
#if defined(__APPLE__)
#include <CoreServices/CoreServices.h>
#include <pthread.h>
#include "Types.h"
#elif defined(__linux__)
#include "Types.h"
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#else
#error "error: Unsupported OS type"
#endif
DWORD GetTickCount();
void Sleep(DWORD msec);
#endif // defined(_WIN32)
#include "CriticalSectionLock.h"
#endif // __OS_DEP_H__

View File

@ -0,0 +1,21 @@
#ifndef REPORT_QUEUE_H
#define REPORT_QUEUE_H
#include "OsDep.h"
#include <vector>
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<BYTE> m_queue;
CCriticalSectionLock m_Lock;
};
#endif // REPORT_QUEUE_H

View File

@ -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 <windows.h>
#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

View File

@ -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)

View File

@ -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)

View File

@ -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 <WinSDKVer.h>
#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 <SdkDdkVer.h>
#include <windows.h>
// 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)

View File

@ -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)

View File

@ -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 <mach/mach.h>
#include <mach/mach_time.h>
#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 <stdio.h>
#include <stdarg.h>
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)

View File

@ -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)

View File

@ -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 <time.h>
#include <unistd.h> // 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);
}

View File

@ -0,0 +1,239 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Includes
/////////////////////////////////////////////////////////////////////////////
#include "Types.h"
#include <vector>
#include <string>
#include <fstream>
#include <iomanip>
#include <time.h>
/////////////////////////////////////////////////////////////////////////////
// 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<ProfilerTimestamp> m_timestamps;
};

View File

@ -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<DWORD>(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<DWORD>(m_queue.size());
m_Lock.Unlock();
return size;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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<DWORD>( 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<DWORD>(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;
}

View File

@ -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

View File

@ -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<CCP210xDevice> 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);
}

View File

@ -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;
}
}

View File

@ -0,0 +1,28 @@
/*
* CP210xSupportFunctions.h
*
* Created on: Oct 30, 2012
* Author: strowlan
*/
#ifndef CP210XSUPPORTFUNCTIONS_H_
#define CP210XSUPPORTFUNCTIONS_H_
#include <string.h>
#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_ */

View File

@ -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

View File

@ -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.

View File

@ -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<libraryname>:
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

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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
//-----------------------------------------------------------------------------

View File

@ -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 <CoreServices/CoreServices.h>
#include <pthread.h>
#include "Types.h"
#elif defined(__linux__)
#include "Types.h"
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#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

View File

@ -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)

View File

@ -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 <time.h>
#include <unistd.h> // 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);
}

View File

@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////
// CCriticalSectionLock
/////////////////////////////////////////////////////////////////////////////
#ifndef __OS_DEP_H__
#define __OS_DEP_H__
#if defined(_WIN32)
#include "Types.h"
#else
#if defined(__APPLE__)
#include <CoreServices/CoreServices.h>
#include <pthread.h>
#include "Types.h"
#elif defined(__linux__)
#include "Types.h"
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#else
#error "error: Unsupported OS type"
#endif
DWORD GetTickCount();
void Sleep(DWORD msec);
#endif // defined(_WIN32)
#include "CriticalSectionLock.h"
#endif // __OS_DEP_H__

View File

@ -0,0 +1,239 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Includes
/////////////////////////////////////////////////////////////////////////////
#include "Types.h"
#include <vector>
#include <string>
#include <fstream>
#include <iomanip>
#include <time.h>
/////////////////////////////////////////////////////////////////////////////
// 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<ProfilerTimestamp> m_timestamps;
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
/////////////////////////////////////////////////////////////////////////////

View File

@ -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 <windows.h>
#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

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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 <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <climits>
#include "util.h"
#include "smt.h"
#include <stdio.h>
#include <stdlib.h>
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 <decimal number>\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 <Rpc.h>
#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 <uuid/uuid.h>
#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<BYTE*>(&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<const BYTE&>( 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
}

View File

@ -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 <Windows.h>
#pragma warning(disable : 4996) // TODO - I'd be happy to use never functions if everybody upgraded to VS2015
#else
#include "OsDep.h"
#endif
#include <errno.h> // 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<TDev*>::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<DWORD>( m_DevSet.size()); }
const TDev& at( size_t i) const { return *m_DevSet[ i]; }
void printDevInfo() const;
private:
CDevVector<TDev> m_DevSet;
};
template< class TDev >
CDevSet<TDev>::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<TDev>::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<BYTE> m_str;
};
template< class TDev >
bool CManufacturerString<TDev>::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<TDev>::program( const TDev &dev) const
{
if( !m_Specified) { return; }
dev.setManufacturer( m_str, m_IsAscii);
}
template< class TDev >
void CManufacturerString<TDev>::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<BYTE> *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<BYTE> m_ProdStr;
bool m_PowerModeSpecified;
BYTE m_PowerMode;
bool m_MaxPowerSpecified;
BYTE m_MaxPower;
bool m_DevVerSpecified;
WORD m_DevVer;
void resetAll( const CDevSet<TDev> &devSet) const;
void programAll( const CDevSet<TDev> &devSet, const CSerNumSet &serNumSet) const;
void verifyAll( const CDevSet<TDev> &devSet, CSerNumSet sSerNumSet) const;
void lockAll( const CDevSet<TDev> &devSet) const;
};
void waitForTotalDeviceCount( const CVidPid &oldVidPid, const CVidPid &newVidPid, DWORD expectedCount);
template< class TDev >
void CDevParms<TDev>::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<TDev>::program( const TDev &dev, const std::vector<BYTE> *pSerNum) const
{
if( pSerNum)
{
dev.setSerNum( *pSerNum, true /*isAscii*/);
}
if( m_ProdStrSpecified)
{
dev.setProduct( m_ProdStr, m_ProdStrIsAscii);
}
}
template< class TDev >
void CDevParms<TDev>::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<TDev>::resetAll( const CDevSet<TDev> &devSet) const
{
for( size_t i = 0; i < devSet.size(); i++)
{
devSet.at( i).reset();
}
}
template< class TDev >
void CDevParms<TDev>::programAll( const CDevSet<TDev> &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<TDev>::verifyAll( const CDevSet<TDev> &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<TDev>::lockAll( const CDevSet<TDev> &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<TDev> oldDevSet( devType, FilterVidPid, true /*allowLocked*/);
devParms.resetAll( oldDevSet);
if( FilterVidPid.m_Vid != NewFilterVidPid.m_Vid || FilterVidPid.m_Pid != NewFilterVidPid.m_Pid)
{
const CDevSet<TDev> newDevSet( devType, NewFilterVidPid, true /*allowLocked*/);
devParms.resetAll( newDevSet);
}
return;
}
if( isSpecified( argc, argv, "--list"))
{
const CDevSet<TDev> 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<TDev> 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<TDev> 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<TDev> 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__

View File

@ -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 <string>
#include <sstream>
#include <iostream>
#include <vector>
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
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<BYTE> &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<BYTE> &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<char>( 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<char>( 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<DWORD>( 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<DWORD>( 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<WORD>( 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<WORD>( 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<BYTE>( 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<BYTE>( 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<BYTE>( strtoul(valStr.c_str(), NULL, 16));
return true;
}
// read from stdin a variable-size byte array in braces
void readByteArrayParm( std::vector<BYTE> &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<BYTE> &arr, size_t CeRequired)
{
readByteArrayParm( arr, CeRequired);
if( arr.size() != CeRequired)
{
throw CSyntErr( "byte array too small");
}
}
std::string toString( const std::vector<BYTE> &a)
{
std::string s;
for( size_t i = 0; i < a.size(); i++)
{
s += a[ i];
}
return s;
}

View File

@ -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 <Windows.h>
#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<BYTE> &arr);
void writeByteArray( DWORD CbArr, const BYTE *arr);
void writeByteArrayParm( const std::vector<BYTE> &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<BYTE> &arr, size_t max);
void readByteArrayParmExact( std::vector<BYTE> &arr, size_t CeRequired);
extern bool g_EchoParserReads;
// misc
std::string toString( const std::vector<BYTE> &a);
#endif // __SLABUTIL_H__

View File

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
</head>
<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<body lang="EN-US">
<h2>About This Content</h2>
<p>February 22, 2006</p>
<h3>License</h3>
<p>This directory contains third-party libraries that are required by the Eclipse launcher. Refer below for further information.</p>
<h4>Cairo for Linux</h4>
<p>Refer to the file <a href="about_files/about_cairo.html">about_cairo.html</a> for licensing details about &quot;Cairo for Linux&quot;.</p>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.