123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- /*
- * File : rthw.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #include "synopsys_emac.h"
- /* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
- extern EMAC_DMADESCTypeDef *DMATxDescToSet;
- extern EMAC_DMADESCTypeDef *DMARxDescToGet;
- /**
- * Initializes the ETHERNET peripheral according to the specified
- */
- rt_uint32_t EMAC_init(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t SystemCoreClock)
- {
- rt_uint32_t value = 0;
- /*-------------------------------- MAC Config ------------------------------*/
- /*---------------------- ETHERNET MACMIIAR Configuration -------------------*/
- /* Get the ETHERNET MACMIIAR value */
- value = ETHERNET_MAC->GAR;
- /* Clear CSR Clock Range CR[2:0] bits */
- value &= MACMIIAR_CR_MASK;
- /* Get hclk frequency value */
- /* Set CR bits depending on hclk value */
- if((SystemCoreClock >= 20000000)&&(SystemCoreClock < 35000000))
- {
- /* CSR Clock Range between 20-35 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div16;
- }
- else if((SystemCoreClock >= 35000000)&&(SystemCoreClock < 60000000))
- {
- /* CSR Clock Range between 35-60 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div26;
- }
- else if((SystemCoreClock >= 60000000)&&(SystemCoreClock <= 100000000))
- {
- /* CSR Clock Range between 60-100 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div42;
- }
- else if((SystemCoreClock >= 100000000)&&(SystemCoreClock <= 150000000))
- {
- /* CSR Clock Range between 100-150 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div62;
- }
- else if((SystemCoreClock >= 150000000)&&(SystemCoreClock <= 250000000))
- {
- /* CSR Clock Range between 150-250 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div102;
- }
- else /* if((SystemCoreClock >= 250000000)&&(SystemCoreClock <= 300000000)) */
- {
- /* CSR Clock Range between 250-300 MHz */
- value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div122;
- }
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
- ETHERNET_MAC->GAR = (rt_uint32_t)value;
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- value = ETHERNET_MAC->MCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- value &= MACCR_CLEAR_MASK;
- value |= (rt_uint32_t)(EMAC_Watchdog_Enable |
- EMAC_Jabber_Enable |
- EMAC_InterFrameGap_96Bit |
- EMAC_CarrierSense_Enable |
- EMAC_Speed_100M |
- EMAC_ReceiveOwn_Enable |
- EMAC_LoopbackMode_Disable |
- EMAC_Mode_FullDuplex |
- EMAC_ChecksumOffload_Enable |
- EMAC_RetryTransmission_Disable |
- EMAC_AutomaticPadCRCStrip_Disable |
- EMAC_BackOffLimit_10 |
- EMAC_DeferralCheck_Disable);
- /* Write to ETHERNET MACCR */
- value |= (1<<15);
- value &= ~(1<<25);
- value &= ~(1<<24);
- ETHERNET_MAC->MCR = (rt_uint32_t)value;
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Write to ETHERNET MACFFR */
- ETHERNET_MAC->MFFR = (rt_uint32_t)(EMAC_ReceiveAll_Enable |
- EMAC_SourceAddrFilter_Disable |
- EMAC_PassControlFrames_BlockAll |
- EMAC_BroadcastFramesReception_Disable |
- EMAC_DestinationAddrFilter_Normal |
- EMAC_PromiscuousMode_Disable |
- EMAC_MulticastFramesFilter_Perfect |
- EMAC_UnicastFramesFilter_Perfect);
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
- /* Write to ETHERNET MACHTHR */
- ETHERNET_MAC->MHTRH = 0;
- /* Write to ETHERNET MACHTLR */
- ETHERNET_MAC->MHTRL = 0;
- /*----------------------- ETHERNET MACFCR Configuration --------------------*/
- /* Get the ETHERNET MACFCR value */
- value = ETHERNET_MAC->FCR;
- /* Clear xx bits */
- value &= MACFCR_CLEAR_MASK;
- value |= (rt_uint32_t)((0 << 16) |
- EMAC_ZeroQuantaPause_Disable |
- EMAC_PauseLowThreshold_Minus4 |
- EMAC_UnicastPauseFrameDetect_Disable |
- EMAC_ReceiveFlowControl_Disable |
- EMAC_TransmitFlowControl_Disable);
- /* Write to ETHERNET MACFCR */
- ETHERNET_MAC->FCR = (rt_uint32_t)value;
- /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
- ETHERNET_MAC->VTR = (rt_uint32_t)(EMAC_VLANTagComparison_16Bit |
- 0);
- /*-------------------------------- DMA Config ------------------------------*/
- /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
- /* Get the ETHERNET DMAOMR value */
- value = ETHERNET_MAC->OMR;
- /* Clear xx bits */
- value &= DMAOMR_CLEAR_MASK;
- value |= (rt_uint32_t)(EMAC_DropTCPIPChecksumErrorFrame_Disable |
- EMAC_ReceiveStoreForward_Enable |
- EMAC_FlushReceivedFrame_Enable |
- EMAC_TransmitStoreForward_Enable |
- EMAC_TransmitThresholdControl_64Bytes |
- EMAC_ForwardErrorFrames_Disable |
- EMAC_ForwardUndersizedGoodFrames_Disable |
- EMAC_ReceiveThresholdControl_64Bytes |
- EMAC_SecondFrameOperate_Disable);
- /* Write to ETHERNET DMAOMR */
- ETHERNET_MAC->OMR = (rt_uint32_t)value;
- /*----------------------- ETHERNET DMABMR Configuration --------------------*/
- ETHERNET_MAC->BMR = (rt_uint32_t)(EMAC_AddressAlignedBeats_Enable |
- EMAC_FixedBurst_Enable |
- EMAC_RxDMABurstLength_32Beat | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- EMAC_TxDMABurstLength_32Beat |
- (0 << 2) |
- EMAC_DMAArbitration_RoundRobin_RxTx_2_1 |
- EMAC_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
- /* Return Ethernet configuration success */
- return EMAC_SUCCESS;
- }
- /**
- * Enables or disables the specified ETHERNET DMA interrupts.
- */
- void EMAC_INT_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState)
- {
- if (NewState)
- {
- /* Enable the selected ETHERNET DMA interrupts */
- ETHERNET_MAC->IER |= EMAC_DMA_IT;
- }
- else
- {
- /* Disable the selected ETHERNET DMA interrupts */
- ETHERNET_MAC->IER &=(~(rt_uint32_t)EMAC_DMA_IT);
- }
- }
- /**
- * Configures the selected MAC address.
- */
- void EMAC_MAC_Addr_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr)
- {
- rt_uint32_t value;
- /* Calculate the selectecd MAC address high register */
- value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4];
- /* Load the selectecd MAC address high register */
- //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value;
- ETHERNET_MAC->MARs[MacAddr].MARH = value;
- /* Calculate the selectecd MAC address low register */
- value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0];
- /* Load the selectecd MAC address low register */
- //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value;
- ETHERNET_MAC->MARs[MacAddr].MARL = value;
- }
- /**
- * Enables or disables the MAC transmission.
- */
- void EMAC_MACTransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
- {
- if (NewState)
- {
- /* Enable the MAC transmission */
- ETHERNET_MAC->MCR |= EMAC_MACCR_TE;
- }
- else
- {
- /* Disable the MAC transmission */
- ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE;
- }
- }
- /**
- * Clears the ETHERNET transmit FIFO.
- */
- void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth * ETHERNET_MAC)
- {
- /* Set the Flush Transmit FIFO bit */
- ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF;
- }
- /**
- * Enables or disables the MAC reception.
- */
- void EMAC_MACReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
- {
- if (NewState)
- {
- /* Enable the MAC reception */
- ETHERNET_MAC->MCR |= EMAC_MACCR_RE;
- }
- else
- {
- /* Disable the MAC reception */
- ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE;
- }
- }
- /**
- * Enables or disables the DMA transmission.
- */
- void EMAC_DMATransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
- {
- if (NewState)
- {
- /* Enable the DMA transmission */
- ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST;
- }
- else
- {
- /* Disable the DMA transmission */
- ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST;
- }
- }
- /**
- * Enables or disables the DMA reception.
- */
- void EMAC_DMAReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
- {
- if (NewState)
- {
- /* Enable the DMA reception */
- ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR;
- }
- else
- {
- /* Disable the DMA reception */
- ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR;
- }
- }
- /**
- * Enables ENET MAC and DMA reception/transmission
- */
- void EMAC_start(struct rt_synopsys_eth * ETHERNET_MAC)
- {
- /* Enable transmit state machine of the MAC for transmission on the MII */
- EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE);
- /* Flush Transmit FIFO */
- EMAC_FlushTransmitFIFO(ETHERNET_MAC);
- /* Enable receive state machine of the MAC for reception from the MII */
- EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE);
- /* Start DMA transmission */
- EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE);
- /* Start DMA reception */
- EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE);
- }
- /**
- * Clears the ETHERNET's DMA interrupt pending bit.
- */
- void EMAC_clear_pending(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t pending)
- {
- /* Clear the selected ETHERNET DMA IT */
- ETHERNET_MAC->SR = (rt_uint32_t) pending;
- }
- /**
- * Resumes the DMA Transmission by writing to the DmaRxPollDemand register
- * (the data written could be anything). This forces the DMA to resume reception.
- */
- void EMAC_resume_reception(struct rt_synopsys_eth * ETHERNET_MAC)
- {
- ETHERNET_MAC->RPDR = 0;
- }
- /**
- * Resumes the DMA Transmission by writing to the DmaTxPollDemand register
- * (the data written could be anything). This forces the DMA to resume transmission.
- */
- void EMAC_resume_transmission(struct rt_synopsys_eth * ETHERNET_MAC)
- {
- ETHERNET_MAC->TPDR = 0;
- }
- /**
- * Read a PHY register
- */
- rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg)
- {
- rt_uint32_t value = 0;
- volatile rt_uint32_t timeout = 0;
- /* Get the ETHERNET MACMIIAR value */
- value = ETHERNET_MAC->GAR;
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- value &= ~MACMIIAR_CR_MASK;
- /* Prepare the MII address register value */
- value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
- value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
- value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */
- value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
- /* Write the result value into the MII Address register */
- ETHERNET_MAC->GAR = value;
- /* Check for the Busy flag */
- do
- {
- timeout++;
- value = ETHERNET_MAC->GAR;
- }
- while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO));
- /* Return ERROR in case of timeout */
- if(timeout == PHY_READ_TO)
- {
- return (rt_uint16_t)EMAC_ERROR;
- }
- /* Return data register value */
- return (rt_uint16_t)(ETHERNET_MAC->GDR);
- }
- /**
- * Write to a PHY register
- */
- rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue)
- {
- rt_uint32_t value = 0;
- volatile rt_uint32_t timeout = 0;
- /* Get the ETHERNET MACMIIAR value */
- value = ETHERNET_MAC->GAR;
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- value &= ~MACMIIAR_CR_MASK;
- /* Prepare the MII register address value */
- value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
- value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
- value |= EMAC_MACMIIAR_MW; /* Set the write mode */
- value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
- /* Give the value to the MII data register */
- ETHERNET_MAC->GDR = PHYValue;
- /* Write the result value into the MII Address register */
- ETHERNET_MAC->GAR = value;
- /* Check for the Busy flag */
- do
- {
- timeout++;
- value = ETHERNET_MAC->GAR;
- }
- while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO));
- /* Return ERROR in case of timeout */
- if(timeout == PHY_WRITE_TO)
- {
- return EMAC_ERROR;
- }
- /* Return SUCCESS */
- return EMAC_SUCCESS;
- }
|