void vEMACInit( void ) { int iData; extern int periph_clk_khz; const unsigned portCHAR ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; /* Enable the ENET clock. */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; /* Allow concurrent access to MPU controller to avoid bus errors. */ MPU_CESR = 0; prvInitialiseDescriptors(); /* Reset and enable. */ ENET_ECR = ENET_ECR_RESET_MASK; /* Wait at least 8 clock cycles */ vTaskDelay( 2 ); /* Start the MII interface*/ mii_init( 0, periph_clk_khz / 1000L ); /* Configure the transmit interrupt. */ set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacTX_INTERRUPT_NO ); /* Configure the receive interrupt. */ set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacRX_INTERRUPT_NO ); /* Configure the error interrupt. */ set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacERROR_INTERRUPT_NO ); /* Configure the pins to the PHY - RMII mode used. */ PORTB_PCR0 = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */ PORTB_PCR1 = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */ PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */ PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */ PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */ PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */ PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */ PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */ /* Is there communication with the PHY? */ do { vTaskDelay( emacLINK_DELAY ); iData = 0xFFFF; mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData ); } while( iData == 0xFFFF ); /* Start to auto negotiate. */ mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) ); /* Wait for auto negotiate to complete. */ do { vTaskDelay( emacLINK_DELAY ); mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData ); } while( !( iData & PHY_BMSR_AN_COMPLETE ) ); /* A link has been established. What was negotiated? */ iData = 0; mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData ); /* Clear the Individual and Group Address Hash registers */ ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; /* Set the Physical Address for the selected ENET */ enet_set_address( 0, ucMACAddress ); ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; /* Clear the control registers. */ ENET_TCR = 0; if( iData & emacPHY_DUPLEX_STATUS ) { /* Full duplex */ ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { /* Half duplex */ ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK; } if( iData & emacPHY_SPEED_STATUS ) { /* 10Mbps */ ENET_RCR |= ENET_RCR_RMII_10T_MASK; } ENET_ECR = ENET_ECR_EN1588_MASK; /* Store and forward checksum. */ ENET_TFWR = ENET_TFWR_STRFWD_MASK; /* Set Rx Buffer Size */ ENET_MRBR = ( unsigned short ) UIP_BUFSIZE; /* Point to the start of the circular Rx buffer descriptor queue */ ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] ); /* Point to the start of the circular Tx buffer descriptor queue */ ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] ); /* Clear all ENET interrupt events */ ENET_EIR = ( unsigned long ) -1; /* Enable interrupts. */ ENET_EIMR = 0 /*rx irqs*/ | ENET_EIMR_RXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/ /*xmit irqs*/ | ENET_EIMR_TXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/ /*enet irqs*/ | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK ; /* Enable the MAC itself. */ ENET_ECR |= ENET_ECR_ETHEREN_MASK; /* Indicate that there have been empty receive buffers produced */ ENET_RDAR = ENET_RDAR_RDAR_MASK; }
/* ===================================================================*/ LDD_TDeviceData* ETH1_Init(LDD_TUserData *UserDataPtr) { ETH1_TDeviceData *DeviceDataPrv; ETH1_TTxQueueItem *TxQueueItemPtr; ETH1_TRxQueueItem *RxQueueItemPtr; uint8_t* MemPtr; /* Allocate internal device data structure */ /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->DuplexMode = LDD_ETH_FULL_DUPLEX; /* Store duplex mode configuration */ DeviceDataPrv->FilterMode = LDD_ETH_ACCEPT_BC; /* Store filter mode configuration */ DeviceDataPrv->SleepMode = LDD_ETH_DISABLED; /* Store sleep mode configuration */ DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ DeviceDataPrv->Index = 0U; /* Set the component instance index */ DeviceDataPrv->EventMask = /* Initialize the event mask */ LDD_ETH_ON_FRAME_TRANSMITTED | LDD_ETH_ON_FRAME_RECEIVED | LDD_ETH_ON_FATAL_ERROR |0U; DeviceDataPrv->EnabledMode = TRUE; /* Enable the device clock configuration */ /* SIM_SCGC2: ENET=1 */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; ENET_PDD_DisableDevice(ENET_BASE_PTR); DeviceDataPrv->Enabled = FALSE; ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, FALSE); /* Disable statistic counters */ ENET_PDD_ClearMIBCounters(ENET_BASE_PTR); /* Clear statistic counters */ ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, TRUE); /* Enable statistic counters */ /* Set pin assignments */ /* PORTB_PCR1: ISF=0,MUX=4 */ PORTB_PCR1 = (uint32_t)((PORTB_PCR1 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTB_PCR0: ISF=0,MUX=4 */ PORTB_PCR0 = (uint32_t)((PORTB_PCR0 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR16: ISF=0,MUX=4 */ PORTA_PCR16 = (uint32_t)((PORTA_PCR16 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR17: ISF=0,MUX=4 */ PORTA_PCR17 = (uint32_t)((PORTA_PCR17 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR15: ISF=0,MUX=4 */ PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR14: ISF=0,MUX=4 */ PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR13: ISF=0,MUX=4 */ PORTA_PCR13 = (uint32_t)((PORTA_PCR13 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR12: ISF=0,MUX=4 */ PORTA_PCR12 = (uint32_t)((PORTA_PCR12 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* Set interrupt priorities */ /* NVICIP76: PRI76=0x80 */ NVICIP76 = NVIC_IP_PRI76(0x80); /* NVICISER2: SETENA|=0x1000 */ NVICISER2 |= NVIC_ISER_SETENA(0x1000); /* NVICIP77: PRI77=0x80 */ NVICIP77 = NVIC_IP_PRI77(0x80); /* NVICISER2: SETENA|=0x2000 */ NVICISER2 |= NVIC_ISER_SETENA(0x2000); /* NVICIP78: PRI78=0x80 */ NVICIP78 = NVIC_IP_PRI78(0x80); /* NVICISER2: SETENA|=0x4000 */ NVICISER2 |= NVIC_ISER_SETENA(0x4000); /* Set interrupt mask */ /* ENET_EIMR: ??=0,BABR=0,BABT=0,GRA=0,TXF=1,TXB=0,RXF=1,RXB=0,MII=0,EBERR=1,LC=0,RL=0,UN=0,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ ENET_EIMR = (ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK); /* Clear interrupt flags */ /* ENET_EIR: ??=1,BABR=1,BABT=1,GRA=1,TXF=1,TXB=1,RXF=1,RXB=1,MII=1,EBERR=1,LC=1,RL=1,UN=1,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ ENET_EIR = ENET_EIR_BABR_MASK | ENET_EIR_BABT_MASK | ENET_EIR_GRA_MASK | ENET_EIR_TXF_MASK | ENET_EIR_TXB_MASK | ENET_EIR_RXF_MASK | ENET_EIR_RXB_MASK | ENET_EIR_MII_MASK | ENET_EIR_EBERR_MASK | ENET_EIR_LC_MASK | ENET_EIR_RL_MASK | ENET_EIR_UN_MASK | 0x80000000U; /* Allocate the transmit frame interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Transmit__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Allocate the receive frame interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Receive__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Allocate the shared interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Error__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Set MAC address */ /* ENET_PALR: PADDR1=0x43EF783A */ ENET_PALR = ENET_PALR_PADDR1(0x43EF783A); /* ENET_PAUR: PADDR2=0x2E19,TYPE=0 */ ENET_PAUR = (ENET_PAUR_PADDR2(0x2E19) | ENET_PAUR_TYPE(0x00)); /* Set unicast address hash table */ /* ENET_IAUR: IADDR1=0 */ ENET_IAUR = ENET_IAUR_IADDR1(0x00); /* ENET_IALR: IADDR2=0 */ ENET_IALR = ENET_IALR_IADDR2(0x00); /* Set multicast address hash table */ /* ENET_GAUR: GADDR1=0 */ ENET_GAUR = ENET_GAUR_GADDR1(0x00); /* ENET_GALR: GADDR2=0 */ ENET_GALR = ENET_GALR_GADDR2(0x00); /* Set PAUSE frame duration */ /* ENET_OPD: OPCODE=0,PAUSE_DUR=0 */ ENET_OPD = (ENET_OPD_OPCODE(0x00) | ENET_OPD_PAUSE_DUR(0x00)); /* Set transmit control register */ /* ENET_TCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CRCFWD=0,ADDINS=0,ADDSEL=0,RFC_PAUSE=0,TFC_PAUSE=0,FDEN=1,??=0,GTS=0 */ ENET_TCR = (ENET_TCR_ADDSEL(0x00) | ENET_TCR_FDEN_MASK); /* Set transmit accelerator function configuration register */ /* ENET_TACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PROCHK=0,IPCHK=0,??=0,??=0,SHIFT16=0 */ ENET_TACC = 0x00U; /* Set receive control register */ /* ENET_RCR: GRS=0,NLC=0,MAX_FL=0x05EE,CFEN=0,CRCFWD=0,PAUFWD=1,PADEN=0,??=0,??=0,RMII_10T=0,RMII_MODE=1,??=0,??=0,FCE=1,BC_REJ=0,PROM=0,MII_MODE=1,DRT=0,LOOP=0 */ ENET_RCR = ENET_RCR_MAX_FL(0x05EE) | ENET_RCR_PAUFWD_MASK | ENET_RCR_RMII_MODE_MASK | ENET_RCR_FCE_MASK | ENET_RCR_MII_MODE_MASK; /* Set receive accelerator function configuration register */ /* ENET_RACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,SHIFT16=0,LINEDIS=0,??=0,??=0,??=0,PRODIS=0,IPDIS=0,PADREM=0 */ ENET_RACC = 0x00U; /* Set transmit inter-packet gap */ /* ENET_TIPG: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,IPG=8 */ ENET_TIPG = ENET_TIPG_IPG(0x08); /* Set frame truncation length */ /* ENET_FTRL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TRUNC_FL=0x0800 */ ENET_FTRL = ENET_FTRL_TRUNC_FL(0x0800); /* Set transmit FIFO watermark */ /* ENET_TFWR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,STRFWD=1,??=0,??=0,TFWR=0 */ ENET_TFWR = (ENET_TFWR_STRFWD_MASK | ENET_TFWR_TFWR(0x00)); /* Set transmit FIFO section empty threshold */ /* ENET_TSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_SECTION_EMPTY=0 */ ENET_TSEM = ENET_TSEM_TX_SECTION_EMPTY(0x00); /* Set transmit FIFO almost empty threshold */ /* ENET_TAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_EMPTY=8 */ ENET_TAEM = ENET_TAEM_TX_ALMOST_EMPTY(0x08); /* Set transmit FIFO almost full threshold */ /* ENET_TAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_FULL=8 */ ENET_TAFL = ENET_TAFL_TX_ALMOST_FULL(0x08); /* Set receive FIFO section full threshold */ /* ENET_RSFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_FULL=0 */ ENET_RSFL = ENET_RSFL_RX_SECTION_FULL(0x00); /* Set receive FIFO section empty threshold */ /* ENET_RSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_EMPTY=0 */ ENET_RSEM = ENET_RSEM_RX_SECTION_EMPTY(0x00); /* Set receive FIFO almost empty threshold */ /* ENET_RAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_EMPTY=8 */ ENET_RAEM = ENET_RAEM_RX_ALMOST_EMPTY(0x08); /* Set receive FIFO almost full threshold */ /* ENET_RAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_FULL=8 */ ENET_RAFL = ENET_RAFL_RX_ALMOST_FULL(0x08); /* Set MII speed control register */ /* ENET_MSCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HOLDTIME=7,DIS_PRE=1,MII_SPEED=3,??=0 */ ENET_MSCR = ENET_MSCR_HOLDTIME(0x07) | ENET_MSCR_DIS_PRE_MASK | ENET_MSCR_MII_SPEED(0x03); /* Set receive buffer size */ /* ENET_MRBR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,R_BUF_SIZE=0,??=0,??=0,??=0,??=0 */ ENET_MRBR = ENET_MRBR_R_BUF_SIZE(0x00); /* Initialize the transmit frame buffer queue */ LDD_QUEUE_INIT(ETH1_TTxQueueItem, DeviceDataPrv->TxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */ TxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue); while (TxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->TxQueue) + 1)) { /* Clear queue item */ for (MemPtr = (uint8_t*)(uint32_t)TxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(TxQueueItemPtr + 1); MemPtr++) { *MemPtr = 0U; } TxQueueItemPtr++; /* Move to the next queue item */ } setReg32(ENET_TDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue)); /* Initialize the receive frame buffer queue */ LDD_QUEUE_INIT(ETH1_TRxQueueItem, DeviceDataPrv->RxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */ RxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue); while (RxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->RxQueue) + 1)) { /* Clear queue item */ for (MemPtr = (uint8_t*)(uint32_t)RxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(RxQueueItemPtr + 1); MemPtr++) { *MemPtr = 0U; } RxQueueItemPtr++; /* Move to the next queue item */ } setReg32(ENET_RDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue)); /* ENET_ECR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DBSWP=0,STOPEN=0,DBGEN=0,??=0,EN1588=0,SLEEP=0,MAGICEN=0,ETHEREN=0,RESET=0 */ ENET_ECR = 0x00U; /* Enable the device */ ENET_PDD_EnableDevice(ENET_BASE_PTR); DeviceDataPrv->Enabled = TRUE; /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ETH1_ID,DeviceDataPrv); return (LDD_TDeviceData*)DeviceDataPrv; }
void imxenet_init(struct imxenet_softc *sc) { struct ifnet *ifp = &sc->sc_ac.ac_if; int speed = 0; uint32_t rate = clk_get_rate(clk_get("enet_ref")); /* reset the controller */ HWRITE4(sc, ENET_ECR, ENET_ECR_RESET); while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); /* set hw address */ HWRITE4(sc, ENET_PALR, (sc->sc_ac.ac_enaddr[0] << 24) | (sc->sc_ac.ac_enaddr[1] << 16) | (sc->sc_ac.ac_enaddr[2] << 8) | sc->sc_ac.ac_enaddr[3]); HWRITE4(sc, ENET_PAUR, (sc->sc_ac.ac_enaddr[4] << 24) | (sc->sc_ac.ac_enaddr[5] << 16)); /* clear outstanding interrupts */ HWRITE4(sc, ENET_EIR, 0xffffffff); /* set address filter */ HWRITE4(sc, ENET_GAUR, 0); HWRITE4(sc, ENET_GALR, 0); /* set max receive buffer size, 3-0 bits always zero for alignment */ HWRITE4(sc, ENET_MRBR, ENET_MAX_PKT_SIZE); /* init descriptor */ imxenet_init_txd(sc); imxenet_init_rxd(sc); /* set descriptor */ HWRITE4(sc, ENET_TDSR, sc->txdma.dma_paddr); HWRITE4(sc, ENET_RDSR, sc->rxdma.dma_paddr); /* set it to full-duplex */ HWRITE4(sc, ENET_TCR, ENET_TCR_FDEN); /* * Set max frame length to 1518 or 1522 with VLANs, * pause frames and promisc mode. * XXX: RGMII mode - phy dependant */ HWRITE4(sc, ENET_RCR, ENET_RCR_MAX_FL(1522) | ENET_RCR_RGMII_MODE | ENET_RCR_MII_MODE | ENET_RCR_FCE); bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR, (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100); /* RX FIFO treshold and pause */ HWRITE4(sc, ENET_RSEM, 0x84); HWRITE4(sc, ENET_RSFL, 16); HWRITE4(sc, ENET_RAEM, 8); HWRITE4(sc, ENET_RAFL, 8); HWRITE4(sc, ENET_OPD, 0xFFF0); /* do store and forward, only i.MX6, needs to be set correctly else */ HWRITE4(sc, ENET_TFWR, ENET_TFWR_STRFWD); /* enable gigabit-ethernet and set it to support little-endian */ switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { case IFM_1000_T: /* Gigabit */ speed |= ENET_ECR_SPEED; break; default: speed &= ~ENET_ECR_SPEED; break; } HWRITE4(sc, ENET_ECR, ENET_ECR_ETHEREN | speed | ENET_ECR_DBSWP); #ifdef ENET_ENHANCED_BD HSET4(sc, ENET_ECR, ENET_ECR_EN1588); #endif /* rx descriptors are ready */ HWRITE4(sc, ENET_RDAR, ENET_RDAR_RDAR); /* Indicate we are up and running. */ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; /* enable interrupts for tx/rx */ HWRITE4(sc, ENET_EIMR, ENET_EIR_TXF | ENET_EIR_RXF); HWRITE4(sc, ENET_EIMR, 0xffffffff); imxenet_start(ifp); }
/* * LPLD_ENET_Init * ENET模块初始化,包括PHY收发器初始化,MAC初始化,BD初始化 * * 参数: * *MACAddress--MAC地址指针 * * 输出: * 无 */ void LPLD_ENET_Init(const uint8* MACAddress) { uint16 usData; //使能ENET时钟 SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; //允许并发访问MPU控制器 MPU_CESR = 0; //缓冲区描述符初始化 LPLD_ENET_BDInit(); //复位ENET ENET_ECR = ENET_ECR_RESET_MASK; //等待至少8个时钟周期 for( usData = 0; usData < 10; usData++ ) { asm( "NOP" ); } //初始化MII接口 LPLD_ENET_MiiInit(periph_clk_khz/1000/*MHz*/); //使能中断并设置优先级 set_irq_priority (76, 6); enable_irq(76); //ENET发送中断 set_irq_priority (77, 6); enable_irq(77); //ENET接收中断 //set_irq_priority (78, 6); //enable_irq(78); //ENET错误及其他中断 //使能GPIO引脚复用功能 PORTB_PCR0 = PORT_PCR_MUX(4); //GPIO;//RMII0_MDIO/MII0_MDIO PORTB_PCR1 = PORT_PCR_MUX(4); //GPIO;//RMII0_MDC/MII0_MDC PORTA_PCR14 = PORT_PCR_MUX(4); //RMII0_CRS_DV/MII0_RXDV PORTA_PCR12 = PORT_PCR_MUX(4); //RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4); //RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4); //RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4); //RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4); //RMII0_TXD1/MII0_TXD1 //等待PHY收发器复位完成 do { LPLD_ENET_Delay( ENET_LINK_DELAY ); usData = 0xffff; LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYIDR1, &usData ); } while( usData == 0xffff ); #ifdef PHY_PRINT_REG printf("PHY_PHYIDR1=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYIDR2, &usData ); printf("PHY_PHYIDR2=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_ANLPAR, &usData ); printf("PHY_ANLPAR=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_ANLPARNP, &usData ); printf("PHY_ANLPARNP=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYSTS, &usData ); printf("PHY_PHYSTS=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_MICR, &usData ); printf("PHY_MICR=0x%X\r\n",usData); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_MISR, &usData ); printf("PHY_MISR=0x%X\r\n",usData); #endif //开始自动协商 LPLD_ENET_MiiWrite(CFG_PHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) ); #ifdef PHY_PRINT_REG LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_BMCR, &usData ); printf("PHY_BMCR=0x%X\r\n",usData); #endif //等待自动协商完成 do { LPLD_ENET_Delay( ENET_LINK_DELAY ); LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_BMSR, &usData ); } while( !( usData & PHY_BMSR_AN_COMPLETE ) ); #ifdef PHY_PRINT_REG printf("PHY_BMSR=0x%X\r\n",usData); #endif //根据协商结果设置ENET模块 LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_STATUS, &usData ); #ifdef PHY_PRINT_REG printf("PHY_STATUS=0x%X\r\n",usData); #endif //清除单独和组地址哈希寄存器 ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; //设置ENET模块MAC地址 LPLD_ENET_SetAddress(MACAddress); //设置接收控制寄存器,最大长度、RMII模式、接收CRC校验等 ENET_RCR = ENET_RCR_MAX_FL(CFG_ENET_MAX_PACKET_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; //清除发送接收控制 ENET_TCR = 0; //通讯方式设置 if( usData & PHY_DUPLEX_STATUS ) { //全双工 ENET_RCR &= (unsigned long)~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { //半双工 ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= (unsigned long)~ENET_TCR_FDEN_MASK; } //通信速率设置 if( usData & PHY_SPEED_STATUS ) { //10Mbps ENET_RCR |= ENET_RCR_RMII_10T_MASK; } //使用非增强型缓冲区描述符 ENET_ECR = 0; //设置接收缓冲区长度 ENET_MRBR = (unsigned short) CFG_ENET_RX_BUFFER_SIZE; //指向环形接收缓冲区描述符序列的头地址 ENET_RDSR = ( unsigned long ) &( xENETRxDescriptors[ 0 ] ); //指向环形发送缓冲区描述符序列的头地址 ENET_TDSR = ( unsigned long ) xENETTxDescriptors; //清除ENET中断事件 ENET_EIR = ( unsigned long ) -1; //使能中断 ENET_EIMR = 0 | ENET_EIMR_RXF_MASK //接收中断 | ENET_EIMR_TXF_MASK //发送中断 //ENET中断 | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK | ENET_EIMR_RXB_MASK ; //使能ENET模块 ENET_ECR |= ENET_ECR_ETHEREN_MASK; //表明接收缓冲区为空 ENET_RDAR = ENET_RDAR_RDAR_MASK; }
//======================================================================== //函数名称:hw_mac_init //功能概要:初始化链路层 //参数说明:ucMACAddress:MAC地址 //函数返回:无 //======================================================================== void hw_mac_init(uint8 ucMACAddress[]) { uint16 usData; //初始化缓冲区 prvInitialiseENETBuffers(); //查询物理层自动协商的结果,根据自动协商的结果配置链路层 usData = 0; mii_read(PHY_ADDRESS, PHY_STATUS, &usData ); //清除单独和组地址哈希寄存器 ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0xFFFFFFFF; ENET_GAUR = 0xFFFFFFFF; //设置MAC地址 enet_set_address(ucMACAddress); ENET_RCR = ENET_RCR_MAX_FL(configENET_BUFFER_SIZE) //最大帧长 | ENET_RCR_MII_MODE_MASK //必须置1 | ENET_RCR_CRCFWD_MASK //接受时取出CRC校验码 | ENET_RCR_RMII_MODE_MASK;//RMII模式使能 //清除发送寄存器 ENET_TCR = 0; //设置半双工,全双工 if( usData & PHY_DUPLEX_STATUS ) { //全双工 ENET_RCR &= (uint16)~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { //半双工 ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= (uint16)~ENET_TCR_FDEN_MASK; } //设置速度(默认100M) if( usData & PHY_SPEED_STATUS ) { //10M ENET_RCR |= ENET_RCR_RMII_10T_MASK; } ENET_ECR = 0;//使用非增强型缓冲区描述符 //设置接受缓冲区大小 ENET_MRBR = (uint16) configENET_BUFFER_SIZE; //接受描述符激活寄存器只想第一个接受缓冲区 ENET_RDSR = (uint32) &( xENETRxDescriptors[ 0 ] ); //接发送描述符激活寄存器只想第一个发送缓冲区 ENET_TDSR = (uint32) pxENETTxDescriptor; //清除所有以太网中断标志 ENET_EIR = (uint32) -1; //使能中断 ENET_EIMR = ENET_EIR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_RXB_MASK | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK; //使能以太网模块 ENET_ECR |= ENET_ECR_ETHEREN_MASK; //只是有空的接受缓冲区生成 ENET_RDAR = ENET_RDAR_RDAR_MASK; }
/** * In this function, the hardware should be initialized. * Called from ethernetif_init(). * * @param netif the already initialized lwip network interface structure * for this ethernetif */ static void low_level_init(struct netif *netif) { StatusType result; int data; /* set MAC hardware address length */ netif->hwaddr_len = ETHARP_HWADDR_LEN; /* set MAC hardware address */ netif->hwaddr[0] = MAC_ADDR0; netif->hwaddr[1] = MAC_ADDR1; netif->hwaddr[2] = MAC_ADDR2; netif->hwaddr[3] = MAC_ADDR3; netif->hwaddr[4] = MAC_ADDR4; netif->hwaddr[5] = MAC_ADDR5; /* maximum transfer unit */ netif->mtu = ENET_MAX_PKT_SIZE - 20; /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; /* enable the ENET clock */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; /* allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise bus error */ MPU_CESR = 0; init_enet_bufs(); /* create semaphores */ sem_rx = CoCreateSem(NUM_ENET_TX_BUFS, NUM_ENET_TX_BUFS, 1); sem_tx = CoCreateSem(0, NUM_ENET_RX_BUFS, 1); /* Set the Reset bit and clear the Enable bit */ ENET_ECR = ENET_ECR_RESET_MASK; /* Wait at least 8 clock cycles */ for (data = 0; data < 10; data++) { asm("NOP"); } /* start MII interface */ mii_init(50/*BUS_CLOCK*/); // enet tx interrupt NVIC_SetPriority(ENET_Transmit_IRQn, 6); NVIC_EnableIRQ(ENET_Transmit_IRQn); // enet rx interrupt NVIC_SetPriority(ENET_Receive_IRQn, 6); NVIC_EnableIRQ(ENET_Receive_IRQn); //enet error interrupt NVIC_SetPriority(ENET_Error_IRQn, 6); NVIC_EnableIRQ(ENET_Error_IRQn); /* Make sure the external interface signals are enabled */ PORTB_PCR0 = PORT_PCR_MUX(4); //RMII0_MDIO/MII0_MDIO PORTB_PCR1 = PORT_PCR_MUX(4); //RMII0_MDC/MII0_MDC #if USE_MII_MODE PORTA_PCR14 = PORT_PCR_MUX(4); //RMII0_CRS_DV/MII0_RXDV //PORTA_PCR5 = PORT_PCR_MUX(4); //RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4); //RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4); //RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4); //RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4); //RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4); //RMII0_TXD1/MII0_TXD1 PORTA_PCR11 = PORT_PCR_MUX(4); //MII0_RXCLK PORTA_PCR25 = PORT_PCR_MUX(4); //MII0_TXCLK PORTA_PCR9 = PORT_PCR_MUX(4); //MII0_RXD3 PORTA_PCR10 = PORT_PCR_MUX(4); //MII0_RXD2 PORTA_PCR28 = PORT_PCR_MUX(4); //MII0_TXER PORTA_PCR24 = PORT_PCR_MUX(4); //MII0_TXD2 PORTA_PCR26 = PORT_PCR_MUX(4); //MII0_TXD3 PORTA_PCR27 = PORT_PCR_MUX(4); //MII0_CRS PORTA_PCR29 = PORT_PCR_MUX(4); //MII0_COL #else PORTA_PCR14 = PORT_PCR_MUX(4); //RMII0_CRS_DV/MII0_RXDV // PORTA_PCR5 = PORT_PCR_MUX(4); //RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4); //RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4); //RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4); //RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4); //RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4); //RMII0_TXD1/MII0_TXD1 #endif /* USE_MII_MODE */ /* Can we talk to the PHY? */ do { CoTickDelay(PHY_LINK_DELAY); data = 0xffff; mii_read(PHY_ADDR, MII_PHYID1, (uint16_t*)&data); } while (data == 0xffff); /* Start auto negotiate. */ mii_write(PHY_ADDR, MII_BMCR, (MII_BMCR_ANRESTART | MII_BMCR_ANENABLE)); /* Wait for auto negotiate to complete. */ do { CoTickDelay(PHY_LINK_DELAY); mii_read(PHY_ADDR, MII_BMSR, (uint16_t*)&data); } while (!(data & MII_BMSR_ANEGCOMPLETE)); /* When we get here we have a link - find out what has been negotiated. */ data = 0; mii_read(PHY_ADDR, PHY_STATUS, (uint16_t*)&data); /* Set the Physical Address for the selected ENET */ ENET_PALR = (uint32_t)((netif->hwaddr[0] << 24) | (netif->hwaddr[1] << 16) | (netif->hwaddr[2] << 8) | netif->hwaddr[3]); ENET_PAUR = (uint32_t)((netif->hwaddr[4] << 24) | (netif->hwaddr[5] << 16)); /* Clear the Individual and Group Address Hash registers */ ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; #if USE_MII_MODE /* various mode/status setup */ ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK; #else ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; #endif /* clear rx/tx control registers */ ENET_TCR = 0; /* setup half or full duplex */ if (data & PHY_DUPLEX_STATUS) { /* full duplex */ ENET_RCR &= ~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { /* half duplex */ ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= ~ENET_TCR_FDEN_MASK; } /* Setup speed */ if (data & PHY_SPEED_STATUS) { /* 10Mbps */ ENET_RCR |= ENET_RCR_RMII_10T_MASK; } #if USE_PROMISCUOUS_MODE ENET_RCR |= ENET_RCR_PROM_MASK; #endif #ifdef ENHANCED_BD ENET_ECR = ENET_ECR_EN1588_MASK; #else ENET_ECR = 0; #endif #if ENET_HARDWARE_CHECKSUM /* enable discard on wrong protocol checksum and other nice features */ ENET_RACC = ENET_RACC_IPDIS_MASK | ENET_RACC_PRODIS_MASK | ENET_RACC_LINEDIS_MASK | ENET_RACC_IPDIS_MASK | ENET_RACC_PADREM_MASK; /* enable protocol checksum insertion */ ENET_TACC = ENET_TACC_IPCHK_MASK | ENET_TACC_PROCHK_MASK; #endif ENET_TFWR = ENET_TFWR_STRFWD_MASK; #if ENET_HARDWARE_SHIFT /* enable ethernet header alignment for rx */ ENET_RACC |= ENET_RACC_SHIFT16_MASK; /* enable ethernet header alignment for tx */ ENET_TACC |= ENET_TACC_SHIFT16_MASK; #endif /* set rx buffer size */ ENET_MRBR = ENET_RX_BUF_SIZE; /* point to the start of the circular rx buffer descriptor queue */ ENET_RDSR = (uint32_t)rx_bd; /* point to the start of the circular tx buffer descriptor queue */ ENET_TDSR = (uint32_t)tx_bd; /* clear all ENET interrupt events */ ENET_EIR = -1u; /* enable interrupts */ ENET_EIMR = 0 /* rx irqs */ | ENET_EIMR_RXF_MASK /* only for complete frame, not partial buffer descriptor */ /* tx irqs */ | ENET_EIMR_TXF_MASK /* only for complete frame, not partial buffer descriptor */ /* others enet irqs */ | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK; /* create the task that handles the MAC ENET */ result = CoCreateTask((FUNCPtr)ethernetif_input, (void *)netif, TASK_ETHIF_PRIO, &stack[TASK_ETHIF_STACK_SIZE - 1], TASK_ETHIF_STACK_SIZE); if (result == E_CREATE_FAIL) { LWIP_DEBUGF(NETIF_DEBUG,("Task for ETH recive created failed !\n\r ")); }; /* Enable the MAC itself */ ENET_ECR |= ENET_ECR_ETHEREN_MASK; /* Indicate that there have been empty receive buffers produced */ ENET_RDAR = ENET_RDAR_RDAR_MASK; }