32 #define TRACE_LEVEL NIC_TRACE_LEVEL
36 #include "em_device.h"
47 #if defined(__ICCARM__)
50 #pragma data_alignment = 8
53 #pragma data_alignment = 8
56 #pragma data_alignment = 4
59 #pragma data_alignment = 4
81 static uint_t txBufferIndex;
83 static uint_t rxBufferIndex;
120 volatile uint32_t status;
123 TRACE_INFO(
"Initializing EFM32GG11 Ethernet MAC...\r\n");
126 nicDriverInterface = interface;
129 CMU_ClockEnable(cmuClock_HFPER,
true);
131 CMU_ClockEnable(cmuClock_ETH,
true);
134 ETH->NETWORKCTRL = 0;
140 ETH->NETWORKCFG = (4 << _ETH_NETWORKCFG_MDCCLKDIV_SHIFT) &
141 _ETH_NETWORKCFG_MDCCLKDIV_MASK;
144 ETH->NETWORKCTRL |= _ETH_NETWORKCTRL_MANPORTEN_MASK;
147 if(interface->phyDriver != NULL)
150 error = interface->phyDriver->init(interface);
152 else if(interface->switchDriver != NULL)
155 error = interface->switchDriver->init(interface);
170 ETH->SPECADDR1BOTTOM = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
171 ETH->SPECADDR1TOP = interface->macAddr.w[2];
174 ETH->SPECADDR2BOTTOM = 0;
175 ETH->SPECADDR3BOTTOM = 0;
176 ETH->SPECADDR4BOTTOM = 0;
183 ETH->NETWORKCFG |= _ETH_NETWORKCFG_RX1536BYTEFRAMES_MASK |
184 _ETH_NETWORKCFG_MULTICASTHASHEN_MASK;
190 ETH->TXSTATUS = _ETH_TXSTATUS_TXUNDERRUN_MASK |
191 _ETH_TXSTATUS_TXCMPLT_MASK | _ETH_TXSTATUS_AMBAERR_MASK |
192 _ETH_TXSTATUS_TXGO_MASK | _ETH_TXSTATUS_RETRYLMTEXCD_MASK |
193 _ETH_TXSTATUS_COLOCCRD_MASK | _ETH_TXSTATUS_USEDBITREAD_MASK;
196 ETH->RXSTATUS = _ETH_RXSTATUS_RXOVERRUN_MASK | _ETH_RXSTATUS_FRMRX_MASK |
197 _ETH_RXSTATUS_BUFFNOTAVAIL_MASK;
200 ETH->IENC = 0xFFFFFFFF;
203 ETH->IENS = _ETH_IENS_RXOVERRUN_MASK |
204 _ETH_IENS_TXCMPLT_MASK | _ETH_IENS_AMBAERR_MASK |
205 _ETH_IENS_RTRYLMTORLATECOL_MASK | _ETH_IENS_TXUNDERRUN_MASK |
206 _ETH_IENS_RXUSEDBITREAD_MASK | _ETH_IENS_RXCMPLT_MASK;
220 ETH->NETWORKCTRL |= _ETH_NETWORKCTRL_ENBTX_MASK | _ETH_NETWORKCTRL_ENBRX_MASK;
238 #if defined(USE_EFM32_GIANT_GECKO_11_SK)
242 CMU_ClockEnable(cmuClock_GPIO,
true);
244 CMU_OscillatorEnable(cmuOsc_HFXO,
true,
true);
247 CMU->CTRL |= CMU_CTRL_CLKOUTSEL2_HFXO;
250 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_CMU_CLK2_PORT(5),
251 AF_CMU_CLK2_PIN(5), gpioModePushPull, 0);
254 temp = CMU->ROUTELOC0 & ~_CMU_ROUTELOC0_CLKOUT2LOC_MASK;
255 CMU->ROUTELOC0 = temp | CMU_ROUTELOC0_CLKOUT2LOC_LOC5;
258 CMU->ROUTEPEN |= CMU_ROUTEPEN_CLKOUT2PEN;
261 ETH->CTRL = ETH_CTRL_GBLCLKEN | ETH_CTRL_MIISEL_RMII;
264 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIITXD0_PORT(1),
265 AF_ETH_RMIITXD0_PIN(1), gpioModePushPull, 0);
268 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIITXD1_PORT(1),
269 AF_ETH_RMIITXD1_PIN(1), gpioModePushPull, 0);
272 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIITXEN_PORT(1),
273 AF_ETH_RMIITXEN_PIN(1), gpioModePushPull, 0);
276 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIIRXD0_PORT(1),
277 AF_ETH_RMIIRXD0_PIN(1), gpioModeInput, 0);
280 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIIRXD1_PORT(1),
281 AF_ETH_RMIIRXD1_PIN(1), gpioModeInput, 0);
284 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIICRSDV_PORT(1),
285 AF_ETH_RMIICRSDV_PIN(1), gpioModeInput, 0);
288 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_RMIIRXER_PORT(1),
289 AF_ETH_RMIIRXER_PIN(1), gpioModeInput, 0);
292 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_MDIO_PORT(1),
293 AF_ETH_MDIO_PIN(1), gpioModePushPull, 0);
296 GPIO_PinModeSet((GPIO_Port_TypeDef) AF_ETH_MDC_PORT(1),
297 AF_ETH_MDC_PIN(1), gpioModePushPull, 0);
300 temp = ETH->ROUTELOC1 & ~(_ETH_ROUTELOC1_RMIILOC_MASK & _ETH_ROUTELOC1_MDIOLOC_MASK);
301 ETH->ROUTELOC1 = temp | (ETH_ROUTELOC1_RMIILOC_LOC1 | ETH_ROUTELOC1_MDIOLOC_LOC1);
304 ETH->ROUTEPEN = ETH_ROUTEPEN_RMIIPEN | ETH_ROUTEPEN_MDIOPEN;
307 GPIO_PinModeSet(gpioPortI, 10, gpioModePushPull, 0);
309 GPIO_PinModeSet(gpioPortH, 7, gpioModePushPull, 0);
311 GPIO_PinModeSet(gpioPortG, 15, gpioModeInput, 0);
314 GPIO_PinOutSet(gpioPortI, 10);
318 GPIO_PinOutClear(gpioPortH, 7);
320 GPIO_PinOutSet(gpioPortH, 7);
360 rxBufferDesc[i].
status = 0;
369 ETH->TXQPTR = (uint32_t) txBufferDesc;
371 ETH->RXQPTR = (uint32_t) rxBufferDesc;
387 if(interface->phyDriver != NULL)
390 interface->phyDriver->tick(interface);
392 else if(interface->switchDriver != NULL)
395 interface->switchDriver->tick(interface);
412 NVIC_EnableIRQ(ETH_IRQn);
415 if(interface->phyDriver != NULL)
418 interface->phyDriver->enableIrq(interface);
420 else if(interface->switchDriver != NULL)
423 interface->switchDriver->enableIrq(interface);
440 NVIC_DisableIRQ(ETH_IRQn);
443 if(interface->phyDriver != NULL)
446 interface->phyDriver->disableIrq(interface);
448 else if(interface->switchDriver != NULL)
451 interface->switchDriver->disableIrq(interface);
467 volatile uint32_t isr;
468 volatile uint32_t tsr;
469 volatile uint32_t rsr;
487 if((tsr & (_ETH_TXSTATUS_TXUNDERRUN_MASK | _ETH_TXSTATUS_TXCMPLT_MASK |
488 _ETH_TXSTATUS_AMBAERR_MASK | _ETH_TXSTATUS_TXGO_MASK |
489 _ETH_TXSTATUS_RETRYLMTEXCD_MASK | _ETH_TXSTATUS_COLOCCRD_MASK |
490 _ETH_TXSTATUS_USEDBITREAD_MASK)) != 0)
496 if((txBufferDesc[txBufferIndex].status &
ETH_TX_USED) != 0)
504 if((rsr & (_ETH_RXSTATUS_RXOVERRUN_MASK | _ETH_RXSTATUS_FRMRX_MASK |
505 _ETH_RXSTATUS_BUFFNOTAVAIL_MASK)) != 0)
508 nicDriverInterface->nicEvent =
TRUE;
532 if((rsr & (_ETH_RXSTATUS_RXOVERRUN_MASK | _ETH_RXSTATUS_FRMRX_MASK |
533 _ETH_RXSTATUS_BUFFNOTAVAIL_MASK)) != 0)
578 if((txBufferDesc[txBufferIndex].status &
ETH_TX_USED) == 0)
607 ETH->NETWORKCTRL |= _ETH_NETWORKCTRL_TXSTRT_MASK;
610 if((txBufferDesc[txBufferIndex].status &
ETH_TX_USED) != 0)
648 j = rxBufferIndex + i;
664 if((rxBufferDesc[j].status &
ETH_RX_SOF) != 0)
671 if((rxBufferDesc[j].status &
ETH_RX_EOF) != 0 && sofIndex != UINT_MAX)
685 if(eofIndex != UINT_MAX)
689 else if(sofIndex != UINT_MAX)
702 for(i = 0; i < j; i++)
705 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
765 uint32_t hashTable[2];
773 ETH->SPECADDR1BOTTOM = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
774 ETH->SPECADDR1TOP = interface->macAddr.w[2];
790 entry = &interface->macAddrFilter[i];
802 k = (
p[0] >> 6) ^
p[0];
803 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
804 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
805 k ^= (
p[3] >> 6) ^
p[3];
806 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
807 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
813 hashTable[k / 32] |= (1 << (k % 32));
821 unicastMacAddr[j++] = entry->
addr;
831 ETH->SPECADDR2BOTTOM = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
832 ETH->SPECADDR2TOP = unicastMacAddr[0].w[2];
837 ETH->SPECADDR2BOTTOM = 0;
844 ETH->SPECADDR3BOTTOM = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
845 ETH->SPECADDR3TOP = unicastMacAddr[1].w[2];
850 ETH->SPECADDR3BOTTOM = 0;
857 ETH->SPECADDR4BOTTOM = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
858 ETH->SPECADDR4TOP = unicastMacAddr[2].w[2];
863 ETH->SPECADDR4BOTTOM = 0;
867 ETH->HASHBOTTOM = hashTable[0];
868 ETH->HASHTOP = hashTable[1];
871 TRACE_DEBUG(
" HASHBOTTOM = %08" PRIX32
"\r\n", ETH->HASHBOTTOM);
872 TRACE_DEBUG(
" HASHTOP = %08" PRIX32
"\r\n", ETH->HASHTOP);
890 config = ETH->NETWORKCFG;
895 config |= _ETH_NETWORKCFG_SPEED_MASK;
899 config &= ~_ETH_NETWORKCFG_SPEED_MASK;
905 config |= _ETH_NETWORKCFG_FULLDUPLEX_MASK;
909 config &= ~_ETH_NETWORKCFG_FULLDUPLEX_MASK;
913 ETH->NETWORKCFG = config;
937 temp = _ETH_PHYMNGMNT_WRITE1_MASK;
938 temp |= (1 << _ETH_PHYMNGMNT_OPERATION_SHIFT) & _ETH_PHYMNGMNT_OPERATION_MASK;
939 temp |= (2 << _ETH_PHYMNGMNT_WRITE10_SHIFT) & _ETH_PHYMNGMNT_WRITE10_MASK;
942 temp |= (phyAddr << _ETH_PHYMNGMNT_PHYADDR_SHIFT) & _ETH_PHYMNGMNT_PHYADDR_MASK;
944 temp |= (
regAddr << _ETH_PHYMNGMNT_REGADDR_SHIFT) & _ETH_PHYMNGMNT_REGADDR_MASK;
946 temp |=
data & _ETH_PHYMNGMNT_PHYRWDATA_MASK;
949 ETH->PHYMNGMNT = temp;
951 while((ETH->NETWORKSTATUS & _ETH_NETWORKSTATUS_MANDONE_MASK) == 0)
980 temp = _ETH_PHYMNGMNT_WRITE1_MASK;
981 temp |= (2 << _ETH_PHYMNGMNT_OPERATION_SHIFT) & _ETH_PHYMNGMNT_OPERATION_MASK;
982 temp |= (2 << _ETH_PHYMNGMNT_WRITE10_SHIFT) & _ETH_PHYMNGMNT_WRITE10_MASK;
985 temp |= (phyAddr << _ETH_PHYMNGMNT_PHYADDR_SHIFT) & _ETH_PHYMNGMNT_PHYADDR_MASK;
987 temp |= (
regAddr << _ETH_PHYMNGMNT_REGADDR_SHIFT) & _ETH_PHYMNGMNT_REGADDR_MASK;
990 ETH->PHYMNGMNT = temp;
992 while((ETH->NETWORKSTATUS & _ETH_NETWORKSTATUS_MANDONE_MASK) == 0)
997 data = ETH->PHYMNGMNT & _ETH_PHYMNGMNT_PHYRWDATA_MASK;