⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orionpll.c

📁 数码投影仪,包含电路,RS232通信,远程控制
💻 C
字号:
//=============================================================================
// Filename:     orionpll.c
//
// Description:  Code for setup of PLLs
//
// Copyright (C) 2000 - 2002 Texas Instruments Incorporated
//
//============================================================================


static volatile unsigned long* const clkm_stop_reg       
                                           = (unsigned long*)0xffff2f00;
static volatile unsigned long* const clkm_dsp_reg        
                                           = (unsigned long*)0xffff2f04;
static volatile unsigned long* const clkm_wakeup_reg     
                                           = (unsigned long*)0xffff2f08;
static volatile unsigned long* const clkm_low_power_reg  
                                           = (unsigned long*)0xffff2f1c;

/* clkm_stop_reg */
/* clkm_wakeup_reg */
#define CLKM_STOP_SPI      0x0800
#define CLKM_STOP_I2C      0x0400

/* clkm_dsp_reg */
#define CLKM_DSP_PLL_RSN     (0x01 << 7)
/* 
 * really PLL mode 
 * CLKM_DSP_PLL_NDIV = '0' ==> DIV mode
 * CLKM_DSP_PLL_NDIV = '1' ==> PLL mode
 */
#define CLKM_DSP_PLL_NDIV    (0x01 << 6)
#define CLKM_DSP_PLL_ONOFF   (0x01 << 5)
#define CLKM_DSP_PLL_MUL3     (0x18)   

/* clkm_lowpower_reg */
#define CLKM_NORMAL_MODE      0x00


/*
 * ARM PLL stuff
 */
static volatile unsigned long* const arm_pll_reg = (unsigned long*)0xffff3200;

#define PLL_MUL(n)    ((n)<<12)
#define PLL_DIV       0x0800
#define PLL_DIV_1     0x0000
#define PLL_COUNT(n)  ((n)<<3)
#define PLL_ON        0x0004
#define PLL_NDIV      0x0002
#define PLL_NDIV_DIV  0x0000
#define PLL_NDIV_PLL  0x0002

#define PLL_COUNT_MASK 0x07f8     
#define PLL_MUL_MASK   0xf000


static unsigned long sw_wait_loop(volatile unsigned long ctr)
{
    unsigned long i = 0;
    while(ctr-- ) {
        i++;
    }
    return(i);
}


/*
 * this main procedure sketches the following scenario.
 * we want to stop clock for modules not used by the application
 *    - i2c
 *    - spi
 *
 * we want to multiply by 2 the input clock frequency for the ARM sub-system
 * and by 4 the DSP clock .
 * we download code from the ARM to the API ram, then let the DSP sub-system go
 */
