/* * File: sysinit.c * Purpose: Reset configuration of the M5223EVB * * Notes: */ #include "m5223evb.h" #include "common.h" /********************************************************************/ void mcf5223_init(void); void mcf5223_wtm_init(void); void mcf5223_pll_init(void); void mcf5223_uart_init(void); void mcf5223_scm_init(void); void mcf5223_gpio_init(void); /********************************************************************/ void mcf5223_init(void) { extern char __DATA_ROM[]; extern char __DATA_RAM[]; extern char __DATA_END[]; extern char __BSS_START[]; extern char __BSS_END[]; extern char __heap_addr[]; extern char __heap_size[]; extern uint32 VECTOR_TABLE[]; extern uint32 __VECTOR_RAM[]; extern uint8 __SRAM[]; extern uint8 __SRAM_SIZE[]; extern uint32 __SP_INIT[]; register uint32 n; register uint8 *dp, *sp; MCF_GPIO_PDDPAR = 0x0F;//enable pst[0..3] mcf5xxx_wr_vbr((uint32)VECTOR_TABLE); /* * Move initialized data from ROM to RAM. */ if (__DATA_ROM != __DATA_RAM) { dp = (uint8 *)__DATA_RAM; sp = (uint8 *)__DATA_ROM; n = (uint32)(__DATA_END - __DATA_RAM); while (n--) *dp++ = *sp++; } /* * Zero uninitialized data */ if (__BSS_START != __BSS_END) { sp = (uint8 *)__BSS_START; n = (uint32)(__BSS_END - __BSS_START); while (n--) *sp++ = 0; } /* * Set Port UA to initialize URXD0/UTXD0 */ MCF_GPIO_PUAPAR = 0 | MCF_GPIO_PUAPAR_RXD0_RXD0 | MCF_GPIO_PUAPAR_TXD0_TXD0; MCF_GPIO_PUBPAR = 0 | MCF_GPIO_PUBPAR_RXD1_RXD1 | MCF_GPIO_PUBPAR_TXD1_TXD1; uart_init(0); uart_init(1); /* Set real time clock freq */ MCF_CLOCK_RTCDR = 25000000; mcf5223_wtm_init(); mcf5223_pll_init(); mcf5223_scm_init(); mcf5223_gpio_init(); } /********************************************************************/ void mcf5223_wtm_init(void) { /* * Disable Software Watchdog Timer */ MCF_SCM_CWCR = 0; } /********************************************************************/ void mcf5223_pll_init(void) { /* The PLL pre-divider affects this!!! * Multiply 25Mhz reference crystal /CCHR by 12 to acheive system clock of 60Mhz */ MCF_CLOCK_SYNCR = MCF_CLOCK_SYNCR_MFD(4) | MCF_CLOCK_SYNCR_CLKSRC| MCF_CLOCK_SYNCR_PLLMODE | MCF_CLOCK_SYNCR_PLLEN ; while (!(MCF_CLOCK_SYNSR & MCF_CLOCK_SYNSR_LOCK)) { } } /********************************************************************/ void mcf5223_scm_init(void) { /* * Enable on-chip modules to access internal SRAM */ MCF_SCM_RAMBAR = (0 | MCF_SCM_RAMBAR_BA(SRAM_ADDRESS) | MCF_SCM_RAMBAR_BDE); } /********************************************************************/ tU08 gotlink; /**0; myctr--) { uart_isr(0); #ifdef DEBUG_PRINT if( ( myctr % 10000 ) == 0 ) { printf("."); } #endif while ( !(fec_mii_read(FEC_PHY0, PHY_REG_PSR, &mymrdata))) {}; if ((mymrdata & PHY_R17_ANNC) == PHY_R17_ANNC) { #ifdef DEBUG_PRINT printf("\nePHY Ready \n\n"); #endif break;} } //Read Proprietary Status Register (PSR) for status while ( !(fec_mii_read(FEC_PHY0, PHY_REG_PSR, &mymrdata))) { }; //CHECK PSR:Is link down??? if ((mymrdata & PHY_R17_LNK) == PHY_R17_LNK) { //No link present gotlink = 0; printf("\n@@@@ LINK IS DOWN @@@@\n\n"); } else { //Link present gotlink = 1; #ifdef DEBUG_PRINT printf("@@@@ LINK IS UP @@@@\n"); #endif while ( !(fec_mii_read(FEC_PHY0, PHY_REG_PSR, &mymrdata)) ) { }; if ((mymrdata & PHY_R17_ANNC) == PHY_R17_ANNC) { //Complete #ifdef DEBUG_PRINT printf("@@@@ A-N Complete @@@@\n"); #endif while ( !(fec_mii_read(FEC_PHY0, PHY_REG_PSR, &mymrdata)) ) { }; if ((mymrdata & PHY_R17_ANCM) == PHY_R17_ANCM) { //Common Mode found #ifdef DEBUG_PRINT printf("@@@@ No Comm mode @@@@\n"); #endif } else { //No common mode #ifdef DEBUG_PRINT printf("@@@@ Comm mode Est. @@@@\n"); #endif } } else { //Not complete #ifdef DEBUG_PRINT printf("@@@@ A-N FAILED! @@@@\n"); #endif } } while ( !(fec_mii_read(FEC_PHY0, PHY_REG_PSR, &mymrdata)) ) { }; if ((mymrdata & PHY_R17_SPD) == PHY_R17_SPD) { #ifdef DEBUG_PRINT printf("\n100bT "); #endif } else { #ifdef DEBUG_PRINT printf("\n10bT "); #endif } if ((mymrdata & PHY_R17_DPM) == PHY_R17_DPM) { #ifdef DEBUG_PRINT printf("Full Dup\n\n"); #endif } else { #ifdef DEBUG_PRINT printf("Half Dup\n\n"); #endif } // fec_mii_reg_printf(); for (myctr=20000; myctr >0; myctr--){uart_isr(0);} //Enable PHY interrupts in Reg 16 (PHY Interrupt Control Register) //Set PHY Interrupt Control Register mymwdata = PHY_R16_ACKIE | PHY_R16_PRIE | PHY_R16_LCIE | PHY_R16_ANIE; mymwdata = mymwdata | PHY_R16_PDFIE | PHY_R16_RFIE | PHY_R16_JABIE; while (!(fec_mii_write(FEC_PHY0, PHY_REG_IR, mymwdata))) { }; MCF_INTC0_ICR36 = MCF_INTC_ICR_IL(PHY_LEVEL)|MCF_INTC_ICR_IP(PHY_PRIORITY); MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_MASK36); MCF_PHY_EPHYCTL0 = MCF_PHY_EPHYCTL0 | (MCF_PHY_EPHYCTL0_EPHYIEN ); */ MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED((uint32)(SYS_CLK_MHZ/5)); // set phy address to zero MCF_PHY_EPHYCTL1 = MCF_PHY_EPHYCTL1_PHYADDR(FEC_PHY0); // FEC_PHY0 from MCF52235_EVB.h //Enable EPHY module with PHY clocks disabled //Do not turn on PHY clocks until both FEC and EPHY are completely setup (see Below) MCF_PHY_EPHYCTL0 = (uint8)(MCF_PHY_EPHYCTL0 & ~(MCF_PHY_EPHYCTL0_DIS100 | MCF_PHY_EPHYCTL0_DIS10)); //Disable auto_neg at start-up MCF_PHY_EPHYCTL0 = (uint8)(MCF_PHY_EPHYCTL0 | (MCF_PHY_EPHYCTL0_ANDIS)); //Enable EPHY module MCF_PHY_EPHYCTL0 = (uint8)(MCF_PHY_EPHYCTL0_EPHYEN | MCF_PHY_EPHYCTL0); // Force ePHY to manual, 100mbps, Half Duplexe (void)fec_mii_read(0, 0, ®0); reg0 |= 0x2000; // 100Mbps reg0 &= ~0x0100; // Half Duplexe reg0 &= ~0x1000; // Manual Mode (void)fec_mii_write( 0, 0, reg0 ); // (void)fec_mii_write( 0, 0, (reg0|0x0200) ); // Force re-negotiate // Startup delay // for (myctr=150000; myctr >0; myctr--){uart_isr(0);} //Enable PHY interrupts in Reg 16 (PHY Interrupt Control Register) //Set PHY Interrupt Control Register mymwdata = PHY_R16_ACKIE | PHY_R16_PRIE | PHY_R16_LCIE | PHY_R16_ANIE; mymwdata = mymwdata | PHY_R16_PDFIE | PHY_R16_RFIE | PHY_R16_JABIE; while (!(fec_mii_write(FEC_PHY0, PHY_REG_IR, mymwdata))) { }; MCF_INTC0_ICR36 = MCF_INTC_ICR_IL(3); MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_MASK36); MCF_PHY_EPHYCTL0 = MCF_PHY_EPHYCTL0 | (MCF_PHY_EPHYCTL0_EPHYIEN ); for (myctr=10000; myctr >0; myctr--){uart_check();} //***************************************************************************** // // Work-around for bug in hardware autonegotiation. // Attempt to connect at 100Mbps - Half Duplexe // Wait for seconds // Attempt to connect at 10Mbps - Half Duplexe // // Returns 10, or 100 on success, 0 on failure //***************************************************************************** if( 1 ) { // Force ePHY to manual, 100mbps, Half Duplexe while( !fec_mii_read(0, 0, ®0) ){}; reg0 |= 0x2000; // 100Mbps reg0 &= ~0x0100; // Half Duplexe reg0 &= ~0x1000; // Manual Mode while( !fec_mii_write( 0, 0, reg0 ) ){}; while( !fec_mii_write( 0, 0, (reg0|0x0200) )){}; // Force re-negotiate for( myctr=400000; myctr; myctr-- ) { uart_check(); (void)fec_mii_read(0, 1, ®1); if( reg1 & 0x0004 ) { // printf( "\nLink UP - 100 HD" ); return; } } // Force ePHY to manual, 10mbps, Half Duplexe while( !fec_mii_read(0, 0, ®0) ){}; reg0 &= ~0x2000; // 10Mbps reg0 &= ~0x0100; // Half Duplexe reg0 &= ~0x1000; // Manual Mode while( !fec_mii_write( 0, 0, reg0 ) ){}; while( !fec_mii_write( 0, 0, (reg0|0x0200) )){}; // Force re-negotiate #if 0 for( myctr=20000; myctr; myctr-- ) { uart_check(); (void)fec_mii_read(0, 1, ®1); printf( "\nLink UP - 10 HD" ); if( reg1 & 0x0004 ) { printf( "\nLink UP - 10 HD" ); return; } } #endif } printf("\nLink DOWN" ); return; } /********************************************************************/ void mcf5223_uart_init(void) { /* * Initialize all three UARTs for serial communications */ register uint16 ubgs; /* * Set Port UA to initialize URXD0/UTXD0 */ MCF_GPIO_PUAPAR = 0 | MCF_GPIO_PUAPAR_RXD0_RXD0 | MCF_GPIO_PUAPAR_TXD0_TXD0; MCF_GPIO_PUBPAR = 0 | MCF_GPIO_PUBPAR_RXD1_RXD1 | MCF_GPIO_PUBPAR_TXD1_TXD1; MCF_GPIO_PUCPAR = 0 | MCF_GPIO_PUCPAR_RXD2_RXD2 | MCF_GPIO_PUCPAR_TXD2_TXD2; /* * Reset Transmitter */ MCF_UART0_UCR = MCF_UART_UCR_RESET_TX; MCF_UART1_UCR = MCF_UART_UCR_RESET_TX; MCF_UART2_UCR = MCF_UART_UCR_RESET_TX; /* * Reset Receiver */ MCF_UART0_UCR = MCF_UART_UCR_RESET_RX; MCF_UART1_UCR = MCF_UART_UCR_RESET_RX; MCF_UART2_UCR = MCF_UART_UCR_RESET_RX; /* * Reset Mode Register */ MCF_UART0_UCR = MCF_UART_UCR_RESET_MR; MCF_UART1_UCR = MCF_UART_UCR_RESET_MR; MCF_UART2_UCR = MCF_UART_UCR_RESET_MR; /* * No parity, 8-bits per character */ MCF_UART0_UMR = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); MCF_UART1_UMR = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); MCF_UART2_UMR = (0 | MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8 ); /* * No echo or loopback, 1 stop bit */ MCF_UART0_UMR = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); MCF_UART1_UMR = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); MCF_UART2_UMR = (0 | MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1); /* * Set Rx and Tx baud by SYSTEM CLOCK */ MCF_UART0_UCSR = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); MCF_UART1_UCSR = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); MCF_UART2_UCSR = (0 | MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); /* * Mask all UART interrupts */ MCF_UART0_UIMR = 0; MCF_UART1_UIMR = 0; MCF_UART2_UIMR = 0; /* * Calculate baud settings */ ubgs = (uint16)((SYS_CLK_MHZ*1000000)/(UART_BAUD * 32)); MCF_UART0_UBG1 = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART0_UBG2 = (uint8)(ubgs & 0x00FF); MCF_UART1_UBG1 = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART1_UBG2 = (uint8)(ubgs & 0x00FF); MCF_UART2_UBG1 = (uint8)((ubgs & 0xFF00) >> 8); MCF_UART2_UBG2 = (uint8)(ubgs & 0x00FF); /* * Enable receiver and transmitter */ MCF_UART0_UCR = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); MCF_UART1_UCR = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); MCF_UART2_UCR = (0 | MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); } /********************************************************************/