mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
<>
Date:
Wed Jan 04 16:58:05 2017 +0000
Revision:
154:37f96f9d4de2
Child:
156:95d6b41a828b
This updates the lib to the mbed lib v133

Who changed what in which revision?

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