From 1b382a931d6f3db02fdc3bd1160ef25e9e221e99 Mon Sep 17 00:00:00 2001
From: cnlohr <lohr85@gmail.com>
Date: Fri, 19 Apr 2024 00:40:52 -0700
Subject: [PATCH] Working on making the x035 work.

---
 ch32v003fun/ch32v003fun.c       | 100 +++++++++++--
 ch32v003fun/ch32v003fun.h       | 249 +++++++++++++++++++++++++++++---
 ch32v003fun/ch32v003fun.ld      |   7 +
 ch32v003fun/ch32v003fun.mk      |  24 +++
 examples_x035/blink/Makefile    |  11 ++
 examples_x035/blink/blink.c     |  31 ++++
 examples_x035/blink/funconfig.h |   5 +
 minichlink/pgm-wch-linke.c      |  21 ++-
 8 files changed, 415 insertions(+), 33 deletions(-)
 create mode 100644 examples_x035/blink/Makefile
 create mode 100644 examples_x035/blink/blink.c
 create mode 100644 examples_x035/blink/funconfig.h

diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c
index d7d8f97..f8b435d 100644
--- a/ch32v003fun/ch32v003fun.c
+++ b/ch32v003fun/ch32v003fun.c
@@ -732,7 +732,7 @@ void RTC_IRQHandler( void )				 __attribute__((section(".text.vector_handler")))
 #endif // defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 void FLASH_IRQHandler( void )            __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void RCC_IRQHandler( void )              __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
-#ifdef CH32V003
+#if defined(CH32V003) || defined(CH32X03x)
 void EXTI7_0_IRQHandler( void )          __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void AWU_IRQHandler( void )              __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
