diff --git a/examples/sandbox/sandbox.c b/examples/sandbox/sandbox.c
deleted file mode 100644
index 33b76fdefb866b36fdd030c949f2710a7ad3fee0..0000000000000000000000000000000000000000
--- a/examples/sandbox/sandbox.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Small example showing how to use the SWIO programming pin to 
-   do printf through the debug interface */
-
-#include "ch32v003fun.h"
-#include <stdio.h>
-
-uint32_t count;
-
-
-
-// Tell the compiler to put this code in the .data section.  That
-// will cause the startup code to copy it from flash into RAM where
-// it can be easily modified at runtime.
-void SRAMCode( ) __attribute__(( section(".data"))) __attribute__((noinline)) __attribute__((noreturn));
-void SRAMCode( )
-{
-	asm volatile( 
-"li a0, 0x40011410\n"
-"li a1, (1 | (1<<4))\n"
-"li a2, (1 | (1<<4))<<16\n"
-"1: c.sw a1, 0(a0)\n"
-"   c.sw a2, 0(a0)\n"
-"   j 1b\n" );
-    __builtin_unreachable();
-}
-
-int main()
-{
-	SystemInit48HSI();
-	SetupDebugPrintf();
-
-	// Boost CPU supply.
-	EXTEN->EXTEN_CTR = EXTEN_LDO_TRIM;
-
-	// Enable GPIOs
-	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
-
-	// GPIO D0 Push-Pull
-	GPIOD->CFGLR &= ~(0xf<<(4*0));
-	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
-
-	// GPIO D4 Push-Pull
-	GPIOD->CFGLR &= ~(0xf<<(4*4));
-	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
-
-	// GPIO C0 Push-Pull
-	GPIOC->CFGLR &= ~(0xf<<(4*0));
-	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
-
-	SRAMCode();
-}
-
diff --git a/examples/template/.vscode/c_cpp_properties.json b/examples/template/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000000000000000000000000000000000000..b52c5f523093a4d5db08d9b49089335ef1749a04
--- /dev/null
+++ b/examples/template/.vscode/c_cpp_properties.json
@@ -0,0 +1,20 @@
+{
+    "configurations": [
+        {
+            "name": "Linux",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../../ch32v003fun"
+            ],
+            "defines": [],
+            "compilerPath": "/usr/bin/clang",
+            "cppStandard": "c++14",
+            "intelliSenseMode": "linux-clang-x64",
+            "compilerArgs": [
+                "-DCH32V003FUN_BASE"
+            ],
+            "configurationProvider": "ms-vscode.makefile-tools"
+        }
+    ],
+    "version": 4
+}
\ No newline at end of file
diff --git a/examples/template/.vscode/launch.json b/examples/template/.vscode/launch.json
new file mode 100644
index 0000000000000000000000000000000000000000..b8cdedfe59b331ebac01e49813c7edf6120c7056
--- /dev/null
+++ b/examples/template/.vscode/launch.json
@@ -0,0 +1,39 @@
+{
+	"configurations": [
+		{
+			"name": "GDB Debug Target",
+			"type": "cppdbg",
+			"request": "launch",
+			"program": "template.elf",
+			"args": [],
+			"stopAtEntry": true,
+			"cwd": "${workspaceFolder}",
+			"environment": [],
+			"externalConsole": false,
+			"MIMode": "gdb",
+			"deploySteps": [
+				{
+					"type": "shell",
+					"continueOn": "GDBServer",
+					"command": "make --directory=${workspaceFolder} closechlink flash gdbserver"
+				},
+			],
+			"setupCommands": [
+				{
+					"description": "Enable pretty-printing for gdb",
+					"text": "-enable-pretty-printing",
+					"ignoreFailures": true
+				}
+			],
+			"miDebuggerPath": "gdb-multiarch",
+			"miDebuggerServerAddress": "127.0.0.1:2000"
+		},
+		{
+			"name": "Run Only (In Terminal)",
+			"type": "node",
+			"request": "launch",
+			"program": "",
+			"preLaunchTask": "run_flash_and_gdbserver",
+		}	
+		]
+}
diff --git a/examples/template/.vscode/settings.json b/examples/template/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f7790e17f25ffb056231c9e95e5ecb65837a14c
--- /dev/null
+++ b/examples/template/.vscode/settings.json
@@ -0,0 +1,15 @@
+{
+    "cmake.configureOnOpen": false,
+    "makefile.launchConfigurations": [
+        {
+            "cwd": "",
+            "sbinaryPath": "blink.elf",
+            "binaryArgs": []
+        }
+    ],
+    "editor.insertSpaces": false,
+    "editor.tabSize": 4,
+    "files.associations": {
+        "ch32v003fun.h": "c"
+    }
+}
diff --git a/examples/template/.vscode/tasks.json b/examples/template/.vscode/tasks.json
new file mode 100644
index 0000000000000000000000000000000000000000..d086ce2071367d63333095ab57bba8615df8f184
--- /dev/null
+++ b/examples/template/.vscode/tasks.json
@@ -0,0 +1,56 @@
+{
+	"version": "2.0.0",
+	"tasks": [
+		{
+			"type": "shell",
+			"label": "flash",
+			"presentation": {
+				"echo": true,
+				"focus": false,
+				"group": "build",
+				"panel": "shared",
+				"showReuseMessage" : false
+			},
+			"command": "make closechlink flash",
+		},
+		{
+			"type": "shell",
+			"label": "run_flash_and_gdbserver",
+			"command": "make closechlink flash gdbserver",
+
+			"presentation": {
+				"echo": true,
+				"focus": false,
+				"group": "build",
+				"panel": "shared",
+				"close": true,
+				"showReuseMessage" : false
+			},
+
+			"isBackground": true,
+			"options": {
+				"cwd": "${workspaceFolder}",
+			},
+			"runOptions": {
+				"instanceLimit": 2,
+			},			 
+			"group": "build",
+			"problemMatcher": {
+				"pattern": [
+					{
+						"regexp": ".",
+						"file": 1,
+						"location": 2,
+						"message": 3
+					}
+				],
+
+				"background": {
+					"activeOnStart": false,
+					"beginsPattern": "^.*Image written.*",
+					"endsPattern": "^.*GDBServer*"
+				}
+			},
+		}
+	]
+}
diff --git a/examples/sandbox/Makefile b/examples/template/Makefile
similarity index 84%
rename from examples/sandbox/Makefile
rename to examples/template/Makefile
index b3f8b71aad1aab9cde12d9a8a36662cac06fc31c..64198f4a1131d865edcb0615105f2c0cccd66005 100644
--- a/examples/sandbox/Makefile
+++ b/examples/template/Makefile
@@ -1,6 +1,6 @@
 all : flash
 
