diff --git a/README.md b/README.md index fcdc921a0a185712f219684898605104d560bd4d..cdf479b2b5c5c10eca3f633132e77742d8c31c1c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ ch32v003fun contains: * An STM32F042 Programmer, the NHC-Link042 * An ESP32S2 Programmer, the [esp32s2-funprog](https://github.com/cnlohr/esp32s2-cookbook/tree/master/ch32v003programmer) * The official WCH Link-E Programmer. + * An Arduino-based interface, [Ardulink](https://gitlab.com/BlueSyncLine/arduino-ch32v003-swio). * Supports gdbserver-style-debugging for use with Visual Studio. * Supports printf-over-single-wire. (At about 400kBaud) 3. An extra copy of libgcc so you can use unusual risc-v build chains, located in the `misc/libgcc.a`. @@ -57,7 +58,7 @@ The generated .bin is used by minichlink and the .hex file is compatible with th ## VSCode +/- PlatformIO -Note: With PlatformIO is genearlly used for CI on this repo. However, note that this is **not** the path that allows for debugging on Windows. +Note: With PlatformIO is genearlly used for CI on this repo. However, note that this is **not** the path that allows for debugging on Windows (For that see [debugprintfdemo](https://github.com/cnlohr/ch32v003fun/tree/master/examples/debugprintfdemo/.vscode)) This project can also be built, uploaded and debugged with VSCode and the PlatformIO extension. Simply clone and open this project in VSCode and have the PlatformIO extension installed. @@ -70,9 +71,9 @@ If the C/C++ language server clangd is unable to find `ch32v003fun.h`, the examp `build_all_clangd.sh` does in `build scripts` does this for all examples. ## Quick Reference - * Needed for programming/debugging: `SWIO` is on `PD1` - * Optional (not needed, can be configured as output if fuse set): `NRST` is on `PD7` - * UART TX (optional) is on: `PD5` + * **REQUIRED** for programming/debugging: `SWIO` is on `PD1`. Do not re-use PD1 for multiple functions. + * **OPTIONAL** `NRST` is on `PD7`. Not needed, defaults as GPIO in some configurations. + * **OPTIONAL** UART `TX` is on: `PD5`. We recommend using SWIO for `printf` debugging.   diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c index 6e6e60d4cd857cfa262c115b104370d6eef845c1..78fae9b786aead0126cd564f199ee6a3f71f7292 100644 --- a/ch32v003fun/ch32v003fun.c +++ b/ch32v003fun/ch32v003fun.c @@ -810,11 +810,11 @@ asm volatile( #ifdef CPLUSPLUS // Call __libc_init_array function " call %0 \n\t" -: : "i" (__libc_init_array) +: : "i" (__libc_init_array) +: "a0", "a1", "a2", "a3", "a4", "a5", "t0", "t1", "t2", "memory" #else -: : +: : : "a0", "a1", "a2", "a3", "memory" #endif -: "a0", "a1", "a2", "a3", "memory" ); SETUP_SYSTICK_HCLK diff --git a/minichlink/ardulink.c b/minichlink/ardulink.c index 82284c66d8e0be8a342b492b33419e4f82cb0280..cd28635be0d3b4999302c21056d41fb392400c6a 100644 --- a/minichlink/ardulink.c +++ b/minichlink/ardulink.c @@ -9,8 +9,9 @@ void * TryInit_Ardulink(const init_hints_t*); static int ArdulinkWriteReg32(void * dev, uint8_t reg_7_bit, uint32_t command); static int ArdulinkReadReg32(void * dev, uint8_t reg_7_bit, uint32_t * commandresp); static int ArdulinkFlushLLCommands(void * dev); +static int ArdulinkDelayUS(void * dev, int microseconds); +static int ArdulinkControl3v3(void * dev, int power_on); static int ArdulinkExit(void * dev); -static int ArdulinkTargetReset(void * dev, int reset); typedef struct { struct ProgrammerStructBase psb; @@ -64,20 +65,12 @@ int ArdulinkFlushLLCommands(void * dev) return 0; } -int ArdulinkExit(void * dev) -{ - serial_dev_close(&((ardulink_ctx_t*)dev)->serial); - free(dev); - return 0; -} - -int ArdulinkTargetReset(void * dev, int reset) { +int ArdulinkControl3v3(void * dev, int power_on) { char c; - fprintf(stderr, "Ardulink: target reset %d\n", reset); + fprintf(stderr, "Ardulink: target power %d\n", power_on); - // Assert reset. - c = reset ? 'a' : 'A'; + c = power_on ? 'p' : 'P'; if (serial_dev_write(&((ardulink_ctx_t*)dev)->serial, &c, 1) == -1) return -errno; @@ -91,6 +84,20 @@ int ArdulinkTargetReset(void * dev, int reset) { return 0; } +int ArdulinkDelayUS(void * dev, int microseconds) { + //fprintf(stderr, "Ardulink: faking delay %d\n", microseconds); + //usleep(microseconds); + return 0; +} + +int ArdulinkExit(void * dev) +{ + serial_dev_close(&((ardulink_ctx_t*)dev)->serial); + free(dev); + return 0; +} + + void * TryInit_Ardulink(const init_hints_t* hints) { ardulink_ctx_t *ctx; @@ -149,18 +156,14 @@ void * TryInit_Ardulink(const init_hints_t* hints) return NULL; } - if (ArdulinkTargetReset(ctx, 1) != 0) { - fprintf(stderr, "Ardulink: target reset failed.\n"); - return NULL; - } - fprintf(stderr, "Ardulink: synced.\n"); MCF.WriteReg32 = ArdulinkWriteReg32; MCF.ReadReg32 = ArdulinkReadReg32; MCF.FlushLLCommands = ArdulinkFlushLLCommands; + MCF.Control3v3 = ArdulinkControl3v3; + MCF.DelayUS = ArdulinkDelayUS; MCF.Exit = ArdulinkExit; - MCF.TargetReset = ArdulinkTargetReset; return ctx; } diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c index 25855a65b87a139c16585781ca8446cfbf4bda1e..1c38ad647a36c77daede21ed719a671ae0456540 100644 --- a/minichlink/minichlink.c +++ b/minichlink/minichlink.c @@ -1598,13 +1598,7 @@ static int DefaultHaltMode( void * dev, int mode ) fprintf( stderr, "Error: Unknown halt mode %d\n", mode ); } - // pull reset line back to 0 again (NO RESET) ((XXX TODO: Move this to unbrick)) - if (MCF.TargetReset) { - MCF.TargetReset(dev, 0); - } - iss->flash_unlocked = 0; - iss->processor_in_mode = mode; return 0; } @@ -1664,6 +1658,7 @@ int DefaultUnbrick( void * dev ) { printf( "Entering Unbrick Mode\n" ); MCF.Control3v3( dev, 0 ); + MCF.DelayUS( dev, 60000 ); MCF.DelayUS( dev, 60000 ); MCF.DelayUS( dev, 60000 ); diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h index fb09ecb7dd915c1c2029a0abbcc19ed8ccdfbd1a..2992e5f93193bcdca57e4cdf6e3230c2c2a3cb8c 100644 --- a/minichlink/minichlink.h +++ b/minichlink/minichlink.h @@ -75,8 +75,6 @@ struct MiniChlinkFunctions int (*WriteByte)( void * dev, uint32_t address_to_write, uint8_t data ); int (*ReadByte)( void * dev, uint32_t address_to_read, uint8_t * data ); - - int (*TargetReset)( void * dev, int reset ); }; /** If you are writing a driver, the minimal number of functions you can implement are: