Skip to content

[CH32VM00X] Update SDK to apply correct clock #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

tako0910
Copy link
Contributor

@tako0910 tako0910 commented May 26, 2025

I ran the CH32V006 in an Arduino environment and noticed that
the delay() function was waiting longer than it should.

Assuming that there was a problem with the clock settings,
I first looked at the SDK and noticed that it was fixed in the latest SDK,
so I synchronized it with this SDK.

https://www.wch.cn/downloads/CH32V006EVT_ZIP.html (Ver.1.4)

$ cp /path/to/EVT/EXAM/GPIO/GPIO_Toggle/User/* /path/to/arduino_core_ch32/system/CH32VM00X/USER/
$ cd /path/to/arduino_core_ch32/system/CH32VM00X/USER/
$ find . -type f | xargs file |grep CRLF | awk -F: '{print $1}' | xargs nkf -Lu --overwrite
  • The SDK source code and the code in this repository use different line endings, so I converted them using a command...

* Clock was not set correctly due to flawed SYSCLK_FREQ logic.
@tako0910 tako0910 changed the title Update CH32VM00X SDK to apply correct clock [Update SDK to apply correct clock May 26, 2025
@tako0910 tako0910 changed the title [Update SDK to apply correct clock [CH32VM00X] Update SDK to apply correct clock May 26, 2025
@maxint-rd
Copy link
Contributor

maxint-rd commented May 26, 2025

Interesting. In my first experiments with the V006 I had problems flashing the chip when using OpenOCD, so I used the WCH Link Utility to flash a generated hex file. I like to believe that test (featuring serial.print of millis after delay) used the selected 48Mhz clock speed and it ran fine with proprr delay duration, but I guess I need to check that in more detail.

Note that clock speed should not be defined in the header file, but be selected in the IDE. Also note that some time ago there was conflicting capitalization usage of Mhz vs. MHZ in the used defines. Having consistent capitalization may require some further changes.

One question @tako0910 : were you able to upload directly from the IDE? (I think my version of OpenOCD is outdated and diesn't support V006 or V002)

tako0910 added 2 commits May 27, 2025 11:27
* This definition is defined from the IDE side and should not be defined here.
@tako0910
Copy link
Contributor Author

tako0910 commented May 27, 2025

Thank you for your response! I now understand that I had a slight misunderstanding.

  • Originally, system_ch32v00X.c should not simply be copied from the SDK —
    all clock-related #defines need to be commented out:
    • This is because the clock speed definition provided by the IDE must be used.
    • In the case of the Arduino IDE, this definition is specified in boards.txt.

I reviewed the source code again as it was before I made any modifications.

First, the definition of boards.txt is as follows
boards.txt

# Clock Select
CH32VM00X_EVT.menu.clock.48MHz_HSI=48MHz Internal
CH32VM00X_EVT.menu.clock.48MHz_HSI.build.flags.clock=-DSYSCLK_FREQ_48MHz_HSI=48000000 -DF_CPU=48000000
CH32VM00X_EVT.menu.clock.24MHz_HSI=24MHz Internal
CH32VM00X_EVT.menu.clock.24MHz_HSI.build.flags.clock=-DSYSCLK_FREQ_24MHz_HSI=24000000 -DF_CPU=24000000
CH32VM00X_EVT.menu.clock.8MHz_HSI=8MHz Internal
CH32VM00X_EVT.menu.clock.8MHz_HSI.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSI=8000000 -DF_CPU=8000000
CH32VM00X_EVT.menu.clock.48MHz_HSE=48MHz External
CH32VM00X_EVT.menu.clock.48MHz_HSE.build.flags.clock=-DSYSCLK_FREQ_48MHz_HSE=48000000 -DF_CPU=48000000
CH32VM00X_EVT.menu.clock.24MHz_HSE=24MHz External
CH32VM00X_EVT.menu.clock.24MHz_HSE.build.flags.clock=-DSYSCLK_FREQ_24MHz_HSE=24000000 -DF_CPU=24000000
CH32VM00X_EVT.menu.clock.8MHz_HSE=8MHz External
CH32VM00X_EVT.menu.clock.8MHz_HSE.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSE=8000000 -DF_CPU=8000000

Next, the function prototypes in system_ch32v00X.c appear to be correctly defined:

system/CH32VM00X/USER/system_ch32v00X.c

/* system_private_function_proto_types */
static void SetSysClock(void);

#ifdef SYSCLK_FREQ_8MHz_HSI
  static void SetSysClockTo_8MHz_HSI(void);
#elif defined SYSCLK_FREQ_24MHz_HSI
  static void SetSysClockTo_24MHz_HSI(void);
#elif defined SYSCLK_FREQ_48MHz_HSI
  static void SetSysClockTo_48MHz_HSI(void);
#elif defined SYSCLK_FREQ_8MHz_HSE
  static void SetSysClockTo_8MHz_HSE(void);
#elif defined SYSCLK_FREQ_24MHz_HSE
  static void SetSysClockTo_24MHz_HSE(void);
#elif defined SYSCLK_FREQ_48MHz_HSE
  static void SetSysClockTo_48MHz_HSE(void);
#endif

And the actual implementation also exists:

#elif defined SYSCLK_FREQ_48MHz_HSI

/*********************************************************************
 * @fn      SetSysClockTo_48MHZ_HSI
 *
 * @brief   Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
 *
 * @return  none
 */