void pll_init(unsigned long ARM_Freq, unsigned long DSP_Freq)
{
    unsigned long pll_value;
    unsigned long arm_pll_value;

    *clkm_stop_reg   = CLKM_STOP_I2C | CLKM_STOP_SPI;
    *clkm_wakeup_reg = CLKM_STOP_I2C | CLKM_STOP_SPI;

    /* First put the ARM into N DIVIDE MODE                           */ 
    /* This will allow to change Frequency if PLL was already Enabled */ 
    arm_pll_value = *arm_pll_reg;
    arm_pll_value &= ~(PLL_NDIV);  
    arm_pll_value &= ~(PLL_MUL_MASK);   
    *arm_pll_reg &= arm_pll_value;                           
       
    sw_wait_loop( 0x10000 );  
                             
    /* Fit User Frequency to Closest Mapping */
    /*                                       */
    /* ODD 12.5 MHZ        25mhz   INCLK     */
    /* 1    3.125          6.25              */
    /* 3    9.375         18.75              */
    /* 5    15.625        31.25              */
    /* 7    21.875        43.75              */
    /* 9    28.125        56.25              */
    /*11    34.375                           */
    /*13    40.625                           */
    /*15    46.875                           */   
    /* EVEN 12.5 MHZ        25mhz  INCLK     */
    /* 0    6.25          12.5               */
    /* 2    18.75         37.5               */
    /* 4    31.25                            */
    /* 6    43.75                            */
    /* 8    56.25                            */
    /*10                                     */
    /*12                                     */
    /*14                                     */
    /* INTEGER                               */
    /* 1    12.5          25                 */
    /* 2    25.00         50                 */
    /* 3    37.5                             */ 
    /* 4    50                               */
                             
    if(( ARM_Freq >45 ) && (ARM_Freq <= 50)) {  /* 50 Mhz */
        *arm_pll_reg = PLL_MUL(1) | PLL_DIV_1 | PLL_COUNT(0x10) |
                       PLL_ON | PLL_NDIV_DIV;        
    }
    else if(( ARM_Freq >40 ) && (ARM_Freq <= 45)) { /* 43.75 Mhz */
        *arm_pll_reg = PLL_MUL(7) | PLL_DIV | PLL_COUNT(0x10) | 
                       PLL_ON | PLL_NDIV_DIV;
    }  
    else if(( ARM_Freq >35 ) && (ARM_Freq <= 40)) { /* 37.5 Mhz */
        *arm_pll_reg = PLL_MUL(2) | PLL_DIV | PLL_COUNT(0x10) | 
                       PLL_ON | PLL_NDIV_DIV;
    }
    else if(( ARM_Freq >30 ) && (ARM_Freq <= 35)) { /* 31.25 Mhz */
            *arm_pll_reg = PLL_MUL(5) | PLL_DIV | PLL_COUNT(0x10) | 
                           PLL_ON | PLL_NDIV_DIV;
    }
    else if(( ARM_Freq >20 ) && (ARM_Freq <= 30)) { /* 25.00 Mhz */
            *arm_pll_reg = PLL_MUL(0) | PLL_DIV_1 | PLL_COUNT(0x10) |
                           PLL_ON | PLL_NDIV_DIV;        
      
        }
    else if(( ARM_Freq >15 ) && (ARM_Freq <= 20)) { /* 18.75 Mhz */
        *arm_pll_reg = PLL_MUL(3) | PLL_DIV | PLL_COUNT(0x10) | 
                       PLL_ON | PLL_NDIV_DIV;
    } 
    else if(( ARM_Freq >10 ) && (ARM_Freq <= 15)) { /* 12.5 Mhz */
            *arm_pll_reg = PLL_MUL(0) | PLL_DIV | PLL_COUNT(0x10) | 
                           PLL_ON | PLL_NDIV_DIV;
    }
    else if( ARM_Freq <=10 ) {    /* 6.25 Mhz */
        *arm_pll_reg = PLL_MUL(1) | PLL_DIV | PLL_COUNT(0x10) | 
                       PLL_ON | PLL_NDIV_DIV;
    }
  
    *clkm_dsp_reg |= (CLKM_DSP_PLL_ONOFF | (CLKM_DSP_PLL_MUL3) );
 
    /* now switches the PLL mode */
    *arm_pll_reg |= PLL_NDIV_PLL;
    do {
        pll_value = (*arm_pll_reg ) & PLL_COUNT_MASK;
    }
    while (pll_value != 0x000);   
   
    /* we can check that the PLL is in PLL mode */
    if ((*arm_pll_reg & 0x01) != 0x01) {
        /* abnormal situation, PLL should be in PLL mode .. */
        while(1);
    }

    /* 
     * now it is time to tell the clock module to switch from test mode
     * to normal mode
     */
    *clkm_low_power_reg = CLKM_NORMAL_MODE;

    /* now the ARM sub-system should have a clock with twice */
    /* input reference clock frequency                       */
   
    /* 
     * by this time the DSP PLL should also have lock since it is the same 
     * PLL as the ARM sub-system PLL switch from DIV mode to PLL mode 
     * and then release DSP PLL from reset 
     */
    *clkm_dsp_reg  |= CLKM_DSP_PLL_NDIV;
    *clkm_dsp_reg  |= CLKM_DSP_PLL_RSN;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -