tiny4412 时钟测试

 前面分析了 4412 时钟体系,本文来简单测试一下,参考韦东山老师的 Linux 应用完全开发手册4412 (上)

  

第一实验:

  三星公司的BL1会将ARMCLK初始化为400MHz,我们关闭APLL,让 ARMCLK 工作在 24MHz,查看LED闪烁是否缓慢

start.S

[cpp]  view plain  copy
  1. .text  
  2. .globl _start  
  3. _start:  
  4.     ldr sp, =0x02027800   
  5. // 调用C函数之前必须设置栈,栈用于保存运行环境,给局部变量分配空间  
  6. // 参考ROM手册P14, 我们把栈指向BL2上方1K处(1K已经够用),  
  7. // 即:0x02020000 (iRAM基地址) + 5K(iROM代码用) + 8K(BL1用) + 16K(BL2用) + 1K(用作栈))  
  8.   
  9.     bl main  // 调用main函数(main这个名称不是固定的,可以随意改)  
  10.   
  11. halt_loop:  
  12.   
  13.     b halt_loop  
led.c
[cpp]  view plain  copy
  1. #define GPM4CON (*(volatile unsigned int *)0x110002E0)  
  2. #define GPM4DAT (*(volatile unsigned int *)0x110002E4)  
  3. void delay(volatile int time)  
  4. {  
  5.     for(; time > 0; time-- )  
  6.         ;  
  7. }  
  8. int main(void)  
  9. {  
  10.     unsigned long tmp = 0;  
  11.     int i = 0;  
  12. /* 
  13.  * GPM4_0-GPM4_3 设置为输出功能 
  14.  */  
  15.     tmp = GPM4CON;  
  16.     tmp &= ~0xffff;  
  17.     tmp |= 0x1111;  
  18.     GPM4CON = tmp;   
  19. /* 
  20.  * 实现流水灯 
  21.  */  
  22.     system_clock_init();  
  23.     while(1)  
  24.     {  
  25.         GPM4DAT = i;  
  26.         if (++i == 16)  
  27.             i = 0;  
  28.         delay(9999999);  
  29.     }  
  30.     return 0;  
  31. }  
clock_init.c
[cpp]  view plain  copy
  1. // CMU_CPU  
  2. #define CLK_SRC_CPU (*(volatile unsigned int *)0x10044200)  
  3. #define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10044500)  
  4. #define CLK_DIV_CPU1 (*(volatile unsigned int *)0x10044504)  
  5. // CMU_DMC  
  6. #define CLK_SRC_DMC (*(volatile unsigned int *)0x10040200)  
  7. #define CLK_DIV_DMC0 (*(volatile unsigned int *)0x10040500)  
  8. #define CLK_DIV_DMC1 (*(volatile unsigned int *)0x10040504)  
  9. // CMU_TOP  
  10. #define CLK_SRC_TOP0 (*(volatile unsigned int *)0x1003C210)  
  11. #define CLK_SRC_TOP1 (*(volatile unsigned int *)0x1003C214)  
  12. #define CLK_DIV_TOP (*(volatile unsigned int *)0x1003C510)  
  13. // CMU_LEFTBUS  
  14. #define CLK_SRC_LEFTBUS (*(volatile unsigned int *)0x10034200)  
  15. #define CLK_DIV_LEFTBUS (*(volatile unsigned int *)0x10034500)  
  16. // CMU_RIGHTBUS  
  17. #define CLK_SRC_RIGHTBUS (*(volatile unsigned int *)0x10038200)  
  18. #define CLK_DIV_RIGHTBUS (*(volatile unsigned int *)0x10038500)  
  19. // locktime  
  20.   
  21. #define APLL_LOCK (*(volatile unsigned int *)0x10044000)  
  22. #define MPLL_LOCK (*(volatile unsigned int *)0x10044008)  
  23. #define EPLL_LOCK (*(volatile unsigned int *)0x1003C010)  
  24. #define VPLL_LOCK (*(volatile unsigned int *)0x1003C020)  
  25.   
  26. // APLL  
  27. #define APLL_CON1 (*(volatile unsigned int *)0x10044104)  
  28. #define APLL_CON0 (*(volatile unsigned int *)0x10044100)  
  29.   
  30. // MPLL  
  31. #define MPLL_CON0 (*(volatile unsigned int *)0x10040108)  
  32. #define MPLL_CON1 (*(volatile unsigned int *)0x1004010c)  
  33.   
  34. // EPLL  
  35. #define EPLL_CON2 (*(volatile unsigned int *)0x1003C118)  
  36. #define EPLL_CON1 (*(volatile unsigned int *)0x1003C114)  
  37. #define EPLL_CON0 (*(volatile unsigned int *)0x1003C110)  
  38.   
  39. // VPLL  
  40. #define VPLL_CON0 (*(volatile unsigned int *)0x1003C120)  
  41. #define VPLL_CON1 (*(volatile unsigned int *)0x1003C124)  
  42. #define VPLL_CON2 (*(volatile unsigned int *)0x1003C128)  
  43.   
  44.    
  45.   
  46. /* 
  47.  * 函数名: 
  48.  * system_clock_init 
  49.  * 功能: 初始化4412的系统时钟 
  50.  */  
  51. void system_clock_init(void)  
  52. {  
  53.  /* IROM或BL1设置了APLL, 
  54.   * 本程序设置不启动APLL, 
  55.   * 而是使在晶振时钟, 以体验一下LED闪灯变慢 
  56.   */  
  57.    CLK_SRC_CPU = 0x0;  
  58. }  
Makfile
[cpp]  view plain  copy
  1. objs := start.o led.o clock_init.o  
  2. led.bin : $(objs)  
  3.     arm-linux-ld -Tled.lds -N -o led.elf $^  
  4.     arm-linux-objcopy -O binary -S led.elf $@  
  5.     arm-linux-objdump -D -m arm led.elf > led.dis  
  6. %.o:%.c  
  7.     arm-linux-gcc -Wall -marm -c -O2 -o $@ $<  
  8. %.o:%.S  
  9.     arm-linux-gcc -Wall -marm -c -O2 -o $@ $  
  10. clean:  
  11.     rm -f *.dis *.bin *.elf *.o  
led.lds
[cpp]  view plain  copy
  1. SECTIONS {    
  2. . = 0x02023400;    
  3. .text : { *(.text) }    
  4. .rodata ALIGN(4) : {*(.rodata*)}    
  5. .data ALIGN(4) : { *(.data*) }    
  6. .bss ALIGN(4) : { *(.bss) *(COMMON) }    
  7. }    
  实验现象应该是相比 led.c 中不加 system_clock_init() 的时候,LED闪烁的非常缓慢。

第二个实验:

  将 ARMCLK 提升到1400MHz ,观察LED闪烁是否变快。只更改 clock_init.c

