diff --git a/barebones/Makefile b/barebones/Makefile
index dbab07120acd8ce83e802e0c0a9e96880f2ffe4c..3f68c644f4c2c6697cd684611c0429b0e2437ffd 100644
--- a/barebones/Makefile
+++ b/barebones/Makefile
@@ -25,14 +25,16 @@ SYSTEM_C:=$(EVT)/startup_ch32v00x.S $(EVT)/embedlibc.c
 $(TARGET).elf : barebones.c $(SYSTEM_C)
 	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
-$(TARGET).hex : $(TARGET).elf
+$(TARGET).bin : $(TARGET).elf
 	$(PREFIX)-size $^
 	$(PREFIX)-objdump -S $^ > $(TARGET).lst
 	$(PREFIX)-objdump -t $^ > $(TARGET).map
 	$(PREFIX)-objcopy -O binary $< $(TARGET).bin
-	$(PREFIX)-objcopy -O ihex $< $@
+	$(PREFIX)-objcopy -O ihex $< $(TARGET).hex
 
-flash : $(TARGET).hex
+flash : $(TARGET).bin
+	make -C ../minichlink all
+	../minichlink/minichlink -w $< -r
 
 clean :
 	rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
diff --git a/barebones/barebones.c b/barebones/barebones.c
index 3ae0efa9d57ab0380053d53fb8f0041ec791ea70..f73159450ffd90d6f94b24de1ff3c05435998310 100644
--- a/barebones/barebones.c
+++ b/barebones/barebones.c
@@ -78,8 +78,8 @@ int main()
 	{
 		GPIOD->BSHR = 1;	 // Turn on GPIOD0
 		puts( "Hello" );
-		Delay_Ms( 100 );
+		Delay_Ms( 50 );
 		GPIOD->BSHR = 1<<16; // Turn off GPIOD0
-		Delay_Ms( 100 );
+		Delay_Ms( 50 );
 	}
 }
