added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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 }