diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c
index 62d2a53b9856a47ec0922016df78e0eaed1cefe7..a99e520aeff87cf1b11b7d2da3275f35cb40fa30 100644
--- a/ch32v003fun/ch32v003fun.c
+++ b/ch32v003fun/ch32v003fun.c
@@ -31,11 +31,6 @@ int printf(const char* format, ...)
 	va_end( args );
 	return ret_status;
 }
-
-int putchar(int c)
-{
-	return _write( 0, (const char *)(&c), 1 );
-}
 	
 /* Some stuff from MUSL
 
@@ -883,13 +878,21 @@ int _write(int fd, const char *buf, int size)
 	}
 	return size;
 }
+
+// single char to UART
+int putchar(int c)
+{
+	while( !(USART1->STATR & USART_FLAG_TC));
+	USART1->DATAR = (const char)c;
+	return 1;
+}
 #else
 // For debug writing to the debug interface.
+#define DMDATA0 ((volatile uint32_t*)0xe00000f4)
+#define DMDATA1 ((volatile uint32_t*)0xe00000f8)
+
 int _write(int fd, const char *buf, int size)
 {
-	#define DMDATA0 ((volatile uint32_t*)0xe00000f4)
-	#define DMDATA1 ((volatile uint32_t*)0xe00000f8)
-
 	char buffer[4] = { 0 };
 	int place = 0;
 	uint32_t timeout = 160000; // Give up after ~40ms
@@ -924,6 +927,15 @@ int _write(int fd, const char *buf, int size)
 	return size;
 }
 
+// single to debug intf
+int putchar(int c)
+{
+	int timeout = 16000;
+    while( ((*DMDATA0) & 0x80) ) if( timeout-- == 0 ) return 0;
+    *DMDATA0 = 0x85 | ((const char)c<<8);
+    return 1;
+}
+
 void SetupDebugPrintf()
 {
 	// Clear out the sending flag.