32 #define TRACE_LEVEL NIC_TRACE_LEVEL
35 #include "fsl_device_registers.h"
37 #include "fsl_iomuxc.h"
46 #if defined(__ICCARM__)
49 #pragma data_alignment = 64
50 #pragma location = MIMXRT1040_ETH_RAM_SECTION
53 #pragma data_alignment = 64
54 #pragma location = MIMXRT1040_ETH_RAM_SECTION
57 #pragma data_alignment = 64
58 #pragma location = MIMXRT1040_ETH_RAM_SECTION
61 #pragma data_alignment = 64
62 #pragma location = MIMXRT1040_ETH_RAM_SECTION
84 static uint_t txBufferIndex;
86 static uint_t rxBufferIndex;
126 TRACE_INFO(
"Initializing i.MX RT1040 Ethernet MAC...\r\n");
129 nicDriverInterface = interface;
132 CLOCK_EnableClock(kCLOCK_Enet);
138 ENET->ECR = ENET_ECR_RESET_MASK;
140 while((ENET->ECR & ENET_ECR_RESET_MASK) != 0)
146 ENET_RCR_RMII_MODE_MASK | ENET_RCR_MII_MODE_MASK;
151 ENET->MSCR = ENET_MSCR_HOLDTIME(10) | ENET_MSCR_MII_SPEED(120);
154 if(interface->phyDriver != NULL)
157 error = interface->phyDriver->init(interface);
159 else if(interface->switchDriver != NULL)
162 error = interface->switchDriver->init(interface);
177 value = interface->macAddr.b[5];
178 value |= (interface->macAddr.b[4] << 8);
179 ENET->PAUR = ENET_PAUR_PADDR2(
value) | ENET_PAUR_TYPE(0x8808);
182 value = interface->macAddr.b[3];
183 value |= (interface->macAddr.b[2] << 8);
184 value |= (interface->macAddr.b[1] << 16);
185 value |= (interface->macAddr.b[0] << 24);
186 ENET->PALR = ENET_PALR_PADDR1(
value);
201 ENET->ECR = ENET_ECR_DBSWP_MASK | ENET_ECR_EN1588_MASK;
204 ENET->MIBC = ENET_MIBC_MIB_CLEAR_MASK;
211 ENET->EIR = 0xFFFFFFFF;
213 ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
223 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
225 ENET->RDAR = ENET_RDAR_RDAR_MASK;
243 #if defined(USE_MIMXRT1040_EVK)
244 gpio_pin_config_t pinConfig;
245 clock_enet_pll_config_t pllConfig;
248 pllConfig.enableClkOutput =
true;
249 pllConfig.enableClkOutput25M =
false;
250 pllConfig.loopDivider = 1;
252 CLOCK_InitEnetPll(&pllConfig);
255 IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir,
true);
258 CLOCK_EnableClock(kCLOCK_Iomuxc);
261 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0);
264 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_04_ENET_RX_DATA00,
265 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
266 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
267 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
268 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
269 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
270 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
271 IOMUXC_SW_PAD_CTL_PAD_DSE(0) |
272 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
275 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0);
278 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_ENET_RX_DATA01,
279 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
280 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
281 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
282 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
283 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
284 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
285 IOMUXC_SW_PAD_CTL_PAD_DSE(0) |
286 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
289 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0);
292 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_06_ENET_RX_EN,
293 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
294 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
295 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
296 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
297 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
298 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
299 IOMUXC_SW_PAD_CTL_PAD_DSE(0) |
300 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
303 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0);
306 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_07_ENET_TX_DATA00,
307 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
308 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
309 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
310 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
311 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
312 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
313 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
314 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
317 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0);
320 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_08_ENET_TX_DATA01,
321 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
322 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
323 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
324 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
325 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
326 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
327 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
328 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
331 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0);
334 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_09_ENET_TX_EN,
335 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
336 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
337 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
338 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
339 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
340 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
341 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
342 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
345 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1);
348 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_10_ENET_REF_CLK,
349 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
350 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
351 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
352 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
353 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
354 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
355 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
356 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
359 IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0);
362 IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_11_ENET_RX_ER,
363 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
364 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
365 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
366 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
367 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
368 IOMUXC_SW_PAD_CTL_PAD_SPEED(3) |
369 IOMUXC_SW_PAD_CTL_PAD_DSE(0) |
370 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
373 IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0);
376 IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_40_ENET_MDC,
377 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
378 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
379 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
380 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
381 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
382 IOMUXC_SW_PAD_CTL_PAD_SPEED(0) |
383 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
384 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
387 IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0);
390 IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_41_ENET_MDIO,
391 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
392 IOMUXC_SW_PAD_CTL_PAD_PUS(2) |
393 IOMUXC_SW_PAD_CTL_PAD_PUE(1) |
394 IOMUXC_SW_PAD_CTL_PAD_PKE(1) |
395 IOMUXC_SW_PAD_CTL_PAD_ODE(1) |
396 IOMUXC_SW_PAD_CTL_PAD_SPEED(0) |
397 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
398 IOMUXC_SW_PAD_CTL_PAD_SRE(1));
401 IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_GPIO3_IO04, 0);
404 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_GPIO3_IO04,
405 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
406 IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
407 IOMUXC_SW_PAD_CTL_PAD_PUE(0) |
408 IOMUXC_SW_PAD_CTL_PAD_PKE(0) |
409 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
410 IOMUXC_SW_PAD_CTL_PAD_SPEED(0) |
411 IOMUXC_SW_PAD_CTL_PAD_DSE(5) |
412 IOMUXC_SW_PAD_CTL_PAD_SRE(0));
415 IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, 0);
418 IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_GPIO1_IO10,
419 IOMUXC_SW_PAD_CTL_PAD_HYS(0) |
420 IOMUXC_SW_PAD_CTL_PAD_PUS(2) |
421 IOMUXC_SW_PAD_CTL_PAD_PUE(1) |
422 IOMUXC_SW_PAD_CTL_PAD_PKE(1) |
423 IOMUXC_SW_PAD_CTL_PAD_ODE(0) |
424 IOMUXC_SW_PAD_CTL_PAD_SPEED(0) |
425 IOMUXC_SW_PAD_CTL_PAD_DSE(0) |
426 IOMUXC_SW_PAD_CTL_PAD_SRE(0));
429 pinConfig.direction = kGPIO_DigitalOutput;
430 pinConfig.outputLogic = 0;
431 pinConfig.interruptMode = kGPIO_NoIntmode;
432 GPIO_PinInit(GPIO3, 4, &pinConfig);
435 pinConfig.direction = kGPIO_DigitalInput;
436 pinConfig.outputLogic = 0;
437 pinConfig.interruptMode = kGPIO_NoIntmode;
438 GPIO_PinInit(GPIO1, 10, &pinConfig);
441 GPIO_PinWrite(GPIO3, 4, 0);
443 GPIO_PinWrite(GPIO3, 4, 1);
460 osMemset(txBufferDesc, 0,
sizeof(txBufferDesc));
461 osMemset(rxBufferDesc, 0,
sizeof(rxBufferDesc));
498 ENET->TDSR = (uint32_t) txBufferDesc;
500 ENET->RDSR = (uint32_t) rxBufferDesc;
518 if(interface->phyDriver != NULL)
521 interface->phyDriver->tick(interface);
523 else if(interface->switchDriver != NULL)
526 interface->switchDriver->tick(interface);
543 NVIC_EnableIRQ(ENET_IRQn);
546 if(interface->phyDriver != NULL)
549 interface->phyDriver->enableIrq(interface);
551 else if(interface->switchDriver != NULL)
554 interface->switchDriver->enableIrq(interface);
571 NVIC_DisableIRQ(ENET_IRQn);
574 if(interface->phyDriver != NULL)
577 interface->phyDriver->disableIrq(interface);
579 else if(interface->switchDriver != NULL)
582 interface->switchDriver->disableIrq(interface);
609 if((events & ENET_EIR_TXF_MASK) != 0)
612 ENET->EIR = ENET_EIR_TXF_MASK;
615 if((txBufferDesc[txBufferIndex][0] &
ENET_TBD0_R) == 0)
622 ENET->TDAR = ENET_TDAR_TDAR_MASK;
626 if((events & ENET_EIR_RXF_MASK) != 0)
629 ENET->EIMR &= ~ENET_EIMR_RXF_MASK;
632 nicDriverInterface->nicEvent =
TRUE;
638 if((events & ENET_EIR_EBERR_MASK) != 0)
641 ENET->EIMR &= ~ENET_EIMR_EBERR_MASK;
644 nicDriverInterface->nicEvent =
TRUE;
668 if((status & ENET_EIR_RXF_MASK) != 0)
671 ENET->EIR = ENET_EIR_RXF_MASK;
684 if((status & ENET_EIR_EBERR_MASK) != 0)
687 ENET->EIR = ENET_EIR_EBERR_MASK;
690 ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
694 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
696 ENET->RDAR = ENET_RDAR_RDAR_MASK;
700 ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
733 if((txBufferDesc[txBufferIndex][0] &
ENET_TBD0_R) != 0)
743 txBufferDesc[txBufferIndex][4] = 0;
769 ENET->TDAR = ENET_TDAR_TDAR_MASK;
772 if((txBufferDesc[txBufferIndex][0] &
ENET_TBD0_R) == 0)
797 if((rxBufferDesc[rxBufferIndex][0] &
ENET_RBD0_E) == 0)
800 if((rxBufferDesc[rxBufferIndex][0] &
ENET_RBD0_L) != 0)
836 rxBufferDesc[rxBufferIndex][4] = 0;
855 ENET->RDAR = ENET_RDAR_RDAR_MASK;
880 uint32_t unicastHashTable[2];
881 uint32_t multicastHashTable[2];
888 value = interface->macAddr.b[5];
889 value |= (interface->macAddr.b[4] << 8);
890 ENET->PAUR = ENET_PAUR_PADDR2(
value) | ENET_PAUR_TYPE(0x8808);
893 value = interface->macAddr.b[3];
894 value |= (interface->macAddr.b[2] << 8);
895 value |= (interface->macAddr.b[1] << 16);
896 value |= (interface->macAddr.b[0] << 24);
897 ENET->PALR = ENET_PALR_PADDR1(
value);
900 unicastHashTable[0] = 0;
901 unicastHashTable[1] = 0;
904 multicastHashTable[0] = 0;
905 multicastHashTable[1] = 0;
912 entry = &interface->macAddrFilter[i];
922 k = (crc >> 26) & 0x3F;
928 multicastHashTable[k / 32] |= (1 << (k % 32));
933 unicastHashTable[k / 32] |= (1 << (k % 32));
939 ENET->IALR = unicastHashTable[0];
940 ENET->IAUR = unicastHashTable[1];
943 ENET->GALR = multicastHashTable[0];
944 ENET->GAUR = multicastHashTable[1];
947 TRACE_DEBUG(
" IALR = %08" PRIX32
"\r\n", ENET->IALR);
948 TRACE_DEBUG(
" IAUR = %08" PRIX32
"\r\n", ENET->IAUR);
949 TRACE_DEBUG(
" GALR = %08" PRIX32
"\r\n", ENET->GALR);
950 TRACE_DEBUG(
" GAUR = %08" PRIX32
"\r\n", ENET->GAUR);
966 ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
972 ENET->RCR &= ~ENET_RCR_RMII_10T_MASK;
977 ENET->RCR |= ENET_RCR_RMII_10T_MASK;
984 ENET->TCR |= ENET_TCR_FDEN_MASK;
986 ENET->RCR &= ~ENET_RCR_DRT_MASK;
991 ENET->TCR &= ~ENET_TCR_FDEN_MASK;
993 ENET->RCR |= ENET_RCR_DRT_MASK;
1000 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
1002 ENET->RDAR = ENET_RDAR_RDAR_MASK;
1026 temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(1) | ENET_MMFR_TA(2);
1028 temp |= ENET_MMFR_PA(phyAddr);
1030 temp |= ENET_MMFR_RA(
regAddr);
1032 temp |= ENET_MMFR_DATA(
data);
1035 ENET->EIR = ENET_EIR_MII_MASK;
1040 while((ENET->EIR & ENET_EIR_MII_MASK) == 0)
1069 temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(2) | ENET_MMFR_TA(2);
1071 temp |= ENET_MMFR_PA(phyAddr);
1073 temp |= ENET_MMFR_RA(
regAddr);
1076 ENET->EIR = ENET_EIR_MII_MASK;
1081 while((ENET->EIR & ENET_EIR_MII_MASK) == 0)
1086 data = ENET->MMFR & ENET_MMFR_DATA_MASK;
1114 p = (uint8_t *)
data;
1119 for(i = 0; i <
length; i++)
1125 for(j = 0; j < 8; j++)
1127 if((crc & 0x01) != 0)
1129 crc = (crc >> 1) ^ 0xEDB88320;
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
@ ERROR_FAILURE
Generic error code.
#define macIsMulticastAddr(macAddr)
#define MAC_ADDR_FILTER_SIZE
#define ENET_RBD0_DATA_LENGTH
#define ENET_TBD0_DATA_LENGTH
error_t mimxrt1040EthReceivePacket(NetInterface *interface)
Receive a packet.
void mimxrt1040EthDisableIrq(NetInterface *interface)
Disable interrupts.
error_t mimxrt1040EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
const NicDriver mimxrt1040EthDriver
i.MX RT1040 Ethernet MAC driver
void mimxrt1040EthEventHandler(NetInterface *interface)
i.MX RT1040 Ethernet MAC event handler
error_t mimxrt1040EthInit(NetInterface *interface)
i.MX RT1040 Ethernet MAC initialization
void ENET_IRQHandler(void)
Ethernet MAC interrupt.
error_t mimxrt1040EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
error_t mimxrt1040EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void mimxrt1040EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
uint16_t mimxrt1040EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
uint32_t mimxrt1040EthCalcCrc(const void *data, size_t length)
CRC calculation.
__weak_func void mimxrt1040EthInitGpio(NetInterface *interface)
GPIO configuration.
void mimxrt1040EthEnableIrq(NetInterface *interface)
Enable interrupts.
void mimxrt1040EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void mimxrt1040EthTick(NetInterface *interface)
i.MX RT1040 Ethernet MAC timer handler
NXP i.MX RT1040 Ethernet MAC driver.
#define MIMXRT1040_ETH_IRQ_SUB_PRIORITY
#define MIMXRT1040_ETH_RX_BUFFER_COUNT
#define MIMXRT1040_ETH_RX_BUFFER_SIZE
#define MIMXRT1040_ETH_IRQ_GROUP_PRIORITY
#define MIMXRT1040_ETH_TX_BUFFER_SIZE
#define MIMXRT1040_ETH_IRQ_PRIORITY_GROUPING
#define MIMXRT1040_ETH_TX_BUFFER_COUNT
#define MIMXRT1040_ETH_RAM_SECTION
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
@ NIC_TYPE_ETHERNET
Ethernet interface.
#define osMemset(p, value, length)
#define osMemcpy(dest, src, length)
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
uint_t refCount
Reference count for the current entry.
Structure describing a buffer that spans multiple chunks.