added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 144:ef7eb2e8f9f7 12 * list of conditions and the following disclaimer in the documentation and/or
<> 144:ef7eb2e8f9f7 13 * other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 144:ef7eb2e8f9f7 16 * contributors may be used to endorse or promote products derived from this
<> 144:ef7eb2e8f9f7 17 * software without specific prior written permission.
<> 144:ef7eb2e8f9f7 18 *
<> 144:ef7eb2e8f9f7 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 144:ef7eb2e8f9f7 31 #include "fsl_enet.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /*******************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitions
<> 144:ef7eb2e8f9f7 35 ******************************************************************************/
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 /*! @brief IPv4 PTP message IP version offset. */
<> 144:ef7eb2e8f9f7 38 #define ENET_PTP1588_IPVERSION_OFFSET 0x0EU
<> 144:ef7eb2e8f9f7 39 /*! @brief IPv4 PTP message UDP protocol offset. */
<> 144:ef7eb2e8f9f7 40 #define ENET_PTP1588_IPV4_UDP_PROTOCOL_OFFSET 0x17U
<> 144:ef7eb2e8f9f7 41 /*! @brief IPv4 PTP message UDP port offset. */
<> 144:ef7eb2e8f9f7 42 #define ENET_PTP1588_IPV4_UDP_PORT_OFFSET 0x24U
<> 144:ef7eb2e8f9f7 43 /*! @brief IPv4 PTP message UDP message type offset. */
<> 144:ef7eb2e8f9f7 44 #define ENET_PTP1588_IPV4_UDP_MSGTYPE_OFFSET 0x2AU
<> 144:ef7eb2e8f9f7 45 /*! @brief IPv4 PTP message UDP version offset. */
<> 144:ef7eb2e8f9f7 46 #define ENET_PTP1588_IPV4_UDP_VERSION_OFFSET 0x2BU
<> 144:ef7eb2e8f9f7 47 /*! @brief IPv4 PTP message UDP clock id offset. */
<> 144:ef7eb2e8f9f7 48 #define ENET_PTP1588_IPV4_UDP_CLKID_OFFSET 0x3EU
<> 144:ef7eb2e8f9f7 49 /*! @brief IPv4 PTP message UDP sequence id offset. */
<> 144:ef7eb2e8f9f7 50 #define ENET_PTP1588_IPV4_UDP_SEQUENCEID_OFFSET 0x48U
<> 144:ef7eb2e8f9f7 51 /*! @brief IPv4 PTP message UDP control offset. */
<> 144:ef7eb2e8f9f7 52 #define ENET_PTP1588_IPV4_UDP_CTL_OFFSET 0x4AU
<> 144:ef7eb2e8f9f7 53 /*! @brief IPv6 PTP message UDP protocol offset. */
<> 144:ef7eb2e8f9f7 54 #define ENET_PTP1588_IPV6_UDP_PROTOCOL_OFFSET 0x14U
<> 144:ef7eb2e8f9f7 55 /*! @brief IPv6 PTP message UDP port offset. */
<> 144:ef7eb2e8f9f7 56 #define ENET_PTP1588_IPV6_UDP_PORT_OFFSET 0x38U
<> 144:ef7eb2e8f9f7 57 /*! @brief IPv6 PTP message UDP message type offset. */
<> 144:ef7eb2e8f9f7 58 #define ENET_PTP1588_IPV6_UDP_MSGTYPE_OFFSET 0x3EU
<> 144:ef7eb2e8f9f7 59 /*! @brief IPv6 PTP message UDP version offset. */
<> 144:ef7eb2e8f9f7 60 #define ENET_PTP1588_IPV6_UDP_VERSION_OFFSET 0x3FU
<> 144:ef7eb2e8f9f7 61 /*! @brief IPv6 PTP message UDP clock id offset. */
<> 144:ef7eb2e8f9f7 62 #define ENET_PTP1588_IPV6_UDP_CLKID_OFFSET 0x52U
<> 144:ef7eb2e8f9f7 63 /*! @brief IPv6 PTP message UDP sequence id offset. */
<> 144:ef7eb2e8f9f7 64 #define ENET_PTP1588_IPV6_UDP_SEQUENCEID_OFFSET 0x5CU
<> 144:ef7eb2e8f9f7 65 /*! @brief IPv6 PTP message UDP control offset. */
<> 144:ef7eb2e8f9f7 66 #define ENET_PTP1588_IPV6_UDP_CTL_OFFSET 0x5EU
<> 144:ef7eb2e8f9f7 67 /*! @brief PTPv2 message Ethernet packet type offset. */
<> 144:ef7eb2e8f9f7 68 #define ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET 0x0CU
<> 144:ef7eb2e8f9f7 69 /*! @brief PTPv2 message Ethernet message type offset. */
<> 144:ef7eb2e8f9f7 70 #define ENET_PTP1588_ETHL2_MSGTYPE_OFFSET 0x0EU
<> 144:ef7eb2e8f9f7 71 /*! @brief PTPv2 message Ethernet version type offset. */
<> 144:ef7eb2e8f9f7 72 #define ENET_PTP1588_ETHL2_VERSION_OFFSET 0X0FU
<> 144:ef7eb2e8f9f7 73 /*! @brief PTPv2 message Ethernet clock id offset. */
<> 144:ef7eb2e8f9f7 74 #define ENET_PTP1588_ETHL2_CLOCKID_OFFSET 0x22
<> 144:ef7eb2e8f9f7 75 /*! @brief PTPv2 message Ethernet sequence id offset. */
<> 144:ef7eb2e8f9f7 76 #define ENET_PTP1588_ETHL2_SEQUENCEID_OFFSET 0x2c
<> 144:ef7eb2e8f9f7 77 /*! @brief Packet type Ethernet IEEE802.3 for PTPv2. */
<> 144:ef7eb2e8f9f7 78 #define ENET_ETHERNETL2 0x88F7U
<> 144:ef7eb2e8f9f7 79 /*! @brief Packet type IPv4. */
<> 144:ef7eb2e8f9f7 80 #define ENET_IPV4 0x0800U
<> 144:ef7eb2e8f9f7 81 /*! @brief Packet type IPv6. */
<> 144:ef7eb2e8f9f7 82 #define ENET_IPV6 0x86ddU
<> 144:ef7eb2e8f9f7 83 /*! @brief Packet type VLAN. */
<> 144:ef7eb2e8f9f7 84 #define ENET_8021QVLAN 0x8100U
<> 144:ef7eb2e8f9f7 85 /*! @brief UDP protocol type. */
<> 144:ef7eb2e8f9f7 86 #define ENET_UDPVERSION 0x0011U
<> 144:ef7eb2e8f9f7 87 /*! @brief Packet IP version IPv4. */
<> 144:ef7eb2e8f9f7 88 #define ENET_IPV4VERSION 0x0004U
<> 144:ef7eb2e8f9f7 89 /*! @brief Packet IP version IPv6. */
<> 144:ef7eb2e8f9f7 90 #define ENET_IPV6VERSION 0x0006U
<> 144:ef7eb2e8f9f7 91 /*! @brief Ethernet mac address length. */
<> 144:ef7eb2e8f9f7 92 #define ENET_FRAME_MACLEN 6U
<> 144:ef7eb2e8f9f7 93 /*! @brief Ethernet Frame header length. */
<> 144:ef7eb2e8f9f7 94 #define ENET_FRAME_HEADERLEN 14U
<> 144:ef7eb2e8f9f7 95 /*! @brief Ethernet VLAN header length. */
<> 144:ef7eb2e8f9f7 96 #define ENET_FRAME_VLAN_HEADERLEN 18U
<> 144:ef7eb2e8f9f7 97 /*! @brief MDC frequency. */
<> 144:ef7eb2e8f9f7 98 #define ENET_MDC_FREQUENCY 2500000U
<> 144:ef7eb2e8f9f7 99 /*! @brief NanoSecond in one second. */
<> 144:ef7eb2e8f9f7 100 #define ENET_NANOSECOND_ONE_SECOND 1000000000U
<> 144:ef7eb2e8f9f7 101 /*! @brief Define a common clock cycle delays used for time stamp capture. */
<> 144:ef7eb2e8f9f7 102 #define ENET_1588TIME_DELAY_COUNT 10U
<> 144:ef7eb2e8f9f7 103 /*! @brief Defines the macro for converting constants from host byte order to network byte order. */
<> 144:ef7eb2e8f9f7 104 #define ENET_HTONS(n) __REV16(n)
<> 144:ef7eb2e8f9f7 105 #define ENET_HTONL(n) __REV(n)
<> 144:ef7eb2e8f9f7 106 #define ENET_NTOHS(n) __REV16(n)
<> 144:ef7eb2e8f9f7 107 #define ENET_NTOHL(n) __REV(n)
<> 144:ef7eb2e8f9f7 108
<> 144:ef7eb2e8f9f7 109 /*******************************************************************************
<> 144:ef7eb2e8f9f7 110 * Prototypes
<> 144:ef7eb2e8f9f7 111 ******************************************************************************/
<> 144:ef7eb2e8f9f7 112
<> 144:ef7eb2e8f9f7 113 /*!
<> 144:ef7eb2e8f9f7 114 * @brief Get the ENET instance from peripheral base address.
<> 144:ef7eb2e8f9f7 115 *
<> 144:ef7eb2e8f9f7 116 * @param base ENET peripheral base address.
<> 144:ef7eb2e8f9f7 117 * @return ENET instance.
<> 144:ef7eb2e8f9f7 118 */
<> 144:ef7eb2e8f9f7 119 uint32_t ENET_GetInstance(ENET_Type *base);
<> 144:ef7eb2e8f9f7 120
<> 144:ef7eb2e8f9f7 121 /*!
<> 144:ef7eb2e8f9f7 122 * @brief Set ENET MAC controller with the configuration.
<> 144:ef7eb2e8f9f7 123 *
<> 144:ef7eb2e8f9f7 124 * @param base ENET peripheral base address.
<> 144:ef7eb2e8f9f7 125 * @param config ENET Mac configuration.
<> 144:ef7eb2e8f9f7 126 * @param bufferConfig ENET buffer configuration.
<> 144:ef7eb2e8f9f7 127 * @param macAddr ENET six-byte mac address.
<> 144:ef7eb2e8f9f7 128 * @param srcClock_Hz ENET module clock source, normally it's system clock.
<> 144:ef7eb2e8f9f7 129 */
<> 144:ef7eb2e8f9f7 130 static void ENET_SetMacController(ENET_Type *base,
<> 144:ef7eb2e8f9f7 131 const enet_config_t *config,
<> 144:ef7eb2e8f9f7 132 const enet_buffer_config_t *bufferConfig,
<> 144:ef7eb2e8f9f7 133 uint8_t *macAddr,
<> 144:ef7eb2e8f9f7 134 uint32_t srcClock_Hz);
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 /*!
<> 144:ef7eb2e8f9f7 137 * @brief Set ENET MAC transmit buffer descriptors.
<> 144:ef7eb2e8f9f7 138 *
<> 144:ef7eb2e8f9f7 139 * @param txBdStartAlign The aligned start address of ENET transmit buffer descriptors.
<> 144:ef7eb2e8f9f7 140 * is recommended to evenly divisible by 16.
<> 144:ef7eb2e8f9f7 141 * @param txBuffStartAlign The aligned start address of ENET transmit buffers, must be evenly divisible by 16.
<> 144:ef7eb2e8f9f7 142 * @param txBuffSizeAlign The aligned ENET transmit buffer size, must be evenly divisible by 16.
<> 144:ef7eb2e8f9f7 143 * @param txBdNumber The number of ENET transmit buffers.
<> 144:ef7eb2e8f9f7 144 */
<> 144:ef7eb2e8f9f7 145 static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartAlign,
<> 144:ef7eb2e8f9f7 146 uint8_t *txBuffStartAlign,
<> 144:ef7eb2e8f9f7 147 uint32_t txBuffSizeAlign,
<> 144:ef7eb2e8f9f7 148 uint32_t txBdNumber);
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 /*!
<> 144:ef7eb2e8f9f7 151 * @brief Set ENET MAC receive buffer descriptors.
<> 144:ef7eb2e8f9f7 152 *
<> 144:ef7eb2e8f9f7 153 * @param rxBdStartAlign The aligned start address of ENET receive buffer descriptors.
<> 144:ef7eb2e8f9f7 154 * is recommended to evenly divisible by 16.
<> 144:ef7eb2e8f9f7 155 * @param rxBuffStartAlign The aligned start address of ENET receive buffers, must be evenly divisible by 16.
<> 144:ef7eb2e8f9f7 156 * @param rxBuffSizeAlign The aligned ENET receive buffer size, must be evenly divisible by 16.
<> 144:ef7eb2e8f9f7 157 * @param rxBdNumber The number of ENET receive buffers.
<> 144:ef7eb2e8f9f7 158 * @param enableInterrupt Enable/disables to generate the receive byte and frame interrupt.
<> 144:ef7eb2e8f9f7 159 * It's used for ENET_ENHANCEDBUFFERDESCRIPTOR_MODE enabled case.
<> 144:ef7eb2e8f9f7 160 */
<> 144:ef7eb2e8f9f7 161 static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign,
<> 144:ef7eb2e8f9f7 162 uint8_t *rxBuffStartAlign,
<> 144:ef7eb2e8f9f7 163 uint32_t rxBuffSizeAlign,
<> 144:ef7eb2e8f9f7 164 uint32_t rxBdNumber,
<> 144:ef7eb2e8f9f7 165 bool enableInterrupt);
<> 144:ef7eb2e8f9f7 166
<> 144:ef7eb2e8f9f7 167 /*!
<> 144:ef7eb2e8f9f7 168 * @brief Updates the ENET read buffer descriptors.
<> 144:ef7eb2e8f9f7 169 *
<> 144:ef7eb2e8f9f7 170 * @param base ENET peripheral base address.
<> 144:ef7eb2e8f9f7 171 * @param handle The ENET handle pointer.
<> 144:ef7eb2e8f9f7 172 */
<> 144:ef7eb2e8f9f7 173 static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle);
<> 144:ef7eb2e8f9f7 174
<> 144:ef7eb2e8f9f7 175 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 176 /*!
<> 144:ef7eb2e8f9f7 177 * @brief Parses the ENET frame for time-stamp process of PTP 1588 frame.
<> 144:ef7eb2e8f9f7 178 *
<> 144:ef7eb2e8f9f7 179 * @param data The ENET read data for frame parse.
<> 144:ef7eb2e8f9f7 180 * @param ptpTsData The ENET PTP message and time-stamp data pointer.
<> 144:ef7eb2e8f9f7 181 * @param isFastEnabled The fast parse flag.
<> 144:ef7eb2e8f9f7 182 * - true , Fast processing, only check if this is a PTP message.
<> 144:ef7eb2e8f9f7 183 * - false, Store the PTP message data after check the PTP message.
<> 144:ef7eb2e8f9f7 184 */
<> 144:ef7eb2e8f9f7 185 static bool ENET_Ptp1588ParseFrame(uint8_t *data, enet_ptp_time_data_t *ptpTsData, bool isFastEnabled);
<> 144:ef7eb2e8f9f7 186
<> 144:ef7eb2e8f9f7 187 /*!
<> 144:ef7eb2e8f9f7 188 * @brief Updates the new PTP 1588 time-stamp to the time-stamp buffer ring.
<> 144:ef7eb2e8f9f7 189 *
<> 144:ef7eb2e8f9f7 190 * @param ptpTsDataRing The PTP message and time-stamp data ring pointer.
<> 144:ef7eb2e8f9f7 191 * @param ptpTimeData The new PTP 1588 time-stamp data pointer.
<> 144:ef7eb2e8f9f7 192 */
<> 144:ef7eb2e8f9f7 193 static status_t ENET_Ptp1588UpdateTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimeData);
<> 144:ef7eb2e8f9f7 194
<> 144:ef7eb2e8f9f7 195 /*!
<> 144:ef7eb2e8f9f7 196 * @brief Search up the right PTP 1588 time-stamp from the time-stamp buffer ring.
<> 144:ef7eb2e8f9f7 197 *
<> 144:ef7eb2e8f9f7 198 * @param ptpTsDataRing The PTP message and time-stamp data ring pointer.
<> 144:ef7eb2e8f9f7 199 * @param ptpTimeData The find out right PTP 1588 time-stamp data pointer with the specific PTP message.
<> 144:ef7eb2e8f9f7 200 */
<> 144:ef7eb2e8f9f7 201 static status_t ENET_Ptp1588SearchTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimedata);
<> 144:ef7eb2e8f9f7 202
<> 144:ef7eb2e8f9f7 203 /*!
<> 144:ef7eb2e8f9f7 204 * @brief Store the transmit time-stamp for event PTP frame in the time-stamp buffer ring.
<> 144:ef7eb2e8f9f7 205 *
<> 144:ef7eb2e8f9f7 206 * @param base ENET peripheral base address.
<> 144:ef7eb2e8f9f7 207 * @param handle The ENET handle pointer.
<> 144:ef7eb2e8f9f7 208 */
<> 144:ef7eb2e8f9f7 209 static status_t ENET_StoreTxFrameTime(ENET_Type *base, enet_handle_t *handle);
<> 144:ef7eb2e8f9f7 210
<> 144:ef7eb2e8f9f7 211 /*!
<> 144:ef7eb2e8f9f7 212 * @brief Store the receive time-stamp for event PTP frame in the time-stamp buffer ring.
<> 144:ef7eb2e8f9f7 213 *
<> 144:ef7eb2e8f9f7 214 * @param base ENET peripheral base address.
<> 144:ef7eb2e8f9f7 215 * @param handle The ENET handle pointer.
<> 144:ef7eb2e8f9f7 216 * @param ptpTimeData The PTP 1588 time-stamp data pointer.
<> 144:ef7eb2e8f9f7 217 */
<> 144:ef7eb2e8f9f7 218 static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData);
<> 144:ef7eb2e8f9f7 219 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 220
<> 144:ef7eb2e8f9f7 221 /*******************************************************************************
<> 144:ef7eb2e8f9f7 222 * Variables
<> 144:ef7eb2e8f9f7 223 ******************************************************************************/
<> 144:ef7eb2e8f9f7 224
<> 144:ef7eb2e8f9f7 225 /*! @brief Pointers to enet handles for each instance. */
<> 144:ef7eb2e8f9f7 226 static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL};
<> 144:ef7eb2e8f9f7 227
<> 144:ef7eb2e8f9f7 228 /*! @brief Pointers to enet clocks for each instance. */
<> 144:ef7eb2e8f9f7 229 const clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT] = ENET_CLOCKS;
<> 144:ef7eb2e8f9f7 230
<> 144:ef7eb2e8f9f7 231 /*! @brief Pointers to enet transmit IRQ number for each instance. */
<> 144:ef7eb2e8f9f7 232 const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
<> 144:ef7eb2e8f9f7 233 /*! @brief Pointers to enet receive IRQ number for each instance. */
<> 144:ef7eb2e8f9f7 234 const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
<> 144:ef7eb2e8f9f7 235 #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 236 /*! @brief Pointers to enet timestamp IRQ number for each instance. */
<> 144:ef7eb2e8f9f7 237 const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
<> 144:ef7eb2e8f9f7 238 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 239 /*! @brief Pointers to enet error IRQ number for each instance. */
<> 144:ef7eb2e8f9f7 240 const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
<> 144:ef7eb2e8f9f7 241
<> 144:ef7eb2e8f9f7 242 /*! @brief Pointers to enet bases for each instance. */
<> 144:ef7eb2e8f9f7 243 static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
<> 144:ef7eb2e8f9f7 244
<> 144:ef7eb2e8f9f7 245 /*******************************************************************************
<> 144:ef7eb2e8f9f7 246 * Code
<> 144:ef7eb2e8f9f7 247 ******************************************************************************/
<> 144:ef7eb2e8f9f7 248
<> 144:ef7eb2e8f9f7 249 uint32_t ENET_GetInstance(ENET_Type *base)
<> 144:ef7eb2e8f9f7 250 {
<> 144:ef7eb2e8f9f7 251 uint32_t instance;
<> 144:ef7eb2e8f9f7 252
<> 144:ef7eb2e8f9f7 253 /* Find the instance index from base address mappings. */
<> 144:ef7eb2e8f9f7 254 for (instance = 0; instance < FSL_FEATURE_SOC_ENET_COUNT; instance++)
<> 144:ef7eb2e8f9f7 255 {
<> 144:ef7eb2e8f9f7 256 if (s_enetBases[instance] == base)
<> 144:ef7eb2e8f9f7 257 {
<> 144:ef7eb2e8f9f7 258 break;
<> 144:ef7eb2e8f9f7 259 }
<> 144:ef7eb2e8f9f7 260 }
<> 144:ef7eb2e8f9f7 261
<> 144:ef7eb2e8f9f7 262 assert(instance < FSL_FEATURE_SOC_ENET_COUNT);
<> 144:ef7eb2e8f9f7 263
<> 144:ef7eb2e8f9f7 264 return instance;
<> 144:ef7eb2e8f9f7 265 }
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 void ENET_GetDefaultConfig(enet_config_t *config)
<> 144:ef7eb2e8f9f7 268 {
<> 144:ef7eb2e8f9f7 269 /* Checks input parameter. */
<> 144:ef7eb2e8f9f7 270 assert(config);
<> 144:ef7eb2e8f9f7 271
<> 144:ef7eb2e8f9f7 272 /* Initializes the MAC configure structure to zero. */
<> 144:ef7eb2e8f9f7 273 memset(config, 0, sizeof(enet_config_t));
<> 144:ef7eb2e8f9f7 274
<> 144:ef7eb2e8f9f7 275 /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */
<> 144:ef7eb2e8f9f7 276 config->miiMode = kENET_RmiiMode;
<> 144:ef7eb2e8f9f7 277 config->miiSpeed = kENET_MiiSpeed100M;
<> 144:ef7eb2e8f9f7 278 config->miiDuplex = kENET_MiiFullDuplex;
<> 144:ef7eb2e8f9f7 279
<> 144:ef7eb2e8f9f7 280 /* Sets the maximum receive frame length. */
<> 144:ef7eb2e8f9f7 281 config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN;
<> 144:ef7eb2e8f9f7 282 }
<> 144:ef7eb2e8f9f7 283
<> 144:ef7eb2e8f9f7 284 void ENET_Init(ENET_Type *base,
<> 144:ef7eb2e8f9f7 285 enet_handle_t *handle,
<> 144:ef7eb2e8f9f7 286 const enet_config_t *config,
<> 144:ef7eb2e8f9f7 287 const enet_buffer_config_t *bufferConfig,
<> 144:ef7eb2e8f9f7 288 uint8_t *macAddr,
<> 144:ef7eb2e8f9f7 289 uint32_t srcClock_Hz)
<> 144:ef7eb2e8f9f7 290 {
<> 144:ef7eb2e8f9f7 291 /* Checks input parameters. */
<> 144:ef7eb2e8f9f7 292 assert(handle);
<> 144:ef7eb2e8f9f7 293 assert(config);
<> 144:ef7eb2e8f9f7 294 assert(bufferConfig);
<> 144:ef7eb2e8f9f7 295 assert(bufferConfig->rxBdStartAddrAlign);
<> 144:ef7eb2e8f9f7 296 assert(bufferConfig->txBdStartAddrAlign);
<> 144:ef7eb2e8f9f7 297 assert(bufferConfig->rxBufferAlign);
<> 144:ef7eb2e8f9f7 298 assert(macAddr);
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 uint32_t instance = ENET_GetInstance(base);
<> 144:ef7eb2e8f9f7 301
<> 144:ef7eb2e8f9f7 302 /* Ungate ENET clock. */
<> 144:ef7eb2e8f9f7 303 CLOCK_EnableClock(s_enetClock[instance]);
<> 144:ef7eb2e8f9f7 304
<> 144:ef7eb2e8f9f7 305 /* Reset ENET module. */
<> 144:ef7eb2e8f9f7 306 ENET_Reset(base);
<> 144:ef7eb2e8f9f7 307
<> 144:ef7eb2e8f9f7 308 /* Initializes the ENET transmit buffer descriptors. */
<> 144:ef7eb2e8f9f7 309 ENET_SetTxBufferDescriptors(bufferConfig->txBdStartAddrAlign, bufferConfig->txBufferAlign,
<> 144:ef7eb2e8f9f7 310 bufferConfig->txBuffSizeAlign, bufferConfig->txBdNumber);
<> 144:ef7eb2e8f9f7 311
<> 144:ef7eb2e8f9f7 312 /* Initializes the ENET receive buffer descriptors. */
<> 144:ef7eb2e8f9f7 313 ENET_SetRxBufferDescriptors(bufferConfig->rxBdStartAddrAlign, bufferConfig->rxBufferAlign,
<> 144:ef7eb2e8f9f7 314 bufferConfig->rxBuffSizeAlign, bufferConfig->rxBdNumber,
<> 144:ef7eb2e8f9f7 315 !!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxByteInterrupt)));
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 /* Initializes the ENET MAC controller. */
<> 144:ef7eb2e8f9f7 318 ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz);
<> 144:ef7eb2e8f9f7 319
<> 144:ef7eb2e8f9f7 320 /* Initialize the handle to zero. */
<> 144:ef7eb2e8f9f7 321 memset(handle, 0, sizeof(enet_handle_t));
<> 144:ef7eb2e8f9f7 322
<> 144:ef7eb2e8f9f7 323 /* Store transfer parameters in handle pointer. */
<> 144:ef7eb2e8f9f7 324 handle->rxBdBase = bufferConfig->rxBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 325 handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 326 handle->rxBdDirty = bufferConfig->rxBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 327 handle->txBdBase = bufferConfig->txBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 328 handle->txBdCurrent = bufferConfig->txBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 329 handle->txBdDirty = bufferConfig->txBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 330 handle->rxBuffSizeAlign = bufferConfig->rxBuffSizeAlign;
<> 144:ef7eb2e8f9f7 331 handle->txBuffSizeAlign = bufferConfig->txBuffSizeAlign;
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 /* Save the handle pointer in the global variables. */
<> 144:ef7eb2e8f9f7 334 s_ENETHandle[instance] = handle;
<> 144:ef7eb2e8f9f7 335 }
<> 144:ef7eb2e8f9f7 336
<> 144:ef7eb2e8f9f7 337 void ENET_Deinit(ENET_Type *base)
<> 144:ef7eb2e8f9f7 338 {
<> 144:ef7eb2e8f9f7 339 /* Disable interrupt. */
<> 144:ef7eb2e8f9f7 340 base->EIMR = 0;
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 /* Disable ENET. */
<> 144:ef7eb2e8f9f7 343 base->ECR &= ~ENET_ECR_ETHEREN_MASK;
<> 144:ef7eb2e8f9f7 344
<> 144:ef7eb2e8f9f7 345 /* Disables the clock source. */
<> 144:ef7eb2e8f9f7 346 CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 347 }
<> 144:ef7eb2e8f9f7 348
<> 144:ef7eb2e8f9f7 349 void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData)
<> 144:ef7eb2e8f9f7 350 {
<> 144:ef7eb2e8f9f7 351 assert(handle);
<> 144:ef7eb2e8f9f7 352
<> 144:ef7eb2e8f9f7 353 /* Set callback and userData. */
<> 144:ef7eb2e8f9f7 354 handle->callback = callback;
<> 144:ef7eb2e8f9f7 355 handle->userData = userData;
<> 144:ef7eb2e8f9f7 356 }
<> 144:ef7eb2e8f9f7 357
<> 144:ef7eb2e8f9f7 358 static void ENET_SetMacController(ENET_Type *base,
<> 144:ef7eb2e8f9f7 359 const enet_config_t *config,
<> 144:ef7eb2e8f9f7 360 const enet_buffer_config_t *bufferConfig,
<> 144:ef7eb2e8f9f7 361 uint8_t *macAddr,
<> 144:ef7eb2e8f9f7 362 uint32_t srcClock_Hz)
<> 144:ef7eb2e8f9f7 363 {
<> 144:ef7eb2e8f9f7 364 uint32_t rcr = 0;
<> 144:ef7eb2e8f9f7 365 uint32_t tcr = 0;
<> 144:ef7eb2e8f9f7 366 uint32_t ecr = 0;
<> 144:ef7eb2e8f9f7 367 uint32_t macSpecialConfig = config->macSpecialConfig;
<> 144:ef7eb2e8f9f7 368 uint32_t instance = ENET_GetInstance(base);
<> 144:ef7eb2e8f9f7 369
<> 144:ef7eb2e8f9f7 370 /* Configures MAC receive controller with user configure structure. */
<> 144:ef7eb2e8f9f7 371 rcr = ENET_RCR_NLC(!!(macSpecialConfig & kENET_ControlRxPayloadCheckEnable)) |
<> 144:ef7eb2e8f9f7 372 ENET_RCR_CFEN(!!(macSpecialConfig & kENET_ControlFlowControlEnable)) |
<> 144:ef7eb2e8f9f7 373 ENET_RCR_FCE(!!(macSpecialConfig & kENET_ControlFlowControlEnable)) |
<> 144:ef7eb2e8f9f7 374 ENET_RCR_PADEN(!!(macSpecialConfig & kENET_ControlRxPadRemoveEnable)) |
<> 144:ef7eb2e8f9f7 375 ENET_RCR_BC_REJ(!!(macSpecialConfig & kENET_ControlRxBroadCastRejectEnable)) |
<> 144:ef7eb2e8f9f7 376 ENET_RCR_PROM(!!(macSpecialConfig & kENET_ControlPromiscuousEnable)) | ENET_RCR_MII_MODE(1) |
<> 144:ef7eb2e8f9f7 377 ENET_RCR_RMII_MODE(config->miiMode) | ENET_RCR_RMII_10T(!config->miiSpeed) |
<> 144:ef7eb2e8f9f7 378 ENET_RCR_MAX_FL(config->rxMaxFrameLen) | ENET_RCR_CRCFWD(1);
<> 144:ef7eb2e8f9f7 379 /* Receive setting for half duplex. */
<> 144:ef7eb2e8f9f7 380 if (config->miiDuplex == kENET_MiiHalfDuplex)
<> 144:ef7eb2e8f9f7 381 {
<> 144:ef7eb2e8f9f7 382 rcr |= ENET_RCR_DRT(1);
<> 144:ef7eb2e8f9f7 383 }
<> 144:ef7eb2e8f9f7 384 /* Sets internal loop only for MII mode. */
<> 144:ef7eb2e8f9f7 385 if ((config->macSpecialConfig & kENET_ControlMIILoopEnable) && (config->miiMode == kENET_MiiMode))
<> 144:ef7eb2e8f9f7 386 {
<> 144:ef7eb2e8f9f7 387 rcr |= ENET_RCR_LOOP(1);
<> 144:ef7eb2e8f9f7 388 rcr &= ~ENET_RCR_DRT_MASK;
<> 144:ef7eb2e8f9f7 389 }
<> 144:ef7eb2e8f9f7 390 base->RCR = rcr;
<> 144:ef7eb2e8f9f7 391
<> 144:ef7eb2e8f9f7 392 /* Configures MAC transmit controller: duplex mode, mac address insertion. */
<> 144:ef7eb2e8f9f7 393 tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK);
<> 144:ef7eb2e8f9f7 394 tcr |= ENET_TCR_FDEN(config->miiDuplex) | ENET_TCR_ADDINS(!!(macSpecialConfig & kENET_ControlMacAddrInsert));
<> 144:ef7eb2e8f9f7 395 base->TCR = tcr;
<> 144:ef7eb2e8f9f7 396
<> 144:ef7eb2e8f9f7 397 /* Configures receive and transmit accelerator. */
<> 144:ef7eb2e8f9f7 398 base->TACC = config->txAccelerConfig;
<> 144:ef7eb2e8f9f7 399 base->RACC = config->rxAccelerConfig;
<> 144:ef7eb2e8f9f7 400
<> 144:ef7eb2e8f9f7 401 /* Sets the pause duration and FIFO threshold for the flow control enabled case. */
<> 144:ef7eb2e8f9f7 402 if (macSpecialConfig & kENET_ControlFlowControlEnable)
<> 144:ef7eb2e8f9f7 403 {
<> 144:ef7eb2e8f9f7 404 uint32_t reemReg;
<> 144:ef7eb2e8f9f7 405 base->OPD = config->pauseDuration;
<> 144:ef7eb2e8f9f7 406 reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold);
<> 144:ef7eb2e8f9f7 407 #if FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD
<> 144:ef7eb2e8f9f7 408 reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold);
<> 144:ef7eb2e8f9f7 409 #endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */
<> 144:ef7eb2e8f9f7 410 base->RSEM = reemReg;
<> 144:ef7eb2e8f9f7 411 }
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 /* FIFO threshold setting for store and forward enable/disable case. */
<> 144:ef7eb2e8f9f7 414 if (macSpecialConfig & kENET_ControlStoreAndFwdDisable)
<> 144:ef7eb2e8f9f7 415 {
<> 144:ef7eb2e8f9f7 416 /* Transmit fifo watermark settings. */
<> 144:ef7eb2e8f9f7 417 base->TFWR = config->txFifoWatermark & ENET_TFWR_TFWR_MASK;
<> 144:ef7eb2e8f9f7 418 /* Receive fifo full threshold settings. */
<> 144:ef7eb2e8f9f7 419 base->RSFL = config->rxFifoFullThreshold & ENET_RSFL_RX_SECTION_FULL_MASK;
<> 144:ef7eb2e8f9f7 420 }
<> 144:ef7eb2e8f9f7 421 else
<> 144:ef7eb2e8f9f7 422 {
<> 144:ef7eb2e8f9f7 423 /* Transmit fifo watermark settings. */
<> 144:ef7eb2e8f9f7 424 base->TFWR = ENET_TFWR_STRFWD_MASK;
<> 144:ef7eb2e8f9f7 425 base->RSFL = 0;
<> 144:ef7eb2e8f9f7 426 }
<> 144:ef7eb2e8f9f7 427
<> 144:ef7eb2e8f9f7 428 /* Enable store and forward when accelerator is enabled */
<> 144:ef7eb2e8f9f7 429 if (config->txAccelerConfig & (kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled))
<> 144:ef7eb2e8f9f7 430 {
<> 144:ef7eb2e8f9f7 431 base->TFWR = ENET_TFWR_STRFWD_MASK;
<> 144:ef7eb2e8f9f7 432 }
<> 144:ef7eb2e8f9f7 433 if (config->rxAccelerConfig & (kENET_RxAccelIpCheckEnabled | kENET_RxAccelProtoCheckEnabled))
<> 144:ef7eb2e8f9f7 434 {
<> 144:ef7eb2e8f9f7 435 base->RSFL = 0;
<> 144:ef7eb2e8f9f7 436 }
<> 144:ef7eb2e8f9f7 437
<> 144:ef7eb2e8f9f7 438 /* Initializes transmit buffer descriptor rings start address, two start address should be aligned. */
<> 144:ef7eb2e8f9f7 439 base->TDSR = (uint32_t)bufferConfig->txBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 440 base->RDSR = (uint32_t)bufferConfig->rxBdStartAddrAlign;
<> 144:ef7eb2e8f9f7 441 /* Initializes the maximum buffer size, the buffer size should be aligned. */
<> 144:ef7eb2e8f9f7 442 base->MRBR = bufferConfig->rxBuffSizeAlign;
<> 144:ef7eb2e8f9f7 443
<> 144:ef7eb2e8f9f7 444 /* Configures the Mac address. */
<> 144:ef7eb2e8f9f7 445 ENET_SetMacAddr(base, macAddr);
<> 144:ef7eb2e8f9f7 446
<> 144:ef7eb2e8f9f7 447 /* Initialize the SMI if uninitialized. */
<> 144:ef7eb2e8f9f7 448 if (!ENET_GetSMI(base))
<> 144:ef7eb2e8f9f7 449 {
<> 144:ef7eb2e8f9f7 450 ENET_SetSMI(base, srcClock_Hz, !!(config->macSpecialConfig & kENET_ControlSMIPreambleDisable));
<> 144:ef7eb2e8f9f7 451 }
<> 144:ef7eb2e8f9f7 452
<> 144:ef7eb2e8f9f7 453 /* Enables Ethernet interrupt and NVIC. */
<> 144:ef7eb2e8f9f7 454 ENET_EnableInterrupts(base, config->interrupt);
<> 144:ef7eb2e8f9f7 455 if (config->interrupt & (kENET_RxByteInterrupt | kENET_RxFrameInterrupt))
<> 144:ef7eb2e8f9f7 456 {
<> 144:ef7eb2e8f9f7 457 EnableIRQ(s_enetRxIrqId[instance]);
<> 144:ef7eb2e8f9f7 458 }
<> 144:ef7eb2e8f9f7 459 if (config->interrupt & (kENET_TxByteInterrupt | kENET_TxFrameInterrupt))
<> 144:ef7eb2e8f9f7 460 {
<> 144:ef7eb2e8f9f7 461 EnableIRQ(s_enetTxIrqId[instance]);
<> 144:ef7eb2e8f9f7 462 }
<> 144:ef7eb2e8f9f7 463 if (config->interrupt & (kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_GraceStopInterrupt | kENET_MiiInterrupt |
<> 144:ef7eb2e8f9f7 464 kENET_EBusERInterrupt | kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt |
<> 144:ef7eb2e8f9f7 465 kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt | kENET_WakeupInterrupt))
<> 144:ef7eb2e8f9f7 466 {
<> 144:ef7eb2e8f9f7 467 EnableIRQ(s_enetErrIrqId[instance]);
<> 144:ef7eb2e8f9f7 468 }
<> 144:ef7eb2e8f9f7 469
<> 144:ef7eb2e8f9f7 470 /* ENET control register setting. */
<> 144:ef7eb2e8f9f7 471 ecr = base->ECR;
<> 144:ef7eb2e8f9f7 472 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 473 /* Sets the 1588 enhanced feature. */
<> 144:ef7eb2e8f9f7 474 ecr |= ENET_ECR_EN1588_MASK;
<> 144:ef7eb2e8f9f7 475 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 476 /* Enables Ethernet module after all configuration except the buffer descriptor active. */
<> 144:ef7eb2e8f9f7 477 ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK;
<> 144:ef7eb2e8f9f7 478 base->ECR = ecr;
<> 144:ef7eb2e8f9f7 479 }
<> 144:ef7eb2e8f9f7 480
<> 144:ef7eb2e8f9f7 481 static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartAlign,
<> 144:ef7eb2e8f9f7 482 uint8_t *txBuffStartAlign,
<> 144:ef7eb2e8f9f7 483 uint32_t txBuffSizeAlign,
<> 144:ef7eb2e8f9f7 484 uint32_t txBdNumber)
<> 144:ef7eb2e8f9f7 485 {
<> 144:ef7eb2e8f9f7 486 assert(txBdStartAlign);
<> 144:ef7eb2e8f9f7 487
<> 144:ef7eb2e8f9f7 488 uint32_t count;
<> 144:ef7eb2e8f9f7 489 volatile enet_tx_bd_struct_t *curBuffDescrip = txBdStartAlign;
<> 144:ef7eb2e8f9f7 490
<> 144:ef7eb2e8f9f7 491 for (count = 0; count < txBdNumber; count++)
<> 144:ef7eb2e8f9f7 492 {
<> 144:ef7eb2e8f9f7 493 if (txBuffSizeAlign != NULL)
<> 144:ef7eb2e8f9f7 494 {
<> 144:ef7eb2e8f9f7 495 /* Set data buffer address. */
<> 144:ef7eb2e8f9f7 496 curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffStartAlign[count * txBuffSizeAlign]);
<> 144:ef7eb2e8f9f7 497 }
<> 144:ef7eb2e8f9f7 498 else
<> 144:ef7eb2e8f9f7 499 {
<> 144:ef7eb2e8f9f7 500 /* User should provide the transmit buffer at a later time */
<> 144:ef7eb2e8f9f7 501 curBuffDescrip->buffer = NULL;
<> 144:ef7eb2e8f9f7 502 }
<> 144:ef7eb2e8f9f7 503 /* Initializes data length. */
<> 144:ef7eb2e8f9f7 504 curBuffDescrip->length = 0;
<> 144:ef7eb2e8f9f7 505 /* Sets the crc. */
<> 144:ef7eb2e8f9f7 506 curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK;
<> 144:ef7eb2e8f9f7 507 /* Sets the last buffer descriptor with the wrap flag. */
<> 144:ef7eb2e8f9f7 508 if (count == txBdNumber - 1)
<> 144:ef7eb2e8f9f7 509 {
<> 144:ef7eb2e8f9f7 510 curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
<> 144:ef7eb2e8f9f7 511 }
<> 144:ef7eb2e8f9f7 512
<> 144:ef7eb2e8f9f7 513 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 514 /* Enable transmit interrupt for store the transmit timestamp. */
<> 144:ef7eb2e8f9f7 515 curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK;
<> 144:ef7eb2e8f9f7 516 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 517 /* Increase the index. */
<> 144:ef7eb2e8f9f7 518 curBuffDescrip++;
<> 144:ef7eb2e8f9f7 519 }
<> 144:ef7eb2e8f9f7 520 }
<> 144:ef7eb2e8f9f7 521
<> 144:ef7eb2e8f9f7 522 static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign,
<> 144:ef7eb2e8f9f7 523 uint8_t *rxBuffStartAlign,
<> 144:ef7eb2e8f9f7 524 uint32_t rxBuffSizeAlign,
<> 144:ef7eb2e8f9f7 525 uint32_t rxBdNumber,
<> 144:ef7eb2e8f9f7 526 bool enableInterrupt)
<> 144:ef7eb2e8f9f7 527 {
<> 144:ef7eb2e8f9f7 528 assert(rxBdStartAlign);
<> 144:ef7eb2e8f9f7 529 assert(rxBuffStartAlign);
<> 144:ef7eb2e8f9f7 530
<> 144:ef7eb2e8f9f7 531 volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdStartAlign;
<> 144:ef7eb2e8f9f7 532 uint32_t count = 0;
<> 144:ef7eb2e8f9f7 533
<> 144:ef7eb2e8f9f7 534 /* Initializes receive buffer descriptors. */
<> 144:ef7eb2e8f9f7 535 for (count = 0; count < rxBdNumber; count++)
<> 144:ef7eb2e8f9f7 536 {
<> 144:ef7eb2e8f9f7 537 /* Set data buffer and the length. */
<> 144:ef7eb2e8f9f7 538 curBuffDescrip->buffer = (uint8_t *)(*((uint32_t *)(rxBuffStartAlign + count * 4)));
<> 144:ef7eb2e8f9f7 539 curBuffDescrip->length = 0;
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 /* Initializes the buffer descriptors with empty bit. */
<> 144:ef7eb2e8f9f7 542 curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
<> 144:ef7eb2e8f9f7 543 /* Sets the last buffer descriptor with the wrap flag. */
<> 144:ef7eb2e8f9f7 544 if (count == rxBdNumber - 1)
<> 144:ef7eb2e8f9f7 545 {
<> 144:ef7eb2e8f9f7 546 curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
<> 144:ef7eb2e8f9f7 547 }
<> 144:ef7eb2e8f9f7 548
<> 144:ef7eb2e8f9f7 549 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 550 if (enableInterrupt)
<> 144:ef7eb2e8f9f7 551 {
<> 144:ef7eb2e8f9f7 552 /* Enable receive interrupt. */
<> 144:ef7eb2e8f9f7 553 curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK;
<> 144:ef7eb2e8f9f7 554 }
<> 144:ef7eb2e8f9f7 555 else
<> 144:ef7eb2e8f9f7 556 {
<> 144:ef7eb2e8f9f7 557 curBuffDescrip->controlExtend1 = 0;
<> 144:ef7eb2e8f9f7 558 }
<> 144:ef7eb2e8f9f7 559 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 560 /* Increase the index. */
<> 144:ef7eb2e8f9f7 561 curBuffDescrip++;
<> 144:ef7eb2e8f9f7 562 }
<> 144:ef7eb2e8f9f7 563 }
<> 144:ef7eb2e8f9f7 564
<> 144:ef7eb2e8f9f7 565 void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
<> 144:ef7eb2e8f9f7 566 {
<> 144:ef7eb2e8f9f7 567 uint32_t rcr;
<> 144:ef7eb2e8f9f7 568 uint32_t tcr;
<> 144:ef7eb2e8f9f7 569
<> 144:ef7eb2e8f9f7 570 rcr = base->RCR;
<> 144:ef7eb2e8f9f7 571 tcr = base->TCR;
<> 144:ef7eb2e8f9f7 572
<> 144:ef7eb2e8f9f7 573 /* Sets speed mode. */
<> 144:ef7eb2e8f9f7 574 if (kENET_MiiSpeed10M == speed)
<> 144:ef7eb2e8f9f7 575 {
<> 144:ef7eb2e8f9f7 576 rcr |= ENET_RCR_RMII_10T_MASK;
<> 144:ef7eb2e8f9f7 577 }
<> 144:ef7eb2e8f9f7 578 else
<> 144:ef7eb2e8f9f7 579 {
<> 144:ef7eb2e8f9f7 580 rcr &= ~ENET_RCR_RMII_10T_MASK;
<> 144:ef7eb2e8f9f7 581 }
<> 144:ef7eb2e8f9f7 582 /* Set duplex mode. */
<> 144:ef7eb2e8f9f7 583 if (duplex == kENET_MiiHalfDuplex)
<> 144:ef7eb2e8f9f7 584 {
<> 144:ef7eb2e8f9f7 585 rcr |= ENET_RCR_DRT_MASK;
<> 144:ef7eb2e8f9f7 586 tcr &= ~ENET_TCR_FDEN_MASK;
<> 144:ef7eb2e8f9f7 587 }
<> 144:ef7eb2e8f9f7 588 else
<> 144:ef7eb2e8f9f7 589 {
<> 144:ef7eb2e8f9f7 590 rcr &= ~ENET_RCR_DRT_MASK;
<> 144:ef7eb2e8f9f7 591 tcr |= ENET_TCR_FDEN_MASK;
<> 144:ef7eb2e8f9f7 592 }
<> 144:ef7eb2e8f9f7 593
<> 144:ef7eb2e8f9f7 594 base->RCR = rcr;
<> 144:ef7eb2e8f9f7 595 base->TCR = tcr;
<> 144:ef7eb2e8f9f7 596 }
<> 144:ef7eb2e8f9f7 597
<> 144:ef7eb2e8f9f7 598 void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
<> 144:ef7eb2e8f9f7 599 {
<> 144:ef7eb2e8f9f7 600 uint32_t address;
<> 144:ef7eb2e8f9f7 601
<> 144:ef7eb2e8f9f7 602 /* Set physical address lower register. */
<> 144:ef7eb2e8f9f7 603 address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) |
<> 144:ef7eb2e8f9f7 604 (uint32_t)macAddr[3]);
<> 144:ef7eb2e8f9f7 605 base->PALR = address;
<> 144:ef7eb2e8f9f7 606 /* Set physical address high register. */
<> 144:ef7eb2e8f9f7 607 address = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5]));
<> 144:ef7eb2e8f9f7 608 base->PAUR = address << ENET_PAUR_PADDR2_SHIFT;
<> 144:ef7eb2e8f9f7 609 }
<> 144:ef7eb2e8f9f7 610
<> 144:ef7eb2e8f9f7 611 void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr)
<> 144:ef7eb2e8f9f7 612 {
<> 144:ef7eb2e8f9f7 613 assert(macAddr);
<> 144:ef7eb2e8f9f7 614
<> 144:ef7eb2e8f9f7 615 uint32_t address;
<> 144:ef7eb2e8f9f7 616
<> 144:ef7eb2e8f9f7 617 /* Get from physical address lower register. */
<> 144:ef7eb2e8f9f7 618 address = base->PALR;
<> 144:ef7eb2e8f9f7 619 macAddr[0] = 0xFFU & (address >> 24U);
<> 144:ef7eb2e8f9f7 620 macAddr[1] = 0xFFU & (address >> 16U);
<> 144:ef7eb2e8f9f7 621 macAddr[2] = 0xFFU & (address >> 8U);
<> 144:ef7eb2e8f9f7 622 macAddr[3] = 0xFFU & address;
<> 144:ef7eb2e8f9f7 623
<> 144:ef7eb2e8f9f7 624 /* Get from physical address high register. */
<> 144:ef7eb2e8f9f7 625 address = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT;
<> 144:ef7eb2e8f9f7 626 macAddr[4] = 0xFFU & (address >> 8U);
<> 144:ef7eb2e8f9f7 627 macAddr[5] = 0xFFU & address;
<> 144:ef7eb2e8f9f7 628 }
<> 144:ef7eb2e8f9f7 629
<> 144:ef7eb2e8f9f7 630 void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
<> 144:ef7eb2e8f9f7 631 {
<> 144:ef7eb2e8f9f7 632 assert(srcClock_Hz);
<> 144:ef7eb2e8f9f7 633
<> 144:ef7eb2e8f9f7 634 uint32_t clkCycle = 0;
<> 144:ef7eb2e8f9f7 635 uint32_t speed = 0;
<> 144:ef7eb2e8f9f7 636 uint32_t mscr = 0;
<> 144:ef7eb2e8f9f7 637
<> 144:ef7eb2e8f9f7 638 /* Calculate the MII speed which controls the frequency of the MDC. */
<> 144:ef7eb2e8f9f7 639 speed = srcClock_Hz / (2 * ENET_MDC_FREQUENCY);
<> 144:ef7eb2e8f9f7 640 /* Calculate the hold time on the MDIO output. */
<> 144:ef7eb2e8f9f7 641 clkCycle = (10 + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1;
<> 144:ef7eb2e8f9f7 642 /* Build the configuration for MDC/MDIO control. */
<> 144:ef7eb2e8f9f7 643 mscr = ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_DIS_PRE(isPreambleDisabled) | ENET_MSCR_HOLDTIME(clkCycle);
<> 144:ef7eb2e8f9f7 644 base->MSCR = mscr;
<> 144:ef7eb2e8f9f7 645 }
<> 144:ef7eb2e8f9f7 646
<> 144:ef7eb2e8f9f7 647 void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data)
<> 144:ef7eb2e8f9f7 648 {
<> 144:ef7eb2e8f9f7 649 uint32_t mmfr = 0;
<> 144:ef7eb2e8f9f7 650
<> 144:ef7eb2e8f9f7 651 /* Build MII write command. */
<> 144:ef7eb2e8f9f7 652 mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2) |
<> 144:ef7eb2e8f9f7 653 (data & 0xFFFF);
<> 144:ef7eb2e8f9f7 654 base->MMFR = mmfr;
<> 144:ef7eb2e8f9f7 655 }
<> 144:ef7eb2e8f9f7 656
<> 144:ef7eb2e8f9f7 657 void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation)
<> 144:ef7eb2e8f9f7 658 {
<> 144:ef7eb2e8f9f7 659 uint32_t mmfr = 0;
<> 144:ef7eb2e8f9f7 660
<> 144:ef7eb2e8f9f7 661 /* Build MII read command. */
<> 144:ef7eb2e8f9f7 662 mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2);
<> 144:ef7eb2e8f9f7 663 base->MMFR = mmfr;
<> 144:ef7eb2e8f9f7 664 }
<> 144:ef7eb2e8f9f7 665
<> 144:ef7eb2e8f9f7 666 void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic)
<> 144:ef7eb2e8f9f7 667 {
<> 144:ef7eb2e8f9f7 668 assert(handle);
<> 144:ef7eb2e8f9f7 669 assert(handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 670 assert(eErrorStatic);
<> 144:ef7eb2e8f9f7 671
<> 144:ef7eb2e8f9f7 672 uint16_t control = 0;
<> 144:ef7eb2e8f9f7 673 volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
<> 144:ef7eb2e8f9f7 674
<> 144:ef7eb2e8f9f7 675 do
<> 144:ef7eb2e8f9f7 676 {
<> 144:ef7eb2e8f9f7 677 /* The last buffer descriptor of a frame. */
<> 144:ef7eb2e8f9f7 678 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
<> 144:ef7eb2e8f9f7 679 {
<> 144:ef7eb2e8f9f7 680 control = curBuffDescrip->control;
<> 144:ef7eb2e8f9f7 681 if (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK)
<> 144:ef7eb2e8f9f7 682 {
<> 144:ef7eb2e8f9f7 683 /* The receive truncate error. */
<> 144:ef7eb2e8f9f7 684 eErrorStatic->statsRxTruncateErr++;
<> 144:ef7eb2e8f9f7 685 }
<> 144:ef7eb2e8f9f7 686 if (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK)
<> 144:ef7eb2e8f9f7 687 {
<> 144:ef7eb2e8f9f7 688 /* The receive over run error. */
<> 144:ef7eb2e8f9f7 689 eErrorStatic->statsRxOverRunErr++;
<> 144:ef7eb2e8f9f7 690 }
<> 144:ef7eb2e8f9f7 691 if (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK)
<> 144:ef7eb2e8f9f7 692 {
<> 144:ef7eb2e8f9f7 693 /* The receive length violation error. */
<> 144:ef7eb2e8f9f7 694 eErrorStatic->statsRxLenGreaterErr++;
<> 144:ef7eb2e8f9f7 695 }
<> 144:ef7eb2e8f9f7 696 if (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK)
<> 144:ef7eb2e8f9f7 697 {
<> 144:ef7eb2e8f9f7 698 /* The receive alignment error. */
<> 144:ef7eb2e8f9f7 699 eErrorStatic->statsRxAlignErr++;
<> 144:ef7eb2e8f9f7 700 }
<> 144:ef7eb2e8f9f7 701 if (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK)
<> 144:ef7eb2e8f9f7 702 {
<> 144:ef7eb2e8f9f7 703 /* The receive CRC error. */
<> 144:ef7eb2e8f9f7 704 eErrorStatic->statsRxFcsErr++;
<> 144:ef7eb2e8f9f7 705 }
<> 144:ef7eb2e8f9f7 706 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 707 uint16_t controlExt = curBuffDescrip->controlExtend1;
<> 144:ef7eb2e8f9f7 708 if (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK)
<> 144:ef7eb2e8f9f7 709 {
<> 144:ef7eb2e8f9f7 710 /* The MAC error. */
<> 144:ef7eb2e8f9f7 711 eErrorStatic->statsRxMacErr++;
<> 144:ef7eb2e8f9f7 712 }
<> 144:ef7eb2e8f9f7 713 if (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK)
<> 144:ef7eb2e8f9f7 714 {
<> 144:ef7eb2e8f9f7 715 /* The PHY error. */
<> 144:ef7eb2e8f9f7 716 eErrorStatic->statsRxPhyErr++;
<> 144:ef7eb2e8f9f7 717 }
<> 144:ef7eb2e8f9f7 718 if (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK)
<> 144:ef7eb2e8f9f7 719 {
<> 144:ef7eb2e8f9f7 720 /* The receive collision error. */
<> 144:ef7eb2e8f9f7 721 eErrorStatic->statsRxCollisionErr++;
<> 144:ef7eb2e8f9f7 722 }
<> 144:ef7eb2e8f9f7 723 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 724
<> 144:ef7eb2e8f9f7 725 break;
<> 144:ef7eb2e8f9f7 726 }
<> 144:ef7eb2e8f9f7 727
<> 144:ef7eb2e8f9f7 728 /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
<> 144:ef7eb2e8f9f7 729 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 730 {
<> 144:ef7eb2e8f9f7 731 curBuffDescrip = handle->rxBdBase;
<> 144:ef7eb2e8f9f7 732 }
<> 144:ef7eb2e8f9f7 733 else
<> 144:ef7eb2e8f9f7 734 {
<> 144:ef7eb2e8f9f7 735 curBuffDescrip++;
<> 144:ef7eb2e8f9f7 736 }
<> 144:ef7eb2e8f9f7 737
<> 144:ef7eb2e8f9f7 738 } while (curBuffDescrip != handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 739 }
<> 144:ef7eb2e8f9f7 740
<> 144:ef7eb2e8f9f7 741 status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length)
<> 144:ef7eb2e8f9f7 742 {
<> 144:ef7eb2e8f9f7 743 assert(handle);
<> 144:ef7eb2e8f9f7 744 assert(handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 745 assert(length);
<> 144:ef7eb2e8f9f7 746
<> 144:ef7eb2e8f9f7 747 uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
<> 144:ef7eb2e8f9f7 748 volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
<> 144:ef7eb2e8f9f7 749
<> 144:ef7eb2e8f9f7 750 /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */
<> 144:ef7eb2e8f9f7 751 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)
<> 144:ef7eb2e8f9f7 752 {
<> 144:ef7eb2e8f9f7 753 *length = 0;
<> 144:ef7eb2e8f9f7 754 return kStatus_ENET_RxFrameEmpty;
<> 144:ef7eb2e8f9f7 755 }
<> 144:ef7eb2e8f9f7 756
<> 144:ef7eb2e8f9f7 757 do
<> 144:ef7eb2e8f9f7 758 {
<> 144:ef7eb2e8f9f7 759 /* Find the last buffer descriptor. */
<> 144:ef7eb2e8f9f7 760 if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
<> 144:ef7eb2e8f9f7 761 {
<> 144:ef7eb2e8f9f7 762 /* The last buffer descriptor in the frame check the status of the received frame. */
<> 144:ef7eb2e8f9f7 763 if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK)
<> 144:ef7eb2e8f9f7 764 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 765 || (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK)
<> 144:ef7eb2e8f9f7 766 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 767 )
<> 144:ef7eb2e8f9f7 768 {
<> 144:ef7eb2e8f9f7 769 *length = 0;
<> 144:ef7eb2e8f9f7 770 return kStatus_ENET_RxFrameError;
<> 144:ef7eb2e8f9f7 771 }
<> 144:ef7eb2e8f9f7 772 /* FCS is removed by MAC. */
<> 144:ef7eb2e8f9f7 773 *length = curBuffDescrip->length;
<> 144:ef7eb2e8f9f7 774 return kStatus_Success;
<> 144:ef7eb2e8f9f7 775 }
<> 144:ef7eb2e8f9f7 776 /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
<> 144:ef7eb2e8f9f7 777 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 778 {
<> 144:ef7eb2e8f9f7 779 curBuffDescrip = handle->rxBdBase;
<> 144:ef7eb2e8f9f7 780 }
<> 144:ef7eb2e8f9f7 781 else
<> 144:ef7eb2e8f9f7 782 {
<> 144:ef7eb2e8f9f7 783 curBuffDescrip++;
<> 144:ef7eb2e8f9f7 784 }
<> 144:ef7eb2e8f9f7 785
<> 144:ef7eb2e8f9f7 786 } while (curBuffDescrip != handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 787
<> 144:ef7eb2e8f9f7 788 /* The frame is on processing - set to empty status to make application to receive it next time. */
<> 144:ef7eb2e8f9f7 789 return kStatus_ENET_RxFrameEmpty;
<> 144:ef7eb2e8f9f7 790 }
<> 144:ef7eb2e8f9f7 791
<> 144:ef7eb2e8f9f7 792 status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length)
<> 144:ef7eb2e8f9f7 793 {
<> 144:ef7eb2e8f9f7 794 assert(handle);
<> 144:ef7eb2e8f9f7 795 assert(handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 796
<> 144:ef7eb2e8f9f7 797 uint32_t len = 0;
<> 144:ef7eb2e8f9f7 798 uint32_t offset = 0;
<> 144:ef7eb2e8f9f7 799 bool isLastBuff = false;
<> 144:ef7eb2e8f9f7 800 volatile enet_rx_bd_struct_t *curBuffDescrip;
<> 144:ef7eb2e8f9f7 801 status_t result = kStatus_Success;
<> 144:ef7eb2e8f9f7 802
<> 144:ef7eb2e8f9f7 803 /* For data-NULL input, only update the buffer descriptor. */
<> 144:ef7eb2e8f9f7 804 if (!data)
<> 144:ef7eb2e8f9f7 805 {
<> 144:ef7eb2e8f9f7 806 do
<> 144:ef7eb2e8f9f7 807 {
<> 144:ef7eb2e8f9f7 808 /* Get the current buffer descriptor. */
<> 144:ef7eb2e8f9f7 809 curBuffDescrip = handle->rxBdCurrent;
<> 144:ef7eb2e8f9f7 810 /* Increase current buffer descriptor to the next one. */
<> 144:ef7eb2e8f9f7 811 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 812 {
<> 144:ef7eb2e8f9f7 813 handle->rxBdCurrent = handle->rxBdBase;
<> 144:ef7eb2e8f9f7 814 }
<> 144:ef7eb2e8f9f7 815 else
<> 144:ef7eb2e8f9f7 816 {
<> 144:ef7eb2e8f9f7 817 handle->rxBdCurrent++;
<> 144:ef7eb2e8f9f7 818 }
<> 144:ef7eb2e8f9f7 819
<> 144:ef7eb2e8f9f7 820 /* The last buffer descriptor of a frame. */
<> 144:ef7eb2e8f9f7 821 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
<> 144:ef7eb2e8f9f7 822 {
<> 144:ef7eb2e8f9f7 823 /* Find the last buffer descriptor for the frame*/
<> 144:ef7eb2e8f9f7 824 break;
<> 144:ef7eb2e8f9f7 825 }
<> 144:ef7eb2e8f9f7 826 } while (handle->rxBdCurrent != handle->rxBdDirty);
<> 144:ef7eb2e8f9f7 827
<> 144:ef7eb2e8f9f7 828 /* Update all receive buffer descriptors for the whole frame. */
<> 144:ef7eb2e8f9f7 829 ENET_UpdateReadBuffers(base, handle);
<> 144:ef7eb2e8f9f7 830
<> 144:ef7eb2e8f9f7 831 return result;
<> 144:ef7eb2e8f9f7 832 }
<> 144:ef7eb2e8f9f7 833 else
<> 144:ef7eb2e8f9f7 834 {
<> 144:ef7eb2e8f9f7 835 /* Frame read from the MAC to user buffer and update the buffer descriptors.
<> 144:ef7eb2e8f9f7 836 Process the frame, a frame on several receive buffers are considered . */
<> 144:ef7eb2e8f9f7 837 /* Get the current buffer descriptor. */
<> 144:ef7eb2e8f9f7 838 curBuffDescrip = handle->rxBdCurrent;
<> 144:ef7eb2e8f9f7 839 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 840 enet_ptp_time_data_t ptpTimestamp;
<> 144:ef7eb2e8f9f7 841 bool isPtpEventMessage = false;
<> 144:ef7eb2e8f9f7 842
<> 144:ef7eb2e8f9f7 843 /* Parse the PTP message according to the header message. */
<> 144:ef7eb2e8f9f7 844 isPtpEventMessage = ENET_Ptp1588ParseFrame(curBuffDescrip->buffer, &ptpTimestamp, false);
<> 144:ef7eb2e8f9f7 845 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 846
<> 144:ef7eb2e8f9f7 847 while (!isLastBuff)
<> 144:ef7eb2e8f9f7 848 {
<> 144:ef7eb2e8f9f7 849 /* Increase current buffer descriptor to the next one. */
<> 144:ef7eb2e8f9f7 850 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 851 {
<> 144:ef7eb2e8f9f7 852 handle->rxBdCurrent = handle->rxBdBase;
<> 144:ef7eb2e8f9f7 853 }
<> 144:ef7eb2e8f9f7 854 else
<> 144:ef7eb2e8f9f7 855 {
<> 144:ef7eb2e8f9f7 856 handle->rxBdCurrent++;
<> 144:ef7eb2e8f9f7 857 }
<> 144:ef7eb2e8f9f7 858
<> 144:ef7eb2e8f9f7 859 /* The last buffer descriptor of a frame. */
<> 144:ef7eb2e8f9f7 860 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
<> 144:ef7eb2e8f9f7 861 {
<> 144:ef7eb2e8f9f7 862 /* This is a valid frame. */
<> 144:ef7eb2e8f9f7 863 isLastBuff = true;
<> 144:ef7eb2e8f9f7 864 if (length == curBuffDescrip->length)
<> 144:ef7eb2e8f9f7 865 {
<> 144:ef7eb2e8f9f7 866 /* Copy the frame to user's buffer without FCS. */
<> 144:ef7eb2e8f9f7 867 len = curBuffDescrip->length - offset;
<> 144:ef7eb2e8f9f7 868 memcpy(data + offset, curBuffDescrip->buffer, len);
<> 144:ef7eb2e8f9f7 869 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 870 /* Store the PTP 1588 timestamp for received PTP event frame. */
<> 144:ef7eb2e8f9f7 871 if (isPtpEventMessage)
<> 144:ef7eb2e8f9f7 872 {
<> 144:ef7eb2e8f9f7 873 /* Set the timestamp to the timestamp ring. */
<> 144:ef7eb2e8f9f7 874 ptpTimestamp.timeStamp.nanosecond = curBuffDescrip->timestamp;
<> 144:ef7eb2e8f9f7 875 result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp);
<> 144:ef7eb2e8f9f7 876 }
<> 144:ef7eb2e8f9f7 877 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 878 ENET_UpdateReadBuffers(base, handle);
<> 144:ef7eb2e8f9f7 879 return result;
<> 144:ef7eb2e8f9f7 880 }
<> 144:ef7eb2e8f9f7 881 }
<> 144:ef7eb2e8f9f7 882 else
<> 144:ef7eb2e8f9f7 883 {
<> 144:ef7eb2e8f9f7 884 /* Store the fragments of a frame on several buffer descriptors. */
<> 144:ef7eb2e8f9f7 885 isLastBuff = false;
<> 144:ef7eb2e8f9f7 886 memcpy(data + offset, curBuffDescrip->buffer, handle->rxBuffSizeAlign);
<> 144:ef7eb2e8f9f7 887 offset += handle->rxBuffSizeAlign;
<> 144:ef7eb2e8f9f7 888 if (offset >= length)
<> 144:ef7eb2e8f9f7 889 {
<> 144:ef7eb2e8f9f7 890 break;
<> 144:ef7eb2e8f9f7 891 }
<> 144:ef7eb2e8f9f7 892 }
<> 144:ef7eb2e8f9f7 893
<> 144:ef7eb2e8f9f7 894 /* Get the current buffer descriptor. */
<> 144:ef7eb2e8f9f7 895 curBuffDescrip = handle->rxBdCurrent;
<> 144:ef7eb2e8f9f7 896 }
<> 144:ef7eb2e8f9f7 897 /* All error happens will break the while loop and arrive here to update receive buffers. */
<> 144:ef7eb2e8f9f7 898 ENET_UpdateReadBuffers(base, handle);
<> 144:ef7eb2e8f9f7 899 }
<> 144:ef7eb2e8f9f7 900 return kStatus_ENET_RxFrameFail;
<> 144:ef7eb2e8f9f7 901 }
<> 144:ef7eb2e8f9f7 902
<> 144:ef7eb2e8f9f7 903 static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 904 {
<> 144:ef7eb2e8f9f7 905 assert(handle);
<> 144:ef7eb2e8f9f7 906
<> 144:ef7eb2e8f9f7 907 do
<> 144:ef7eb2e8f9f7 908 {
<> 144:ef7eb2e8f9f7 909 /* Clears status. */
<> 144:ef7eb2e8f9f7 910 handle->rxBdDirty->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
<> 144:ef7eb2e8f9f7 911 /* Sets the receive buffer descriptor with the empty flag. */
<> 144:ef7eb2e8f9f7 912 handle->rxBdDirty->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
<> 144:ef7eb2e8f9f7 913 /* Increases the buffer descriptor to the next one. */
<> 144:ef7eb2e8f9f7 914 if (handle->rxBdDirty->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 915 {
<> 144:ef7eb2e8f9f7 916 handle->rxBdDirty = handle->rxBdBase;
<> 144:ef7eb2e8f9f7 917 }
<> 144:ef7eb2e8f9f7 918 else
<> 144:ef7eb2e8f9f7 919 {
<> 144:ef7eb2e8f9f7 920 handle->rxBdDirty++;
<> 144:ef7eb2e8f9f7 921 }
<> 144:ef7eb2e8f9f7 922
<> 144:ef7eb2e8f9f7 923 /* Actives the receive buffer descriptor. */
<> 144:ef7eb2e8f9f7 924 base->RDAR = ENET_RDAR_RDAR_MASK;
<> 144:ef7eb2e8f9f7 925
<> 144:ef7eb2e8f9f7 926 } while (handle->rxBdDirty != handle->rxBdCurrent);
<> 144:ef7eb2e8f9f7 927 }
<> 144:ef7eb2e8f9f7 928
<> 144:ef7eb2e8f9f7 929 status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length)
<> 144:ef7eb2e8f9f7 930 {
<> 144:ef7eb2e8f9f7 931 assert(handle);
<> 144:ef7eb2e8f9f7 932 assert(handle->txBdCurrent);
<> 144:ef7eb2e8f9f7 933 assert(data);
<> 144:ef7eb2e8f9f7 934 assert(length <= (ENET_FRAME_MAX_VALNFRAMELEN - 4));
<> 144:ef7eb2e8f9f7 935
<> 144:ef7eb2e8f9f7 936 volatile enet_tx_bd_struct_t *curBuffDescrip = handle->txBdCurrent;
<> 144:ef7eb2e8f9f7 937 uint32_t len = 0;
<> 144:ef7eb2e8f9f7 938 uint32_t sizeleft = 0;
<> 144:ef7eb2e8f9f7 939
<> 144:ef7eb2e8f9f7 940 /* Check if the transmit buffer is ready. */
<> 144:ef7eb2e8f9f7 941 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
<> 144:ef7eb2e8f9f7 942 {
<> 144:ef7eb2e8f9f7 943 return kStatus_ENET_TxFrameBusy;
<> 144:ef7eb2e8f9f7 944 }
<> 144:ef7eb2e8f9f7 945 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 946 bool isPtpEventMessage = false;
<> 144:ef7eb2e8f9f7 947 /* Check PTP message with the PTP header. */
<> 144:ef7eb2e8f9f7 948 isPtpEventMessage = ENET_Ptp1588ParseFrame(data, NULL, true);
<> 144:ef7eb2e8f9f7 949 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 950 /* One transmit buffer is enough for one frame. */
<> 144:ef7eb2e8f9f7 951 if (handle->txBuffSizeAlign >= length)
<> 144:ef7eb2e8f9f7 952 {
<> 144:ef7eb2e8f9f7 953 /* Copy data to the buffer for uDMA transfer. */
<> 144:ef7eb2e8f9f7 954 memcpy(curBuffDescrip->buffer, data, length);
<> 144:ef7eb2e8f9f7 955 /* Set data length. */
<> 144:ef7eb2e8f9f7 956 curBuffDescrip->length = length;
<> 144:ef7eb2e8f9f7 957 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 958 /* For enable the timestamp. */
<> 144:ef7eb2e8f9f7 959 if (isPtpEventMessage)
<> 144:ef7eb2e8f9f7 960 {
<> 144:ef7eb2e8f9f7 961 curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
<> 144:ef7eb2e8f9f7 962 }
<> 144:ef7eb2e8f9f7 963 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 964 curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
<> 144:ef7eb2e8f9f7 965
<> 144:ef7eb2e8f9f7 966 /* Increase the buffer descriptor address. */
<> 144:ef7eb2e8f9f7 967 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 968 {
<> 144:ef7eb2e8f9f7 969 handle->txBdCurrent = handle->txBdBase;
<> 144:ef7eb2e8f9f7 970 }
<> 144:ef7eb2e8f9f7 971 else
<> 144:ef7eb2e8f9f7 972 {
<> 144:ef7eb2e8f9f7 973 handle->txBdCurrent++;
<> 144:ef7eb2e8f9f7 974 }
<> 144:ef7eb2e8f9f7 975
<> 144:ef7eb2e8f9f7 976 /* Active the transmit buffer descriptor. */
<> 144:ef7eb2e8f9f7 977 base->TDAR = ENET_TDAR_TDAR_MASK;
<> 144:ef7eb2e8f9f7 978 return kStatus_Success;
<> 144:ef7eb2e8f9f7 979 }
<> 144:ef7eb2e8f9f7 980 else
<> 144:ef7eb2e8f9f7 981 {
<> 144:ef7eb2e8f9f7 982 /* One frame requires more than one transmit buffers. */
<> 144:ef7eb2e8f9f7 983 do
<> 144:ef7eb2e8f9f7 984 {
<> 144:ef7eb2e8f9f7 985 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 986 /* For enable the timestamp. */
<> 144:ef7eb2e8f9f7 987 if (isPtpEventMessage)
<> 144:ef7eb2e8f9f7 988 {
<> 144:ef7eb2e8f9f7 989 curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
<> 144:ef7eb2e8f9f7 990 }
<> 144:ef7eb2e8f9f7 991 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 992
<> 144:ef7eb2e8f9f7 993 /* Increase the buffer descriptor address. */
<> 144:ef7eb2e8f9f7 994 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 995 {
<> 144:ef7eb2e8f9f7 996 handle->txBdCurrent = handle->txBdBase;
<> 144:ef7eb2e8f9f7 997 }
<> 144:ef7eb2e8f9f7 998 else
<> 144:ef7eb2e8f9f7 999 {
<> 144:ef7eb2e8f9f7 1000 handle->txBdCurrent++;
<> 144:ef7eb2e8f9f7 1001 }
<> 144:ef7eb2e8f9f7 1002 /* update the size left to be transmit. */
<> 144:ef7eb2e8f9f7 1003 sizeleft = length - len;
<> 144:ef7eb2e8f9f7 1004 if (sizeleft > handle->txBuffSizeAlign)
<> 144:ef7eb2e8f9f7 1005 {
<> 144:ef7eb2e8f9f7 1006 /* Data copy. */
<> 144:ef7eb2e8f9f7 1007 memcpy(curBuffDescrip->buffer, data + len, handle->txBuffSizeAlign);
<> 144:ef7eb2e8f9f7 1008 /* Data length update. */
<> 144:ef7eb2e8f9f7 1009 curBuffDescrip->length = handle->txBuffSizeAlign;
<> 144:ef7eb2e8f9f7 1010 len += handle->txBuffSizeAlign;
<> 144:ef7eb2e8f9f7 1011 /* Sets the control flag. */
<> 144:ef7eb2e8f9f7 1012 curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
<> 144:ef7eb2e8f9f7 1013 /* Active the transmit buffer descriptor*/
<> 144:ef7eb2e8f9f7 1014 base->TDAR = ENET_TDAR_TDAR_MASK;
<> 144:ef7eb2e8f9f7 1015 }
<> 144:ef7eb2e8f9f7 1016 else
<> 144:ef7eb2e8f9f7 1017 {
<> 144:ef7eb2e8f9f7 1018 memcpy(curBuffDescrip->buffer, data + len, sizeleft);
<> 144:ef7eb2e8f9f7 1019 curBuffDescrip->length = sizeleft;
<> 144:ef7eb2e8f9f7 1020 /* Set Last buffer wrap flag. */
<> 144:ef7eb2e8f9f7 1021 curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
<> 144:ef7eb2e8f9f7 1022 /* Active the transmit buffer descriptor. */
<> 144:ef7eb2e8f9f7 1023 base->TDAR = ENET_TDAR_TDAR_MASK;
<> 144:ef7eb2e8f9f7 1024 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1025 }
<> 144:ef7eb2e8f9f7 1026
<> 144:ef7eb2e8f9f7 1027 /* Get the current buffer descriptor address. */
<> 144:ef7eb2e8f9f7 1028 curBuffDescrip = handle->txBdCurrent;
<> 144:ef7eb2e8f9f7 1029
<> 144:ef7eb2e8f9f7 1030 } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
<> 144:ef7eb2e8f9f7 1031
<> 144:ef7eb2e8f9f7 1032 return kStatus_ENET_TxFrameFail;
<> 144:ef7eb2e8f9f7 1033 }
<> 144:ef7eb2e8f9f7 1034 }
<> 144:ef7eb2e8f9f7 1035
<> 144:ef7eb2e8f9f7 1036 void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address)
<> 144:ef7eb2e8f9f7 1037 {
<> 144:ef7eb2e8f9f7 1038 assert(address);
<> 144:ef7eb2e8f9f7 1039
<> 144:ef7eb2e8f9f7 1040 uint32_t crc = 0xFFFFFFFFU;
<> 144:ef7eb2e8f9f7 1041 uint32_t count1 = 0;
<> 144:ef7eb2e8f9f7 1042 uint32_t count2 = 0;
<> 144:ef7eb2e8f9f7 1043
<> 144:ef7eb2e8f9f7 1044 /* Calculates the CRC-32 polynomial on the multicast group address. */
<> 144:ef7eb2e8f9f7 1045 for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
<> 144:ef7eb2e8f9f7 1046 {
<> 144:ef7eb2e8f9f7 1047 uint8_t c = address[count1];
<> 144:ef7eb2e8f9f7 1048 for (count2 = 0; count2 < 0x08U; count2++)
<> 144:ef7eb2e8f9f7 1049 {
<> 144:ef7eb2e8f9f7 1050 if ((c ^ crc) & 1U)
<> 144:ef7eb2e8f9f7 1051 {
<> 144:ef7eb2e8f9f7 1052 crc >>= 1U;
<> 144:ef7eb2e8f9f7 1053 c >>= 1U;
<> 144:ef7eb2e8f9f7 1054 crc ^= 0xEDB88320U;
<> 144:ef7eb2e8f9f7 1055 }
<> 144:ef7eb2e8f9f7 1056 else
<> 144:ef7eb2e8f9f7 1057 {
<> 144:ef7eb2e8f9f7 1058 crc >>= 1U;
<> 144:ef7eb2e8f9f7 1059 c >>= 1U;
<> 144:ef7eb2e8f9f7 1060 }
<> 144:ef7eb2e8f9f7 1061 }
<> 144:ef7eb2e8f9f7 1062 }
<> 144:ef7eb2e8f9f7 1063
<> 144:ef7eb2e8f9f7 1064 /* Enable a multicast group address. */
<> 144:ef7eb2e8f9f7 1065 if (!((crc >> 0x1FU) & 1U))
<> 144:ef7eb2e8f9f7 1066 {
<> 144:ef7eb2e8f9f7 1067 base->GALR = 1U << ((crc >> 0x1AU) & 0x1FU);
<> 144:ef7eb2e8f9f7 1068 }
<> 144:ef7eb2e8f9f7 1069 else
<> 144:ef7eb2e8f9f7 1070 {
<> 144:ef7eb2e8f9f7 1071 base->GAUR = 1U << ((crc >> 0x1AU) & 0x1FU);
<> 144:ef7eb2e8f9f7 1072 }
<> 144:ef7eb2e8f9f7 1073 }
<> 144:ef7eb2e8f9f7 1074
<> 144:ef7eb2e8f9f7 1075 void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address)
<> 144:ef7eb2e8f9f7 1076 {
<> 144:ef7eb2e8f9f7 1077 assert(address);
<> 144:ef7eb2e8f9f7 1078
<> 144:ef7eb2e8f9f7 1079 uint32_t crc = 0xFFFFFFFFU;
<> 144:ef7eb2e8f9f7 1080 uint32_t count1 = 0;
<> 144:ef7eb2e8f9f7 1081 uint32_t count2 = 0;
<> 144:ef7eb2e8f9f7 1082
<> 144:ef7eb2e8f9f7 1083 /* Calculates the CRC-32 polynomial on the multicast group address. */
<> 144:ef7eb2e8f9f7 1084 for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
<> 144:ef7eb2e8f9f7 1085 {
<> 144:ef7eb2e8f9f7 1086 uint8_t c = address[count1];
<> 144:ef7eb2e8f9f7 1087 for (count2 = 0; count2 < 0x08U; count2++)
<> 144:ef7eb2e8f9f7 1088 {
<> 144:ef7eb2e8f9f7 1089 if ((c ^ crc) & 1U)
<> 144:ef7eb2e8f9f7 1090 {
<> 144:ef7eb2e8f9f7 1091 crc >>= 1U;
<> 144:ef7eb2e8f9f7 1092 c >>= 1U;
<> 144:ef7eb2e8f9f7 1093 crc ^= 0xEDB88320U;
<> 144:ef7eb2e8f9f7 1094 }
<> 144:ef7eb2e8f9f7 1095 else
<> 144:ef7eb2e8f9f7 1096 {
<> 144:ef7eb2e8f9f7 1097 crc >>= 1U;
<> 144:ef7eb2e8f9f7 1098 c >>= 1U;
<> 144:ef7eb2e8f9f7 1099 }
<> 144:ef7eb2e8f9f7 1100 }
<> 144:ef7eb2e8f9f7 1101 }
<> 144:ef7eb2e8f9f7 1102
<> 144:ef7eb2e8f9f7 1103 /* Set the hash table. */
<> 144:ef7eb2e8f9f7 1104 if (!((crc >> 0x1FU) & 1U))
<> 144:ef7eb2e8f9f7 1105 {
<> 144:ef7eb2e8f9f7 1106 base->GALR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
<> 144:ef7eb2e8f9f7 1107 }
<> 144:ef7eb2e8f9f7 1108 else
<> 144:ef7eb2e8f9f7 1109 {
<> 144:ef7eb2e8f9f7 1110 base->GAUR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
<> 144:ef7eb2e8f9f7 1111 }
<> 144:ef7eb2e8f9f7 1112 }
<> 144:ef7eb2e8f9f7 1113
<> 144:ef7eb2e8f9f7 1114 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 1115 status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic)
<> 144:ef7eb2e8f9f7 1116 {
<> 144:ef7eb2e8f9f7 1117 assert(handle);
<> 144:ef7eb2e8f9f7 1118 assert(eErrorStatic);
<> 144:ef7eb2e8f9f7 1119
<> 144:ef7eb2e8f9f7 1120 uint16_t control = 0;
<> 144:ef7eb2e8f9f7 1121 uint16_t controlExt = 0;
<> 144:ef7eb2e8f9f7 1122
<> 144:ef7eb2e8f9f7 1123 do
<> 144:ef7eb2e8f9f7 1124 {
<> 144:ef7eb2e8f9f7 1125 /* Get the current dirty transmit buffer descriptor. */
<> 144:ef7eb2e8f9f7 1126 control = handle->txBdDirtyStatic->control;
<> 144:ef7eb2e8f9f7 1127 controlExt = handle->txBdDirtyStatic->controlExtend0;
<> 144:ef7eb2e8f9f7 1128 /* Get the control status data, If the buffer descriptor has not been processed break out. */
<> 144:ef7eb2e8f9f7 1129 if (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
<> 144:ef7eb2e8f9f7 1130 {
<> 144:ef7eb2e8f9f7 1131 return kStatus_ENET_TxFrameBusy;
<> 144:ef7eb2e8f9f7 1132 }
<> 144:ef7eb2e8f9f7 1133 /* Increase the transmit dirty static pointer. */
<> 144:ef7eb2e8f9f7 1134 if (handle->txBdDirtyStatic->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 1135 {
<> 144:ef7eb2e8f9f7 1136 handle->txBdDirtyStatic = handle->txBdBase;
<> 144:ef7eb2e8f9f7 1137 }
<> 144:ef7eb2e8f9f7 1138 else
<> 144:ef7eb2e8f9f7 1139 {
<> 144:ef7eb2e8f9f7 1140 handle->txBdDirtyStatic++;
<> 144:ef7eb2e8f9f7 1141 }
<> 144:ef7eb2e8f9f7 1142
<> 144:ef7eb2e8f9f7 1143 /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */
<> 144:ef7eb2e8f9f7 1144 if (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)
<> 144:ef7eb2e8f9f7 1145 {
<> 144:ef7eb2e8f9f7 1146 if (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK)
<> 144:ef7eb2e8f9f7 1147 {
<> 144:ef7eb2e8f9f7 1148 /* Transmit error. */
<> 144:ef7eb2e8f9f7 1149 eErrorStatic->statsTxErr++;
<> 144:ef7eb2e8f9f7 1150 }
<> 144:ef7eb2e8f9f7 1151 if (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK)
<> 144:ef7eb2e8f9f7 1152 {
<> 144:ef7eb2e8f9f7 1153 /* Transmit excess collision error. */
<> 144:ef7eb2e8f9f7 1154 eErrorStatic->statsTxExcessCollisionErr++;
<> 144:ef7eb2e8f9f7 1155 }
<> 144:ef7eb2e8f9f7 1156 if (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK)
<> 144:ef7eb2e8f9f7 1157 {
<> 144:ef7eb2e8f9f7 1158 /* Transmit late collision error. */
<> 144:ef7eb2e8f9f7 1159 eErrorStatic->statsTxLateCollisionErr++;
<> 144:ef7eb2e8f9f7 1160 }
<> 144:ef7eb2e8f9f7 1161 if (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK)
<> 144:ef7eb2e8f9f7 1162 {
<> 144:ef7eb2e8f9f7 1163 /* Transmit under flow error. */
<> 144:ef7eb2e8f9f7 1164 eErrorStatic->statsTxUnderFlowErr++;
<> 144:ef7eb2e8f9f7 1165 }
<> 144:ef7eb2e8f9f7 1166 if (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK)
<> 144:ef7eb2e8f9f7 1167 {
<> 144:ef7eb2e8f9f7 1168 /* Transmit over flow error. */
<> 144:ef7eb2e8f9f7 1169 eErrorStatic->statsTxOverFlowErr++;
<> 144:ef7eb2e8f9f7 1170 }
<> 144:ef7eb2e8f9f7 1171 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1172 }
<> 144:ef7eb2e8f9f7 1173
<> 144:ef7eb2e8f9f7 1174 } while (handle->txBdDirtyStatic != handle->txBdCurrent);
<> 144:ef7eb2e8f9f7 1175
<> 144:ef7eb2e8f9f7 1176 return kStatus_ENET_TxFrameFail;
<> 144:ef7eb2e8f9f7 1177 }
<> 144:ef7eb2e8f9f7 1178
<> 144:ef7eb2e8f9f7 1179 static bool ENET_Ptp1588ParseFrame(uint8_t *data, enet_ptp_time_data_t *ptpTsData, bool isFastEnabled)
<> 144:ef7eb2e8f9f7 1180 {
<> 144:ef7eb2e8f9f7 1181 assert(data);
<> 144:ef7eb2e8f9f7 1182 if (!isFastEnabled)
<> 144:ef7eb2e8f9f7 1183 {
<> 144:ef7eb2e8f9f7 1184 assert(ptpTsData);
<> 144:ef7eb2e8f9f7 1185 }
<> 144:ef7eb2e8f9f7 1186
<> 144:ef7eb2e8f9f7 1187 bool isPtpMsg = false;
<> 144:ef7eb2e8f9f7 1188 uint8_t *buffer = data;
<> 144:ef7eb2e8f9f7 1189 uint16_t ptpType;
<> 144:ef7eb2e8f9f7 1190
<> 144:ef7eb2e8f9f7 1191 /* Check for VLAN frame. */
<> 144:ef7eb2e8f9f7 1192 if (*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET) == ENET_HTONS(ENET_8021QVLAN))
<> 144:ef7eb2e8f9f7 1193 {
<> 144:ef7eb2e8f9f7 1194 buffer += (ENET_FRAME_VLAN_HEADERLEN - ENET_FRAME_HEADERLEN);
<> 144:ef7eb2e8f9f7 1195 }
<> 144:ef7eb2e8f9f7 1196
<> 144:ef7eb2e8f9f7 1197 ptpType = *(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET);
<> 144:ef7eb2e8f9f7 1198 switch (ENET_HTONS(ptpType))
<> 144:ef7eb2e8f9f7 1199 { /* Ethernet layer 2. */
<> 144:ef7eb2e8f9f7 1200 case ENET_ETHERNETL2:
<> 144:ef7eb2e8f9f7 1201 if (*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_MSGTYPE_OFFSET) <= kENET_PtpEventMsgType)
<> 144:ef7eb2e8f9f7 1202 {
<> 144:ef7eb2e8f9f7 1203 isPtpMsg = true;
<> 144:ef7eb2e8f9f7 1204 if (!isFastEnabled)
<> 144:ef7eb2e8f9f7 1205 {
<> 144:ef7eb2e8f9f7 1206 /* It's a ptpv2 message and store the ptp header information. */
<> 144:ef7eb2e8f9f7 1207 ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_VERSION_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1208 ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_MSGTYPE_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1209 ptpTsData->sequenceId = ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_SEQUENCEID_OFFSET));
<> 144:ef7eb2e8f9f7 1210 memcpy((void *)&ptpTsData->sourcePortId[0], (void *)(buffer + ENET_PTP1588_ETHL2_CLOCKID_OFFSET),
<> 144:ef7eb2e8f9f7 1211 kENET_PtpSrcPortIdLen);
<> 144:ef7eb2e8f9f7 1212 }
<> 144:ef7eb2e8f9f7 1213 }
<> 144:ef7eb2e8f9f7 1214 break;
<> 144:ef7eb2e8f9f7 1215 /* IPV4. */
<> 144:ef7eb2e8f9f7 1216 case ENET_IPV4:
<> 144:ef7eb2e8f9f7 1217 if ((*(uint8_t *)(buffer + ENET_PTP1588_IPVERSION_OFFSET) >> 4) == ENET_IPV4VERSION)
<> 144:ef7eb2e8f9f7 1218 {
<> 144:ef7eb2e8f9f7 1219 if (((*(uint16_t *)(buffer + ENET_PTP1588_IPV4_UDP_PORT_OFFSET)) == ENET_HTONS(kENET_PtpEventPort)) &&
<> 144:ef7eb2e8f9f7 1220 (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_PROTOCOL_OFFSET) == ENET_UDPVERSION))
<> 144:ef7eb2e8f9f7 1221 {
<> 144:ef7eb2e8f9f7 1222 /* Set the PTP message flag. */
<> 144:ef7eb2e8f9f7 1223 isPtpMsg = true;
<> 144:ef7eb2e8f9f7 1224 if (!isFastEnabled)
<> 144:ef7eb2e8f9f7 1225 {
<> 144:ef7eb2e8f9f7 1226 /* It's a IPV4 ptp message and store the ptp header information. */
<> 144:ef7eb2e8f9f7 1227 ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_VERSION_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1228 ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_MSGTYPE_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1229 ptpTsData->sequenceId =
<> 144:ef7eb2e8f9f7 1230 ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_IPV4_UDP_SEQUENCEID_OFFSET));
<> 144:ef7eb2e8f9f7 1231 memcpy((void *)&ptpTsData->sourcePortId[0],
<> 144:ef7eb2e8f9f7 1232 (void *)(buffer + ENET_PTP1588_IPV4_UDP_CLKID_OFFSET), kENET_PtpSrcPortIdLen);
<> 144:ef7eb2e8f9f7 1233 }
<> 144:ef7eb2e8f9f7 1234 }
<> 144:ef7eb2e8f9f7 1235 }
<> 144:ef7eb2e8f9f7 1236 break;
<> 144:ef7eb2e8f9f7 1237 /* IPV6. */
<> 144:ef7eb2e8f9f7 1238 case ENET_IPV6:
<> 144:ef7eb2e8f9f7 1239 if ((*(uint8_t *)(buffer + ENET_PTP1588_IPVERSION_OFFSET) >> 4) == ENET_IPV6VERSION)
<> 144:ef7eb2e8f9f7 1240 {
<> 144:ef7eb2e8f9f7 1241 if (((*(uint16_t *)(buffer + ENET_PTP1588_IPV6_UDP_PORT_OFFSET)) == ENET_HTONS(kENET_PtpEventPort)) &&
<> 144:ef7eb2e8f9f7 1242 (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_PROTOCOL_OFFSET) == ENET_UDPVERSION))
<> 144:ef7eb2e8f9f7 1243 {
<> 144:ef7eb2e8f9f7 1244 /* Set the PTP message flag. */
<> 144:ef7eb2e8f9f7 1245 isPtpMsg = true;
<> 144:ef7eb2e8f9f7 1246 if (!isFastEnabled)
<> 144:ef7eb2e8f9f7 1247 {
<> 144:ef7eb2e8f9f7 1248 /* It's a IPV6 ptp message and store the ptp header information. */
<> 144:ef7eb2e8f9f7 1249 ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_VERSION_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1250 ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_MSGTYPE_OFFSET)) & 0x0F;
<> 144:ef7eb2e8f9f7 1251 ptpTsData->sequenceId =
<> 144:ef7eb2e8f9f7 1252 ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_IPV6_UDP_SEQUENCEID_OFFSET));
<> 144:ef7eb2e8f9f7 1253 memcpy((void *)&ptpTsData->sourcePortId[0],
<> 144:ef7eb2e8f9f7 1254 (void *)(buffer + ENET_PTP1588_IPV6_UDP_CLKID_OFFSET), kENET_PtpSrcPortIdLen);
<> 144:ef7eb2e8f9f7 1255 }
<> 144:ef7eb2e8f9f7 1256 }
<> 144:ef7eb2e8f9f7 1257 }
<> 144:ef7eb2e8f9f7 1258 break;
<> 144:ef7eb2e8f9f7 1259 default:
<> 144:ef7eb2e8f9f7 1260 break;
<> 144:ef7eb2e8f9f7 1261 }
<> 144:ef7eb2e8f9f7 1262 return isPtpMsg;
<> 144:ef7eb2e8f9f7 1263 }
<> 144:ef7eb2e8f9f7 1264
<> 144:ef7eb2e8f9f7 1265 void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
<> 144:ef7eb2e8f9f7 1266 {
<> 144:ef7eb2e8f9f7 1267 assert(handle);
<> 144:ef7eb2e8f9f7 1268 assert(ptpConfig);
<> 144:ef7eb2e8f9f7 1269
<> 144:ef7eb2e8f9f7 1270 uint32_t instance = ENET_GetInstance(base);
<> 144:ef7eb2e8f9f7 1271
<> 144:ef7eb2e8f9f7 1272 /* Start the 1588 timer. */
<> 144:ef7eb2e8f9f7 1273 ENET_Ptp1588StartTimer(base, ptpConfig->ptp1588ClockSrc_Hz);
<> 144:ef7eb2e8f9f7 1274
<> 144:ef7eb2e8f9f7 1275 /* Enables the time stamp interrupt for the master clock on a device. */
<> 144:ef7eb2e8f9f7 1276 ENET_EnableInterrupts(base, kENET_TsTimerInterrupt);
<> 144:ef7eb2e8f9f7 1277 EnableIRQ(s_enetTsIrqId[instance]);
<> 144:ef7eb2e8f9f7 1278
<> 144:ef7eb2e8f9f7 1279 /* Enables the transmit interrupt to store the transmit frame time-stamp. */
<> 144:ef7eb2e8f9f7 1280 ENET_EnableInterrupts(base, kENET_TxFrameInterrupt);
<> 144:ef7eb2e8f9f7 1281 EnableIRQ(s_enetTxIrqId[instance]);
<> 144:ef7eb2e8f9f7 1282
<> 144:ef7eb2e8f9f7 1283 /* Setting the receive and transmit state for transaction. */
<> 144:ef7eb2e8f9f7 1284 handle->rxPtpTsDataRing.ptpTsData = ptpConfig->rxPtpTsData;
<> 144:ef7eb2e8f9f7 1285 handle->rxPtpTsDataRing.size = ptpConfig->ptpTsRxBuffNum;
<> 144:ef7eb2e8f9f7 1286 handle->rxPtpTsDataRing.front = 0;
<> 144:ef7eb2e8f9f7 1287 handle->rxPtpTsDataRing.end = 0;
<> 144:ef7eb2e8f9f7 1288 handle->txPtpTsDataRing.ptpTsData = ptpConfig->txPtpTsData;
<> 144:ef7eb2e8f9f7 1289 handle->txPtpTsDataRing.size = ptpConfig->ptpTsTxBuffNum;
<> 144:ef7eb2e8f9f7 1290 handle->txPtpTsDataRing.front = 0;
<> 144:ef7eb2e8f9f7 1291 handle->txPtpTsDataRing.end = 0;
<> 144:ef7eb2e8f9f7 1292 handle->msTimerSecond = 0;
<> 144:ef7eb2e8f9f7 1293 handle->txBdDirtyTime = handle->txBdBase;
<> 144:ef7eb2e8f9f7 1294 handle->txBdDirtyStatic = handle->txBdBase;
<> 144:ef7eb2e8f9f7 1295 }
<> 144:ef7eb2e8f9f7 1296
<> 144:ef7eb2e8f9f7 1297 void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
<> 144:ef7eb2e8f9f7 1298 {
<> 144:ef7eb2e8f9f7 1299 /* Restart PTP 1588 timer, master clock. */
<> 144:ef7eb2e8f9f7 1300 base->ATCR = ENET_ATCR_RESTART_MASK;
<> 144:ef7eb2e8f9f7 1301
<> 144:ef7eb2e8f9f7 1302 /* Initializes PTP 1588 timer. */
<> 144:ef7eb2e8f9f7 1303 base->ATINC = ENET_ATINC_INC(ENET_NANOSECOND_ONE_SECOND / ptpClkSrc);
<> 144:ef7eb2e8f9f7 1304 base->ATPER = ENET_NANOSECOND_ONE_SECOND;
<> 144:ef7eb2e8f9f7 1305 /* Sets periodical event and the event signal output assertion and Actives PTP 1588 timer. */
<> 144:ef7eb2e8f9f7 1306 base->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK | ENET_ATCR_EN_MASK;
<> 144:ef7eb2e8f9f7 1307 }
<> 144:ef7eb2e8f9f7 1308
<> 144:ef7eb2e8f9f7 1309 void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
<> 144:ef7eb2e8f9f7 1310 {
<> 144:ef7eb2e8f9f7 1311 assert(handle);
<> 144:ef7eb2e8f9f7 1312 assert(ptpTime);
<> 144:ef7eb2e8f9f7 1313 uint16_t count = ENET_1588TIME_DELAY_COUNT;
<> 144:ef7eb2e8f9f7 1314 uint32_t primask;
<> 144:ef7eb2e8f9f7 1315
<> 144:ef7eb2e8f9f7 1316 /* Disables the interrupt. */
<> 144:ef7eb2e8f9f7 1317 primask = DisableGlobalIRQ();
<> 144:ef7eb2e8f9f7 1318
<> 144:ef7eb2e8f9f7 1319 /* Get the current PTP time. */
<> 144:ef7eb2e8f9f7 1320 ptpTime->second = handle->msTimerSecond;
<> 144:ef7eb2e8f9f7 1321 /* Get the nanosecond from the master timer. */
<> 144:ef7eb2e8f9f7 1322 base->ATCR |= ENET_ATCR_CAPTURE_MASK;
<> 144:ef7eb2e8f9f7 1323 /* Add at least six clock cycle delay to get accurate time.
<> 144:ef7eb2e8f9f7 1324 It's the requirement when the 1588 clock source is slower
<> 144:ef7eb2e8f9f7 1325 than the register clock.
<> 144:ef7eb2e8f9f7 1326 */
<> 144:ef7eb2e8f9f7 1327 while (count--)
<> 144:ef7eb2e8f9f7 1328 {
<> 144:ef7eb2e8f9f7 1329 __NOP();
<> 144:ef7eb2e8f9f7 1330 }
<> 144:ef7eb2e8f9f7 1331 /* Get the captured time. */
<> 144:ef7eb2e8f9f7 1332 ptpTime->nanosecond = base->ATVR;
<> 144:ef7eb2e8f9f7 1333
<> 144:ef7eb2e8f9f7 1334 /* Enables the interrupt. */
<> 144:ef7eb2e8f9f7 1335 EnableGlobalIRQ(primask);
<> 144:ef7eb2e8f9f7 1336 }
<> 144:ef7eb2e8f9f7 1337
<> 144:ef7eb2e8f9f7 1338 void ENET_Ptp1588SetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
<> 144:ef7eb2e8f9f7 1339 {
<> 144:ef7eb2e8f9f7 1340 assert(handle);
<> 144:ef7eb2e8f9f7 1341 assert(ptpTime);
<> 144:ef7eb2e8f9f7 1342
<> 144:ef7eb2e8f9f7 1343 uint32_t primask;
<> 144:ef7eb2e8f9f7 1344
<> 144:ef7eb2e8f9f7 1345 /* Disables the interrupt. */
<> 144:ef7eb2e8f9f7 1346 primask = DisableGlobalIRQ();
<> 144:ef7eb2e8f9f7 1347
<> 144:ef7eb2e8f9f7 1348 /* Sets PTP timer. */
<> 144:ef7eb2e8f9f7 1349 handle->msTimerSecond = ptpTime->second;
<> 144:ef7eb2e8f9f7 1350 base->ATVR = ptpTime->nanosecond;
<> 144:ef7eb2e8f9f7 1351
<> 144:ef7eb2e8f9f7 1352 /* Enables the interrupt. */
<> 144:ef7eb2e8f9f7 1353 EnableGlobalIRQ(primask);
<> 144:ef7eb2e8f9f7 1354 }
<> 144:ef7eb2e8f9f7 1355
<> 144:ef7eb2e8f9f7 1356 void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod)
<> 144:ef7eb2e8f9f7 1357 {
<> 144:ef7eb2e8f9f7 1358 /* Set correction for PTP timer increment. */
<> 144:ef7eb2e8f9f7 1359 base->ATINC = (base->ATINC & ~ENET_ATINC_INC_CORR_MASK) | (corrIncrease << ENET_ATINC_INC_CORR_SHIFT);
<> 144:ef7eb2e8f9f7 1360 /* Set correction for PTP timer period. */
<> 144:ef7eb2e8f9f7 1361 base->ATCOR = (base->ATCOR & ~ENET_ATCOR_COR_MASK) | (corrPeriod << ENET_ATCOR_COR_SHIFT);
<> 144:ef7eb2e8f9f7 1362 }
<> 144:ef7eb2e8f9f7 1363
<> 144:ef7eb2e8f9f7 1364 static status_t ENET_Ptp1588UpdateTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimeData)
<> 144:ef7eb2e8f9f7 1365 {
<> 144:ef7eb2e8f9f7 1366 assert(ptpTsDataRing);
<> 144:ef7eb2e8f9f7 1367 assert(ptpTsDataRing->ptpTsData);
<> 144:ef7eb2e8f9f7 1368 assert(ptpTimeData);
<> 144:ef7eb2e8f9f7 1369
<> 144:ef7eb2e8f9f7 1370 uint16_t usedBuffer = 0;
<> 144:ef7eb2e8f9f7 1371
<> 144:ef7eb2e8f9f7 1372 /* Check if the buffers ring is full. */
<> 144:ef7eb2e8f9f7 1373 if (ptpTsDataRing->end >= ptpTsDataRing->front)
<> 144:ef7eb2e8f9f7 1374 {
<> 144:ef7eb2e8f9f7 1375 usedBuffer = ptpTsDataRing->end - ptpTsDataRing->front;
<> 144:ef7eb2e8f9f7 1376 }
<> 144:ef7eb2e8f9f7 1377 else
<> 144:ef7eb2e8f9f7 1378 {
<> 144:ef7eb2e8f9f7 1379 usedBuffer = ptpTsDataRing->size - (ptpTsDataRing->front - ptpTsDataRing->end);
<> 144:ef7eb2e8f9f7 1380 }
<> 144:ef7eb2e8f9f7 1381
<> 144:ef7eb2e8f9f7 1382 if (usedBuffer == ptpTsDataRing->size)
<> 144:ef7eb2e8f9f7 1383 {
<> 144:ef7eb2e8f9f7 1384 return kStatus_ENET_PtpTsRingFull;
<> 144:ef7eb2e8f9f7 1385 }
<> 144:ef7eb2e8f9f7 1386
<> 144:ef7eb2e8f9f7 1387 /* Copy the new data into the buffer. */
<> 144:ef7eb2e8f9f7 1388 memcpy((ptpTsDataRing->ptpTsData + ptpTsDataRing->end), ptpTimeData, sizeof(enet_ptp_time_data_t));
<> 144:ef7eb2e8f9f7 1389
<> 144:ef7eb2e8f9f7 1390 /* Increase the buffer pointer to the next empty one. */
<> 144:ef7eb2e8f9f7 1391 ptpTsDataRing->end = (ptpTsDataRing->end + 1) % ptpTsDataRing->size;
<> 144:ef7eb2e8f9f7 1392
<> 144:ef7eb2e8f9f7 1393 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1394 }
<> 144:ef7eb2e8f9f7 1395
<> 144:ef7eb2e8f9f7 1396 static status_t ENET_Ptp1588SearchTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimedata)
<> 144:ef7eb2e8f9f7 1397 {
<> 144:ef7eb2e8f9f7 1398 assert(ptpTsDataRing);
<> 144:ef7eb2e8f9f7 1399 assert(ptpTsDataRing->ptpTsData);
<> 144:ef7eb2e8f9f7 1400 assert(ptpTimedata);
<> 144:ef7eb2e8f9f7 1401
<> 144:ef7eb2e8f9f7 1402 uint32_t index;
<> 144:ef7eb2e8f9f7 1403 uint32_t size;
<> 144:ef7eb2e8f9f7 1404 uint16_t usedBuffer = 0;
<> 144:ef7eb2e8f9f7 1405
<> 144:ef7eb2e8f9f7 1406 /* Check the PTP 1588 timestamp ring. */
<> 144:ef7eb2e8f9f7 1407 if (ptpTsDataRing->front == ptpTsDataRing->end)
<> 144:ef7eb2e8f9f7 1408 {
<> 144:ef7eb2e8f9f7 1409 return kStatus_ENET_PtpTsRingEmpty;
<> 144:ef7eb2e8f9f7 1410 }
<> 144:ef7eb2e8f9f7 1411
<> 144:ef7eb2e8f9f7 1412 /* Search the element in the ring buffer */
<> 144:ef7eb2e8f9f7 1413 index = ptpTsDataRing->front;
<> 144:ef7eb2e8f9f7 1414 size = ptpTsDataRing->size;
<> 144:ef7eb2e8f9f7 1415 while (index != ptpTsDataRing->end)
<> 144:ef7eb2e8f9f7 1416 {
<> 144:ef7eb2e8f9f7 1417 if (((ptpTsDataRing->ptpTsData + index)->sequenceId == ptpTimedata->sequenceId) &&
<> 144:ef7eb2e8f9f7 1418 (!memcmp(((void *)&(ptpTsDataRing->ptpTsData + index)->sourcePortId[0]),
<> 144:ef7eb2e8f9f7 1419 (void *)&ptpTimedata->sourcePortId[0], kENET_PtpSrcPortIdLen)) &&
<> 144:ef7eb2e8f9f7 1420 ((ptpTsDataRing->ptpTsData + index)->version == ptpTimedata->version) &&
<> 144:ef7eb2e8f9f7 1421 ((ptpTsDataRing->ptpTsData + index)->messageType == ptpTimedata->messageType))
<> 144:ef7eb2e8f9f7 1422 {
<> 144:ef7eb2e8f9f7 1423 break;
<> 144:ef7eb2e8f9f7 1424 }
<> 144:ef7eb2e8f9f7 1425
<> 144:ef7eb2e8f9f7 1426 /* Increase the ptp ring index. */
<> 144:ef7eb2e8f9f7 1427 index = (index + 1) % size;
<> 144:ef7eb2e8f9f7 1428 }
<> 144:ef7eb2e8f9f7 1429
<> 144:ef7eb2e8f9f7 1430 if (index == ptpTsDataRing->end)
<> 144:ef7eb2e8f9f7 1431 {
<> 144:ef7eb2e8f9f7 1432 /* Check if buffers is full. */
<> 144:ef7eb2e8f9f7 1433 if (ptpTsDataRing->end >= ptpTsDataRing->front)
<> 144:ef7eb2e8f9f7 1434 {
<> 144:ef7eb2e8f9f7 1435 usedBuffer = ptpTsDataRing->end - ptpTsDataRing->front;
<> 144:ef7eb2e8f9f7 1436 }
<> 144:ef7eb2e8f9f7 1437 else
<> 144:ef7eb2e8f9f7 1438 {
<> 144:ef7eb2e8f9f7 1439 usedBuffer = ptpTsDataRing->size - (ptpTsDataRing->front - ptpTsDataRing->end);
<> 144:ef7eb2e8f9f7 1440 }
<> 144:ef7eb2e8f9f7 1441
<> 144:ef7eb2e8f9f7 1442 if (usedBuffer == ptpTsDataRing->size)
<> 144:ef7eb2e8f9f7 1443 { /* Drop one in the front. */
<> 144:ef7eb2e8f9f7 1444 ptpTsDataRing->front = (ptpTsDataRing->front + 1) % size;
<> 144:ef7eb2e8f9f7 1445 }
<> 144:ef7eb2e8f9f7 1446 return kStatus_ENET_PtpTsRingFull;
<> 144:ef7eb2e8f9f7 1447 }
<> 144:ef7eb2e8f9f7 1448
<> 144:ef7eb2e8f9f7 1449 /* Get the right timestamp of the required ptp messag. */
<> 144:ef7eb2e8f9f7 1450 ptpTimedata->timeStamp.second = (ptpTsDataRing->ptpTsData + index)->timeStamp.second;
<> 144:ef7eb2e8f9f7 1451 ptpTimedata->timeStamp.nanosecond = (ptpTsDataRing->ptpTsData + index)->timeStamp.nanosecond;
<> 144:ef7eb2e8f9f7 1452
<> 144:ef7eb2e8f9f7 1453 /* Increase the index. */
<> 144:ef7eb2e8f9f7 1454 ptpTsDataRing->front = (ptpTsDataRing->front + 1) % size;
<> 144:ef7eb2e8f9f7 1455
<> 144:ef7eb2e8f9f7 1456 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1457 }
<> 144:ef7eb2e8f9f7 1458
<> 144:ef7eb2e8f9f7 1459 static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
<> 144:ef7eb2e8f9f7 1460 {
<> 144:ef7eb2e8f9f7 1461 assert(handle);
<> 144:ef7eb2e8f9f7 1462 assert(ptpTimeData);
<> 144:ef7eb2e8f9f7 1463
<> 144:ef7eb2e8f9f7 1464 bool ptpTimerWrap = false;
<> 144:ef7eb2e8f9f7 1465 enet_ptp_time_t ptpTimer;
<> 144:ef7eb2e8f9f7 1466 uint32_t primask;
<> 144:ef7eb2e8f9f7 1467
<> 144:ef7eb2e8f9f7 1468 /* Disables the interrupt. */
<> 144:ef7eb2e8f9f7 1469 primask = DisableGlobalIRQ();
<> 144:ef7eb2e8f9f7 1470
<> 144:ef7eb2e8f9f7 1471 /* Get current PTP timer nanosecond value. */
<> 144:ef7eb2e8f9f7 1472 ENET_Ptp1588GetTimer(base, handle, &ptpTimer);
<> 144:ef7eb2e8f9f7 1473
<> 144:ef7eb2e8f9f7 1474 /* Get PTP timer wrap event. */
<> 144:ef7eb2e8f9f7 1475 ptpTimerWrap = base->EIR & kENET_TsTimerInterrupt;
<> 144:ef7eb2e8f9f7 1476
<> 144:ef7eb2e8f9f7 1477 /* Get transmit time stamp second. */
<> 144:ef7eb2e8f9f7 1478 if ((ptpTimer.nanosecond > ptpTimeData->timeStamp.nanosecond) ||
<> 144:ef7eb2e8f9f7 1479 ((ptpTimer.nanosecond < ptpTimeData->timeStamp.nanosecond) && ptpTimerWrap))
<> 144:ef7eb2e8f9f7 1480 {
<> 144:ef7eb2e8f9f7 1481 ptpTimeData->timeStamp.second = handle->msTimerSecond;
<> 144:ef7eb2e8f9f7 1482 }
<> 144:ef7eb2e8f9f7 1483 else
<> 144:ef7eb2e8f9f7 1484 {
<> 144:ef7eb2e8f9f7 1485 ptpTimeData->timeStamp.second = handle->msTimerSecond - 1;
<> 144:ef7eb2e8f9f7 1486 }
<> 144:ef7eb2e8f9f7 1487 /* Enable the interrupt. */
<> 144:ef7eb2e8f9f7 1488 EnableGlobalIRQ(primask);
<> 144:ef7eb2e8f9f7 1489
<> 144:ef7eb2e8f9f7 1490 /* Store the timestamp to the receive time stamp ring. */
<> 144:ef7eb2e8f9f7 1491 /* Check if the buffers ring is full. */
<> 144:ef7eb2e8f9f7 1492 return ENET_Ptp1588UpdateTimeRing(&handle->rxPtpTsDataRing, ptpTimeData);
<> 144:ef7eb2e8f9f7 1493 }
<> 144:ef7eb2e8f9f7 1494
<> 144:ef7eb2e8f9f7 1495 static status_t ENET_StoreTxFrameTime(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 1496 {
<> 144:ef7eb2e8f9f7 1497 assert(handle);
<> 144:ef7eb2e8f9f7 1498
<> 144:ef7eb2e8f9f7 1499 uint32_t primask;
<> 144:ef7eb2e8f9f7 1500 bool ptpTimerWrap;
<> 144:ef7eb2e8f9f7 1501 bool isPtpEventMessage = false;
<> 144:ef7eb2e8f9f7 1502 enet_ptp_time_data_t ptpTimeData;
<> 144:ef7eb2e8f9f7 1503 volatile enet_tx_bd_struct_t *curBuffDescrip = handle->txBdDirtyTime;
<> 144:ef7eb2e8f9f7 1504
<> 144:ef7eb2e8f9f7 1505 /* Get the control status data, If the buffer descriptor has not been processed break out. */
<> 144:ef7eb2e8f9f7 1506 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
<> 144:ef7eb2e8f9f7 1507 {
<> 144:ef7eb2e8f9f7 1508 return kStatus_ENET_TxFrameBusy;
<> 144:ef7eb2e8f9f7 1509 }
<> 144:ef7eb2e8f9f7 1510
<> 144:ef7eb2e8f9f7 1511 /* Parse the PTP message. */
<> 144:ef7eb2e8f9f7 1512 isPtpEventMessage = ENET_Ptp1588ParseFrame(curBuffDescrip->buffer, &ptpTimeData, false);
<> 144:ef7eb2e8f9f7 1513 if (isPtpEventMessage)
<> 144:ef7eb2e8f9f7 1514 {
<> 144:ef7eb2e8f9f7 1515 do
<> 144:ef7eb2e8f9f7 1516 {
<> 144:ef7eb2e8f9f7 1517 /* Increase current buffer descriptor to the next one. */
<> 144:ef7eb2e8f9f7 1518 if (handle->txBdDirtyTime->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
<> 144:ef7eb2e8f9f7 1519 {
<> 144:ef7eb2e8f9f7 1520 handle->txBdDirtyTime = handle->txBdBase;
<> 144:ef7eb2e8f9f7 1521 }
<> 144:ef7eb2e8f9f7 1522 else
<> 144:ef7eb2e8f9f7 1523 {
<> 144:ef7eb2e8f9f7 1524 handle->txBdDirtyTime++;
<> 144:ef7eb2e8f9f7 1525 }
<> 144:ef7eb2e8f9f7 1526
<> 144:ef7eb2e8f9f7 1527 /* Do time stamp check on the last buffer descriptor of the frame. */
<> 144:ef7eb2e8f9f7 1528 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)
<> 144:ef7eb2e8f9f7 1529 {
<> 144:ef7eb2e8f9f7 1530 /* Disables the interrupt. */
<> 144:ef7eb2e8f9f7 1531 primask = DisableGlobalIRQ();
<> 144:ef7eb2e8f9f7 1532
<> 144:ef7eb2e8f9f7 1533 /* Get current PTP timer nanosecond value. */
<> 144:ef7eb2e8f9f7 1534 ENET_Ptp1588GetTimer(base, handle, &ptpTimeData.timeStamp);
<> 144:ef7eb2e8f9f7 1535
<> 144:ef7eb2e8f9f7 1536 /* Get PTP timer wrap event. */
<> 144:ef7eb2e8f9f7 1537 ptpTimerWrap = base->EIR & kENET_TsTimerInterrupt;
<> 144:ef7eb2e8f9f7 1538
<> 144:ef7eb2e8f9f7 1539 /* Get transmit time stamp second. */
<> 144:ef7eb2e8f9f7 1540 if ((ptpTimeData.timeStamp.nanosecond > curBuffDescrip->timestamp) ||
<> 144:ef7eb2e8f9f7 1541 ((ptpTimeData.timeStamp.nanosecond < curBuffDescrip->timestamp) && ptpTimerWrap))
<> 144:ef7eb2e8f9f7 1542 {
<> 144:ef7eb2e8f9f7 1543 ptpTimeData.timeStamp.second = handle->msTimerSecond;
<> 144:ef7eb2e8f9f7 1544 }
<> 144:ef7eb2e8f9f7 1545 else
<> 144:ef7eb2e8f9f7 1546 {
<> 144:ef7eb2e8f9f7 1547 ptpTimeData.timeStamp.second = handle->msTimerSecond - 1;
<> 144:ef7eb2e8f9f7 1548 }
<> 144:ef7eb2e8f9f7 1549
<> 144:ef7eb2e8f9f7 1550 /* Enable the interrupt. */
<> 144:ef7eb2e8f9f7 1551 EnableGlobalIRQ(primask);
<> 144:ef7eb2e8f9f7 1552
<> 144:ef7eb2e8f9f7 1553 /* Store the timestamp to the transmit timestamp ring. */
<> 144:ef7eb2e8f9f7 1554 return ENET_Ptp1588UpdateTimeRing(&handle->txPtpTsDataRing, &ptpTimeData);
<> 144:ef7eb2e8f9f7 1555 }
<> 144:ef7eb2e8f9f7 1556
<> 144:ef7eb2e8f9f7 1557 /* Get the current transmit buffer descriptor. */
<> 144:ef7eb2e8f9f7 1558 curBuffDescrip = handle->txBdDirtyTime;
<> 144:ef7eb2e8f9f7 1559
<> 144:ef7eb2e8f9f7 1560 /* Get the control status data, If the buffer descriptor has not been processed break out. */
<> 144:ef7eb2e8f9f7 1561 if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
<> 144:ef7eb2e8f9f7 1562 {
<> 144:ef7eb2e8f9f7 1563 return kStatus_ENET_TxFrameBusy;
<> 144:ef7eb2e8f9f7 1564 }
<> 144:ef7eb2e8f9f7 1565 } while (handle->txBdDirtyTime != handle->txBdCurrent);
<> 144:ef7eb2e8f9f7 1566 return kStatus_ENET_TxFrameFail;
<> 144:ef7eb2e8f9f7 1567 }
<> 144:ef7eb2e8f9f7 1568 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1569 }
<> 144:ef7eb2e8f9f7 1570
<> 144:ef7eb2e8f9f7 1571 status_t ENET_GetTxFrameTime(enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
<> 144:ef7eb2e8f9f7 1572 {
<> 144:ef7eb2e8f9f7 1573 assert(handle);
<> 144:ef7eb2e8f9f7 1574 assert(ptpTimeData);
<> 144:ef7eb2e8f9f7 1575
<> 144:ef7eb2e8f9f7 1576 return ENET_Ptp1588SearchTimeRing(&handle->txPtpTsDataRing, ptpTimeData);
<> 144:ef7eb2e8f9f7 1577 }
<> 144:ef7eb2e8f9f7 1578
<> 144:ef7eb2e8f9f7 1579 status_t ENET_GetRxFrameTime(enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
<> 144:ef7eb2e8f9f7 1580 {
<> 144:ef7eb2e8f9f7 1581 assert(handle);
<> 144:ef7eb2e8f9f7 1582 assert(ptpTimeData);
<> 144:ef7eb2e8f9f7 1583
<> 144:ef7eb2e8f9f7 1584 return ENET_Ptp1588SearchTimeRing(&handle->rxPtpTsDataRing, ptpTimeData);
<> 144:ef7eb2e8f9f7 1585 }
<> 144:ef7eb2e8f9f7 1586
<> 144:ef7eb2e8f9f7 1587 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 1588
<> 144:ef7eb2e8f9f7 1589 void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 1590 {
<> 144:ef7eb2e8f9f7 1591 assert(handle);
<> 144:ef7eb2e8f9f7 1592
<> 144:ef7eb2e8f9f7 1593 /* Check if the transmit interrupt happen. */
<> 144:ef7eb2e8f9f7 1594 if ((kENET_TxByteInterrupt | kENET_TxFrameInterrupt) & base->EIR)
<> 144:ef7eb2e8f9f7 1595 {
<> 144:ef7eb2e8f9f7 1596 /* Clear the transmit interrupt event. */
<> 144:ef7eb2e8f9f7 1597 base->EIR = kENET_TxFrameInterrupt | kENET_TxByteInterrupt;
<> 144:ef7eb2e8f9f7 1598 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 1599 /* Store the transmit timestamp from the buffer descriptor should be done here. */
<> 144:ef7eb2e8f9f7 1600 ENET_StoreTxFrameTime(base, handle);
<> 144:ef7eb2e8f9f7 1601 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 1602 /* Callback function. */
<> 144:ef7eb2e8f9f7 1603 if (handle->callback)
<> 144:ef7eb2e8f9f7 1604 {
<> 144:ef7eb2e8f9f7 1605 handle->callback(base, handle, kENET_TxEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1606 }
<> 144:ef7eb2e8f9f7 1607 }
<> 144:ef7eb2e8f9f7 1608 }
<> 144:ef7eb2e8f9f7 1609
<> 144:ef7eb2e8f9f7 1610 void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 1611 {
<> 144:ef7eb2e8f9f7 1612 assert(handle);
<> 144:ef7eb2e8f9f7 1613
<> 144:ef7eb2e8f9f7 1614 /* Check if the receive interrupt happen. */
<> 144:ef7eb2e8f9f7 1615 if ((kENET_RxByteInterrupt | kENET_RxFrameInterrupt) & base->EIR)
<> 144:ef7eb2e8f9f7 1616 {
<> 144:ef7eb2e8f9f7 1617 /* Clear the transmit interrupt event. */
<> 144:ef7eb2e8f9f7 1618 base->EIR = kENET_RxFrameInterrupt | kENET_RxByteInterrupt;
<> 144:ef7eb2e8f9f7 1619
<> 144:ef7eb2e8f9f7 1620 /* Callback function. */
<> 144:ef7eb2e8f9f7 1621 if (handle->callback)
<> 144:ef7eb2e8f9f7 1622 {
<> 144:ef7eb2e8f9f7 1623 handle->callback(base, handle, kENET_RxEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1624 }
<> 144:ef7eb2e8f9f7 1625 }
<> 144:ef7eb2e8f9f7 1626 }
<> 144:ef7eb2e8f9f7 1627
<> 144:ef7eb2e8f9f7 1628 void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 1629 {
<> 144:ef7eb2e8f9f7 1630 assert(handle);
<> 144:ef7eb2e8f9f7 1631
<> 144:ef7eb2e8f9f7 1632 uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt |
<> 144:ef7eb2e8f9f7 1633 kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt;
<> 144:ef7eb2e8f9f7 1634
<> 144:ef7eb2e8f9f7 1635 /* Check if the PTP time stamp interrupt happen. */
<> 144:ef7eb2e8f9f7 1636 if (kENET_WakeupInterrupt & base->EIR)
<> 144:ef7eb2e8f9f7 1637 {
<> 144:ef7eb2e8f9f7 1638 /* Clear the wakeup interrupt. */
<> 144:ef7eb2e8f9f7 1639 base->EIR = kENET_WakeupInterrupt;
<> 144:ef7eb2e8f9f7 1640 /* wake up and enter the normal mode. */
<> 144:ef7eb2e8f9f7 1641 ENET_EnableSleepMode(base, false);
<> 144:ef7eb2e8f9f7 1642 /* Callback function. */
<> 144:ef7eb2e8f9f7 1643 if (handle->callback)
<> 144:ef7eb2e8f9f7 1644 {
<> 144:ef7eb2e8f9f7 1645 handle->callback(base, handle, kENET_WakeUpEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1646 }
<> 144:ef7eb2e8f9f7 1647 }
<> 144:ef7eb2e8f9f7 1648 else
<> 144:ef7eb2e8f9f7 1649 {
<> 144:ef7eb2e8f9f7 1650 /* Clear the time stamp interrupt. */
<> 144:ef7eb2e8f9f7 1651 errMask &= base->EIR;
<> 144:ef7eb2e8f9f7 1652 base->EIR = errMask;
<> 144:ef7eb2e8f9f7 1653 /* Callback function. */
<> 144:ef7eb2e8f9f7 1654 if (handle->callback)
<> 144:ef7eb2e8f9f7 1655 {
<> 144:ef7eb2e8f9f7 1656 handle->callback(base, handle, kENET_ErrEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1657 }
<> 144:ef7eb2e8f9f7 1658 }
<> 144:ef7eb2e8f9f7 1659 }
<> 144:ef7eb2e8f9f7 1660 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 1661 void ENET_Ptp1588TimerIRQHandler(ENET_Type *base, enet_handle_t *handle)
<> 144:ef7eb2e8f9f7 1662 {
<> 144:ef7eb2e8f9f7 1663 assert(handle);
<> 144:ef7eb2e8f9f7 1664
<> 144:ef7eb2e8f9f7 1665 /* Check if the PTP time stamp interrupt happen. */
<> 144:ef7eb2e8f9f7 1666 if (kENET_TsTimerInterrupt & base->EIR)
<> 144:ef7eb2e8f9f7 1667 {
<> 144:ef7eb2e8f9f7 1668 /* Clear the time stamp interrupt. */
<> 144:ef7eb2e8f9f7 1669 base->EIR = kENET_TsTimerInterrupt;
<> 144:ef7eb2e8f9f7 1670
<> 144:ef7eb2e8f9f7 1671 /* Increase timer second counter. */
<> 144:ef7eb2e8f9f7 1672 handle->msTimerSecond++;
<> 144:ef7eb2e8f9f7 1673
<> 144:ef7eb2e8f9f7 1674 /* Callback function. */
<> 144:ef7eb2e8f9f7 1675 if (handle->callback)
<> 144:ef7eb2e8f9f7 1676 {
<> 144:ef7eb2e8f9f7 1677 handle->callback(base, handle, kENET_TimeStampEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1678 }
<> 144:ef7eb2e8f9f7 1679 }
<> 144:ef7eb2e8f9f7 1680 else
<> 144:ef7eb2e8f9f7 1681 {
<> 144:ef7eb2e8f9f7 1682 /* Clear the time stamp interrupt. */
<> 144:ef7eb2e8f9f7 1683 base->EIR = kENET_TsAvailInterrupt;
<> 144:ef7eb2e8f9f7 1684 /* Callback function. */
<> 144:ef7eb2e8f9f7 1685 if (handle->callback)
<> 144:ef7eb2e8f9f7 1686 {
<> 144:ef7eb2e8f9f7 1687 handle->callback(base, handle, kENET_TimeStampAvailEvent, handle->userData);
<> 144:ef7eb2e8f9f7 1688 }
<> 144:ef7eb2e8f9f7 1689 }
<> 144:ef7eb2e8f9f7 1690 }
<> 144:ef7eb2e8f9f7 1691 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 1692
<> 144:ef7eb2e8f9f7 1693 void ENET_Transmit_IRQHandler(void)
<> 144:ef7eb2e8f9f7 1694 {
<> 144:ef7eb2e8f9f7 1695 ENET_TransmitIRQHandler(ENET, s_ENETHandle[0]);
<> 144:ef7eb2e8f9f7 1696 }
<> 144:ef7eb2e8f9f7 1697
<> 144:ef7eb2e8f9f7 1698 void ENET_Receive_IRQHandler(void)
<> 144:ef7eb2e8f9f7 1699 {
<> 144:ef7eb2e8f9f7 1700 ENET_ReceiveIRQHandler(ENET, s_ENETHandle[0]);
<> 144:ef7eb2e8f9f7 1701 }
<> 144:ef7eb2e8f9f7 1702
<> 144:ef7eb2e8f9f7 1703 void ENET_Error_IRQHandler(void)
<> 144:ef7eb2e8f9f7 1704 {
<> 144:ef7eb2e8f9f7 1705 ENET_ErrorIRQHandler(ENET, s_ENETHandle[0]);
<> 144:ef7eb2e8f9f7 1706 }
<> 144:ef7eb2e8f9f7 1707
<> 144:ef7eb2e8f9f7 1708 void ENET_1588_Timer_IRQHandler(void)
<> 144:ef7eb2e8f9f7 1709 {
<> 144:ef7eb2e8f9f7 1710 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
<> 144:ef7eb2e8f9f7 1711 ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]);
<> 144:ef7eb2e8f9f7 1712 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
<> 144:ef7eb2e8f9f7 1713 }