Skip to content

Commit a2bee01

Browse files
authored
Fix on windows + Allow bypass mode for ch32v006 (#544)
1 parent eb474e0 commit a2bee01

File tree

4 files changed

+94
-55
lines changed

4 files changed

+94
-55
lines changed

ch32fun/ch32fun.mk

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Default prefix for Windows
22
ifeq ($(OS),Windows_NT)
33
PREFIX?=riscv64-unknown-elf
4+
ifeq ($(shell which $(PREFIX)),)
5+
PREFIX:=riscv-none-elf
6+
endif
47
# Check if riscv64-unknown-elf-gcc exists
58
else ifneq ($(shell which riscv64-unknown-elf-gcc),)
69
PREFIX?=riscv64-unknown-elf

minichlink/minichlink.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ int main( int argc, char ** argv )
578578
}
579579
case 'w':
580580
{
581-
struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
581+
//struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
582582
if( argchar[2] != 0 ) goto help;
583583
iarg++;
584584
argchar = 0; // Stop advancing

minichlink/minichlink.exe

512 Bytes
Binary file not shown.

minichlink/pgm-wch-linke.c

+90-54
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ static void printChipInfo(enum RiscVChip chip) {
6363

6464
static int checkChip(enum RiscVChip chip) {
6565
switch(chip) {
66+
case CHIP_UNKNOWN:
6667
case CHIP_CH32V003:
6768
case CHIP_CH32X03x:
69+
case CHIP_CH32V002:
70+
case CHIP_CH32V004:
71+
case CHIP_CH32V006:
72+
case CHIP_CH32V005:
6873
return 0; // Use direct mode
6974
case CHIP_CH32V10x:
7075
case CHIP_CH32V20x:
@@ -365,21 +370,29 @@ static int LESetupInterface( void * d )
365370
// My capture differs in this case: \x05 instead of \x09 -> But does not seem to be needed
366371
//wch_link_command( dev, "\x81\x0c\x02\x05\x01", 5, 0, 0, 0 ); //Reply is: 820c0101
367372

373+
int unknown_chip_fallback = 0;
374+
368375
// This puts the processor on hold to allow the debugger to run.
369376
int already_tried_reset = 0;
370377
int is_already_connected = 0;
371378
do
372379
{
373380
// Read DMSTATUS - in case we are a ch32x035, or other chip that does not respond to \x81\x0d\x01\x02.
374381
wch_link_command( dev, "\x81\x08\x06\x05\x11\x00\x00\x00\x00\x01", 11, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500
375-
if( transferred == 9 && rbuff[8] != 0x02 && rbuff[8] != 0x03 && rbuff[8] != 0x00 )
382+
383+
// There's a couple situations where the older firmware on the official programmer freaks out.
384+
// We don't want to inconvenience our users, so just try to work through it by falling back to the minichlink functions.
385+
// Part connected. But the programmer doesn't know what it is.
386+
if( transferred == 9 && ( ( rbuff[4] == 0x00 ) ||
387+
( rbuff[8] != 0x02 && rbuff[8] != 0x03 && rbuff[8] != 0x00 ) ) )
376388
{
377389
// Already connected.
378390
if( is_already_connected )
379391
{
380392
printf( "Already Connected\n" );
381393
// Still need to read in the data so we can select the correct chip.
382394
wch_link_command( dev, "\x81\x0d\x01\x02", 4, (int*)&transferred, rbuff, 1024 ); // ?? this seems to work?
395+
unknown_chip_fallback = 1;
383396
break;
384397
}
385398
is_already_connected = 1;
@@ -394,8 +407,11 @@ static int LESetupInterface( void * d )
394407
fprintf(stderr, "link error, nothing connected to linker (%d = [%02x %02x %02x %02x]). Trying to put processor in hold and retrying.\n", transferred, rbuff[0], rbuff[1], rbuff[2], rbuff[3]);
395408

396409
// Give up if too long
397-
if( already_tried_reset > 10 )
398-
return -1;
410+
if( already_tried_reset > 5 )
411+
{
412+
unknown_chip_fallback = 1;
413+
break;
414+
}
399415

400416
wch_link_multicommands( (libusb_device_handle *)dev, 1, 4, "\x81\x0d\x01\x13" ); // Try forcing reset line low.
401417
wch_link_command( (libusb_device_handle *)dev, "\x81\x0d\x01\xff", 4, 0, 0, 0); //Exit programming
@@ -423,11 +439,22 @@ static int LESetupInterface( void * d )
423439
printf( "Full Chip Type Reply: [%d] %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", transferred, rbuff[0], rbuff[1], rbuff[2], rbuff[3], rbuff[4], rbuff[5], rbuff[6], rbuff[7], rbuff[8] );
424440

425441
enum RiscVChip chip = (enum RiscVChip)rbuff[3];
426-
if( ( chip == 0x08 || chip > 0x09 ) && chip != CHIP_CH32X03x ) {
442+
if( chip == 0x4e )
443+
{
444+
// It's one of the 00x's. AND we're on a new programmer, so no need to unknown' it.
445+
chip = CHIP_CH32V006;
446+
}
447+
else if( ( chip == 0x08 || chip > 0x09 ) && chip != CHIP_CH32X03x ) {
427448
fprintf( stderr, "Chip Type unknown [%02x]. Aborting...\n", chip );
428449
return -1;
429450
}
430451

452+
if( unknown_chip_fallback )
453+
{
454+
printf( "Unknown chip fallback\n" );
455+
chip = CHIP_UNKNOWN;
456+
}
457+
431458
printChipInfo(chip);
432459

433460
iss->target_chip_type = chip;
@@ -463,69 +490,78 @@ static int LESetupInterface( void * d )
463490
// Recommended to switch to 05 from 09 by Alexander M
464491
// wch_link_command( dev, "\x81\x11\x01\x09", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
465492

466-
retry_ID:
467-
wch_link_command( dev, "\x81\x11\x01\x05", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
468-
469-
if( rbuff[0] == 0x00 )
493+
if( unknown_chip_fallback )
470494
{
471-
if( timeout++ < 10 ) goto retry_ID;
472-
fprintf( stderr, "Failed to get chip ID\n" );
473-
return -4;
495+
// This is a little cursed. If we're in fallback mode, none of the other chip-specific operations will work
496+
// the processor will be in a very cursed mode. We can't trust it.
497+
MCF.HaltMode( d, HALT_MODE_REBOOT );
474498
}
475-
476-
if( transferred != 20 )
499+
else
477500
{
478-
fprintf( stderr, "Error: could not get part status\n" );
479-
return -1;
480-
}
481-
int flash_size = (rbuff[2]<<8) | rbuff[3];
482-
fprintf( stderr, "Flash Storage: %d kB\n", flash_size );
483-
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] );
484-
fprintf( stderr, "PFlags : %02x-%02x-%02x-%02x\n", rbuff[12], rbuff[13], rbuff[14], rbuff[15] );
485-
fprintf( stderr, "Part Type (B): %02x-%02x-%02x-%02x\n", rbuff[16], rbuff[17], rbuff[18], rbuff[19] );
501+
retry_ID:
502+
wch_link_command( dev, "\x81\x11\x01\x05", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
486503

487-
// Quirk, was fixed in LinkE version 2.12.
488-
if( iss->target_chip_type == CHIP_CH32V10x && flash_size == 62 )
489-
{
490-
fprintf( stderr, "While the debugger reports this as a CH32V10x, it's probably a CH32X03x\n" );
491-
chip = iss->target_chip_type = CHIP_CH32X03x;
492-
}
504+
if( rbuff[0] == 0x00 )
505+
{
506+
if( timeout++ < 10 ) goto retry_ID;
507+
fprintf( stderr, "Failed to get chip ID\n" );
508+
return -4;
509+
}
493510

494-
if( iss->target_chip_type == CHIP_CH32X03x )
495-
{
496-
iss->sector_size = 256;
497-
}
511+
if( transferred != 20 )
512+
{
513+
fprintf( stderr, "Error: could not get part status\n" );
514+
return -1;
515+
}
516+
int flash_size = (rbuff[2]<<8) | rbuff[3];
517+
fprintf( stderr, "Flash Storage: %d kB\n", flash_size );
518+
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] );
519+
fprintf( stderr, "PFlags : %02x-%02x-%02x-%02x\n", rbuff[12], rbuff[13], rbuff[14], rbuff[15] );
520+
fprintf( stderr, "Part Type (B): %02x-%02x-%02x-%02x\n", rbuff[16], rbuff[17], rbuff[18], rbuff[19] );
521+
522+
// Quirk, was fixed in LinkE version 2.12.
523+
if( iss->target_chip_type == CHIP_CH32V10x && flash_size == 62 )
524+
{
525+
fprintf( stderr, "While the debugger reports this as a CH32V10x, it's probably a CH32X03x\n" );
526+
chip = iss->target_chip_type = CHIP_CH32X03x;
527+
}
498528

499-
int result = checkChip(chip);
500-
if( result == 1 ) // Using blob write
501-
{
502-
fprintf( stderr, "Using binary blob write for operation.\n" );
503-
MCF.WriteBinaryBlob = LEWriteBinaryBlob;
529+
if( iss->target_chip_type == CHIP_CH32X03x )
530+
{
531+
iss->sector_size = 256;
532+
}
504533

505-
iss->sector_size = 256;
534+
int result = checkChip(chip);
535+
if( result == 1 ) // Using blob write
536+
{
537+
fprintf( stderr, "Using binary blob write for operation.\n" );
538+
MCF.WriteBinaryBlob = LEWriteBinaryBlob;
506539

507-
wch_link_command( dev, "\x81\x0d\x01\x03", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500
540+
iss->sector_size = 256;
508541

509-
} else if( result < 0 ) {
510-
fprintf( stderr, "Chip type not supported. Aborting...\n" );
511-
return -1;
512-
}
542+
wch_link_command( dev, "\x81\x0d\x01\x03", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500
513543

544+
} else if( result < 0 ) {
545+
fprintf( stderr, "Chip type not supported. Aborting...\n" );
546+
return -1;
547+
}
514548

515-
// Check for read protection
516-
wch_link_command( dev, "\x81\x06\x01\x01", 4, (int*)&transferred, rbuff, 1024 );
517-
if(transferred != 4) {
518-
fprintf(stderr, "Error: could not get read protection status\n");
519-
return -1;
520-
}
521549

522-
if(rbuff[3] == 0x01) {
523-
fprintf(stderr, "Read protection: enabled\n");
524-
} else {
525-
fprintf(stderr, "Read protection: disabled\n");
526-
}
550+
// Check for read protection
551+
wch_link_command( dev, "\x81\x06\x01\x01", 4, (int*)&transferred, rbuff, 1024 );
552+
if(transferred != 4) {
553+
fprintf(stderr, "Error: could not get read protection status\n");
554+
return -1;
555+
}
527556

528-
iss->flash_size = flash_size*1024;
557+
if(rbuff[3] == 0x01) {
558+
fprintf(stderr, "Read protection: enabled\n");
559+
} else {
560+
fprintf(stderr, "Read protection: disabled\n");
561+
}
562+
563+
iss->flash_size = flash_size*1024;
564+
}
529565

530566
return 0;
531567
}

0 commit comments

Comments
 (0)