diff --git a/minichlink/Makefile b/minichlink/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bdc97bc760d8e1d5d020f7a5d86632d88a97a296
--- /dev/null
+++ b/minichlink/Makefile
@@ -0,0 +1,24 @@
+TOOLS:=wch_erase wch_reset wch_write_simple minichlink
+
+all : $(TOOLS)
+
+CFLAGS:=-O1 -g
+LDFLAGS:=-lpthread -lusb-1.0
+
+wch_erase : wch_erase.c
+	gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
+wch_reset : wch_reset.c
+	gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
+wch_write_simple : wch_write_simple.c
+	gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
+minichlink : minichlink.c
+	gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
+
+install_udev_rules :
+	echo "SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1a86\", ATTRS{idProduct}==\"8010\", GROUP=\"plugdev\", MODE=\"0666\"" > /etc/udev/rules.d/99-qch-LinkE.rules
+
+clean :
+	rm -rf $(TOOLS)
+	
+
+
diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c
new file mode 100644
index 0000000000000000000000000000000000000000..7a2dc21c69eda0e8e3c5e235272717c37a292aaf
--- /dev/null
+++ b/minichlink/minichlink.c
@@ -0,0 +1,192 @@
+#include <stdio.h>
+#include "wch_link_base.h"
+
+
+const uint8_t * bootloader = (const uint8_t*)
+"\x21\x11\x22\xca\x26\xc8\x93\x77\x15\x00\x99\xcf\xb7\x06\x67\x45" \
+"\xb7\x27\x02\x40\x93\x86\x36\x12\x37\x97\xef\xcd\xd4\xc3\x13\x07" \
+"\xb7\x9a\xd8\xc3\xd4\xd3\xd8\xd3\x93\x77\x25\x00\x9d\xc7\xb7\x27" \
+"\x02\x40\x98\x4b\xad\x66\x37\x33\x00\x40\x13\x67\x47\x00\x98\xcb" \
+"\x98\x4b\x93\x86\xa6\xaa\x13\x67\x07\x04\x98\xcb\xd8\x47\x05\x8b" \
+"\x63\x16\x07\x10\x98\x4b\x6d\x9b\x98\xcb\x93\x77\x45\x00\xa9\xcb" \
+"\x93\x07\xf6\x03\x99\x83\x2e\xc0\x2d\x63\x81\x76\x3e\xc4\xb7\x32" \
+"\x00\x40\xb7\x27\x02\x40\x13\x03\xa3\xaa\xfd\x16\x98\x4b\xb7\x03" \
+"\x02\x00\x33\x67\x77\x00\x98\xcb\x02\x47\xd8\xcb\x98\x4b\x13\x67" \
+"\x07\x04\x98\xcb\xd8\x47\x05\x8b\x69\xe7\x98\x4b\x75\x8f\x98\xcb" \
+"\x02\x47\x13\x07\x07\x04\x3a\xc0\x22\x47\x7d\x17\x3a\xc4\x79\xf7" \
+"\x93\x77\x85\x00\xf1\xcf\x93\x07\xf6\x03\x2e\xc0\x99\x83\x37\x27" \
+"\x02\x40\x3e\xc4\x1c\x4b\xc1\x66\x2d\x63\xd5\x8f\x1c\xcb\x37\x07" \
+"\x00\x20\x13\x07\x07\x20\xb7\x27\x02\x40\xb7\x03\x08\x00\xb7\x32" \
+"\x00\x40\x13\x03\xa3\xaa\x94\x4b\xb3\xe6\x76\x00\x94\xcb\xd4\x47" \
+"\x85\x8a\xf5\xfe\x82\x46\xba\x84\x37\x04\x04\x00\x36\xc2\xc1\x46" \
+"\x36\xc6\x92\x46\x84\x40\x11\x07\x84\xc2\x94\x4b\xc1\x8e\x94\xcb" \
+"\xd4\x47\x85\x8a\xb1\xea\x92\x46\xba\x84\x91\x06\x36\xc2\xb2\x46" \
+"\xfd\x16\x36\xc6\xf9\xfe\x82\x46\xd4\xcb\x94\x4b\x93\xe6\x06\x04" \
+"\x94\xcb\xd4\x47\x85\x8a\x85\xee\xd4\x47\xc1\x8a\x85\xce\xd8\x47" \
+"\xb7\x06\xf3\xff\xfd\x16\x13\x67\x07\x01\xd8\xc7\x98\x4b\x21\x45" \
+"\x75\x8f\x98\xcb\x52\x44\xc2\x44\x61\x01\x02\x90\x23\x20\xd3\x00" \
+"\xf5\xb5\x23\xa0\x62\x00\x3d\xb7\x23\xa0\x62\x00\x55\xb7\x23\xa0" \
+"\x62\x00\xc1\xb7\x82\x46\x93\x86\x06\x04\x36\xc0\xa2\x46\xfd\x16" \
+"\x36\xc4\xb5\xf2\x98\x4b\xb7\x06\xf3\xff\xfd\x16\x75\x8f\x98\xcb" \
+"\x41\x89\x05\xcd\x2e\xc0\x0d\x06\x02\xc4\x09\x82\xb7\x07\x00\x20" \
+"\x32\xc6\x93\x87\x07\x20\x98\x43\x13\x86\x47\x00\xa2\x47\x82\x46" \
+"\x8a\x07\xb6\x97\x9c\x43\x63\x1c\xf7\x00\xa2\x47\x85\x07\x3e\xc4" \
+"\xa2\x46\x32\x47\xb2\x87\xe3\xe0\xe6\xfe\x01\x45\x61\xb7\x41\x45" \
+"\x51\xb7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \
+"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \
+"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+
+int bootloader_len = 512;
+
+int main( int argc, char ** argv )
+{
+	int status;
+	uint8_t rbuff[1024];
+
+	libusb_device_handle * devh = wch_link_base_setup();
+
+	int iarg;
+	for( iarg = 1; iarg < argc; iarg++ )
+	{
+		char * argchar = argv[iarg];
+		if( argchar[0] != '-' ) goto help;
+keep_going:
+		switch( argchar[1] )
+		{
+			default: goto help;
+			case '3': wch_link_command( devh, "\x81\x0d\x01\x09", 4, 0, 0, 0 ); break;
+			case '5': wch_link_command( devh, "\x81\x0d\x01\x0b", 4, 0, 0, 0 ); break;
+			case 't': wch_link_command( devh, "\x81\x0d\x01\x0a", 4, 0, 0, 0 ); break;
+			case 'f': wch_link_command( devh, "\x81\x0d\x01\x0c", 4, 0, 0, 0 ); break;
+			case 'r': 
+				// This is clearly not the "best" method to exit reset.  I don't know why this combination works.
+				wch_link_multicommands( devh, 3, 4, "\x81\x0b\x01\x01", 4, "\x81\x0d\x01\x02", 4, "\x81\x0d\x01\xff" );
+				break;
+			case 'R':
+				// Part one "immediately" places the part into reset.  Part 2 says when we're done, leave part in reset.
+				wch_link_multicommands( devh, 2, 4, "\x81\x0d\x01\x02", 4, "\x81\x0d\x01\x01" );
+				break;
+
+			// PROTECTION UNTESTED!
+			/*
+			case 'p':
+				wch_link_multicommands( devh, 8,
+					11, "\x81\x06\x08\x02\xf7\xff\xff\xff\xff\xff\xff",
+					4, "\x81\x0b\x01\x01",
+					4, "\x81\x0d\x01\xff",
+					4, "\x81\x0d\x01\x01",
+					5, "\x81\x0c\x02\x09\x01",
+					4, "\x81\x0d\x01\x02",
+					4, "\x81\x06\x01\x01",
+					4, "\x81\x0d\x01\xff" );
+				break;
+			case 'P':
+				wch_link_multicommands( devh, 7,
+					11, "\x81\x06\x08\x03\xf7\xff\xff\xff\xff\xff\xff",
+					4, "\x81\x0b\x01\x01",
+					4, "\x81\x0d\x01\xff",
+					4, "\x81\x0d\x01\x01",
+					5, "\x81\x0c\x02\x09\x01",
+					4, "\x81\x0d\x01\x02",
+					4, "\x81\x06\x01\x01" );
+				break;
+			*/
+			case 'w':
+				{
+				if( argchar[2] != 0 ) goto help;
+				iarg++;
+				argchar = 0; // Stop advancing
+				if( iarg >= argc ) goto help;
+
+				// Write binary.
+				int i;
+				FILE * f = fopen( argv[iarg], "rb" );
+				fseek( f, 0, SEEK_END );
+				int len = ftell( f );
+				fseek( f, 0, SEEK_SET );
+				int padlen = ((len-1) & (~0x3f)) + 0x40;
+				char * image = malloc( padlen );
+				memset( image, 0xff, padlen );
+				status = fread( image, len, 1, f );
+				fclose( f );
+	
+				if( status != 1 )
+				{
+					fprintf( stderr, "Error: File I/O Fault.\n" );
+					exit( -10 );
+				}
+				if( len > 16384 )
+				{
+					fprintf( stderr, "Error: Image for CH32V003 too large (%d)\n", len );
+					exit( -9 );
+				}
+
+				int transferred;
+				wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 );
+				wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 ); // Not sure why but it seems to work better when we request twice.
+
+				// This contains the write data quantity, in bytes.  (The last 2 octets)
+				// Then it just rollllls on in.
+				char rksbuff[11] = { 0x81, 0x01, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+				rksbuff[9] = len >> 8;
+				rksbuff[10] = len & 0xff;
+				wch_link_command( devh, rksbuff, 11, 0, 0, 0 );
+				
+				wch_link_command( devh, "\x81\x02\x01\x05", 4, 0, 0, 0 );
+				
+				int pplace = 0;
+				for( pplace = 0; pplace < bootloader_len; pplace += 64 )
+				{
+					WCHCHECK( libusb_bulk_transfer( devh, 0x02, (uint8_t*)(bootloader+pplace), 64, &transferred, WCHTIMEOUT ) );
+				}
+				
+				for( i = 0; i < 10; i++ )
+				{
+					wch_link_command( devh, "\x81\x02\x01\x07", 4, &transferred, rbuff, 1024 );
+					if( transferred == 4 && rbuff[0] == 0x82 && rbuff[1] == 0x02 && rbuff[2] == 0x01 && rbuff[3] == 0x07 )
+					{
+						break;
+					}
+				} 
+				if( i == 10 )
+				{
+					fprintf( stderr, "Error, confusing respones to 02/01/07\n" );
+					exit( -109 );
+				}
+				
+				wch_link_command( devh, "\x81\x02\x01\x02", 4, 0, 0, 0 );
+
+				for( pplace = 0; pplace < padlen; pplace += 64 )
+				{
+					WCHCHECK( libusb_bulk_transfer( devh, 0x02,image+pplace, 64, &transferred, WCHTIMEOUT ) );
+				}
+
+				// Waiting or something on 2.46.2???????  I don't know why the main system does this.
+				//	WCHCHECK( libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, 2000 ) ); // Ignore respone.
+				free( image );
+				break;
+			}
+			
+		}
+		if( argchar && argchar[2] != 0 ) { argchar++; goto keep_going; }
+	}
+
+	wch_link_command( devh, "\x81\x0d\x01\xff", 4, 0, 0, 0);
+
+	return 0;
+
+help:
+	fprintf( stderr, "Usage: minichlink [args]\n" );
+	fprintf( stderr, " single-letter args may be combined, i.e. -3r\n" );
+	fprintf( stderr, " multi-part args cannot.\n" );
+	fprintf( stderr, " -3 Enable 3.3V\n" );
+	fprintf( stderr, " -5 Enable 5V\n" );
+	fprintf( stderr, " -t Disable 3.3V\n" );
+	fprintf( stderr, " -f Disable 5V\n" );
+	fprintf( stderr, " -r Release from reest\n" );
+	fprintf( stderr, " -R Place into Reset\n" );
+//	fprintf( stderr, " -P Enable Read Protection (UNTESTED)\n" );
+//	fprintf( stderr, " -p Disable Read Protection (UNTESTED)\n" );
+	fprintf( stderr, " -w [binary image to write]\n" );
+	return -1;	
+}
diff --git a/minichlink/wch_link_base.h b/minichlink/wch_link_base.h
index 515d9521ef863413a2d9208bb47c4bfc50b13c9f..ee4145505cef2d671acf9bfb71d87795b8e97612 100644
--- a/minichlink/wch_link_base.h
+++ b/minichlink/wch_link_base.h
@@ -3,6 +3,9 @@
 #ifndef _WCH_LINK_BASE_H
 #define _WCH_LINK_BASE_H
 
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
 #include "libusb.h"
 
 #define WCHTIMEOUT 5000
