mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "lib/core/globals.h"
 | |
| #include "lib/config/config.h"
 | |
| #include "lib/config/flags.h"
 | |
| #include "lib/usb/usb.h"
 | |
| #include "libusbp_config.h"
 | |
| #include "libusbp.hpp"
 | |
| #include "protocol.h"
 | |
| #include "lib/data/fluxmap.h"
 | |
| #include "lib/core/bytes.h"
 | |
| #include "lib/config/proto.h"
 | |
| #include "lib/usb/usbfinder.h"
 | |
| #include "lib/core/logger.h"
 | |
| #include "lib/external/applesauce.h"
 | |
| #include "lib/external/greaseweazle.h"
 | |
| 
 | |
| static USB* usb = NULL;
 | |
| 
 | |
| USB::~USB() {}
 | |
| 
 | |
| static std::shared_ptr<CandidateDevice> selectDevice()
 | |
| {
 | |
|     auto candidates = findUsbDevices();
 | |
|     if (candidates.size() == 0)
 | |
|         error(
 | |
|             "no devices found (is one plugged in? Do you have the "
 | |
|             "appropriate permissions?");
 | |
| 
 | |
|     if (globalConfig()->usb().has_serial())
 | |
|     {
 | |
|         auto wantedSerial = globalConfig()->usb().serial();
 | |
|         for (auto& c : candidates)
 | |
|         {
 | |
|             if (c->serial == wantedSerial)
 | |
|                 return c;
 | |
|         }
 | |
|         error(
 | |
|             "serial number not found (try without one to list or "
 | |
|             "autodetect devices)");
 | |
|     }
 | |
| 
 | |
|     if (candidates.size() == 1)
 | |
|         return candidates[0];
 | |
| 
 | |
|     std::cerr << "More than one device detected; use --usb.serial=<serial> to "
 | |
|                  "select one:\n";
 | |
|     for (const auto& c : candidates)
 | |
|     {
 | |
|         std::cerr << "    ";
 | |
|         switch (c->id)
 | |
|         {
 | |
|             case FLUXENGINE_ID:
 | |
|                 std::cerr << fmt::format("FluxEngine: {}\n", c->serial);
 | |
|                 break;
 | |
| 
 | |
|             case GREASEWEAZLE_ID:
 | |
|                 std::cerr << fmt::format(
 | |
|                     "Greaseweazle: {} on {}\n", c->serial, c->serialPort);
 | |
|                 break;
 | |
| 
 | |
|             case APPLESAUCE_ID:
 | |
|                 std::cerr << fmt::format(
 | |
|                     "Applesauce: {} on {}\n", c->serial, c->serialPort);
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| USB* get_usb_impl()
 | |
| {
 | |
|     /* Special case for certain configurations. */
 | |
| 
 | |
|     if (globalConfig()->usb().has_greaseweazle() &&
 | |
|         globalConfig()->usb().greaseweazle().has_port())
 | |
|     {
 | |
|         const auto& conf = globalConfig()->usb().greaseweazle();
 | |
|         log("Using Greaseweazle on serial port {}", conf.port());
 | |
|         return createGreaseweazleUsb(conf.port(), conf);
 | |
|     }
 | |
| 
 | |
|     if (globalConfig()->usb().has_applesauce() &&
 | |
|         globalConfig()->usb().applesauce().has_port())
 | |
|     {
 | |
|         const auto& conf = globalConfig()->usb().applesauce();
 | |
|         log("Using Applesauce on serial port {}", conf.port());
 | |
|         return createApplesauceUsb(conf.port(), conf);
 | |
|     }
 | |
| 
 | |
|     /* Otherwise, select a device by USB ID. */
 | |
| 
 | |
|     auto candidate = selectDevice();
 | |
|     switch (candidate->id)
 | |
|     {
 | |
|         case FLUXENGINE_ID:
 | |
|             log("Using FluxEngine {}", candidate->serial);
 | |
|             return createFluxengineUsb(candidate->device);
 | |
| 
 | |
|         case GREASEWEAZLE_ID:
 | |
|             log("Using Greaseweazle {} on {}",
 | |
|                 candidate->serial,
 | |
|                 candidate->serialPort);
 | |
|             return createGreaseweazleUsb(
 | |
|                 candidate->serialPort, globalConfig()->usb().greaseweazle());
 | |
| 
 | |
|         case APPLESAUCE_ID:
 | |
|             log("Using Applesauce {} on {}",
 | |
|                 candidate->serial,
 | |
|                 candidate->serialPort);
 | |
|             return createApplesauceUsb(
 | |
|                 candidate->serialPort, globalConfig()->usb().applesauce());
 | |
| 
 | |
|         default:
 | |
|             error("internal");
 | |
|     }
 | |
| }
 | |
| 
 | |
| USB& getUsb()
 | |
| {
 | |
|     if (!usb)
 | |
|         usb = get_usb_impl();
 | |
|     return *usb;
 | |
| }
 |