@@ -749,7 +749,7 @@ void DMA1_Channel4_IRQHandler( void )    __attribute__((section(".text.vector_ha
 void DMA1_Channel5_IRQHandler( void )    __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void DMA1_Channel6_IRQHandler( void )    __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void DMA1_Channel7_IRQHandler( void )    __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
-#ifdef CH32V003
+#if defined( CH32V003 ) || defined(CH32X03x)
 void ADC1_IRQHandler( void )             __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 void ADC1_2_IRQHandler( void ) 			 __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
@@ -774,7 +774,7 @@ void TIM4_IRQHandler( void ) 			 __attribute__((section(".text.vector_handler"))
 #endif // defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 void I2C1_EV_IRQHandler( void )          __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void I2C1_ER_IRQHandler( void )          __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
-#ifdef CH32V003
+#if defined( CH32V003 ) || defined( CH32X03x )
 void USART1_IRQHandler( void )           __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 void SPI1_IRQHandler( void )             __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
@@ -840,7 +840,26 @@ void DMA2_Channel10_IRQHandler( void ) 	__attribute__((section(".text.vector_han
 void DMA2_Channel11_IRQHandler( void ) 	__attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
 #endif
 
-#ifdef CH32V003
+#if defined( CH32X03X )
+void USART2_IRQHandler( void )        __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void EXTI15_8_IRQHandler( void )      __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void EXTI25_16_IRQHandler( void )     __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USART3_IRQHandler( void ) 		  __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USART4_IRQHandler( void ) 		  __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void DMA1_Channel8_IRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USBFS_IRQHandler( void )         __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USBFS_WakeUp_IRQHandler( void )  __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void PIOC_IRQHandler( void )          __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void OPA_IRQHandler( void )           __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USBPD_IRQHandler( void )         __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void USBPD_WKUP_IRQHandler( void )    __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void TIM2_CC_IRQHandler( void )       __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void TIM2_TRG_IRQHandler( void )      __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void TIM2_BRK_IRQHandler( void )      __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+void TIM3_IRQHandler( void )          __attribute__((section(".text.vector_handler"))) __attribute((weak,alias("DefaultIRQHandler"))) __attribute__((used));
+#endif
+
+#if defined( CH32V003 ) || defined( CH32X03x )
 
 void InterruptVector()         __attribute__((naked)) __attribute((section(".init"))) __attribute((weak,alias("InterruptVectorDefault")));
 void InterruptVectorDefault()  __attribute__((naked)) __attribute((section(".init")));
@@ -852,18 +871,46 @@ void InterruptVectorDefault()
 	.option   push;\n\
 	.option   norvc;\n\
 	j handle_reset\n" );
+#if 0 // What is this for?  I don't see any reason to have it.
+#ifdef CH32X03x
+	asm volatile( "\n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00000013 \n\
+	.word 0x00100073" );
+#endif
+#endif
+
 #if !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
 	asm volatile( "\n\
 	.word   0\n\
 	.word   NMI_Handler               /* NMI Handler */                    \n\
 	.word   HardFault_Handler         /* Hard Fault Handler */             \n\
+	.word   0\n"
+#if !defined(CH32X03x)
+"	.word   Ecall_M_Mode_Handler       /* Ecall M Mode */ \n\
+	.word   0 \n\
+	.word   0 \n\
+	.word   Ecall_U_Mode_Handler       /* Ecall U Mode */ \n\
+	.word   Break_Point_Handler        /* Break Point */ \n\
+"
+#else
+"	.word   0\n\
 	.word   0\n\
 	.word   0\n\
 	.word   0\n\
-	.word   0\n\
-	.word   0\n\
-	.word   0\n\
-	.word   0\n\
+	.word   0\n"
+#endif
+"	.word   0\n\
 	.word   0\n\
 	.word   SysTick_Handler           /* SysTick Handler */                \n\
 	.word   0\n\
@@ -892,8 +939,26 @@ void InterruptVectorDefault()
 	.word   TIM1_UP_IRQHandler        /* TIM1 Update */                    \n\
 	.word   TIM1_TRG_COM_IRQHandler   /* TIM1 Trigger and Commutation */   \n\
 	.word   TIM1_CC_IRQHandler        /* TIM1 Capture Compare */           \n\
-	.word   TIM2_IRQHandler           /* TIM2 */                           \n\
-");
+	.word   TIM2_IRQHandler           /* TIM2 */                           \n"
+#if defined( CH32X03X )
+"	.word	USART2_IRQn = 39,          /* UART2 Interrupt                          */ \n\
+	.word	EXTI15_8_IRQn = 40,        /* External Line[8:15] Interrupt            */ \n\
+	.word	EXTI25_16_IRQn = 41,       /* External Line[25:16] Interrupt           */ \n\
+	.word	USART3_IRQn = 42,          /* UART2 Interrupt                          */ \n\
+	.word	USART4_IRQn = 43,          /* UART2 Interrupt                          */ \n\
+	.word	DMA1_Channel8_IRQn = 44,   /* DMA1 Channel 8 global Interrupt          */ \n\
+	.word	USBFS_IRQn = 45,           /* USB Full-Speed Interrupt                 */ \n\
+	.word	USBFS_WakeUp_IRQn = 46,    /* USB Full-Speed Wake-Up Interrupt         */ \n\
+	.word	PIOC_IRQn = 47,            /* Programmable IO Controller Interrupt     */ \n\
+	.word	OPA_IRQn = 48,             /* Op Amp Interrupt                         */ \n\
+	.word	USBPD_IRQn = 49,           /* USB Power Delivery Interrupt             */ \n\
+	.word	USBPD_WKUP_IRQn = 50,      /* USB Power Delivery Wake-Up Interrupt     */ \n\
+	.word	TIM2_CC_IRQn = 51,         /* Timer 2 Compare Global Interrupt         */ \n\
+	.word	TIM2_TRG_IRQn = 52,        /* Timer 2 Trigger Global Interrupt         */ \n\
+	.word	TIM2_BRK_IRQn = 53,        /* Timer 2 Brk Global Interrupt             */ \n\
+	.word	TIM3_IRQn = 54,            /* Timer 3 Global Interrupt                 */"
+#endif
+	);
 #endif
 	asm volatile( ".option   pop;\n");
 }
@@ -1137,7 +1202,8 @@ void InterruptVectorDefault()
     .word   DMA2_Channel10_IRQHandler  /* DMA2 Channel 10 */ \n\
     .word   DMA2_Channel11_IRQHandler  /* DMA2 Channel 11 */ \n"
 #endif
-#endif
+
+#endif // !defined(FUNCONF_TINYVECTOR) || !FUNCONF_TINYVECTOR
 "	.option rvc; \n");
 
 }
@@ -1190,7 +1256,7 @@ void handle_reset( void )
 	asm volatile(
 "	li t0, 0x1f\n\
 	csrw 0xbc0, t0\n"
-#if defined(CH32V20x)
+#if defined(CH32V20x) || defined(CH32X03x)
 	// Enabled nested and hardware stack
 "	li t0, 0x88\n\
 	csrs mstatus, t0\n"
@@ -1232,6 +1298,12 @@ void SetupUART( int uartBRR )
 	// Push-Pull, 10MHz Output, GPIO D5, with AutoFunction
 	GPIOD->CFGLR &= ~(0xf<<(4*5));
 	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5);
+#elif defined(CH32X03x)
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1;
+
+	// Push-Pull, 10MHz Output, GPIO A9, with AutoFunction
+	GPIOB->CFGHR &= ~(0xf<<(4*2));
+	GPIOB->CFGHR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*2);
 #else
 	RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1;
 
@@ -1403,9 +1475,11 @@ void DelaySysTick( uint32_t n )
 #elif defined(CH32V20x) || defined(CH32V30x)
 	uint64_t targend = SysTick->CNT + n;
 	while( ((int64_t)( SysTick->CNT - targend )) < 0 );
-#elif defined(CH32V10x)
+#elif defined(CH32V10x) || defined(CH32X03x)
 	uint32_t targend = SysTick->CNTL + n;
 	while( ((int32_t)( SysTick->CNTL - targend )) < 0 );
+#else
+	#error DelaySysTick not defined.
 #endif
 }
 
diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h
index 861fc5f..3b4a530 100644
--- a/ch32v003fun/ch32v003fun.h
+++ b/ch32v003fun/ch32v003fun.h
@@ -58,7 +58,7 @@
 */
 
 // Sanity check for when porting old code.
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 	#if defined(CH32V003)
 		#error Cannot define CH32V003 and another arch.
 	#endif
@@ -85,10 +85,23 @@
 	#define FUNCONF_USE_HSE 0
 #endif
 
+#if defined( CH32X03x ) && FUNCONF_USE_HSE
+	#error No HSE in CH32X03x
+#endif
+
 #if !defined( FUNCONF_USE_PLL )
-	#define FUNCONF_USE_PLL 1 // Default to use PLL
+	#if defined( CH32X03x )
+		#define FUNCONF_USE_PLL 0 // No PLL on X03x
+	#else
+		#define FUNCONF_USE_PLL 1 // Default to use PLL
+	#endif
+#endif
+
+#if defined( CH32X03x ) && FUNCONF_USE_PLL
+	#error No PLL on the X03x
 #endif
 
+
 #if !defined( FUNCONF_USE_CLK_SEC )
 	#define FUNCONF_USE_CLK_SEC  1// use clock security system by default
 #endif
@@ -112,6 +125,8 @@
 #ifndef HSI_VALUE
 	#if defined(CH32V003)
 		#define HSI_VALUE                 (24000000) // Value of the Internal oscillator in Hz, default.
+	#elif defined(CH32X03x)
+		#define HSI_VALUE				  (48000000)
 	#elif defined(CH32V10x)
 		#define HSI_VALUE				  (8000000)
 	#elif defined(CH32V20x)
@@ -208,7 +223,7 @@ typedef enum IRQn
     SysTicK_IRQn = 12,       /* 12 System timer Interrupt                            */
     Software_IRQn = 14,      /* 14 software Interrupt                                */
 
-#ifdef CH32V003
+#if defined( CH32V003 ) || defined(CH32X03x)
     /******  RISC-V specific Interrupt Numbers *********************************************************/
     WWDG_IRQn = 16,          /* Window WatchDog Interrupt                            */
     PVD_IRQn = 17,           /* PVD through EXTI Line detection Interrupt            */
@@ -233,6 +248,24 @@ typedef enum IRQn
     TIM1_TRG_COM_IRQn = 36,  /* TIM1 Trigger and Commutation Interrupt               */
     TIM1_CC_IRQn = 37,       /* TIM1 Capture Compare Interrupt                       */
     TIM2_IRQn = 38,          /* TIM2 global Interrupt                                */
+#if defined(CH32X03x)
+	USART2_IRQn = 39,          /* UART2 Interrupt                          */
+	EXTI15_8_IRQn = 40,        /* External Line[8:15] Interrupt            */
+	EXTI25_16_IRQn = 41,       /* External Line[25:16] Interrupt           */
+	USART3_IRQn = 42,          /* UART2 Interrupt                          */
+	USART4_IRQn = 43,          /* UART2 Interrupt                          */
+	DMA1_Channel8_IRQn = 44,   /* DMA1 Channel 8 global Interrupt          */
+	USBFS_IRQn = 45,           /* USB Full-Speed Interrupt                 */
+	USBFS_WakeUp_IRQn = 46,    /* USB Full-Speed Wake-Up Interrupt         */
+	PIOC_IRQn = 47,            /* Programmable IO Controller Interrupt     */
+	OPA_IRQn = 48,             /* Op Amp Interrupt                         */
+	USBPD_IRQn = 49,           /* USB Power Delivery Interrupt             */
+	USBPD_WKUP_IRQn = 50,      /* USB Power Delivery Wake-Up Interrupt     */
+	TIM2_CC_IRQn = 51,         /* Timer 2 Compare Global Interrupt         */
+	TIM2_TRG_IRQn = 52,        /* Timer 2 Trigger Global Interrupt         */
+	TIM2_BRK_IRQn = 53,        /* Timer 2 Brk Global Interrupt             */
+	TIM3_IRQn = 54,            /* Timer 3 Global Interrupt                 */
+#endif
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 	/******  RISC-V specific Interrupt Numbers *********************************************************/
 	WWDG_IRQn = 16,            /* Window WatchDog Interrupt                            */
@@ -411,7 +444,7 @@ typedef enum IRQn
 
 #define HardFault_IRQn    EXC_IRQn
 
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 	#define ADC1_2_IRQn       ADC_IRQn
 #endif
 
@@ -446,6 +479,11 @@ typedef struct
     __IO uint32_t RDATAR;
 #if defined(CH32V20x)
     __IO uint32_t DLYR;
+#elif defined(CH32X03x)
+    __IO uint32_t CTLR3;
+    __IO uint32_t WDTR1;
+    __IO uint32_t WDTR2;
+    __IO uint32_t WDTR3;
 #endif
 } ADC_TypeDef;
 
@@ -855,6 +893,10 @@ typedef struct
 	__IO uint32_t BSHR;
 	__IO uint32_t BCR;
 	__IO uint32_t LCKR;
+#ifdef CH32X03x
+	__IO uint32_t CFGXR;
+	__IO uint32_t BSXR;
+#endif
 } GPIO_TypeDef;
 
 #define DYN_GPIO_READ(gpio, field) ((GPIO_##field##_t) { .__FULL = gpio->field })
