27 January 2025
Because this has happened before, I will archive the two project files from the confused project and compare them to a newly generated one.
So it seems that after you delete all the generated project files (except the linker script for now), any new source files that are added to the project must be located within a sub folder of the project, as placing them in the project folder itself produces an error. Then just clean the project and re-build it.
Also, to access the generated include files, you have to add ‘../../inc’ to the include directories command (-I) in the Project Properties -> C/C++ Build -> Build Settings -> GNU RISC-V Cross Assembler -> Includes dialog box.
OK, now that everything works again, I need to narrow down which bit I offended when I was trying to reset all the peripherals at once. This happened once before on a -003 project, but I don’t recall exactly which one.
It was the ‘F4-28BYJ-48.S’, where I used a CH32V003F4 to drive a small stepper motor:
# hard reset all peripherals
li t0, RCC_I2C1RST | RCC_WWDGRST | RCC_TIM2RST # just these bits - not RCC_PWRRST!
sw t0, RCC_APB1PRSTR(tp) # reset APB1 peripherals
li t0, 0xFFFFFFFF # all of the ones
sh t0, RCC_APB2PRSTR(tp) # reset APB2 peripherals
sw zero, RCC_APB1PRSTR(tp) # release APB1 peripherals
sw zero, RCC_APB2PRSTR(tp) # release APB2 peripherals
Note that the CH32V003 family only has reset registers for the APB1 and APB2 peripherals.
Looking for the latest reference manuals leads me to discover that the wch-ic.com web site is not responding at the moment. This is the english-language version of the Chinese language web site, wch.cn, which is also not working for me at the moment.
The -003 chips only have four peripherals that can be reset via the RCC_APB1PRSTR register:
0 Timer 2
11 Window watchdog
21 I2C 1
28 Power interface
It was the ‘Power interface’ module that sent everything crashing down when reset. There were no problems resetting the other peripherals.
I also seem to remember reading somewhere, but I can’t find it now, that you only had to set the bits in the reset registers and they would automatically reset themselves. This is most certainly not the case. The peripherals remain in a reset state until you write a zero back into the corresponding bit position.
Now on the CH32X035 chips, there are reset registers for the HB, PB1 and PB2 buses. It also has the same reset bits for the PB1 peripherals, in the same places. It also adds support for the additional peripherals offered, including TIM3, USART2, USART3 and USART4.
I will conduct a slightly risky experiment in terms of time required to recover if I’m wrong by eliminating the PWR reset bit from my initialization routine and see if it bricks. It seems to work! Here is the adjusted reset code:
# reset all the peripherals
li t1, 0xFFFFFFFF # all of the ones
sw t1, RCC_AHBRSTR(t0) # reset HB peripherals
sw t1, RCC_APB2PRSTR(t0) # reset PB2 peripherals
li t1, ~RCC_PWRRST # everything but RCC_PWRRST
sw t1, RCC_APB1PRSTR(t0) # reset PB1 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
Instead of only setting the actual bits in the PB1 reset register, I set all of the bits except for PWRRST. Nothing terrible happened.
I tried to ask the MRS2 folks a question via the ‘Feedback’ option, but it failed with a timeout. It seems we’re having a hard time talking to China today. The question was how to change the numerical bases in the Debug Variables/Register view.