CommunityGD32Cores / gd32-pio-projects

PlatformIO test projects for the new GD32 platform and arduino core
42 stars 10 forks source link

Blink speed in gd32-spl-blinky seems incorrect #11

Closed crosswick closed 8 months ago

crosswick commented 8 months ago

Hi, I was wondering whether the blink speed is supposed to be accurate? From the code it seems like the LED is toggled off and on with a combined period of 200 ms; in reality I measure about 900 ms.

GPT-4 says this about it, perhaps useful:

image

maxgerhardt commented 8 months ago

The delay should be about as accurate as the time clock. It uses the SysClk to setup interrupts every one millisecond, which decrements a global variable. The delay loop then simply waits for that variable to be zero again. So it should be accurate to about 1 millisecond.

Can you post which exact environment ([env:xxxx]) you are using in the project, and what exact board you have (Microcontroller, quartz crystal's speed if present)?

crosswick commented 8 months ago

It's a GD32E103CBT6 on this board with a 8.000 (GHz?) crystal:

image

using the genericGD32E103CB environment.

maxgerhardt commented 8 months ago

I see. so it has an 8MHz crystal on it. Per default clock settings, that should match, since that expects a 8MHz crystall and PLL-boosts the clock rate to 120MHz (div by 2, mul by 30).

Can you do the following:

  1. Set a breakpoint in src/main.c at this line: https://github.com/CommunityGD32Cores/gd32-pio-projects/blob/10804f14f622a19ba0c93d67cd84b60c4a613e27/gd32-spl-blinky/src/main.c#L77C24-L77C40
  2. Start debugging in the "PIO Debug" configuration
  3. Read the value of SystemCoreClock. Is it 120000000?
crosswick commented 8 months ago

Ah, time to get my debug setup working then I guess :) thanks, I'll investigate and get back

maxgerhardt commented 8 months ago

If that is too complicated, simply try adding

build_flags = -D__SYSTEM_CLOCK_120M_PLL_IRC8M

to the platformio.ini and reupload. That should make it use the internal oscillator instead of relying on the quartz.

crosswick commented 8 months ago

If that is too complicated, simply try adding

build_flags = -D__SYSTEM_CLOCK_120M_PLL_IRC8M

to the platformio.ini and reupload. That should make it use the internal oscillator instead of relying on the quartz.

this makes the LED not blink at all anymore

crosswick commented 8 months ago

little video of the current blink speed

https://github.com/CommunityGD32Cores/gd32-pio-projects/assets/526402/e174a1f4-c8fb-4fc8-a1e6-07c0efeb6850

crosswick commented 8 months ago

Ah, I've started debugging and although I can't find the SystemCoreClock value, it does then blink way faster

edit: and I do measure it as 200 ms

maxgerhardt commented 8 months ago

You should be able to press the "Pause" button in the debugger and then add SystemCoreClock to the "Watches" section in the left side to see the variable's current value.

I will shortly test this on my own board.

build_flags = -D__SYSTEM_CLOCK_120M_PLL_IRC8M

That should also not be happening. Will investigate why.

crosswick commented 8 months ago

I see... when I add SystemCoreClock though it says it's not available , also after pressing Continue in the debugger

crosswick commented 8 months ago

Not sure if this is relevant, but just so you know: I’m using PlatformIO within a fork of VS Code called Cursor

maxgerhardt commented 8 months ago

I see... when I add SystemCoreClock though it says it's not available

Default optimization level (-Og) might be too aggressive. Add

debug_build_flags = -O0 -g3 -ggdb

to the platformio.ini and debug again. It should now not optimize away anything.

crosswick commented 8 months ago

I see - then I do get a value of 120000000. The LED does not blink anymore btw, either in Pause or Continue state

crosswick commented 8 months ago

...and when I stop the debugging sessing the LED blinks with 200ms interval

and when I then again upload the firmware it's back to 900ms again

maxgerhardt commented 8 months ago

I have a commercial GD32E103C8 board with 8MHz quartz (so very close to your CB one) and I can say the following:

  1. With all default settings, when I change the delay time to 1000ms in the code, I also see 1000ms in the blink behavior. So there are no timing mismatches
  2. build_flags = -D__SYSTEM_CLOCK_120M_PLL_IRC8M indeed makes the LED stop but that's because it expects the macro's value to be the clock speed. So, it has to be build_flags = -D__SYSTEM_CLOCK_120M_PLL_IRC8M=120000000UL. I tested that to work and blinks at the same rate as before.
  3. I tested both clock settings (default and irc8m per above) with build_type = debug and build_type = release. It did not make a difference, the same blink rate is output in both release and debug optimization.

Signal when using internal clock (variants expected):

grafik

Signal when using external clock (default settings, accurate to under one 1ms as expected):

grafik

Can you please provide the following info:

My board: grafik

crosswick commented 8 months ago

Thanks, my OS is macOS Monterey 12.6.6.

I can test the 4 variations later if needed, but I think I've found the culprit: the missing BOOT jumper on my board... perhaps you know why this would make this difference? With it present on the 0 position the timing is normal.

maxgerhardt commented 8 months ago

Well if you don't have the jumper in place, the BOOT0 pin of the MCU might float, so you might randomly go into bootloader mode.. But it would be too much of a coincidence if the bootloader also had a blinky 900ms code.

crosswick commented 8 months ago

Right :) but perhaps this floating causes some condition where the basic system timing is thrown off...

crosswick commented 8 months ago

Thanks again for the super swift assistance Max! So great to have all this GD32-related support.