-TARGET:=sandbox
+TARGET:=template
 
 include ../../ch32v003fun/ch32v003fun.mk
 
diff --git a/examples/template/template.c b/examples/template/template.c
new file mode 100644
index 0000000000000000000000000000000000000000..25d236be8c10ac4457f9cd9aa39e6a7054955944
--- /dev/null
+++ b/examples/template/template.c
@@ -0,0 +1,38 @@
+/* Template app on which you can build your own. */
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+uint32_t count;
+
+int main()
+{
+	SystemInit48HSI();
+	SetupDebugPrintf();
+
+	// Enable GPIOs
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
+
+	// GPIO D0 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*0));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+	// GPIO D4 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+
+	// GPIO C0 Push-Pull
+	GPIOC->CFGLR &= ~(0xf<<(4*0));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+	while(1)
+	{
+		GPIOD->BSHR = 1 | (1<<4);	 // Turn on GPIOs
+		GPIOC->BSHR = 1;
+		printf( "+%lu\n", count++ );
+		GPIOD->BSHR = (1<<16) | (1<<(16+4)); // Turn off GPIODs
+		GPIOC->BSHR = (1<<16);
+		printf( "-%lu\n", count++ );
+	}
+}
+
diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c
index 0abb1ff5441d6c34c3593b22a156d198a2628e00..fbfe5bff2915eeb069b0e04f38e50b6ac95967d4 100644
--- a/minichlink/minichlink.c
+++ b/minichlink/minichlink.c
@@ -28,27 +28,46 @@ struct MiniChlinkFunctions MCF;
 void * MiniCHLinkInitAsDLL( struct MiniChlinkFunctions ** MCFO, const init_hints_t* init_hints )
 {
 	void * dev = 0;
-	if( (dev = TryInit_WCHLinkE()) )
-	{
-		fprintf( stderr, "Found WCH Link\n" );
-	}
-	else if( (dev = TryInit_ESP32S2CHFUN()) )
-	{
-		fprintf( stderr, "Found ESP32S2 Programmer\n" );
-	}
-	else if ((dev = TryInit_NHCLink042()))
-	{
-		fprintf( stderr, "Found NHC-Link042 Programmer\n" );
-	}
-	else if ((dev = TryInit_B003Fun()))
+	
+	const char * specpgm = init_hints->specific_programmer;
+	if( specpgm )
 	{
-		fprintf( stderr, "Found B003Fun Bootloader\n" );
+		if( strcmp( specpgm, "linke" ) == 0 )
+			dev = TryInit_WCHLinkE();
+		else if( strcmp( specpgm, "esp32s2chfun" ) == 0 )
+			dev = dev = TryInit_ESP32S2CHFUN();
+		else if( strcmp( specpgm, "nchlink" ) == 0 )
+			dev = dev = TryInit_NHCLink042();
+		else if( strcmp( specpgm, "b003boot" ) == 0 )
+			dev = dev = TryInit_B003Fun();
+		else if( strcmp( specpgm, "ardulink" ) == 0 )
+			dev = dev = TryInit_B003Fun();
 	}
-	else if ((dev = TryInit_Ardulink(init_hints)))
+	else
 	{
-		fprintf( stderr, "Found Ardulink Programmer\n" );
+		if( (dev = TryInit_WCHLinkE()) )
+		{
+			fprintf( stderr, "Found WCH Link\n" );
+		}
+		else if( (dev = TryInit_ESP32S2CHFUN()) )
+		{
+			fprintf( stderr, "Found ESP32S2 Programmer\n" );
+		}
+		else if ((dev = TryInit_NHCLink042()))
+		{
+			fprintf( stderr, "Found NHC-Link042 Programmer\n" );
+		}
+		else if ((dev = TryInit_B003Fun()))
+		{
+			fprintf( stderr, "Found B003Fun Bootloader\n" );
+		}
+		else if ( init_hints->serial_port && (dev = TryInit_Ardulink(init_hints)))
+		{
+			fprintf( stderr, "Found Ardulink Programmer\n" );
+		}
 	}
-	else
+
+	if( !dev )
 	{
 		fprintf( stderr, "Error: Could not initialize any supported programmers\n" );
 		return 0;
@@ -93,6 +112,12 @@ int main( int argc, char ** argv )
 			if( i < argc )
 				hints.serial_port = argv[i];
 		}
+		else if( strncmp( v, "-c", 2 ) == 0 )
+		{
+			i++;
+			if( i < argc )
+				hints.specific_programmer = argv[i];
+		}
 	}
 
 	void * dev = MiniCHLinkInitAsDLL( 0, &hints );
@@ -173,13 +198,14 @@ keep_going:
 				else
 					goto unimplemented;
 				break;
+			case 'C': // For specifying programmer
 			case 'c':
-				// COM port argument already parsed previously
+				// COM port or programmer 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" );
+					fprintf( stderr, "-c/C argument required 2 arguments\n" );
 					goto unimplemented;
 				}
 				break;
diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe
index d3404712091bdd8dcc125d58deeb556c528a3c93..5bbad93764ed20f109bc7e89424a6ef4b3b783da 100644
Binary files a/minichlink/minichlink.exe and b/minichlink/minichlink.exe differ
diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h
index dfdb2447ec9661a1af0ed0a095a6a9a600257d53..1433f6d05ea853f454ae6fba16599c65a27915a5 100644
--- a/minichlink/minichlink.h
+++ b/minichlink/minichlink.h
@@ -158,7 +158,8 @@ struct InternalState
 /* could be expanded with more in the future (e.g., PID/VID hints, priorities, ...)*/
 /* not all init functions currently need these hints. */
 typedef struct {
-	const char* serial_port;
+	const char * serial_port;
+	const char * specific_programmer;
 } init_hints_t;
 
 void * MiniCHLinkInitAsDLL(struct MiniChlinkFunctions ** MCFO, const init_hints_t* init_hints) DLLDECORATE;