- 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/
1081 lines
38 KiB
C++
1081 lines
38 KiB
C++
// 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 <cstring>
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#pragma comment (lib, "CP210xManufacturing.lib")
|
|
#include "CP210xManufacturingDLL.h"
|
|
#else
|
|
#include "OsDep.h"
|
|
#include "CP210xManufacturing.h"
|
|
#endif
|
|
#include "stdio.h"
|
|
#include "util.h"
|
|
#include "smt.h"
|
|
|
|
void AbortOnErr( CP210x_STATUS status, std::string funcName)
|
|
{
|
|
if( status != CP210x_SUCCESS)
|
|
{
|
|
char msg[ 128];
|
|
sprintf( msg, /*SIZEOF_ARRAY( msg),*/ "%s returned 0x%x", funcName.c_str(), status);
|
|
throw CDllErr( msg);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
DWORD LibSpecificNumDevices( const CVidPid &, const CVidPid &)
|
|
{
|
|
DWORD DevCnt;
|
|
AbortOnErr( CP210x_GetNumDevices( &DevCnt ), "CP210x_GetNumDevices");
|
|
return DevCnt;
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
class CCP210xDev
|
|
{
|
|
public:
|
|
CCP210xDev( const CVidPid &FilterVidPid, DWORD devIndex);
|
|
~CCP210xDev();
|
|
HANDLE handle() const { return m_H; }
|
|
bool isLocked() const;
|
|
void lock() const;
|
|
void reset() const;
|
|
CDevType getDevType() const;
|
|
CVidPid getVidPid() const;
|
|
BYTE getPowerMode() const;
|
|
BYTE getMaxPower() const;
|
|
WORD getDevVer() const;
|
|
WORD getFlushBufCfg() const;
|
|
std::vector<BYTE> getSerNum( bool isAscii) const;
|
|
std::vector<BYTE> getManufacturer( bool isAscii) const;
|
|
std::vector<BYTE> getProduct( bool isAscii) const;
|
|
void setVidPid( WORD vid, WORD pid) const;
|
|
void setPowerMode( BYTE val) const;
|
|
void setMaxPower( BYTE val) const;
|
|
void setDevVer( WORD val) const;
|
|
void setFlushBufCfg( WORD val) const;
|
|
void setSerNum( const std::vector<BYTE> &str, bool isAscii) const;
|
|
void setManufacturer( const std::vector<BYTE> &str, bool isAscii) const;
|
|
void setProduct( const std::vector<BYTE> &str, bool isAscii) const;
|
|
|
|
HANDLE m_H;
|
|
};
|
|
CCP210xDev::CCP210xDev( const CVidPid &, DWORD devIndex)
|
|
{
|
|
AbortOnErr( CP210x_Open( devIndex, &m_H), "CP210x_Open");
|
|
}
|
|
CCP210xDev::~CCP210xDev()
|
|
{
|
|
CP210x_STATUS status = CP210x_Close( m_H);
|
|
if( status != CP210x_SUCCESS)
|
|
{
|
|
std::cerr << "CP210x_Close failed\n";
|
|
}
|
|
}
|
|
bool CCP210xDev::isLocked() const
|
|
{
|
|
BYTE lock;
|
|
AbortOnErr( CP210x_GetLockValue( m_H, &lock), "CP210x_GetLockValue");
|
|
return lock != 0;
|
|
}
|
|
void CCP210xDev::lock() const
|
|
{
|
|
AbortOnErr( CP210x_SetLockValue( m_H), "CP210x_SetLockValue");
|
|
}
|
|
void CCP210xDev::reset() const
|
|
{
|
|
AbortOnErr( CP210x_Reset( m_H), "CP210x_Reset");
|
|
}
|
|
CDevType CCP210xDev::getDevType() const
|
|
{
|
|
BYTE partNum;
|
|
AbortOnErr( CP210x_GetPartNumber( m_H, &partNum ), "CP210x_GetPartNumber");
|
|
return CDevType( partNum);
|
|
}
|
|
CVidPid CCP210xDev::getVidPid() const
|
|
{
|
|
WORD vid, pid;
|
|
AbortOnErr( CP210x_GetDeviceVid( m_H, &vid ), "CP210x_GetDeviceVid");
|
|
AbortOnErr( CP210x_GetDevicePid( m_H, &pid ), "CP210x_GetDevicePid");
|
|
return CVidPid( vid, pid);
|
|
}
|
|
BYTE CCP210xDev::getPowerMode() const
|
|
{
|
|
BOOL SelfPower;
|
|
AbortOnErr( CP210x_GetSelfPower( m_H, &SelfPower), "CP210x_GetSelfPower");
|
|
return SelfPower ? 1 : 0;
|
|
}
|
|
BYTE CCP210xDev::getMaxPower() const
|
|
{
|
|
BYTE MaxPower;
|
|
AbortOnErr( CP210x_GetMaxPower( m_H, &MaxPower), "CP210x_GetMaxPower");
|
|
return MaxPower;
|
|
}
|
|
WORD CCP210xDev::getDevVer() const
|
|
{
|
|
WORD devVer;
|
|
AbortOnErr( CP210x_GetDeviceVersion( m_H, &devVer), "CP210x_GetDeviceVersion");
|
|
return devVer;
|
|
}
|
|
WORD CCP210xDev::getFlushBufCfg() const
|
|
{
|
|
WORD flushBufCfg;
|
|
AbortOnErr( CP210x_GetFlushBufferConfig( m_H, &flushBufCfg), "CP210x_GetFlushBufferConfig");
|
|
return flushBufCfg;
|
|
}
|
|
std::vector<BYTE> CCP210xDev::getSerNum( bool isAscii) const
|
|
{
|
|
std::vector<BYTE> str( MAX_UCHAR);
|
|
BYTE CchStr = 0;
|
|
AbortOnErr( CP210x_GetDeviceSerialNumber( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceSerialNumber");
|
|
str.resize( CchStr * (isAscii ? 1 : 2));
|
|
return str;
|
|
}
|
|
std::vector<BYTE> CCP210xDev::getManufacturer( bool isAscii) const
|
|
{
|
|
std::vector<BYTE> str( MAX_UCHAR);
|
|
BYTE CchStr = 0;
|
|
AbortOnErr( CP210x_GetDeviceManufacturerString( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceManufacturerString");
|
|
str.resize( CchStr * (isAscii ? 1 : 2));
|
|
return str;
|
|
}
|
|
std::vector<BYTE> CCP210xDev::getProduct( bool isAscii) const
|
|
{
|
|
std::vector<BYTE> str( MAX_UCHAR);
|
|
BYTE CchStr = 0;
|
|
AbortOnErr( CP210x_GetDeviceProductString( m_H, str.data(), &CchStr, isAscii), "CP210x_GetDeviceProductString");
|
|
str.resize( CchStr * (isAscii ? 1 : 2));
|
|
return str;
|
|
}
|
|
void CCP210xDev::setVidPid( WORD vid, WORD pid) const
|
|
{
|
|
AbortOnErr( CP210x_SetVid( m_H, vid), "CP210x_SetVid");
|
|
AbortOnErr( CP210x_SetPid( m_H, pid), "CP210x_SetPid");
|
|
}
|
|
void CCP210xDev::setPowerMode( BYTE val) const
|
|
{
|
|
AbortOnErr( CP210x_SetSelfPower( m_H, val ? TRUE : FALSE ), "CP210x_SetSelfPower");
|
|
}
|
|
void CCP210xDev::setMaxPower( BYTE val) const
|
|
{
|
|
AbortOnErr( CP210x_SetMaxPower( m_H, val), "CP210x_SetMaxPower");
|
|
}
|
|
void CCP210xDev::setDevVer( WORD val) const
|
|
{
|
|
AbortOnErr( CP210x_SetDeviceVersion( m_H, val), "CP210x_SetDeviceVersion");
|
|
}
|
|
void CCP210xDev::setFlushBufCfg( WORD val) const
|
|
{
|
|
AbortOnErr( CP210x_SetFlushBufferConfig( m_H, val), "CP210x_SetFlushBufferConfig");
|
|
}
|
|
void CCP210xDev::setSerNum( const std::vector<BYTE> &str, bool isAscii) const
|
|
{
|
|
BYTE CchStr = static_cast<BYTE> ( str.size() / (isAscii ? 1 : 2));
|
|
AbortOnErr( CP210x_SetSerialNumber( m_H, const_cast<BYTE*>( str.data()), CchStr, isAscii), "CP210x_SetSerialNumber");
|
|
}
|
|
void CCP210xDev::setManufacturer( const std::vector<BYTE> &str, bool isAscii) const
|
|
{
|
|
BYTE CchStr = static_cast<BYTE> ( str.size() / (isAscii ? 1 : 2));
|
|
AbortOnErr( CP210x_SetManufacturerString( m_H, const_cast<BYTE*>( str.data()), CchStr, isAscii), "CP210x_SetManufacturerString");
|
|
}
|
|
void CCP210xDev::setProduct( const std::vector<BYTE> &str, bool isAscii) const
|
|
{
|
|
BYTE CchStr = static_cast<BYTE> ( str.size() / (isAscii ? 1 : 2));
|
|
AbortOnErr( CP210x_SetProductString( m_H, const_cast<BYTE*>( str.data()), CchStr, isAscii), "CP210x_SetProductString");
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// CP2102N has non-standard get/set lock functions.
|
|
|
|
#pragma pack(push, 1)
|
|
// The original complete copy of the below struct is called Config_t in the CP2102N repo.
|
|
// "Used to store default settings and customized values passed from host PC."
|
|
union CCP2102NConfig {
|
|
struct { // just the top of it, as far as we need
|
|
WORD configSize;
|
|
BYTE configVersion;
|
|
// Allows Bootloader entry from VCP vendor command/HID report. Bootloader always runs
|
|
// if flash address 0x0 is 0xFF.
|
|
BYTE enableBootloader;
|
|
// Allows configuration updates. If a bad burn happens, this will become
|
|
// 0xff allowing a recovery.
|
|
BYTE enableConfigUpdate;
|
|
} Fields;
|
|
BYTE Raw[ 0x2a6];
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
#define CP2102N_CONFIG_VERSION 1
|
|
#define CP2102N_CONFIG_UNLOCKED 0xff
|
|
|
|
class CCP2102NDev : public CCP210xDev
|
|
{
|
|
public:
|
|
CCP2102NDev( const CVidPid &FilterVidPid, DWORD devIndex) : CCP210xDev( FilterVidPid, devIndex) {}
|
|
bool isLocked() const;
|
|
void lock() const;
|
|
};
|
|
bool CCP2102NDev::isLocked() const
|
|
{
|
|
CCP2102NConfig Config = {0};
|
|
AbortOnErr( CP210x_GetConfig( m_H, &Config.Raw[0], static_cast<WORD>( sizeof( Config))), "CP210x_GetConfig");
|
|
if( Config.Fields.configVersion != CP2102N_CONFIG_VERSION)
|
|
{
|
|
throw CCustErr( "CP2102N returned unknown config version");
|
|
}
|
|
if( Config.Fields.configSize < sizeof( Config.Fields))
|
|
{
|
|
throw CCustErr( "CP2102N returned invalid config size");
|
|
}
|
|
return Config.Fields.enableConfigUpdate != CP2102N_CONFIG_UNLOCKED;
|
|
}
|
|
void CCP2102NDev::lock() const
|
|
{
|
|
CCP2102NConfig Config;
|
|
AbortOnErr( CP210x_GetConfig( m_H, &Config.Raw[0], static_cast<WORD>( sizeof( Config))), "CP210x_GetConfig");
|
|
Config.Fields.enableConfigUpdate = 0;
|
|
AbortOnErr( CP210x_SetConfig( m_H, &Config.Raw[0], static_cast<WORD>( sizeof( Config))), "CP210x_SetConfig");
|
|
|
|
CCP2102NConfig finalConfig;
|
|
AbortOnErr( CP210x_GetConfig( m_H, &finalConfig.Raw[0], static_cast<WORD>( sizeof( finalConfig))), "CP210x_GetConfig");
|
|
if( memcmp( &Config.Raw[0], &finalConfig.Raw[0], sizeof( finalConfig)))
|
|
{
|
|
throw CCustErr( "CP2102N config verification failed after locking");
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Here is a bunch of customization parametersfound in cp210x devices. They are included
|
|
// into each individual cp210x device that supports the parameter.
|
|
//---------------------------------------------------------------------------------
|
|
struct CFlushBufferConfig
|
|
{
|
|
CFlushBufferConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
WORD m_Config;
|
|
};
|
|
bool CFlushBufferConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "FlushBufferConfig")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
m_Config = readUshortParm();
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CFlushBufferConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
dev.setFlushBufCfg( m_Config);
|
|
}
|
|
void CFlushBufferConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
if( m_Config != dev.getFlushBufCfg())
|
|
{
|
|
throw CCustErr( "Failed FlushBufferConfig verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CDeviceMode
|
|
{
|
|
CDeviceMode() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
BYTE m_ModeECI;
|
|
BYTE m_ModeSCI;
|
|
};
|
|
bool CDeviceMode::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "DeviceMode")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
m_ModeECI = readUcharParm();
|
|
m_ModeSCI = readUcharParm();
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CDeviceMode::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetDeviceMode( dev.handle(), m_ModeECI, m_ModeSCI), "CP210x_SetDeviceMode");
|
|
}
|
|
void CDeviceMode::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
BYTE ModeECI;
|
|
BYTE ModeSCI;
|
|
AbortOnErr( CP210x_GetDeviceMode( dev.handle(), &ModeECI, &ModeSCI), "CP210x_GetDeviceMode");
|
|
if( m_ModeECI != ModeECI || m_ModeSCI != ModeSCI)
|
|
{
|
|
throw CCustErr( "Failed DeviceMode verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CInterfaceString
|
|
{
|
|
CInterfaceString() { m_Specified = false; }
|
|
bool readParm( BYTE ifc, const std::string &parmName);
|
|
void program( BYTE ifc, const CCP210xDev &dev) const;
|
|
void verify( BYTE ifc, const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
bool m_IsAscii;
|
|
std::vector<BYTE> m_str;
|
|
};
|
|
bool CInterfaceString::readParm( BYTE ifc, const std::string &parmName)
|
|
{
|
|
char ifcDigit = '0' + ifc;
|
|
if( parmName == std::string( "InterfaceStringAscii") + ifcDigit)
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
m_IsAscii = true;
|
|
readByteArrayParm( m_str, MAX_UCHAR);
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
else if( parmName == std::string("InterfaceStringUnicode") + ifcDigit)
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
m_IsAscii = false;
|
|
readByteArrayParm( m_str, MAX_UCHAR);
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CInterfaceString::program( BYTE ifc, const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
BYTE CchStr = static_cast<BYTE> ( m_str.size() / (m_IsAscii ? 1 : 2));
|
|
AbortOnErr( CP210x_SetInterfaceString( dev.handle(), ifc, const_cast<BYTE*>( m_str.data()), CchStr, m_IsAscii), "CP210x_SetInterfaceString");
|
|
}
|
|
void CInterfaceString::verify( BYTE ifc, const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
std::vector<BYTE> str( MAX_UCHAR);
|
|
BYTE CchStr = 0;
|
|
AbortOnErr( CP210x_GetDeviceInterfaceString( dev.handle(), ifc, str.data(), &CchStr, m_IsAscii), "CP210x_GetDeviceInterfaceString");
|
|
str.resize( CchStr * (m_IsAscii ? 1 : 2));
|
|
if( m_str != str)
|
|
{
|
|
throw CCustErr( "Failed InterfaceString verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CBaudRateConfig
|
|
{
|
|
CBaudRateConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
BAUD_CONFIG m_Config[ NUM_BAUD_CONFIGS];
|
|
};
|
|
bool CBaudRateConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "BaudRateConfig")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
readKeyword( "{");
|
|
for( DWORD i = 0; i < SIZEOF_ARRAY( m_Config); i++)
|
|
{
|
|
m_Config[ i].BaudGen = readUshort();
|
|
m_Config[ i].Timer0Reload = readUshort();
|
|
m_Config[ i].Prescaler = readUchar();
|
|
m_Config[ i].BaudRate = readUlong();
|
|
}
|
|
readKeyword( "}");
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CBaudRateConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetBaudRateConfig( dev.handle(), const_cast<BAUD_CONFIG*>(&m_Config[ 0])), "CP210x_SetBaudRateConfig");
|
|
}
|
|
void CBaudRateConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
BAUD_CONFIG Config[ NUM_BAUD_CONFIGS];
|
|
AbortOnErr( CP210x_GetBaudRateConfig( dev.handle(), &Config[ 0]), "CP210x_GetBaudRateConfig");
|
|
for( DWORD i = 0; i < SIZEOF_ARRAY( m_Config); i++)
|
|
{
|
|
// printf("verify %d\n", Config[ i].BaudRate); // TODO remove
|
|
if( m_Config[ i].BaudGen != Config[ i].BaudGen ||
|
|
m_Config[ i].Timer0Reload != Config[ i].Timer0Reload ||
|
|
m_Config[ i].Prescaler != Config[ i].Prescaler ||
|
|
m_Config[ i].BaudRate != Config[ i].BaudRate)
|
|
{
|
|
throw CCustErr( "Failed BaudRateConfig verification");
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CPortConfig
|
|
{
|
|
CPortConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
PORT_CONFIG m_PortCfg;
|
|
};
|
|
bool CPortConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "PortConfig")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
readKeyword( "{");
|
|
m_PortCfg.Mode = readUshort();
|
|
m_PortCfg.Reset_Latch = readUshort();
|
|
m_PortCfg.Suspend_Latch = readUshort();
|
|
m_PortCfg.EnhancedFxn = readUchar();
|
|
readKeyword( "}");
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CPortConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetPortConfig( dev.handle(), const_cast<PORT_CONFIG*>(&m_PortCfg)), "CP210x_SetPortConfig");
|
|
}
|
|
void CPortConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
PORT_CONFIG PortCfg;
|
|
AbortOnErr( CP210x_GetPortConfig( dev.handle(), &PortCfg), "CP210x_GetPortConfig");
|
|
if( m_PortCfg.Mode != PortCfg.Mode ||
|
|
m_PortCfg.Reset_Latch != PortCfg.Reset_Latch ||
|
|
m_PortCfg.Suspend_Latch != PortCfg.Suspend_Latch ||
|
|
m_PortCfg.EnhancedFxn != PortCfg.EnhancedFxn)
|
|
{
|
|
throw CCustErr( "Failed PortConfig verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CDualPortConfig
|
|
{
|
|
CDualPortConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
DUAL_PORT_CONFIG m_PortCfg;
|
|
};
|
|
bool CDualPortConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "DualPortConfig")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
readKeyword( "{");
|
|
m_PortCfg.Mode = readUshort();
|
|
m_PortCfg.Reset_Latch = readUshort();
|
|
m_PortCfg.Suspend_Latch = readUshort();
|
|
m_PortCfg.EnhancedFxn_ECI = readUchar();
|
|
m_PortCfg.EnhancedFxn_SCI = readUchar();
|
|
m_PortCfg.EnhancedFxn_Device = readUchar();
|
|
readKeyword( "}");
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CDualPortConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetDualPortConfig( dev.handle(), const_cast<DUAL_PORT_CONFIG*>(&m_PortCfg)), "CP210x_SetDualPortConfig");
|
|
}
|
|
void CDualPortConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
DUAL_PORT_CONFIG PortCfg;
|
|
AbortOnErr( CP210x_GetDualPortConfig( dev.handle(), &PortCfg), "CP210x_GetDualPortConfig");
|
|
if( m_PortCfg.Mode != PortCfg.Mode ||
|
|
m_PortCfg.Reset_Latch != PortCfg.Reset_Latch ||
|
|
m_PortCfg.Suspend_Latch != PortCfg.Suspend_Latch ||
|
|
m_PortCfg.EnhancedFxn_ECI != PortCfg.EnhancedFxn_ECI ||
|
|
m_PortCfg.EnhancedFxn_SCI != PortCfg.EnhancedFxn_SCI ||
|
|
m_PortCfg.EnhancedFxn_Device != PortCfg.EnhancedFxn_Device)
|
|
{
|
|
throw CCustErr( "Failed DualPortConfig verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CQuadPortConfig
|
|
{
|
|
CQuadPortConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
QUAD_PORT_CONFIG m_PortCfg;
|
|
};
|
|
void readQuadPortState( QUAD_PORT_STATE &qps)
|
|
{
|
|
qps.Mode_PB0 = readUshort();
|
|
qps.Mode_PB1 = readUshort();
|
|
qps.Mode_PB2 = readUshort();
|
|
qps.Mode_PB3 = readUshort();
|
|
qps.Mode_PB4 = readUshort();
|
|
qps.LowPower_PB0 = readUshort();
|
|
qps.LowPower_PB1 = readUshort();
|
|
qps.LowPower_PB2 = readUshort();
|
|
qps.LowPower_PB3 = readUshort();
|
|
qps.LowPower_PB4 = readUshort();
|
|
qps.Latch_PB0 = readUshort();
|
|
qps.Latch_PB1 = readUshort();
|
|
qps.Latch_PB2 = readUshort();
|
|
qps.Latch_PB3 = readUshort();
|
|
qps.Latch_PB4 = readUshort();
|
|
}
|
|
bool CQuadPortConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "QuadPortConfig")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
readKeyword( "{");
|
|
readQuadPortState( m_PortCfg.Reset_Latch);
|
|
readQuadPortState( m_PortCfg.Suspend_Latch);
|
|
m_PortCfg.IPDelay_IFC0 = readUchar();
|
|
m_PortCfg.IPDelay_IFC1 = readUchar();
|
|
m_PortCfg.IPDelay_IFC2 = readUchar();
|
|
m_PortCfg.IPDelay_IFC3 = readUchar();
|
|
m_PortCfg.EnhancedFxn_IFC0 = readUchar();
|
|
m_PortCfg.EnhancedFxn_IFC1 = readUchar();
|
|
m_PortCfg.EnhancedFxn_IFC2 = readUchar();
|
|
m_PortCfg.EnhancedFxn_IFC3 = readUchar();
|
|
m_PortCfg.EnhancedFxn_Device = readUchar();
|
|
m_PortCfg.ExtClk0Freq = readUchar();
|
|
m_PortCfg.ExtClk1Freq = readUchar();
|
|
m_PortCfg.ExtClk2Freq = readUchar();
|
|
m_PortCfg.ExtClk3Freq = readUchar();
|
|
readKeyword( "}");
|
|
readKeyword( "}"); // end of parameter list
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CQuadPortConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetQuadPortConfig( dev.handle(), const_cast<QUAD_PORT_CONFIG*>(&m_PortCfg)), "CP210x_SetQuadPortConfig");
|
|
}
|
|
bool isEqualQuadPortState( const QUAD_PORT_STATE &qps1, const QUAD_PORT_STATE &qps2)
|
|
{
|
|
if( qps1.Mode_PB0 != qps2.Mode_PB0 ||
|
|
qps1.Mode_PB1 != qps2.Mode_PB1 ||
|
|
qps1.Mode_PB2 != qps2.Mode_PB2 ||
|
|
qps1.Mode_PB3 != qps2.Mode_PB3 ||
|
|
qps1.Mode_PB4 != qps2.Mode_PB4 ||
|
|
qps1.LowPower_PB0 != qps2.LowPower_PB0 ||
|
|
qps1.LowPower_PB1 != qps2.LowPower_PB1 ||
|
|
qps1.LowPower_PB2 != qps2.LowPower_PB2 ||
|
|
qps1.LowPower_PB3 != qps2.LowPower_PB3 ||
|
|
qps1.LowPower_PB4 != qps2.LowPower_PB4 ||
|
|
qps1.Latch_PB0 != qps2.Latch_PB0 ||
|
|
qps1.Latch_PB1 != qps2.Latch_PB1 ||
|
|
qps1.Latch_PB2 != qps2.Latch_PB2 ||
|
|
qps1.Latch_PB3 != qps2.Latch_PB3 ||
|
|
qps1.Latch_PB4 != qps2.Latch_PB4)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
void CQuadPortConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
QUAD_PORT_CONFIG PortCfg;
|
|
AbortOnErr( CP210x_GetQuadPortConfig( dev.handle(), &PortCfg), "CP210x_GetQuadPortConfig");
|
|
if( !isEqualQuadPortState( m_PortCfg.Reset_Latch, PortCfg.Reset_Latch ) ||
|
|
!isEqualQuadPortState( m_PortCfg.Suspend_Latch, PortCfg.Suspend_Latch ) ||
|
|
m_PortCfg.IPDelay_IFC0 != PortCfg.IPDelay_IFC0 ||
|
|
m_PortCfg.IPDelay_IFC1 != PortCfg.IPDelay_IFC1 ||
|
|
m_PortCfg.IPDelay_IFC2 != PortCfg.IPDelay_IFC2 ||
|
|
m_PortCfg.IPDelay_IFC3 != PortCfg.IPDelay_IFC3 ||
|
|
m_PortCfg.EnhancedFxn_IFC0 != PortCfg.EnhancedFxn_IFC0 ||
|
|
m_PortCfg.EnhancedFxn_IFC1 != PortCfg.EnhancedFxn_IFC1 ||
|
|
m_PortCfg.EnhancedFxn_IFC2 != PortCfg.EnhancedFxn_IFC2 ||
|
|
m_PortCfg.EnhancedFxn_IFC3 != PortCfg.EnhancedFxn_IFC3 ||
|
|
m_PortCfg.EnhancedFxn_Device != PortCfg.EnhancedFxn_Device ||
|
|
m_PortCfg.ExtClk0Freq != PortCfg.ExtClk0Freq ||
|
|
m_PortCfg.ExtClk1Freq != PortCfg.ExtClk1Freq ||
|
|
m_PortCfg.ExtClk2Freq != PortCfg.ExtClk2Freq ||
|
|
m_PortCfg.ExtClk3Freq != PortCfg.ExtClk3Freq)
|
|
{
|
|
throw CCustErr( "Failed QuadPortConfig verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CConfig
|
|
{
|
|
CConfig() { m_Specified = false; }
|
|
bool readParm( const std::string &parmName);
|
|
void program( const CCP210xDev &dev) const;
|
|
void verify( const CCP210xDev &dev) const;
|
|
private:
|
|
bool m_Specified;
|
|
CCP2102NConfig m_Config;
|
|
};
|
|
bool CConfig::readParm( const std::string &parmName)
|
|
{
|
|
if( parmName == "Config")
|
|
{
|
|
setSpecified( m_Specified, parmName);
|
|
|
|
// Jeff said it's best to always write the whole thing, hence "Exact" read
|
|
std::vector<BYTE> Config;
|
|
readByteArrayParmExact( Config, sizeof( m_Config));
|
|
readKeyword( "}"); // end of parameter list
|
|
std::memcpy( &m_Config.Raw[0], &Config[0], sizeof( m_Config)); // Copy into the formatted storage
|
|
|
|
// Few sanity checks
|
|
if( m_Config.Fields.configVersion != CP2102N_CONFIG_VERSION)
|
|
{
|
|
throw CUsageErr( "CP2102N Config::configVersion is invalid");
|
|
}
|
|
if( m_Config.Fields.configSize != sizeof(CCP2102NConfig))
|
|
{
|
|
throw CUsageErr( "CP2102N Config::configSize is invalid");
|
|
}
|
|
if( m_Config.Fields.enableConfigUpdate != CP2102N_CONFIG_UNLOCKED)
|
|
{
|
|
// The user isn't trying to lock the config by enableConfigUpdate. We don't allow this,
|
|
// we lock it explicitly after verification, by writing same data with enableConfigUpdate
|
|
// clear.
|
|
throw CUsageErr( "CP2102N Config::enableConfigUpdate attempts to lock, use --lock instead");
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void CConfig::program( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
AbortOnErr( CP210x_SetConfig( dev.handle(), const_cast<BYTE*>( &m_Config.Raw[0]), static_cast<WORD>( sizeof( m_Config.Raw))), "CP210x_SetConfig");
|
|
}
|
|
void CConfig::verify( const CCP210xDev &dev) const
|
|
{
|
|
if( !m_Specified) { return; }
|
|
CCP2102NConfig readConfig;
|
|
AbortOnErr( CP210x_GetConfig( dev.handle(), &readConfig.Raw[0], static_cast<WORD>( sizeof( readConfig.Raw))), "CP210x_GetConfig");
|
|
|
|
// A little hack to workaround locked configurations.
|
|
// If the Config on the chip is locked, the dumb array comparison will fail because of enableConfigUpdate.
|
|
// But it wouldn't be a valid failure. So, hack the "unlocked" value into it before comparing.
|
|
ASSERT( m_Config.Fields.enableConfigUpdate == CP2102N_CONFIG_UNLOCKED);
|
|
readConfig.Fields.enableConfigUpdate = CP2102N_CONFIG_UNLOCKED;
|
|
|
|
if( memcmp( &readConfig.Raw[0], &m_Config.Raw[0], sizeof( readConfig)))
|
|
{
|
|
throw CCustErr( "Failed Config verification");
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
// Base class for all cp210x devices, contains ommmon customization parameters
|
|
//---------------------------------------------------------------------------------
|
|
template< class TDev >
|
|
struct CCP210xParms : public CDevParms<TDev>
|
|
{
|
|
virtual bool supportsUnicode() const { return true; }
|
|
virtual void readParm( const std::string &parmName);
|
|
void program( const TDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
void verify( const TDev &dev, CSerNumSet &serNumSet) const;
|
|
};
|
|
template< class TDev >
|
|
void CCP210xParms<TDev>::readParm( const std::string &parmName)
|
|
{
|
|
CDevParms<TDev>::readParm( parmName);
|
|
}
|
|
template< class TDev >
|
|
void CCP210xParms<TDev>::program( const TDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
#if 0 // TODO remove
|
|
if( pSerNum) {
|
|
std::vector<BYTE> sn = *pSerNum;
|
|
sn.push_back( 0);
|
|
printf( "program serial num: %s\n", sn.data());
|
|
sn.pop_back();
|
|
}
|
|
#endif
|
|
CDevParms<TDev>::program( dev, pSerNum);
|
|
if( CDevParms<TDev>::m_VidPidSpecified)
|
|
{
|
|
dev.setVidPid( CDevParms<TDev>::m_Vid, CDevParms<TDev>::m_Pid);
|
|
}
|
|
if( CDevParms<TDev>::m_PowerModeSpecified)
|
|
{
|
|
dev.setPowerMode( CDevParms<TDev>::m_PowerMode);
|
|
}
|
|
if( CDevParms<TDev>::m_MaxPowerSpecified)
|
|
{
|
|
dev.setMaxPower( CDevParms<TDev>::m_MaxPower);
|
|
}
|
|
if( CDevParms<TDev>::m_DevVerSpecified)
|
|
{
|
|
dev.setDevVer( CDevParms<TDev>::m_DevVer);
|
|
}
|
|
}
|
|
template< class TDev >
|
|
void CCP210xParms<TDev>::verify( const TDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CDevParms<TDev>::verify( dev, serNumSet);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2101Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
};
|
|
void CCP2101Parms::readParm( const std::string &parmName)
|
|
{
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2101Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
}
|
|
void CCP2101Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2102Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CBaudRateConfig m_BaudRateCfg;
|
|
};
|
|
void CCP2102Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_BaudRateCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2102Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_BaudRateCfg.program( dev);
|
|
}
|
|
void CCP2102Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_BaudRateCfg.verify( dev);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2102NParms : public CCP210xParms<CCP2102NDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP2102NDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP2102NDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CConfig m_Cfg;
|
|
};
|
|
void CCP2102NParms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_Cfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2102NParms::program( const CCP2102NDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_Cfg.program( dev);
|
|
}
|
|
void CCP2102NParms::verify( const CCP2102NDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_Cfg.verify( dev);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2103Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CBaudRateConfig m_BaudRateCfg;
|
|
CPortConfig m_PortCfg;
|
|
};
|
|
void CCP2103Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_PortCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_BaudRateCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2103Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_BaudRateCfg.program( dev);
|
|
m_PortCfg.program( dev);
|
|
}
|
|
void CCP2103Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_BaudRateCfg.verify( dev);
|
|
m_PortCfg.verify( dev);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2104Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CPortConfig m_PortCfg;
|
|
CFlushBufferConfig m_FlushBufferConfig;
|
|
};
|
|
void CCP2104Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_PortCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_FlushBufferConfig.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2104Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_PortCfg.program( dev);
|
|
m_FlushBufferConfig.program( dev);
|
|
}
|
|
void CCP2104Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_PortCfg.verify( dev);
|
|
m_FlushBufferConfig.verify( dev);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2105Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CFlushBufferConfig m_FlushBufferConfig;
|
|
CDeviceMode m_DeviceMode;
|
|
CDualPortConfig m_PortCfg;
|
|
CInterfaceString m_IfcStr[ 2];
|
|
};
|
|
void CCP2105Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_FlushBufferConfig.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_DeviceMode.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_PortCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
if( m_IfcStr[ i].readParm( i, parmName))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2105Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_FlushBufferConfig.program( dev);
|
|
m_DeviceMode.program( dev);
|
|
m_PortCfg.program( dev);
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
m_IfcStr[ i].program( i, dev);
|
|
}
|
|
}
|
|
void CCP2105Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_FlushBufferConfig.verify( dev);
|
|
m_DeviceMode.verify( dev);
|
|
m_PortCfg.verify( dev);
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
m_IfcStr[ i].verify( i, dev);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2108Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
CCP2108Parms() : m_ManufStr( true /*supportsUnicode*/) {}
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CFlushBufferConfig m_FlushBufferConfig;
|
|
CManufacturerString<CCP210xDev> m_ManufStr;
|
|
CQuadPortConfig m_PortCfg;
|
|
CInterfaceString m_IfcStr[ 4];
|
|
};
|
|
|
|
void CCP2108Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_FlushBufferConfig.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_ManufStr.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
if( m_PortCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
if( m_IfcStr[ i].readParm( i, parmName))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2108Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_FlushBufferConfig.program( dev);
|
|
m_ManufStr.program( dev);
|
|
m_PortCfg.program( dev);
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
m_IfcStr[ i].program( i, dev);
|
|
}
|
|
}
|
|
void CCP2108Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_FlushBufferConfig.verify( dev);
|
|
m_ManufStr.verify( dev);
|
|
m_PortCfg.verify( dev);
|
|
for( BYTE i = 0; i < SIZEOF_ARRAY( m_IfcStr); i++)
|
|
{
|
|
m_IfcStr[ i].verify( i, dev);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
struct CCP2109Parms : public CCP210xParms<CCP210xDev>
|
|
{
|
|
virtual void readParm( const std::string &parmName);
|
|
virtual void program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const;
|
|
virtual void verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const;
|
|
private:
|
|
CBaudRateConfig m_BaudRateCfg;
|
|
};
|
|
void CCP2109Parms::readParm( const std::string &parmName)
|
|
{
|
|
if( m_BaudRateCfg.readParm( parmName))
|
|
{
|
|
return;
|
|
}
|
|
CCP210xParms::readParm( parmName);
|
|
}
|
|
void CCP2109Parms::program( const CCP210xDev &dev, const std::vector<BYTE> *pSerNum) const
|
|
{
|
|
CCP210xParms::program( dev, pSerNum);
|
|
m_BaudRateCfg.program( dev);
|
|
}
|
|
void CCP2109Parms::verify( const CCP210xDev &dev, CSerNumSet &serNumSet) const
|
|
{
|
|
CCP210xParms::verify( dev, serNumSet);
|
|
m_BaudRateCfg.verify( dev);
|
|
}
|
|
//---------------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------------
|
|
void LibSpecificMain( const CDevType &devType, const CVidPid &vidPid, int argc, const char * argv[])
|
|
{
|
|
if( devType.Value() == CP210x_CP2101_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2101Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2102_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2102Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2102N_QFN28_VERSION ||
|
|
devType.Value() == CP210x_CP2102N_QFN24_VERSION ||
|
|
devType.Value() == CP210x_CP2102N_QFN20_VERSION)
|
|
{
|
|
DevSpecificMain<CCP2102NDev,CCP2102NParms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2103_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2103Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2104_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2104Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2105_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2105Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2108_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2108Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else if( devType.Value() == CP210x_CP2109_VERSION)
|
|
{
|
|
DevSpecificMain<CCP210xDev,CCP2109Parms> ( devType, vidPid, argc, argv);
|
|
}
|
|
else
|
|
{
|
|
throw CSyntErr( "Unsupported PartNum");
|
|
}
|
|
}
|