add debug over minichlink

This commit is contained in:
Kizarm 2024-03-15 15:13:20 +01:00
parent e39352208d
commit bab3e086e9
7 changed files with 173 additions and 0 deletions

View file

@ -44,3 +44,8 @@ typu melodický zvonek, piánko atd. to stačí. Výhoda je, že piny vydrží 2
je možné připojit 30 Ohm sluchátka (do série) plus sériový odpor 100 Ohm mezi je možné připojit 30 Ohm sluchátka (do série) plus sériový odpor 100 Ohm mezi
piny PD0 a PD2 a hraje to s dostatečnou hlasitostí a docela čistě. piny PD0 a PD2 a hraje to s dostatečnou hlasitostí a docela čistě.
## debug
Debug přes jednodrátové rozhraní WCH Link.
Je to pomalé a divné, ale funguje to. Sice nevím jak,
ale je to celkem jedno. Fakticky je to kompletně
převzato z https://github.com/cnlohr/ch32v003fun.

53
debug/Makefile Normal file
View file

@ -0,0 +1,53 @@
# ch32v003
TARGET?= ch32v003
TOOL ?= gcc
#TOOL ?= clang
PRJ = example
VPATH = . ./$(TARGET) ./common
BLD = ./build/
DFLAGS = -S
LFLAGS = -g
LDLIBS =
BFLAGS = --strip-unneeded
CFLAGS = -MMD -Wall -ggdb -fno-exceptions -ffunction-sections -fdata-sections
CFLAGS+= -I. -I./$(TARGET) -I./common -I/usr/include/newlib
DEL = rm -f
# zdrojaky
OBJS = main.o debug.o print.o
include $(TARGET)/$(TOOL).mk
BOBJS = $(addprefix $(BLD),$(OBJS))
all: $(BLD) $(PRJ).elf
# ... atd.
-include $(BLD)*.d
# linker
$(PRJ).elf: $(BOBJS)
-@echo [LD $(TOOL),$(TARGET)] $@
@$(LD) $(LFLAGS) -o $(PRJ).elf $(BOBJS) $(LDLIBS)
-@echo "size:"
@$(SIZE) $(PRJ).elf
-@echo "listing:"
$(DUMP) $(DFLAGS) $(PRJ).elf > $(PRJ).lst
-@echo "OK."
$(COPY) $(BFLAGS) -O binary $(PRJ).elf $(PRJ).bin
# preloz co je potreba
$(BLD)%.o: %.c
-@echo [CC $(TOOL),$(TARGET)] $@
@$(CC) -c $(CFLAGS) $< -o $@
$(BLD)%.o: %.cpp
-@echo [CX $(TOOL),$(TARGET)] $@
@$(CXX) -std=c++17 -fno-rtti -c $(CFLAGS) $< -o $@
$(BLD):
mkdir $(BLD)
flash: $(PRJ).elf
minichlink -w $(PRJ).bin flash -b
# vycisti
clean:
$(DEL) $(BLD)* *.lst *.bin *.elf *.map *~
.PHONY: all clean

1
debug/ch32v003 Symbolic link
View file

@ -0,0 +1 @@
../ch32v003/

1
debug/common Symbolic link
View file

@ -0,0 +1 @@
../common/

81
debug/debug.cpp Normal file
View file

@ -0,0 +1,81 @@
#include "system.h"
#include "debug.h"
struct DEBUG_S {
uint32_t UNUSED0;
volatile uint32_t DATA0;
volatile uint32_t DATA1;
};
static DEBUG_S & DBGM = * reinterpret_cast<DEBUG_S * const> (0xe00000f0);
static constexpr unsigned FUNCONF_DEBUGPRINTF_TIMEOUT = 160000u;
// Převzato i když jsem to nekontroloval. Ono je to dost divoké.
extern "C" {
void handle_debug_input( int numbytes, uint8_t * data ) __attribute__((used,weak));
void handle_debug_input( int numbytes, uint8_t * data ) { }
void internal_handle_input( volatile uint32_t * dmdata0 ) {
uint32_t dmd0 = * dmdata0;
int bytes = (dmd0 & 0x3f) - 4;
if( bytes > 0 ) {
handle_debug_input( bytes, ((uint8_t*)dmdata0) + 1 );
}
}
};
// where [status word] is:
// b7 = is a "printf" waiting?
// b0..b3 = # of bytes in printf (+4). (5 or higher indicates a print of some kind)
// note: if b7 is 0 in reply, but b0..b3 have >=4 then we received data from host.
static int _write (const char * buf, const int size) {
char buffer[4] = { 0 };
int place = 0;
uint32_t lastdmd;
uint32_t timeout = FUNCONF_DEBUGPRINTF_TIMEOUT; // Give up after ~40ms
if( size == 0 ) {
lastdmd = DBGM.DATA0;
if( lastdmd && !(lastdmd & 0x80) ) internal_handle_input( (uint32_t*) & DBGM.DATA0 );
}
while( place < size ) {
int tosend = size - place;
if( tosend > 7 ) tosend = 7;
while( ( lastdmd = DBGM.DATA0 ) & 0x80 )
if( timeout-- == 0 ) return place;
if( lastdmd ) internal_handle_input( (uint32_t*) & DBGM.DATA0 );
timeout = FUNCONF_DEBUGPRINTF_TIMEOUT;
int t = 3;
while( t < tosend ) {
buffer[t-3] = buf[t+place];
t++;
}
DBGM.DATA1 = *(uint32_t*)&(buffer[0]);
t = 0;
while( t < tosend && t < 3 ) {
buffer[t+1] = buf[t+place];
t++;
}
buffer[0] = 0x80 | (tosend + 4);
DBGM.DATA0 = *(uint32_t*)&(buffer[0]);
//buf += tosend;
place += tosend;
}
return size;
}
Debug::Debug() noexcept : BaseLayer() {
// Clear out the sending flag.
DBGM.DATA1 = 0u;
DBGM.DATA0 = 0x80u;
// Tohle je asi zbytečné.
while ( DBGM.DATA0 & 0x80 );
}
uint32_t Debug::Down(const char * buf, const uint32_t size) {
/* Z nějakého záhadného důvodu pokud namastím kód přímo sem,
* optimalizace ho vyhodí. Nějak se to nesnáší s virtuálními
* metodami.
* */
return _write (buf, size);
}

11
debug/debug.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef DEBUG_H
#define DEBUG_H
#include "baselayer.h"
class Debug : public BaseLayer {
public:
explicit Debug () noexcept;
uint32_t Down (const char * buf, const uint32_t size) override;
};
#endif // DEBUG_H

21
debug/main.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "print.h"
#include "debug.h"
//////////////////////////////////////////////////////
/* Debug přes jednodrátové rozhraní WCH Link.
* Je to pomalé a divné, ale funguje to. Sice nevím jak,
* ale je to celkem jedno. Fakticky je to kompletně
* převzato z https://github.com/cnlohr/ch32v003fun.
* */
//////////////////////////////////////////////////////
static int n = 0;
int main () {
Print cout (DEC);
Debug debug;
cout += debug;
cout << "Begin tests ... \n";
for (;;) {
cout << "pass: " << n << "\n";
n += 1u;
}
return 0;
}