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