SilentSensors / mbed-dev

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Thu Aug 31 17:27:04 2017 +0100
Revision:
172:7d866c31b3c5
This updates the lib to the mbed lib v 150

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 172:7d866c31b3c5 1 /**************************************************************************//**
AnnaBridge 172:7d866c31b3c5 2 * @file emac.c
AnnaBridge 172:7d866c31b3c5 3 * @version V1.00
AnnaBridge 172:7d866c31b3c5 4 * @brief M480 EMAC driver source file
AnnaBridge 172:7d866c31b3c5 5 *
AnnaBridge 172:7d866c31b3c5 6 * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
AnnaBridge 172:7d866c31b3c5 7 *****************************************************************************/
AnnaBridge 172:7d866c31b3c5 8 #include <stdio.h>
AnnaBridge 172:7d866c31b3c5 9 #include <string.h>
AnnaBridge 172:7d866c31b3c5 10 #include "M480.h"
AnnaBridge 172:7d866c31b3c5 11
AnnaBridge 172:7d866c31b3c5 12
AnnaBridge 172:7d866c31b3c5 13 /** @addtogroup M480_Device_Driver M480 Device Driver
AnnaBridge 172:7d866c31b3c5 14 @{
AnnaBridge 172:7d866c31b3c5 15 */
AnnaBridge 172:7d866c31b3c5 16
AnnaBridge 172:7d866c31b3c5 17 /** @addtogroup M480_EMAC_Driver EMAC Driver
AnnaBridge 172:7d866c31b3c5 18 @{
AnnaBridge 172:7d866c31b3c5 19 */
AnnaBridge 172:7d866c31b3c5 20
AnnaBridge 172:7d866c31b3c5 21
AnnaBridge 172:7d866c31b3c5 22 /* Below are structure, definitions, static variables used locally by EMAC driver and does not want to parse by doxygen unless HIDDEN_SYMBOLS is defined */
AnnaBridge 172:7d866c31b3c5 23 /** @cond HIDDEN_SYMBOLS */
AnnaBridge 172:7d866c31b3c5 24
AnnaBridge 172:7d866c31b3c5 25 /** @addtogroup M480_EMAC_EXPORTED_CONSTANTS EMAC Exported Constants
AnnaBridge 172:7d866c31b3c5 26 @{
AnnaBridge 172:7d866c31b3c5 27 */
AnnaBridge 172:7d866c31b3c5 28
AnnaBridge 172:7d866c31b3c5 29 /* PHY Register Description */
AnnaBridge 172:7d866c31b3c5 30 #define PHY_CNTL_REG 0x00UL /*!< PHY control register address */
AnnaBridge 172:7d866c31b3c5 31 #define PHY_STATUS_REG 0x01UL /*!< PHY status register address */
AnnaBridge 172:7d866c31b3c5 32 #define PHY_ID1_REG 0x02UL /*!< PHY ID1 register */
AnnaBridge 172:7d866c31b3c5 33 #define PHY_ID2_REG 0x03UL /*!< PHY ID2 register */
AnnaBridge 172:7d866c31b3c5 34 #define PHY_ANA_REG 0x04UL /*!< PHY auto-negotiation advertisement register */
AnnaBridge 172:7d866c31b3c5 35 #define PHY_ANLPA_REG 0x05UL /*!< PHY auto-negotiation link partner availability register */
AnnaBridge 172:7d866c31b3c5 36 #define PHY_ANE_REG 0x06UL /*!< PHY auto-negotiation expansion register */
AnnaBridge 172:7d866c31b3c5 37
AnnaBridge 172:7d866c31b3c5 38 /* PHY Control Register */
AnnaBridge 172:7d866c31b3c5 39 #define PHY_CNTL_RESET_PHY (1UL << 15UL)
AnnaBridge 172:7d866c31b3c5 40 #define PHY_CNTL_DR_100MB (1UL << 13UL)
AnnaBridge 172:7d866c31b3c5 41 #define PHY_CNTL_ENABLE_AN (1UL << 12UL)
AnnaBridge 172:7d866c31b3c5 42 #define PHY_CNTL_POWER_DOWN (1UL << 11UL)
AnnaBridge 172:7d866c31b3c5 43 #define PHY_CNTL_RESTART_AN (1UL << 9UL)
AnnaBridge 172:7d866c31b3c5 44 #define PHY_CNTL_FULLDUPLEX (1UL << 8UL)
AnnaBridge 172:7d866c31b3c5 45
AnnaBridge 172:7d866c31b3c5 46 /* PHY Status Register */
AnnaBridge 172:7d866c31b3c5 47 #define PHY_STATUS_AN_COMPLETE (1UL << 5UL)
AnnaBridge 172:7d866c31b3c5 48 #define PHY_STATUS_LINK_VALID (1UL << 2UL)
AnnaBridge 172:7d866c31b3c5 49
AnnaBridge 172:7d866c31b3c5 50 /* PHY Auto-negotiation Advertisement Register */
AnnaBridge 172:7d866c31b3c5 51 #define PHY_ANA_DR100_TX_FULL (1UL << 8UL)
AnnaBridge 172:7d866c31b3c5 52 #define PHY_ANA_DR100_TX_HALF (1UL << 7UL)
AnnaBridge 172:7d866c31b3c5 53 #define PHY_ANA_DR10_TX_FULL (1UL << 6UL)
AnnaBridge 172:7d866c31b3c5 54 #define PHY_ANA_DR10_TX_HALF (1UL << 5UL)
AnnaBridge 172:7d866c31b3c5 55 #define PHY_ANA_IEEE_802_3_CSMA_CD (1UL << 0UL)
AnnaBridge 172:7d866c31b3c5 56
AnnaBridge 172:7d866c31b3c5 57 /* PHY Auto-negotiation Link Partner Advertisement Register */
AnnaBridge 172:7d866c31b3c5 58 #define PHY_ANLPA_DR100_TX_FULL (1UL << 8UL)
AnnaBridge 172:7d866c31b3c5 59 #define PHY_ANLPA_DR100_TX_HALF (1UL << 7UL)
AnnaBridge 172:7d866c31b3c5 60 #define PHY_ANLPA_DR10_TX_FULL (1UL << 6UL)
AnnaBridge 172:7d866c31b3c5 61 #define PHY_ANLPA_DR10_TX_HALF (1UL << 5UL)
AnnaBridge 172:7d866c31b3c5 62
AnnaBridge 172:7d866c31b3c5 63 /* EMAC Tx/Rx descriptor's owner bit */
AnnaBridge 172:7d866c31b3c5 64 #define EMAC_DESC_OWN_EMAC 0x80000000UL /*!< Set owner to EMAC */
AnnaBridge 172:7d866c31b3c5 65 #define EMAC_DESC_OWN_CPU 0x00000000UL /*!< Set owner to CPU */
AnnaBridge 172:7d866c31b3c5 66
AnnaBridge 172:7d866c31b3c5 67 /* Rx Frame Descriptor Status */
AnnaBridge 172:7d866c31b3c5 68 #define EMAC_RXFD_RTSAS 0x0080UL /*!< Time Stamp Available */
AnnaBridge 172:7d866c31b3c5 69 #define EMAC_RXFD_RP 0x0040UL /*!< Runt Packet */
AnnaBridge 172:7d866c31b3c5 70 #define EMAC_RXFD_ALIE 0x0020UL /*!< Alignment Error */
AnnaBridge 172:7d866c31b3c5 71 #define EMAC_RXFD_RXGD 0x0010UL /*!< Receiving Good packet received */
AnnaBridge 172:7d866c31b3c5 72 #define EMAC_RXFD_PTLE 0x0008UL /*!< Packet Too Long Error */
AnnaBridge 172:7d866c31b3c5 73 #define EMAC_RXFD_CRCE 0x0002UL /*!< CRC Error */
AnnaBridge 172:7d866c31b3c5 74 #define EMAC_RXFD_RXINTR 0x0001UL /*!< Interrupt on receive */
AnnaBridge 172:7d866c31b3c5 75
AnnaBridge 172:7d866c31b3c5 76 /* Tx Frame Descriptor's Control bits */
AnnaBridge 172:7d866c31b3c5 77 #define EMAC_TXFD_TTSEN 0x08UL /*!< Tx time stamp enable */
AnnaBridge 172:7d866c31b3c5 78 #define EMAC_TXFD_INTEN 0x04UL /*!< Tx interrupt enable */
AnnaBridge 172:7d866c31b3c5 79 #define EMAC_TXFD_CRCAPP 0x02UL /*!< Append CRC */
AnnaBridge 172:7d866c31b3c5 80 #define EMAC_TXFD_PADEN 0x01UL /*!< Padding mode enable */
AnnaBridge 172:7d866c31b3c5 81
AnnaBridge 172:7d866c31b3c5 82 /* Tx Frame Descriptor Status */
AnnaBridge 172:7d866c31b3c5 83 #define EMAC_TXFD_TXINTR 0x0001UL /*!< Interrupt on Transmit */
AnnaBridge 172:7d866c31b3c5 84 #define EMAC_TXFD_DEF 0x0002UL /*!< Transmit deferred */
AnnaBridge 172:7d866c31b3c5 85 #define EMAC_TXFD_TXCP 0x0008UL /*!< Transmission Completion */
AnnaBridge 172:7d866c31b3c5 86 #define EMAC_TXFD_EXDEF 0x0010UL /*!< Exceed Deferral */
AnnaBridge 172:7d866c31b3c5 87 #define EMAC_TXFD_NCS 0x0020UL /*!< No Carrier Sense Error */
AnnaBridge 172:7d866c31b3c5 88 #define EMAC_TXFD_TXABT 0x0040UL /*!< Transmission Abort */
AnnaBridge 172:7d866c31b3c5 89 #define EMAC_TXFD_LC 0x0080UL /*!< Late Collision */
AnnaBridge 172:7d866c31b3c5 90 #define EMAC_TXFD_TXHA 0x0100UL /*!< Transmission halted */
AnnaBridge 172:7d866c31b3c5 91 #define EMAC_TXFD_PAU 0x0200UL /*!< Paused */
AnnaBridge 172:7d866c31b3c5 92 #define EMAC_TXFD_SQE 0x0400UL /*!< SQE error */
AnnaBridge 172:7d866c31b3c5 93 #define EMAC_TXFD_TTSAS 0x0800UL /*!< Time Stamp available */
AnnaBridge 172:7d866c31b3c5 94
AnnaBridge 172:7d866c31b3c5 95 /*@}*/ /* end of group M480_EMAC_EXPORTED_CONSTANTS */
AnnaBridge 172:7d866c31b3c5 96
AnnaBridge 172:7d866c31b3c5 97 /** @addtogroup M480_EMAC_EXPORTED_TYPEDEF EMAC Exported Type Defines
AnnaBridge 172:7d866c31b3c5 98 @{
AnnaBridge 172:7d866c31b3c5 99 */
AnnaBridge 172:7d866c31b3c5 100
AnnaBridge 172:7d866c31b3c5 101 /** Tx/Rx buffer descriptor structure */
AnnaBridge 172:7d866c31b3c5 102 typedef struct {
AnnaBridge 172:7d866c31b3c5 103 uint32_t u32Status1; /*!< Status word 1 */
AnnaBridge 172:7d866c31b3c5 104 uint32_t u32Data; /*!< Pointer to data buffer */
AnnaBridge 172:7d866c31b3c5 105 uint32_t u32Status2; /*!< Status word 2 */
AnnaBridge 172:7d866c31b3c5 106 uint32_t u32Next; /*!< Pointer to next descriptor */
AnnaBridge 172:7d866c31b3c5 107 uint32_t u32Backup1; /*!< For backup descriptor fields over written by time stamp */
AnnaBridge 172:7d866c31b3c5 108 uint32_t u32Backup2; /*!< For backup descriptor fields over written by time stamp */
AnnaBridge 172:7d866c31b3c5 109 } EMAC_DESCRIPTOR_T;
AnnaBridge 172:7d866c31b3c5 110
AnnaBridge 172:7d866c31b3c5 111 /** Tx/Rx buffer structure */
AnnaBridge 172:7d866c31b3c5 112 typedef struct {
AnnaBridge 172:7d866c31b3c5 113 uint8_t au8Buf[1520];
AnnaBridge 172:7d866c31b3c5 114 } EMAC_FRAME_T;
AnnaBridge 172:7d866c31b3c5 115
AnnaBridge 172:7d866c31b3c5 116 /*@}*/ /* end of group M480_EMAC_EXPORTED_TYPEDEF */
AnnaBridge 172:7d866c31b3c5 117
AnnaBridge 172:7d866c31b3c5 118 /* local variables */
AnnaBridge 172:7d866c31b3c5 119 static volatile EMAC_DESCRIPTOR_T rx_desc[EMAC_RX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 120 static volatile EMAC_FRAME_T rx_buf[EMAC_RX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 121 static volatile EMAC_DESCRIPTOR_T tx_desc[EMAC_TX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 122 static volatile EMAC_FRAME_T tx_buf[EMAC_TX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 123
AnnaBridge 172:7d866c31b3c5 124
AnnaBridge 172:7d866c31b3c5 125 static uint32_t u32CurrentTxDesc, u32NextTxDesc, u32CurrentRxDesc;
AnnaBridge 172:7d866c31b3c5 126 static uint32_t s_u32EnableTs = 0UL;
AnnaBridge 172:7d866c31b3c5 127
AnnaBridge 172:7d866c31b3c5 128 static void EMAC_MdioWrite(uint32_t u32Reg, uint32_t u32Addr, uint32_t u32Data);
AnnaBridge 172:7d866c31b3c5 129 static uint32_t EMAC_MdioRead(uint32_t u32Reg, uint32_t u32Addr);
AnnaBridge 172:7d866c31b3c5 130 static void EMAC_PhyInit(void);
AnnaBridge 172:7d866c31b3c5 131 static void EMAC_TxDescInit(void);
AnnaBridge 172:7d866c31b3c5 132 static void EMAC_RxDescInit(void);
AnnaBridge 172:7d866c31b3c5 133 static uint32_t EMAC_Subsec2Nsec(uint32_t subsec);
AnnaBridge 172:7d866c31b3c5 134 static uint32_t EMAC_Nsec2Subsec(uint32_t nsec);
AnnaBridge 172:7d866c31b3c5 135
AnnaBridge 172:7d866c31b3c5 136 /** @addtogroup M480_EMAC_EXPORTED_FUNCTIONS EMAC Exported Functions
AnnaBridge 172:7d866c31b3c5 137 @{
AnnaBridge 172:7d866c31b3c5 138 */
AnnaBridge 172:7d866c31b3c5 139
AnnaBridge 172:7d866c31b3c5 140 /**
AnnaBridge 172:7d866c31b3c5 141 * @brief Trigger EMAC Rx function
AnnaBridge 172:7d866c31b3c5 142 * @param None
AnnaBridge 172:7d866c31b3c5 143 * @return None
AnnaBridge 172:7d866c31b3c5 144 */
AnnaBridge 172:7d866c31b3c5 145 #define EMAC_TRIGGER_RX() do{EMAC->RXST = 0UL;}while(0)
AnnaBridge 172:7d866c31b3c5 146
AnnaBridge 172:7d866c31b3c5 147 /**
AnnaBridge 172:7d866c31b3c5 148 * @brief Trigger EMAC Tx function
AnnaBridge 172:7d866c31b3c5 149 * @param None
AnnaBridge 172:7d866c31b3c5 150 * @return None
AnnaBridge 172:7d866c31b3c5 151 */
AnnaBridge 172:7d866c31b3c5 152 #define EMAC_TRIGGER_TX() do{EMAC->TXST = 0UL;}while(0)
AnnaBridge 172:7d866c31b3c5 153
AnnaBridge 172:7d866c31b3c5 154
AnnaBridge 172:7d866c31b3c5 155 /**
AnnaBridge 172:7d866c31b3c5 156 * @brief Write PHY register
AnnaBridge 172:7d866c31b3c5 157 * @param[in] u32Reg PHY register number
AnnaBridge 172:7d866c31b3c5 158 * @param[in] u32Addr PHY address, this address is board dependent
AnnaBridge 172:7d866c31b3c5 159 * @param[in] u32Data data to write to PHY register
AnnaBridge 172:7d866c31b3c5 160 * @return None
AnnaBridge 172:7d866c31b3c5 161 */
AnnaBridge 172:7d866c31b3c5 162 static void EMAC_MdioWrite(uint32_t u32Reg, uint32_t u32Addr, uint32_t u32Data)
AnnaBridge 172:7d866c31b3c5 163 {
AnnaBridge 172:7d866c31b3c5 164 /* Set data register */
AnnaBridge 172:7d866c31b3c5 165 EMAC->MIIMDAT = u32Data ;
AnnaBridge 172:7d866c31b3c5 166 /* Set PHY address, PHY register address, busy bit and write bit */
AnnaBridge 172:7d866c31b3c5 167 EMAC->MIIMCTL = u32Reg | (u32Addr << 8) | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
AnnaBridge 172:7d866c31b3c5 168 /* Wait write complete by polling busy bit. */
AnnaBridge 172:7d866c31b3c5 169 while(EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk) {
AnnaBridge 172:7d866c31b3c5 170 ;
AnnaBridge 172:7d866c31b3c5 171 }
AnnaBridge 172:7d866c31b3c5 172
AnnaBridge 172:7d866c31b3c5 173 }
AnnaBridge 172:7d866c31b3c5 174
AnnaBridge 172:7d866c31b3c5 175 /**
AnnaBridge 172:7d866c31b3c5 176 * @brief Read PHY register
AnnaBridge 172:7d866c31b3c5 177 * @param[in] u32Reg PHY register number
AnnaBridge 172:7d866c31b3c5 178 * @param[in] u32Addr PHY address, this address is board dependent
AnnaBridge 172:7d866c31b3c5 179 * @return Value read from PHY register
AnnaBridge 172:7d866c31b3c5 180 */
AnnaBridge 172:7d866c31b3c5 181 static uint32_t EMAC_MdioRead(uint32_t u32Reg, uint32_t u32Addr)
AnnaBridge 172:7d866c31b3c5 182 {
AnnaBridge 172:7d866c31b3c5 183 /* Set PHY address, PHY register address, busy bit */
AnnaBridge 172:7d866c31b3c5 184 EMAC->MIIMCTL = u32Reg | (u32Addr << EMAC_MIIMCTL_PHYADDR_Pos) | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
AnnaBridge 172:7d866c31b3c5 185 /* Wait read complete by polling busy bit */
AnnaBridge 172:7d866c31b3c5 186 while(EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk) {
AnnaBridge 172:7d866c31b3c5 187 ;
AnnaBridge 172:7d866c31b3c5 188 }
AnnaBridge 172:7d866c31b3c5 189 /* Get return data */
AnnaBridge 172:7d866c31b3c5 190 return EMAC->MIIMDAT;
AnnaBridge 172:7d866c31b3c5 191 }
AnnaBridge 172:7d866c31b3c5 192
AnnaBridge 172:7d866c31b3c5 193 /**
AnnaBridge 172:7d866c31b3c5 194 * @brief Initialize PHY chip, check for the auto-negotiation result.
AnnaBridge 172:7d866c31b3c5 195 * @param None
AnnaBridge 172:7d866c31b3c5 196 * @return None
AnnaBridge 172:7d866c31b3c5 197 */
AnnaBridge 172:7d866c31b3c5 198 static void EMAC_PhyInit(void)
AnnaBridge 172:7d866c31b3c5 199 {
AnnaBridge 172:7d866c31b3c5 200 uint32_t reg;
AnnaBridge 172:7d866c31b3c5 201 uint32_t i = 0UL;
AnnaBridge 172:7d866c31b3c5 202
AnnaBridge 172:7d866c31b3c5 203 /* Reset Phy Chip */
AnnaBridge 172:7d866c31b3c5 204 EMAC_MdioWrite(PHY_CNTL_REG, EMAC_PHY_ADDR, PHY_CNTL_RESET_PHY);
AnnaBridge 172:7d866c31b3c5 205
AnnaBridge 172:7d866c31b3c5 206 /* Wait until reset complete */
AnnaBridge 172:7d866c31b3c5 207 while (1) {
AnnaBridge 172:7d866c31b3c5 208 reg = EMAC_MdioRead(PHY_CNTL_REG, EMAC_PHY_ADDR) ;
AnnaBridge 172:7d866c31b3c5 209 if ((reg & PHY_CNTL_RESET_PHY)==0UL) {
AnnaBridge 172:7d866c31b3c5 210 break;
AnnaBridge 172:7d866c31b3c5 211 }
AnnaBridge 172:7d866c31b3c5 212 }
AnnaBridge 172:7d866c31b3c5 213 while(!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID)) {
AnnaBridge 172:7d866c31b3c5 214 if(i++ > 80000UL) { /* Cable not connected */
AnnaBridge 172:7d866c31b3c5 215 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
AnnaBridge 172:7d866c31b3c5 216 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
AnnaBridge 172:7d866c31b3c5 217 break;
AnnaBridge 172:7d866c31b3c5 218 }
AnnaBridge 172:7d866c31b3c5 219 }
AnnaBridge 172:7d866c31b3c5 220
AnnaBridge 172:7d866c31b3c5 221 if(i <= 80000UL) {
AnnaBridge 172:7d866c31b3c5 222 /* Configure auto negotiation capability */
AnnaBridge 172:7d866c31b3c5 223 EMAC_MdioWrite(PHY_ANA_REG, EMAC_PHY_ADDR, PHY_ANA_DR100_TX_FULL |
AnnaBridge 172:7d866c31b3c5 224 PHY_ANA_DR100_TX_HALF |
AnnaBridge 172:7d866c31b3c5 225 PHY_ANA_DR10_TX_FULL |
AnnaBridge 172:7d866c31b3c5 226 PHY_ANA_DR10_TX_HALF |
AnnaBridge 172:7d866c31b3c5 227 PHY_ANA_IEEE_802_3_CSMA_CD);
AnnaBridge 172:7d866c31b3c5 228 /* Restart auto negotiation */
AnnaBridge 172:7d866c31b3c5 229 EMAC_MdioWrite(PHY_CNTL_REG, EMAC_PHY_ADDR, EMAC_MdioRead(PHY_CNTL_REG, EMAC_PHY_ADDR) | PHY_CNTL_RESTART_AN);
AnnaBridge 172:7d866c31b3c5 230
AnnaBridge 172:7d866c31b3c5 231 /* Wait for auto-negotiation complete */
AnnaBridge 172:7d866c31b3c5 232 while(!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_AN_COMPLETE)) {
AnnaBridge 172:7d866c31b3c5 233 ;
AnnaBridge 172:7d866c31b3c5 234 }
AnnaBridge 172:7d866c31b3c5 235 /* Check link valid again. Some PHYs needs to check result after link valid bit set */
AnnaBridge 172:7d866c31b3c5 236 while(!(EMAC_MdioRead(PHY_STATUS_REG, EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID)) {
AnnaBridge 172:7d866c31b3c5 237 ;
AnnaBridge 172:7d866c31b3c5 238 }
AnnaBridge 172:7d866c31b3c5 239
AnnaBridge 172:7d866c31b3c5 240 /* Check link partner capability */
AnnaBridge 172:7d866c31b3c5 241 reg = EMAC_MdioRead(PHY_ANLPA_REG, EMAC_PHY_ADDR) ;
AnnaBridge 172:7d866c31b3c5 242 if (reg & PHY_ANLPA_DR100_TX_FULL) {
AnnaBridge 172:7d866c31b3c5 243 EMAC->CTL |= EMAC_CTL_OPMODE_Msk;
AnnaBridge 172:7d866c31b3c5 244 EMAC->CTL |= EMAC_CTL_FUDUP_Msk;
AnnaBridge 172:7d866c31b3c5 245 } else if (reg & PHY_ANLPA_DR100_TX_HALF) {
AnnaBridge 172:7d866c31b3c5 246 EMAC->CTL |= EMAC_CTL_OPMODE_Msk;
AnnaBridge 172:7d866c31b3c5 247 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
AnnaBridge 172:7d866c31b3c5 248 } else if (reg & PHY_ANLPA_DR10_TX_FULL) {
AnnaBridge 172:7d866c31b3c5 249 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
AnnaBridge 172:7d866c31b3c5 250 EMAC->CTL |= EMAC_CTL_FUDUP_Msk;
AnnaBridge 172:7d866c31b3c5 251 } else {
AnnaBridge 172:7d866c31b3c5 252 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
AnnaBridge 172:7d866c31b3c5 253 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
AnnaBridge 172:7d866c31b3c5 254 }
AnnaBridge 172:7d866c31b3c5 255 }
AnnaBridge 172:7d866c31b3c5 256 }
AnnaBridge 172:7d866c31b3c5 257
AnnaBridge 172:7d866c31b3c5 258 /**
AnnaBridge 172:7d866c31b3c5 259 * @brief Initial EMAC Tx descriptors and get Tx descriptor base address
AnnaBridge 172:7d866c31b3c5 260 * @param None
AnnaBridge 172:7d866c31b3c5 261 * @return None
AnnaBridge 172:7d866c31b3c5 262 */
AnnaBridge 172:7d866c31b3c5 263 static void EMAC_TxDescInit(void)
AnnaBridge 172:7d866c31b3c5 264 {
AnnaBridge 172:7d866c31b3c5 265 uint32_t i;
AnnaBridge 172:7d866c31b3c5 266
AnnaBridge 172:7d866c31b3c5 267 /* Get Frame descriptor's base address. */
AnnaBridge 172:7d866c31b3c5 268 EMAC->TXDSA = (uint32_t)&tx_desc[0];
AnnaBridge 172:7d866c31b3c5 269 u32NextTxDesc = u32CurrentTxDesc = (uint32_t)&tx_desc[0];
AnnaBridge 172:7d866c31b3c5 270
AnnaBridge 172:7d866c31b3c5 271 for(i = 0UL; i < EMAC_TX_DESC_SIZE; i++) {
AnnaBridge 172:7d866c31b3c5 272
AnnaBridge 172:7d866c31b3c5 273 if(s_u32EnableTs) {
AnnaBridge 172:7d866c31b3c5 274 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN;
AnnaBridge 172:7d866c31b3c5 275 } else {
AnnaBridge 172:7d866c31b3c5 276 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN | EMAC_TXFD_TTSEN;
AnnaBridge 172:7d866c31b3c5 277 }
AnnaBridge 172:7d866c31b3c5 278 tx_desc[i].u32Data = (uint32_t)((uint32_t)&tx_buf[i]);
AnnaBridge 172:7d866c31b3c5 279 tx_desc[i].u32Backup1 = tx_desc[i].u32Data;
AnnaBridge 172:7d866c31b3c5 280 tx_desc[i].u32Status2 = 0UL;
AnnaBridge 172:7d866c31b3c5 281 tx_desc[i].u32Next = (uint32_t)&tx_desc[(i + 1UL) % EMAC_TX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 282 tx_desc[i].u32Backup2 = tx_desc[i].u32Next;
AnnaBridge 172:7d866c31b3c5 283
AnnaBridge 172:7d866c31b3c5 284 }
AnnaBridge 172:7d866c31b3c5 285
AnnaBridge 172:7d866c31b3c5 286 }
AnnaBridge 172:7d866c31b3c5 287
AnnaBridge 172:7d866c31b3c5 288
AnnaBridge 172:7d866c31b3c5 289 /**
AnnaBridge 172:7d866c31b3c5 290 * @brief Initial EMAC Rx descriptors and get Rx descriptor base address
AnnaBridge 172:7d866c31b3c5 291 * @param None
AnnaBridge 172:7d866c31b3c5 292 * @return None
AnnaBridge 172:7d866c31b3c5 293 */
AnnaBridge 172:7d866c31b3c5 294 static void EMAC_RxDescInit(void)
AnnaBridge 172:7d866c31b3c5 295 {
AnnaBridge 172:7d866c31b3c5 296
AnnaBridge 172:7d866c31b3c5 297 uint32_t i;
AnnaBridge 172:7d866c31b3c5 298
AnnaBridge 172:7d866c31b3c5 299 /* Get Frame descriptor's base address. */
AnnaBridge 172:7d866c31b3c5 300 EMAC->RXDSA = (uint32_t)&rx_desc[0];
AnnaBridge 172:7d866c31b3c5 301 u32CurrentRxDesc = (uint32_t)&rx_desc[0];
AnnaBridge 172:7d866c31b3c5 302
AnnaBridge 172:7d866c31b3c5 303 for(i = 0UL; i < EMAC_RX_DESC_SIZE; i++) {
AnnaBridge 172:7d866c31b3c5 304 rx_desc[i].u32Status1 = EMAC_DESC_OWN_EMAC;
AnnaBridge 172:7d866c31b3c5 305 rx_desc[i].u32Data = (uint32_t)((uint32_t)&rx_buf[i]);
AnnaBridge 172:7d866c31b3c5 306 rx_desc[i].u32Backup1 = rx_desc[i].u32Data;
AnnaBridge 172:7d866c31b3c5 307 rx_desc[i].u32Status2 = 0UL;
AnnaBridge 172:7d866c31b3c5 308 rx_desc[i].u32Next = (uint32_t)&rx_desc[(i + 1UL) % EMAC_RX_DESC_SIZE];
AnnaBridge 172:7d866c31b3c5 309 rx_desc[i].u32Backup2 = rx_desc[i].u32Next;
AnnaBridge 172:7d866c31b3c5 310 }
AnnaBridge 172:7d866c31b3c5 311
AnnaBridge 172:7d866c31b3c5 312 }
AnnaBridge 172:7d866c31b3c5 313
AnnaBridge 172:7d866c31b3c5 314 /**
AnnaBridge 172:7d866c31b3c5 315 * @brief Convert subsecond value to nano second
AnnaBridge 172:7d866c31b3c5 316 * @param[in] subsec Subsecond value to be convert
AnnaBridge 172:7d866c31b3c5 317 * @return Nano second
AnnaBridge 172:7d866c31b3c5 318 */
AnnaBridge 172:7d866c31b3c5 319 static uint32_t EMAC_Subsec2Nsec(uint32_t subsec)
AnnaBridge 172:7d866c31b3c5 320 {
AnnaBridge 172:7d866c31b3c5 321 /* 2^31 subsec == 10^9 ns */
AnnaBridge 172:7d866c31b3c5 322 uint64_t i;
AnnaBridge 172:7d866c31b3c5 323 i = 1000000000ull * (uint64_t)subsec;
AnnaBridge 172:7d866c31b3c5 324 i >>= 31;
AnnaBridge 172:7d866c31b3c5 325 return((uint32_t)i);
AnnaBridge 172:7d866c31b3c5 326 }
AnnaBridge 172:7d866c31b3c5 327
AnnaBridge 172:7d866c31b3c5 328 /**
AnnaBridge 172:7d866c31b3c5 329 * @brief Convert nano second to subsecond value
AnnaBridge 172:7d866c31b3c5 330 * @param[in] nsec Nano second to be convert
AnnaBridge 172:7d866c31b3c5 331 * @return Subsecond
AnnaBridge 172:7d866c31b3c5 332 */
AnnaBridge 172:7d866c31b3c5 333 static uint32_t EMAC_Nsec2Subsec(uint32_t nsec)
AnnaBridge 172:7d866c31b3c5 334 {
AnnaBridge 172:7d866c31b3c5 335 /* 10^9 ns = 2^31 subsec */
AnnaBridge 172:7d866c31b3c5 336 uint64_t i;
AnnaBridge 172:7d866c31b3c5 337 i = (1ull << 31) * nsec;
AnnaBridge 172:7d866c31b3c5 338 i /= 1000000000ull;
AnnaBridge 172:7d866c31b3c5 339 return((uint32_t)i);
AnnaBridge 172:7d866c31b3c5 340 }
AnnaBridge 172:7d866c31b3c5 341
AnnaBridge 172:7d866c31b3c5 342
AnnaBridge 172:7d866c31b3c5 343 /*@}*/ /* end of group M480_EMAC_EXPORTED_FUNCTIONS */
AnnaBridge 172:7d866c31b3c5 344
AnnaBridge 172:7d866c31b3c5 345
AnnaBridge 172:7d866c31b3c5 346
AnnaBridge 172:7d866c31b3c5 347 /** @endcond HIDDEN_SYMBOLS */
AnnaBridge 172:7d866c31b3c5 348
AnnaBridge 172:7d866c31b3c5 349
AnnaBridge 172:7d866c31b3c5 350 /** @addtogroup M480_EMAC_EXPORTED_FUNCTIONS EMAC Exported Functions
AnnaBridge 172:7d866c31b3c5 351 @{
AnnaBridge 172:7d866c31b3c5 352 */
AnnaBridge 172:7d866c31b3c5 353
AnnaBridge 172:7d866c31b3c5 354
AnnaBridge 172:7d866c31b3c5 355 /**
AnnaBridge 172:7d866c31b3c5 356 * @brief Initialize EMAC interface, including descriptors, MAC address, and PHY.
AnnaBridge 172:7d866c31b3c5 357 * @param[in] pu8MacAddr Pointer to uint8_t array holds MAC address
AnnaBridge 172:7d866c31b3c5 358 * @return None
AnnaBridge 172:7d866c31b3c5 359 * @note This API sets EMAC to work in RMII mode, but could configure to MII mode later with \ref EMAC_ENABLE_MII_INTF macro
AnnaBridge 172:7d866c31b3c5 360 * @note This API configures EMAC to receive all broadcast and multicast packets, but could configure to other settings with
AnnaBridge 172:7d866c31b3c5 361 * \ref EMAC_ENABLE_RECV_BCASTPKT, \ref EMAC_DISABLE_RECV_BCASTPKT, \ref EMAC_ENABLE_RECV_MCASTPKT, and \ref EMAC_DISABLE_RECV_MCASTPKT
AnnaBridge 172:7d866c31b3c5 362 * @note Receive(RX) and transmit(TX) are not enabled yet, application must call \ref EMAC_ENABLE_RX and \ref EMAC_ENABLE_TX to
AnnaBridge 172:7d866c31b3c5 363 * enable receive and transmit function.
AnnaBridge 172:7d866c31b3c5 364 */
AnnaBridge 172:7d866c31b3c5 365 void EMAC_Open(uint8_t *pu8MacAddr)
AnnaBridge 172:7d866c31b3c5 366 {
AnnaBridge 172:7d866c31b3c5 367 /* Enable transmit and receive descriptor */
AnnaBridge 172:7d866c31b3c5 368 EMAC_TxDescInit();
AnnaBridge 172:7d866c31b3c5 369 EMAC_RxDescInit();
AnnaBridge 172:7d866c31b3c5 370
AnnaBridge 172:7d866c31b3c5 371 /* Set the CAM Control register and the MAC address value */
AnnaBridge 172:7d866c31b3c5 372 EMAC_SetMacAddr(pu8MacAddr);
AnnaBridge 172:7d866c31b3c5 373
AnnaBridge 172:7d866c31b3c5 374 /* Configure the MAC interrupt enable register. */
AnnaBridge 172:7d866c31b3c5 375 EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
AnnaBridge 172:7d866c31b3c5 376 EMAC_INTEN_TXIEN_Msk |
AnnaBridge 172:7d866c31b3c5 377 EMAC_INTEN_RXGDIEN_Msk |
AnnaBridge 172:7d866c31b3c5 378 EMAC_INTEN_TXCPIEN_Msk |
AnnaBridge 172:7d866c31b3c5 379 EMAC_INTEN_RXBEIEN_Msk |
AnnaBridge 172:7d866c31b3c5 380 EMAC_INTEN_TXBEIEN_Msk |
AnnaBridge 172:7d866c31b3c5 381 EMAC_INTEN_RDUIEN_Msk |
AnnaBridge 172:7d866c31b3c5 382 EMAC_INTEN_TSALMIEN_Msk |
AnnaBridge 172:7d866c31b3c5 383 EMAC_INTEN_WOLIEN_Msk;
AnnaBridge 172:7d866c31b3c5 384
AnnaBridge 172:7d866c31b3c5 385 /* Configure the MAC control register. */
AnnaBridge 172:7d866c31b3c5 386 EMAC->CTL = EMAC_CTL_STRIPCRC_Msk |
AnnaBridge 172:7d866c31b3c5 387 EMAC_CTL_RMIIEN_Msk;
AnnaBridge 172:7d866c31b3c5 388
AnnaBridge 172:7d866c31b3c5 389 /* Accept packets for us and all broadcast and multicast packets */
AnnaBridge 172:7d866c31b3c5 390 EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
AnnaBridge 172:7d866c31b3c5 391 EMAC_CAMCTL_AMP_Msk |
AnnaBridge 172:7d866c31b3c5 392 EMAC_CAMCTL_ABP_Msk;
AnnaBridge 172:7d866c31b3c5 393
AnnaBridge 172:7d866c31b3c5 394 EMAC_PhyInit();
AnnaBridge 172:7d866c31b3c5 395 }
AnnaBridge 172:7d866c31b3c5 396
AnnaBridge 172:7d866c31b3c5 397 /**
AnnaBridge 172:7d866c31b3c5 398 * @brief This function stop all receive and transmit activity and disable MAC interface
AnnaBridge 172:7d866c31b3c5 399 * @param None
AnnaBridge 172:7d866c31b3c5 400 * @return None
AnnaBridge 172:7d866c31b3c5 401 */
AnnaBridge 172:7d866c31b3c5 402
AnnaBridge 172:7d866c31b3c5 403 void EMAC_Close(void)
AnnaBridge 172:7d866c31b3c5 404 {
AnnaBridge 172:7d866c31b3c5 405 EMAC->CTL |= EMAC_CTL_RST_Msk;
AnnaBridge 172:7d866c31b3c5 406 while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
AnnaBridge 172:7d866c31b3c5 407 }
AnnaBridge 172:7d866c31b3c5 408
AnnaBridge 172:7d866c31b3c5 409 /**
AnnaBridge 172:7d866c31b3c5 410 * @brief Set the device MAC address
AnnaBridge 172:7d866c31b3c5 411 * @param[in] pu8MacAddr Pointer to uint8_t array holds MAC address
AnnaBridge 172:7d866c31b3c5 412 * @return None
AnnaBridge 172:7d866c31b3c5 413 */
AnnaBridge 172:7d866c31b3c5 414 void EMAC_SetMacAddr(uint8_t *pu8MacAddr)
AnnaBridge 172:7d866c31b3c5 415 {
AnnaBridge 172:7d866c31b3c5 416 EMAC_EnableCamEntry(0UL, pu8MacAddr);
AnnaBridge 172:7d866c31b3c5 417
AnnaBridge 172:7d866c31b3c5 418 }
AnnaBridge 172:7d866c31b3c5 419
AnnaBridge 172:7d866c31b3c5 420 /**
AnnaBridge 172:7d866c31b3c5 421 * @brief Fill a CAM entry for MAC address comparison.
AnnaBridge 172:7d866c31b3c5 422 * @param[in] u32Entry MAC entry to fill. Entry 0 is used to store device MAC address, do not overwrite the setting in it.
AnnaBridge 172:7d866c31b3c5 423 * @param[in] pu8MacAddr Pointer to uint8_t array holds MAC address
AnnaBridge 172:7d866c31b3c5 424 * @return None
AnnaBridge 172:7d866c31b3c5 425 */
AnnaBridge 172:7d866c31b3c5 426 void EMAC_EnableCamEntry(uint32_t u32Entry, uint8_t pu8MacAddr[])
AnnaBridge 172:7d866c31b3c5 427 {
AnnaBridge 172:7d866c31b3c5 428 uint32_t u32Lsw, u32Msw;
AnnaBridge 172:7d866c31b3c5 429 uint32_t reg;
AnnaBridge 172:7d866c31b3c5 430 u32Lsw = (uint32_t)(((uint32_t)pu8MacAddr[4] << 24) |
AnnaBridge 172:7d866c31b3c5 431 ((uint32_t)pu8MacAddr[5] << 16));
AnnaBridge 172:7d866c31b3c5 432 u32Msw = (uint32_t)(((uint32_t)pu8MacAddr[0] << 24)|
AnnaBridge 172:7d866c31b3c5 433 ((uint32_t)pu8MacAddr[1] << 16)|
AnnaBridge 172:7d866c31b3c5 434 ((uint32_t)pu8MacAddr[2] << 8)|
AnnaBridge 172:7d866c31b3c5 435 (uint32_t)pu8MacAddr[3]);
AnnaBridge 172:7d866c31b3c5 436
AnnaBridge 172:7d866c31b3c5 437 reg = (uint32_t)&EMAC->CAM0M + u32Entry * 2UL * 4UL;
AnnaBridge 172:7d866c31b3c5 438 *(uint32_t volatile *)reg = u32Msw;
AnnaBridge 172:7d866c31b3c5 439 reg = (uint32_t)&EMAC->CAM0L + u32Entry * 2UL * 4UL;
AnnaBridge 172:7d866c31b3c5 440 *(uint32_t volatile *)reg = u32Lsw;
AnnaBridge 172:7d866c31b3c5 441
AnnaBridge 172:7d866c31b3c5 442 EMAC->CAMEN |= (1UL << u32Entry);
AnnaBridge 172:7d866c31b3c5 443 }
AnnaBridge 172:7d866c31b3c5 444
AnnaBridge 172:7d866c31b3c5 445 /**
AnnaBridge 172:7d866c31b3c5 446 * @brief Disable a specified CAM entry
AnnaBridge 172:7d866c31b3c5 447 * @param[in] u32Entry CAM entry to be disabled
AnnaBridge 172:7d866c31b3c5 448 * @return None
AnnaBridge 172:7d866c31b3c5 449 */
AnnaBridge 172:7d866c31b3c5 450 void EMAC_DisableCamEntry(uint32_t u32Entry)
AnnaBridge 172:7d866c31b3c5 451 {
AnnaBridge 172:7d866c31b3c5 452 EMAC->CAMEN &= ~(1UL << u32Entry);
AnnaBridge 172:7d866c31b3c5 453 }
AnnaBridge 172:7d866c31b3c5 454
AnnaBridge 172:7d866c31b3c5 455
AnnaBridge 172:7d866c31b3c5 456 /**
AnnaBridge 172:7d866c31b3c5 457 * @brief Receive an Ethernet packet
AnnaBridge 172:7d866c31b3c5 458 * @param[in] pu8Data Pointer to a buffer to store received packet (4 byte CRC removed)
AnnaBridge 172:7d866c31b3c5 459 * @param[in] pu32Size Received packet size (without 4 byte CRC).
AnnaBridge 172:7d866c31b3c5 460 * @return Packet receive success or not
AnnaBridge 172:7d866c31b3c5 461 * @retval 0 No packet available for receive
AnnaBridge 172:7d866c31b3c5 462 * @retval 1 A packet is received
AnnaBridge 172:7d866c31b3c5 463 * @note Return 0 doesn't guarantee the packet will be sent and received successfully.
AnnaBridge 172:7d866c31b3c5 464 */
AnnaBridge 172:7d866c31b3c5 465 uint32_t EMAC_RecvPkt(uint8_t *pu8Data, uint32_t *pu32Size)
AnnaBridge 172:7d866c31b3c5 466 {
AnnaBridge 172:7d866c31b3c5 467 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 468 uint32_t status, reg;
AnnaBridge 172:7d866c31b3c5 469 uint32_t u32Count = 0UL;
AnnaBridge 172:7d866c31b3c5 470
AnnaBridge 172:7d866c31b3c5 471 /* Clear Rx interrupt flags */
AnnaBridge 172:7d866c31b3c5 472 reg = EMAC->INTSTS;
AnnaBridge 172:7d866c31b3c5 473 EMAC->INTSTS = reg & 0xFFFFUL; /* Clear all RX related interrupt status */
AnnaBridge 172:7d866c31b3c5 474
AnnaBridge 172:7d866c31b3c5 475 if (reg & EMAC_INTSTS_RXBEIF_Msk) {
AnnaBridge 172:7d866c31b3c5 476 /* Bus error occurred, this is usually a bad sign about software bug and will occur again... */
AnnaBridge 172:7d866c31b3c5 477 while(1) {}
AnnaBridge 172:7d866c31b3c5 478 } else {
AnnaBridge 172:7d866c31b3c5 479
AnnaBridge 172:7d866c31b3c5 480 /* Get Rx Frame Descriptor */
AnnaBridge 172:7d866c31b3c5 481 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
AnnaBridge 172:7d866c31b3c5 482
AnnaBridge 172:7d866c31b3c5 483 /* If we reach last recv Rx descriptor, leave the loop */
AnnaBridge 172:7d866c31b3c5 484 if ((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC) { /* ownership=CPU */
AnnaBridge 172:7d866c31b3c5 485
AnnaBridge 172:7d866c31b3c5 486 status = desc->u32Status1 >> 16;
AnnaBridge 172:7d866c31b3c5 487
AnnaBridge 172:7d866c31b3c5 488 /* If Rx frame is good, process received frame */
AnnaBridge 172:7d866c31b3c5 489 if(status & EMAC_RXFD_RXGD) {
AnnaBridge 172:7d866c31b3c5 490 /* lower 16 bit in descriptor status1 stores the Rx packet length */
AnnaBridge 172:7d866c31b3c5 491 *pu32Size = desc->u32Status1 & 0xFFFFUL;
AnnaBridge 172:7d866c31b3c5 492 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
AnnaBridge 172:7d866c31b3c5 493 u32Count = 1UL;
AnnaBridge 172:7d866c31b3c5 494 } else {
AnnaBridge 172:7d866c31b3c5 495 /* Save Error status if necessary */
AnnaBridge 172:7d866c31b3c5 496 if (status & EMAC_RXFD_RP) {}
AnnaBridge 172:7d866c31b3c5 497 if (status & EMAC_RXFD_ALIE) {}
AnnaBridge 172:7d866c31b3c5 498 if (status & EMAC_RXFD_PTLE) {}
AnnaBridge 172:7d866c31b3c5 499 if (status & EMAC_RXFD_CRCE) {}
AnnaBridge 172:7d866c31b3c5 500 }
AnnaBridge 172:7d866c31b3c5 501 }
AnnaBridge 172:7d866c31b3c5 502 }
AnnaBridge 172:7d866c31b3c5 503 return(u32Count);
AnnaBridge 172:7d866c31b3c5 504 }
AnnaBridge 172:7d866c31b3c5 505
AnnaBridge 172:7d866c31b3c5 506 /**
AnnaBridge 172:7d866c31b3c5 507 * @brief Receive an Ethernet packet and the time stamp while it's received
AnnaBridge 172:7d866c31b3c5 508 * @param[out] pu8Data Pointer to a buffer to store received packet (4 byte CRC removed)
AnnaBridge 172:7d866c31b3c5 509 * @param[out] pu32Size Received packet size (without 4 byte CRC).
AnnaBridge 172:7d866c31b3c5 510 * @param[out] pu32Sec Second value while packet sent
AnnaBridge 172:7d866c31b3c5 511 * @param[out] pu32Nsec Nano second value while packet sent
AnnaBridge 172:7d866c31b3c5 512 * @return Packet receive success or not
AnnaBridge 172:7d866c31b3c5 513 * @retval 0 No packet available for receive
AnnaBridge 172:7d866c31b3c5 514 * @retval 1 A packet is received
AnnaBridge 172:7d866c31b3c5 515 * @note Return 0 doesn't guarantee the packet will be sent and received successfully.
AnnaBridge 172:7d866c31b3c5 516 * @note Largest Ethernet packet is 1514 bytes after stripped CRC, application must give
AnnaBridge 172:7d866c31b3c5 517 * a buffer large enough to store such packet
AnnaBridge 172:7d866c31b3c5 518 */
AnnaBridge 172:7d866c31b3c5 519 uint32_t EMAC_RecvPktTS(uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec)
AnnaBridge 172:7d866c31b3c5 520 {
AnnaBridge 172:7d866c31b3c5 521 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 522 uint32_t status, reg;
AnnaBridge 172:7d866c31b3c5 523 uint32_t u32Count = 0UL;
AnnaBridge 172:7d866c31b3c5 524
AnnaBridge 172:7d866c31b3c5 525 /* Clear Rx interrupt flags */
AnnaBridge 172:7d866c31b3c5 526 reg = EMAC->INTSTS;
AnnaBridge 172:7d866c31b3c5 527 EMAC->INTSTS = reg & 0xFFFFUL; /* Clear all Rx related interrupt status */
AnnaBridge 172:7d866c31b3c5 528
AnnaBridge 172:7d866c31b3c5 529 if (reg & EMAC_INTSTS_RXBEIF_Msk) {
AnnaBridge 172:7d866c31b3c5 530 /* Bus error occurred, this is usually a bad sign about software bug and will occur again... */
AnnaBridge 172:7d866c31b3c5 531 while(1) {}
AnnaBridge 172:7d866c31b3c5 532 } else {
AnnaBridge 172:7d866c31b3c5 533
AnnaBridge 172:7d866c31b3c5 534 /* Get Rx Frame Descriptor */
AnnaBridge 172:7d866c31b3c5 535 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
AnnaBridge 172:7d866c31b3c5 536
AnnaBridge 172:7d866c31b3c5 537 /* If we reach last recv Rx descriptor, leave the loop */
AnnaBridge 172:7d866c31b3c5 538 if(EMAC->CRXDSA != (uint32_t)desc) {
AnnaBridge 172:7d866c31b3c5 539 if ((desc->u32Status1 | EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC) { /* ownership=CPU */
AnnaBridge 172:7d866c31b3c5 540
AnnaBridge 172:7d866c31b3c5 541 status = desc->u32Status1 >> 16;
AnnaBridge 172:7d866c31b3c5 542
AnnaBridge 172:7d866c31b3c5 543 /* If Rx frame is good, process received frame */
AnnaBridge 172:7d866c31b3c5 544 if(status & EMAC_RXFD_RXGD) {
AnnaBridge 172:7d866c31b3c5 545 /* lower 16 bit in descriptor status1 stores the Rx packet length */
AnnaBridge 172:7d866c31b3c5 546 *pu32Size = desc->u32Status1 & 0xFFFFUL;
AnnaBridge 172:7d866c31b3c5 547 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
AnnaBridge 172:7d866c31b3c5 548
AnnaBridge 172:7d866c31b3c5 549 *pu32Sec = desc->u32Next; /* second stores in descriptor's NEXT field */
AnnaBridge 172:7d866c31b3c5 550 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data); /* Sub nano second store in DATA field */
AnnaBridge 172:7d866c31b3c5 551
AnnaBridge 172:7d866c31b3c5 552 u32Count = 1UL;
AnnaBridge 172:7d866c31b3c5 553 } else {
AnnaBridge 172:7d866c31b3c5 554 /* Save Error status if necessary */
AnnaBridge 172:7d866c31b3c5 555 if (status & EMAC_RXFD_RP) {}
AnnaBridge 172:7d866c31b3c5 556 if (status & EMAC_RXFD_ALIE) {}
AnnaBridge 172:7d866c31b3c5 557 if (status & EMAC_RXFD_PTLE) {}
AnnaBridge 172:7d866c31b3c5 558 if (status & EMAC_RXFD_CRCE) {}
AnnaBridge 172:7d866c31b3c5 559 }
AnnaBridge 172:7d866c31b3c5 560 }
AnnaBridge 172:7d866c31b3c5 561 }
AnnaBridge 172:7d866c31b3c5 562 }
AnnaBridge 172:7d866c31b3c5 563 return(u32Count);
AnnaBridge 172:7d866c31b3c5 564 }
AnnaBridge 172:7d866c31b3c5 565
AnnaBridge 172:7d866c31b3c5 566 /**
AnnaBridge 172:7d866c31b3c5 567 * @brief Clean up process after a packet is received
AnnaBridge 172:7d866c31b3c5 568 * @param None
AnnaBridge 172:7d866c31b3c5 569 * @return None
AnnaBridge 172:7d866c31b3c5 570 * @details EMAC Rx interrupt service routine \b must call this API to release the resource use by receive process
AnnaBridge 172:7d866c31b3c5 571 * @note Application can only call this function once every time \ref EMAC_RecvPkt or \ref EMAC_RecvPktTS returns 1
AnnaBridge 172:7d866c31b3c5 572 */
AnnaBridge 172:7d866c31b3c5 573 void EMAC_RecvPktDone(void)
AnnaBridge 172:7d866c31b3c5 574 {
AnnaBridge 172:7d866c31b3c5 575 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 576 /* Get Rx Frame Descriptor */
AnnaBridge 172:7d866c31b3c5 577 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
AnnaBridge 172:7d866c31b3c5 578
AnnaBridge 172:7d866c31b3c5 579 /* Restore descriptor link list and data pointer they will be overwrite if time stamp enabled */
AnnaBridge 172:7d866c31b3c5 580 desc->u32Data = desc->u32Backup1;
AnnaBridge 172:7d866c31b3c5 581 desc->u32Next = desc->u32Backup2;
AnnaBridge 172:7d866c31b3c5 582
AnnaBridge 172:7d866c31b3c5 583 /* Get Next Frame Descriptor pointer to process */
AnnaBridge 172:7d866c31b3c5 584 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
AnnaBridge 172:7d866c31b3c5 585
AnnaBridge 172:7d866c31b3c5 586 /* Save last processed Rx descriptor */
AnnaBridge 172:7d866c31b3c5 587 u32CurrentRxDesc = (uint32_t)desc;
AnnaBridge 172:7d866c31b3c5 588
AnnaBridge 172:7d866c31b3c5 589 /* Change ownership to DMA for next use */
AnnaBridge 172:7d866c31b3c5 590 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
AnnaBridge 172:7d866c31b3c5 591
AnnaBridge 172:7d866c31b3c5 592 EMAC_TRIGGER_RX();
AnnaBridge 172:7d866c31b3c5 593 }
AnnaBridge 172:7d866c31b3c5 594
AnnaBridge 172:7d866c31b3c5 595
AnnaBridge 172:7d866c31b3c5 596 /**
AnnaBridge 172:7d866c31b3c5 597 * @brief Send an Ethernet packet
AnnaBridge 172:7d866c31b3c5 598 * @param[in] pu8Data Pointer to a buffer holds the packet to transmit
AnnaBridge 172:7d866c31b3c5 599 * @param[in] u32Size Packet size (without 4 byte CRC).
AnnaBridge 172:7d866c31b3c5 600 * @return Packet transmit success or not
AnnaBridge 172:7d866c31b3c5 601 * @retval 0 Transmit failed due to descriptor unavailable.
AnnaBridge 172:7d866c31b3c5 602 * @retval 1 Packet is copied to descriptor and triggered to transmit.
AnnaBridge 172:7d866c31b3c5 603 * @note Return 1 doesn't guarantee the packet will be sent and received successfully.
AnnaBridge 172:7d866c31b3c5 604 */
AnnaBridge 172:7d866c31b3c5 605 uint32_t EMAC_SendPkt(uint8_t *pu8Data, uint32_t u32Size)
AnnaBridge 172:7d866c31b3c5 606 {
AnnaBridge 172:7d866c31b3c5 607 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 608 uint32_t status;
AnnaBridge 172:7d866c31b3c5 609 uint32_t ret = 0UL;
AnnaBridge 172:7d866c31b3c5 610 /* Get Tx frame descriptor & data pointer */
AnnaBridge 172:7d866c31b3c5 611 desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
AnnaBridge 172:7d866c31b3c5 612
AnnaBridge 172:7d866c31b3c5 613 status = desc->u32Status1;
AnnaBridge 172:7d866c31b3c5 614
AnnaBridge 172:7d866c31b3c5 615 /* Check descriptor ownership */
AnnaBridge 172:7d866c31b3c5 616 if((status & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC) {
AnnaBridge 172:7d866c31b3c5 617 memcpy((uint8_t *)desc->u32Data, pu8Data, u32Size);
AnnaBridge 172:7d866c31b3c5 618
AnnaBridge 172:7d866c31b3c5 619 /* Set Tx descriptor transmit byte count */
AnnaBridge 172:7d866c31b3c5 620 desc->u32Status2 = u32Size;
AnnaBridge 172:7d866c31b3c5 621
AnnaBridge 172:7d866c31b3c5 622 /* Change descriptor ownership to EMAC */
AnnaBridge 172:7d866c31b3c5 623 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
AnnaBridge 172:7d866c31b3c5 624
AnnaBridge 172:7d866c31b3c5 625 /* Get next Tx descriptor */
AnnaBridge 172:7d866c31b3c5 626 u32NextTxDesc = (uint32_t)(desc->u32Next);
AnnaBridge 172:7d866c31b3c5 627
AnnaBridge 172:7d866c31b3c5 628 /* Trigger EMAC to send the packet */
AnnaBridge 172:7d866c31b3c5 629 EMAC_TRIGGER_TX();
AnnaBridge 172:7d866c31b3c5 630 ret = 1UL;
AnnaBridge 172:7d866c31b3c5 631 }
AnnaBridge 172:7d866c31b3c5 632 return(ret);
AnnaBridge 172:7d866c31b3c5 633 }
AnnaBridge 172:7d866c31b3c5 634
AnnaBridge 172:7d866c31b3c5 635
AnnaBridge 172:7d866c31b3c5 636 /**
AnnaBridge 172:7d866c31b3c5 637 * @brief Clean up process after packet(s) are sent
AnnaBridge 172:7d866c31b3c5 638 * @param None
AnnaBridge 172:7d866c31b3c5 639 * @return Number of packet sent between two function calls
AnnaBridge 172:7d866c31b3c5 640 * @details EMAC Tx interrupt service routine \b must call this API or \ref EMAC_SendPktDoneTS to
AnnaBridge 172:7d866c31b3c5 641 * release the resource use by transmit process
AnnaBridge 172:7d866c31b3c5 642 */
AnnaBridge 172:7d866c31b3c5 643 uint32_t EMAC_SendPktDone(void)
AnnaBridge 172:7d866c31b3c5 644 {
AnnaBridge 172:7d866c31b3c5 645 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 646 uint32_t status, reg;
AnnaBridge 172:7d866c31b3c5 647 uint32_t last_tx_desc;
AnnaBridge 172:7d866c31b3c5 648 uint32_t u32Count = 0UL;
AnnaBridge 172:7d866c31b3c5 649
AnnaBridge 172:7d866c31b3c5 650 reg = EMAC->INTSTS;
AnnaBridge 172:7d866c31b3c5 651 /* Clear Tx interrupt flags */
AnnaBridge 172:7d866c31b3c5 652 EMAC->INTSTS = reg & (0xFFFF0000UL & ~EMAC_INTSTS_TSALMIF_Msk);
AnnaBridge 172:7d866c31b3c5 653
AnnaBridge 172:7d866c31b3c5 654
AnnaBridge 172:7d866c31b3c5 655 if (reg & EMAC_INTSTS_TXBEIF_Msk) {
AnnaBridge 172:7d866c31b3c5 656 /* Bus error occurred, this is usually a bad sign about software bug and will occur again... */
AnnaBridge 172:7d866c31b3c5 657 while(1) {}
AnnaBridge 172:7d866c31b3c5 658 } else {
AnnaBridge 172:7d866c31b3c5 659 /* Process the descriptor(s). */
AnnaBridge 172:7d866c31b3c5 660 last_tx_desc = EMAC->CTXDSA ;
AnnaBridge 172:7d866c31b3c5 661 /* Get our first descriptor to process */
AnnaBridge 172:7d866c31b3c5 662 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
AnnaBridge 172:7d866c31b3c5 663 do {
AnnaBridge 172:7d866c31b3c5 664 /* Descriptor ownership is still EMAC, so this packet haven't been send. */
AnnaBridge 172:7d866c31b3c5 665 if(desc->u32Status1 & EMAC_DESC_OWN_EMAC) {
AnnaBridge 172:7d866c31b3c5 666 break;
AnnaBridge 172:7d866c31b3c5 667 }
AnnaBridge 172:7d866c31b3c5 668 /* Get Tx status stored in descriptor */
AnnaBridge 172:7d866c31b3c5 669 status = desc->u32Status2 >> 16UL;
AnnaBridge 172:7d866c31b3c5 670 if (status & EMAC_TXFD_TXCP) {
AnnaBridge 172:7d866c31b3c5 671 u32Count++;
AnnaBridge 172:7d866c31b3c5 672 } else {
AnnaBridge 172:7d866c31b3c5 673 /* Do nothing here on error. */
AnnaBridge 172:7d866c31b3c5 674 if (status & EMAC_TXFD_TXABT) {}
AnnaBridge 172:7d866c31b3c5 675 if (status & EMAC_TXFD_DEF) {}
AnnaBridge 172:7d866c31b3c5 676 if (status & EMAC_TXFD_PAU) {}
AnnaBridge 172:7d866c31b3c5 677 if (status & EMAC_TXFD_EXDEF) {}
AnnaBridge 172:7d866c31b3c5 678 if (status & EMAC_TXFD_NCS) {}
AnnaBridge 172:7d866c31b3c5 679 if (status & EMAC_TXFD_SQE) {}
AnnaBridge 172:7d866c31b3c5 680 if (status & EMAC_TXFD_LC) {}
AnnaBridge 172:7d866c31b3c5 681 if (status & EMAC_TXFD_TXHA) {}
AnnaBridge 172:7d866c31b3c5 682 }
AnnaBridge 172:7d866c31b3c5 683
AnnaBridge 172:7d866c31b3c5 684 /* restore descriptor link list and data pointer they will be overwrite if time stamp enabled */
AnnaBridge 172:7d866c31b3c5 685 desc->u32Data = desc->u32Backup1;
AnnaBridge 172:7d866c31b3c5 686 desc->u32Next = desc->u32Backup2;
AnnaBridge 172:7d866c31b3c5 687 /* go to next descriptor in link */
AnnaBridge 172:7d866c31b3c5 688 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
AnnaBridge 172:7d866c31b3c5 689 } while (last_tx_desc != (uint32_t)desc); /* If we reach last sent Tx descriptor, leave the loop */
AnnaBridge 172:7d866c31b3c5 690 /* Save last processed Tx descriptor */
AnnaBridge 172:7d866c31b3c5 691 u32CurrentTxDesc = (uint32_t)desc;
AnnaBridge 172:7d866c31b3c5 692 }
AnnaBridge 172:7d866c31b3c5 693 return(u32Count);
AnnaBridge 172:7d866c31b3c5 694 }
AnnaBridge 172:7d866c31b3c5 695
AnnaBridge 172:7d866c31b3c5 696 /**
AnnaBridge 172:7d866c31b3c5 697 * @brief Clean up process after a packet is sent, and get the time stamp while packet is sent
AnnaBridge 172:7d866c31b3c5 698 * @param[in] pu32Sec Second value while packet sent
AnnaBridge 172:7d866c31b3c5 699 * @param[in] pu32Nsec Nano second value while packet sent
AnnaBridge 172:7d866c31b3c5 700 * @return If a packet sent successfully
AnnaBridge 172:7d866c31b3c5 701 * @retval 0 No packet sent successfully, and the value in *pu32Sec and *pu32Nsec are meaningless
AnnaBridge 172:7d866c31b3c5 702 * @retval 1 A packet sent successfully, and the value in *pu32Sec and *pu32Nsec is the time stamp while packet sent
AnnaBridge 172:7d866c31b3c5 703 * @details EMAC Tx interrupt service routine \b must call this API or \ref EMAC_SendPktDone to
AnnaBridge 172:7d866c31b3c5 704 * release the resource use by transmit process
AnnaBridge 172:7d866c31b3c5 705 */
AnnaBridge 172:7d866c31b3c5 706 uint32_t EMAC_SendPktDoneTS(uint32_t *pu32Sec, uint32_t *pu32Nsec)
AnnaBridge 172:7d866c31b3c5 707 {
AnnaBridge 172:7d866c31b3c5 708
AnnaBridge 172:7d866c31b3c5 709 EMAC_DESCRIPTOR_T *desc;
AnnaBridge 172:7d866c31b3c5 710 uint32_t status, reg;
AnnaBridge 172:7d866c31b3c5 711 uint32_t u32Count = 0UL;
AnnaBridge 172:7d866c31b3c5 712
AnnaBridge 172:7d866c31b3c5 713 reg = EMAC->INTSTS;
AnnaBridge 172:7d866c31b3c5 714 /* Clear Tx interrupt flags */
AnnaBridge 172:7d866c31b3c5 715 EMAC->INTSTS = reg & (0xFFFF0000UL & ~EMAC_INTSTS_TSALMIF_Msk);
AnnaBridge 172:7d866c31b3c5 716
AnnaBridge 172:7d866c31b3c5 717
AnnaBridge 172:7d866c31b3c5 718 if (reg & EMAC_INTSTS_TXBEIF_Msk) {
AnnaBridge 172:7d866c31b3c5 719 /* Bus error occurred, this is usually a bad sign about software bug and will occur again... */
AnnaBridge 172:7d866c31b3c5 720 while(1) {}
AnnaBridge 172:7d866c31b3c5 721 } else {
AnnaBridge 172:7d866c31b3c5 722 /* Process the descriptor.
AnnaBridge 172:7d866c31b3c5 723 Get our first descriptor to process */
AnnaBridge 172:7d866c31b3c5 724 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
AnnaBridge 172:7d866c31b3c5 725
AnnaBridge 172:7d866c31b3c5 726 /* Descriptor ownership is still EMAC, so this packet haven't been send. */
AnnaBridge 172:7d866c31b3c5 727 if((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC) {
AnnaBridge 172:7d866c31b3c5 728 /* Get Tx status stored in descriptor */
AnnaBridge 172:7d866c31b3c5 729 status = desc->u32Status2 >> 16UL;
AnnaBridge 172:7d866c31b3c5 730 if (status & EMAC_TXFD_TXCP) {
AnnaBridge 172:7d866c31b3c5 731 u32Count = 1UL;
AnnaBridge 172:7d866c31b3c5 732 *pu32Sec = desc->u32Next; /* second stores in descriptor's NEXT field */
AnnaBridge 172:7d866c31b3c5 733 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data); /* Sub nano second store in DATA field */
AnnaBridge 172:7d866c31b3c5 734 } else {
AnnaBridge 172:7d866c31b3c5 735 /* Do nothing here on error. */
AnnaBridge 172:7d866c31b3c5 736 if (status & EMAC_TXFD_TXABT) {}
AnnaBridge 172:7d866c31b3c5 737 if (status & EMAC_TXFD_DEF) {}
AnnaBridge 172:7d866c31b3c5 738 if (status & EMAC_TXFD_PAU) {}
AnnaBridge 172:7d866c31b3c5 739 if (status & EMAC_TXFD_EXDEF) {}
AnnaBridge 172:7d866c31b3c5 740 if (status & EMAC_TXFD_NCS) {}
AnnaBridge 172:7d866c31b3c5 741 if (status & EMAC_TXFD_SQE) {}
AnnaBridge 172:7d866c31b3c5 742 if (status & EMAC_TXFD_LC) {}
AnnaBridge 172:7d866c31b3c5 743 if (status & EMAC_TXFD_TXHA) {}
AnnaBridge 172:7d866c31b3c5 744 }
AnnaBridge 172:7d866c31b3c5 745
AnnaBridge 172:7d866c31b3c5 746 /* restore descriptor link list and data pointer they will be overwrite if time stamp enabled */
AnnaBridge 172:7d866c31b3c5 747 desc->u32Data = desc->u32Backup1;
AnnaBridge 172:7d866c31b3c5 748 desc->u32Next = desc->u32Backup2;
AnnaBridge 172:7d866c31b3c5 749 /* go to next descriptor in link */
AnnaBridge 172:7d866c31b3c5 750 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
AnnaBridge 172:7d866c31b3c5 751
AnnaBridge 172:7d866c31b3c5 752 /* Save last processed Tx descriptor */
AnnaBridge 172:7d866c31b3c5 753 u32CurrentTxDesc = (uint32_t)desc;
AnnaBridge 172:7d866c31b3c5 754 }
AnnaBridge 172:7d866c31b3c5 755 }
AnnaBridge 172:7d866c31b3c5 756
AnnaBridge 172:7d866c31b3c5 757 return(u32Count);
AnnaBridge 172:7d866c31b3c5 758 }
AnnaBridge 172:7d866c31b3c5 759
AnnaBridge 172:7d866c31b3c5 760 /**
AnnaBridge 172:7d866c31b3c5 761 * @brief Enable IEEE1588 time stamp function and set current time
AnnaBridge 172:7d866c31b3c5 762 * @param[in] u32Sec Second value
AnnaBridge 172:7d866c31b3c5 763 * @param[in] u32Nsec Nano second value
AnnaBridge 172:7d866c31b3c5 764 * @return None
AnnaBridge 172:7d866c31b3c5 765 */
AnnaBridge 172:7d866c31b3c5 766 void EMAC_EnableTS(uint32_t u32Sec, uint32_t u32Nsec)
AnnaBridge 172:7d866c31b3c5 767 {
AnnaBridge 172:7d866c31b3c5 768 double f;
AnnaBridge 172:7d866c31b3c5 769 uint32_t reg;
AnnaBridge 172:7d866c31b3c5 770 EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;
AnnaBridge 172:7d866c31b3c5 771 EMAC->UPDSEC = u32Sec; /* Assume current time is 0 sec + 0 nano sec */
AnnaBridge 172:7d866c31b3c5 772 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
AnnaBridge 172:7d866c31b3c5 773
AnnaBridge 172:7d866c31b3c5 774 /* PTP source clock is 160MHz (Real chip using PLL). Each tick is 6.25ns
AnnaBridge 172:7d866c31b3c5 775 Assume we want to set each tick to 100ns.
AnnaBridge 172:7d866c31b3c5 776 Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
AnnaBridge 172:7d866c31b3c5 777 Addend register = 2^32 * tick_freq / (160MHz), where tick_freq = (2^31 / 215) MHz
AnnaBridge 172:7d866c31b3c5 778 From above equation, addend register = 2^63 / (160M * 215) ~= 268121280 = 0xFFB34C0
AnnaBridge 172:7d866c31b3c5 779 So:
AnnaBridge 172:7d866c31b3c5 780 EMAC->TSIR = 0xD7;
AnnaBridge 172:7d866c31b3c5 781 EMAC->TSAR = 0x1E70C600; */
AnnaBridge 172:7d866c31b3c5 782 f = (100.0 * 2147483648.0) / (1000000000.0) + 0.5;
AnnaBridge 172:7d866c31b3c5 783 EMAC->TSINC = (reg = (uint32_t)f);
AnnaBridge 172:7d866c31b3c5 784 f = (double)9223372036854775808.0 / ((double)(CLK_GetHCLKFreq()) * (double)reg);
AnnaBridge 172:7d866c31b3c5 785 EMAC->TSADDEND = (uint32_t)f;
AnnaBridge 172:7d866c31b3c5 786 EMAC->TSCTL |= (EMAC_TSCTL_TSUPDATE_Msk | EMAC_TSCTL_TSIEN_Msk | EMAC_TSCTL_TSMODE_Msk); /* Fine update */
AnnaBridge 172:7d866c31b3c5 787 }
AnnaBridge 172:7d866c31b3c5 788
AnnaBridge 172:7d866c31b3c5 789 /**
AnnaBridge 172:7d866c31b3c5 790 * @brief Disable IEEE1588 time stamp function
AnnaBridge 172:7d866c31b3c5 791 * @param None
AnnaBridge 172:7d866c31b3c5 792 * @return None
AnnaBridge 172:7d866c31b3c5 793 */
AnnaBridge 172:7d866c31b3c5 794 void EMAC_DisableTS(void)
AnnaBridge 172:7d866c31b3c5 795 {
AnnaBridge 172:7d866c31b3c5 796 EMAC->TSCTL = 0UL;
AnnaBridge 172:7d866c31b3c5 797 }
AnnaBridge 172:7d866c31b3c5 798
AnnaBridge 172:7d866c31b3c5 799 /**
AnnaBridge 172:7d866c31b3c5 800 * @brief Get current time stamp
AnnaBridge 172:7d866c31b3c5 801 * @param[out] pu32Sec Current second value
AnnaBridge 172:7d866c31b3c5 802 * @param[out] pu32Nsec Current nano second value
AnnaBridge 172:7d866c31b3c5 803 * @return None
AnnaBridge 172:7d866c31b3c5 804 */
AnnaBridge 172:7d866c31b3c5 805 void EMAC_GetTime(uint32_t *pu32Sec, uint32_t *pu32Nsec)
AnnaBridge 172:7d866c31b3c5 806 {
AnnaBridge 172:7d866c31b3c5 807 /* Must read TSLSR firstly. Hardware will preserve TSMSR value at the time TSLSR read. */
AnnaBridge 172:7d866c31b3c5 808 *pu32Nsec = EMAC_Subsec2Nsec(EMAC->TSSUBSEC);
AnnaBridge 172:7d866c31b3c5 809 *pu32Sec = EMAC->TSSEC;
AnnaBridge 172:7d866c31b3c5 810 }
AnnaBridge 172:7d866c31b3c5 811
AnnaBridge 172:7d866c31b3c5 812 /**
AnnaBridge 172:7d866c31b3c5 813 * @brief Set current time stamp
AnnaBridge 172:7d866c31b3c5 814 * @param[in] u32Sec Second value
AnnaBridge 172:7d866c31b3c5 815 * @param[in] u32Nsec Nano second value
AnnaBridge 172:7d866c31b3c5 816 * @return None
AnnaBridge 172:7d866c31b3c5 817 */
AnnaBridge 172:7d866c31b3c5 818 void EMAC_SetTime(uint32_t u32Sec, uint32_t u32Nsec)
AnnaBridge 172:7d866c31b3c5 819 {
AnnaBridge 172:7d866c31b3c5 820 /* Disable time stamp counter before update time value (clear EMAC_TSCTL_TSIEN_Msk) */
AnnaBridge 172:7d866c31b3c5 821 EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;
AnnaBridge 172:7d866c31b3c5 822 EMAC->UPDSEC = u32Sec;
AnnaBridge 172:7d866c31b3c5 823 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
AnnaBridge 172:7d866c31b3c5 824 EMAC->TSCTL |= (EMAC_TSCTL_TSIEN_Msk | EMAC_TSCTL_TSMODE_Msk);
AnnaBridge 172:7d866c31b3c5 825
AnnaBridge 172:7d866c31b3c5 826 }
AnnaBridge 172:7d866c31b3c5 827
AnnaBridge 172:7d866c31b3c5 828 /**
AnnaBridge 172:7d866c31b3c5 829 * @brief Enable alarm function and set alarm time
AnnaBridge 172:7d866c31b3c5 830 * @param[in] u32Sec Second value to trigger alarm
AnnaBridge 172:7d866c31b3c5 831 * @param[in] u32Nsec Nano second value to trigger alarm
AnnaBridge 172:7d866c31b3c5 832 * @return None
AnnaBridge 172:7d866c31b3c5 833 */
AnnaBridge 172:7d866c31b3c5 834 void EMAC_EnableAlarm(uint32_t u32Sec, uint32_t u32Nsec)
AnnaBridge 172:7d866c31b3c5 835 {
AnnaBridge 172:7d866c31b3c5 836
AnnaBridge 172:7d866c31b3c5 837 EMAC->ALMSEC = u32Sec;
AnnaBridge 172:7d866c31b3c5 838 EMAC->ALMSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
AnnaBridge 172:7d866c31b3c5 839 EMAC->TSCTL |= EMAC_TSCTL_TSALMEN_Msk;
AnnaBridge 172:7d866c31b3c5 840
AnnaBridge 172:7d866c31b3c5 841 }
AnnaBridge 172:7d866c31b3c5 842
AnnaBridge 172:7d866c31b3c5 843 /**
AnnaBridge 172:7d866c31b3c5 844 * @brief Disable alarm function
AnnaBridge 172:7d866c31b3c5 845 * @param None
AnnaBridge 172:7d866c31b3c5 846 * @return None
AnnaBridge 172:7d866c31b3c5 847 */
AnnaBridge 172:7d866c31b3c5 848 void EMAC_DisableAlarm(void)
AnnaBridge 172:7d866c31b3c5 849 {
AnnaBridge 172:7d866c31b3c5 850
AnnaBridge 172:7d866c31b3c5 851 EMAC->TSCTL &= ~EMAC_TSCTL_TSALMEN_Msk;
AnnaBridge 172:7d866c31b3c5 852
AnnaBridge 172:7d866c31b3c5 853 }
AnnaBridge 172:7d866c31b3c5 854
AnnaBridge 172:7d866c31b3c5 855 /**
AnnaBridge 172:7d866c31b3c5 856 * @brief Add a offset to current time
AnnaBridge 172:7d866c31b3c5 857 * @param[in] u32Neg Offset is negative value (u32Neg == 1) or positive value (u32Neg == 0).
AnnaBridge 172:7d866c31b3c5 858 * @param[in] u32Sec Second value to add to current time
AnnaBridge 172:7d866c31b3c5 859 * @param[in] u32Nsec Nano second value to add to current time
AnnaBridge 172:7d866c31b3c5 860 * @return None
AnnaBridge 172:7d866c31b3c5 861 */
AnnaBridge 172:7d866c31b3c5 862 void EMAC_UpdateTime(uint32_t u32Neg, uint32_t u32Sec, uint32_t u32Nsec)
AnnaBridge 172:7d866c31b3c5 863 {
AnnaBridge 172:7d866c31b3c5 864 EMAC->UPDSEC = u32Sec;
AnnaBridge 172:7d866c31b3c5 865 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
AnnaBridge 172:7d866c31b3c5 866 if(u32Neg) {
AnnaBridge 172:7d866c31b3c5 867 EMAC->UPDSUBSEC |= BIT31; /* Set bit 31 indicates this is a negative value */
AnnaBridge 172:7d866c31b3c5 868 }
AnnaBridge 172:7d866c31b3c5 869 EMAC->TSCTL |= EMAC_TSCTL_TSUPDATE_Msk;
AnnaBridge 172:7d866c31b3c5 870
AnnaBridge 172:7d866c31b3c5 871 }
AnnaBridge 172:7d866c31b3c5 872
AnnaBridge 172:7d866c31b3c5 873
AnnaBridge 172:7d866c31b3c5 874 /*@}*/ /* end of group M480_EMAC_EXPORTED_FUNCTIONS */
AnnaBridge 172:7d866c31b3c5 875
AnnaBridge 172:7d866c31b3c5 876 /*@}*/ /* end of group M480_EMAC_Driver */
AnnaBridge 172:7d866c31b3c5 877
AnnaBridge 172:7d866c31b3c5 878 /*@}*/ /* end of group M480_Device_Driver */
AnnaBridge 172:7d866c31b3c5 879
AnnaBridge 172:7d866c31b3c5 880 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/