@@ -38,6 +41,19 @@ sendfail:
 	exit( status );
 }
 
+static void wch_link_multicommands( libusb_device_handle * devh, int nrcommands, ... )
+{
+	int i;
+	va_list argp;
+	va_start(argp, nrcommands);
+	for( i = 0; i < nrcommands; i++ )
+	{
+		int clen = va_arg(argp, int);
+		wch_link_command( devh, va_arg(argp, char *), clen, 0, 0, 0 );
+	}
+	va_end( argp );
+}
+
 static inline libusb_device_handle * wch_link_base_setup()
 {
 	libusb_context * ctx = 0;
@@ -47,8 +63,6 @@ static inline libusb_device_handle * wch_link_base_setup()
 		fprintf( stderr, "Error: libusb_init_context() returned %d\n", status );
 		exit( status );
 	}
-	printf( "OK %d %p\n", status, ctx );
-	//libusb_set_debug(ctx, 0);
 	
 	libusb_device **list;
 	libusb_device *found = NULL;
@@ -68,8 +82,6 @@ static inline libusb_device_handle * wch_link_base_setup()
 		exit( -9 );
 	}
 
-	//USB\VID_1A86&PID_8010&MI_00\6&3AA7447&0&0000
-	//USB\VID_1A86&PID_8010&MI_00
 	libusb_device_handle * devh;
 	status = libusb_open( found, &devh );
 	if( status )
