32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
49 #pragma location = PIC32CZ_ETH_RAM_SECTION
52 #pragma data_alignment = 8
53 #pragma location = PIC32CZ_ETH_RAM_SECTION
56 #pragma data_alignment = 8
57 #pragma location = PIC32CZ_ETH_RAM_SECTION
60 #pragma data_alignment = 8
61 #pragma location = PIC32CZ_ETH_RAM_SECTION
65 #pragma data_alignment = 8
66 #pragma location = PIC32CZ_ETH_RAM_SECTION
69 #pragma data_alignment = 8
70 #pragma location = PIC32CZ_ETH_RAM_SECTION
73 #pragma data_alignment = 8
74 #pragma location = PIC32CZ_ETH_RAM_SECTION
77 #pragma data_alignment = 8
78 #pragma location = PIC32CZ_ETH_RAM_SECTION
113 static uint_t txBufferIndex;
115 static uint_t rxBufferIndex;
152 volatile uint32_t status;
155 TRACE_INFO(
"Initializing PIC32CZ Ethernet MAC...\r\n");
158 nicDriverInterface = interface;
160 #if defined(__PIC32CZ2051CA70064__) || defined(__PIC32CZ2051CA70100__) || \
161 defined(__PIC32CZ2051CA70144__)
163 PMC_REGS->PMC_PCER1 = (1 << (ID_GMAC - 32));
166 GCLK_REGS->GCLK_PCHCTRL[ETH_GCLK_ID_TX] = GCLK_PCHCTRL_GEN_GCLK2 |
167 GCLK_PCHCTRL_CHEN_Msk;
170 while((GCLK_REGS->GCLK_PCHCTRL[ETH_GCLK_ID_TX] & GCLK_PCHCTRL_CHEN_Msk) == 0)
175 GCLK_REGS->GCLK_PCHCTRL[ETH_GCLK_ID_TSU] = GCLK_PCHCTRL_GEN_GCLK2 |
176 GCLK_PCHCTRL_CHEN_Msk;
179 while((GCLK_REGS->GCLK_PCHCTRL[ETH_GCLK_ID_TSU] & GCLK_PCHCTRL_CHEN_Msk) == 0)
184 MCLK_REGS->MCLK_CLKMSK[ETH_MCLK_ID_APB / 32] |= (1U << (ETH_MCLK_ID_APB % 32));
185 MCLK_REGS->MCLK_CLKMSK[ETH_MCLK_ID_AXI / 32] |= (1U << (ETH_MCLK_ID_AXI % 32));
188 ETH_REGS->ETH_CTRLA = ETH_CTRLA_ENABLE_Msk;
191 while(ETH_REGS->ETH_SYNCB != 0)
208 if(interface->phyDriver != NULL)
211 error = interface->phyDriver->init(interface);
213 else if(interface->switchDriver != NULL)
216 error = interface->switchDriver->init(interface);
231 GMAC_REGS->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
232 GMAC_REGS->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
316 #if defined(USE_PIC32CZ_CA70_CURIOSITY_ULTRA)
320 PMC_REGS->PMC_PCER0 = (1 << ID_PIOC) | (1 << ID_PIOD);
323 mask = PIO_PD9A_GMAC_GMDIO | PIO_PD8A_GMAC_GMDC |
324 PIO_PD7A_GMAC_GRXER | PIO_PD6A_GMAC_GRX1 | PIO_PD5A_GMAC_GRX0 |
325 PIO_PD4A_GMAC_GRXDV | PIO_PD3A_GMAC_GTX1 | PIO_PD2A_GMAC_GTX0 |
326 PIO_PD1A_GMAC_GTXEN | PIO_PD0A_GMAC_GTXCK;
329 PIOD_REGS->PIO_PUDR =
mask;
331 PIOD_REGS->PIO_IDR =
mask;
333 PIOD_REGS->PIO_ABCDSR[0] &= ~
mask;
334 PIOD_REGS->PIO_ABCDSR[1] &= ~
mask;
336 PIOD_REGS->PIO_PDR =
mask;
342 PIOC_REGS->PIO_PER = PIO_PC10;
343 PIOC_REGS->PIO_OER = PIO_PC10;
346 PIOC_REGS->PIO_CODR = PIO_PC10;
348 PIOC_REGS->PIO_SODR = PIO_PC10;
352 #elif defined(USE_PIC32CZ_CA80_CURIOSITY_ULTRA) || \
353 defined(USE_PIC32CZ_CA90_CURIOSITY_ULTRA)
357 MCLK_REGS->MCLK_CLKMSK[PORT_MCLK_ID_APB / 32] |= (1U << (PORT_MCLK_ID_APB % 32));
358 MCLK_REGS->MCLK_CLKMSK[PORT_MCLK_ID_AHB / 32] |= (1U << (PORT_MCLK_ID_AHB % 32));
361 PORT_REGS->GROUP[0].PORT_PINCFG[0] |= PORT_PINCFG_PMUXEN_Msk;
362 temp = PORT_REGS->GROUP[0].PORT_PMUX[0] & ~PORT_PMUX_PMUXE_Msk;
363 PORT_REGS->GROUP[0].PORT_PMUX[0] = temp | PORT_PMUX_PMUXE(MUX_PA00K_ETH_TXD1);
366 PORT_REGS->GROUP[0].PORT_PINCFG[1] |= PORT_PINCFG_PMUXEN_Msk;
367 temp = PORT_REGS->GROUP[0].PORT_PMUX[0] & ~PORT_PMUX_PMUXO_Msk;
368 PORT_REGS->GROUP[0].PORT_PMUX[0] = temp | PORT_PMUX_PMUXO(MUX_PA01K_ETH_TXD0);
371 PORT_REGS->GROUP[0].PORT_PINCFG[2] |= PORT_PINCFG_PMUXEN_Msk;
372 temp = PORT_REGS->GROUP[0].PORT_PMUX[1] & ~PORT_PMUX_PMUXE_Msk;
373 PORT_REGS->GROUP[0].PORT_PMUX[1] = temp | PORT_PMUX_PMUXE(MUX_PA02K_ETH_TXEN);
376 PORT_REGS->GROUP[0].PORT_PINCFG[3] |= PORT_PINCFG_PMUXEN_Msk;
377 temp = PORT_REGS->GROUP[0].PORT_PMUX[1] & ~PORT_PMUX_PMUXO_Msk;
378 PORT_REGS->GROUP[0].PORT_PMUX[1] = temp | PORT_PMUX_PMUXO(MUX_PA03K_ETH_MDC);
381 PORT_REGS->GROUP[0].PORT_PINCFG[4] |= PORT_PINCFG_PMUXEN_Msk;
382 temp = PORT_REGS->GROUP[0].PORT_PMUX[2] & ~PORT_PMUX_PMUXE_Msk;
383 PORT_REGS->GROUP[0].PORT_PMUX[2] = temp | PORT_PMUX_PMUXE(MUX_PA04K_ETH_MDIO);
386 PORT_REGS->GROUP[0].PORT_PINCFG[5] |= PORT_PINCFG_PMUXEN_Msk;
387 temp = PORT_REGS->GROUP[0].PORT_PMUX[2] & ~PORT_PMUX_PMUXO_Msk;
388 PORT_REGS->GROUP[0].PORT_PMUX[2] = temp | PORT_PMUX_PMUXO(MUX_PA05K_ETH_RXDV);
391 PORT_REGS->GROUP[0].PORT_PINCFG[6] |= PORT_PINCFG_PMUXEN_Msk;
392 temp = PORT_REGS->GROUP[0].PORT_PMUX[3] & ~PORT_PMUX_PMUXE_Msk;
393 PORT_REGS->GROUP[0].PORT_PMUX[3] = temp | PORT_PMUX_PMUXE(MUX_PA06K_ETH_RXER);
396 PORT_REGS->GROUP[0].PORT_PINCFG[21] |= PORT_PINCFG_PMUXEN_Msk;
397 temp = PORT_REGS->GROUP[0].PORT_PMUX[10] & ~PORT_PMUX_PMUXO_Msk;
398 PORT_REGS->GROUP[0].PORT_PMUX[10] = temp | PORT_PMUX_PMUXO(MUX_PA21K_ETH_TX_CLK);
401 PORT_REGS->GROUP[3].PORT_PINCFG[2] |= PORT_PINCFG_PMUXEN_Msk;
402 temp = PORT_REGS->GROUP[3].PORT_PMUX[1] & ~PORT_PMUX_PMUXE_Msk;
403 PORT_REGS->GROUP[3].PORT_PMUX[1] = temp | PORT_PMUX_PMUXE(MUX_PD02K_ETH_TXER);
406 PORT_REGS->GROUP[3].PORT_PINCFG[3] |= PORT_PINCFG_PMUXEN_Msk;
407 temp = PORT_REGS->GROUP[3].PORT_PMUX[1] & ~PORT_PMUX_PMUXO_Msk;
408 PORT_REGS->GROUP[3].PORT_PMUX[1] = temp | PORT_PMUX_PMUXO(MUX_PD03K_ETH_TXD3);
411 PORT_REGS->GROUP[3].PORT_PINCFG[4] |= PORT_PINCFG_PMUXEN_Msk;
412 temp = PORT_REGS->GROUP[3].PORT_PMUX[2] & ~PORT_PMUX_PMUXE_Msk;
413 PORT_REGS->GROUP[3].PORT_PMUX[2] = temp | PORT_PMUX_PMUXE(MUX_PD04K_ETH_TXD2);
416 PORT_REGS->GROUP[3].PORT_PINCFG[5] |= PORT_PINCFG_PMUXEN_Msk;
417 temp = PORT_REGS->GROUP[3].PORT_PMUX[2] & ~PORT_PMUX_PMUXO_Msk;
418 PORT_REGS->GROUP[3].PORT_PMUX[2] = temp | PORT_PMUX_PMUXO(MUX_PD05L_ETH_GTX_CLK);
421 PORT_REGS->GROUP[3].PORT_PINCFG[6] |= PORT_PINCFG_PMUXEN_Msk;
422 temp = PORT_REGS->GROUP[3].PORT_PMUX[3] & ~PORT_PMUX_PMUXE_Msk;
423 PORT_REGS->GROUP[3].PORT_PMUX[3] = temp | PORT_PMUX_PMUXE(MUX_PD06K_ETH_RXD3);
426 PORT_REGS->GROUP[3].PORT_PINCFG[7] |= PORT_PINCFG_PMUXEN_Msk;
427 temp = PORT_REGS->GROUP[3].PORT_PMUX[3] & ~PORT_PMUX_PMUXO_Msk;
428 PORT_REGS->GROUP[3].PORT_PMUX[3] = temp | PORT_PMUX_PMUXO(MUX_PD07K_ETH_RXD2);
431 PORT_REGS->GROUP[3].PORT_PINCFG[8] |= PORT_PINCFG_PMUXEN_Msk;
432 temp = PORT_REGS->GROUP[3].PORT_PMUX[4] & ~PORT_PMUX_PMUXE_Msk;
433 PORT_REGS->GROUP[3].PORT_PMUX[4] = temp | PORT_PMUX_PMUXE(MUX_PD08K_ETH_COL);
436 PORT_REGS->GROUP[3].PORT_PINCFG[9] |= PORT_PINCFG_PMUXEN_Msk;
437 temp = PORT_REGS->GROUP[3].PORT_PMUX[4] & ~PORT_PMUX_PMUXO_Msk;
438 PORT_REGS->GROUP[3].PORT_PMUX[4] = temp | PORT_PMUX_PMUXO(MUX_PD09K_ETH_CRS);
441 PORT_REGS->GROUP[3].PORT_PINCFG[10] |= PORT_PINCFG_PMUXEN_Msk;
442 temp = PORT_REGS->GROUP[3].PORT_PMUX[5] & ~PORT_PMUX_PMUXE_Msk;
443 PORT_REGS->GROUP[3].PORT_PMUX[5] = temp | PORT_PMUX_PMUXE(MUX_PD10K_ETH_RXD1);
446 PORT_REGS->GROUP[3].PORT_PINCFG[11] |= PORT_PINCFG_PMUXEN_Msk;
447 temp = PORT_REGS->GROUP[3].PORT_PMUX[5] & ~PORT_PMUX_PMUXO_Msk;
448 PORT_REGS->GROUP[3].PORT_PMUX[5] = temp | PORT_PMUX_PMUXO(MUX_PD11K_ETH_RXD0);
451 PORT_REGS->GROUP[3].PORT_PINCFG[12] |= PORT_PINCFG_PMUXEN_Msk;
452 temp = PORT_REGS->GROUP[3].PORT_PMUX[6] & ~PORT_PMUX_PMUXE_Msk;
453 PORT_REGS->GROUP[3].PORT_PMUX[6] = temp | PORT_PMUX_PMUXE(MUX_PD12L_ETH_RX_CLK);
456 PORT_REGS->GROUP[3].PORT_PINCFG[14] |= PORT_PINCFG_PMUXEN_Msk;
457 temp = PORT_REGS->GROUP[3].PORT_PMUX[7] & ~PORT_PMUX_PMUXE_Msk;
458 PORT_REGS->GROUP[3].PORT_PMUX[7] = temp | PORT_PMUX_PMUXE(MUX_PD14K_ETH_TXD7);
461 PORT_REGS->GROUP[3].PORT_PINCFG[15] |= PORT_PINCFG_PMUXEN_Msk;
462 temp = PORT_REGS->GROUP[3].PORT_PMUX[7] & ~PORT_PMUX_PMUXO_Msk;
463 PORT_REGS->GROUP[3].PORT_PMUX[7] = temp | PORT_PMUX_PMUXO(MUX_PD15K_ETH_TXD6);
466 PORT_REGS->GROUP[3].PORT_PINCFG[16] |= PORT_PINCFG_PMUXEN_Msk;
467 temp = PORT_REGS->GROUP[3].PORT_PMUX[8] & ~PORT_PMUX_PMUXE_Msk;
468 PORT_REGS->GROUP[3].PORT_PMUX[8] = temp | PORT_PMUX_PMUXE(MUX_PD16K_ETH_TXD5);
471 PORT_REGS->GROUP[3].PORT_PINCFG[17] |= PORT_PINCFG_PMUXEN_Msk;
472 temp = PORT_REGS->GROUP[3].PORT_PMUX[8] & ~PORT_PMUX_PMUXO_Msk;
473 PORT_REGS->GROUP[3].PORT_PMUX[8] = temp | PORT_PMUX_PMUXO(MUX_PD17K_ETH_TXD4);
476 PORT_REGS->GROUP[3].PORT_PINCFG[18] |= PORT_PINCFG_PMUXEN_Msk;
477 temp = PORT_REGS->GROUP[3].PORT_PMUX[9] & ~PORT_PMUX_PMUXE_Msk;
478 PORT_REGS->GROUP[3].PORT_PMUX[9] = temp | PORT_PMUX_PMUXE(MUX_PD18K_ETH_RXD7);
481 PORT_REGS->GROUP[3].PORT_PINCFG[19] |= PORT_PINCFG_PMUXEN_Msk;
482 temp = PORT_REGS->GROUP[3].PORT_PMUX[9] & ~PORT_PMUX_PMUXO_Msk;
483 PORT_REGS->GROUP[3].PORT_PMUX[9] = temp | PORT_PMUX_PMUXO(MUX_PD19K_ETH_RXD6);
486 PORT_REGS->GROUP[3].PORT_PINCFG[20] |= PORT_PINCFG_PMUXEN_Msk;
487 temp = PORT_REGS->GROUP[3].PORT_PMUX[10] & ~PORT_PMUX_PMUXE_Msk;
488 PORT_REGS->GROUP[3].PORT_PMUX[10] = temp | PORT_PMUX_PMUXE(MUX_PD20K_ETH_RXD4);
491 PORT_REGS->GROUP[3].PORT_PINCFG[21] |= PORT_PINCFG_PMUXEN_Msk;
492 temp = PORT_REGS->GROUP[3].PORT_PMUX[10] & ~PORT_PMUX_PMUXO_Msk;
493 PORT_REGS->GROUP[3].PORT_PMUX[10] = temp | PORT_PMUX_PMUXO(MUX_PD21K_ETH_RXD5);
496 ETH_REGS->ETH_CTRLB |= ETH_CTRLB_GMIIEN_Msk | ETH_CTRLB_GBITCLKREQ_Msk;
499 while(ETH_REGS->ETH_SYNCB != 0)
504 PORT_REGS->GROUP[0].PORT_PINCFG[5] |= PORT_PINCFG_PULLEN_Msk;
505 PORT_REGS->GROUP[0].PORT_OUTCLR = PORT_PA05;
508 PORT_REGS->GROUP[3].PORT_PINCFG[6] |= PORT_PINCFG_PULLEN_Msk;
509 PORT_REGS->GROUP[3].PORT_OUTCLR = PORT_PD06;
512 PORT_REGS->GROUP[3].PORT_PINCFG[7] |= PORT_PINCFG_PULLEN_Msk;
513 PORT_REGS->GROUP[3].PORT_OUTCLR = PORT_PD07;
516 PORT_REGS->GROUP[3].PORT_PINCFG[10] |= PORT_PINCFG_PULLEN_Msk;
517 PORT_REGS->GROUP[3].PORT_OUTCLR = PORT_PD10;
520 PORT_REGS->GROUP[3].PORT_PINCFG[11] |= PORT_PINCFG_PULLEN_Msk;
521 PORT_REGS->GROUP[3].PORT_OUTSET = PORT_PD11;
524 PORT_REGS->GROUP[3].PORT_PINCFG[12] |= PORT_PINCFG_PULLEN_Msk;
525 PORT_REGS->GROUP[3].PORT_OUTSET = PORT_PD12;
528 PORT_REGS->GROUP[1].PORT_DIRSET = PORT_PB23;
531 PORT_REGS->GROUP[1].PORT_OUTCLR = PORT_PB23;
533 PORT_REGS->GROUP[1].PORT_OUTSET = PORT_PB23;
573 rxBufferDesc[i].
status = 0;
585 address = (uint32_t) dummyTxBuffer[i];
599 address = (uint32_t) dummyRxBuffer[i];
603 dummyRxBufferDesc[i].
status = 0;
610 GMAC_REGS->GMAC_TBQB = (uint32_t) txBufferDesc;
611 GMAC_REGS->GMAC_TBQBAPQ[0] = (uint32_t) dummyTxBufferDesc;
612 GMAC_REGS->GMAC_TBQBAPQ[1] = (uint32_t) dummyTxBufferDesc;
613 GMAC_REGS->GMAC_TBQBAPQ[2] = (uint32_t) dummyTxBufferDesc;
614 GMAC_REGS->GMAC_TBQBAPQ[3] = (uint32_t) dummyTxBufferDesc;
615 GMAC_REGS->GMAC_TBQBAPQ[4] = (uint32_t) dummyTxBufferDesc;
618 GMAC_REGS->GMAC_RBQB = (uint32_t) rxBufferDesc;
619 GMAC_REGS->GMAC_RBQBAPQ[0] = (uint32_t) dummyRxBufferDesc;
620 GMAC_REGS->GMAC_RBQBAPQ[1] = (uint32_t) dummyRxBufferDesc;
621 GMAC_REGS->GMAC_RBQBAPQ[2] = (uint32_t) dummyRxBufferDesc;
622 GMAC_REGS->GMAC_RBQBAPQ[3] = (uint32_t) dummyRxBufferDesc;
623 GMAC_REGS->GMAC_RBQBAPQ[4] = (uint32_t) dummyRxBufferDesc;
639 if(interface->phyDriver != NULL)
642 interface->phyDriver->tick(interface);
644 else if(interface->switchDriver != NULL)
647 interface->switchDriver->tick(interface);
667 if(interface->phyDriver != NULL)
670 interface->phyDriver->enableIrq(interface);
672 else if(interface->switchDriver != NULL)
675 interface->switchDriver->enableIrq(interface);
695 if(interface->phyDriver != NULL)
698 interface->phyDriver->disableIrq(interface);
700 else if(interface->switchDriver != NULL)
703 interface->switchDriver->disableIrq(interface);
719 volatile uint32_t isr;
720 volatile uint32_t tsr;
721 volatile uint32_t rsr;
729 #if defined(__PIC32CZ2051CA70064__) || defined(__PIC32CZ2051CA70100__) || \
730 defined(__PIC32CZ2051CA70144__)
762 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
774 nicDriverInterface->nicEvent =
TRUE;
844 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) == 0)
879 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
917 j = rxBufferIndex + i;
940 if((rxBufferDesc[j].status &
GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
954 if(eofIndex != UINT_MAX)
958 else if(sofIndex != UINT_MAX)
971 for(i = 0; i < j; i++)
974 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
1034 uint32_t hashTable[2];
1042 GMAC_REGS->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
1043 GMAC_REGS->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
1059 entry = &interface->macAddrFilter[i];
1071 k = (
p[0] >> 6) ^
p[0];
1072 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
1073 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
1074 k ^= (
p[3] >> 6) ^
p[3];
1075 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
1076 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
1082 hashTable[k / 32] |= (1 << (k % 32));
1090 unicastMacAddr[j] = entry->
addr;
1098 k = (
p[0] >> 6) ^
p[0];
1099 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
1100 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
1101 k ^= (
p[3] >> 6) ^
p[3];
1102 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
1103 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
1109 hashTable[k / 32] |= (1 << (k % 32));
1122 GMAC_REGS->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
1123 GMAC_REGS->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
1135 GMAC_REGS->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
1136 GMAC_REGS->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
1148 GMAC_REGS->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
1149 GMAC_REGS->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
1193 #if defined(__PIC32CZ2051CA70064__) || defined(__PIC32CZ2051CA70100__) || \
1194 defined(__PIC32CZ2051CA70144__)