mbed library sources. Supersedes mbed-src.

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

Committer:
Kojto
Date:
Wed Jul 19 17:31:21 2017 +0100
Revision:
169:e3b6fe271b81
Parent:
156:95d6b41a828b
This updates the lib to the mbed lib v 147

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