@@ -868,6 +910,14 @@ typedef struct
     uint32_t RESERVED0;
     __IO uint32_t PCFR1;
     __IO uint32_t EXTICR;
+#elif defined(CH32X03x)
+    uint32_t RESERVED0;
+    __IO uint32_t PCFR1;
+    __IO uint32_t EXTICR1;
+    __IO uint32_t EXTICR2;
+    uint32_t RESERVED1;
+    uint32_t RESERVED2;
+    __IO uint32_t CTLR;
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 	__IO uint32_t ECR;
 	__IO uint32_t PCFR1;
@@ -1073,6 +1123,19 @@ typedef struct
     uint16_t      RESERVED14;
     __IO uint16_t DMAADR;
     uint16_t      RESERVED15;
+#elif defined( CH32X03x )
+    __IO uint32_t CH1CVR;
+    __IO uint32_t CH2CVR;
+    __IO uint32_t CH3CVR;
+    __IO uint32_t CH4CVR;
+    __IO uint16_t BDTR;
+    uint16_t      RESERVED13;
+    __IO uint16_t DMACFGR;
+    uint16_t      RESERVED14;
+    __IO uint16_t DMAADR;
+    uint16_t      RESERVED15;
+    __IO uint16_t SPEC;
+    uint16_t      RESERVED16;
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 	__IO uint16_t CH1CVR;
 	uint16_t      RESERVED13;
