From 1fec489dc62c839a7d1732eed1de538fb8aacba0 Mon Sep 17 00:00:00 2001
From: cnlohr <lohr85@gmail.com>
Date: Sun, 12 Mar 2023 10:31:15 -0400
Subject: [PATCH] Fix printf debugging.  Weird... something.

---
 ch32v003fun/ch32v003fun.c                  | 38 ++++++++++++------
 examples/debugprintfdemo/Makefile          | 46 ++++++++++++++++++++++
 examples/debugprintfdemo/debugprintfdemo.c | 36 +++++++++++++++++
 minichlink/minichlink.c                    |  7 ++++
 4 files changed, 114 insertions(+), 13 deletions(-)
 create mode 100644 examples/debugprintfdemo/Makefile
 create mode 100644 examples/debugprintfdemo/debugprintfdemo.c

diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c
index 77e1e34..c800f90 100644
--- a/ch32v003fun/ch32v003fun.c
+++ b/ch32v003fun/ch32v003fun.c
@@ -855,25 +855,37 @@ int _write(int fd, const char *buf, int size)
 	#define DMDATA0 ((volatile uint32_t*)0xe00000f4)
 	#define DMDATA1 ((volatile uint32_t*)0xe00000f8)
 
-	while( ((*DMDATA0) & 0x80) );
 
-	int remain = size;
-	while( remain > 0 )
+	char buffer[4] = { 0 };
+	int place = 0;
+	while( place < size )
 	{
-		int tosend = remain;
+		int tosend = size - place;
 		if( tosend > 7 ) tosend = 7;
 
-		uint32_t dmd1 = 0;
-		if( tosend > 3 ) memcpy( &dmd1, buf + 3, tosend - 3 );
-		uint32_t d1 = (tosend + 4) | 0x80;
+		while( ((*DMDATA0) & 0x80) );
 
-		int subsend = tosend;
-		if( subsend > 3 ) subsend = 3;
-		memcpy( ((uint8_t*)(&d1))+1, buf, subsend );
-		*DMDATA1 = dmd1;
-		*DMDATA0 = d1;
-		remain =- tosend;
+		uint32_t d;
+		int t = 3;
+		while( t < tosend )
+		{
+			buffer[t-3] = buf[t+place];
+			t++;
+		}
+		*DMDATA1 = *(uint32_t*)&(buffer[0]);
+		t = 0;
+		while( t < tosend && t < 3 )
+		{
+			buffer[t+1] = buf[t+place];
+			t++;
+		}
+		buffer[0] = 0x80 | (tosend + 4);
+		*DMDATA0 = *(uint32_t*)&(buffer[0]);
+
+		//buf += tosend;
+		place += tosend;
 	}
+	return size;
 }
 #endif
 
diff --git a/examples/debugprintfdemo/Makefile b/examples/debugprintfdemo/Makefile
new file mode 100644
index 0000000..0bd546a
--- /dev/null
+++ b/examples/debugprintfdemo/Makefile
@@ -0,0 +1,46 @@
+TARGET:=debugprintfdemo
+
+all : flash
+
+PREFIX:=riscv64-unknown-elf
+
+GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
+
+CH32V003FUN:=../../ch32v003fun
+MINICHLINK:=../../minichlink
+
+CFLAGS:= \
+	-g -Os -flto -ffunction-sections \
+	-static-libgcc -lgcc \
+	-march=rv32ec \
+	-mabi=ilp32e \
+	-I/usr/include/newlib \
+	-I$(CH32V003FUN) \
+	-nostdlib \
+	-I.
+
+LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
+
+SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
+
+$(TARGET).elf : $(SYSTEM_C) $(TARGET).c
+	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
+
+$(TARGET).bin : $(TARGET).elf
+	$(PREFIX)-size $^
+	$(PREFIX)-objdump -S $^ > $(TARGET).lst
+	$(PREFIX)-objdump -t $^ > $(TARGET).map
+	$(PREFIX)-objcopy -O binary $< $(TARGET).bin
+	$(PREFIX)-objcopy -O ihex $< $(TARGET).hex
+
+flash : $(TARGET).bin
+	make -C $(MINICHLINK) all
+	$(MINICHLINK)/minichlink -w $< flash -b
+
+monitor : flash
+	$(MINICHLINK)/minichlink -T
+	
+
+clean :
+	rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
+
diff --git a/examples/debugprintfdemo/debugprintfdemo.c b/examples/debugprintfdemo/debugprintfdemo.c
new file mode 100644
index 0000000..237fd5e
--- /dev/null
+++ b/examples/debugprintfdemo/debugprintfdemo.c
@@ -0,0 +1,36 @@
+// Really basic self-contained demo for the ch32v003
+// Doesn't rely on any of the weird HAL stuff from CH
+// Final executable is ~1/4th the size.
+
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+uint32_t count;
+
+int main()
+{
+	SystemInit48HSI();
+	SetupDebugPrintf();
+
+	// Enable GPIOD.
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+
+	// GPIO D0, D4 Push-Pull, 10MHz Output
+	GPIOD->CFGLR &= ~(0xf<<(4*0));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+
+	while(1)
+	{
+		GPIOD->BSHR = 1 | (1<<4);	 // Turn on GPIOD0
+		//Delay_Ms( 50 );
+		GPIOD->BSHR = (1<<16) | ( 1<<(4+16); // Turn off GPIOD0
+		//Delay_Ms( 50 );
+		printf( "%d\n", count++ );
+	}
+}
diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c
index 57dfe80..15c39d5 100644
--- a/minichlink/minichlink.c
+++ b/minichlink/minichlink.c
@@ -869,8 +869,15 @@ static int DefaultHaltMode( void * dev, int mode )
 // maxlen MUST be at least 8 characters.  We null terminate.
 int DefaultPollTerminal( void * dev, uint8_t * buffer, int maxlen )
 {
+	struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
+
 	int r;
 	uint32_t rr;
+	if( iss->statetag != STTAG( "TERM" ) )
+	{
+		MCF.WriteReg32( dev, DMABSTRACTAUTO, 0x00000000 ); // Disable Autoexec.
+		iss->statetag = STTAG( "TERM" );
+	}
 	r = MCF.ReadReg32( dev, DMDATA0, &rr );
 	if( r < 0 ) return r;
 
-- 
GitLab