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

📄 clock.c

📁 coldfire的mcf5329的程序
💻 C
字号:
/*
 * File:    clock.c
 * Purpose: Driver for the on-chip Clock module
 *
 * Notes:       
 */

#include "common.h"
#include "clock.h"

/********************************************************************/
/* Initialize the PLL
 * 
 * Parameters:
 *  fref    PLL reference clock frequency in KHz
 *  fsys    Desired PLL output frequency in KHz
 *  flags   Operating parameters
 *
 * Return Value:
 *  The resulting output system frequency
 */
int
clock_pll (int fsys, int flags)
{
    int fref, temp, fout, mfd;
    uint32 i;
        
    fref = FREF;    
        
    if (fsys == 0)
    {
        /* Return current PLL output */
        mfd = MCF_PLL_PFDR;       

        return ( fref * mfd / (BUSDIV * 4));
    }
    
    /* Check bounds of requested system clock */
    if (fsys > MAX_FSYS)
        fsys = MAX_FSYS;
    
    if (fsys < MIN_FSYS)
    	fsys = MIN_FSYS;
        
   	/* Multiplying by 100 when calculating the temp value,
   	   and then dividing by 100 to calculate the mfd allows
   	   for exact values without needing to include floating
   	   point libraries. */
   	temp = 100 * fsys / fref;
    mfd = 4 * BUSDIV * temp / 100;
    	    	    	
    /* Determine the output frequency for selected values */
    fout = ( fref * mfd / (BUSDIV * 4));
    
   	/*
	 * Check to see if the SDRAM has already been initialized.
	 * If it has then the SDRAM needs to be put into self refresh
	 * mode before reprogramming the PLL.
	 */
	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
		/* Put SDRAM into self refresh mode */
		MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;

    /* 
     * Initialize the PLL to generate the new system clock frequency. 
     * The device must be put into LIMP mode to reprogram the PLL. 
     */

	/* Enter LIMP mode */     
    clock_limp( DEFAULT_LPD );
     					
	/* Reprogram PLL for desired fsys */
	MCF_PLL_PODR = ( 0
						| MCF_PLL_PODR_CPUDIV(BUSDIV/3)
						| MCF_PLL_PODR_BUSDIV(BUSDIV) );
						
	MCF_PLL_PFDR = mfd;
		
    /* Exit LIMP mode */
	clock_exit_limp();
	
   	/*
	 * Return the SDRAM to normal operation if it is in use.
	 */
	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
	    /* Exit self refresh mode */
    	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;

	/* software workaround for SDRAM operation after exiting LIMP mode errata */
   	*((uint32 *)(0xFC0B8080)) = 0x40000000;
    /* wait for DQS logic to relock */
	for(i=0; i<0x200; i++);
	

    return fout;
}
/********************************************************************/
/*
 * Initialize the Low Power Divider circuit
 * 
 * Parameters:
 *  div     Desired system frequency divider
 *
 * Return Value:
 *  The resulting output system frequency
 */
int
clock_limp (int div)
{
	uint32 temp;

    /* Check bounds of divider */
    if (div < MIN_LPD) 
    	div = MIN_LPD;
    if (div > MAX_LPD)
        div = MAX_LPD;
    
    /* Save of the current value of the SSIDIV so we don't
       overwrite the value*/
	temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF) );       
      
    /* Apply the divider to the system clock */
    MCF_CCM_CDR = ( 0
    				| MCF_CCM_CDR_LPDIV(div)
    				| MCF_CCM_CDR_SSIDIV(temp) );
    
    MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
    
    return (FREF/(3*(1 << div)));
}
/********************************************************************/
/*
 * Exit low power LIMP mode
 * 
 * Parameters:
 *  div     Desired system frequency divider
 *
 * Return Value:
 *  The resulting output system frequency
 */
int
clock_exit_limp (void)
{
	int fout;
	
    /* Exit LIMP mode */
    MCF_CCM_MISCCR = ( MCF_CCM_MISCCR
    					& ~ MCF_CCM_MISCCR_LIMP);

	/* Wait for PLL to lock */
	while ( !(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK ));
	
	fout = get_sys_clock();						     					

    return fout;
}
/********************************************************************/
/*
 * Get the value of the current system clock
 * 
 * Parameters:
 *  none
 *
 * Return Value:
 *  The current output system frequency
 */
int
get_sys_clock (void)
{

	int divider; 
	
	/* Test to see if device is in LIMP mode */
	if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP)
	{
		divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
		return (FREF/(2 << divider));
	}
	else
	{
		return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));	
	
	}
}
/********************************************************************/

⌨️ 快捷键说明

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