/** * \brief Disable transfer, reset registers and descriptor lists. * * \param p_dev Pointer to GMAC driver instance. * */ static void gmac_reset_tx_mem(gmac_device_t* p_dev) { Gmac *p_hw = p_dev->p_hw; uint8_t *p_tx_buff = p_dev->p_tx_buffer; gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr; uint32_t ul_index; uint32_t ul_address; /* Disable TX */ gmac_enable_transmit(p_hw, 0); /* Set up the TX descriptors */ CIRC_CLEAR(p_dev->us_tx_head, p_dev->us_tx_tail); for (ul_index = 0; ul_index < p_dev->us_tx_list_size; ul_index++) { ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE])); p_td[ul_index].addr = ul_address; p_td[ul_index].status.val = GMAC_TXD_USED; } p_td[p_dev->us_tx_list_size - 1].status.val = GMAC_TXD_USED | GMAC_TXD_WRAP; /* Set transmit buffer queue */ gmac_set_tx_queue(p_hw, (uint32_t) p_td); }
//----------------------------------------------------------------------------- /// Disable TX & reset registers and descriptor list //----------------------------------------------------------------------------- static void EMAC_ResetTx(void) { unsigned int Index; unsigned int Address; // Disable TX AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_TE; // Setup the TX descriptors. CIRC_CLEAR(&txTd); for(Index = 0; Index < TX_BUFFERS; Index++) { Address = (unsigned int)(&(pTxBuffer[Index * EMAC_TX_UNITSIZE])); txTd.td[Index].addr = Address; txTd.td[Index].status = EMAC_TX_USED_BIT; } txTd.td[TX_BUFFERS - 1].status = EMAC_TX_USED_BIT | EMAC_TX_WRAP_BIT; // Transmit Buffer Queue Pointer Register AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int) (txTd.td); }
//----------------------------------------------------------------------------- /// Initialize the EMAC with the emac controller address /// \param id HW ID for power management /// \param pTxWakeUpfct Thresold TX Wakeup Callback /// \param pRxfct RX Wakeup Callback /// \param pMacAddress Mac Address /// \param enableCAF enable AT91C_EMAC_CAF if needed by application /// \param enableNBC AT91C_EMAC_NBC if needed by application //----------------------------------------------------------------------------- void EMAC_Init( unsigned char id, const unsigned char *pMacAddress, unsigned char enableCAF, unsigned char enableNBC ) { int Index; unsigned int Address; // Check parameters ASSERT(RX_BUFFERS * EMAC_RX_UNITSIZE > EMAC_FRAME_LENTGH_MAX, "E: RX buffers too small\n\r"); TRACE_DEBUG("EMAC_Init\n\r"); // Power ON AT91C_BASE_PMC->PMC_PCER = 1 << id; // Disable TX & RX and more AT91C_BASE_EMAC->EMAC_NCR = 0; // disable AT91C_BASE_EMAC->EMAC_IDR = ~0; rxTd.idx = 0; CIRC_CLEAR(&txTd); // Setup the RX descriptors. for(Index = 0; Index < RX_BUFFERS; Index++) { Address = (unsigned int)(&(pRxBuffer[Index * EMAC_RX_UNITSIZE])); // Remove EMAC_RX_OWNERSHIP_BIT and EMAC_RX_WRAP_BIT rxTd.td[Index].addr = Address & EMAC_ADDRESS_MASK; rxTd.td[Index].status = 0; } rxTd.td[RX_BUFFERS - 1].addr |= EMAC_RX_WRAP_BIT; // Setup the TX descriptors. for(Index = 0; Index < TX_BUFFERS; Index++) { Address = (unsigned int)(&(pTxBuffer[Index * EMAC_TX_UNITSIZE])); txTd.td[Index].addr = Address; txTd.td[Index].status = EMAC_TX_USED_BIT; } txTd.td[TX_BUFFERS - 1].status = EMAC_TX_USED_BIT | EMAC_TX_WRAP_BIT; // Set the MAC address if( pMacAddress != (unsigned char *)0 ) { AT91C_BASE_EMAC->EMAC_SA1L = ( ((unsigned int)pMacAddress[3] << 24) | ((unsigned int)pMacAddress[2] << 16) | ((unsigned int)pMacAddress[1] << 8 ) | pMacAddress[0] ); AT91C_BASE_EMAC->EMAC_SA1H = ( ((unsigned int)pMacAddress[5] << 8 ) | pMacAddress[4] ); } // Now setup the descriptors // Receive Buffer Queue Pointer Register AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int) (rxTd.td); // Transmit Buffer Queue Pointer Register AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int) (txTd.td); AT91C_BASE_EMAC->EMAC_NCR = AT91C_EMAC_CLRSTAT; // Clear all status bits in the receive status register. AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); // Clear all status bits in the transmit status register AT91C_BASE_EMAC->EMAC_TSR = ( AT91C_EMAC_UBR | AT91C_EMAC_COL | AT91C_EMAC_RLES | AT91C_EMAC_BEX | AT91C_EMAC_COMP | AT91C_EMAC_UND ); // Clear interrupts AT91C_BASE_EMAC->EMAC_ISR; // Enable the copy of data into the buffers // ignore broadcasts, and don't copy FCS. AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_DRFCS | AT91C_EMAC_PAE); if( enableCAF == EMAC_CAF_ENABLE ) { AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_CAF; } if( enableNBC == EMAC_NBC_ENABLE ) { AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_NBC; } // Enable Rx and Tx, plus the stats register. AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT); // Setup the interrupts for TX (and errors) /* AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RXUBR | AT91C_EMAC_TUNDR | AT91C_EMAC_RLEX | AT91C_EMAC_TXERR | AT91C_EMAC_TCOMP | AT91C_EMAC_ROVR | AT91C_EMAC_HRESP; */ AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP; }
void AT91_EMAC_LWIP_Init(struct netif *pNetIf) { AT91_EMAC &emac = AT91_EMAC::EMAC(); UINT32 Index; UINT32 Address; UINT32 Status; AT91_PMC &pmc = AT91::PMC(); pmc.EnablePeriphClock(AT91C_ID_EMAC); // Disable TX & RX and more emac.EMAC_NCR = 0; // Disable interrupts emac.EMAC_IDR = ~0; // Clear buffer index rxTd.idx = 0; CIRC_CLEAR(&txTd); // Setup the RX descriptors. for(Index = 0; Index < RX_BUFFERS; Index++) { Address = (UINT32)(&(RxBuffer[Index * EMAC_RX_UNITSIZE])); // Remove EMAC_RX_OWNERSHIP_BIT and EMAC_RX_WRAP_BIT rxTd.td[Index].addr = Address & EMAC_ADDRESS_MASK; rxTd.td[Index].status = 0; } rxTd.td[RX_BUFFERS - 1].addr |= EMAC_RX_WRAP_BIT; // Setup the TX descriptors. for(Index = 0; Index < TX_BUFFERS; Index++) { Address = (UINT32)(&(TxBuffer[Index * EMAC_TX_UNITSIZE])); txTd.td[Index].addr = Address; txTd.td[Index].status = (UINT32)EMAC_TX_USED_BIT; } txTd.td[TX_BUFFERS - 1].status |= EMAC_TX_WRAP_BIT; // Set the MAC address emac.EMAC_SA1L = ( ((UINT32)pNetIf->hwaddr[3] << 24) | ((UINT32)pNetIf->hwaddr[2] << 16) | ((UINT32)pNetIf->hwaddr[1] << 8 ) | pNetIf->hwaddr[0] ); emac.EMAC_SA1H = ( ((UINT32)pNetIf->hwaddr[5] << 8 ) | pNetIf->hwaddr[4] ); // Now setup the descriptors // Receive Buffer Queue Pointer Register emac.EMAC_RBQP = (UINT32) (rxTd.td); // Transmit Buffer Queue Pointer Register emac.EMAC_TBQP = (UINT32) (txTd.td); emac.EMAC_NCR = AT91_EMAC::EMAC_CLRSTAT; // Clear all status bits in the receive status register. emac.EMAC_RSR = (AT91_EMAC::EMAC_OVR | AT91_EMAC::EMAC_REC | AT91_EMAC::EMAC_BNA); // Clear all status bits in the transmit status register emac.EMAC_TSR = ( AT91_EMAC::EMAC_UBR | AT91_EMAC::EMAC_COL | AT91_EMAC::EMAC_RLES | AT91_EMAC::EMAC_BEX | AT91_EMAC::EMAC_COMP | AT91_EMAC::EMAC_UND ); // Clear Status Status = emac.EMAC_ISR; // Don't copy FCS emac.EMAC_NCFGR |= (AT91_EMAC::EMAC_CAF | AT91_EMAC::EMAC_DRFCS | AT91_EMAC::EMAC_PAE); // Enable Rx and Tx, plus the stats register. emac.EMAC_NCR |= (AT91_EMAC::EMAC_TE | AT91_EMAC::EMAC_RE | AT91_EMAC::EMAC_WESTAT); // Setup the interrupts for TX (and errors) emac.EMAC_IER = AT91_EMAC::EMAC_RXUBR | AT91_EMAC::EMAC_TUNDR | AT91_EMAC::EMAC_RLEX | AT91_EMAC::EMAC_TXERR | AT91_EMAC::EMAC_TCOMP | AT91_EMAC::EMAC_ROVR | AT91_EMAC::EMAC_HRESP | AT91_EMAC::EMAC_RCOMP; }