s3c2440的时钟体系

来源:互联网 发布:奥迪工程师软件 编辑:程序博客网 时间:2024/05/17 07:26

学习:韦东山ARM裸机开发实战(第一期加强版)时钟部分


S3C2440的时钟&电源管理模块(Clock & Power management block)由三部分组成:时钟控制器(Clock control )、USB控制器(USB control)和电源控制器(Power control)。S3C2440的时钟控制逻辑能够生产系统必需的时钟信号,包括CPU所需的FCLK时钟、AHB总线外设所需的HCLK时钟、APB总线外设所需的PCLK时钟。S3C2440的时钟系统中有两个锁相环(PLLS),分别为MPLLUPLLMPLL用于FCLKHCLKPCLKUMLL专门用于USB48MHz)。S3C2440的时钟控制逻辑可以不使用PLL下降低时钟,通过软件来连接/断开到每个外设的时钟,这能够降低功耗。

通过电源控制逻辑(power control logic ),S3C2440有多方面的电源管理方案去优化功耗(power consumption),四种模式:正常模式(NORMAL mode)、低速模式(SLOW mode,空闲模式(IDLE mode),睡眠模式(SLEEP mode)。



FCLK最高可达400Mhz,因此s3c2440CPU最高可以运行400MHz下工作。



引脚OM[3:2] 控制主时钟和USB时钟的来源。JZ2440OM[3:2]两个引脚接地。



OSC接外部晶振(12M),经过OM[3:2]选择器,OM[3:2]=00(OM[3:2]两个引脚接地),进入MPLL锁相环,在MPLL中通过三个计算因子(PMS)按照一定公式输出MPLL时钟,MPLL时钟经过 CLKCNTL 模块输出系统所需的FCLKHCLKPCLKFLCK直接等于MPLL时钟,HCLK通过MPLL时钟的HDIVN分频得到,PCLK通过MPLL时钟的PDIVN分频得到。FCLKHCLKPCLK通过POWCNTL模块送往系统的各个外设。



先看看这张图,系统上电时,复位引脚没有马上拉高,等到上电电压稳定后复位引脚拉高。这个过程由硬件来完成,JZ2440的硬件设计中复位引脚连接复位芯片来完成这个过程。晶振(12M)起振,这个时候FCLK等于晶振频率12Mhz,如果设置PLL,会有一个”Lock Time”,这时系统时钟停止,就会锁定lock time直到PLL输出稳定,然后CPU工作于新的频率FCLKFCLK is new frequency)。


接下来来设置FCLK :HCLK : PCLK的时钟大小为400MHz : 100MHz : 50MHz

一、设置lock time

 

设置LOCKTIME寄存器,直接设置默认值0xFFFFFFFF就好了。

二、设置HDIVNPDIVN的分频大小

 

设置CLKDIVN寄存器,HCLK=FCLK/4PLCK=HCLK/2,因此寄存器的第三位为101。这时FCLK :HCLK : PCLK的始终比例就为1:4:8

 

三、设置MPLL

 

 

设置MPLLCON寄存器,那么其中MDIVPDIVSDIV设置为多少才能使MPLL输出400MHz时钟呢,参考手册,如上图的表中,设置MDIV92PDIVSDIV1,既可以使MPLL输出400Mhz。用手册提供的公式验证一下:

 

m = MDIV+8 = 92+8=100

p = PDIV+2 = 1+2 = 3

s = SDIV = 1

Mpll= 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M

即输出400Mhz

 

四、设置CPU工作于异步模式

 

手册的注意事项中说明,若CPU在没有处于异步模式时,如果HDIVN非零,则CPU的工作频率最终变为HCLK提供。这样就不达不到CPU工作在400Mhz频率下的目的了,因此需将CPU设置在异步模式下,用上面提供的汇编代码即可。所以整个时钟的代码编写需汇编来完成。


汇编代码:

.text
.global _start

_start:

/* 关闭看门狗 */
ldr r0, =0x53000000
ldr r1, =0
str r1, [r0]

/* 设置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
ldr r0, =0x4C000000
ldr r1, =0xFFFFFFFF
str r1, [r0]

/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */
ldr r0, =0x4C000014
ldr r1, =0x5
str r1, [r0]

/* 设置CPU工作于异步模式 */
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0


/* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 
*  m = MDIV+8 = 92+8=100
*  p = PDIV+2 = 1+2 = 3
*  s = SDIV = 1
*  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
*/
ldr r0, =0x4C000004
ldr r1, =(92<<12)|(1<<4)|(1<<0)
str r1, [r0]

/* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
* 然后CPU工作于新的频率FCLK
*/

/* 设置内存: sp 栈 */
/* 分辨是nor/nand启动
* 写0到0地址, 再读出来
* 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
* 否则就是nor启动
* (向Norflash中写数据需要特定的命令时序,而向内存中写数据可以直接向内存地址赋值)
*/
mov r1, #0
ldr r0, [r1] /* 读出原来的值备份 */
str r1, [r1] /* 0->[0] */ 
ldr r2, [r1] /* r2=[0] */
cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */
ldr sp, =0x40000000+4096 /* 先假设是nor启动 */
moveq sp, #4096  /* nand启动 */
streq r0, [r1]   /* 恢复原来的值 */

bl main

halt:
b halt



原创粉丝点击