diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe index 41c7a0961ea714c1698c7f42a519ef9283b9b923..64720779b1a4060fc876e65c9be7c39ce9fe6f80 100644 Binary files a/minichlink/minichlink.exe and b/minichlink/minichlink.exe differ diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h index 1433f6d05ea853f454ae6fba16599c65a27915a5..a46793cd331e2f58fe02a3a35c402e13061fd7cd 100644 --- a/minichlink/minichlink.h +++ b/minichlink/minichlink.h @@ -104,6 +104,16 @@ struct ProgrammerStructBase #define MAX_FLASH_SECTORS 262144 +enum RiscVChip { + CH32V10x = 0x01, + CH57x = 0x02, + CH56x = 0x03, + CH32V20x = 0x05, + CH32V30x = 0x06, + CH58x = 0x07, + CH32V003 = 0x09 +}; + struct InternalState { uint32_t statetag; @@ -116,7 +126,7 @@ struct InternalState uint32_t ram_size; int sector_size; int flash_size; - int target_chip_type; // 0 for unknown (or 003), otherwise a part number. + enum RiscVChip target_chip_type; uint8_t flash_sector_status[MAX_FLASH_SECTORS]; // 0 means unerased/unknown. 1 means erased. }; diff --git a/minichlink/pgm-wch-linke.c b/minichlink/pgm-wch-linke.c index 6034f24bdd6128cca92b9f4da5296d497155f788..6db97501b08933bb569286ce22e04893c7096d6a 100644 --- a/minichlink/pgm-wch-linke.c +++ b/minichlink/pgm-wch-linke.c @@ -16,6 +16,48 @@ struct LinkEProgrammerStruct int lasthaltmode; // For non-003 chips }; +static void printChipInfo(enum RiscVChip chip) { + switch(chip) { + case CH32V10x: + fprintf(stderr, "Detected: CH32V10x\n"); + break; + case CH57x: + fprintf(stderr, "Detected: CH57x\n"); + break; + case CH56x: + fprintf(stderr, "Detected: CH56x\n"); + break; + case CH32V20x: + fprintf(stderr, "Detected: CH32V20x\n"); + break; + case CH32V30x: + fprintf(stderr, "Detected: CH32V30x\n"); + break; + case CH58x: + fprintf(stderr, "Detected: CH58x\n"); + break; + case CH32V003: + fprintf(stderr, "Detected: CH32V003\n"); + break; + } +} + +static int checkChip(enum RiscVChip chip) { + switch(chip) { + case CH32V003: + return 0; // Use direct mode + case CH32V10x: + case CH32V20x: + case CH32V30x: + return 1; // Use binary blob mode + case CH56x: + case CH57x: + case CH58x: + default: + return -1; // Not supported yet + } +} + // For non-ch32v003 chips. //static int LEReadBinaryBlob( void * d, uint32_t offset, uint32_t amount, uint8_t * readbuff ); static int InternalLinkEHaltMode( void * d, int mode ); @@ -230,26 +272,36 @@ static int LESetupInterface( void * d ) // This puts the processor on hold to allow the debugger to run. wch_link_command( dev, "\x81\x0d\x01\x02", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500 - if (rbuff[0] == 0x81 && rbuff[1] == 0x55 && rbuff[2] == 0x01 && rbuff[3] == 0x01) + if (rbuff[0] == 0x81 && rbuff[1] == 0x55) { fprintf(stderr, "link error, nothing connected to linker\n"); return -1; } - uint32_t mcu_series = rbuff[4] << 4; - uint32_t target_chip_type = mcu_series + (rbuff[5] >> 4); - fprintf(stderr, "Chip Type: %03x\n", target_chip_type); + if(rbuff[3] == 0x08 || rbuff[3] > 0x09) { + fprintf( stderr, "Chip Type unknown. Aborting...\n" ); + return -1; + } - if( mcu_series == 0x300 || mcu_series == 0x200 ) + enum RiscVChip chip = (enum RiscVChip)rbuff[3]; + printChipInfo(chip); + + int result = checkChip(chip); + if( result == 1 ) // Using blob write { - fprintf( stderr, "CH32V30x or CH32V20x MCU detected. Using binary blob write for operation.\n" ); + fprintf( stderr, "Using binary blob write for operation.\n" ); MCF.WriteBinaryBlob = LEWriteBinaryBlob; iss->sector_size = 256; wch_link_command( dev, "\x81\x0d\x01\x03", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500 + } else if( !result ) { + fprintf( stderr, "Chip type not supported. Aborting...\n" ); + return -1; } + iss->target_chip_type = chip; + // For some reason, if we don't do this sometimes the programmer starts in a hosey mode. MCF.WriteReg32( d, DMCONTROL, 0x80000001 ); // Make the debug module work properly. MCF.WriteReg32( d, DMCONTROL, 0x80000001 ); // Initiate a halt request. @@ -299,7 +351,6 @@ static int LESetupInterface( void * d ) } iss->flash_size = ((rbuff[2]<<8) | rbuff[3])*1024; - iss->target_chip_type = target_chip_type; return 0; } @@ -405,7 +456,41 @@ void * TryInit_WCHLinkE() // Flash Bootloader for V20x and V30x series MCUs -const uint8_t * bootloader = (const uint8_t*) +const uint8_t * bootloader_v1 = (const uint8_t*) +"\x93\x77\x15\x00\x41\x11\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\x38\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\x1F\x07\x10" \ +"\x98\x4B\x6D\x9B\x98\xCB\x93\x77\x45\x00\xA9\xCB\x93\x07\xF6\x07" \ +"\x9D\x83\x2E\xC0\x2D\x68\x81\x76\x3E\xC4\xB7\x08\x02\x00\xB7\x27" \ +"\x02\x40\x37\x33\x00\x40\x13\x08\xA8\xAA\xFD\x16\x98\x4B\x33\x67" \ +"\x17\x01\x98\xCB\x02\x47\xD8\xCB\x98\x4B\x13\x67\x07\x04\x98\xCB" \ +"\xD8\x47\x05\x8B\x71\xEF\x98\x4B\x75\x8F\x98\xCB\x02\x47\x13\x07" \ +"\x07\x08\x3A\xC0\x22\x47\x7D\x17\x3A\xC4\x69\xFB\x93\x77\x85\x00" \ +"\xED\xC3\x93\x07\xF6\x07\x2E\xC0\x9D\x83\x37\x27\x02\x40\x3E\xC4" \ +"\x1C\x4B\xC1\x66\x37\x08\x08\x00\xD5\x8F\x1C\xCB\xA1\x48\x37\x17" \ +"\x00\x20\xB7\x27\x02\x40\x37\x03\x04\x00\x94\x4B\xB3\xE6\x06\x01" \ +"\x94\xCB\xD4\x47\x85\x8A\xF5\xFE\x82\x46\x3A\x8E\x36\xC2\x46\xC6" \ +"\x92\x46\x83\x2E\x07\x00\x41\x07\x23\xA0\xD6\x01\x92\x46\x83\x2E" \ +"\x47\xFF\x23\xA2\xD6\x01\x92\x46\x83\x2E\x87\xFF\x23\xA4\xD6\x01" \ +"\x92\x46\x03\x2E\xCE\x00\x23\xA6\xC6\x01\x94\x4B\xB3\xE6\x66\x00" \ +"\x94\xCB\xD4\x47\x85\x8A\xF5\xFE\x92\x46\x3A\x8E\xC1\x06\x36\xC2" \ +"\xB2\x46\xFD\x16\x36\xC6\xCD\xFE\x82\x46\xD4\xCB\x94\x4B\x93\xE6" \ +"\x06\x04\x94\xCB\xD4\x47\x85\x8A\xF5\xFE\xD4\x47\xD1\x8A\x85\xC6" \ +"\xD8\x47\xB7\x06\xF3\xFF\xFD\x16\x13\x67\x47\x01\xD8\xC7\x98\x4B" \ +"\x21\x45\x75\x8F\x98\xCB\x41\x01\x02\x90\x23\x20\xD8\x00\xE9\xBD" \ +"\x23\x20\x03\x01\x31\xBF\x82\x46\x93\x86\x06\x08\x36\xC0\xA2\x46" \ +"\xFD\x16\x36\xC4\xB9\xFA\x98\x4B\xB7\x06\xF3\xFF\xFD\x16\x75\x8F" \ +"\x98\xCB\x41\x89\x15\xC9\x2E\xC0\x0D\x06\x02\xC4\x09\x82\x32\xC6" \ +"\xB7\x17\x00\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\x71\xBF\x41\x45\x61\xBF" \ +"\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\xff\xff"; + +const uint8_t * bootloader_v2 = (const uint8_t*) "\x93\x77\x15\x00\x41\x11\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\x95\xc7\xb7\x27\x02\x40\x98\x4b" \ @@ -442,6 +527,18 @@ const uint8_t * bootloader = (const uint8_t*) int bootloader_len = 512; #endif +static const uint8_t * GetFlashLoader( enum RiscVChip chip ) +{ + switch(chip) { + case CH32V10x: + return bootloader_v1; + case CH32V20x: + case CH32V30x: + default: + return bootloader_v2; + } +} + static int InternalLinkEHaltMode( void * d, int mode ) { libusb_device_handle * dev = ((struct LinkEProgrammerStruct*)d)->devh; @@ -556,7 +653,10 @@ static int LEWriteBinaryBlob( void * d, uint32_t address_to_write, uint32_t len, wch_link_command( (libusb_device_handle *)dev, rksbuff, 11, 0, 0, 0 ); wch_link_command( (libusb_device_handle *)dev, "\x81\x02\x01\x05", 4, 0, 0, 0 ); - + + uint32_t mcu_series = iss->target_chip_type & 0xf00; + const uint8_t *bootloader = GetFlashLoader(mcu_series); + int pplace = 0; for( pplace = 0; pplace < bootloader_len; pplace += iss->sector_size ) {