add debug over minichlink
This commit is contained in:
parent
e39352208d
commit
bab3e086e9
7 changed files with 173 additions and 0 deletions
|
@ -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
53
debug/Makefile
Normal 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
1
debug/ch32v003
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../ch32v003/
|
1
debug/common
Symbolic link
1
debug/common
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../common/
|
81
debug/debug.cpp
Normal file
81
debug/debug.cpp
Normal 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
11
debug/debug.h
Normal 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
21
debug/main.cpp
Normal 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;
|
||||||
|
}
|
Loading…
Reference in a new issue