@@ -84,7 +96,9 @@ static inline libusb_device_handle * wch_link_base_setup()
 	int transferred;
 	libusb_bulk_transfer( devh, 0x81, rbuff, 1024, &transferred, 1 ); // Clear out any pending transfers.  Don't wait though.
 
-	wch_link_command( devh, "\x81\x0d\x01\x01", 4, 0, 0, 0 );	// Reply is: "\x82\x0d\x04\x02\x08\x02\x00"
+	// Place part into reset.
+	wch_link_command( devh, "\x81\x0d\x01\x01", 4, &transferred, rbuff, 1024 );	// Reply is: "\x82\x0d\x04\x02\x08\x02\x00"
+
 	wch_link_command( devh, "\x81\x0c\x02\x09\x01", 5, 0, 0, 0 ); //Reply is: 820c0101
 	wch_link_command( devh, "\x81\x0d\x01\x02", 4, 0, 0, 0 ); // Reply: Ignored, 820d050900300500
 	wch_link_command( devh, "\x81\x11\x01\x09", 4, &transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
@@ -93,8 +107,14 @@ static inline libusb_device_handle * wch_link_base_setup()
 		fprintf( stderr, "Error: could not get part status\n" );
 		exit( -99 );
 	}
-	fprintf( stderr, "Part Type: 0x%02x%02x\n", rbuff[1], rbuff[2] );
-	fprintf( stderr, "Part UUID: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", rbuff[3], rbuff[4], rbuff[5], rbuff[6], rbuff[7], rbuff[8], rbuff[9], rbuff[10] );
+	fprintf( stderr, "Part Type (A): 0x%02x%02x\n", rbuff[2], rbuff[3] );  // Is this Flash size?
+	fprintf( stderr, "Part UUID    : %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", rbuff[4], rbuff[5], rbuff[6], rbuff[7], rbuff[8], rbuff[9], rbuff[10], rbuff[11] );
+	fprintf( stderr, "PFlags       : %02x-%02x-%02x-%02x\n", rbuff[12], rbuff[13], rbuff[14], rbuff[15] );
+	fprintf( stderr, "Part Type (B): %02x-%02x-%02x-%02x\n", rbuff[16], rbuff[17], rbuff[18], rbuff[19] );
+
+	//for( i = 0; i < transferred; i++ )
+	//	printf( "%02x ", rbuff[i] );
+	//printf( "\n" );
 
 	return devh;
 }
