diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c index 1af064c48f35bd434572b90fddd595101164be4f..18ce488f90546ec317a470f20032a03dd1b70ae2 100644 --- a/ch32v003fun/ch32v003fun.c +++ b/ch32v003fun/ch32v003fun.c @@ -795,7 +795,7 @@ void handle_reset() while( tempout != tempend ) *(tempout++) = *(tempin++); - __set_MEPC( (uint32_t)main ); + asm volatile("csrw mepc, %0" : : "r"(main)); // set mepc to be main as the root app. asm volatile( "mret\n" ); @@ -844,4 +844,12 @@ int _write(int fd, const char *buf, int size) return size; } - +void DelaySysTick( uint32_t n ) +{ + SysTick->SR &= ~(1 << 0); + SysTick->CMP = n; + SysTick->CNT = 0; + SysTick->CTLR |=(1 << 0); + while(!(SysTick->SR & (1 << 0))); + SysTick->CTLR &= ~(1 << 0); +} diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h index 33242f6183e7bd90fbf0c4b0f7ff4e099d0d6364..92ca4daeb4bb96b0b6dcffa2a28fdbf432b1b995 100644 --- a/ch32v003fun/ch32v003fun.h +++ b/ch32v003fun/ch32v003fun.h @@ -4819,21 +4819,11 @@ extern "C" { #define DELAY_US_TIME (SYSTEM_CORE_CLOCK / 8000000) #define DELAY_MS_TIME (SYSTEM_CORE_CLOCK / 8000) -static void DelaySysTick( uint32_t n ) -{ - SysTick->SR &= ~(1 << 0); - SysTick->CMP = n; - SysTick->CNT = 0; - SysTick->CTLR |=(1 << 0); - while(!(SysTick->SR & (1 << 0))); - SysTick->CTLR &= ~(1 << 0); -} +void DelaySysTick( uint32_t n ); #define Delay_Us(n) DelaySysTick( n * DELAY_US_TIME ) #define Delay_Ms(n) DelaySysTick( n * DELAY_MS_TIME ) - - // Tricky: We need to make sure main and SystemInit() are preserved. int main() __attribute__((used)); void SystemInit(void) __attribute__((used)); diff --git a/ch32v003fun/ch32v003fun.ld b/ch32v003fun/ch32v003fun.ld new file mode 100644 index 0000000000000000000000000000000000000000..d3d27288f1530e420dafd11ea17d1c93401890c9 --- /dev/null +++ b/ch32v003fun/ch32v003fun.ld @@ -0,0 +1,159 @@ +ENTRY( InterruptVector ) + +__stack_size = 256; + +PROVIDE( _stack_size = __stack_size ); + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K +} + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + . = ALIGN(4); + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} + + + diff --git a/examples/blink/Makefile b/examples/blink/Makefile index d15d989a4124e5c201ee3bb74ab6e8914ce9eb49..0a4310763ff6d7bf7217bf4c8605f652274616fd 100644 --- a/examples/blink/Makefile +++ b/examples/blink/Makefile @@ -11,7 +11,7 @@ EVT:=../../ch32v003evt MINICHLINK:=../../minichlink ifeq ($(OS),Windows_NT) -# On Windows, all the major GCC installs are missing the eg +# On Windows, all the major RISC-V GCC installs are missing the -ec libgcc. LIB_GCC=../../misc/libgcc.a else LIB_GCC=-lgcc @@ -29,7 +29,7 @@ CFLAGS:= \ -nostdlib \ -I. -LDFLAGS:=-T $(EVT)/ch32v003.ld -Wl,--gc-sections +LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c diff --git a/examples/blink/blink.bin b/examples/blink/blink.bin index c211941e46da7c4c56961e2b686a0183d307c903..e22d2b54b66c603299ca02592e7849815ac9ac9e 100644 Binary files a/examples/blink/blink.bin and b/examples/blink/blink.bin differ diff --git a/examples/blink/blink.c b/examples/blink/blink.c index 12d2f242b82c8a8b54c80fccd72dfa54aae5e37b..9b99747755972c996826b2746e9da96746a4f782 100644 --- a/examples/blink/blink.c +++ b/examples/blink/blink.c @@ -6,6 +6,8 @@ #define APB_CLOCK SYSTEM_CORE_CLOCK +uint32_t count; + int main() { SystemInit48HSI(); @@ -26,5 +28,6 @@ int main() Delay_Ms( 100 ); GPIOD->BSHR = (1<<(16+0)) | (1<<(16+4)); // Turn off GPIOD0 Delay_Ms( 100 ); + count++; } } diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c index 60b31e9a2e796b197d1ffcd2c49379c60b07df65..f1aee9c8f51f2a84b9cc2ff997dfbb692c07d834 100644 --- a/minichlink/minichlink.c +++ b/minichlink/minichlink.c @@ -9,7 +9,7 @@ #include "minichlink.h" static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber ); - +void TestFunction(void * v ); struct MiniChlinkFunctions MCF; int main( int argc, char ** argv ) @@ -28,6 +28,8 @@ int main( int argc, char ** argv ) fprintf( stderr, "Error: Could not initialize any supported programmers\n" ); return -32; } + + SetupAutomaticHighLevelFunctions(); int status; int must_be_end = 0; @@ -42,6 +44,8 @@ int main( int argc, char ** argv ) } } + //TestFunction( dev ); + int iarg = 1; const char * lastcommand = 0; for( ; iarg < argc; iarg++ ) @@ -314,21 +318,21 @@ static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber ) } -int ESPSetupInterface( void * dev ) +int DefaultSetupInterface( void * dev ) { struct ESP32ProgrammerStruct * eps = (struct ESP32ProgrammerStruct *)dev; if( MCF.Control3v3 ) MCF.Control3v3( dev, 1 ); if( MCF.DelayUS ) MCF.DelayUS( dev, 16000 ); - MCF.WriteReg32( dev, 0x7e, 0x5aa50000 | (1<<10) ); // Shadow Config Reg - MCF.WriteReg32( dev, 0x7d, 0x5aa50000 | (1<<10) ); // CFGR (1<<10 == Allow output from slave) - MCF.WriteReg32( dev, 0x7d, 0x5aa50000 | (1<<10) ); // Bug in silicon? If coming out of cold boot, and we don't do our little "song and dance" this has to be called. - MCF.WriteReg32( dev, 0x10, 0x80000001 ); // Make the debug module work properly. - MCF.WriteReg32( dev, 0x10, 0x80000001 ); // Initiate a halt request. + MCF.WriteReg32( dev, SHDWCFGR, 0x5aa50000 | (1<<10) ); // Shadow Config Reg + MCF.WriteReg32( dev, CFGR, 0x5aa50000 | (1<<10) ); // CFGR (1<<10 == Allow output from slave) + MCF.WriteReg32( dev, CFGR, 0x5aa50000 | (1<<10) ); // Bug in silicon? If coming out of cold boot, and we don't do our little "song and dance" this has to be called. + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly. + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request. // Read back chip ID. uint32_t reg; - int r = MCF.ReadReg32( dev, 0x11, ® ); + int r = MCF.ReadReg32( dev, DMSTATUS, ® ); if( r >= 0 ) { // Valid R. @@ -346,6 +350,97 @@ int ESPSetupInterface( void * dev ) } } +static int WriteWord( void * dev, uint32_t address_to_write, uint32_t data ) +{ + int r; + MCF.WriteReg32( dev, DMPROGBUF0, 0x0072a023 ); // sw x7,0(x5) + MCF.WriteReg32( dev, DMPROGBUF0, 0x00100073 ); // ebreak + MCF.WriteReg32( dev, DMDATA0, address_to_write ); + MCF.WriteReg32( dev, DMCOMMAND, 0x00231005 ); // Copy data to x5 + uint32_t rrv; + do + { + r = MCF.ReadReg32( dev, DMABSTRACTCS, &rrv ); + if( r ) return r; + } + while( rrv & (1<<12) ); + + MCF.WriteReg32( dev, DMDATA0, data ); + MCF.WriteReg32( dev, DMCOMMAND, 0x00271007 ); // Copy data to x7, and execute program. + do + { + r = MCF.ReadReg32( dev, DMABSTRACTCS, &rrv ); + if( r ) return r; + } + while( rrv & (1<<12) ); + if( (rrv >> 8 ) & 7 ) + { + fprintf( stderr, "Fault writing memory (DMABSTRACTS = %08x)\n", rrv ); + } + return 0; +} + +int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob_size, uint8_t * blob ) +{ + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly. + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request. + MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request. +} + +static int ReadWord( void * dev, uint32_t address_to_read, uint32_t * data ) +{ + int r; + MCF.WriteReg32( dev, DMPROGBUF0, 0x0002a303 ); // lw x6,0(x5) + MCF.WriteReg32( dev, DMPROGBUF0, 0x00100073 ); // ebreak + MCF.WriteReg32( dev, DMDATA0, address_to_read ); + MCF.WriteReg32( dev, DMCOMMAND, 0x00271005 ); // Copy data to x5 + uint32_t rrv; + do + { + r = MCF.ReadReg32( dev, DMABSTRACTCS, &rrv ); + if( r ) return r; + } + while( rrv & (1<<12) ); + printf( "RRV: %08x\n", rrv ); + MCF.WriteReg32( dev, DMCOMMAND, 0x00221006 ); // Copy x7 to data0 + do + { + r = MCF.ReadReg32( dev, DMABSTRACTCS, &rrv ); + if( r ) return r; + } + while( rrv & (1<<12) ); + printf( "RRV: %08x\n", rrv ); + if( (rrv >> 8 ) & 7 ) + { + fprintf( stderr, "Fault writing memory (DMABSTRACTS = %08x)\n", rrv ); + } + + return MCF.ReadReg32( dev, DMDATA0, data ); +} + +int DefaultReadBinaryBlob( void * dev, uint32_t address_to_read_from, uint32_t read_size, uint8_t * blob ) +{ + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly. + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request. + MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request. + + +} + +void TestFunction(void * dev ) +{ + uint32_t rv; + int r; + + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly. + MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request. + MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request. + + r = ReadWord( dev, 0x08000004, &rv ); + printf( "%d %08x\n", r, rv ); +} + + int SetupAutomaticHighLevelFunctions() { @@ -354,5 +449,13 @@ int SetupAutomaticHighLevelFunctions() // Else, TODO: Build the high level functions from low level functions. // If a high-level function alrady exists, don't override. + + if( !MCF.SetupInterface ) + MCF.SetupInterface = DefaultSetupInterface; + if( !MCF.WriteBinaryBlob ) + MCF.WriteBinaryBlob = DefaultWriteBinaryBlob; + if( !MCF.ReadBinaryBlob ) + MCF.ReadBinaryBlob = DefaultReadBinaryBlob; + } diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe index c03479bd4cb8ca2901becc1164a234389be3f8be..5c187f5e3995cdace9814183aecea6eedf6fc83d 100644 Binary files a/minichlink/minichlink.exe and b/minichlink/minichlink.exe differ diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h index 22b4f9b32f3e64e720d1e194087dc6f2ec8d11bd..730409c059a232492dcdda79fb34f0834ad87a3d 100644 --- a/minichlink/minichlink.h +++ b/minichlink/minichlink.h @@ -30,6 +30,28 @@ struct MiniChlinkFunctions int (*ReadBinaryBlob)( void * dev, uint32_t address_to_read_from, uint32_t read_size, uint8_t * blob ); }; + +#define DMDATA0 0x04 +#define DMDATA1 0x05 +#define DMCONTROL 0x10 +#define DMSTATUS 0x11 +#define DMHARTINFO 0x12 +#define DMABSTRACTCS 0x16 +#define DMCOMMAND 0x17 +#define DMABSTRACTAUTO 0x18 +#define DMPROGBUF0 0x20 +#define DMPROGBUF1 0x21 +#define DMPROGBUF2 0x22 +#define DMPROGBUF3 0x23 +#define DMPROGBUF4 0x24 +#define DMPROGBUF5 0x25 +#define DMPROGBUF6 0x26 +#define DMPROGBUF7 0x27 + +#define CPBR 0x7C +#define CFGR 0x7D +#define SHDWCFGR 0x7E + extern struct MiniChlinkFunctions MCF; // Returns 'dev' on success, else 0. diff --git a/minichlink/pgm-esp32s2-ch32xx.c b/minichlink/pgm-esp32s2-ch32xx.c index deb89c7a9875107ba342392ead0d8933f553eaf3..c51dcbb5a855c91021026475fa2df5ffe572596e 100644 --- a/minichlink/pgm-esp32s2-ch32xx.c +++ b/minichlink/pgm-esp32s2-ch32xx.c @@ -64,6 +64,7 @@ int ESPReadReg32( void * dev, uint8_t reg_7_bit, uint32_t * commandresp ) Write1( eps, (reg_7_bit<<1) | 0 ); int len = ESPFlushLLCommands( eps ); + if( eps->replylen < 5 ) { return -9; @@ -86,7 +87,7 @@ int ESPFlushLLCommands( void * dev ) } eps->commandbuffer[0] = 0xad; // Key report ID eps->commandbuffer[eps->commandplace] = 0xff; - int r = hid_send_feature_report( eps->hd, eps->commandbuffer, eps->commandplace ); + int r = hid_send_feature_report( eps->hd, eps->commandbuffer, 255 ); eps->commandplace = 1; if( r < 0 ) { @@ -96,6 +97,7 @@ int ESPFlushLLCommands( void * dev ) eps->reply[0] = 0xad; // Key report ID r = hid_get_feature_report( eps->hd, eps->reply, sizeof( eps->reply ) ); +printf( "RRLEN: %d\n", r ); if( r < 0 ) { fprintf( stderr, "Error: Got error %d when sending hid feature report.\n", r );