[cpp]  view plain  copy
  1. // CMU_CPU  
  2. #define CLK_SRC_CPU (*(volatile unsigned int *)0x10044200)  
  3. #define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10044500)  
  4. #define CLK_DIV_CPU1 (*(volatile unsigned int *)0x10044504)  
  5.   
  6. // CMU_DMC  
  7. #define CLK_SRC_DMC (*(volatile unsigned int *)0x10040200)  
  8. #define CLK_DIV_DMC0 (*(volatile unsigned int *)0x10040500)  
  9. #define CLK_DIV_DMC1 (*(volatile unsigned int *)0x10040504)  
  10.   
  11. // CMU_TOP  
  12. #define CLK_SRC_TOP0 (*(volatile unsigned int *)0x1003C210)  
  13. #define CLK_SRC_TOP1 (*(volatile unsigned int *)0x1003C214)  
  14. #define CLK_DIV_TOP (*(volatile unsigned int *)0x1003C510)  
  15.   
  16. // CMU_LEFTBUS  
  17. #define CLK_SRC_LEFTBUS (*(volatile unsigned int *)0x10034200)  
  18. #define CLK_DIV_LEFTBUS (*(volatile unsigned int *)0x10034500)  
  19.   
  20. // CMU_RIGHTBUS  
  21. #define CLK_SRC_RIGHTBUS (*(volatile unsigned int *)0x10038200)  
  22. #define CLK_DIV_RIGHTBUS (*(volatile unsigned int *)0x10038500)  
  23.   
  24. // locktime  
  25. #define APLL_LOCK (*(volatile unsigned int *)0x10044000)  
  26. #define MPLL_LOCK (*(volatile unsigned int *)0x10044008)  
  27. #define EPLL_LOCK (*(volatile unsigned int *)0x1003C010)  
  28. #define VPLL_LOCK (*(volatile unsigned int *)0x1003C020)  
  29.   
  30. // APLL  
  31. #define APLL_CON1 (*(volatile unsigned int *)0x10044104)  
  32. #define APLL_CON0 (*(volatile unsigned int *)0x10044100)  
  33.   
  34. // MPLL  
  35. #define MPLL_CON0 (*(volatile unsigned int *)0x10040108)  
  36. #define MPLL_CON1 (*(volatile unsigned int *)0x1004010c)  
  37.   
  38. // EPLL  
  39. #define EPLL_CON2 (*(volatile unsigned int *)0x1003C118)  
  40. #define EPLL_CON1 (*(volatile unsigned int *)0x1003C114)  
  41. #define EPLL_CON0 (*(volatile unsigned int *)0x1003C110)  
  42.   
  43. // VPLL  
  44. #define VPLL_CON0 (*(volatile unsigned int *)0x1003C120)  
  45. #define VPLL_CON1 (*(volatile unsigned int *)0x1003C124)  
  46. #define VPLL_CON2 (*(volatile unsigned int *)0x1003C128)  
  47.   
  48.    
  49.   
  50. /* 
  51.  * 函数名: 
  52.  * system_clock_init 
  53.  * 功能: 初始化4412的系统时钟 
  54.  */  
  55.   
  56. void system_clock_init(void)  
  57. {  
  58.     /* 1. 在设置APLL之前, 先设置时钟源为晶振 */  
  59.     CLK_SRC_CPU = 0x0;  
  60.     /* 2. 设置APLL */  
  61.     /* 2.1 设置锁定时间: APLL_CON0中PDIV=3, 所以APLL_LOCK = 270x3 */  
  62.     APLL_LOCK = 270 * 3;  
  63.     /* 2.2 设置分频参数 */  
  64.     CLK_DIV_CPU0 = 0x00160760;  
  65.     CLK_DIV_CPU1 = 0x00000106;  
  66.   
  67.     /* 2.3 设置控制参数并使能PLL */  
  68.     /* 默认值 */  
  69.     APLL_CON1 = 0x00803800;  
  70.     /* 
  71.      * 设置APLL的M,P,S值, APLL输出 = 0xAF x 24MHz / (3 x 2 ^ 0) = 1.4GHz 
  72.      * 使能APLL 
  73.      */  
  74.     APLL_CON0 = (1<<31 | 0xAF<<16 | 3<<8 | 0x0);  
  75.     /* 3. 设置MUX, 使用APLL的输出 */  
  76.     CLK_SRC_CPU = 0x01000001;  
  77. }  


  一开始,测试时,我试图只把ARMCLK提升到1400MHz,其余寄存器都使用默认值,但是发现LED闪烁几下程序就会跑飞,根据下图采用默认值的情况下大部分DIV分频系数都是1,因此比如ACLK_COREM0等也都会是 1400MHz,但是它们是无法承受如此高的工作频率。



  三星给出了 high-performance 状态下的频率值,我将 cpu 部分的频率配置到该表推荐值以下,程序就正常运行了。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值