/************************************************************************************ * Copyright © 1995-2004 metrowerks inc. All rights reserved. * * * * * * $RCSfile: hwinit.c,v $ * * $Revision: 1.1.1.1 $ * * $Date: 2004/08/07 07:50:07 $ * * * * DESCRIPTION * * This file initialize the hardware. * * * * * * * * NOTE * * * * * * * * HISTORY * * * ************************************************************************************/ /* * Portions of the code in this file were provided by Freescale. * The RTXC_QUADROS macro definition is used to include code added * by Quadros Systems, Inc. for use with RTXC Quadros and to exclude * portions of code not used or supported by Quadros Systems, Inc. */ #define RTXC_QUADROS #ifdef RTXC_QUADROS /* { */ #include "rtxcapi.h" #include "sysinit.h" #include "enable.h" /* NOTE: This File contains RTXCgen Project **DEPENDENCIES** as follows: */ #include "kproject.h" /* CLKTICK */ #include "m52xxevb.h" #include "mcf5xxx.h" #include "mcf523x.h" /* PRESCALER value used is log2'(x) where x is divider */ /* */ /* log2' / N */ /* -- ---- */ /* 0 0000 2 */ /* 1 0001 4 */ /* 2 0010 8 */ /* 3 0011 16 */ /* 4 0100 32 */ /* 5 0101 64 */ /* 6 0110 128 */ /* 7 0111 256 */ /* 8 1000 512 */ /* 9 1001 1024 */ /* 10 1010 2048 */ /* 11 1011 4096 */ /* 12 1100 8192 */ /* 13 1101 16384 */ /* 14 1110 32768 */ /* 15 1111 65536 */ /* * Ideally, LOAD_VALUE = (CLKTICK * 1.0E6) / SYSTEM_CLK_PERIOD * but LOAD_VALUE is limited to 16-bits so you must divide using PRESCALER_VALUE * which means that SYSTEM_CLK_PERIOD term must be multiplied by same value * * The goal is to use as small as a divider as possible to get largest 16-bit load value. * Note: See MCF5282 User Manual for calculation formula. Note: The input clock frequency * does not seem to be divided by 2 as suggested by the manual. */ #define LOAD0_VALUE (uint16)( (CLKTICK * 1.0E-3) / ( 32 * SYSTEM_CLK_PERIOD ) ) #define PRESCALER0_VALUE 4 #define LOAD1_VALUE (uint16)( (CLKTICK * 1.0E-3) / ( 32 * SYSTEM_CLK_PERIOD ) ) #define PRESCALER1_VALUE 4 #define LOAD2_VALUE (uint16)( (CLKTICK * 1.0E-3) / ( 32 * SYSTEM_CLK_PERIOD ) ) #define PRESCALER2_VALUE 4 #define LOAD3_VALUE (uint16)( (CLKTICK * 1.0E-3) / ( 32 * SYSTEM_CLK_PERIOD ) ) #define PRESCALER3_VALUE 4 /* PIT device handles for internal use */ #define PIT0_DEVICE 0 /* do not change */ #define PIT1_DEVICE 1 /* do not change */ #define PIT2_DEVICE 2 /* do not change */ #define PIT3_DEVICE 3 /* do not change */ #else #include "523x/Headers/m523xevb.h" /********************************************************************/ void mcf523x_init(void); void mcf523x_wtm_init(void); void mcf523x_pll_init(void); void mcf523x_uart_init(void); void mcf523x_scm_init(void); void mcf523x_gpio_init(void); void mcf523x_cs_init(void); void mcf523x_sdram_init(void); #endif /* } RTXC_QUADROS */ /********************************************************************/ void mcf523x_init(void) { #ifndef RTXC_QUADROS /* { */ extern char __DATA_ROM[]; extern char __DATA_RAM[]; extern char __DATA_END[]; extern char __BSS_START[]; extern char __BSS_END[]; extern uint32 VECTOR_TABLE[]; extern uint32 __VECTOR_RAM[]; register uint32 n; register uint8 *dp, *sp; #endif /* } RTXC_QUADROS */ mcf523x_wtm_init(); mcf523x_pll_init(); mcf523x_gpio_init(); mcf523x_scm_init(); #ifndef RTXC_QUADROS /* { */ mcf523x_uart_init(); #endif /* } RTXC_QUADROS */ mcf523x_cs_init(); mcf523x_sdram_init(); #ifndef RTXC_QUADROS /* { */ /* Turn Instruction Cache ON */ /* Left off because of Cache bug mcf5xxx_wr_cacr(0 | MCF5XXX_CACR_CENB | MCF5XXX_CACR_CINV | MCF5XXX_CACR_DISD | MCF5XXX_CACR_CEIB | MCF5XXX_CACR_CLNF_00); */ /* Copy the vector table to RAM */ if (__VECTOR_RAM != VECTOR_TABLE) { for (n = 0; n < 256; n++) __VECTOR_RAM[n] = VECTOR_TABLE[n]; } mcf5xxx_wr_vbr((uint32)__VECTOR_RAM); /* * Move initialized data from ROM to RAM. */ if (__DATA_ROM != __DATA_RAM) { dp = (uint8 *)__DATA_RAM; sp = (uint8 *)__DATA_ROM; n = __DATA_END - __DATA_RAM; while (n--) *dp++ = *sp++; } /* * Zero uninitialized data */ if (__BSS_START != __BSS_END) { sp = (uint8 *)__BSS_START; n = __BSS_END - __BSS_START; while (n--) *sp++ = 0; } #endif /* } RTXC_QUADROS */ } /********************************************************************/ void mcf523x_wtm_init(void) { /* * Disable Software Watchdog Timer */ MCF_WTM_WCR = 0; } /********************************************************************/ void mcf523x_pll_init(void) { /* * Multiply 25Mhz reference crystal to acheive system clock of 150Mhz */ /* Modified By A19257 */ MCF_FMPLL_SYNCR = MCF_FMPLL_SYNCR_MFD(1); while (!(MCF_FMPLL_SYNSR & MCF_FMPLL_SYNSR_LOCK)); } /********************************************************************/ void mcf523x_scm_init(void) { /* * Enable on-chip modules to access internal SRAM */ MCF_SCM_RAMBAR = (0 | MCF_SCM_RAMBAR_BA(SRAM_ADDRESS>>16) | MCF_SCM_RAMBAR_BDE); } /********************************************************************/ void mcf523x_gpio_init(void) { /* * When booting from external Flash, the port-size is less than * the port-size of SDRAM. In this case it is necessary to enable * Data[15:0] on Port Address/Data. */ MCF_GPIO_PAR_AD = (0 | MCF_GPIO_PAR_AD_PAR_ADDR23 | MCF_GPIO_PAR_AD_PAR_ADDR22 | MCF_GPIO_PAR_AD_PAR_ADDR21 | MCF_GPIO_PAR_AD_PAR_DATAL); /* * Initialize PAR to enable SDRAM signals */ MCF_GPIO_PAR_SDRAM = 0x3F; /* * Initialize PAR to enable Ethernet signals */ MCF_GPIO_PAR_FECI2C = 0xF0; } /********************************************************************/ #ifndef RTXC_QUADROS /* { */ /* * This is the original UART initialization routine provided by * Freescale for the M523xEVB. This code has been left here for * reference purposes and is not supported by Quadros Systems, Inc. * * RTXC Quadros uses mcf523x_uart_init() from rtxcuart.c instead. */ void mcf523x_uart_init(void) { /* * Initialize all three UARTs for serial communications */ register uint16 ubgs; /* * Set Port UA to initialize URXD0/URXD1 UTXD0/UTXD1 */ MCF_GPIO_PAR_UART = 0x0F; /* * Reset Transmitter */ MCF_UART_UCR0 = MCF_UART_UCR_RESET_TX; MCF_UART_UCR1 = MCF_UART_UCR_RESET_TX; MCF_UART_UCR2 = MCF_UART_UCR_RESET_TX; /* * Reset Receiver */ MCF_UART_UCR0 = MCF_UART_UCR_RESET_RX; MCF_UART_UCR1 = MCF_UART_UCR_RESET_RX; MCF_UART_UCR2 = MCF_UART_UCR_RESET_RX; /* * Reset Mode Register */ MCF_UART_UCR0 = MCF_UART_UCR_RESET_MR; MCF_UART_UCR1 = MCF_UART_UCR_RESET_MR; MCF_UART_UCR2 = MCF_UART_UCR_RESET_MR; /* * No parity, 8-bits per character */ MCF_UART_UMR0 = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); MCF_UART_UMR1 = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); MCF_UART_UMR2 = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); /* * No echo or loopback, 1 stop bit */ MCF_UART_UMR0 = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); MCF_UART_UMR1 = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); MCF_UART_UMR2 = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); /* * Set Rx and Tx baud by timer */ MCF_UART_UCSR0 = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); MCF_UART_UCSR1 = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); MCF_UART_UCSR2 = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); /* * Mask all UART interrupts */ MCF_UART_UIMR0 = 0; MCF_UART_UIMR1 = 0; MCF_UART_UIMR2 = 0; /* * Calculate baud settings */ ubgs = (uint16)((SYSTEM_CLOCK*1000000)/(UART_BAUD * 32)); MCF_UART_UBG1(0) = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART_UBG2(0) = (uint8)(ubgs & 0x00FF); MCF_UART_UBG1(1) = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART_UBG2(1) = (uint8)(ubgs & 0x00FF); MCF_UART_UBG1(2) = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART_UBG2(2) = (uint8)(ubgs & 0x00FF); /* * Enable receiver and transmitter */ MCF_UART_UCR0 = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); MCF_UART_UCR1 = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); MCF_UART_UCR2 = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); } #endif /* } RTXC_QUADROS */ /********************************************************************/ void mcf523x_sdram_init(void) { int i; /* * Check to see if the SDRAM has already been initialized * by a run control tool */ if (!(MCF_SDRAMC_DACR0 & MCF_SDRAMC_DACR0_RE)) { /* * Initialize DRAM Control Register: DCR */ /* Modified by A19257 */ MCF_SDRAMC_DCR = (0 | MCF_SDRAMC_DCR_RTIM(1) | MCF_SDRAMC_DCR_RC((15 * SYSTEM_CLOCK)>>4)); /* * Initialize DACR0 */ MCF_SDRAMC_DACR0 = (0 | MCF_SDRAMC_DACR0_BA(SDRAM_ADDRESS) | MCF_SDRAMC_DACR0_CASL(1) | MCF_SDRAMC_DACR0_CBM(3) | MCF_SDRAMC_DACR0_PS(0)); /* Modified by A19257 */ /* * Initialize DMR0 */ MCF_SDRAMC_DMR0 = (0 | MCF_SDRAMC_DMR_BAM_16M | MCF_SDRAMC_DMR0_V); /* * Set IP (bit 3) in DACR */ MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_IP; /* * Wait 30ns to allow banks to precharge */ for (i = 0; i < 5; i++) { #ifndef __MWERKS__ asm(" nop"); #else asm( nop); #endif } /* * Write to this block to initiate precharge */ *(uint32 *)(SDRAM_ADDRESS) = 0xA5A59696; /* * Set RE (bit 15) in DACR */ MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_RE; /* * Wait for at least 8 auto refresh cycles to occur */ for (i = 0; i < 2000; i++) { #ifndef __MWERKS__ asm(" nop"); #else asm( nop); #endif } /* * Finish the configuration by issuing the IMRS. */ MCF_SDRAMC_DACR0 |= MCF_SDRAMC_DACR0_MRS; /* * Write to the SDRAM Mode Register */ *(uint32 *)(SDRAM_ADDRESS + 0x400) = 0xA5A59696; } } /********************************************************************/ void mcf523x_cs_init(void) { /* * ChipSelect 1 - External SRAM (Modified by A19257) */ MCF_CS_CSAR1 = MCF_CS_CSAR_BA(EXT_SRAM_ADDRESS); MCF_CS_CSCR1 = MCF_CS_CSCR_IWS(0x0F)|MCF_CS_CSCR_AA | MCF_CS_CSCR_BEM | MCF_CS_CSCR_PS_32; //MCF_CS_CSCR1 = 0x3d20; MCF_CS_CSMR1 = MCF_CS_CSMR_BAM_1M | MCF_CS_CSMR_V; /* * ChipSelect 0 - External Flash */ MCF_CS_CSAR0 = MCF_CS_CSAR_BA(EXT_FLASH_ADDRESS); MCF_CS_CSCR0 = (0 | MCF_CS_CSCR_IWS(6) | MCF_CS_CSCR_AA | MCF_CS_CSCR_PS_16); MCF_CS_CSMR0 = MCF_CS_CSMR_BAM_2M | MCF_CS_CSMR_V; } /********************************************************************/ #ifndef ROM_TARGET void __initialize_hardware(void) { mcf523x_init(); return; } #endif void mcf523x_pit_init(void) { #ifdef HAS_PIT0 /* { */ /* Enable PIT 0 interrupts to ColdFire core */ if (checkICR(36, PIT0_LEVEL, PIT0_PRIORITY) ) __asm__("halt"); MCF_INTC0_ICR36 = MCF_INTC0_ICRn_IL(PIT0_LEVEL) | MCF_INTC0_ICRn_IP(PIT0_PRIORITY); /* Set Timer Interrupt Mask Register */ MCF_INTC0_IMRH &= (unsigned long) ~(MCF_INTC0_IMRH_INT_MASK36); MCF_PIT_PCSR(PIT0_DEVICE) = MCF_PIT_PCSR_PRE(PRESCALER0_VALUE) | MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_RLD; MCF_PIT_PMR(PIT0_DEVICE) = LOAD0_VALUE - 1; /* enable count and enable interrupt, disable overwrite PMR */ MCF_PIT_PCSR(PIT0_DEVICE) |= MCF_PIT_PCSR_EN | MCF_PIT_PCSR_PIE; MCF_PIT_PCSR(PIT0_DEVICE) &= (uint16) ~(MCF_PIT_PCSR_OVW); #endif /* } HAS_PIT0 */ } /* PIT 0 interrupt handler */ void pit0isrc(void); #ifdef HAS_PIT0 /* { */ uint32 pit0cnt; void pit0isrc(void) { pit0cnt++; /* clear interrupt */ MCF_PIT_PMR(PIT0_DEVICE) = LOAD0_VALUE - 1; IS_ProcessEventSourceTick((EVNTSRC)0, 1); LOWER; } #else void pit0isrc(void) { ; } #endif /* } HAS_PIT0 */ /********************************************************************/ /********************************************************************/ /* validate that duplicates level/priority settings don't exist within INTC */ int checkICR(int n, int level, int priority) { int i; unsigned char *pICR, icrvalue; icrvalue = (unsigned char) (MCF_INTC0_ICRn_IL(level) | MCF_INTC0_ICRn_IP(priority)); if (n < 64) { pICR = (unsigned char *)(&__IPSBAR[0x0C40]); /* INTC0 */ /* check ICR range ICR8...62 in INTC0 */ for(i = 8; i <= 62; i++) { if (i == n) /* skip self */ continue; if (*(pICR + i) == icrvalue) return 1; /* failure - duplicate IL/IP combo */ } } else { pICR = (unsigned char *)(&__IPSBAR[0x0D40 - 64]); /* INTC1 */ /* check ICR range ICR8...26 in INTC1 */ for(i = 8; i <= 26; i++) { if (i == n) /* skip self */ continue; if (*(pICR + i) == icrvalue) return 1; /* failure - duplicate IL/IP combo */ } } return 0; } /* NOTE: ICR # .GT. 63 refers to INTC1; e.g., 72 -> INTC1 + ICR8 */ void writeICR(int n, int level, int priority); void writeICR(int n, int level, int priority) { unsigned char *pICR, icrvalue; icrvalue = (unsigned char) (MCF_INTC0_ICRn_IL(level) | MCF_INTC0_ICRn_IP(priority)); if (n < 64) pICR = (unsigned char *)(&__IPSBAR[0x0C40]); /* INTC0 */ else pICR = (unsigned char *)(&__IPSBAR[0x0D40 - 64]); /* INTC1 */ *(pICR + n) = icrvalue; } void mcf523x_fec_init(void) { /* Enable FEC Rx Frame interrupts to ColdFire core */ if(checkICR(27, FEC_LEVEL, FEC_PRIORITY)) __asm__("halt"); MCF_INTC0_ICR27 = MCF_INTC0_ICRn_IL(FEC_LEVEL) | MCF_INTC0_ICRn_IP(FEC_PRIORITY); /* Set FEC Interrupt Mask Register */ MCF_INTC0_IMRL &= (unsigned long) ~(MCF_INTC0_IMRL_INT_MASK27 | MCF_INTC0_IMRL_MASKALL); } /* end of file - sysinit.c */