跳转至

动态调整频率*

本文主要介绍了如何调整硬件模块的频率。 芯片的 CPU、NPU、Flash、Sram 模块的输入时钟都来自 PLL。

1. PLL 配置:*

注意

注意 pll 的时钟配置只能上电配置一次,具体源码见: boards/nationalchip/grus_gx8002b_dev_1v/clock_board.c

1.1 PLL 24M 配置*

  • 参考如下代码完成 PLL 24M 配置:
    boards/nationalchip/grus_gx8002b_dev_1v/clock_board.c
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static GX_CLOCK_PLL pll = {
        .pll_enable      = 1,
    
        .pll_in          = 32768,
        .pll_fvco        = 98304000,
        .pll_out         = 24576000,
    
        .pll_div_in      = 0,
        .pll_div_fb      = 3071,
        .pll_icpsel      = 2,
        .pll_bwsel_lpf   = 0,
        .pll_vco_subband = 3,
        .pll_div_out     = 1,
    
        .pll_itrim       = 0,
        .pll_vco_trim    = 4,
        .pll_2nd3nd_lpf  = 0,
        .pll_lock_tiehi  = 0,
    };
    gx_clock_set_pll(&pll);
    

1.2 PLL 50M 配置*

  • 参考如下代码完成 PLL 50M 配置:
    boards/nationalchip/grus_gx8002b_dev_1v/clock_board.c
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static GX_CLOCK_PLL pll = {
        .pll_enable      = 1,
    
        .pll_in          = 32768,
        .pll_fvco        = 98304000,
        .pll_out         = 49152000,
    
        .pll_div_in      = 0,
        .pll_div_fb      = 3071,
        .pll_icpsel      = 2,
        .pll_bwsel_lpf   = 0,
        .pll_vco_subband = 3,
        .pll_div_out     = 0,
    
        .pll_itrim       = 0,
        .pll_vco_trim    = 4,
        .pll_2nd3nd_lpf  = 0,
        .pll_lock_tiehi  = 0,
    };
    gx_clock_set_pll(&pll);
    

2 动态调整频率*

  • 所有的频率调整都是通过如下函数进行调整。

    include/driver/gx_clock/gx_clock_v2.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
     * @brief DIV分配配置
     *
     * @param module 时钟模块名,详细说明请参考 GX_CLOCK_MODULE
     * @param div    整数分频
     *
     * @return 无返回值
     */
    void gx_clock_set_div(GX_CLOCK_MODULE module, int div)
    

    注意

    div 的值为 PLL 频率 除以 目标频率,并且取整

2.1 动态调整 CPU 频率*

  • PLL 50M 情况下, CPU 频率调整为 8M
    1
    gx_clock_set_div(CLOCK_MODULE_SCPU, 6)
    
  • PLL 24M 情况下, CPU 频率调整为 8M

    1
    gx_clock_set_div(CLOCK_MODULE_SCPU, 3)
    

    获取 CPU 频率

    int cpu_fre = gx_clock_get_module_frequence(CLOCK_MODULE_SCPU);

2.2 动态调整 NPU 频率*

  • PLL 50M 情况下, NPU 频率调整为 8M
    1
    gx_clock_set_div(CLOCK_MODULE_NPU, 6)
    
  • PLL 24M 情况下, NPU 频率调整为 8M

    1
    gx_clock_set_div(CLOCK_MODULE_NPU, 3)
    

    获取 NPU 频率

    int npu_fre = gx_clock_get_module_frequence(CLOCK_MODULE_NPU);

2.3 动态调整 Flash 频率*

  • PLL 50M 情况下, Flash 频率调整为 50M
    1
    gx_clock_set_div(CLOCK_MODULE_FLASH_SPI, 1)
    
  • PLL 24M 情况下, Flash 频率调整为 24M

    1
    gx_clock_set_div(CLOCK_MODULE_FLASH_SPI, 1)
    

    获取 Flash 频率

    int flash_fre = gx_clock_get_module_frequence(CLOCK_MODULE_FLASH_SPI);

2.4 动态调整 Sram 频率*

  • PLL 50M 情况下, Sram 频率调整为 25M
    1
    gx_clock_set_div(CLOCK_MODULE_SRAM, 2)
    
  • PLL 24M 情况下, Sram 频率调整为 12M

    1
    gx_clock_set_div(CLOCK_MODULE_SRAM, 2)
    

    获取 Sram 频率

    int sram_fre = gx_clock_get_module_frequence(CLOCK_MODULE_SRAM);

注意

  • 建议先调用 unsigned int state = gx_lock_irq_save() 获取当前中断状态并关闭中断,再调用 gx_clock_set_div(GX_CLOCK_MODULE module, int div) 进行调频,调频过程是瞬时的,接口运行结束即表示调频完成,最后调用 gx_unlock_irq_restore(state) 恢复当前保存的中断。

  • 可以参考:lvp/common/lvp_system_init.c 中的接口 LvpDynamiciallyAdjustCpuFrequency

  • unsigned int gx_clock_get_module_frequence(GX_CLOCK_MODULE module) 此接口用于获取模块时钟频率