diff --git a/minichlink/wch_power.c b/minichlink/wch_power.c
deleted file mode 100644
index 5cc3d9e5bb74cfb5d42dd66f6c3b3d39564ba1ff..0000000000000000000000000000000000000000
--- a/minichlink/wch_power.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include "wch_link_base.h"
-
-int main()
-{
-	// Note this is for CH32V003, MCU UID 20-9e-ab-cd-88-b3-bc-84
-
-return 0;
-
-	libusb_device_handle * devh = wch_link_base_setup();
-	int transferred;
-	int status;
-"\x81\x0d\x01\x01"
-"\x81\x0c\x02\x09\x01"
-
-// Disable 3.3:
-"\x81\x0d\x01\x0a"
-// Enable 3.3:
-"\x81\x0d\x01\x09"
-// Disable 5v:
-"\x81\x0d\x01\x0c"
-// Enable 5v:
-"\x81\x0d\x01\x0b"
-
-// Or so the software says...  In reality it doesn't follow those rules.
-
-// also for disabling read protection:
-"\x81\x0c\x02\x09\x01"
-"\x81\x0d\x01\x02"
-"\x81\x06\x08\x02\xf7\xff\xff\xff\xff\xff\xff"
-"\x81\x0b\x01\x01"
-"\x81\x0d\x01\xff"
-"\x81\x0d\x01\x01"
-"\x81\x0c\x02\x09\x01"
-"\x81\x0d\x01\x02"
-"\x81\x06\x01\x01"
-"\x81\x0d\x01\xff"
-
-// to enable read protection
-"\x81\x0d\x01\x01"
-"\x81\x0c\x02\x09\x01"
-"\x81\x0d\x01\x02"
-"\x81\x06\x08\x03\xf7\xff\xff\xff\xff\xff\xff"
-"\x81\x0b\x01\x01"
-"\x81\x0d\x01\xff"
-"\x81\x0d\x01\x01"
-"\x81\x0c\x02\x09\x01"
-"\x81\x0d\x01\x02"
-"\x81\x06\x01\x01"
-"\x81\x0d\x01\xff"
-
-}
diff --git a/minichlink/wch_reset.c b/minichlink/wch_reset.c
index 0a3ee17fcf6426c2bd17686e2265a716aa0b246e..be2d3899f85371a6d6c1127536831942c53c2a0b 100644
--- a/minichlink/wch_reset.c
+++ b/minichlink/wch_reset.c
@@ -3,16 +3,13 @@
 
 // TESTED
 
