Slow down system clock

When a board shall run on reduced clock frequency, by using the prescaler or external clock source (32kHz), what has to be done so that the timing of e.g. ADC, UART, millis() etc. will stay correct?

Can proper timing be accomplished by modifications to the standard pins_arduino.h, or how else?
Only setting the prescaler mode in code will cause trouble :frowning:

What about uploading sketches to such a system, using ISP?
I'd assume that here the internal RC clock is used, unaffected by other clock sources and settings?

All things which use system clock will be affected if the frequency is changed: USART, millis...
The pins_arduino.h has nothing with this.It defines MCU's port mapping to the Arduino. The frequency is defined in the boards.txt. If such board doesn't exists, it can be created/modified. Howewer, it has an impact to the program which must be compiled for specific frequency and also to the bootloader too. Programming via ISP should be fine.

EDIT: Clock source is defined by fuses. Internal oscillator can be chosen also, of course. The clock source is system wide. Only Timer/Counter2 (on ATmega) can have different clock source from the system clock. ATmega328P shares the pins for external system clock source and RTC so if the TC2 have to use 32kHz for timekeeping, system clock has to be the same or internal.

I.e. the prescaler setting is not supported/reflected in the standard libraries? :frowning:

Will it help to change the clock frequency in boards.txt, and to set the prescaling factor (in CLKPR) in setup()?
Or am I missing means to change the prescaler mode or factor in boards.txt?

No, you have to change also fuses. First, send what exactly you want to do and what is your HW. I think, you are trying some advanced technique which is not supported by Arduino. No problem, maybe, but provide detailed info.

I think you are talking about this, which should be changeable on the fly by changing a register, and not fuses or other setting files:

9.11 System Clock Prescaler
The ATmega48A/PA/88A/PA/168A/PA/328/P has a system clock prescaler, and the system clock can be
divided by setting the ”CLKPR – Clock Prescale Register” on page 377. This feature can be used to decrease
the system clock frequency and the power consumption when the requirement for processing power is low. This
can be used with all clock source options, and it will affect the clock frequency of the CPU and all synchronous
peripherals. clkI/O, clkADC, clkCPU, and clkFLASH are divided by a factor as shown in Table 29-11 on page 305.

When switching between prescaler settings, the System Clock Prescaler ensures that no glitches occurs in the
clock system. It also ensures that no intermediate frequency is higher than neither the clock frequency
corresponding to the previous setting, nor the clock frequency corresponding to the new setting. The ripple
counter that implements the prescaler runs at the frequency of the undivided clock, which may be faster than the
CPU's clock frequency. Hence, it is not possible to determine the state of the prescaler - even if it were
readable, and the exact time it takes to switch from one clock division to the other cannot be exactly predicted.

From the time the CLKPS values are written, it takes between T1 + T2 and T1 + 2 * T2 before the new clock
frequency is active. In this interval, 2 active clock edges are produced. Here, T1 is the previous clock period,
and T2 is the period corresponding to the new prescaler setting.

To avoid unintentional changes of clock frequency, a special write procedure must be followed to change the
CLKPS bits:
1. Write the Clock Prescaler Change Enable (CLKPCE) bit to one and all other bits in CLKPR to zero.
2. Within four cycles, write the desired value to CLKPS while writing a zero to CLKPCE.
Interrupts must be disabled when changing prescaler setting to make sure the write procedure is not interrupted.

My current concern is of the prescaler only. The fuses for the selection of the right clock source are left to the board developer. He seems to have managed the change of the prescaling factor already, but then reports problems with the all related settings (baudrate...).

He also reports a problem with the ADC returning values only in the range 0-127. Could this really be related to the prescaled clock?

Yes, if CLKPR is changed. Look at the reading in CrossRoads's post.

The Arduino standard libraries do not correct for changes to the clock prescaler. This is an advanced functionality (one which is rarely worth doing, either, as it happens - especially considering these sorts of issues). Your code must make appropriate adjustments to the ADC registers in order to get the ADC back running within it's allowed parameters, and also anywhere where you're setting a baud rate. And millis() and delay() will run at the wrong speed too.