Skip to content

Commit ae515dc

Browse files
committed
Fix on windows + Allow bypass mode for ch32v006
1 parent eb474e0 commit ae515dc

File tree

4 files changed

+89
-55
lines changed

4 files changed

+89
-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

+2-2
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
@@ -2274,7 +2274,7 @@ static int DefaultHaltMode( void * dev, int mode )
22742274
// Returns 0 if no text waiting.
22752275
// maxlen MUST be at least 8 characters. We null terminate.
22762276
int DefaultPollTerminal( void * dev, uint8_t * buffer, int maxlen, uint32_t leaveflagA, int leaveflagB )
2277-
{
2277+
{
22782278
struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
22792279
int r;
22802280
uint32_t rr;

minichlink/minichlink.exe

512 Bytes
Binary file not shown.

minichlink/pgm-wch-linke.c

+84-53
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ static void printChipInfo(enum RiscVChip chip) {
6363

6464
static int checkChip(enum RiscVChip chip) {
6565
switch(chip) {
66+
case CHIP_UNKNOWN:
67+
case CHIP_CH32V002:
68+
case CHIP_CH32V004:
6669
case CHIP_CH32V003:
70+
case CHIP_CH32V006:
71+
case CHIP_CH32V005:
6772
case CHIP_CH32X03x:
6873
return 0; // Use direct mode
6974
case CHIP_CH32V10x:
@@ -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
@@ -428,6 +444,12 @@ static int LESetupInterface( void * d )
428444
return -1;
429445
}
430446

447+
if( unknown_chip_fallback )
448+
{
449+
printf( "Unknown chip fallback\n" );
450+
chip = CHIP_UNKNOWN;
451+
}
452+
431453
printChipInfo(chip);
432454

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

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 )
488+
if( unknown_chip_fallback )
470489
{
471-
if( timeout++ < 10 ) goto retry_ID;
472-
fprintf( stderr, "Failed to get chip ID\n" );
473-
return -4;
490+
// This is a little cursed. If we're in fallback mode, none of the other chip-specific operations will work
491+
// the processor will be in a very cursed mode. We can't trust it.
492+
MCF.HaltMode( d, HALT_MODE_REBOOT );
474493
}
475-
476-
if( transferred != 20 )
494+
else
477495
{
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] );
496+
retry_ID:
497+
wch_link_command( dev, "\x81\x11\x01\x05", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
486498

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-
}
499+
if( rbuff[0] == 0x00 )
500+
{
501+
if( timeout++ < 10 ) goto retry_ID;
502+
fprintf( stderr, "Failed to get chip ID\n" );
503+
return -4;
504+
}
493505

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

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;
524+
if( iss->target_chip_type == CHIP_CH32X03x )
525+
{
526+
iss->sector_size = 256;
527+
}
504528

505-
iss->sector_size = 256;
529+
int result = checkChip(chip);
530+
if( result == 1 ) // Using blob write
531+
{
532+
fprintf( stderr, "Using binary blob write for operation.\n" );
533+
MCF.WriteBinaryBlob = LEWriteBinaryBlob;
506534

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

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

539+
} else if( result < 0 ) {
540+
fprintf( stderr, "Chip type not supported. Aborting...\n" );
541+
return -1;
542+
}
514543

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-
}
521544

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

528-
iss->flash_size = flash_size*1024;
552+
if(rbuff[3] == 0x01) {
553+
fprintf(stderr, "Read protection: enabled\n");
554+
} else {
555+
fprintf(stderr, "Read protection: disabled\n");
556+
}
557+
558+
iss->flash_size = flash_size*1024;
559+
}
529560

530561
return 0;
531562
}

0 commit comments

Comments
 (0)