Skip to content

[BUG] Clock div for peri_clock seems not to be working #1037

@nicolube

Description

@nicolube

Hallo there,

I'll expect the clock div for the clock_peri not to be working correctly.

Test case 1:
clock_sys = src <- PLL_USB, src_freq <- 48MHz, target_freq <- 8MHz: works
clock_peri = src <- clock_sys, src_freq <- 8MHz, target_freq <- 8MHz: works

Test case 2:
clock_sys = src <- PLL_USB, src_freq <- 48MHz, target_freq <- 48MHz: works
clock_peri = src <- clock_sys, src_freq <- 48MHz, target_freq <- 8MHz: does not work

I tested test case 2 with 24Mhz, 8MHz and 1 MHz and non of the seems to set the target freq correctly.
Also tried to change the clock src for the clock_peri to PLL_USB also does not work.

As i understand it from the datasheet the clock div for the clock_peri should work as the clock div for the clock_sys
but this seems not to be the case, the peri_clock is unchanged after the the reconfig.

Test code:

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pll.h"
#include "hardware/clocks.h"
#include "hardware/structs/pll.h"
#include "hardware/structs/clocks.h"
#include "hardware/pwm.h"

void measure_freqs(void)
{
    uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);
    uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);
    uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);
    uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
    uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);
    uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);
    uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);
    uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);

    printf("pll_sys  = %dkHz\n", f_pll_sys);
    printf("pll_usb  = %dkHz\n", f_pll_usb);
    printf("rosc     = %dkHz\n", f_rosc);
    printf("clk_sys  = %dkHz\n", f_clk_sys);
    printf("clk_peri = %dkHz\n", f_clk_peri);
    printf("clk_usb  = %dkHz\n", f_clk_usb);
    printf("clk_adc  = %dkHz\n", f_clk_adc);
    printf("clk_rtc  = %dkHz\n", f_clk_rtc);

    // Can't measure clk_ref / xosc as it is the ref
}

int main()
{
    stdio_init_all();

    printf("Hello, world!\n");

    measure_freqs();

    // Change clk_sys to be 48MHz. The simplest way is to take this from PLL_USB
    // which has a source frequency of 48MHz
    clock_configure(clk_sys,
                    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
                    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
                    48 * MHZ,
                    48 * MHZ);

    // Turn off PLL sys for good measure
    pll_deinit(pll_sys);

    // CLK peri is clocked from clk_sys so need to change clk_peri's freq
    clock_configure(clk_peri,
                    0,
                    CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
                    48 * MHZ,
                    8 * MHZ);

    // Re init uart now that clk_peri has changed
    stdio_init_all();

    measure_freqs();
    printf("Hello, 48MHz");

    return 0;
}

Output with default baud of 115200

Hello, world!
pll_sys  = 125000kHz
pll_usb  = 48000kHz
rosc     = 5605kHz
clk_sys  = 125000kHz
clk_peri = 125000kHz
clk_usb  = 48000kHz
clk_ad▒▒▒ge#▒a'e#%s▒e#%▒c'▒3

Output when baudrate is set to a 1/6 of the default speed after the second stdio_init_all();

    // Re init uart now that clk_peri has changed
    stdio_init_all();
    // Fixes baudrate form unchanged clock. 48MHz / 8MHz = 6
    uart_set_baudrate(uart0, 115200/6);

First measure_freqs() cuts of because uart is not done printing until the clocks is re-configuring

Hello, world!
pll_sys  = 125000kHz
pll_usb  = 48000kHz
rosc     = 5612kHz
clk_sys  = 125000kHz
clk_peri = 125000kHz
clk_usb  = 48000kHz
clk_ad▒pll_sys  = 0kHz
pll_usb  = 48000kHz
rosc     = 5621kHz
clk_sys  = 48000kHz
clk_peri = 48000kHz
clk_usb  = 48000kHz
clk_adc  = 48000kHz
clk_rtc  = 47kHz
Hello, 48MHz

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions