Chinaunix首页 | 论坛 | 博客
  • 博客访问: 115955
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-23 17:29
文章分类
文章存档

2014年(39)

2013年(10)

我的朋友

分类: 嵌入式

2014-02-07 13:54:37

原文地址:2. interrupt_init 作者:changyongID


cpu/arm920t/s3c24x0/interrupts.c 设置一些寄存器

1    int interrupt_init (void)
     2    {
     3    S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();

     4    /* use PWM Timer 4 because it has no output */
     5    /* prescaler for Timer 4 is 16 */
     6    timers->TCFG0 = 0x0f00;
     7    if (timer_load_val == 0)
     8    {
     9    /*
    10     * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
    11     * (default) and prescaler = 16. Should be 10390
    12     * @33.25MHz and 15625 @ 50 MHz
    13     */

    14    timer_load_val = get_PCLK()/(2 * 16 * 100);
    15    }
    16    /* load value for 10 ms timeout */
    17    lastdec = timers->TCNTB4 = timer_load_val;
    18    /* auto load, manual update of Timer 4 */
    19    timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
    20    /* auto load, start Timer 4 */
    21    timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
    22    timestamp = 0;

    23    return (0);
    24    }



这里实际上是设置timer定时器。2410总共有5个定时器,timer0~timer4 . 这里使用timer4,上面把原因说的很清楚 use PWM Timer 4 because it has no output

timer的使用
产生timer的频率过程如下
                                                 /---> 1/2 * PLCK1
                          (产生PCLK1)           |/--> 1/4 * PLCK1
PCLK -> 被8-bit prescaler分频 ---> clock divider -----> 1/8 * PLCK1
                                                 |\--> 1/16 * PLCK1
                                                  \--> 外部时钟(TCLK)
 TCFG0              Bit      Description            
Prescaler 1       [15:8]   These 8 bits determine prescaler value for Timer 2, 3 and 4.   
Prescaler 0       [7:0] These 8 bits determine prescaler value for Timer 0 and 1.        0x00

那么看上面的代码

1. prescaler1

timers->TCFG0 = 0x0f00;
这里要使用timer4,所以设置其[15:8]为0f,即prescaler1 = 16

2. 定时器初值计算

timer_load_val = get_PCLK()/(2 * 16 * 100);
get_PCLK()位于cpu/arm920t/s3c24x0/speed.c 中,取得pclk的过程如下
 FCLK => HCLK = FCLK / 2 => PCLK = HCLK / 2
即先通过MPLLCON的值计算得出FCLK,然后根据CLKDIVN的分频率比得出HCLK 和 PCLK

要做一个10ms的定时器,所以这里计算初值。上面prescaler1 = 16, 且此处没有设置TCFG1,所以TCFG1为默认值0, 则divider选择了1/2; 1s = 10ms * 100;
于是,需要的三个参数全都出来了
分频后频率为 (clk /(2 * 16)),即每秒要做(clk/(2 * 16))次减计数,那么10ms就要做 clk / (2 * 16 * 100)次减计数。

3. TCNTB4

timers->TCNTB4 = timer_load_val 将值记录于TCNTB4中。在 auto reload 模式时,在减计数一次完成之后,会自动将 TCNTB4 的值赋给 TCNT4

4. TCON

最后 设置 TCON 的bit[22:20]
 
timers->TCON = (timers->TCON & ~0x0700000) | 0x600000; => bit[22:20] = 110
即选择 auto reload mode, update TCNTB4

timers->TCON = (timers->TCON & ~0x0700000) | 0x500000; => bit[22:20] = 101
即 auto reload mode, start for timer4 此时,真正开始定时器4


ps:
  在uboot后来的版本中,interrupt_init 被改名为 time_init
阅读(1571) | 评论(0) | 转发(0) |
0

上一篇:uboot 初始化循环体

下一篇:1. board_init

给主人留下些什么吧!~~