diff --git a/minichlink/ardulink.c b/minichlink/ardulink.c index 96c0d93a56d7a2a15924c0d747110e9a59d27242..82284c66d8e0be8a342b492b33419e4f82cb0280 100644 --- a/minichlink/ardulink.c +++ b/minichlink/ardulink.c @@ -4,7 +4,7 @@ #include "serial_dev.h" #include "minichlink.h" -void * TryInit_Ardulink(void); +void * TryInit_Ardulink(const init_hints_t*); static int ArdulinkWriteReg32(void * dev, uint8_t reg_7_bit, uint32_t command); static int ArdulinkReadReg32(void * dev, uint8_t reg_7_bit, uint32_t * commandresp); @@ -91,7 +91,7 @@ int ArdulinkTargetReset(void * dev, int reset) { return 0; } -void * TryInit_Ardulink(void) +void * TryInit_Ardulink(const init_hints_t* hints) { ardulink_ctx_t *ctx; char first; @@ -102,14 +102,14 @@ void * TryInit_Ardulink(void) } const char* serial_to_open = NULL; - // This is extremely crude. We receive no parameters, yet we have - // to find the correct serial port for the programmer. - // since the init is executed before the command line parameters are parsed, - // we don't get the value of any "--serial-port=..." switch at all. - // We at least to make it usable by using an environment variable. - // Optimally, we would restructure the init function to include init hints - // or try to enumerate all existing serial ports for our Ardulink programmer. - if ((serial_to_open = getenv("MINICHLINK_SERIAL")) == NULL) { + // Get the serial port that shall be opened. + // First, if we have a directly set serial port hint, use that. + // Otherwise, use the environment variable MINICHLINK_SERIAL. + // If that also doesn't exist, fall back to the default serial. + if (hints && hints->serial_port != NULL) { + serial_to_open = hints->serial_port; + } + else if ((serial_to_open = getenv("MINICHLINK_SERIAL")) == NULL) { // fallback serial_to_open = DEFAULT_SERIAL_NAME; } diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c index 24a8bfad6e3b6ca11a487a269a4f051558c16b7f..6636927020cb894b0161239fbbfa404e0a33ac5c 100644 --- a/minichlink/minichlink.c +++ b/minichlink/minichlink.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <getopt.h> #include "minichlink.h" #include "../ch32v003fun/ch32v003fun.h" @@ -17,7 +18,6 @@ void Sleep(uint32_t dwMilliseconds); #include <unistd.h> #endif - static int64_t StringToMemoryAddress( const char * number ) __attribute__((used)); static void StaticUpdatePROGBUFRegs( void * dev ) __attribute__((used)); static int InternalUnlockBootloader( void * dev ) __attribute__((used)); @@ -26,7 +26,7 @@ int DefaultReadBinaryBlob( void * dev, uint32_t address_to_read_from, uint32_t r void TestFunction(void * v ); struct MiniChlinkFunctions MCF; -void * MiniCHLinkInitAsDLL( struct MiniChlinkFunctions ** MCFO ) +void * MiniCHLinkInitAsDLL( struct MiniChlinkFunctions ** MCFO, const init_hints_t* init_hints ) { void * dev = 0; if( (dev = TryInit_WCHLinkE()) ) @@ -45,7 +45,7 @@ void * MiniCHLinkInitAsDLL( struct MiniChlinkFunctions ** MCFO ) { fprintf( stderr, "Found B003Fun Bootloader\n" ); } - else if ((dev = TryInit_Ardulink())) + else if ((dev = TryInit_Ardulink(init_hints))) { fprintf( stderr, "Found Ardulink Programmer\n" ); } @@ -63,6 +63,26 @@ void * MiniCHLinkInitAsDLL( struct MiniChlinkFunctions ** MCFO ) return dev; } +void parse_possible_init_hints(int argc, char **argv, init_hints_t *hints) +{ + if (!hints) + return; + int c; + opterr = 0; + /* we're only interested in the value for the COM port, given in a -c parameter */ + while ((c = getopt(argc, argv, "c:")) != -1) + { + switch (c) + { + case 'c': + // we can use the pointer as-is because it points in our + // argv array and that is stable. + hints->serial_port = optarg; + break; + } + } +} + #if !defined( MINICHLINK_AS_LIBRARY ) && !defined( MINICHLINK_IMPORT ) int main( int argc, char ** argv ) { @@ -70,7 +90,10 @@ int main( int argc, char ** argv ) { goto help; } - void * dev = MiniCHLinkInitAsDLL( 0 ); + init_hints_t hints; + memset(&hints, 0, sizeof(hints)); + parse_possible_init_hints(argc, argv, &hints); + void * dev = MiniCHLinkInitAsDLL( 0, &hints ); if( !dev ) { fprintf( stderr, "Error: Could not initialize any supported programmers\n" ); @@ -148,6 +171,16 @@ keep_going: else goto unimplemented; break; + case 'c': + // COM port argument already parsed previously + // we still need to skip the next argument + iarg+=1; + if( iarg >= argc ) + { + fprintf( stderr, "-c argument (COM port) required 2 arguments\n" ); + goto unimplemented; + } + break; case 'u': if( MCF.Unbrick ) MCF.Unbrick( dev ); @@ -557,6 +590,7 @@ help: fprintf( stderr, " -5 Enable 5V\n" ); fprintf( stderr, " -t Disable 3.3V\n" ); fprintf( stderr, " -f Disable 5V\n" ); + fprintf( stderr, " -c [serial port for Ardulink, try /dev/ttyACM0 or COM11 etc]\n" ); fprintf( stderr, " -u Clear all code flash - by power off (also can unbrick)\n" ); fprintf( stderr, " -b Reboot out of Halt\n" ); fprintf( stderr, " -e Resume from halt\n" ); diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe index ed694180a0929dbe7e886cae40bec8297efda795..04692974c75efa7a78c2f956226a31c8c3f24050 100644 Binary files a/minichlink/minichlink.exe and b/minichlink/minichlink.exe differ