@@ -1608,6 +1671,112 @@ typedef struct
 
 #endif // #if defined(CH32V20x) || defined(CH32V30x)
 
+
+#if defined(CH32X03x)
+/* Touch Sensor, Mirrors Analog to Digital Converter */
+typedef struct
+{
+	//XXX TODO: CHECK THIS
+	__IO uint32_t RESERVED0[3];
+	__IO uint32_t CHARGE1;
+	__IO uint32_t CHARGE2;
+	__IO uint32_t RESERVED1[10];
+	__IO uint32_t CHGOFFSET;
+	__IO uint32_t RESERVED2[3];
+	__IO uint32_t DR_ACT_DCG;
+} TKEY_TypeDef;
+
+/* Op amp / comparator */
+typedef struct
+{
+	//XXX TODO: CHECK THIS
+	__IO uint16_t CFGR1;
+	__IO uint16_t CFGR2;
+	__IO uint32_t CTLR1;
+	__IO uint32_t CTLR2;
+	__IO uint32_t OPA_KEY;
+	__IO uint32_t CMP_KEY;
+	__IO uint32_t POLL_KEY;
+} OPACMP_TypeDef;
+
+typedef struct
+{
+	__IO uint8_t BASE_CTLR;
+	__IO uint8_t UDEV_CTLR; // or host ctlr
+	__IO uint8_t INT_EN;
+	__IO uint8_t DEV_ADDR;
+	__IO uint8_t RESERVED0;
+	__IO uint8_t MIS_ST;
+	__IO uint8_t INT_FG;
+	__IO uint8_t INT_ST;
+	__IO uint16_t RX_LEN;
+	__IO uint16_t RESERVED1;
+	__IO uint8_t UEP4_1_MOD;
+	__IO uint8_t UEP2_3_MOD; // Also HOST_EP_MOD
+	__IO uint8_t UEP567_MOD;
+	__IO uint8_t RESERVED2;
+
+	__IO uint32_t UEP0_DMA;
+	__IO uint32_t UEP1_DMA;
+	__IO uint32_t UEP2_DMA; // Also HOST_RX_DMA
+	__IO uint32_t UEP3_DMA; // Also HOST_TX_DMA
+
+	//__IO uint32_t UEP0_CTLR;
+	__IO uint16_t UEP0_TX_LEN;
+	__IO uint16_t UEP0_CTLR_H;
+
+	//__IO uint32_t UEP1_CTLR;
+	__IO uint16_t UEP1_TX_LEN;
+	__IO uint16_t UEP1_CTLR_H; // Also HOST_SETUP
+
+	//__IO uint32_t UEP2_CTLR;
+	__IO uint16_t UEP2_TX_LEN; // Also HOST_PID
+	__IO uint16_t UEP2_CTLR_H; // Also HOST_RX_CTL
+
+	//__IO uint32_t UEP3_CTLR;
+	__IO uint16_t UEP3_TX_LEN; // Also HOST_TX_LEN
+	__IO uint16_t UEP3_CTLR_H; // Also HOST_TX_CTL
+
+	//__IO uint32_t UEP4_CTLR;
+	__IO uint16_t UEP4_TX_LEN;
+	__IO uint16_t UEP4_CTLR_H;
+
+	__IO uint32_t RESERVED3[8];
+
+	__IO uint32_t UEP5_DMA;
+	__IO uint32_t UEP6_DMA;
+	__IO uint32_t UEP7_DMA;
+
+	//__IO uint32_t UEP5_CTLR;
+	__IO uint16_t UEP5_TX_LEN;
+	__IO uint16_t UEP5_CTLR_H;
+
+	//__IO uint32_t UEP6_CTLR;
+	__IO uint16_t UEP6_TX_LEN;
+	__IO uint16_t UEP6_CTLR_H;
+
+	//__IO uint32_t UEP7_CTLR;
+	__IO uint16_t UEP7_TX_LEN;
+	__IO uint16_t UEP7_CTLR_H;
+
+	__IO uint32_t UEPX_MOD;
+} USBFS_TypeDef;
+
+// TODO: Break host host-mode.
+
+/* USB Power Delivery */
+typedef struct
+{
+	__IO uint32_t CONFIG;
+	__IO uint32_t CONTROL;
+	__IO uint32_t STATUS;
+	__IO uint32_t PORT;
+	__IO uint32_t DMA;
+} USBPD_TypeDef;
+
+#endif // #if defined(CH32X03x)
+
+
 #endif
 
 /* Peripheral memory map */
