diff --git a/ambed/cftdidevicedescr.cpp b/ambed/cftdidevicedescr.cpp index 71cbfbf..88411a2 100644 --- a/ambed/cftdidevicedescr.cpp +++ b/ambed/cftdidevicedescr.cpp @@ -24,6 +24,10 @@ #include "main.h" #include +#include "cusb3000interface.h" +#include "cusb3003interface.h" +#include "cusb3003hrinterface.h" +#include "cusb3003df2etinterface.h" #include "cftdidevicedescr.h" @@ -56,3 +60,493 @@ CFtdiDeviceDescr::CFtdiDeviceDescr(const CFtdiDeviceDescr &descr) ::memcpy(m_szDescription, descr.m_szDescription, sizeof(m_szDescription)); ::memcpy(m_szSerial, descr.m_szSerial, sizeof(m_szSerial)); } + +//////////////////////////////////////////////////////////////////////////////////////// +// interface factory + +int CFtdiDeviceDescr::CreateInterface(CFtdiDeviceDescr *descr, std::vector*channels) +{ + int iNbChs = 0; + + // single channel devices cannot be created alone + // three channels devices + if ( (::strcmp(descr->GetDescription(), "USB-3003") == 0) || // DVSI's USB-3003 + (::strcmp(descr->GetDescription(), "DF2ET-3003") == 0) || // DF2ET's USB-3003 opensource device + (::strcmp(descr->GetDescription(), "ThumbDV-3") == 0) ) // ThumbDV-3 + { + iNbChs = CreateUsb3003(descr, channels); + } + // six channels devices + else if ( (::strcmp(descr->GetDescription(), "USB-3006 A") == 0) ) // LX3JL's USB-3006 opensource device + { + iNbChs = CreateUsb3006(descr, channels); + } + // twelves channels devices + else if ( (::strcmp(descr->GetDescription(), "USB-3012 A") == 0) ) // DVSI's USB-3012 + { + iNbChs = CreateUsb3012(descr, channels); + } + // done + return iNbChs; +} + +int CFtdiDeviceDescr::CreateInterfacePair(CFtdiDeviceDescr *descr1, CFtdiDeviceDescr *descr2, std::vector*channels) +{ + int iNbChs = 0; + + // create interface objects + if ( (descr1->GetNbChannels() == 1) && (descr1->GetNbChannels() == 1) ) + { + // create 3000-3000 pair + CUsb3000Interface *Usb3000A = InstantiateUsb3000(descr1); + CUsb3000Interface *Usb3000B = InstantiateUsb3000(descr2); + iNbChs = CreatePair(Usb3000A, Usb3000B, channels); + } + else if ( (descr1->GetNbChannels() == 3) && (descr1->GetNbChannels() == 1) ) + { + // create 3003-3000 pair + CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr1); + CUsb3000Interface *Usb3000 = InstantiateUsb3000(descr2); + iNbChs = CreatePair(Usb3003, Usb3000, channels); + } + else if ( (descr1->GetNbChannels() == 1) && (descr1->GetNbChannels() == 3) ) + { + // create 3000-3003 pair + CUsb3000Interface *Usb3000 = InstantiateUsb3000(descr1); + CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr2); + iNbChs = CreatePair(Usb3003, Usb3000, channels); + } + else if ( (descr1->GetNbChannels() == 3) && (descr1->GetNbChannels() == 3) ) + { + // create 3003-3003 pair + CUsb3003Interface *Usb3003A = InstantiateUsb3003(descr1); + CUsb3003Interface *Usb3003B = InstantiateUsb3003(descr2); + iNbChs = CreatePair(Usb3003A, Usb3003B, channels); + } + + // done + return iNbChs; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// get + +int CFtdiDeviceDescr::GetNbChannels(void) const +{ + int iNbChs = 0; + + // single channel devices + if ( (::strcmp(m_szDescription, "USB-3000") == 0) || // DVSI's USB-3000 + (::strcmp(m_szDescription, "ThumbDV") == 0) ) // ThumbDV + { + iNbChs = 1; + } + // three channels devices + else if ( (::strcmp(m_szDescription, "USB-3003") == 0) || // DVSI's USB-3003 + (::strcmp(m_szDescription, "DF2ET-3003") == 0) || // DF2ET's USB-3003 opensource device + (::strcmp(m_szDescription, "ThumbDV-3") == 0) ) // ThumbDV-3 + { + iNbChs = 3; + } + // six channels devices + else if ( (::strcmp(m_szDescription, "USB-3006 A") == 0) ) // LX3JL's USB-3006 opensource device + { + iNbChs = 6; + } + // twelves channels devices + else if ( (::strcmp(m_szDescription, "USB-3012 A") == 0) ) // DVSI's USB-3012 + { + iNbChs = 12; + } + + // done + return iNbChs; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// DVSI's USB-3012 factory helper +// +// This device uses 3 AMBE3003 connected on a single FTDI 4 channels +// USB to serial interface. The reset mechanism is based +// on DTR and SetBreak. Baudrate is 921600 +// + +int CFtdiDeviceDescr::CreateUsb3012(CFtdiDeviceDescr *descr, std::vector*channels) +{ + int nStreams = 0; + + // create the interfaces for the four 3003 chips + CUsb3003HRInterface *Usb3003A = + new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), "USB-3012_A", descr->GetSerialNumber()); + CUsb3003HRInterface *Usb3003B = + new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), "USB-3012_B", descr->GetSerialNumber()); + CUsb3003HRInterface *Usb3003C = + new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), "USB-3012_C", descr->GetSerialNumber()); + CUsb3003HRInterface *Usb3003D = + new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), "USB-3012_D", descr->GetSerialNumber()); + + // init the interfaces + if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) && + Usb3003C->Init(CODEC_AMBEPLUS) && Usb3003D->Init(CODEC_AMBE2PLUS) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch3 + Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch4 + Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch5 + Channel = new CVocodecChannel(Usb3003C, 0, Usb3003C, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003C->AddChannel(Channel); + // ch6 + Channel = new CVocodecChannel(Usb3003C, 1, Usb3003C, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003C->AddChannel(Channel); + // ch7 + Channel = new CVocodecChannel(Usb3003D, 0, Usb3003D, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003D->AddChannel(Channel); + // ch8 + Channel = new CVocodecChannel(Usb3003D, 1, Usb3003D, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003D->AddChannel(Channel); + // ch9 + Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + // ch10 + Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + // ch11 + Channel = new CVocodecChannel(Usb3003C, 2, Usb3003D, 2, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003C->AddChannel(Channel); + Usb3003D->AddChannel(Channel); + // ch12 + Channel = new CVocodecChannel(Usb3003D, 2, Usb3003C, 2, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003C->AddChannel(Channel); + Usb3003D->AddChannel(Channel); + //done + nStreams = 12; + } + } + else + { + // cleanup + delete Usb3003A; + delete Usb3003B; + delete Usb3003C; + delete Usb3003D; + } + + // done + return nStreams; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// LX3JL's USB-3006 factory helper +// +// This device uses 2 AMBE3003 connected on a single FTDI 2 channels +// USB to serial interface. The reset mechanism is based +// on DTR and software reset. Baudrate is 921600 +// +int CFtdiDeviceDescr::CreateUsb3006(CFtdiDeviceDescr *descr, std::vector*channels) +{ + int nStreams = 0; + + // create the interfaces for the four 3003 chips + CUsb3003Interface *Usb3003A = + new CUsb3003Interface(descr->GetVid(), descr->GetPid(), "USB-3006_A", descr->GetSerialNumber()); + CUsb3003Interface *Usb3003B = + new CUsb3003Interface(descr->GetVid(), descr->GetPid(), "USB-3006_B", descr->GetSerialNumber()); + + // init the interfaces + if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch3 + Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch4 + Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch5 + Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + // ch6 + Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + //done + nStreams = 6; + } + } + else + { + // cleanup + delete Usb3003A; + delete Usb3003B; + } + + // done + return nStreams; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// USB-3003 factory helpers +// DVSI +// DF2ET +// ThumbDV +// +// These devices uses a AMBE3003 connected on a single FTDI +// USB to serial interface. The reset mechanism is based +// on DTR and SetBreak, or software. Baudrate is 921600 +// +int CFtdiDeviceDescr::CreateUsb3003(CFtdiDeviceDescr *descr, std::vector*channels) +{ + int nStreams = 0; + + // create the interfaces for the 3003 chip + CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr); + + // init the interface + if ( (Usb3003 != NULL) && Usb3003->Init(CODEC_NONE) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3003, 0, Usb3003, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3003, 1, Usb3003, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003->AddChannel(Channel); + // done + nStreams = 2; + } + } + else + { + // cleanup + delete Usb3003; + } + + // done + return nStreams; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// 1 ch + 1 ch pair creation + +int CFtdiDeviceDescr::CreatePair(CUsb3000Interface *Usb3000A, CUsb3000Interface *Usb3000B, std::vector*channels) +{ + int nStreams = 0; + + // init the interfaces + if ( Usb3000A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3000A, 0, Usb3000B, 0, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3000A->AddChannel(Channel); + Usb3000B->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3000A, 0, Usb3000B, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3000A->AddChannel(Channel); + Usb3000B->AddChannel(Channel); + // done + nStreams = 2; + } + } + else + { + // cleanup + delete Usb3000A; + delete Usb3000B; + } + + // done + return nStreams; + +} + +//////////////////////////////////////////////////////////////////////////////////////// +// 3 ch + 3 ch pair creation + +int CFtdiDeviceDescr::CreatePair(CUsb3003Interface *Usb3003A, CUsb3003Interface *Usb3003B, std::vector*channels) +{ + int nStreams = 0; + + // init the interfaces + if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch3 + Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch4 + Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003B->AddChannel(Channel); + // ch5 + Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + // ch6 + Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3003B->AddChannel(Channel); + // done + nStreams = 6; + } + } + else + { + // cleanup + delete Usb3003A; + delete Usb3003B; + } + + // done + return nStreams; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// 3 ch + 1 ch pair creation + +int CFtdiDeviceDescr::CreatePair(CUsb3003Interface *Usb3003A, CUsb3000Interface *Usb3000B, std::vector*channels) +{ + int nStreams = 0; + + // init the interfaces + if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) ) + { + CVocodecChannel *Channel; + // create all channels + { + // ch1 + Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch2 + Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + // ch5 + Channel = new CVocodecChannel(Usb3003A, 2, Usb3000B, 0, CODECGAIN_AMBEPLUS); + channels->push_back(Channel); + Usb3003A->AddChannel(Channel); + Usb3000B->AddChannel(Channel); + // done + nStreams = 6; + } + } + else + { + // cleanup + delete Usb3003A; + delete Usb3000B; + } + + // done + return nStreams; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// interface instantiation helpers + +CUsb3003Interface *CFtdiDeviceDescr::InstantiateUsb3003(CFtdiDeviceDescr *descr) +{ + CUsb3003Interface *Usb3003 = NULL; + + // intstantiate the proper version of USB-3003 + if ( (::strcmp(descr->GetDescription(), "USB-3003") == 0) ) // DVSI's USB-3003 + { + // hardware reset, 921600 bps + Usb3003 = new CUsb3003HRInterface + (descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber()); + } + else if ( (::strcmp(descr->GetDescription(), "DF2ET-3003") == 0) ) // DF2ET's USB-3003 opensource device + { + // specific hardware reset, 921600 bps + Usb3003 = new CUsb3003DF2ETInterface + (descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber()); + } + else if ( (::strcmp(descr->GetDescription(), "ThumbDV-3") == 0) ) // ThumbDV-3 + { + // software reset, 921600 bps + Usb3003 = new CUsb3003Interface + (descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber()); + } + // done + return Usb3003; +} + +CUsb3000Interface *CFtdiDeviceDescr::InstantiateUsb3000(CFtdiDeviceDescr *descr) +{ + CUsb3000Interface *Usb3000 = NULL; + + // intstantiate the proper version of USB-3000 + if ( (::strcmp(descr->GetDescription(), "USB-3000") == 0) || // DVSI's USB-3000 + (::strcmp(descr->GetDescription(), "ThumbDV") == 0) ) // ThumbDV + { + Usb3000 = new CUsb3000Interface + (descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber()); + } + // done + return Usb3000; +} diff --git a/ambed/cftdidevicedescr.h b/ambed/cftdidevicedescr.h index acbc1bd..c01b485 100644 --- a/ambed/cftdidevicedescr.h +++ b/ambed/cftdidevicedescr.h @@ -27,6 +27,7 @@ #include #include "ftd2xx.h" +#include "cvocodecchannel.h" //////////////////////////////////////////////////////////////////////////////////////// // define @@ -38,6 +39,9 @@ //////////////////////////////////////////////////////////////////////////////////////// // class +class CUsb3000Interface; +class CUsb3003Interface; + class CFtdiDeviceDescr { public: @@ -48,12 +52,14 @@ public: // destructor virtual ~CFtdiDeviceDescr() {} - + + // interface factory + static int CreateInterface(CFtdiDeviceDescr *, std::vector*); + static int CreateInterfacePair(CFtdiDeviceDescr *, CFtdiDeviceDescr *, std::vector*); + // get - bool IsUsed(void) const {return m_bUsed; } - bool IsUsb3000(void) const { return (::strcmp(m_szDescription, "USB-3000") == 0); } - bool IsUsb3003(void) const { return (::strcmp(m_szDescription, "USB-3003") == 0); } - bool IsUsb3012(void) const { return (::strcmp(m_szDescription, "USB-3012 A") == 0); } + bool IsUsed(void) const { return m_bUsed; } + int GetNbChannels(void) const; uint32 GetVid(void) const { return m_uiVid; } uint32 GetPid(void) const { return m_uiPid; } const char *GetDescription(void) const { return m_szDescription; } @@ -61,7 +67,18 @@ public: // set void SetUsed(bool used) { m_bUsed = used; } - + +protected: + // factory helper + static int CreateUsb3012(CFtdiDeviceDescr *, std::vector*); + static int CreateUsb3006(CFtdiDeviceDescr *, std::vector*); + static int CreateUsb3003(CFtdiDeviceDescr *, std::vector*); + static int CreatePair(CUsb3003Interface *, CUsb3003Interface *, std::vector*); + static int CreatePair(CUsb3003Interface *, CUsb3000Interface *, std::vector*); + static int CreatePair(CUsb3000Interface *, CUsb3000Interface *, std::vector*); + static CUsb3003Interface *InstantiateUsb3003(CFtdiDeviceDescr *); + static CUsb3000Interface *InstantiateUsb3000(CFtdiDeviceDescr *); + protected: // status bool m_bUsed; diff --git a/ambed/cusb3000interface.cpp b/ambed/cusb3000interface.cpp index 3cd0754..b340cba 100644 --- a/ambed/cusb3000interface.cpp +++ b/ambed/cusb3000interface.cpp @@ -254,7 +254,7 @@ bool CUsb3000Interface::ResetDevice(void) { FTDI_write_packet(m_FtdiHandle, zeropacket, sizeof(zeropacket)); } - + // write soft-reset packet if ( FTDI_write_packet(m_FtdiHandle, txpacket, sizeof(txpacket)) ) diff --git a/ambed/cusb3003interface.cpp b/ambed/cusb3003interface.cpp index e10361d..309680c 100644 --- a/ambed/cusb3003interface.cpp +++ b/ambed/cusb3003interface.cpp @@ -249,22 +249,46 @@ bool CUsb3003Interface::OpenDevice(void) bool CUsb3003Interface::ResetDevice(void) { bool ok = false; - FT_STATUS ftStatus; int len; char rxpacket[100]; - - //if the device is a USB-3003, it supports reset via UART break signal - //printf("reset via uart break...\n"); - ftStatus = FT_SetBreakOn( m_FtdiHandle ); - CTimePoint::TaskSleepFor(10); - ftStatus = FT_SetBreakOff( m_FtdiHandle ); - //CTimePoint::TaskSleepFor(10); - - len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) ); - ok = ((len == 7) && (rxpacket[4] == PKT_READY)); - if ( !ok ) + char zeropacket[10] = { - std::cout << "USB-3003 hard reset failed" << std::endl; + 0,0,0,0,0,0,0,0,0,0 + }; + char txpacket[7] = + { + PKT_HEADER, + 0, + 3, + 0, + PKT_RESET, + PKT_PARITYBYTE, + 3 ^ PKT_RESET ^ PKT_PARITYBYTE + }; + + + //the chip might be in a state where it is waiting to receive bytes from a prior incomplete packet. + //first send 350 zeros in case, the chip's receive state is still waiting for characters + //if we send more than needed, the exta characters will just get discarded since they do not match the header byte + //after that we send PKT_RESET to reset the device + //As long as the AMBE3000 is able to receive via uart, this method will succeed in resetting it. + + for ( int i = 0; i < 35 ; i++ ) + { + FTDI_write_packet(m_FtdiHandle, zeropacket, sizeof(zeropacket)); + } + + + // write soft-reset packet + if ( FTDI_write_packet(m_FtdiHandle, txpacket, sizeof(txpacket)) ) + { + // read reply + len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) ); + ok = ((len == 7) && (rxpacket[4] == PKT_READY)); + if ( !ok ) + { + std::cout << "USB-3003 soft reset failed" << std::endl; + } } // done diff --git a/ambed/cusb3xxxinterface.cpp b/ambed/cusb3xxxinterface.cpp index b59e3fe..7bf3fdd 100644 --- a/ambed/cusb3xxxinterface.cpp +++ b/ambed/cusb3xxxinterface.cpp @@ -65,7 +65,7 @@ bool CUsb3xxxInterface::Init(void) std::cout << "Opening " << m_szDeviceName << ":" << m_szDeviceSerial << " device" << std::endl; if ( ok &= OpenDevice() ) { - // reset + // reset //std::cout << "Reseting " << m_szDeviceName << "device" << std::endl; if ( ok &= ResetDevice() ) { diff --git a/ambed/cvocodecs.cpp b/ambed/cvocodecs.cpp index ca6ec71..56f4bb4 100644 --- a/ambed/cvocodecs.cpp +++ b/ambed/cvocodecs.cpp @@ -24,8 +24,6 @@ #include "main.h" #include -#include "cusb3000interface.h" -#include "cusb3003interface.h" #include "cvocodecs.h" //////////////////////////////////////////////////////////////////////////////////////// @@ -89,73 +87,80 @@ bool CVocodecs::Init(void) DiscoverFtdiDevices(); // and create interfaces for the discovered devices + // first handle all even number of channels devices for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ ) { - // create relevant interface - if ( m_FtdiDeviceDescrs[i]->IsUsb3012() ) + CFtdiDeviceDescr *descr = m_FtdiDeviceDescrs[i]; + if ( !descr->IsUsed() && IsEven(descr->GetNbChannels()) ) { - iNbCh += InitUsb3012(*m_FtdiDeviceDescrs[i]); - m_FtdiDeviceDescrs[i]->SetUsed(true); + // create the object + iNbCh += CFtdiDeviceDescr::CreateInterface(descr, &m_Channels); + // and flag as used + descr->SetUsed(true); } - else if ( m_FtdiDeviceDescrs[i]->IsUsb3003() && !m_FtdiDeviceDescrs[i]->IsUsed() ) + } + // next handle all single channel devices. + // they must be handeled in pair, or in pair with another + // even number of channels device. + for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ ) + { + CFtdiDeviceDescr *descr1 = m_FtdiDeviceDescrs[i]; + CFtdiDeviceDescr *descr2 = NULL; + if ( !descr1->IsUsed() && (descr1->GetNbChannels() == 1) ) { - // another unsed USB-3003 avaliable for a pair ? + // any other single channel device to pair with ? bool found = false; int j = i+1; while ( !found && (j < m_FtdiDeviceDescrs.size()) ) { - if ( m_FtdiDeviceDescrs[j]->IsUsb3003() && !m_FtdiDeviceDescrs[i]->IsUsed() ) - { - found = true; - } - else - { - j++; - } + descr2 = m_FtdiDeviceDescrs[j]; + found = (!descr2->IsUsed() && (descr2->GetNbChannels() == 1)); } - - // pair ? + // found one ? if ( found ) { - // yes! - iNbCh += InitUsb3003Pair(*m_FtdiDeviceDescrs[i], *m_FtdiDeviceDescrs[j]); - m_FtdiDeviceDescrs[i]->SetUsed(true); - m_FtdiDeviceDescrs[j]->SetUsed(true); + // yes, create and pairboth interfaces + iNbCh += CFtdiDeviceDescr::CreateInterfacePair(descr1, descr2, &m_Channels); + // and flag as used + descr1->SetUsed(true); + descr2->SetUsed(true); + } + } + } + // now we should have only remaining the 3 chennels device(s) + // and possibly an unique single channel device + for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ ) + { + CFtdiDeviceDescr *descr1 = m_FtdiDeviceDescrs[i]; + CFtdiDeviceDescr *descr2 = NULL; + if ( !descr1->IsUsed() && (descr1->GetNbChannels() == 3) ) + { + // any other odd channel device to pair with ? + // any other single channel device to pair with ? + bool found = false; + int j = i+1; + while ( !found && (j < m_FtdiDeviceDescrs.size()) ) + { + descr2 = m_FtdiDeviceDescrs[j]; + found = (!descr2->IsUsed() && IsOdd(descr2->GetNbChannels())); + } + // found one ? + if ( found ) + { + // yes, create and pairboth interfaces + iNbCh += CFtdiDeviceDescr::CreateInterfacePair(descr1, descr2, &m_Channels); + // and flag as used + descr1->SetUsed(true); + descr2->SetUsed(true); } else { - // just single - iNbCh += InitUsb3003(*m_FtdiDeviceDescrs[i]); - m_FtdiDeviceDescrs[i]->SetUsed(true); + // no, just create a standalone 3003 interface + iNbCh += CFtdiDeviceDescr::CreateInterface(descr1, &m_Channels); + // and flag as used + descr1->SetUsed(true); } } - else if ( m_FtdiDeviceDescrs[i]->IsUsb3000() && !m_FtdiDeviceDescrs[i]->IsUsed() ) - { - // another unsed USB-3000 avaliable for a pair ? - bool found = false; - int j = i+1; - while ( !found && (j < m_FtdiDeviceDescrs.size()) ) - { - if ( m_FtdiDeviceDescrs[j]->IsUsb3000() && !m_FtdiDeviceDescrs[i]->IsUsed() ) - { - found = true; - } - else - { - j++; - } - } - - // pair ? - if ( found ) - { - // yes! - iNbCh += InitUsb3000Pair(*m_FtdiDeviceDescrs[i], *m_FtdiDeviceDescrs[j]); - m_FtdiDeviceDescrs[i]->SetUsed(true); - m_FtdiDeviceDescrs[j]->SetUsed(true); - } - // otherwise anonther unused USB-3003 for a pair ? - } } if ( ok ) @@ -222,221 +227,6 @@ bool CVocodecs::DiscoverFtdiDevices(void) return ok; } -int CVocodecs::InitUsb3012(const CFtdiDeviceDescr &descr) -{ - int nStreams = 0; - - // create the interfaces for the four 3003 chips - CUsb3003Interface *Usb3003A = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_A", descr.GetSerialNumber()); - CUsb3003Interface *Usb3003B = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_B", descr.GetSerialNumber()); - CUsb3003Interface *Usb3003C = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_C", descr.GetSerialNumber()); - CUsb3003Interface *Usb3003D = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_D", descr.GetSerialNumber()); - - // init the interfaces - if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) && - Usb3003C->Init(CODEC_AMBEPLUS) && Usb3003D->Init(CODEC_AMBE2PLUS) ) - { - CVocodecChannel *Channel; - // create all channels - { - // ch1 - Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - // ch2 - Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - // ch3 - Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003B->AddChannel(Channel); - // ch4 - Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003B->AddChannel(Channel); - // ch5 - Channel = new CVocodecChannel(Usb3003C, 0, Usb3003C, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003C->AddChannel(Channel); - // ch6 - Channel = new CVocodecChannel(Usb3003C, 1, Usb3003C, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003C->AddChannel(Channel); - // ch7 - Channel = new CVocodecChannel(Usb3003D, 0, Usb3003D, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003D->AddChannel(Channel); - // ch8 - Channel = new CVocodecChannel(Usb3003D, 1, Usb3003D, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003D->AddChannel(Channel); - // ch9 - Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - Usb3003B->AddChannel(Channel); - // ch10 - Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - Usb3003B->AddChannel(Channel); - // ch11 - Channel = new CVocodecChannel(Usb3003C, 2, Usb3003D, 2, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003C->AddChannel(Channel); - Usb3003D->AddChannel(Channel); - // ch12 - Channel = new CVocodecChannel(Usb3003D, 2, Usb3003C, 2, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003C->AddChannel(Channel); - Usb3003D->AddChannel(Channel); - //done - nStreams = 12; - } - } - else - { - // cleanup - delete Usb3003A; - delete Usb3003B; - delete Usb3003C; - delete Usb3003D; - } - - // done - return nStreams; -} - -int CVocodecs::InitUsb3003(const CFtdiDeviceDescr &descr) -{ - int nStreams = 0; - - // create the interfaces for the 3003 chip - CUsb3003Interface *Usb3003 = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3003", descr.GetSerialNumber()); - - // init the interface - if ( Usb3003->Init(CODEC_NONE) ) - { - CVocodecChannel *Channel; - // create all channels - { - // ch1 - Channel = new CVocodecChannel(Usb3003, 0, Usb3003, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003->AddChannel(Channel); - // ch2 - Channel = new CVocodecChannel(Usb3003, 1, Usb3003, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003->AddChannel(Channel); - // done - nStreams = 2; - } - } - else - { - // cleanup - delete Usb3003; - } - - // done - return nStreams; -} - -int CVocodecs::InitUsb3003Pair(const CFtdiDeviceDescr &descr1, const CFtdiDeviceDescr &descr2) -{ - int nStreams = 0; - - // create the interfaces for the two 3003 chips - CUsb3003Interface *Usb3003A = new CUsb3003Interface(descr1.GetVid(), descr1.GetPid(), "USB-3003", descr1.GetSerialNumber()); - CUsb3003Interface *Usb3003B = new CUsb3003Interface(descr2.GetVid(), descr2.GetPid(), "USB-3003", descr2.GetSerialNumber()); - - // init the interfaces - if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) ) - { - CVocodecChannel *Channel; - // create all channels - { - // ch1 - Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - // ch2 - Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - // ch3 - Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003B->AddChannel(Channel); - // ch4 - Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003B->AddChannel(Channel); - // ch5 - Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - Usb3003B->AddChannel(Channel); - // ch6 - Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3003A->AddChannel(Channel); - Usb3003B->AddChannel(Channel); - // done - nStreams = 6; - } - } - else - { - // cleanup - delete Usb3003A; - delete Usb3003B; - } - - // done - return nStreams; -} - -int CVocodecs::InitUsb3000Pair(const CFtdiDeviceDescr &descr1, const CFtdiDeviceDescr &descr2) -{ - int nStreams = 0; - - // create the interfaces for the two 3000 chips - CUsb3000Interface *Usb3000A = new CUsb3000Interface(descr1.GetVid(), descr1.GetPid(), "USB-3000", descr1.GetSerialNumber()); - CUsb3000Interface *Usb3000B = new CUsb3000Interface(descr2.GetVid(), descr2.GetPid(), "USB-3000", descr2.GetSerialNumber()); - - // init the interfaces - if ( Usb3000A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) ) - { - CVocodecChannel *Channel; - // create all channels - { - // ch1 - Channel = new CVocodecChannel(Usb3000A, 0, Usb3000B, 0, CODECGAIN_AMBEPLUS); - m_Channels.push_back(Channel); - Usb3000A->AddChannel(Channel); - Usb3000B->AddChannel(Channel); - // ch2 - Channel = new CVocodecChannel(Usb3000B, 0, Usb3000A, 0, CODECGAIN_AMBE2PLUS); - m_Channels.push_back(Channel); - Usb3000A->AddChannel(Channel); - Usb3000B->AddChannel(Channel); - // done - nStreams = 2; - } - } - else - { - // cleanup - delete Usb3000A; - delete Usb3000B; - } - - // done - return nStreams; -} - //////////////////////////////////////////////////////////////////////////////////////// // manage channels diff --git a/ambed/cvocodecs.h b/ambed/cvocodecs.h index 6688ebb..62da1f6 100644 --- a/ambed/cvocodecs.h +++ b/ambed/cvocodecs.h @@ -56,10 +56,10 @@ public: protected: // initialisation helpers bool DiscoverFtdiDevices(void); - int InitUsb3012(const CFtdiDeviceDescr &); - int InitUsb3003(const CFtdiDeviceDescr &); - int InitUsb3003Pair(const CFtdiDeviceDescr &, const CFtdiDeviceDescr &); - int InitUsb3000Pair(const CFtdiDeviceDescr &, const CFtdiDeviceDescr &); + + // helpers + bool IsEven(int i) const { return ((i % 2) == 0); } + bool IsOdd(int i) const { return !IsEven(i); } protected: // array of interfaces diff --git a/ambed/main.cpp b/ambed/main.cpp index 6892471..078174f 100644 --- a/ambed/main.cpp +++ b/ambed/main.cpp @@ -114,8 +114,12 @@ int main(int argc, const char * argv[]) } #else // wait any key - for (;;); - //std::cin.get(); + for (;;) + { + // sleep 60 seconds + CTimePoint::TaskSleepFor(60000); + //std::cin.get(); + } #endif // and wait for end diff --git a/ambed/main.h b/ambed/main.h index 4c14244..36a04ed 100644 --- a/ambed/main.h +++ b/ambed/main.h @@ -48,8 +48,8 @@ // version ----------------------------------------------------- #define VERSION_MAJOR 1 -#define VERSION_MINOR 1 -#define VERSION_REVISION 1 +#define VERSION_MINOR 2 +#define VERSION_REVISION 0 // global ------------------------------------------------------ diff --git a/ambed/readme b/ambed/readme index 3c6713a..ddfc4c9 100644 --- a/ambed/readme +++ b/ambed/readme @@ -3,7 +3,7 @@ // ambed // // Created by Jean-Luc Deltombe (LX3JL) on 09/07/2017. -// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2017 Jean-Luc Deltombe (LX3JL). All rights reserved. // // ---------------------------------------------------------------------------- // This file is part of ambed. @@ -25,23 +25,30 @@ Hardware compatibility. ====================== -This version of ambed is compatible with DVSI's USB-3000, USB-3003, USB-3012 device -and ThumbDV +This version of ambed is compatible with: +- DF2ET's AMBE3003USB opensource device (https://github.com/phl0/AMBE3003USB) +- LX3JL's USB-3006 opensource device (https://github.com/lx3jl/usb-3006) +- DVSI's USB-3000 device +- DVSI's USB-3003 device +- DVSI's USB-3012 device +- NWDR's ThumbDV device +- NWDR's ThumbDV-3 device Available transcoding channels per device: device DMR->DSTAR DSTAR->DMR Nb Of concurrent channels ---------------------------------------------------------------------- -USB-3000(pair) 1 1 2 -USB-3003 1 1 1 -USB-3003(pair) 3 3 not tested -USB-3012 6 6 8 - -Multiple USB-3xxx can be used at the same time. -You need to use USB-3000 by pairs. -ThumbDV is recognized as USB-3000. -ThumbDV must be programed with FT-Prog (Provided by FTDI) by modifying device description as "USB-3000". +3000(pair) 1 1 2 +3003 1 1 1 +3003(pair) 3 3 not tested +3003-3000(pair) 2 2 not tested +3006 3 3 4 +3012 6 6 8 +Multiple devices can be used at the same time. +You need to use 3000 by pairs or paired with a 3003 +Do not to use USB hubs as they have proven making +system behaviour unreliable. Instructions: =============