static void SetSysClockTo_48MHz_HSI(void)
{
    /* HCLK = SYSCLK = PB1 */
    RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
...

However, in the SetSysClock() function, the #elif conditions for the 24MHz and 48MHz HSI clocks incorrectly use "MHZ" (with a capital "Z") instead of "MHz".

/*********************************************************************
 * @fn      SetSysClock
 *
 * @brief   Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
 *
 * @return  none
 */
static void SetSysClock(void)
{
RCC->PB2PCENR |= RCC_PB2Periph_GPIOD;
GPIOD->CFGLR&=(~0xF0);
GPIOD->CFGLR|=0x80;
GPIOD->BSHR =0x2;
GPIO_IPD_Unused();
#ifdef SYSCLK_FREQ_8MHz_HSI
    SetSysClockTo_8MHz_HSI();
#elif defined SYSCLK_FREQ_24MHZ_HSI
    SetSysClockTo_24MHZ_HSI();
#elif defined SYSCLK_FREQ_48MHZ_HSI
    SetSysClockTo_48MHZ_HSI();
#elif defined SYSCLK_FREQ_8MHz_HSE
    SetSysClockTo_8MHz_HSE();
#elif defined SYSCLK_FREQ_24MHz_HSE
    SetSysClockTo_24MHz_HSE();
#elif defined SYSCLK_FREQ_48MHz_HSE
    SetSysClockTo_48MHz_HSE();
#endif

As a result, when SYSCLK_FREQ_24MHz_HSI or SYSCLK_FREQ_48MHz_HSI (with lowercase "z") is defined — as it is in boards.txt — none of the conditions match, and the corresponding clock initialization functions are never called. This is a bug.

This granularity should have been included in the body of the Pull Request from the beginning.
(But I was partly mistaken in the first place...)


As a fix, I have updated the source code to adjusted the boards.txt definitions to align with the SDK as well.

Although the use of both uppercase and lowercase "z" in "MHz"/"MHZ" is inconsistent and arguably unnatural, I chose to follow the SDK's convention.
This is to prevent similar issues from recurring in the future when updating to newer SDK versions.

The code has already been updated accordingly.


were you able to upload directly from the IDE? (I think my version of OpenOCD is outdated and diesn't support V006 or V002)

You are right. I couldn't upload directly either.
As a temporary measure, I replaced OpenOCD with a copy from MounRiver Studio 2 and works well.

@maxint-rd
Copy link
Contributor

Thanks for the great info. As soon as I find some time somewhere in the coming weeks, I want to test things on the V002 and V006. I've been looking for a new OpenOCD, but had not looked into MounRiver yet. Thanks!

You can read more about the Mhz capitalization and how it was handled in
this comment and further responses in issue #27. It was also mentioned briefly in issue #66.

I guess @yangliangquan will find ways to align things in the next release of this Arduino core. With all the various CH32 chips there are many things to test to ensure they all work.

There are already plenty PRs to integrate, but it's good to see other people trying to use the V006 and it's nice to have that one working too. It's increased memory makes it a great chip to do realtime debugging for V003 projects.

@tako0910
Copy link
Contributor Author

Please do give it a try when you have the time!

Oh, I see — so this issue has been mentioned before.
I hope it will be properly addressed, including the problem with OpenOCD.

I also think the CH32V006 is a great product, and I created this pull request so that more people might take an interest in it.

Thank you for your comments — they helped deepen my understanding.

@Willem004
Copy link

I replaced the instance of openocd with the one from mounriverstudio like you described and got my first code running on the CH32V006. @tako0910 your comment helped me out tremendously.

@maxint-rd
Copy link
Contributor

maxint-rd commented Jun 2, 2025

TL;DR: I successfully tested uploading to V002 and V006 using the WCH OpenOCD obtained from the latest MounRiver Studio.


After installation of MounRiver Studio (in Windows 11 x64 under VMware Workstation Player) following all defaults, WCH OpenOCD v2.3 was found here:
C:\MounRiver\MounRiver_Studio2\resources\app\resources\win32\components\WCH\OpenOCD

I copied the contents of that folder to a new 2.3.0 folder (next to the 1.0.0 folder) in

  • C:\Users\<username>\AppData\Local\Arduino15\packages\WCH\tools\openocd

Then I changed this file:

  • C:\Users\<username>\AppData\Local\Arduino15\packages\WCH\hardware\ch32v\1.0.4\platform.txt
    Use search and replace to change "openocd-1.0.0" into "openocd-2.3.0" in the sections # Uploader tool and # Debugger configuration.

After restarting the Arduino IDE (v2.3.6) I could successfully upload my sketch and use the interactive debugger. Yippie!
Thanks @tako0910 for pointing out this OpenOCD update.

BTW. For uploading to the V002 I made a modified board variant based on ...\variants\CH32VM00X\CH32V006K8 and included a changed LinkV002.ld based on Link.ld in ...\system\CH32VM00X\SRC\Ld

I still need to test and perhaps fix the clock behavior. I noticed that after using the WCH Link utility to query chip ID, the clock changed, resulting in double serial speed. Doing reset (F12) changed the serial speed and output back to normal.

Edit: Tested clock behavior. It was wrong indeed on both V002 and V006. When checking serial monitor with timestamps on, I also saw 500ms delays taking 1000ms. The smallest fix (4 lines) was to align the capitalization bug in ...\system\CH32VM00X\USER\system_ch32v00X.c as done in PR #66.

Still intend to test the other changes in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants