Wrong clockspeed when using MegaCoreX

When selecting a clockspeed in the Tools menu, you'd expect the processor to run at that speed.
It doesn't.
I selected 'Internal 16 MHz' and this is what I had to do to get it working:

volatile uint32_t a = 65550;
volatile uint32_t b = 65560;

int main() {
  Serial.begin(115200);  // uses #defined F_CPU, not actual clock speed
  Serial.println("WrongClockspeed");
  CCP = CCP_IOREG_gc;
  CLKCTRL.MCLKCTRLB = 0;  // won't run at desired clock speed without this

  uint32_t p1 = a * b / 100;                  // expected to overflow 32 bits number
  uint32_t p2 = a * b / 100.0;                // expected to calculate in float
  uint32_t p3 = float(a) * float(b) / 100.0;  // sure to calculate in float
  Serial.println("ImplicitConversion");
  Serial.print("p1 ");
  Serial.print(p1);
  Serial.print("  p2 ");
  Serial.print(p2);
  Serial.print("  p3 ");
  Serial.println(p3);
  Serial.flush();
  return 0;
}

Yes i would also expect it to do that but only if the core is written to use it. With MegaCoreX, the Tools -> Clock (or similarly named) menu does set the CPU clock if that option is implemented in the core’s boards.txt and build system.

I would if I were using the setup() / loop() structure expected for an Arduino sketch. If you are going to define your own main() function, then you will need to do the housekeeping yourself.

Here is the main() function from MegaCoreX:

  1 /*
  2   main.cpp - Main loop for Arduino sketches
  3   Copyright (c) 2005-2013 Arduino Team.  All right reserved.
  4 
  5   This library is free software; you can redistribute it and/or
  6   modify it under the terms of the GNU Lesser General Public
  7   License as published by the Free Software Foundation; either
  8   version 2.1 of the License, or (at your option) any later version.
  9 
 10   This library is distributed in the hope that it will be useful,
 11   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13   Lesser General Public License for more details.
 14 
 15   You should have received a copy of the GNU Lesser General Public
 16   License along with this library; if not, write to the Free Software
 17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18 */
 19 
 20 #include <Arduino.h>
 21 
 22 // Declared weak in Arduino.h to allow user redefinitions.
 23 int atexit(void (* /*func*/)()) { return 0; }
 24 
 25 void setupUSB() __attribute__((weak));
 26 void setupUSB() {}
 27 
 28 int main(void)
 29 {
 30   init();
 31 
 32   initVariant();
 33 
 34 #if defined(USBCON)
 35   USBDevice.attach();
 36 #endif
 37 
 38   setup();
 39 
 40   for (;;)
 41   {
 42     loop();
 43     if (serialEventRun) serialEventRun();
 44   }
 45 
 46   return 0;
 47 }

I just tested it with selecting 'Internal 8 MHz'.
In this case, MegaCoreX does set the main clock prescaler.
Why not for 'Internal 16 MHz'?

volatile uint32_t a = 65550;
volatile uint32_t b = 65560;

void setup() {
  Serial.begin(115200);  // uses #defined F_CPU, not actual clock speed
  Serial.println("WrongClockspeed?");

  uint32_t p1 = a * b / 100;                  // expected to overflow 32 bits number
  uint32_t p2 = a * b / 100.0;                // expected to calculate in float
  uint32_t p3 = float(a) * float(b) / 100.0;  // sure to calculate in float
  Serial.println("ImplicitConversion");
  Serial.print("p1 ");
  Serial.print(p1);
  Serial.print("  p2 ");
  Serial.print(p2);
  Serial.print("  p3 ");
  Serial.println(p3);
  Serial.flush();
}

void loop() {}

Hi @stitech. It seems that you may be performing an "apples to oranges" comparison here.

In post #1, where you reported unexpected behavior from the "Internal 16 MHz" setting, the sketch you presented overrides the main function defined by the MegaCoreX core. In your post #4 demonstrating that functionality is as expected with the "Internal 8 MHz" setting, you have not overridden main.

What happens if you select the "Internal 16 MHz" setting and then upload the sketch from post #4?

Setting the main clock prescaler happens in 'wiring.c'.

Apparently the developer or MegaCoreX was comfortable with depending on that, instead of doing it himself.
I chose MegaCoreX to be independent of Wiring, not waking up the processor every millisecond (it actually doesn't, TCA0 doesn't run when sleeping, ruining the timing system), able to use TCB3, getting rid of more than thousand bytes of code in FLASH, etc.

It's not a big problem to set the prescaler myself, I just expected selecting the clockspeed in the menu would be sufficient.
The sheer number of items in the menu suggests they do something.

Here you can see the platform properties that are defined when you select the "Internal 16 MHz" option:

and here when you select the "Internal 8 MHz" option:

Here you can see the bootloader.OSCCFG property is referenced in the upload command template:

And of course the build.f_cpu property is referenced in the definition of the F_CPU macro in the compilation command templates: