Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

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