[imx6ull]主频与时钟 & AHB_CLK_ROOT无法修改分频系数的解决

忙里偷着看看imx6ull,时钟设置比2440复杂多了

2021/11/27

主频与时钟

来看一下,不多赘述,就是看手册配置寄存器

image.png

配置时钟主频时钟看图配置寄存器就好,总结一句话哪里不会看手册,还是不会继续看手册。

AHB_CLK_ROOT无法修改分频系数的解决

看了正点原子的例程,说是无法修改,网上搜索了一下,找到了一篇关于这个文章的说明,提供了一下解题思路,最初对正点原子的话还是比较相信的,有些东西还是保持客观吧,不能太相信

关于AHB_CLK_ROOT无法修改分频系数的解决_ztm3726的博客-CSDN博客

上面的文章最有参考价值的就是查找nxp官方代码,并且解决了为什么无法修改,主要原因还是,不能直接操作寄存器进行清0

image.png

清0,就是分频1,也就是不分频,显然超了132Mhz,这也就是为什么死机的原因

nxp官方代码 clock_config_ocram.c

 1/* Configure PFD_528
 2     * PFD0     : Disable, set divider 27 352M
 3     * PFD1     : Disable, set divider 16 594M
 4     * PFD2     : Enable, set divider 24 396M
 5     * PFD3     : Disable, set divider 48 198M
 6     */
 7    /* Disable all clock output first. */
 8    CCM_ANALOG->PFD_528 |= CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD1_CLKGATE_MASK |
 9                           CCM_ANALOG_PFD_528_PFD2_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD3_CLKGATE_MASK;
10    /* Set default divide value for all PFD. */
11    CCM_ANALOG->PFD_528 = (CCM_ANALOG->PFD_528 &
12                           ~(CCM_ANALOG_PFD_528_PFD0_FRAC_MASK | CCM_ANALOG_PFD_528_PFD1_FRAC_MASK |
13                             CCM_ANALOG_PFD_528_PFD2_FRAC_MASK | CCM_ANALOG_PFD_528_PFD3_FRAC_MASK)) |
14                          CCM_ANALOG_PFD_528_PFD0_FRAC(0x1B) | CCM_ANALOG_PFD_528_PFD1_FRAC(0x10) |
15                          CCM_ANALOG_PFD_528_PFD2_FRAC(0x18) | CCM_ANALOG_PFD_528_PFD3_FRAC(0x30);
16    /* Enable PFD_528 PFD2*/
17    CCM_ANALOG->PFD_528 &= ~CCM_ANALOG_PFD_528_PFD2_CLKGATE_MASK;
18
19    /* Configure PFD_480
20     * PFD0     : Disable, set divider 12 720M
21     * PFD1     : Disable, set divider 16 540M
22     * PFD2     : Disable, set divider 17 508.2M
23     * PFD3     : Disable, set divider 19 454.7M
24     */
25    /* Disable all clock output. */
26    CCM_ANALOG->PFD_480 |= CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD1_CLKGATE_MASK |
27                           CCM_ANALOG_PFD_480_PFD2_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD3_CLKGATE_MASK;
28    /* Set default divide value for all PFD. */
29    CCM_ANALOG->PFD_480 = (CCM_ANALOG->PFD_480 &
30                           ~(CCM_ANALOG_PFD_480_PFD0_FRAC_MASK | CCM_ANALOG_PFD_480_PFD1_FRAC_MASK |
31                             CCM_ANALOG_PFD_480_PFD2_FRAC_MASK | CCM_ANALOG_PFD_480_PFD3_FRAC_MASK)) |
32                          CCM_ANALOG_PFD_480_PFD0_FRAC(0xC) | CCM_ANALOG_PFD_480_PFD1_FRAC(0x10) |
33                          CCM_ANALOG_PFD_480_PFD2_FRAC(0x11) | CCM_ANALOG_PFD_480_PFD3_FRAC(0x13);
34
35    /* Configure BUS clcok
36     * AHB     : Sourced from SYS PLL PFD2 396M with divider 3 132M
37     * IPG     : Sourced from AHB with divider 2 66M
38     * AXI     : Sourced from SYS PLL PFD2 396M with divider 2 198M
39     * MMDC    : Sourced from SYS PLL PFD2 396M with divider 1 396M
40     */
41
42    /* Set pre_periph2_clk and pre_periph_clk MUX to SYS PLL PFD2*/
43    CCM->CBCMR = (CCM->CBCMR & ~(CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK | CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)) |
44                 CCM_CBCMR_PRE_PERIPH_CLK_SEL(1) | CCM_CBCMR_PRE_PERIPH2_CLK_SEL(1);
45
46    /* Set periph2_clk and periph_clk MUX to PLL2*/
47    CCM->CBCDR = (CCM->CBCDR & ~(CCM_CBCDR_PERIPH2_CLK_SEL_MASK | CCM_CBCDR_PERIPH_CLK_SEL_MASK)) |
48                 (CCM_CBCDR_PERIPH2_CLK_SEL(0) | CCM_CBCDR_PERIPH_CLK_SEL(0));
49    /* Config AXI divide by 2, AHB divide by 3, IPG divide by 2, MMDC divide by 1*/
50    CCM->CBCDR =
51        (CCM->CBCDR &
52         ~(CCM_CBCDR_AXI_PODF_MASK | CCM_CBCDR_AHB_PODF_MASK | CCM_CBCDR_IPG_PODF_MASK |
53           CCM_CBCDR_FABRIC_MMDC_PODF_MASK)) |
54        (CCM_CBCDR_AXI_PODF(1) | CCM_CBCDR_AHB_PODF(2) | CCM_CBCDR_IPG_PODF(1) | CCM_CBCDR_FABRIC_MMDC_PODF(0));
55    /* Wait handshake process */
56    while (CCM->CDHIPR &
57           (CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY_MASK | CCM_CDHIPR_PERIPH_CLK_SEL_BUSY_MASK | CCM_CDHIPR_AXI_PODF_BUSY_MASK |
58            CCM_CDHIPR_AHB_PODF_BUSY_MASK | CCM_CDHIPR_MMDC_PODF_BUSY_MASK))
59    {
60    }

为什么我要复制这么多,还有一个问题要解决,就是正点原子讲错了一个地方,真的容易误导别人

看上面代码这

1/* Enable PFD_528 PFD2*/
2    CCM_ANALOG->PFD_528 &= ~CCM_ANALOG_PFD_528_PFD2_CLKGATE_MASK;

都要进行下面的podf修改了,这里还非要打开时钟,这里的时钟就是下面AHB要用到的PLL2 的PFD2,显然nxp不傻,这个后面说。

分析上面的代码就知道,解决的办法就是:

修改

  • 读取该寄存器12-10位值
  • 清零并赋值
  • 写回到寄存器

代码如下 CCM->CBCDR = ((CCM->CBCDR & ~(7 << 10)) | (2 << 10));

根本原因就是不能直接在寄存器上赋值

修改 AHB_CLK_ROOT 无需关闭时钟

这就是最大的误导,我直接上手册内容啪啪打正点原子的脸,当然这是开个玩笑

官方手册651页,我直接贴图了

image.png

对于上面的英文,我不想翻译,还是说说吧,主要意思是 修改下面的值就要握手,没毛病,看代码是握手了,其实这就ok了

第二段 For dividers without a handshake design, the following sequence must be performed when updating PODF value:

对于没有握手的,更新pidf值,必须要进行下面的两个操作,上面意思大家都懂吧

意思就是说 你握手了,就不需要关闭时钟,你不握手,you must close clock !

这里就与nxp官方代码对上了,说实话正点原子真的误导人,不需要关闭时钟源

总结

对于设置时钟没啥好说的,照做就是,最大的感受就是哪里不会看手册,。说实话网上的话不一定对,要有辨别能力,网上资料太少,那就多看手册

论英语的重要性!


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消