@@ -1636,10 +1805,12 @@ typedef struct
 #define AHBPERIPH_BASE                          (PERIPH_BASE + 0x20000)
 
 #define TIM2_BASE                               (APB1PERIPH_BASE + 0x0000)
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 #define TIM3_BASE                               (APB1PERIPH_BASE + 0x0400)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 #define TIM4_BASE                               (APB1PERIPH_BASE + 0x0800)
 #define TIM5_BASE                               (APB1PERIPH_BASE + 0x0C00)
+#endif // CH32V10x, CH32V20x, CH32V30x
 #if defined(CH32V30x)	// CH32V30x
 #define TIM6_BASE             					(APB1PERIPH_BASE + 0x1000)
 #define TIM7_BASE             					(APB1PERIPH_BASE + 0x1400)
@@ -1654,8 +1825,10 @@ typedef struct
 #define TIM13_BASE                              (APB1PERIPH_BASE + 0x1C00)
 #define TIM14_BASE                              (APB1PERIPH_BASE + 0x2000)
 #endif					// CH32V10x
+#if defined(CH32V003) || defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 #define RTC_BASE                                (APB1PERIPH_BASE + 0x2800)
 #endif
+#endif
 #define WWDG_BASE                               (APB1PERIPH_BASE + 0x2C00)
 #define IWDG_BASE                               (APB1PERIPH_BASE + 0x3000)
 #if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
@@ -1663,6 +1836,8 @@ typedef struct
 #if defined(CH32V10x) || defined(CH32V30x)
 #define SPI3_BASE             					(APB1PERIPH_BASE + 0x3C00)
 #endif // defined(CH32V30x) || defined(CH32V10x)
+#endif
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 #define USART2_BASE                             (APB1PERIPH_BASE + 0x4400)
 #define USART3_BASE                             (APB1PERIPH_BASE + 0x4800)
 #define UART4_BASE                              (APB1PERIPH_BASE + 0x4C00)
@@ -1691,7 +1866,7 @@ typedef struct
 #define AFIO_BASE                               (APB2PERIPH_BASE + 0x0000)
 #define EXTI_BASE                               (APB2PERIPH_BASE + 0x0400)
 #define GPIOA_BASE                              (APB2PERIPH_BASE + 0x0800)
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 #define GPIOB_BASE                              (APB2PERIPH_BASE + 0x0C00)
 #endif
 #define GPIOC_BASE                              (APB2PERIPH_BASE + 0x1000)
