32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
49 #pragma location = SAM9X6_ETH1_RAM_SECTION
52 #pragma data_alignment = 8
53 #pragma location = SAM9X6_ETH1_RAM_SECTION
56 #pragma data_alignment = 4
57 #pragma location = SAM9X6_ETH1_RAM_SECTION
60 #pragma data_alignment = 4
61 #pragma location = SAM9X6_ETH1_RAM_SECTION
83 static uint_t txBufferIndex;
85 static uint_t rxBufferIndex;
122 volatile uint32_t temp;
125 TRACE_INFO(
"Initializing SAM9X6 Ethernet MAC (EMAC0)...\r\n");
128 nicDriverInterface = interface;
131 PMC_REGS->PMC_PCR = PMC_PCR_PID(ID_EMAC0);
132 temp = PMC_REGS->PMC_PCR;
133 PMC_REGS->PMC_PCR = temp | PMC_PCR_CMD_Msk | PMC_PCR_EN_Msk;
136 EMAC0_REGS->EMAC_NCR = 0;
142 EMAC0_REGS->EMAC_NCFGR = EMAC_NCFGR_CLK_MCK_64;
144 EMAC0_REGS->EMAC_NCR |= EMAC_NCR_MPE_Msk;
147 if(interface->phyDriver != NULL)
150 error = interface->phyDriver->init(interface);
152 else if(interface->switchDriver != NULL)
155 error = interface->switchDriver->init(interface);
170 EMAC0_REGS->EMAC_SA[0].EMAC_SAxB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
171 EMAC0_REGS->EMAC_SA[0].EMAC_SAxT = interface->macAddr.w[2];
174 EMAC0_REGS->EMAC_SA[1].EMAC_SAxB = 0;
175 EMAC0_REGS->EMAC_SA[2].EMAC_SAxB = 0;
176 EMAC0_REGS->EMAC_SA[3].EMAC_SAxB = 0;
179 EMAC0_REGS->EMAC_HRB = 0;
180 EMAC0_REGS->EMAC_HRT = 0;
183 EMAC0_REGS->EMAC_NCFGR |= EMAC_NCFGR_BIG_Msk | EMAC_NCFGR_MTI_Msk;
189 EMAC0_REGS->EMAC_TSR = EMAC_TSR_UND_Msk | EMAC_TSR_COMP_Msk |
190 EMAC_TSR_BEX_Msk | EMAC_TSR_TGO_Msk | EMAC_TSR_RLES_Msk |
191 EMAC_TSR_COL_Msk | EMAC_TSR_UBR_Msk;
194 EMAC0_REGS->EMAC_RSR = EMAC_RSR_OVR_Msk | EMAC_RSR_REC_Msk |
198 EMAC0_REGS->EMAC_IDR = 0xFFFFFFFF;
201 EMAC0_REGS->EMAC_IER = EMAC_IER_ROVR_Msk | EMAC_IER_TCOMP_Msk |
202 EMAC_IER_TXERR_Msk | EMAC_IER_RLE_Msk | EMAC_IER_TUND_Msk |
203 EMAC_IER_RXUBR_Msk | EMAC_IER_RCOMP_Msk;
206 temp = EMAC0_REGS->EMAC_ISR;
210 AIC_REGS->AIC_SSR = ID_EMAC0;
215 AIC_REGS->AIC_ICCR = (1 << ID_EMAC0);
218 EMAC0_REGS->EMAC_NCR |= EMAC_NCR_TE_Msk | EMAC_NCR_RE_Msk;
236 #if defined(USE_SAM9X6_EK) || defined(USE_SAM9X6_CURIOSITY)
240 PMC_REGS->PMC_PCR = PMC_PCR_PID(ID_PIOB);
241 temp = PMC_REGS->PMC_PCR;
242 PMC_REGS->PMC_PCR = temp | PMC_PCR_CMD_Msk | PMC_PCR_EN_Msk;
255 EMAC0_REGS->EMAC_USRIO = EMAC_USRIO_CLKEN_Msk | EMAC_USRIO_RMII_Msk;
294 rxBufferDesc[i].
status = 0;
303 EMAC0_REGS->EMAC_TBQP = (uint32_t) txBufferDesc;
305 EMAC0_REGS->EMAC_RBQP = (uint32_t) rxBufferDesc;
321 if(interface->phyDriver != NULL)
324 interface->phyDriver->tick(interface);
326 else if(interface->switchDriver != NULL)
329 interface->switchDriver->tick(interface);
346 AIC_REGS->AIC_SSR = AIC_SSR_INTSEL(ID_EMAC0);
347 AIC_REGS->AIC_IECR = AIC_IECR_INTEN_Msk;
350 if(interface->phyDriver != NULL)
353 interface->phyDriver->enableIrq(interface);
355 else if(interface->switchDriver != NULL)
358 interface->switchDriver->enableIrq(interface);
375 AIC_REGS->AIC_SSR = AIC_SSR_INTSEL(ID_EMAC0);
376 AIC_REGS->AIC_IDCR = AIC_IDCR_INTD_Msk;
379 if(interface->phyDriver != NULL)
382 interface->phyDriver->disableIrq(interface);
384 else if(interface->switchDriver != NULL)
387 interface->switchDriver->disableIrq(interface);
403 volatile uint32_t isr;
404 volatile uint32_t tsr;
405 volatile uint32_t rsr;
415 isr = EMAC0_REGS->EMAC_ISR;
416 tsr = EMAC0_REGS->EMAC_TSR;
417 rsr = EMAC0_REGS->EMAC_RSR;
421 if((tsr & (EMAC_TSR_UND_Msk | EMAC_TSR_COMP_Msk | EMAC_TSR_BEX_Msk |
422 EMAC_TSR_TGO_Msk | EMAC_TSR_RLES_Msk | EMAC_TSR_COL_Msk |
423 EMAC_TSR_UBR_Msk)) != 0)
426 EMAC0_REGS->EMAC_TSR = tsr;
429 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
437 if((rsr & (EMAC_RSR_OVR_Msk | EMAC_RSR_REC_Msk | EMAC_RSR_BNA_Msk)) != 0)
440 nicDriverInterface->nicEvent =
TRUE;
445 #if (NET_RTOS_SUPPORT == DISABLED)
447 AIC_REGS->AIC_EOICR = 0;
466 rsr = EMAC0_REGS->EMAC_RSR;
469 if((rsr & (EMAC_RSR_OVR_Msk | EMAC_RSR_REC_Msk | EMAC_RSR_BNA_Msk)) != 0)
472 EMAC0_REGS->EMAC_RSR = rsr;
514 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) == 0)
543 EMAC0_REGS->EMAC_NCR |= EMAC_NCR_TSTART_Msk;
546 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
584 j = rxBufferIndex + i;
607 if((rxBufferDesc[j].status &
EMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
621 if(eofIndex != UINT_MAX)
625 else if(sofIndex != UINT_MAX)
638 for(i = 0; i < j; i++)
641 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
701 uint32_t hashTable[2];
709 EMAC0_REGS->EMAC_SA[0].EMAC_SAxB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
710 EMAC0_REGS->EMAC_SA[0].EMAC_SAxT = interface->macAddr.w[2];
726 entry = &interface->macAddrFilter[i];
738 k = (
p[0] >> 6) ^
p[0];
739 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
740 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
741 k ^= (
p[3] >> 6) ^
p[3];
742 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
743 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
749 hashTable[k / 32] |= (1 << (k % 32));
757 unicastMacAddr[j++] = entry->
addr;
767 EMAC0_REGS->EMAC_SA[1].EMAC_SAxB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
768 EMAC0_REGS->EMAC_SA[1].EMAC_SAxT = unicastMacAddr[0].w[2];
773 EMAC0_REGS->EMAC_SA[1].EMAC_SAxB = 0;
780 EMAC0_REGS->EMAC_SA[2].EMAC_SAxB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
781 EMAC0_REGS->EMAC_SA[2].EMAC_SAxT = unicastMacAddr[1].w[2];
786 EMAC0_REGS->EMAC_SA[2].EMAC_SAxB = 0;
793 EMAC0_REGS->EMAC_SA[3].EMAC_SAxB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
794 EMAC0_REGS->EMAC_SA[4].EMAC_SAxT = unicastMacAddr[2].w[2];
799 EMAC0_REGS->EMAC_SA[3].EMAC_SAxB = 0;
803 EMAC0_REGS->EMAC_HRB = hashTable[0];
804 EMAC0_REGS->EMAC_HRT = hashTable[1];
807 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", EMAC0_REGS->EMAC_HRB);
808 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", EMAC0_REGS->EMAC_HRT);
826 config = EMAC0_REGS->EMAC_NCFGR;
831 config |= EMAC_NCFGR_SPD_Msk;
835 config &= ~EMAC_NCFGR_SPD_Msk;
841 config |= EMAC_NCFGR_FD_Msk;
845 config &= ~EMAC_NCFGR_FD_Msk;
849 EMAC0_REGS->EMAC_NCFGR = config;
873 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(1) | EMAC_MAN_CODE(2);
875 temp |= EMAC_MAN_PHYA(phyAddr);
877 temp |= EMAC_MAN_REGA(
regAddr);
879 temp |= EMAC_MAN_DATA(
data);
882 EMAC0_REGS->EMAC_MAN = temp;
884 while((EMAC0_REGS->EMAC_NSR & EMAC_NSR_IDLE_Msk) == 0)
913 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(2) | EMAC_MAN_CODE(2);
915 temp |= EMAC_MAN_PHYA(phyAddr);
917 temp |= EMAC_MAN_REGA(
regAddr);
920 EMAC0_REGS->EMAC_MAN = temp;
922 while((EMAC0_REGS->EMAC_NSR & EMAC_NSR_IDLE_Msk) == 0)
927 data = EMAC0_REGS->EMAC_MAN & EMAC_MAN_DATA_Msk;
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
@ ERROR_FAILURE
Generic error code.
const MacAddr MAC_UNSPECIFIED_ADDR
#define macIsMulticastAddr(macAddr)
#define ETH_MAX_FRAME_SIZE
#define MAC_ADDR_FILTER_SIZE
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 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.
#define EMAC_RX_OWNERSHIP
error_t sam9x6Eth1Init(NetInterface *interface)
SAM9X6 Ethernet MAC initialization.
uint16_t sam9x6Eth1ReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
const NicDriver sam9x6Eth1Driver
SAM9X6 Ethernet MAC driver (EMAC0 instance)
void sam9x6Eth1EventHandler(NetInterface *interface)
SAM9X6 Ethernet MAC event handler.
error_t sam9x6Eth1SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
__weak_func void sam9x6Eth1InitGpio(NetInterface *interface)
GPIO configuration.
void sam9x6Eth1WritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t sam9x6Eth1ReceivePacket(NetInterface *interface)
Receive a packet.
error_t sam9x6Eth1UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void sam9x6Eth1IrqHandler(void)
SAM9X6 Ethernet MAC interrupt service routine.
error_t sam9x6Eth1UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void sam9x6Eth1EnableIrq(NetInterface *interface)
Enable interrupts.
void sam9x6Eth1Tick(NetInterface *interface)
SAM9X6 Ethernet MAC timer handler.
void sam9x6Eth1InitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void sam9x6Eth1DisableIrq(NetInterface *interface)
Disable interrupts.
SAM9X60 Ethernet MAC driver (EMAC0 instance)
#define SAM9X6_ETH1_RAM_SECTION
#define SAM9X6_ETH1_IRQ_PRIORITY
#define SAM9X6_ETH1_RX_BUFFER_SIZE
#define SAM9X6_ETH1_TX_BUFFER_COUNT
#define SAM9X6_ETH1_RX_BUFFER_COUNT
#define SAM9X6_ETH1_TX_BUFFER_SIZE
uint_t refCount
Reference count for the current entry.
Structure describing a buffer that spans multiple chunks.
Receive buffer descriptor.
Transmit buffer descriptor.