📄 clock.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 */intclock_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 */intclock_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 */intclock_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 */intget_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 + -