@@ -1755,12 +1930,19 @@ typedef struct
 #define RCC_BASE                                (AHBPERIPH_BASE + 0x1000)
 
 #define FLASH_R_BASE                            (AHBPERIPH_BASE + 0x2000) /* Flash registers base address */
+
 #if defined(CH32V20x)
 #define CRC_BASE                                (AHBPERIPH_BASE + 0x3000)
 #define OPA_BASE                                (AHBPERIPH_BASE + 0x3804)
 #define ETH10M_BASE                             (AHBPERIPH_BASE + 0x8000)
 
 #define USBFS_BASE                              ((uint32_t)0x50000000)
+#elif defined(CH32X03x)
+
+#define OPA_BASE                                (AHBPERIPH_BASE + 0x6000)
+#define USBFS_BASE                              (AHBPERIPH_BASE + 0x3400)
+#define USBPD_BASE                              (AHBPERIPH_BASE + 0x7000)
+
 #elif defined(CH32V30x)
 #define CRC_BASE              					(AHBPERIPH_BASE + 0x3000)
 #define USBHS_BASE            					(AHBPERIPH_BASE + 0x3400)
@@ -1859,7 +2041,7 @@ typedef struct
 #define AFIO                                    ((AFIO_TypeDef *)AFIO_BASE)
 #define EXTI                                    ((EXTI_TypeDef *)EXTI_BASE)
 #define GPIOA                                   ((GPIO_TypeDef *)GPIOA_BASE)
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 #define GPIOB                                   ((GPIO_TypeDef *)GPIOB_BASE)
 #endif
 #define GPIOC                                   ((GPIO_TypeDef *)GPIOC_BASE)
@@ -1872,6 +2054,13 @@ typedef struct
 #define ADC1                                    ((ADC_TypeDef *)ADC1_BASE)
 #if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 #define ADC2                                    ((ADC_TypeDef *)ADC2_BASE)
+#endif
+#ifdef CH32X03x
+#define TKey                                    ((TKEY_TypeDef *)ADC1_BASE)
+#define OPA										((OPACMP_TypeDef *)OPA_BASE)
+#define USBFS									((USBFS_TypeDef *)USBFS_BASE)
+#define USBPD									((USBPD_TypeDef *)USBPD_BASE)
+
 #endif
 #if defined(CH32V20x) || defined(CH32V30x)
 #define TKey1                                   ((ADC_TypeDef *)ADC1_BASE)
@@ -1904,7 +2093,7 @@ typedef struct
 #define DMA1_Channel5                           ((DMA_Channel_TypeDef *)DMA1_Channel5_BASE)
 #define DMA1_Channel6                           ((DMA_Channel_TypeDef *)DMA1_Channel6_BASE)
 #define DMA1_Channel7                           ((DMA_Channel_TypeDef *)DMA1_Channel7_BASE)
-#if defined(CH32V20x)
+#if defined(CH32V20x) || defined(CH32X03x)
 #define DMA1_Channel8                           ((DMA_Channel_TypeDef *)DMA1_Channel8_BASE)
 #endif
 #if defined(CH32V10x) || defined(CH32V30x)
@@ -5080,7 +5269,7 @@ typedef struct
 #define RCC_HPRE_2                              ((uint32_t)0x00000040) /* Bit 2 */
 #define RCC_HPRE_3                              ((uint32_t)0x00000080) /* Bit 3 */
 
-#if defined(CH32V003)
+#if defined(CH32V003) || defined(CH32X03x)
 #define RCC_HPRE_DIV1                           ((uint32_t)0x00000000) /* SYSCLK not divided */
 #define RCC_HPRE_DIV2                           ((uint32_t)0x00000010) /* SYSCLK divided by 2 */
 #define RCC_HPRE_DIV3                           ((uint32_t)0x00000020) /* SYSCLK divided by 3 */
@@ -9131,7 +9320,9 @@ typedef enum
 #define GPIO_PortSourceGPIOA           ((uint8_t)0x00)
 #define GPIO_PortSourceGPIOC           ((uint8_t)0x02)
 #define GPIO_PortSourceGPIOD           ((uint8_t)0x03)
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32X03x)
+#define GPIO_PortSourceGPIOB            ((uint8_t)0x01)
+#elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 #define GPIO_PortSourceGPIOB            ((uint8_t)0x01)
 #define GPIO_PortSourceGPIOD            ((uint8_t)0x03)
 #define GPIO_PortSourceGPIOE            ((uint8_t)0x04)
