diff --git a/lib/usb/usb.cc b/lib/usb/usb.cc index a6654796..8f6e9004 100644 --- a/lib/usb/usb.cc +++ b/lib/usb/usb.cc @@ -11,9 +11,12 @@ #include "lib/logger.h" #include "greaseweazle.h" -static USB* usb = NULL; +static USB* usb = nullptr; -USB::~USB() {} +USB::~USB() +{ + usb = nullptr; +} static std::shared_ptr selectDevice() { @@ -59,8 +62,12 @@ static std::shared_ptr selectDevice() exit(1); } -USB* get_usb_impl() +std::unique_ptr USB::create() { + std::unique_ptr r; + if (usb) + error("more than one USB object created"); + /* Special case for certain configurations. */ if (globalConfig()->usb().has_greaseweazle() && @@ -68,33 +75,40 @@ USB* get_usb_impl() { const auto& conf = globalConfig()->usb().greaseweazle(); log("Using Greaseweazle on serial port {}", conf.port()); - return createGreaseweazleUsb(conf.port(), conf); + r.reset(createGreaseweazleUsb(conf.port(), conf)); } - - /* Otherwise, select a device by USB ID. */ - - auto candidate = selectDevice(); - switch (candidate->id) + else { - case FLUXENGINE_ID: - log("Using FluxEngine {}", candidate->serial); - return createFluxengineUsb(candidate->device); + /* Otherwise, select a device by USB ID. */ - case GREASEWEAZLE_ID: - log("Using Greaseweazle {} on {}", - candidate->serial, - candidate->serialPort); - return createGreaseweazleUsb( - candidate->serialPort, globalConfig()->usb().greaseweazle()); + auto candidate = selectDevice(); + switch (candidate->id) + { + case FLUXENGINE_ID: + log("Using FluxEngine {}", candidate->serial); + r.reset(createFluxengineUsb(candidate->device)); + break; + + case GREASEWEAZLE_ID: + log("Using Greaseweazle {} on {}", + candidate->serial, + candidate->serialPort); + r.reset(createGreaseweazleUsb(candidate->serialPort, + globalConfig()->usb().greaseweazle())); + break; - default: - error("internal"); + default: + error("internal"); + } } + + usb = r.get(); + return r; } USB& getUsb() { if (!usb) - usb = get_usb_impl(); + error("USB instance not created"); return *usb; } diff --git a/lib/usb/usb.h b/lib/usb/usb.h index 7686ad07..00234ece 100644 --- a/lib/usb/usb.h +++ b/lib/usb/usb.h @@ -13,6 +13,9 @@ namespace libusbp class USB { +public: + static std::unique_ptr create(); + public: virtual ~USB(); diff --git a/src/fe-analysedriveresponse.cc b/src/fe-analysedriveresponse.cc index 3841fba2..dc84e212 100644 --- a/src/fe-analysedriveresponse.cc +++ b/src/fe-analysedriveresponse.cc @@ -252,6 +252,7 @@ int mainAnalyseDriveResponse(int argc, const char* argv[]) if (globalConfig()->flux_sink().type() != FLUXTYPE_DRIVE) error("this only makes sense with a real disk drive"); + auto usb = USB::create(); usbSetDrive(globalConfig()->drive().drive(), globalConfig()->drive().high_density(), globalConfig()->drive().index_mode()); diff --git a/src/fe-analyselayout.cc b/src/fe-analyselayout.cc index f7a95a5f..848106ee 100644 --- a/src/fe-analyselayout.cc +++ b/src/fe-analyselayout.cc @@ -7,6 +7,7 @@ #include "lib/csvreader.h" #include "lib/image.h" #include "lib/decoders/fluxmapreader.h" +#include "lib/usb/usb.h" #include "agg2d.h" #include "stb_image_write.h" #include @@ -228,6 +229,7 @@ static Image readCsv(const std::string& filename) int mainAnalyseLayout(int argc, const char* argv[]) { flags.parseFlags(argc, argv); + auto usb = USB::create(); Image image = readCsv(source.get()); visualiseSectorsToFile(image, "out.svg"); diff --git a/src/fe-format.cc b/src/fe-format.cc index 076f64b3..5576b12b 100644 --- a/src/fe-format.cc +++ b/src/fe-format.cc @@ -11,6 +11,7 @@ #include "fluxengine.h" #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -27,16 +28,10 @@ int mainFormat(int argc, const char* argv[]) showProfiles("format", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); - filesystem->create(quick, volumeName); - filesystem->flushChanges(); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + auto usb = USB::create(); + auto filesystem = Filesystem::createFilesystemFromConfig(); + filesystem->create(quick, volumeName); + filesystem->flushChanges(); return 0; } diff --git a/src/fe-getdiskinfo.cc b/src/fe-getdiskinfo.cc index 09f9ea6a..a29bf1db 100644 --- a/src/fe-getdiskinfo.cc +++ b/src/fe-getdiskinfo.cc @@ -12,6 +12,7 @@ #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -24,18 +25,12 @@ int mainGetDiskInfo(int argc, const char* argv[]) showProfiles("getdiskinfo", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); - auto attributes = filesystem->getMetadata(); + auto usb = USB::create(); + auto filesystem = Filesystem::createFilesystemFromConfig(); + auto attributes = filesystem->getMetadata(); - for (const auto& e : attributes) - fmt::print("{}={}\n", e.first, quote(e.second)); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + for (const auto& e : attributes) + fmt::print("{}={}\n", e.first, quote(e.second)); return 0; } diff --git a/src/fe-getfile.cc b/src/fe-getfile.cc index 9627f4ee..79471149 100644 --- a/src/fe-getfile.cc +++ b/src/fe-getfile.cc @@ -11,6 +11,7 @@ #include "fluxengine.h" #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -26,24 +27,19 @@ int mainGetFile(int argc, const char* argv[]) showProfiles("getfile", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - Path inputFilename(directory); - if (inputFilename.size() == 0) - error("you must supply a filename to read"); - - std::string outputFilename = output; - if (outputFilename.empty()) - outputFilename = inputFilename.back(); - - auto filesystem = Filesystem::createFilesystemFromConfig(); - auto data = filesystem->getFile(inputFilename); - data.writeToFile(outputFilename); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + auto usb = USB::create(); + + Path inputFilename(directory); + if (inputFilename.size() == 0) + error("you must supply a filename to read"); + + std::string outputFilename = output; + if (outputFilename.empty()) + outputFilename = inputFilename.back(); + + auto filesystem = Filesystem::createFilesystemFromConfig(); + auto data = filesystem->getFile(inputFilename); + data.writeToFile(outputFilename); return 0; } diff --git a/src/fe-getfileinfo.cc b/src/fe-getfileinfo.cc index 3dabbc7b..cd477932 100644 --- a/src/fe-getfileinfo.cc +++ b/src/fe-getfileinfo.cc @@ -12,6 +12,7 @@ #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -26,18 +27,13 @@ int mainGetFileInfo(int argc, const char* argv[]) showProfiles("getfileinfo", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); - auto dirent = filesystem->getDirent(Path(directory)); + auto usb = USB::create(); - for (const auto& e : dirent->attributes) - fmt::print("{}={}\n", e.first, quote(e.second)); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + auto filesystem = Filesystem::createFilesystemFromConfig(); + auto dirent = filesystem->getDirent(Path(directory)); + + for (const auto& e : dirent->attributes) + fmt::print("{}={}\n", e.first, quote(e.second)); return 0; } diff --git a/src/fe-inspect.cc b/src/fe-inspect.cc index 7514e8bf..f52f01ca 100644 --- a/src/fe-inspect.cc +++ b/src/fe-inspect.cc @@ -10,6 +10,7 @@ #include "lib/decoders/rawbits.h" #include "lib/sector.h" #include "lib/proto.h" +#include "lib/usb/usb.h" static FlagGroup flags; @@ -133,6 +134,7 @@ int mainInspect(int argc, const char* argv[]) { globalConfig().overrides()->mutable_flux_source()->set_type(FLUXTYPE_DRIVE); flags.parseFlagsWithConfigFiles(argc, argv, {}); + auto usb = USB::create(); auto& fluxSource = globalConfig().getFluxSource(); const auto fluxmap = fluxSource->readFlux(trackFlag, headFlag)->next(); diff --git a/src/fe-ls.cc b/src/fe-ls.cc index 4a2869b2..de562dbd 100644 --- a/src/fe-ls.cc +++ b/src/fe-ls.cc @@ -11,6 +11,7 @@ #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -40,33 +41,28 @@ int mainLs(int argc, const char* argv[]) showProfiles("ls", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); - auto files = filesystem->list(Path(directory)); + auto usb = USB::create(); - int maxlen = 0; - for (const auto& dirent : files) - maxlen = std::max(maxlen, (int)quote(dirent->filename).size()); + auto filesystem = Filesystem::createFilesystemFromConfig(); + auto files = filesystem->list(Path(directory)); - uint32_t total = 0; - for (const auto& dirent : files) - { - fmt::print("{} {:{}} {:6} {:4} {}\n", - fileTypeChar(dirent->file_type), - quote(dirent->filename), - maxlen + 2, - dirent->length, - dirent->mode, - dirent->attributes[Filesystem::CTIME]); - total += dirent->length; - } - fmt::print("({} files, {} bytes)\n", files.size(), total); - } - catch (const FilesystemException& e) + int maxlen = 0; + for (const auto& dirent : files) + maxlen = std::max(maxlen, (int)quote(dirent->filename).size()); + + uint32_t total = 0; + for (const auto& dirent : files) { - error("{}", e.message); + fmt::print("{} {:{}} {:6} {:4} {}\n", + fileTypeChar(dirent->file_type), + quote(dirent->filename), + maxlen + 2, + dirent->length, + dirent->mode, + dirent->attributes[Filesystem::CTIME]); + total += dirent->length; } + fmt::print("({} files, {} bytes)\n", files.size(), total); return 0; } diff --git a/src/fe-mkdir.cc b/src/fe-mkdir.cc index bb2f08ee..b721de28 100644 --- a/src/fe-mkdir.cc +++ b/src/fe-mkdir.cc @@ -4,6 +4,7 @@ #include "fluxengine.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -18,21 +19,15 @@ int mainMkDir(int argc, const char* argv[]) showProfiles("mkdir", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); + auto usb = USB::create(); + auto filesystem = Filesystem::createFilesystemFromConfig(); - Path path(filename); - if (path.size() == 0) - error("filename missing"); + Path path(filename); + if (path.size() == 0) + error("filename missing"); - filesystem->createDirectory(path); - filesystem->flushChanges(); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + filesystem->createDirectory(path); + filesystem->flushChanges(); return 0; } diff --git a/src/fe-mv.cc b/src/fe-mv.cc index e61658f1..c895836e 100644 --- a/src/fe-mv.cc +++ b/src/fe-mv.cc @@ -4,6 +4,7 @@ #include "fluxengine.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -19,25 +20,19 @@ int mainMv(int argc, const char* argv[]) showProfiles("mv", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); - - Path oldPath(oldFilename); - if (oldPath.size() == 0) - error("old filename missing"); - - Path newPath(newFilename); - if (newPath.size() == 0) - error("new filename missing"); - - filesystem->moveFile(oldPath, newPath); - filesystem->flushChanges(); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + auto usb = USB::create(); + auto filesystem = Filesystem::createFilesystemFromConfig(); + + Path oldPath(oldFilename); + if (oldPath.size() == 0) + error("old filename missing"); + + Path newPath(newFilename); + if (newPath.size() == 0) + error("new filename missing"); + + filesystem->moveFile(oldPath, newPath); + filesystem->flushChanges(); return 0; } diff --git a/src/fe-putfile.cc b/src/fe-putfile.cc index 0f161e37..55fd1eff 100644 --- a/src/fe-putfile.cc +++ b/src/fe-putfile.cc @@ -11,6 +11,7 @@ #include "fluxengine.h" #include "lib/vfs/sectorinterface.h" #include "lib/vfs/vfs.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -26,25 +27,19 @@ int mainPutFile(int argc, const char* argv[]) showProfiles("putfile", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - std::string inputFilename = input; - if (inputFilename.empty()) - error("you must supply a local file to read from"); + auto usb = USB::create(); + std::string inputFilename = input; + if (inputFilename.empty()) + error("you must supply a local file to read from"); - Path outputFilename(path); - if (outputFilename.size() == 0) - error("you must supply a destination path to write to"); + Path outputFilename(path); + if (outputFilename.size() == 0) + error("you must supply a destination path to write to"); - auto data = Bytes::readFromFile(inputFilename); - auto filesystem = Filesystem::createFilesystemFromConfig(); - filesystem->putFile(outputFilename, data); - filesystem->flushChanges(); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + auto data = Bytes::readFromFile(inputFilename); + auto filesystem = Filesystem::createFilesystemFromConfig(); + filesystem->putFile(outputFilename, data); + filesystem->flushChanges(); return 0; } diff --git a/src/fe-rawread.cc b/src/fe-rawread.cc index 3374e8b5..adf39903 100644 --- a/src/fe-rawread.cc +++ b/src/fe-rawread.cc @@ -8,6 +8,7 @@ #include "lib/fluxsink/fluxsink.h" #include "lib/fluxsource/fluxsource.h" #include "lib/imagewriter/imagewriter.h" +#include "lib/usb/usb.h" #include "fluxengine.h" #include #include @@ -55,6 +56,7 @@ int mainRawRead(int argc, const char* argv[]) showProfiles("rawread", formats); globalConfig().overrides()->mutable_flux_source()->set_type(FLUXTYPE_DRIVE); flags.parseFlagsWithConfigFiles(argc, argv, formats); + auto usb = USB::create(); if (globalConfig()->flux_sink().type() == FLUXTYPE_DRIVE) error("you can't use rawread to write to hardware"); diff --git a/src/fe-rawwrite.cc b/src/fe-rawwrite.cc index 4fbe53f8..3abedfb5 100644 --- a/src/fe-rawwrite.cc +++ b/src/fe-rawwrite.cc @@ -6,6 +6,7 @@ #include "lib/proto.h" #include "lib/fluxsource/fluxsource.h" #include "lib/fluxsink/fluxsink.h" +#include "lib/usb/usb.h" #include "fluxengine.h" #include #include @@ -61,6 +62,7 @@ int mainRawWrite(int argc, const char* argv[]) showProfiles("rawwrite", formats); globalConfig().overrides()->mutable_flux_sink()->set_type(FLUXTYPE_DRIVE); flags.parseFlagsWithConfigFiles(argc, argv, formats); + auto usb = USB::create(); if (globalConfig()->flux_source().type() == FLUXTYPE_DRIVE) error("you can't use rawwrite to read from hardware"); diff --git a/src/fe-read.cc b/src/fe-read.cc index 15651387..894d0f92 100644 --- a/src/fe-read.cc +++ b/src/fe-read.cc @@ -8,6 +8,7 @@ #include "lib/fluxsource/fluxsource.h" #include "lib/fluxsink/fluxsink.h" #include "lib/imagewriter/imagewriter.h" +#include "lib/usb/usb.h" #include "fluxengine.h" #include #include @@ -60,6 +61,7 @@ int mainRead(int argc, const char* argv[]) showProfiles("read", formats); globalConfig().set("flux_source.type", "FLUXTYPE_DRIVE"); flags.parseFlagsWithConfigFiles(argc, argv, formats); + auto usb = USB::create(); if (globalConfig()->decoder().copy_flux_to().type() == FLUXTYPE_DRIVE) error("you cannot copy flux to a hardware device"); diff --git a/src/fe-rm.cc b/src/fe-rm.cc index e02322a4..c50c3831 100644 --- a/src/fe-rm.cc +++ b/src/fe-rm.cc @@ -4,6 +4,7 @@ #include "fluxengine.h" #include "lib/vfs/vfs.h" #include "lib/utils.h" +#include "lib/usb/usb.h" #include "src/fileutils.h" #include #include @@ -18,21 +19,15 @@ int mainRm(int argc, const char* argv[]) showProfiles("rm", formats); flags.parseFlagsWithConfigFiles(argc, argv, formats); - try - { - auto filesystem = Filesystem::createFilesystemFromConfig(); + auto usb = USB::create(); + auto filesystem = Filesystem::createFilesystemFromConfig(); - Path path(filename); - if (path.size() == 0) - error("filename missing"); + Path path(filename); + if (path.size() == 0) + error("filename missing"); - filesystem->deleteFile(path); - filesystem->flushChanges(); - } - catch (const FilesystemException& e) - { - error("{}", e.message); - } + filesystem->deleteFile(path); + filesystem->flushChanges(); return 0; } diff --git a/src/fe-rpm.cc b/src/fe-rpm.cc index a2cade0a..395b5dc8 100644 --- a/src/fe-rpm.cc +++ b/src/fe-rpm.cc @@ -23,6 +23,7 @@ int mainRpm(int argc, const char* argv[]) if (globalConfig()->flux_source().type() != FLUXTYPE_DRIVE) error("this only makes sense with a real disk drive"); + auto usb = USB::create(); usbSetDrive(globalConfig()->drive().drive(), false, globalConfig()->drive().index_mode()); diff --git a/src/fe-seek.cc b/src/fe-seek.cc index aebad132..b7d063cd 100644 --- a/src/fe-seek.cc +++ b/src/fe-seek.cc @@ -26,6 +26,7 @@ int mainSeek(int argc, const char* argv[]) if (globalConfig()->flux_source().type() != FLUXTYPE_DRIVE) error("this only makes sense with a real disk drive"); + auto usb = USB::create(); usbSetDrive(globalConfig()->drive().drive(), false, globalConfig()->drive().index_mode()); diff --git a/src/fe-testbandwidth.cc b/src/fe-testbandwidth.cc index 0f723b73..8472956b 100644 --- a/src/fe-testbandwidth.cc +++ b/src/fe-testbandwidth.cc @@ -7,6 +7,7 @@ static FlagGroup flags; int mainTestBandwidth(int argc, const char* argv[]) { flags.parseFlagsWithConfigFiles(argc, argv, {}); + auto usb = USB::create(); usbTestBulkWrite(); usbTestBulkRead(); return 0; diff --git a/src/fe-testdevices.cc b/src/fe-testdevices.cc index 46b93e30..630db0e4 100644 --- a/src/fe-testdevices.cc +++ b/src/fe-testdevices.cc @@ -1,5 +1,6 @@ #include "lib/globals.h" #include "lib/flags.h" +#include "lib/usb/usb.h" #include "lib/usb/usbfinder.h" #include @@ -8,6 +9,7 @@ static FlagGroup flags; int mainTestDevices(int argc, const char* argv[]) { flags.parseFlagsWithConfigFiles(argc, argv, {}); + auto usb = USB::create(); auto candidates = findUsbDevices(); switch (candidates.size()) diff --git a/src/fe-testvoltages.cc b/src/fe-testvoltages.cc index 9f7c3857..5b8f73a3 100644 --- a/src/fe-testvoltages.cc +++ b/src/fe-testvoltages.cc @@ -15,6 +15,7 @@ static std::string display_voltages(struct voltages& v) int mainTestVoltages(int argc, const char* argv[]) { flags.parseFlagsWithConfigFiles(argc, argv, {}); + auto usb = USB::create(); struct voltages_frame f; usbMeasureVoltages(&f); diff --git a/src/fe-write.cc b/src/fe-write.cc index 3221c42b..2cbbcc38 100644 --- a/src/fe-write.cc +++ b/src/fe-write.cc @@ -11,6 +11,7 @@ #include "arch/brother/brother.h" #include "arch/ibm/ibm.h" #include "lib/imagereader/imagereader.h" +#include "lib/usb/usb.h" #include "fluxengine.h" #include #include @@ -66,6 +67,7 @@ int mainWrite(int argc, const char* argv[]) globalConfig().setVerificationFluxSource("drive:0"); flags.parseFlagsWithConfigFiles(argc, argv, formats); + auto usb = USB::create(); auto& reader = globalConfig().getImageReader(); std::shared_ptr image = reader->readMappedImage(); diff --git a/src/gui/idlepanel.cc b/src/gui/idlepanel.cc index 9e213b7d..fa44bf6f 100644 --- a/src/gui/idlepanel.cc +++ b/src/gui/idlepanel.cc @@ -10,6 +10,7 @@ #include "lib/imagereader/imagereader.h" #include "lib/imagewriter/imagewriter.h" #include "lib/layout.h" +#include "lib/usb/usb.h" #include "texteditorwindow.h" #include "iconbutton.h" #include @@ -291,6 +292,11 @@ class IdlePanelImpl : public IdlePanelGen, public IdlePanel globalConfig().validateAndThrow(); ClearLog(); + + /* Ensure the USB device is opened. */ + + _usb.reset(); + _usb = USB::create(); } const wxBitmap GetBitmap() override @@ -809,6 +815,7 @@ class IdlePanelImpl : public IdlePanelGen, public IdlePanel std::string _extraConfiguration; std::set> _formatOptions; int _currentlyDisplayedFormat = wxNOT_FOUND - 1; + std::unique_ptr _usb; }; IdlePanel* IdlePanel::Create(MainWindow* mainWindow, wxSimplebook* parent)