Skip to content

Clock selection using Arduino IDE menu #27

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

Closed
maxint-rd opened this issue Oct 10, 2023 · 9 comments
Closed

Clock selection using Arduino IDE menu #27

maxint-rd opened this issue Oct 10, 2023 · 9 comments

Comments

@maxint-rd
Copy link
Contributor

maxint-rd commented Oct 10, 2023

While testing this Arduino core on my CH32V003, I found that using a bare CH32V003 TSSOP20 chip without external crystal requires a change of clock selection in system_ch32v00x.c. Not having the correct clock selected resulted in incorrect timing of millis() and micros(). In my test using the timestamp feature of the IDE, I saw that 500ms actually took a second, which illustrated that the default fallback clock is the 24MHz internal oscillator. Having the internal clock as automatic fallback is a nice feature, but having an IDE user changing core code should be avoided.

To make clock selection easier I modified the files boards.txt, platform.txt and system_ch32v00x.c. I now can select the clock using the menu of the Arduino IDE. I don't have other type of chips for testing, but perhaps you may want to make a similar change.


Changes made:

/packages/WCH/hardware/ch32/1.0.3/system/CH32V00x/USER/system_ch32v00x.c :
=> all clock related defines commented out

/packages/WCH/hardware/ch32/1.0.3/boards.txt :

# added Clock selection to menu
menu.clock=Clock

# added flags for Clock selection
CH32V00x_EVT.menu.clock.48MHzE=48 MHz External
CH32V00x_EVT.menu.clock.48MHzE.build.flags.clock=-DSYSCLK_FREQ_48MHz_HSE=48000000
CH32V00x_EVT.menu.clock.24MHzE=24 MHz External
CH32V00x_EVT.menu.clock.24MHzE.build.flags.clock=-DSYSCLK_FREQ_24MHz_HSE=HSE_VALUE
CH32V00x_EVT.menu.clock.8MHzE=8 MHz External
CH32V00x_EVT.menu.clock.8MHzE.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSE=8000000
CH32V00x_EVT.menu.clock.48MHz=48 MHz Internal
CH32V00x_EVT.menu.clock.48MHz.build.flags.clock=-DSYSCLK_FREQ_48MHZ_HSI=48000000
CH32V00x_EVT.menu.clock.24MHz=24 MHz Internal
CH32V00x_EVT.menu.clock.24MHz.build.flags.clock=-DSYSCLK_FREQ_24MHZ_HSI=HSI_VALUE
CH32V00x_EVT.menu.clock.8MHz=8 MHz Internal
CH32V00x_EVT.menu.clock.8MHz.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSI=8000000

/packages/WCH/hardware/ch32/1.0.3/platform.txt "

# added Clock flag to various compiler flags
compiler.S.flags={build.flags.clock} {compiler.extra_flags} -x assembler-with-cpp "-I{build.system.path}/{build.series}/SRC/Startup/" "-I{build.core.path}/ch32/"

compiler.c.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std=gnu99 -MMD {compiler.ch.extra_include}

compiler.cpp.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std={compiler.cpp.std}  -fno-threadsafe-statics  -fno-rtti -fno-exceptions -fno-use-cxa-atexit -MMD {compiler.ch.extra_include} -fpermissive

@0x0fe
Copy link

0x0fe commented Dec 12, 2023

yes that is very much needed if working with HSI. @TianpeiLee

@TianpeiLee
Copy link
Collaborator

While testing this Arduino core on my CH32V003, I found that using a bare CH32V003 TSSOP20 chip without external crystal requires a change of clock selection in system_ch32v00x.c. Not having the correct clock selected resulted in incorrect timing of millis() and micros(). In my test using the timestamp feature of the IDE, I saw that 500ms actually took a second, which illustrated that the default fallback clock is the 24MHz internal oscillator. Having the internal clock as automatic fallback is a nice feature, but having an IDE user changing core code should be avoided.

To make clock selection easier I modified the files boards.txt, platform.txt and system_ch32v00x.c. I now can select the clock using the menu of the Arduino IDE. I don't have other type of chips for testing, but perhaps you may want to make a similar change.

Changes made:

/packages/WCH/hardware/ch32/1.0.3/system/CH32V00x/USER/system_ch32v00x.c : => all clock related defines commented out

/packages/WCH/hardware/ch32/1.0.3/boards.txt :

# added Clock selection to menu
menu.clock=Clock

# added flags for Clock selection
CH32V00x_EVT.menu.clock.48MHzE=48 MHz External
CH32V00x_EVT.menu.clock.48MHzE.build.flags.clock=-DSYSCLK_FREQ_48MHz_HSE=48000000
CH32V00x_EVT.menu.clock.24MHzE=24 MHz External
CH32V00x_EVT.menu.clock.24MHzE.build.flags.clock=-DSYSCLK_FREQ_24MHz_HSE=HSE_VALUE
CH32V00x_EVT.menu.clock.8MHzE=8 MHz External
CH32V00x_EVT.menu.clock.8MHzE.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSE=8000000
CH32V00x_EVT.menu.clock.48MHz=48 MHz Internal
CH32V00x_EVT.menu.clock.48MHz.build.flags.clock=-DSYSCLK_FREQ_48MHZ_HSI=48000000
CH32V00x_EVT.menu.clock.24MHz=24 MHz Internal
CH32V00x_EVT.menu.clock.24MHz.build.flags.clock=-DSYSCLK_FREQ_24MHZ_HSI=HSI_VALUE
CH32V00x_EVT.menu.clock.8MHz=8 MHz Internal
CH32V00x_EVT.menu.clock.8MHz.build.flags.clock=-DSYSCLK_FREQ_8MHz_HSI=8000000

/packages/WCH/hardware/ch32/1.0.3/platform.txt "

# added Clock flag to various compiler flags
compiler.S.flags={build.flags.clock} {compiler.extra_flags} -x assembler-with-cpp "-I{build.system.path}/{build.series}/SRC/Startup/" "-I{build.core.path}/ch32/"

compiler.c.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std=gnu99 -MMD {compiler.ch.extra_include}

compiler.cpp.flags={build.flags.clock} {compiler.extra_flags} -c {build.flags.optimize} {build.flags.debug} {compiler.warning_flags} -std={compiler.cpp.std}  -fno-threadsafe-statics  -fno-rtti -fno-exceptions -fno-use-cxa-atexit -MMD {compiler.ch.extra_include} -fpermissive

@maxint-rd Thank you for your contribution. I am trying to verify your solution and would like to port it to another chip. I am not sure what problem has occurred here. After modifying board.txt and platform.txt, regardless of which clock is selected in the IDE, the result of running is using internal HSI. However, from the compiled log, it does appear that build.flags.clock has already taken effect when generating core. a. So, I would like to know if there is indeed no problem on your end?
image
image

@maxint-rd
Copy link
Contributor Author

maxint-rd commented May 29, 2024

@TianpeiLee : Thank you for addressing this issue. There is also PR #66 by another user that addresses the same issue.

To answer your question: as mentioned in my initial post, the system file that defines the clock setting also needed to be changed. For CH32V003 this is:
/packages/WCH/hardware/ch32/1.0.3/system/CH32V00x/USER/system_ch32v00x.c

In my local version I commented out all clock related defines. As a global solution it may be better to use some #ifdef 's. For my CH32V003 this worked just fine. Unfortunately I don't have any other member of the CH32 family to check this out. While debugging the V003 behavior I did notice the code to follow to interesting steps. Perhaps these are different for other CH32 MCU's.

Finally: I read in another post that your contributions are all done in your spare time. I really appreciate your commitment to maintain this core. Thank you!
I also regret that WCH is not dedicating a budget to support this Arduino core. Maybe WCH doesn't see the commercial gain of helping thousands of developers use this very nice CH32 family of chips. For me having such an affordable processor allowed me to do experiments on using it in project that I normally would not dare to do.

@TianpeiLee
Copy link
Collaborator

@maxint-rd Thank you for your reply,before testing, I had already commented out the relevant definitions in system_ch32v00x.c, but I still cannot implement clock switching function

@maxint-rd
Copy link
Contributor Author

Hmmm... does it work for you on the CH32V003, but not for the others?
If it also doesn't work for the V003 I suggest you to test PR #66
Unfortunately I don't have any other CH32 family members to test.

P.S. Thank you so much for maintaining this core. I really like using the CH32V003 and perhaps will also try some other family members. If you're interested I can also submit PR's for some other core improvements that I only tested for the V003. In my fork of this core you can find branches to implement I2C slave support, an EEPROM emulation library and some other things.

@TianpeiLee
Copy link
Collaborator

I tested it on 003 and found that it is only effective for 24M and 8M. Observing the registers, I found that the values of the registers were not set correctly when selecting 48M. I think it should be a hidden small issue , although I haven't found it yet.

I am very happy for you to submit a PR's for this repository to improve it, that's really great!

I am planning to add the CH32V006 series, which is more like an enhanced 003 and supports hardware multiplication(RV32EC_Zmmul_xw extension). https://www.wch-ic.com/downloads/CH32V006DS0_PDF.html
image
I think many people will be interested in it. Currently, the toolchain on the official website does not support it. I am currently adding some basic peripheral library files and compiling it in the 003 compilation environment.

@maxint-rd
Copy link
Contributor Author

Okay, I looked again at your screenshot. Maybe your problem is something small indeed. The person that submitted PR #66 noticed inconsistencies in capitalization and he corrected that too. Note the inconsistent use of capital Z versus lower case z in the MHz/MHZ definition of DSYSCLK_FREQ_48MHZ_HSI and DSYSCLK_FREQ_8MHz_HSI.
Since 24MHz is the default clock I suspect your 48MHz selection isn't propagated properly. Can you look at that?

BTW. That V006 is certainly ingeresting. In my latest projects the main limitation of the V003 was use of flash memory. The 16MB got full quickly, often requiring me to disable features, or not be able to debug.
I also noted that the LTO had issues, making flash more limiting (see my comment in issue #51 ):

Latest hold-up was that somehow my I2C configuration application doesn't start when using -Os with LTO (Link Time Optimization), which is weird. It did work in Arduino IDE 1.8.19 with an older core, but in IDE v2.3.2 with core 1.4 it only works without LTO. Still need to test more variations and another sketch to see if my changes caused this.

Edit: even the simple basic Blink example doesn't run with LTO, not for smallest (-Os) nor fastest (-O3). Without LTO these same options run fine. Weird!

Does anyone else have issues with LTO?

@TianpeiLee
Copy link
Collaborator

Oh, thank you very much. Yes, I noticed the issue with the capitalization of that letter, and now everything is normal. I am updating it to another chip.

The "LTO" option in gcc seems to overly optimize the code under risc-v, causing program exceptions. Currently, this issue has not been resolved. If the Arduino IDE can generate a list file, it may be easier to find problems from assembly code.

@TianpeiLee
Copy link
Collaborator

It will be enabled in the next update

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

No branches or pull requests

3 participants