@@ -9148,7 +9339,7 @@ typedef enum
 #define GPIO_PinSource5                ((uint8_t)0x05)
 #define GPIO_PinSource6                ((uint8_t)0x06)
 #define GPIO_PinSource7                ((uint8_t)0x07)
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined(CH32X03x)
 #define GPIO_PinSource8                 ((uint8_t)0x08)
 #define GPIO_PinSource9                 ((uint8_t)0x09)
 #define GPIO_PinSource10                ((uint8_t)0x0A)
@@ -9883,7 +10074,7 @@ typedef struct
 
 #endif
 
-#ifdef CH32V003
+#if defined(CH32V003) || defined(CH32X03x)
 
 /* AHB_peripheral */
 #define RCC_AHBPeriph_DMA1               ((uint32_t)0x00000001)
@@ -9892,6 +10083,9 @@ typedef struct
 /* APB2_peripheral */
 #define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)
 #define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
+#ifdef CH32X03x
+#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
+#endif
 #define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
 #define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
 #define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)
@@ -9905,6 +10099,17 @@ typedef struct
 #define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)
 #define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)
 
+#if defined(CH32X03x)
+
+/* APB2_peripheral */
+#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
+
+#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
+#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)
+#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)
+
+#endif
+
 #elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 
 /* AHB_peripheral */
@@ -11481,7 +11686,7 @@ typedef struct{
     __IO uint32_t SCTLR;
 }PFIC_Type;
 
-#ifdef CH32V003
+#if defined (CH32V003) 
 
 /* memory mapped structure for SysTick */
 typedef struct
@@ -11505,7 +11710,7 @@ typedef struct
 	__IO uint64_t CMP;
 } SysTick_Type;
 
-#elif defined(CH32V10x)
+#elif defined(CH32V10x) || defined(CH32X03x)
 
 /* memory mapped structure for SysTick */
 typedef struct
@@ -12310,8 +12515,7 @@ extern "C" {
 #define PD6 54
 #define PD7 55
 
-
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x) || defined( CH32X03x )
 #define PA0 0
 #define PA3 3
 #define PA4 4
@@ -12342,6 +12546,14 @@ extern "C" {
 #define PB13 29
 #define PB14 30
 #define PB15 31
+#define PC8 40
+#define PC9 41
+#define PC10 42
+#define PC11 43
+#define PC12 44
+#define PC13 45
+#define PC14 46
+#define PC15 47
 #endif
 
 
@@ -12350,7 +12562,10 @@ extern "C" {
 
 #define funDigitalWrite( pin, value ) { GpioOf( pin )->BSHR = 1<<((!(value))*16 + ((pin) & 0xf)); }
 
-#if defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
+#if defined(CH32X03x)
+#define funGpioInitAll() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC ); }
+#define funPinMode( pin, mode ) { *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }
+#elif defined(CH32V10x) || defined(CH32V20x) || defined(CH32V30x)
 #define funGpioInitAll() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD ); }
 #define funPinMode( pin, mode ) { *((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3)) = ( (*((&GpioOf(pin)->CFGLR)+((pin&0x8)>>3))) & (~(0xf<<(4*((pin)&0x7))))) | ((mode)<<(4*((pin)&0x7))); }
 #define funGpioInitB() { RCC->APB2PCENR |= ( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB ); }
diff --git a/ch32v003fun/ch32v003fun.ld b/ch32v003fun/ch32v003fun.ld
index 4ad76b4..10096e4 100644
--- a/ch32v003fun/ch32v003fun.ld
+++ b/ch32v003fun/ch32v003fun.ld
@@ -38,6 +38,13 @@ MEMORY
 	#else
 		#error "Unknown MCU package"
 	#endif
+#elif TARGET_MCU_LD == 4
+	#if MCU_PACKAGE == 1
+		FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 62K
+		RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+	#else
+		#error "Unknown MCU package"
+	#endif
 #else
 	#error "Unknown MCU target"
 #endif
diff --git a/ch32v003fun/ch32v003fun.mk b/ch32v003fun/ch32v003fun.mk
index 664a861..a4cbcb6 100644
--- a/ch32v003fun/ch32v003fun.mk
+++ b/ch32v003fun/ch32v003fun.mk
@@ -56,6 +56,30 @@ else
 		endif
 
 		TARGET_MCU_LD:=1
+	else ifeq ($(findstring CH32X03,$(TARGET_MCU)),CH32X03) # CH32X033, X035
+		TARGET_MCU_PACKAGE?=CH32X035F8U6
+		CFLAGS_ARCH+=	-march=rv32imac \
+			-mabi=ilp32 \
+			-DCH32X03x=1
+
+		# MCU Flash/RAM split
+		ifeq ($(findstring F8, $(TARGET_MCU_PACKAGE)), F8)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring R8, $(TARGET_MCU_PACKAGE)), R8)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring K8, $(TARGET_MCU_PACKAGE)), K8)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring C8, $(TARGET_MCU_PACKAGE)), C8)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring G8, $(TARGET_MCU_PACKAGE)), G8)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring G6, $(TARGET_MCU_PACKAGE)), G6)
+			MCU_PACKAGE:=1
+		else ifeq ($(findstring F7, $(TARGET_MCU_PACKAGE)), F7)
+			MCU_PACKAGE:=1
+		endif
+
+		TARGET_MCU_LD:=4		
 	else ifeq ($(findstring CH32V20,$(TARGET_MCU)),CH32V20) # CH32V203
 		TARGET_MCU_PACKAGE?=CH32V203F8P6
 		CFLAGS_ARCH+=	-march=rv32imac \