-// Note - should probably do reads between the writes.
-
 int main()
 {
 	libusb_device_handle * devh = wch_link_base_setup();
-	int transferred;
-	uint8_t rbuff[1024];
-	int status;
-	WCHCHECK( libusb_bulk_transfer( devh, 0x01, "\x81\x0b\x01\x01", 4, &transferred, WCHTIMEOUT) );
-	WCHCHECK( libusb_bulk_transfer( devh, 0x81, rbuff, 1024, &transferred, 500 ) );
-	WCHCHECK( libusb_bulk_transfer( devh, 0x01, "\x81\x0d\x01\xff", 4, &transferred, WCHTIMEOUT) );
-	WCHCHECK( libusb_bulk_transfer( devh, 0x81, rbuff, 1024, &transferred, 500 ) );
-}
\ No newline at end of file
+
+	// Issue reset
+	wch_link_command( devh, "\x81\x0b\x01\x01", 4, 0, 0, 0 );
+
+	// Close out.
+	wch_link_command( devh, "\x81\x0d\x01\xff", 4, 0, 0, 0 );
+}
diff --git a/minichlink/wch_write_simple.c b/minichlink/wch_write_simple.c
index 1b097567bf42444378990a1dfbec1150bc48c349..de314889dccb5ba1dd4ee8d2eb36fa06dabbf355 100644
--- a/minichlink/wch_write_simple.c
+++ b/minichlink/wch_write_simple.c
@@ -1,10 +1,10 @@
 #include <stdio.h>
 #include "wch_link_base.h"
 
-// UNTESTED
+// tested
 //  Having some difficulty with the base.
 
-const char * bootloader = 
+const uint8_t * bootloader = (const uint8_t*)
 "\x21\x11\x22\xca\x26\xc8\x93\x77\x15\x00\x99\xcf\xb7\x06\x67\x45" \
 "\xb7\x27\x02\x40\x93\x86\x36\x12\x37\x97\xef\xcd\xd4\xc3\x13\x07" \
 "\xb7\x9a\xd8\xc3\xd4\xd3\xd8\xd3\x93\x77\x25\x00\x9d\xc7\xb7\x27" \
@@ -44,6 +44,7 @@ int bootloader_len = 512;
 int main( int argc, char ** argv )
 {
 	int i;
+	int status;
 	uint8_t rbuff[1024];
 
 	if( argc != 2 )
@@ -58,9 +59,14 @@ int main( int argc, char ** argv )
 	int padlen = ((len-1) & (~0x3f)) + 0x40;
 	char * image = malloc( padlen );
 	memset( image, 0xff, padlen );
-	fread( image, len, 1, f );
+	status = fread( image, len, 1, f );
 	fclose( f );
 	
+	if( status != 1 )
+	{
+		fprintf( stderr, "Error: File I/O Fault.\n" );
+		return -10;
+	}
 	if( len > 16384 )
 	{
 		fprintf( stderr, "Error: Image for CH32V003 too large\n" );
@@ -69,7 +75,6 @@ int main( int argc, char ** argv )
 	
 	libusb_device_handle * devh = wch_link_base_setup();
 	int transferred;
-	int status;
 	wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 );
 	wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 ); // Not sure why but it seems to work better when we request twice.
 
@@ -85,7 +90,7 @@ int main( int argc, char ** argv )
 	int pplace = 0;
 	for( pplace = 0; pplace < bootloader_len; pplace += 64 )
 	{
-		WCHCHECK( libusb_bulk_transfer( devh, 0x02, bootloader+pplace, 64, &transferred, WCHTIMEOUT ) );
+		WCHCHECK( libusb_bulk_transfer( devh, 0x02, (uint8_t*)(bootloader+pplace), 64, &transferred, WCHTIMEOUT ) );
 	}
 	
 	for( i = 0; i < 10; i++ )
@@ -102,21 +107,19 @@ int main( int argc, char ** argv )
 		exit( -109 );
 	}
 	
-	WCHCHECK( libusb_bulk_transfer( devh, 0x01, "\x81\x02\x01\x02", 4, &transferred, WCHTIMEOUT) ); // checkme.
-	WCHCHECK( libusb_bulk_transfer( devh, 0x81, rbuff, 1024, &transferred, 2000 ) ); // Ignore respone.
-
+	wch_link_command( devh, "\x81\x02\x01\x02", 4, 0, 0, 0 );
 
 	for( pplace = 0; pplace < padlen; pplace += 64 )
 	{
 		WCHCHECK( libusb_bulk_transfer( devh, 0x02,image+pplace, 64, &transferred, WCHTIMEOUT ) );
 	}
 
-	// Waiting or something on 2.46.2???????
-	WCHCHECK( libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, 2000 ) ); // Ignore respone.
-	
-	WCHCHECK( libusb_bulk_transfer( devh, 0x01, "\x81\x0d\x01\xff", 4, &transferred, WCHTIMEOUT) ); // checkme.
-	WCHCHECK( libusb_bulk_transfer( devh, 0x81, rbuff, 1024, &transferred, 2000 ) ); // Ignore respone.
-	
-	//211122ca26c89377150099cfb7066745b7270240938636123797efcdd4c31307b79ad8c3d4d3d8d3937725009dc7b7270240984bad66373300401367470098cb984b9386a6aa1367070498cbd847058b63160710984b6d9b98cb93774500a9cb9307f60399832ec02d6381763ec4b7320040b72702401303a3aafd16984bb703
-//	WCHCHECK( libusb_bulk_transfer( devh, 0x01, "\x81\x02\x01\x05", 4, &transferred, WCHTIMEOUT) );
+	// Waiting or something on 2.46.2???????  I don't know why the main system does this.
+//	WCHCHECK( libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, 2000 ) ); // Ignore respone.
+
+	// Issue reset (this is optional)
+	wch_link_command( devh, "\x81\x0b\x01\x01", 4, 0, 0, 0 );
+
+	// Closeout
+	wch_link_command( devh, "\x81\x0d\x01\xff", 4, 0, 0, 0);
 }