26 January 2025
Where is the SVD file for the CH32X035 chips? I have found it within the MRS2 application itself:
/Applications/MounRiver Studio 2.app/Contents/Resources/app/resources/darwin/components/WCH/SDK/default/RISC-V/CH32X035/NoneOS/CH32X035xx.svd
The original file is dated 23 December 2024.
I have copied it to my CH32X035 project folder:
/Users/dalewheat/Documents/Projects/RISC-V/CH32V/CH32X035/CH32X035xx.svd
Let’s run my existing svd2inc.py script on it and see what breaks first.
Perhaps it would have been better to copy it to my Python project directory, instead. I’m not fluent enough in the Python to be able to run scripts from just anywhere, just yet.
/Users/dalewheat/Documents/Projects/Python/CH32X035xx.svd
I’m just a little surprised that it ran with no issues. It produces the following output to the console:
svd2inc.py - SVD to RISC-V ASM header file converter
SVD filename: CH32X035xx.svd
Parsing CH32X035xx.svd... done
Creating 'CH32X035xx.svd.inc'
Peripherals
PWR/PWR, 0x40007000, Power control
RCC/RCC, 0x40021000, Reset and clock control
GPIO/GPIOA, 0x40010800, General purpose I/O
GPIO/GPIOB, 0x40010C00, derived from GPIOA
GPIO/GPIOC, 0x40011000, derived from GPIOA
AFIO/AFIO, 0x40010000, Alternate function I/O
EXTI/EXTI, 0x40010400, EXTI
DMA/DMA, 0x40020000, DMA controller
IWDG/IWDG, 0x40003000, Independent watchdog
WWDG/WWDG, 0x40002C00, Window watchdog
TIM/TIM1, 0x40012C00, Advanced timer
TIM/TIM2, 0x40000000, derived from TIM1
TIM/TIM3, 0x40000400, General purpose timer
I2C/I2C1, 0x40005400, Inter integrated circuit
SPI/SPI1, 0x40013000, Serial peripheral interface
USART/USART1, 0x40013800, Universal synchronous asynchronous receiver transmitter
USART/USART2, 0x40004400, derived from USART1
USART/USART3, 0x40004800, derived from USART1
USART/UART4, 0x40004C00, derived from USART1
ADC/ADC, 0x40012400, Analog to digital converter
DBG/DBG, 0xE000D000, Debug support
USBFS/USBFS, 0x40023400, USB register
FLASH/FLASH, 0x40022000, FLASH
PFIC/PFIC, 0xE000E000, Programmable Fast Interrupt Controller
AWU/AWU, 0x40026400, AWU configuration
OPA/OPA, 0x40026000, OPA configuration
ESIG/ESIG, 0x1FFFF7E0, ESIG configuration
USBPD/USBPD, 0x40027000, USBPD configuration
Interrupts
2: NMI - Non-maskable interrupt
3: HardFault - Exception interrupt
5: Ecall_M - Callback interrupt in machine mode
8: Ecall_U - Callback interrupt in user mode
9: BreakPoint - Breakpoint callback interrupt
12: STK - System timer interrupt
14: SW - Software interrupt
16: WWDG - Window Watchdog interrupt
17: PVD - PVD through EXTI line detection interrupt
18: FLASH - Flash global interrupt
20: EXTI7_0 - EXTI Line[7:0] interrupt
21: AWU - AWU global interrupt
22: DMA_Channel1 - DMA Channel1 global interrupt
23: DMA_Channel2 - DMA Channel2 global interrupt
24: DMA_Channel3 - DMA Channel3 global interrupt
25: DMA_Channel4 - DMA Channel4 global interrupt
26: DMA_Channel5 - DMA Channel5 global interrupt
27: DMA_Channel6 - DMA Channel6 global interrupt
28: DMA_Channel7 - DMA Channel7 global interrupt
29: ADC1 - ADC global interrupt
30: I2C1_EV - I2C1 event interrupt
31: I2C1_ER - I2C1 error interrupt
32: USART1 - USART1 global interrupt
33: SPI1 - SPI1 global interrupt
34: TIM1_BRK - TIM1 Break interrupt
35: TIM1_UP_ - TIM1 Update interrupt
36: TIM1_TRG_COM - TIM1 Trigger and Commutation interrupts
37: TIM1_CC - TIM1 Capture Compare interrupt
38: TIM2_UP_ - TIM2 Update interrupt
39: USART2 - USART2 global interrupt
40: EXTI15_8 - EXTI Line[15:8] interrupts
41: EXTI25_16 - EXTI Line[25:16] interrupts
42: USART3 - USART3 global interrupt
43: UART4 - UART4 global interrupt
44: DMA_Channel8 - DMA Channel8 global interrupt
45: USBFS - USBFS
46: USBFS_WKUP - USBFS_WKUP
49: USBPD - USBPD global interrupt
50: USBPD_WKUP - USBPD_WKUP global interrupt
51: TIM2_CC - TIM2 Capture Compare interrupt
52: TIM2_TRG_COM - TIM2 Trigger and Commutation interrupts
53: TIM2_BRK - TIM2 Break interrupt
54: TIM3 - TIM3 global interrupt
Creating interrupt vectors
2: NMI_handler
3: HardFault_handler
5: Ecall_M_handler
8: Ecall_U_handler
9: BreakPoint_handler
12: STK_handler
14: SW_handler
Created 7 system vectors
16: WWDG_handler
17: PVD_handler
18: FLASH_handler
20: EXTI7_0_handler
21: AWU_handler
22: DMA_Channel1_handler
23: DMA_Channel2_handler
24: DMA_Channel3_handler
25: DMA_Channel4_handler
26: DMA_Channel5_handler
27: DMA_Channel6_handler
28: DMA_Channel7_handler
29: ADC1_handler
30: I2C1_EV_handler
31: I2C1_ER_handler
32: USART1_handler
33: SPI1_handler
34: TIM1_BRK_handler
35: TIM1_UP__handler
36: TIM1_TRG_COM_handler
37: TIM1_CC_handler
38: TIM2_UP__handler
39: USART2_handler
40: EXTI15_8_handler
41: EXTI25_16_handler
42: USART3_handler
43: UART4_handler
44: DMA_Channel8_handler
45: USBFS_handler
46: USBFS_WKUP_handler
49: USBPD_handler
50: USBPD_WKUP_handler
51: TIM2_CC_handler
52: TIM2_TRG_COM_handler
53: TIM2_BRK_handler
54: TIM3_handler
Created 36 device vectors
Created 43 vectors in total
It also produces a 153 KB file called CH32X035xx.svd.inc. The file has the following header:
# filename: CH32X035xx.svd.inc
# created by svd2inc.py on 2025-01-26
# based on CH32X035xx.svd
# Device Name: CH32X035
# Vendor: WCH Ltd.
# Description: CH32X035 View File
# Version: 1.2
I will now create a ‘inc’ folder in the CH32X035 project folder, and put the new file there. I’m also frustrated that I still don’t know how to create a folder within a folder using the Finder application. It will create a folder at the root of whatever folder that you’re looking at, but not the one selected. Next time I will try to double-click on the desired sub-folder first, then within the new window or tab that is created, I will select File -> New Folder. [TODO]
Two things come to mind to check with this new SVD file:
Q1. Are there any 'enumerated values' defined?
A1. No.
Q2. Does the hard-coded STK definition of 64 bit counter still apply?
A2. Yes.
So now I need to create a generic CH32X035.inc file and have it subsequently include the generated file. I can also place the missing enumerated values that I will need in this file, as well.
Here are the definitions I wrote by hand for the G8-asm.S project:
# register addresses and field definitions
RCC_BASE = 0x40021000 # reset and clock control
RCC_CFGR0 = 0x04
RCC_HPRE_1 = (0 << 4)
RCC_HPRE_6 = (5 << 4)
RCC_MCO_SYS = (4 << 24)
RCC_MCO_HSI = (5 << 24)
RCC_PB2PCENR = 0x18
RCC_IOPAEN = (1 << 2)
RCC_IOPBEN = (1 << 3)
RCC_USART1EN = (1 << 14)
FLASH_BASE = 0x40022000
FLASH_ACTLR = 0x00
FLASH_WAIT_STATE_0 = 0x00
FLASH_WAIT_STATE_1 = 0x01
FLASH_WAIT_STATE_2 = 0x02
GPIOA_BASE = 0x40010800
GPIOB_BASE = 0x40010C00
GPIO_CFGLR = 0x00
GPIO_CFGHR = 0x04
GPIO_OUTDR = 0x0C
USART1_BPS = 115200
USART1_BASE = 0x40013800
USART_DATAR = 0x04
USART_BRR = 0x08
USART_CTLR1 = 0x0C
USART_RE = (1 << 2)
USART_TE = (1 << 3)
USART_UE = (1 << 13)
I should be able to swap in the newly-defined values from the include file.
I had to hard-code the include file into the build properties, as adding a relative reference, .i.e., ‘../inc’ did not work.
Alas, the SVD has not caught up with the new bus naming conventions. I was able to get the G8-asm.S project to assemble and it seems to run the same as before.
Now to add some more appropriate initializations and then put in some interrupts.
Unfortunately, the thorough reset I like to do for these chips has completely bricked the device. Here is the code:
# reset all the peripherals
li t1, 0xFFFFFFFF # all of the ones
sw t1, RCC_AHBRSTR(t0) # reset HB peripherals
sw t1, RCC_APB1PRSTR(t0) # reset PB1 peripherals
sw t1, RCC_APB2PRSTR(t0) # reset PB2 peripherals
sw zero, RCC_AHBRSTR(t0) # release HB peripherals
sw zero, RCC_APB1PRSTR(t0) # release PB1 peripherals
sw zero, RCC_APB2PRSTR(t0) # release PB2 peripherals
I had the same problem with the CH32V003 chip. Now if I can only find out which peripheral it was that objected to the reset procedure…
There is a new ‘No-Reset Debug Tool’ that I haven’t seen before. It’s not unbricking the device, however. I was able to use the minichlink’s ‘unbrick’ command, and that reported success, but I was then still unable to erase the chip using ‘wlink erase’ or download with MRS2.
Wow, it was really bricked. The only thing that would work was to attach it to a Windows PC, connect via USB, hold down the ‘Download’ button while plugging it in, then running the WCHISP program (not available on macOS). Then I could download a blink program that set things right. I still had to run ‘wlink erase’ back on the MacBook to ‘unprotect’ the flash memory. Now it is working again.
In my flailing about with the MRS2 software I seem to have disabled the download function by selecting ‘Others…’ for the programming device. It replaced the usual dialog with just two lines, command and arguments. There does not seem to be any way to recover from this situation, so I’m just going to start over with a new project, saving the single source file G8-asm.S.