diff --git a/examples_x035/blink/Makefile b/examples_x035/blink/Makefile
new file mode 100644
index 0000000..0290b25
--- /dev/null
+++ b/examples_x035/blink/Makefile
@@ -0,0 +1,11 @@
+all : flash
+
+TARGET:=blink
+TARGET_MCU:=CH32X035
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
+
diff --git a/examples_x035/blink/blink.c b/examples_x035/blink/blink.c
new file mode 100644
index 0000000..61199a8
--- /dev/null
+++ b/examples_x035/blink/blink.c
@@ -0,0 +1,31 @@
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+int main()
+{
+	//SystemInit();
+
+	funGpioInitAll();
+
+	funPinMode( PA0, GPIO_CFGLR_OUT_10Mhz_PP );
+
+	while(1)
+	{
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		funDigitalWrite( PA0, FUN_HIGH );	 // Turn on GPIO
+		//Delay_Ms( 1000 );
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		funDigitalWrite( PA0, FUN_LOW );	 // Turn off GPIO
+		//Delay_Ms( 1000 );
+	}
+}
diff --git a/examples_x035/blink/funconfig.h b/examples_x035/blink/funconfig.h
new file mode 100644
index 0000000..d9342ae
--- /dev/null
+++ b/examples_x035/blink/funconfig.h
@@ -0,0 +1,5 @@
+#ifndef _FUNCONFIG_H
+#define _FUNCONFIG_H
+
+#endif
+
diff --git a/minichlink/pgm-wch-linke.c b/minichlink/pgm-wch-linke.c
index b37ae82..b7250bd 100644
--- a/minichlink/pgm-wch-linke.c
+++ b/minichlink/pgm-wch-linke.c
@@ -322,15 +322,30 @@ static int LESetupInterface( void * d )
 
 	// This puts the processor on hold to allow the debugger to run.
 	int already_tried_reset = 0;
+	int is_already_connected = 0;
 	do
 	{
+		// Read DMSTATUS - in case we are a ch32x035, or other chip that does not respond to \x81\x0d\x01\x02.
+		wch_link_command( dev, "\x81\x08\x06\x05\x11\x00\x00\x00\x00\x01", 11, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500
+		if( transferred == 9 && rbuff[8] != 0x02 && rbuff[8] != 0x03 )
+		{
+			// Already connected.
+			if( is_already_connected )
+			{
+				printf( "Already Connected\n" );
+				break;
+			}
+			is_already_connected = 1;
+		}
+
+
 		wch_link_command( dev, "\x81\x0d\x01\x02", 4, (int*)&transferred, rbuff, 1024 ); // Reply: Ignored, 820d050900300500
 		if (rbuff[0] == 0x81 && rbuff[1] == 0x55 && rbuff[2] == 0x01 ) // && rbuff[3] == 0x01 )
 		{
 			// The following code may try to execute a few times to get the processor to actually reset.
 			// This code could likely be much better.
-
-			fprintf(stderr, "link error, nothing connected to linker (%d = [%02x %02x %02x %02x]).  Trying to put processor in hold and retrying.\n", transferred, rbuff[0], rbuff[1], rbuff[2], rbuff[3]);
+			if( already_tried_reset > 1)
+				fprintf(stderr, "link error, nothing connected to linker (%d = [%02x %02x %02x %02x]).  Trying to put processor in hold and retrying.\n", transferred, rbuff[0], rbuff[1], rbuff[2], rbuff[3]);
 
 			// Give up if too long
 			if( already_tried_reset > 10 )
@@ -360,7 +375,7 @@ static int LESetupInterface( void * d )
 	} while( 1 );
 
 	if(rbuff[3] == 0x08 || rbuff[3] > 0x09) {
-		fprintf( stderr, "Chip Type unknown. Aborting...\n" );
+		fprintf( stderr, "Chip Type unknown [%02x]. Aborting...\n", rbuff[3] );
 		return -1;
 	}
 
-- 
GitLab