📄 sysutils.c.bak
字号:
/* sysUtils.c - Motorola ads826x common routines *//* Copyright 1984-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,24dec03,dtr Mod to clk gen for 827x.01c,04oct03,dee fix typos01b,02oct03,dee fix typo in header01a,01oct03,dee common 'C' routines for bootrom and vxWorks*//*DESCRIPTIONThis file contains common utilities that need to be shared betweenbootrom code and vxWorks code*/#include "vxWorks.h"#include "config.h"/* forwards */uint32_t sysBaudClkFreq(void);uint32_t sysCpmFreqGet(void);uint32_t sysVcoFreqGet(void);uint32_t sysBusFreqGet(void);uint32_t sysSccFreqGet(void);void romMsDelay(uint32_t);/* externals */extern void romDecSet(uint32_t);extern uint32_t romDecGet(void);/******************************************************************************** sysBaudClkFreq - Obtains frequency of the BRG_CLK in HZ** From page 9-5 in Rev. 0 MPC8260 PowerQUICC II User's Manual** Baud clock = 2*CPM/2^(2*(sccrDfBrg + 1)* simplifying yields:* Baud clock = CPM/(2^(2*sccrDfbrg + 1))** RETURNS: frequency of the BRG_CLK in Hz*/uint32_t sysBaudClkFreq ( void ) { uint32_t vcoFreq, sccrDfbrg; uint16_t divisor; /* Get the physical location of the Internal Mem Map */ sccrDfbrg = *(UINT32 *)(SCCR); sccrDfbrg &= SCMR_DFBRG_MASK; /* only want lower bits */ divisor = 1 << (2*(sccrDfbrg + 1)); vcoFreq = sysVcoFreqGet(); return ((vcoFreq)/divisor); }/****************************************************************************** * * sysCpmFreqGet - Determines the CPM Operating Frequency * * From page 9.5 Rev. 0 MPC8260 PowerQUICC II User's Manual * Calculation based on Figure 9-1. * * CPM_FREQ = VCO_OUT/(CPMDF + 1) * * RETURNS: CPM clock frequency for the current configuration settings */uint32_t sysCpmFreqGet ( void ) { uint32_t scmr; /* value for system clock mode register */ uint8_t cpmdf; uint32_t vcoFreq; /* vco output frequency */ /* get SCMR (system clock mode reg) */ scmr = *(uint32_t *)(SCMR); cpmdf = SCMR_CPMDF(scmr); /* get value of cpmdf */ vcoFreq = sysVcoFreqGet(); return (vcoFreq / (cpmdf + 1)); /* return the cpm frequency */ }/****************************************************************************** * * sysBusFreqGet - Determines the Bus Operating Frequency * * From page 9.5 Rev. 0 MPC8260 PowerQUICC II User's Manual * Calculation based on Figure 9-1. * * BUS_FREQ = vcoFreq/(BUSDF + 1) * RETURNS: Bus clock frequency for the current configuration settings */uint32_t sysBusFreqGet ( void ) { uint32_t scmr; /* value for system clock mode register */ uint8_t busdf; uint32_t vcoFreq; /* vco output frequency */ /* get SCMR (system clock mode reg) */ scmr = *(uint32_t *)(SCMR); busdf = SCMR_BUSDF(scmr); /* get value of busdf */ vcoFreq = sysVcoFreqGet(); return (vcoFreq / (busdf + 1)); /* return the bus clock frequency */ }/****************************************************************************** * * sysSccFreqGet - Determines the SCC Frequency * * From page 9.5 Rev. 0 MPC8260 PowerQUICC II User's Manual * Calculation based on Figure 9-1. * * SCC_FREQ = vcoFreq/4 * RETURNS: SCC clock frequency for the current configuration settings */uint32_t sysSccFreqGet ( void ) { return (sysVcoFreqGet() / 4); /* return the scc frequency */ }/****************************************************************************** * * sysVcoFreqGet - Determines the VCO Frequency * * From page 9.5 Rev. 0 MPC8260 PowerQUICC II User's Manual * Calculation based on Figure 9-1. * * VCO_OUT = CLKIN/(PLLDF+1) times 2*(PLLMF+1) * * PLLDF, PLLMF are read from System Clock Mode Register (SCMR) * MODCK and MODCK_H determine those values in SCMR * * RETURNS: VCO clock frequency for the current configuration settings */uint32_t sysVcoFreqGet ( void ) { uint32_t scmr; /* value for system clock mode register */ uint16_t pllmf; /* pll divide/multiply factors */ uint32_t vcoFreq; /* vco output frequency */ /* get SCMR (system clock mode reg) */ scmr = *(uint32_t *)(SCMR); pllmf = SCMR_PLLMF(scmr); /* get value of pllmf, lower 4 bits of scmr */ vcoFreq = (OSCILLATOR_FREQ * (pllmf + 1)); return (vcoFreq); /* return the cpm frequency */ } /******************************************************************************** sysUsDelay - delay at least the specified amount of time (in microseconds)** This routine will delay for at least the specified amount of time using the* lower 32 bit "word" of the Time Base register as the timer. The accuracy of* the delay increases as the requested delay increases due to a certain amount* of overhead. As an example, a requested delay of 10 microseconds is* accurate within approximately twenty percent, and a requested delay of 100* microseconds is accurate within approximately two percent.** NOTE: This routine will not relinquish the CPU; it is meant to perform a* busy loop delay. The minimum delay that this routine will provide is* approximately 10 microseconds. The maximum delay is approximately the* size of UINT32; however, there is no roll-over compensation for the total* delay time, so it is necessary to back off two times the system tick rate* from the maximum.** RETURNS: N/A*/void sysUsDelay ( uint32_t delay /* length of time in microsec to delay */ ) { volatile int loop; volatile uint32_t decValue; for(loop=0;loop<(delay/10);loop++) decValue = sysDecGet(); }/********************************************************************* * * sysMsDelay - Uses the decrementer to calculate time elapsed * * void sysMsDelay * ( * UINT delay * length of time in MS to delay * * ) * * RETURNS : NONE * */void sysMsDelay ( uint32_t delay /* length of time in MS to delay */ ) { register uint32_t oldval; /* decrementer value */ register uint32_t newval; /* decrementer value */ register uint32_t totalDelta; /* Dec. delta for entire delay period */ register uint32_t decElapsed; /* cumulative decrementer ticks */ /* * Calculate delta of decrementer ticks for desired elapsed time. * The macro DEC_CLOCK_FREQ MUST REFLECT THE PROPER 6xx BUS SPEED. */ totalDelta = ((DEC_CLOCK_FREQ / 4) / 1000) * delay; /* * Now keep grabbing decrementer value and incrementing "decElapsed" until * we hit the desired delay value. Compensate for the fact that we may * read the decrementer at 0xffffffff before the interrupt service * routine has a chance to set in the rollover value. */ decElapsed = 0; oldval = sysDecGet (); while (decElapsed < totalDelta) { newval = sysDecGet (); if ( DELTA(oldval,newval) < 1000 ) decElapsed += DELTA(oldval,newval); /* no rollover */ else if (newval > oldval) decElapsed += sysAbs((int)oldval); /* rollover */ oldval = newval; } }/********************************************************************* * * sysDelay - Fixed 1ms delay. Just calls sysMsDelay * * sysDelay(void) * * RETURNS : NONE * */void sysDelay (void) { sysMsDelay (1); }#if DEBUG/********************************************************************* * * sysMsDelay - Uses the decrementer to calculate time elapsed * * void sysMsDelay * ( * UINT delay * length of time in MS to delay * * ) * * RETURNS : NONE * * NOTE: This should only be called from bootup code - before decrementer * interrupts are enabled, since it adjusts the decrementer value. */void romMsDelay ( uint32_t delay /* length of time in MS to delay */ ) { uint32_t oneMS; uint32_t i; oneMS = ((DEC_CLOCK_FREQ / 4) / 1000); /* decrementer ticks per ms */ for (i = 0; i < delay; i++) { /* count milliseconds */ romDecSet(oneMS); /* set decrementer to 1 millisecond */ while ((romDecGet() & 0x80000000) == 0) { /* wait for decrementer to go negative */ continue; } } }/********************************************************************* * * flashRedLed - light the Red LED a specified number of times * * void sysMsDelay * ( * uint32_t times * number of times to flash the red LED * * ) * * RETURNS : NONE * * NOTE: This should only be called from bootup code - before decrementer * interrupts are enabled, since it calls romMsDelay. */void flashRedLed ( uint32_t times ) { uint32_t i; for (i = 0; i < times; i++) { *BCSR0 &= ~BCSR0_LED_RED; /* turn on by clearing bit */ romMsDelay(1000); *BCSR0 |= BCSR0_LED_RED; /* turn off by setting bit */ romMsDelay(1000); } romMsDelay (2000); /* delay 2 seconds after sequence */ }/********************************************************************* * * flashGreenLed - light the Green LED a specified number of times * * void sysMsDelay * ( * uint32_t times * number of times to flash the green LED * * ) * * RETURNS : NONE * * NOTE: This should only be called from bootup code - before decrementer * interrupts are enabled, since it calls romMsDelay. */void flashGreenLed ( uint32_t times ) { uint32_t i; for (i = 0; i < times; i++) { *BCSR0 &= ~BCSR0_LED_GREEN; /* turn on by clearing bit */ romMsDelay(1000); *BCSR0 |= BCSR0_LED_GREEN; /* turn off by setting bit */ romMsDelay(1000); } romMsDelay (2000); /* delay 2 seconds after sequence */ }#endif#ifdef CTDB_MPC8280/*初始化SDRAM*/#include "drv/mem/m8260Siu.h"#include "drv/mem/m8260Memc.h"/* SDRAM refresh timer */#define CTDB_M8260_PSRT(base) (CAST(VUINT8 *)((base) + 0x1019c)) /* 60x bus SDRAM mode register */#define CTDB_M8260_PSDMR(base) (CAST(VUINT32 *)((base) + 0x10190))void FillSDRAM(void){ unsigned long *Addr; unsigned long i; Addr=0; for(i=0;i<CFG_60X_SDRAM_SIZE/sizeof(long);i++) *Addr++=0;}void sdraminit(){ volatile unsigned char *ramaddr, c = 0xff; UINT32 immrVal = INTERNAL_MEM_MAP_ADDR; unsigned long i; unsigned long *addr; *M8260_OR2(immrVal) = CFG_OR2_PRELIM; *M8260_BR2(immrVal) = CFG_BR2_PRELIM; /* init 60x sdram dimm */ ramaddr = (unsigned char *)LOCAL_MEM_LOCAL_ADRS; *CTDB_M8260_PSRT(immrVal) = 0x00000008; #if(CFG_60X_SDRAM_SIZE == 0x8000000) | (CFG_60X_SDRAM_SIZE == 0x4000000) *CTDB_M8260_PSDMR(immrVal) = 0xAB4E3662; *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0x8B4E3662; for (i = 0; i < 8; i++) *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0x9B4E3662; *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0xC34E3662; *ramaddr = c;#elif (CFG_60X_SDRAM_SIZE == 0x2000000) *CTDB_M8260_PSDMR(immrVal) = 0xAA4A3662; *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0x8A4A3662; for (i = 0; i < 8; i++) *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0x9A4A3662; *ramaddr = c; *CTDB_M8260_PSDMR(immrVal) = 0xC24A3662; *ramaddr = c;#endif if(CFG_60X_SDRAM_SIZE>0x4000000) {/*检测内存大小,焊128M / 64M 内存自己检测,32M也可以照该方法自己写,程序不用改*/ addr=(unsigned long *)LOCAL_MEM_LOCAL_ADRS; *addr = 0x87654321; addr=(unsigned long *)(LOCAL_MEM_LOCAL_ADRS+0x4000000); *addr=0x12345678; addr=(unsigned long *)LOCAL_MEM_LOCAL_ADRS; if(0x12345678==*addr) { *M8260_OR1(immrVal) = 0xFC002CC0; } }#if 0 FillSDRAM();#endif}/*0 ON1 OFFPC6 31-6=25PC7 31-7=24*/void SetLight0(int status){ unsigned long *PtrData; PtrData=(unsigned long *)(CFG_IMMR+0x10000+0xd50); if(status) *PtrData|=(PC6); else *PtrData&=~(PC6);}void SetLight1(int status){ unsigned long *PtrData; PtrData=(unsigned long *)(CFG_IMMR+0x10000+0xd50); if(status) *PtrData|=(PC7); else *PtrData&=~(PC7);}void SetLight2(int status){ unsigned long *PtrData; PtrData=(unsigned long *)(CFG_IMMR+0x10000+0xd50); if(status) *PtrData|=(PC8); else *PtrData&=~(PC8);}void SetLight3(int status){ unsigned long *PtrData; PtrData=(unsigned long *)(CFG_IMMR+0x10000+0xd50); if(status) *PtrData|=(PC9); else *PtrData&=~(PC9);}void LightDown(void){ *(unsigned long *)(CFG_IMMR+0x10000+0xd00) = 0x300 ; *(unsigned long *)(CFG_IMMR+0x10000+0xd0c) = 0x0; *(unsigned long *)(CFG_IMMR+0x10000+0xd10) = 0x300 ;}void LightUp(void){ *(unsigned long *)(CFG_IMMR+0x10000+0xd00) = 0x300 ; *(unsigned long *)(CFG_IMMR+0x10000+0xd0c) = 0x0; *(unsigned long *)(CFG_IMMR+0x10000+0xd10) = 0x0 ;}/*初始化灯*/void InitLight(void){ *(unsigned long *)(CFG_IMMR+0x10000+0xd00) = 0x300 ; *(unsigned long *)(CFG_IMMR+0x10000+0xd0c) = 0x0;}void Mydelay(void){ int i; for (i=0;i<500000;i++);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -