diff --git a/boards/common/atmega/board.c b/boards/common/atmega/board.c index ef349c737f62..01c58b31ddc3 100644 --- a/boards/common/atmega/board.c +++ b/boards/common/atmega/board.c @@ -23,10 +23,15 @@ #include "irq.h" #include "periph/gpio.h" +#ifndef CPU_ATMEGA_CLK_SCALE_INIT +#define CPU_ATMEGA_CLK_SCALE_INIT CPU_ATMEGA_CLK_SCALE_DIV1 +#endif + void led_init(void); void board_init(void) { + atmega_set_prescaler(CPU_ATMEGA_CLK_SCALE_INIT); atmega_stdio_init(); cpu_init(); led_init(); diff --git a/cpu/atmega_common/include/cpu.h b/cpu/atmega_common/include/cpu.h index 0fc6a078ae85..84d64f0f7f03 100644 --- a/cpu/atmega_common/include/cpu.h +++ b/cpu/atmega_common/include/cpu.h @@ -92,6 +92,37 @@ __attribute__((always_inline)) static inline void cpu_print_last_instruction(voi printf("Stack Pointer: 0x%04x\n", ptr); } +/** + * @brief ATmega system clock prescaler settings + * + * Some CPUs may not support the highest prescaler settings + */ +enum { + CPU_ATMEGA_CLK_SCALE_DIV1 = 0, + CPU_ATMEGA_CLK_SCALE_DIV2 = 1, + CPU_ATMEGA_CLK_SCALE_DIV4 = 2, + CPU_ATMEGA_CLK_SCALE_DIV8 = 3, + CPU_ATMEGA_CLK_SCALE_DIV16 = 4, + CPU_ATMEGA_CLK_SCALE_DIV32 = 5, + CPU_ATMEGA_CLK_SCALE_DIV64 = 6, + CPU_ATMEGA_CLK_SCALE_DIV128 = 7, + CPU_ATMEGA_CLK_SCALE_DIV256 = 8, + CPU_ATMEGA_CLK_SCALE_DIV512 = 9, +}; + +/** + * @brief Initializes system clock prescaler + */ +static inline void atmega_set_prescaler(uint8_t clk_scale) +{ + /* Enable clock change */ + /* Must be assignment to set all other bits to zero, see datasheet */ + CLKPR = (1 << CLKPCE); + + /* Write clock within 4 cycles */ + CLKPR = clk_scale; +} + /** * @brief Initializes avrlibc stdio */