mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
554:edd95c0879f8
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 554:edd95c0879f8 1 /* mbed Microcontroller Library
mbed_official 554:edd95c0879f8 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 554:edd95c0879f8 3 *
mbed_official 554:edd95c0879f8 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 554:edd95c0879f8 5 * you may not use this file except in compliance with the License.
mbed_official 554:edd95c0879f8 6 * You may obtain a copy of the License at
mbed_official 554:edd95c0879f8 7 *
mbed_official 554:edd95c0879f8 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 554:edd95c0879f8 9 *
mbed_official 554:edd95c0879f8 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 554:edd95c0879f8 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 554:edd95c0879f8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 554:edd95c0879f8 13 * See the License for the specific language governing permissions and
mbed_official 554:edd95c0879f8 14 * limitations under the License.
mbed_official 554:edd95c0879f8 15 */
mbed_official 554:edd95c0879f8 16 #include <string.h>
mbed_official 554:edd95c0879f8 17
mbed_official 554:edd95c0879f8 18 #include "ethernet_api.h"
mbed_official 554:edd95c0879f8 19 #include "cmsis.h"
mbed_official 554:edd95c0879f8 20 #include "mbed_interface.h"
mbed_official 554:edd95c0879f8 21 #include "toolchain.h"
mbed_official 554:edd95c0879f8 22 #include "mbed_error.h"
mbed_official 554:edd95c0879f8 23
mbed_official 554:edd95c0879f8 24 #define NEW_LOGIC 0
mbed_official 554:edd95c0879f8 25 #define NEW_ETH_BUFFER 0
mbed_official 554:edd95c0879f8 26
mbed_official 554:edd95c0879f8 27 #if NEW_ETH_BUFFER
mbed_official 554:edd95c0879f8 28
mbed_official 554:edd95c0879f8 29 #define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets)
mbed_official 554:edd95c0879f8 30 #define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets)
mbed_official 554:edd95c0879f8 31
mbed_official 554:edd95c0879f8 32 #define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size
mbed_official 554:edd95c0879f8 33 #define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length)
mbed_official 554:edd95c0879f8 34
mbed_official 554:edd95c0879f8 35 #else
mbed_official 554:edd95c0879f8 36
mbed_official 554:edd95c0879f8 37 // Memfree calculation:
mbed_official 554:edd95c0879f8 38 // (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) +
mbed_official 554:edd95c0879f8 39 // (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556
mbed_official 554:edd95c0879f8 40 /* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
mbed_official 554:edd95c0879f8 41 #define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */
mbed_official 554:edd95c0879f8 42 #define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */
mbed_official 554:edd95c0879f8 43 //#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */
mbed_official 554:edd95c0879f8 44
mbed_official 554:edd95c0879f8 45 //#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
mbed_official 554:edd95c0879f8 46 #define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */
mbed_official 554:edd95c0879f8 47 #define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */
mbed_official 554:edd95c0879f8 48
mbed_official 554:edd95c0879f8 49 const int ethernet_MTU_SIZE = 0x300;
mbed_official 554:edd95c0879f8 50
mbed_official 554:edd95c0879f8 51 #endif
mbed_official 554:edd95c0879f8 52
mbed_official 554:edd95c0879f8 53 #define ETHERNET_ADDR_SIZE 6
mbed_official 554:edd95c0879f8 54
mbed_official 554:edd95c0879f8 55 PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */
mbed_official 554:edd95c0879f8 56 unsigned int Packet;
mbed_official 554:edd95c0879f8 57 unsigned int Ctrl;
mbed_official 554:edd95c0879f8 58 };
mbed_official 554:edd95c0879f8 59 typedef struct RX_DESC_TypeDef RX_DESC_TypeDef;
mbed_official 554:edd95c0879f8 60
mbed_official 554:edd95c0879f8 61 PACKED struct RX_STAT_TypeDef { /* RX Status struct */
mbed_official 554:edd95c0879f8 62 unsigned int Info;
mbed_official 554:edd95c0879f8 63 unsigned int HashCRC;
mbed_official 554:edd95c0879f8 64 };
mbed_official 554:edd95c0879f8 65 typedef struct RX_STAT_TypeDef RX_STAT_TypeDef;
mbed_official 554:edd95c0879f8 66
mbed_official 554:edd95c0879f8 67 PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */
mbed_official 554:edd95c0879f8 68 unsigned int Packet;
mbed_official 554:edd95c0879f8 69 unsigned int Ctrl;
mbed_official 554:edd95c0879f8 70 };
mbed_official 554:edd95c0879f8 71 typedef struct TX_DESC_TypeDef TX_DESC_TypeDef;
mbed_official 554:edd95c0879f8 72
mbed_official 554:edd95c0879f8 73 PACKED struct TX_STAT_TypeDef { /* TX Status struct */
mbed_official 554:edd95c0879f8 74 unsigned int Info;
mbed_official 554:edd95c0879f8 75 };
mbed_official 554:edd95c0879f8 76 typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
mbed_official 554:edd95c0879f8 77
mbed_official 554:edd95c0879f8 78 /* MAC Configuration Register 1 */
mbed_official 554:edd95c0879f8 79 #define MAC1_REC_EN 0x00000001 /* Receive Enable */
mbed_official 554:edd95c0879f8 80 #define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
mbed_official 554:edd95c0879f8 81 #define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */
mbed_official 554:edd95c0879f8 82 #define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */
mbed_official 554:edd95c0879f8 83 #define MAC1_LOOPB 0x00000010 /* Loop Back Mode */
mbed_official 554:edd95c0879f8 84 #define MAC1_RES_TX 0x00000100 /* Reset TX Logic */
mbed_official 554:edd95c0879f8 85 #define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */
mbed_official 554:edd95c0879f8 86 #define MAC1_RES_RX 0x00000400 /* Reset RX Logic */
mbed_official 554:edd95c0879f8 87 #define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */
mbed_official 554:edd95c0879f8 88 #define MAC1_SIM_RES 0x00004000 /* Simulation Reset */
mbed_official 554:edd95c0879f8 89 #define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */
mbed_official 554:edd95c0879f8 90
mbed_official 554:edd95c0879f8 91 /* MAC Configuration Register 2 */
mbed_official 554:edd95c0879f8 92 #define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */
mbed_official 554:edd95c0879f8 93 #define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */
mbed_official 554:edd95c0879f8 94 #define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */
mbed_official 554:edd95c0879f8 95 #define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */
mbed_official 554:edd95c0879f8 96 #define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */
mbed_official 554:edd95c0879f8 97 #define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */
mbed_official 554:edd95c0879f8 98 #define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */
mbed_official 554:edd95c0879f8 99 #define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */
mbed_official 554:edd95c0879f8 100 #define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */
mbed_official 554:edd95c0879f8 101 #define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */
mbed_official 554:edd95c0879f8 102 #define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */
mbed_official 554:edd95c0879f8 103 #define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */
mbed_official 554:edd95c0879f8 104 #define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */
mbed_official 554:edd95c0879f8 105
mbed_official 554:edd95c0879f8 106 /* Back-to-Back Inter-Packet-Gap Register */
mbed_official 554:edd95c0879f8 107 #define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */
mbed_official 554:edd95c0879f8 108 #define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */
mbed_official 554:edd95c0879f8 109
mbed_official 554:edd95c0879f8 110 /* Non Back-to-Back Inter-Packet-Gap Register */
mbed_official 554:edd95c0879f8 111 #define IPGR_DEF 0x00000012 /* Recommended value */
mbed_official 554:edd95c0879f8 112
mbed_official 554:edd95c0879f8 113 /* Collision Window/Retry Register */
mbed_official 554:edd95c0879f8 114 #define CLRT_DEF 0x0000370F /* Default value */
mbed_official 554:edd95c0879f8 115
mbed_official 554:edd95c0879f8 116 /* PHY Support Register */
mbed_official 554:edd95c0879f8 117 #define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */
mbed_official 554:edd95c0879f8 118 //#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */
mbed_official 554:edd95c0879f8 119 #define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */
mbed_official 554:edd95c0879f8 120
mbed_official 554:edd95c0879f8 121 /* Test Register */
mbed_official 554:edd95c0879f8 122 #define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */
mbed_official 554:edd95c0879f8 123 #define TEST_TST_PAUSE 0x00000002 /* Test Pause */
mbed_official 554:edd95c0879f8 124 #define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */
mbed_official 554:edd95c0879f8 125
mbed_official 554:edd95c0879f8 126 /* MII Management Configuration Register */
mbed_official 554:edd95c0879f8 127 #define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
mbed_official 554:edd95c0879f8 128 #define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
mbed_official 554:edd95c0879f8 129 #define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */
mbed_official 554:edd95c0879f8 130 #define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
mbed_official 554:edd95c0879f8 131
mbed_official 554:edd95c0879f8 132 /* MII Management Command Register */
mbed_official 554:edd95c0879f8 133 #define MCMD_READ 0x00000001 /* MII Read */
mbed_official 554:edd95c0879f8 134 #define MCMD_SCAN 0x00000002 /* MII Scan continuously */
mbed_official 554:edd95c0879f8 135
mbed_official 554:edd95c0879f8 136 #define MII_WR_TOUT 0x00050000 /* MII Write timeout count */
mbed_official 554:edd95c0879f8 137 #define MII_RD_TOUT 0x00050000 /* MII Read timeout count */
mbed_official 554:edd95c0879f8 138
mbed_official 554:edd95c0879f8 139 /* MII Management Address Register */
mbed_official 554:edd95c0879f8 140 #define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */
mbed_official 554:edd95c0879f8 141 #define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */
mbed_official 554:edd95c0879f8 142
mbed_official 554:edd95c0879f8 143 /* MII Management Indicators Register */
mbed_official 554:edd95c0879f8 144 #define MIND_BUSY 0x00000001 /* MII is Busy */
mbed_official 554:edd95c0879f8 145 #define MIND_SCAN 0x00000002 /* MII Scanning in Progress */
mbed_official 554:edd95c0879f8 146 #define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */
mbed_official 554:edd95c0879f8 147 #define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */
mbed_official 554:edd95c0879f8 148
mbed_official 554:edd95c0879f8 149 /* Command Register */
mbed_official 554:edd95c0879f8 150 #define CR_RX_EN 0x00000001 /* Enable Receive */
mbed_official 554:edd95c0879f8 151 #define CR_TX_EN 0x00000002 /* Enable Transmit */
mbed_official 554:edd95c0879f8 152 #define CR_REG_RES 0x00000008 /* Reset Host Registers */
mbed_official 554:edd95c0879f8 153 #define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */
mbed_official 554:edd95c0879f8 154 #define CR_RX_RES 0x00000020 /* Reset Receive Datapath */
mbed_official 554:edd95c0879f8 155 #define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */
mbed_official 554:edd95c0879f8 156 #define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */
mbed_official 554:edd95c0879f8 157 #define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */
mbed_official 554:edd95c0879f8 158 #define CR_RMII 0x00000200 /* Reduced MII Interface */
mbed_official 554:edd95c0879f8 159 #define CR_FULL_DUP 0x00000400 /* Full Duplex */
mbed_official 554:edd95c0879f8 160
mbed_official 554:edd95c0879f8 161 /* Status Register */
mbed_official 554:edd95c0879f8 162 #define SR_RX_EN 0x00000001 /* Enable Receive */
mbed_official 554:edd95c0879f8 163 #define SR_TX_EN 0x00000002 /* Enable Transmit */
mbed_official 554:edd95c0879f8 164
mbed_official 554:edd95c0879f8 165 /* Transmit Status Vector 0 Register */
mbed_official 554:edd95c0879f8 166 #define TSV0_CRC_ERR 0x00000001 /* CRC error */
mbed_official 554:edd95c0879f8 167 #define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */
mbed_official 554:edd95c0879f8 168 #define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */
mbed_official 554:edd95c0879f8 169 #define TSV0_DONE 0x00000008 /* Tramsmission Completed */
mbed_official 554:edd95c0879f8 170 #define TSV0_MCAST 0x00000010 /* Multicast Destination */
mbed_official 554:edd95c0879f8 171 #define TSV0_BCAST 0x00000020 /* Broadcast Destination */
mbed_official 554:edd95c0879f8 172 #define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */
mbed_official 554:edd95c0879f8 173 #define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */
mbed_official 554:edd95c0879f8 174 #define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */
mbed_official 554:edd95c0879f8 175 #define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */
mbed_official 554:edd95c0879f8 176 #define TSV0_GIANT 0x00000400 /* Giant Frame */
mbed_official 554:edd95c0879f8 177 #define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */
mbed_official 554:edd95c0879f8 178 #define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */
mbed_official 554:edd95c0879f8 179 #define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */
mbed_official 554:edd95c0879f8 180 #define TSV0_PAUSE 0x20000000 /* Pause Frame */
mbed_official 554:edd95c0879f8 181 #define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */
mbed_official 554:edd95c0879f8 182 #define TSV0_VLAN 0x80000000 /* VLAN Frame */
mbed_official 554:edd95c0879f8 183
mbed_official 554:edd95c0879f8 184 /* Transmit Status Vector 1 Register */
mbed_official 554:edd95c0879f8 185 #define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */
mbed_official 554:edd95c0879f8 186 #define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */
mbed_official 554:edd95c0879f8 187
mbed_official 554:edd95c0879f8 188 /* Receive Status Vector Register */
mbed_official 554:edd95c0879f8 189 #define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */
mbed_official 554:edd95c0879f8 190 #define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */
mbed_official 554:edd95c0879f8 191 #define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */
mbed_official 554:edd95c0879f8 192 #define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */
mbed_official 554:edd95c0879f8 193 #define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */
mbed_official 554:edd95c0879f8 194 #define RSV_CRC_ERR 0x00100000 /* CRC Error */
mbed_official 554:edd95c0879f8 195 #define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */
mbed_official 554:edd95c0879f8 196 #define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */
mbed_official 554:edd95c0879f8 197 #define RSV_REC_OK 0x00800000 /* Frame Received OK */
mbed_official 554:edd95c0879f8 198 #define RSV_MCAST 0x01000000 /* Multicast Frame */
mbed_official 554:edd95c0879f8 199 #define RSV_BCAST 0x02000000 /* Broadcast Frame */
mbed_official 554:edd95c0879f8 200 #define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */
mbed_official 554:edd95c0879f8 201 #define RSV_CTRL_FRAME 0x08000000 /* Control Frame */
mbed_official 554:edd95c0879f8 202 #define RSV_PAUSE 0x10000000 /* Pause Frame */
mbed_official 554:edd95c0879f8 203 #define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */
mbed_official 554:edd95c0879f8 204 #define RSV_VLAN 0x40000000 /* VLAN Frame */
mbed_official 554:edd95c0879f8 205
mbed_official 554:edd95c0879f8 206 /* Flow Control Counter Register */
mbed_official 554:edd95c0879f8 207 #define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */
mbed_official 554:edd95c0879f8 208 #define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */
mbed_official 554:edd95c0879f8 209
mbed_official 554:edd95c0879f8 210 /* Flow Control Status Register */
mbed_official 554:edd95c0879f8 211 #define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */
mbed_official 554:edd95c0879f8 212
mbed_official 554:edd95c0879f8 213 /* Receive Filter Control Register */
mbed_official 554:edd95c0879f8 214 #define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */
mbed_official 554:edd95c0879f8 215 #define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */
mbed_official 554:edd95c0879f8 216 #define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */
mbed_official 554:edd95c0879f8 217 #define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */
mbed_official 554:edd95c0879f8 218 #define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/
mbed_official 554:edd95c0879f8 219 #define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */
mbed_official 554:edd95c0879f8 220 #define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */
mbed_official 554:edd95c0879f8 221 #define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */
mbed_official 554:edd95c0879f8 222
mbed_official 554:edd95c0879f8 223 /* Receive Filter WoL Status/Clear Registers */
mbed_official 554:edd95c0879f8 224 #define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */
mbed_official 554:edd95c0879f8 225 #define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */
mbed_official 554:edd95c0879f8 226 #define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */
mbed_official 554:edd95c0879f8 227 #define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */
mbed_official 554:edd95c0879f8 228 #define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */
mbed_official 554:edd95c0879f8 229 #define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */
mbed_official 554:edd95c0879f8 230 #define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */
mbed_official 554:edd95c0879f8 231 #define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */
mbed_official 554:edd95c0879f8 232
mbed_official 554:edd95c0879f8 233 /* Interrupt Status/Enable/Clear/Set Registers */
mbed_official 554:edd95c0879f8 234 #define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */
mbed_official 554:edd95c0879f8 235 #define INT_RX_ERR 0x00000002 /* Receive Error */
mbed_official 554:edd95c0879f8 236 #define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */
mbed_official 554:edd95c0879f8 237 #define INT_RX_DONE 0x00000008 /* Receive Done */
mbed_official 554:edd95c0879f8 238 #define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */
mbed_official 554:edd95c0879f8 239 #define INT_TX_ERR 0x00000020 /* Transmit Error */
mbed_official 554:edd95c0879f8 240 #define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */
mbed_official 554:edd95c0879f8 241 #define INT_TX_DONE 0x00000080 /* Transmit Done */
mbed_official 554:edd95c0879f8 242 #define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */
mbed_official 554:edd95c0879f8 243 #define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */
mbed_official 554:edd95c0879f8 244
mbed_official 554:edd95c0879f8 245 /* Power Down Register */
mbed_official 554:edd95c0879f8 246 #define PD_POWER_DOWN 0x80000000 /* Power Down MAC */
mbed_official 554:edd95c0879f8 247
mbed_official 554:edd95c0879f8 248 /* RX Descriptor Control Word */
mbed_official 554:edd95c0879f8 249 #define RCTRL_SIZE 0x000007FF /* Buffer size mask */
mbed_official 554:edd95c0879f8 250 #define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */
mbed_official 554:edd95c0879f8 251
mbed_official 554:edd95c0879f8 252 /* RX Status Hash CRC Word */
mbed_official 554:edd95c0879f8 253 #define RHASH_SA 0x000001FF /* Hash CRC for Source Address */
mbed_official 554:edd95c0879f8 254 #define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */
mbed_official 554:edd95c0879f8 255
mbed_official 554:edd95c0879f8 256 /* RX Status Information Word */
mbed_official 554:edd95c0879f8 257 #define RINFO_SIZE 0x000007FF /* Data size in bytes */
mbed_official 554:edd95c0879f8 258 #define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */
mbed_official 554:edd95c0879f8 259 #define RINFO_VLAN 0x00080000 /* VLAN Frame */
mbed_official 554:edd95c0879f8 260 #define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */
mbed_official 554:edd95c0879f8 261 #define RINFO_MCAST 0x00200000 /* Multicast Frame */
mbed_official 554:edd95c0879f8 262 #define RINFO_BCAST 0x00400000 /* Broadcast Frame */
mbed_official 554:edd95c0879f8 263 #define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */
mbed_official 554:edd95c0879f8 264 #define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */
mbed_official 554:edd95c0879f8 265 #define RINFO_LEN_ERR 0x02000000 /* Length Error */
mbed_official 554:edd95c0879f8 266 #define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */
mbed_official 554:edd95c0879f8 267 #define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */
mbed_official 554:edd95c0879f8 268 #define RINFO_OVERRUN 0x10000000 /* Receive overrun */
mbed_official 554:edd95c0879f8 269 #define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */
mbed_official 554:edd95c0879f8 270 #define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */
mbed_official 554:edd95c0879f8 271 #define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
mbed_official 554:edd95c0879f8 272
mbed_official 554:edd95c0879f8 273 //#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
mbed_official 554:edd95c0879f8 274 #define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \
mbed_official 554:edd95c0879f8 275 RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
mbed_official 554:edd95c0879f8 276
mbed_official 554:edd95c0879f8 277
mbed_official 554:edd95c0879f8 278 /* TX Descriptor Control Word */
mbed_official 554:edd95c0879f8 279 #define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */
mbed_official 554:edd95c0879f8 280 #define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */
mbed_official 554:edd95c0879f8 281 #define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */
mbed_official 554:edd95c0879f8 282 #define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */
mbed_official 554:edd95c0879f8 283 #define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */
mbed_official 554:edd95c0879f8 284 #define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */
mbed_official 554:edd95c0879f8 285 #define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */
mbed_official 554:edd95c0879f8 286
mbed_official 554:edd95c0879f8 287 /* TX Status Information Word */
mbed_official 554:edd95c0879f8 288 #define TINFO_COL_CNT 0x01E00000 /* Collision Count */
mbed_official 554:edd95c0879f8 289 #define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */
mbed_official 554:edd95c0879f8 290 #define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */
mbed_official 554:edd95c0879f8 291 #define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */
mbed_official 554:edd95c0879f8 292 #define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */
mbed_official 554:edd95c0879f8 293 #define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */
mbed_official 554:edd95c0879f8 294 #define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */
mbed_official 554:edd95c0879f8 295 #define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
mbed_official 554:edd95c0879f8 296
mbed_official 554:edd95c0879f8 297 /* ENET Device Revision ID */
mbed_official 554:edd95c0879f8 298 #define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */
mbed_official 554:edd95c0879f8 299
mbed_official 554:edd95c0879f8 300 /* DP83848C PHY Registers */
mbed_official 554:edd95c0879f8 301 #define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */
mbed_official 554:edd95c0879f8 302 #define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */
mbed_official 554:edd95c0879f8 303 #define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */
mbed_official 554:edd95c0879f8 304 #define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */
mbed_official 554:edd95c0879f8 305 #define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */
mbed_official 554:edd95c0879f8 306 #define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */
mbed_official 554:edd95c0879f8 307 #define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */
mbed_official 554:edd95c0879f8 308 #define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */
mbed_official 554:edd95c0879f8 309
mbed_official 554:edd95c0879f8 310 /* PHY Extended Registers */
mbed_official 554:edd95c0879f8 311 #define PHY_REG_STS 0x10 /* Status Register */
mbed_official 554:edd95c0879f8 312 #define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */
mbed_official 554:edd95c0879f8 313 #define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */
mbed_official 554:edd95c0879f8 314 #define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */
mbed_official 554:edd95c0879f8 315 #define PHY_REG_RECR 0x15 /* Receive Error Counter */
mbed_official 554:edd95c0879f8 316 #define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */
mbed_official 554:edd95c0879f8 317 #define PHY_REG_RBR 0x17 /* RMII and Bypass Register */
mbed_official 554:edd95c0879f8 318 #define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */
mbed_official 554:edd95c0879f8 319 #define PHY_REG_PHYCR 0x19 /* PHY Control Register */
mbed_official 554:edd95c0879f8 320 #define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */
mbed_official 554:edd95c0879f8 321 #define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */
mbed_official 554:edd95c0879f8 322 #define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */
mbed_official 554:edd95c0879f8 323
mbed_official 554:edd95c0879f8 324 #define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */
mbed_official 554:edd95c0879f8 325
mbed_official 554:edd95c0879f8 326 #define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */
mbed_official 554:edd95c0879f8 327 #define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */
mbed_official 554:edd95c0879f8 328 #define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */
mbed_official 554:edd95c0879f8 329 #define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */
mbed_official 554:edd95c0879f8 330 #define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
mbed_official 554:edd95c0879f8 331
mbed_official 554:edd95c0879f8 332 #define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */
mbed_official 554:edd95c0879f8 333 #define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */
mbed_official 554:edd95c0879f8 334
mbed_official 554:edd95c0879f8 335 #define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */
mbed_official 554:edd95c0879f8 336
mbed_official 554:edd95c0879f8 337 #define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */
mbed_official 554:edd95c0879f8 338 #define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */
mbed_official 554:edd95c0879f8 339 #define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */
mbed_official 554:edd95c0879f8 340
mbed_official 554:edd95c0879f8 341 #define PHY_BMCR_RESET 0x8000 /* PHY Reset */
mbed_official 554:edd95c0879f8 342
mbed_official 554:edd95c0879f8 343 #define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */
mbed_official 554:edd95c0879f8 344
mbed_official 554:edd95c0879f8 345 #define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */
mbed_official 554:edd95c0879f8 346 #define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */
mbed_official 554:edd95c0879f8 347
mbed_official 554:edd95c0879f8 348
mbed_official 554:edd95c0879f8 349 static int phy_read(unsigned int PhyReg);
mbed_official 554:edd95c0879f8 350 static int phy_write(unsigned int PhyReg, unsigned short Data);
mbed_official 554:edd95c0879f8 351
mbed_official 554:edd95c0879f8 352 static void txdscr_init(void);
mbed_official 554:edd95c0879f8 353 static void rxdscr_init(void);
mbed_official 554:edd95c0879f8 354
mbed_official 554:edd95c0879f8 355 #if defined (__ICCARM__)
mbed_official 554:edd95c0879f8 356 # define AHBSRAM1
mbed_official 554:edd95c0879f8 357 #elif defined(TOOLCHAIN_GCC_CR)
mbed_official 554:edd95c0879f8 358 # define AHBSRAM1 __attribute__((section(".data.$RamPeriph32")))
mbed_official 554:edd95c0879f8 359 #else
mbed_official 554:edd95c0879f8 360 # define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned))
mbed_official 554:edd95c0879f8 361 #endif
mbed_official 554:edd95c0879f8 362
mbed_official 554:edd95c0879f8 363 AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE];
mbed_official 554:edd95c0879f8 364 AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE];
mbed_official 554:edd95c0879f8 365 AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG];
mbed_official 554:edd95c0879f8 366 AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG];
mbed_official 554:edd95c0879f8 367 AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG];
mbed_official 554:edd95c0879f8 368 AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG];
mbed_official 554:edd95c0879f8 369
mbed_official 554:edd95c0879f8 370
mbed_official 554:edd95c0879f8 371 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 372 static int rx_consume_offset = -1;
mbed_official 554:edd95c0879f8 373 static int tx_produce_offset = -1;
mbed_official 554:edd95c0879f8 374 #else
mbed_official 554:edd95c0879f8 375 static int send_doff = 0;
mbed_official 554:edd95c0879f8 376 static int send_idx = -1;
mbed_official 554:edd95c0879f8 377 static int send_size = 0;
mbed_official 554:edd95c0879f8 378
mbed_official 554:edd95c0879f8 379 static int receive_soff = 0;
mbed_official 554:edd95c0879f8 380 static int receive_idx = -1;
mbed_official 554:edd95c0879f8 381 #endif
mbed_official 554:edd95c0879f8 382
mbed_official 554:edd95c0879f8 383 static uint32_t phy_id = 0;
mbed_official 554:edd95c0879f8 384
mbed_official 554:edd95c0879f8 385 static inline int rinc(int idx, int mod) {
mbed_official 554:edd95c0879f8 386 ++idx;
mbed_official 554:edd95c0879f8 387 idx %= mod;
mbed_official 554:edd95c0879f8 388 return idx;
mbed_official 554:edd95c0879f8 389 }
mbed_official 554:edd95c0879f8 390
mbed_official 554:edd95c0879f8 391 //extern unsigned int SystemFrequency;
mbed_official 554:edd95c0879f8 392 static inline unsigned int clockselect() {
mbed_official 554:edd95c0879f8 393 if(SystemCoreClock < 10000000) {
mbed_official 554:edd95c0879f8 394 return 1;
mbed_official 554:edd95c0879f8 395 } else if(SystemCoreClock < 15000000) {
mbed_official 554:edd95c0879f8 396 return 2;
mbed_official 554:edd95c0879f8 397 } else if(SystemCoreClock < 20000000) {
mbed_official 554:edd95c0879f8 398 return 3;
mbed_official 554:edd95c0879f8 399 } else if(SystemCoreClock < 25000000) {
mbed_official 554:edd95c0879f8 400 return 4;
mbed_official 554:edd95c0879f8 401 } else if(SystemCoreClock < 35000000) {
mbed_official 554:edd95c0879f8 402 return 5;
mbed_official 554:edd95c0879f8 403 } else if(SystemCoreClock < 50000000) {
mbed_official 554:edd95c0879f8 404 return 6;
mbed_official 554:edd95c0879f8 405 } else if(SystemCoreClock < 70000000) {
mbed_official 554:edd95c0879f8 406 return 7;
mbed_official 554:edd95c0879f8 407 } else if(SystemCoreClock < 80000000) {
mbed_official 554:edd95c0879f8 408 return 8;
mbed_official 554:edd95c0879f8 409 } else if(SystemCoreClock < 90000000) {
mbed_official 554:edd95c0879f8 410 return 9;
mbed_official 554:edd95c0879f8 411 } else if(SystemCoreClock < 100000000) {
mbed_official 554:edd95c0879f8 412 return 10;
mbed_official 554:edd95c0879f8 413 } else if(SystemCoreClock < 120000000) {
mbed_official 554:edd95c0879f8 414 return 11;
mbed_official 554:edd95c0879f8 415 } else if(SystemCoreClock < 130000000) {
mbed_official 554:edd95c0879f8 416 return 12;
mbed_official 554:edd95c0879f8 417 } else if(SystemCoreClock < 140000000) {
mbed_official 554:edd95c0879f8 418 return 13;
mbed_official 554:edd95c0879f8 419 } else if(SystemCoreClock < 150000000) {
mbed_official 554:edd95c0879f8 420 return 15;
mbed_official 554:edd95c0879f8 421 } else if(SystemCoreClock < 160000000) {
mbed_official 554:edd95c0879f8 422 return 16;
mbed_official 554:edd95c0879f8 423 } else {
mbed_official 554:edd95c0879f8 424 return 0;
mbed_official 554:edd95c0879f8 425 }
mbed_official 554:edd95c0879f8 426 }
mbed_official 554:edd95c0879f8 427
mbed_official 554:edd95c0879f8 428 #ifndef min
mbed_official 554:edd95c0879f8 429 #define min(x, y) (((x)<(y))?(x):(y))
mbed_official 554:edd95c0879f8 430 #endif
mbed_official 554:edd95c0879f8 431
mbed_official 554:edd95c0879f8 432 /*----------------------------------------------------------------------------
mbed_official 554:edd95c0879f8 433 Ethernet Device initialize
mbed_official 554:edd95c0879f8 434 *----------------------------------------------------------------------------*/
mbed_official 554:edd95c0879f8 435 int ethernet_init() {
mbed_official 554:edd95c0879f8 436 int regv, tout;
mbed_official 554:edd95c0879f8 437 char mac[ETHERNET_ADDR_SIZE];
mbed_official 554:edd95c0879f8 438 unsigned int clock = clockselect();
mbed_official 554:edd95c0879f8 439
mbed_official 554:edd95c0879f8 440 LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */
mbed_official 554:edd95c0879f8 441
mbed_official 554:edd95c0879f8 442 LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */
mbed_official 554:edd95c0879f8 443 LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
mbed_official 554:edd95c0879f8 444
mbed_official 554:edd95c0879f8 445 /* Reset all EMAC internal modules. */
mbed_official 554:edd95c0879f8 446 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX |
mbed_official 554:edd95c0879f8 447 MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
mbed_official 554:edd95c0879f8 448 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
mbed_official 554:edd95c0879f8 449
mbed_official 554:edd95c0879f8 450 for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */
mbed_official 554:edd95c0879f8 451
mbed_official 554:edd95c0879f8 452 LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */
mbed_official 554:edd95c0879f8 453 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
mbed_official 554:edd95c0879f8 454 LPC_EMAC->MAXF = ETH_MAX_FLEN;
mbed_official 554:edd95c0879f8 455 LPC_EMAC->CLRT = CLRT_DEF;
mbed_official 554:edd95c0879f8 456 LPC_EMAC->IPGR = IPGR_DEF;
mbed_official 554:edd95c0879f8 457
mbed_official 554:edd95c0879f8 458 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */
mbed_official 554:edd95c0879f8 459
mbed_official 554:edd95c0879f8 460 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */
mbed_official 554:edd95c0879f8 461 LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */
mbed_official 554:edd95c0879f8 462
mbed_official 554:edd95c0879f8 463 for(tout = 100; tout; tout--) __NOP(); /* A short delay */
mbed_official 554:edd95c0879f8 464
mbed_official 554:edd95c0879f8 465 LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL;
mbed_official 554:edd95c0879f8 466 LPC_EMAC->MCMD = 0;
mbed_official 554:edd95c0879f8 467
mbed_official 554:edd95c0879f8 468 LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */
mbed_official 554:edd95c0879f8 469
mbed_official 554:edd95c0879f8 470 for (tout = 100; tout; tout--) __NOP(); /* A short delay */
mbed_official 554:edd95c0879f8 471
mbed_official 554:edd95c0879f8 472 LPC_EMAC->SUPP = 0;
mbed_official 554:edd95c0879f8 473
mbed_official 554:edd95c0879f8 474 phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */
mbed_official 554:edd95c0879f8 475 for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */
mbed_official 554:edd95c0879f8 476 regv = phy_read(PHY_REG_BMCR);
mbed_official 554:edd95c0879f8 477 if(regv < 0 || tout == 0) {
mbed_official 554:edd95c0879f8 478 return -1; /* Error */
mbed_official 554:edd95c0879f8 479 }
mbed_official 554:edd95c0879f8 480 if(!(regv & PHY_BMCR_RESET)) {
mbed_official 554:edd95c0879f8 481 break; /* Reset complete. */
mbed_official 554:edd95c0879f8 482 }
mbed_official 554:edd95c0879f8 483 }
mbed_official 554:edd95c0879f8 484
mbed_official 554:edd95c0879f8 485 phy_id = (phy_read(PHY_REG_IDR1) << 16);
mbed_official 554:edd95c0879f8 486 phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0);
mbed_official 554:edd95c0879f8 487
mbed_official 554:edd95c0879f8 488 if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) {
mbed_official 554:edd95c0879f8 489 error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id);
mbed_official 554:edd95c0879f8 490 }
mbed_official 554:edd95c0879f8 491
mbed_official 554:edd95c0879f8 492 ethernet_set_link(-1, 0);
mbed_official 554:edd95c0879f8 493
mbed_official 554:edd95c0879f8 494 /* Set the Ethernet MAC Address registers */
mbed_official 554:edd95c0879f8 495 ethernet_address(mac);
mbed_official 554:edd95c0879f8 496 LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4];
mbed_official 554:edd95c0879f8 497 LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2];
mbed_official 554:edd95c0879f8 498 LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0];
mbed_official 554:edd95c0879f8 499
mbed_official 554:edd95c0879f8 500 txdscr_init(); /* initialize DMA TX Descriptor */
mbed_official 554:edd95c0879f8 501 rxdscr_init(); /* initialize DMA RX Descriptor */
mbed_official 554:edd95c0879f8 502
mbed_official 554:edd95c0879f8 503 LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
mbed_official 554:edd95c0879f8 504 /* Receive Broadcast, Perfect Match Packets */
mbed_official 554:edd95c0879f8 505
mbed_official 554:edd95c0879f8 506 LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */
mbed_official 554:edd95c0879f8 507 LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */
mbed_official 554:edd95c0879f8 508
mbed_official 554:edd95c0879f8 509
mbed_official 554:edd95c0879f8 510 LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */
mbed_official 554:edd95c0879f8 511 LPC_EMAC->MAC1 |= MAC1_REC_EN;
mbed_official 554:edd95c0879f8 512
mbed_official 554:edd95c0879f8 513 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 514 rx_consume_offset = -1;
mbed_official 554:edd95c0879f8 515 tx_produce_offset = -1;
mbed_official 554:edd95c0879f8 516 #else
mbed_official 554:edd95c0879f8 517 send_doff = 0;
mbed_official 554:edd95c0879f8 518 send_idx = -1;
mbed_official 554:edd95c0879f8 519 send_size = 0;
mbed_official 554:edd95c0879f8 520
mbed_official 554:edd95c0879f8 521 receive_soff = 0;
mbed_official 554:edd95c0879f8 522 receive_idx = -1;
mbed_official 554:edd95c0879f8 523 #endif
mbed_official 554:edd95c0879f8 524
mbed_official 554:edd95c0879f8 525 return 0;
mbed_official 554:edd95c0879f8 526 }
mbed_official 554:edd95c0879f8 527
mbed_official 554:edd95c0879f8 528 /*----------------------------------------------------------------------------
mbed_official 554:edd95c0879f8 529 Ethernet Device Uninitialize
mbed_official 554:edd95c0879f8 530 *----------------------------------------------------------------------------*/
mbed_official 554:edd95c0879f8 531 void ethernet_free() {
mbed_official 554:edd95c0879f8 532 LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE);
mbed_official 554:edd95c0879f8 533 LPC_EMAC->IntClear = 0xFFFF;
mbed_official 554:edd95c0879f8 534
mbed_official 554:edd95c0879f8 535 LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */
mbed_official 554:edd95c0879f8 536
mbed_official 554:edd95c0879f8 537 LPC_PINCON->PINSEL2 &= ~0x50150105; /* Disable P1 ethernet pins. */
mbed_official 554:edd95c0879f8 538 LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000000;
mbed_official 554:edd95c0879f8 539 }
mbed_official 554:edd95c0879f8 540
mbed_official 554:edd95c0879f8 541 // if(TxProduceIndex == TxConsumeIndex) buffer array is empty
mbed_official 554:edd95c0879f8 542 // if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill
mbed_official 554:edd95c0879f8 543 // TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment
mbed_official 554:edd95c0879f8 544 // TxConsumeIndex - The buffer that will/is beign sent by hardware
mbed_official 554:edd95c0879f8 545
mbed_official 554:edd95c0879f8 546 int ethernet_write(const char *data, int slen) {
mbed_official 554:edd95c0879f8 547
mbed_official 554:edd95c0879f8 548 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 549
mbed_official 554:edd95c0879f8 550 if(tx_produce_offset < 0) { // mark as active if not already
mbed_official 554:edd95c0879f8 551 tx_produce_offset = 0;
mbed_official 554:edd95c0879f8 552 }
mbed_official 554:edd95c0879f8 553
mbed_official 554:edd95c0879f8 554 int index = LPC_EMAC->TxProduceIndex;
mbed_official 554:edd95c0879f8 555
mbed_official 554:edd95c0879f8 556 int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum
mbed_official 554:edd95c0879f8 557 int requested = slen;
mbed_official 554:edd95c0879f8 558 int ncopy = min(remaining, requested);
mbed_official 554:edd95c0879f8 559
mbed_official 554:edd95c0879f8 560 void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset);
mbed_official 554:edd95c0879f8 561 void *psrc = (void *)(data);
mbed_official 554:edd95c0879f8 562
mbed_official 554:edd95c0879f8 563 if(ncopy > 0 ){
mbed_official 554:edd95c0879f8 564 if(data != NULL) {
mbed_official 554:edd95c0879f8 565 memcpy(pdst, psrc, ncopy);
mbed_official 554:edd95c0879f8 566 } else {
mbed_official 554:edd95c0879f8 567 memset(pdst, 0, ncopy);
mbed_official 554:edd95c0879f8 568 }
mbed_official 554:edd95c0879f8 569 }
mbed_official 554:edd95c0879f8 570
mbed_official 554:edd95c0879f8 571 tx_produce_offset += ncopy;
mbed_official 554:edd95c0879f8 572
mbed_official 554:edd95c0879f8 573 return ncopy;
mbed_official 554:edd95c0879f8 574
mbed_official 554:edd95c0879f8 575 #else
mbed_official 554:edd95c0879f8 576 void *pdst, *psrc;
mbed_official 554:edd95c0879f8 577 const int dlen = ETH_FRAG_SIZE;
mbed_official 554:edd95c0879f8 578 int copy = 0;
mbed_official 554:edd95c0879f8 579 int soff = 0;
mbed_official 554:edd95c0879f8 580
mbed_official 554:edd95c0879f8 581 if(send_idx == -1) {
mbed_official 554:edd95c0879f8 582 send_idx = LPC_EMAC->TxProduceIndex;
mbed_official 554:edd95c0879f8 583 }
mbed_official 554:edd95c0879f8 584
mbed_official 554:edd95c0879f8 585 if(slen + send_doff > ethernet_MTU_SIZE) {
mbed_official 554:edd95c0879f8 586 return -1;
mbed_official 554:edd95c0879f8 587 }
mbed_official 554:edd95c0879f8 588
mbed_official 554:edd95c0879f8 589 do {
mbed_official 554:edd95c0879f8 590 copy = min(slen - soff, dlen - send_doff);
mbed_official 554:edd95c0879f8 591 pdst = (void *)(txdesc[send_idx].Packet + send_doff);
mbed_official 554:edd95c0879f8 592 psrc = (void *)(data + soff);
mbed_official 554:edd95c0879f8 593 if(send_doff + copy > ETH_FRAG_SIZE) {
mbed_official 554:edd95c0879f8 594 txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT);
mbed_official 554:edd95c0879f8 595 send_idx = rinc(send_idx, NUM_TX_FRAG);
mbed_official 554:edd95c0879f8 596 send_doff = 0;
mbed_official 554:edd95c0879f8 597 }
mbed_official 554:edd95c0879f8 598
mbed_official 554:edd95c0879f8 599 if(data != NULL) {
mbed_official 554:edd95c0879f8 600 memcpy(pdst, psrc, copy);
mbed_official 554:edd95c0879f8 601 } else {
mbed_official 554:edd95c0879f8 602 memset(pdst, 0, copy);
mbed_official 554:edd95c0879f8 603 }
mbed_official 554:edd95c0879f8 604
mbed_official 554:edd95c0879f8 605 soff += copy;
mbed_official 554:edd95c0879f8 606 send_doff += copy;
mbed_official 554:edd95c0879f8 607 send_size += copy;
mbed_official 554:edd95c0879f8 608 } while(soff != slen);
mbed_official 554:edd95c0879f8 609
mbed_official 554:edd95c0879f8 610 return soff;
mbed_official 554:edd95c0879f8 611 #endif
mbed_official 554:edd95c0879f8 612 }
mbed_official 554:edd95c0879f8 613
mbed_official 554:edd95c0879f8 614 int ethernet_send() {
mbed_official 554:edd95c0879f8 615
mbed_official 554:edd95c0879f8 616 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 617 if(tx_produce_offset < 0) { // no buffer active
mbed_official 554:edd95c0879f8 618 return -1;
mbed_official 554:edd95c0879f8 619 }
mbed_official 554:edd95c0879f8 620
mbed_official 554:edd95c0879f8 621 // ensure there is a link
mbed_official 554:edd95c0879f8 622 if(!ethernet_link()) {
mbed_official 554:edd95c0879f8 623 return -2;
mbed_official 554:edd95c0879f8 624 }
mbed_official 554:edd95c0879f8 625
mbed_official 554:edd95c0879f8 626 // we have been writing in to a buffer, so finalise it
mbed_official 554:edd95c0879f8 627 int size = tx_produce_offset;
mbed_official 554:edd95c0879f8 628 int index = LPC_EMAC->TxProduceIndex;
mbed_official 554:edd95c0879f8 629 txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST);
mbed_official 554:edd95c0879f8 630
mbed_official 554:edd95c0879f8 631 // Increment ProduceIndex to allow it to be sent
mbed_official 554:edd95c0879f8 632 // We can only do this if the next slot is free
mbed_official 554:edd95c0879f8 633 int next = rinc(index, NUM_TX_FRAG);
mbed_official 554:edd95c0879f8 634 while(next == LPC_EMAC->TxConsumeIndex) {
mbed_official 554:edd95c0879f8 635 for(int i=0; i<1000; i++) { __NOP(); }
mbed_official 554:edd95c0879f8 636 }
mbed_official 554:edd95c0879f8 637
mbed_official 554:edd95c0879f8 638 LPC_EMAC->TxProduceIndex = next;
mbed_official 554:edd95c0879f8 639 tx_produce_offset = -1;
mbed_official 554:edd95c0879f8 640 return size;
mbed_official 554:edd95c0879f8 641
mbed_official 554:edd95c0879f8 642 #else
mbed_official 554:edd95c0879f8 643 int s = send_size;
mbed_official 554:edd95c0879f8 644 txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST);
mbed_official 554:edd95c0879f8 645 send_idx = rinc(send_idx, NUM_TX_FRAG);
mbed_official 554:edd95c0879f8 646 LPC_EMAC->TxProduceIndex = send_idx;
mbed_official 554:edd95c0879f8 647 send_doff = 0;
mbed_official 554:edd95c0879f8 648 send_idx = -1;
mbed_official 554:edd95c0879f8 649 send_size = 0;
mbed_official 554:edd95c0879f8 650 return s;
mbed_official 554:edd95c0879f8 651 #endif
mbed_official 554:edd95c0879f8 652 }
mbed_official 554:edd95c0879f8 653
mbed_official 554:edd95c0879f8 654 // RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read
mbed_official 554:edd95c0879f8 655 // RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd
mbed_official 554:edd95c0879f8 656 //
mbed_official 554:edd95c0879f8 657 // if(RxConsumeIndex == RxProduceIndex) buffer array is empty
mbed_official 554:edd95c0879f8 658 // if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full
mbed_official 554:edd95c0879f8 659
mbed_official 554:edd95c0879f8 660 // Recevies an arrived ethernet packet.
mbed_official 554:edd95c0879f8 661 // Receiving an ethernet packet will drop the last received ethernet packet
mbed_official 554:edd95c0879f8 662 // and make a new ethernet packet ready to read.
mbed_official 554:edd95c0879f8 663 // Returns size of packet, else 0 if nothing to receive
mbed_official 554:edd95c0879f8 664
mbed_official 554:edd95c0879f8 665 // We read from RxConsumeIndex from position rx_consume_offset
mbed_official 554:edd95c0879f8 666 // if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading
mbed_official 554:edd95c0879f8 667 // rx_consume_offset = -1 // no frame
mbed_official 554:edd95c0879f8 668 // rx_consume_offset = 0 // start of frame
mbed_official 554:edd95c0879f8 669 // Assumption: A fragment should alway be a whole frame
mbed_official 554:edd95c0879f8 670
mbed_official 554:edd95c0879f8 671 int ethernet_receive() {
mbed_official 554:edd95c0879f8 672 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 673
mbed_official 554:edd95c0879f8 674 // if we are currently reading a valid RxConsume buffer, increment to the next one
mbed_official 554:edd95c0879f8 675 if(rx_consume_offset >= 0) {
mbed_official 554:edd95c0879f8 676 LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 677 }
mbed_official 554:edd95c0879f8 678
mbed_official 554:edd95c0879f8 679 // if the buffer is empty, mark it as no valid buffer
mbed_official 554:edd95c0879f8 680 if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) {
mbed_official 554:edd95c0879f8 681 rx_consume_offset = -1;
mbed_official 554:edd95c0879f8 682 return 0;
mbed_official 554:edd95c0879f8 683 }
mbed_official 554:edd95c0879f8 684
mbed_official 554:edd95c0879f8 685 uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info;
mbed_official 554:edd95c0879f8 686 rx_consume_offset = 0;
mbed_official 554:edd95c0879f8 687
mbed_official 554:edd95c0879f8 688 // check if it is not marked as last or for errors
mbed_official 554:edd95c0879f8 689 if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) {
mbed_official 554:edd95c0879f8 690 return -1;
mbed_official 554:edd95c0879f8 691 }
mbed_official 554:edd95c0879f8 692
mbed_official 554:edd95c0879f8 693 int size = (info & RINFO_SIZE) + 1;
mbed_official 554:edd95c0879f8 694 return size - 4; // don't include checksum bytes
mbed_official 554:edd95c0879f8 695
mbed_official 554:edd95c0879f8 696 #else
mbed_official 554:edd95c0879f8 697 if(receive_idx == -1) {
mbed_official 554:edd95c0879f8 698 receive_idx = LPC_EMAC->RxConsumeIndex;
mbed_official 554:edd95c0879f8 699 } else {
mbed_official 554:edd95c0879f8 700 while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) {
mbed_official 554:edd95c0879f8 701 receive_idx = rinc(receive_idx, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 702 }
mbed_official 554:edd95c0879f8 703 unsigned int info = rxstat[receive_idx].Info;
mbed_official 554:edd95c0879f8 704 int slen = (info & RINFO_SIZE) + 1;
mbed_official 554:edd95c0879f8 705
mbed_official 554:edd95c0879f8 706 if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) {
mbed_official 554:edd95c0879f8 707 /* Invalid frame, ignore it and free buffer. */
mbed_official 554:edd95c0879f8 708 receive_idx = rinc(receive_idx, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 709 }
mbed_official 554:edd95c0879f8 710 receive_idx = rinc(receive_idx, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 711 receive_soff = 0;
mbed_official 554:edd95c0879f8 712
mbed_official 554:edd95c0879f8 713 LPC_EMAC->RxConsumeIndex = receive_idx;
mbed_official 554:edd95c0879f8 714 }
mbed_official 554:edd95c0879f8 715
mbed_official 554:edd95c0879f8 716 if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) {
mbed_official 554:edd95c0879f8 717 receive_idx = -1;
mbed_official 554:edd95c0879f8 718 return 0;
mbed_official 554:edd95c0879f8 719 }
mbed_official 554:edd95c0879f8 720
mbed_official 554:edd95c0879f8 721 return (rxstat[receive_idx].Info & RINFO_SIZE) - 3;
mbed_official 554:edd95c0879f8 722 #endif
mbed_official 554:edd95c0879f8 723 }
mbed_official 554:edd95c0879f8 724
mbed_official 554:edd95c0879f8 725 // Read from an recevied ethernet packet.
mbed_official 554:edd95c0879f8 726 // After receive returnd a number bigger than 0 it is
mbed_official 554:edd95c0879f8 727 // possible to read bytes from this packet.
mbed_official 554:edd95c0879f8 728 // Read will write up to size bytes into data.
mbed_official 554:edd95c0879f8 729 // It is possible to use read multible times.
mbed_official 554:edd95c0879f8 730 // Each time read will start reading after the last read byte before.
mbed_official 554:edd95c0879f8 731
mbed_official 554:edd95c0879f8 732 int ethernet_read(char *data, int dlen) {
mbed_official 554:edd95c0879f8 733 #if NEW_LOGIC
mbed_official 554:edd95c0879f8 734 // Check we have a valid buffer to read
mbed_official 554:edd95c0879f8 735 if(rx_consume_offset < 0) {
mbed_official 554:edd95c0879f8 736 return 0;
mbed_official 554:edd95c0879f8 737 }
mbed_official 554:edd95c0879f8 738
mbed_official 554:edd95c0879f8 739 // Assume 1 fragment block
mbed_official 554:edd95c0879f8 740 uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info;
mbed_official 554:edd95c0879f8 741 int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum
mbed_official 554:edd95c0879f8 742
mbed_official 554:edd95c0879f8 743 int remaining = size - rx_consume_offset;
mbed_official 554:edd95c0879f8 744 int requested = dlen;
mbed_official 554:edd95c0879f8 745 int ncopy = min(remaining, requested);
mbed_official 554:edd95c0879f8 746
mbed_official 554:edd95c0879f8 747 void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset);
mbed_official 554:edd95c0879f8 748 void *pdst = (void *)(data);
mbed_official 554:edd95c0879f8 749
mbed_official 554:edd95c0879f8 750 if(data != NULL && ncopy > 0) {
mbed_official 554:edd95c0879f8 751 memcpy(pdst, psrc, ncopy);
mbed_official 554:edd95c0879f8 752 }
mbed_official 554:edd95c0879f8 753
mbed_official 554:edd95c0879f8 754 rx_consume_offset += ncopy;
mbed_official 554:edd95c0879f8 755
mbed_official 554:edd95c0879f8 756 return ncopy;
mbed_official 554:edd95c0879f8 757 #else
mbed_official 554:edd95c0879f8 758 int slen;
mbed_official 554:edd95c0879f8 759 int copy = 0;
mbed_official 554:edd95c0879f8 760 unsigned int more;
mbed_official 554:edd95c0879f8 761 unsigned int info;
mbed_official 554:edd95c0879f8 762 void *pdst, *psrc;
mbed_official 554:edd95c0879f8 763 int doff = 0;
mbed_official 554:edd95c0879f8 764
mbed_official 554:edd95c0879f8 765 if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) {
mbed_official 554:edd95c0879f8 766 return 0;
mbed_official 554:edd95c0879f8 767 }
mbed_official 554:edd95c0879f8 768
mbed_official 554:edd95c0879f8 769 do {
mbed_official 554:edd95c0879f8 770 info = rxstat[receive_idx].Info;
mbed_official 554:edd95c0879f8 771 more = !(info & RINFO_LAST_FLAG);
mbed_official 554:edd95c0879f8 772 slen = (info & RINFO_SIZE) + 1;
mbed_official 554:edd95c0879f8 773
mbed_official 554:edd95c0879f8 774 if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) {
mbed_official 554:edd95c0879f8 775 /* Invalid frame, ignore it and free buffer. */
mbed_official 554:edd95c0879f8 776 receive_idx = rinc(receive_idx, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 777 } else {
mbed_official 554:edd95c0879f8 778
mbed_official 554:edd95c0879f8 779 copy = min(slen - receive_soff, dlen - doff);
mbed_official 554:edd95c0879f8 780 psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff);
mbed_official 554:edd95c0879f8 781 pdst = (void *)(data + doff);
mbed_official 554:edd95c0879f8 782
mbed_official 554:edd95c0879f8 783 if(data != NULL) {
mbed_official 554:edd95c0879f8 784 /* check if Buffer available */
mbed_official 554:edd95c0879f8 785 memcpy(pdst, psrc, copy);
mbed_official 554:edd95c0879f8 786 }
mbed_official 554:edd95c0879f8 787
mbed_official 554:edd95c0879f8 788 receive_soff += copy;
mbed_official 554:edd95c0879f8 789 doff += copy;
mbed_official 554:edd95c0879f8 790
mbed_official 554:edd95c0879f8 791 if((more && (receive_soff == slen))) {
mbed_official 554:edd95c0879f8 792 receive_idx = rinc(receive_idx, NUM_RX_FRAG);
mbed_official 554:edd95c0879f8 793 receive_soff = 0;
mbed_official 554:edd95c0879f8 794 }
mbed_official 554:edd95c0879f8 795 }
mbed_official 554:edd95c0879f8 796 } while(more && !(doff == dlen) && !receive_soff);
mbed_official 554:edd95c0879f8 797
mbed_official 554:edd95c0879f8 798 return doff;
mbed_official 554:edd95c0879f8 799 #endif
mbed_official 554:edd95c0879f8 800 }
mbed_official 554:edd95c0879f8 801
mbed_official 554:edd95c0879f8 802 int ethernet_link(void) {
mbed_official 554:edd95c0879f8 803 if (phy_id == DP83848C_ID) {
mbed_official 554:edd95c0879f8 804 return (phy_read(PHY_REG_STS) & PHY_STS_LINK);
mbed_official 554:edd95c0879f8 805 }
mbed_official 554:edd95c0879f8 806 else { // LAN8720_ID
mbed_official 554:edd95c0879f8 807 return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK);
mbed_official 554:edd95c0879f8 808 }
mbed_official 554:edd95c0879f8 809 }
mbed_official 554:edd95c0879f8 810
mbed_official 554:edd95c0879f8 811 static int phy_write(unsigned int PhyReg, unsigned short Data) {
mbed_official 554:edd95c0879f8 812 unsigned int timeOut;
mbed_official 554:edd95c0879f8 813
mbed_official 554:edd95c0879f8 814 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
mbed_official 554:edd95c0879f8 815 LPC_EMAC->MWTD = Data;
mbed_official 554:edd95c0879f8 816
mbed_official 554:edd95c0879f8 817 for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */
mbed_official 554:edd95c0879f8 818 if((LPC_EMAC->MIND & MIND_BUSY) == 0) {
mbed_official 554:edd95c0879f8 819 return 0;
mbed_official 554:edd95c0879f8 820 }
mbed_official 554:edd95c0879f8 821 }
mbed_official 554:edd95c0879f8 822
mbed_official 554:edd95c0879f8 823 return -1;
mbed_official 554:edd95c0879f8 824 }
mbed_official 554:edd95c0879f8 825
mbed_official 554:edd95c0879f8 826 static int phy_read(unsigned int PhyReg) {
mbed_official 554:edd95c0879f8 827 unsigned int timeOut;
mbed_official 554:edd95c0879f8 828
mbed_official 554:edd95c0879f8 829 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
mbed_official 554:edd95c0879f8 830 LPC_EMAC->MCMD = MCMD_READ;
mbed_official 554:edd95c0879f8 831
mbed_official 554:edd95c0879f8 832 for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */
mbed_official 554:edd95c0879f8 833 if((LPC_EMAC->MIND & MIND_BUSY) == 0) {
mbed_official 554:edd95c0879f8 834 LPC_EMAC->MCMD = 0;
mbed_official 554:edd95c0879f8 835 return LPC_EMAC->MRDD; /* Return a 16-bit value. */
mbed_official 554:edd95c0879f8 836 }
mbed_official 554:edd95c0879f8 837 }
mbed_official 554:edd95c0879f8 838
mbed_official 554:edd95c0879f8 839 return -1;
mbed_official 554:edd95c0879f8 840 }
mbed_official 554:edd95c0879f8 841
mbed_official 554:edd95c0879f8 842
mbed_official 554:edd95c0879f8 843 static void txdscr_init() {
mbed_official 554:edd95c0879f8 844 int i;
mbed_official 554:edd95c0879f8 845
mbed_official 554:edd95c0879f8 846 for(i = 0; i < NUM_TX_FRAG; i++) {
mbed_official 554:edd95c0879f8 847 txdesc[i].Packet = (uint32_t)&txbuf[i];
mbed_official 554:edd95c0879f8 848 txdesc[i].Ctrl = 0;
mbed_official 554:edd95c0879f8 849 txstat[i].Info = 0;
mbed_official 554:edd95c0879f8 850 }
mbed_official 554:edd95c0879f8 851
mbed_official 554:edd95c0879f8 852 LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */
mbed_official 554:edd95c0879f8 853 LPC_EMAC->TxStatus = (uint32_t)txstat;
mbed_official 554:edd95c0879f8 854 LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
mbed_official 554:edd95c0879f8 855
mbed_official 554:edd95c0879f8 856 LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */
mbed_official 554:edd95c0879f8 857 }
mbed_official 554:edd95c0879f8 858
mbed_official 554:edd95c0879f8 859 static void rxdscr_init() {
mbed_official 554:edd95c0879f8 860 int i;
mbed_official 554:edd95c0879f8 861
mbed_official 554:edd95c0879f8 862 for(i = 0; i < NUM_RX_FRAG; i++) {
mbed_official 554:edd95c0879f8 863 rxdesc[i].Packet = (uint32_t)&rxbuf[i];
mbed_official 554:edd95c0879f8 864 rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1);
mbed_official 554:edd95c0879f8 865 rxstat[i].Info = 0;
mbed_official 554:edd95c0879f8 866 rxstat[i].HashCRC = 0;
mbed_official 554:edd95c0879f8 867 }
mbed_official 554:edd95c0879f8 868
mbed_official 554:edd95c0879f8 869 LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */
mbed_official 554:edd95c0879f8 870 LPC_EMAC->RxStatus = (uint32_t)rxstat;
mbed_official 554:edd95c0879f8 871 LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1;
mbed_official 554:edd95c0879f8 872
mbed_official 554:edd95c0879f8 873 LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */
mbed_official 554:edd95c0879f8 874 }
mbed_official 554:edd95c0879f8 875
mbed_official 554:edd95c0879f8 876 void ethernet_address(char *mac) {
mbed_official 554:edd95c0879f8 877 mbed_mac_address(mac);
mbed_official 554:edd95c0879f8 878 }
mbed_official 554:edd95c0879f8 879
mbed_official 554:edd95c0879f8 880 void ethernet_set_link(int speed, int duplex) {
mbed_official 554:edd95c0879f8 881 unsigned short phy_data;
mbed_official 554:edd95c0879f8 882 int tout;
mbed_official 554:edd95c0879f8 883
mbed_official 554:edd95c0879f8 884 if((speed < 0) || (speed > 1)) {
mbed_official 554:edd95c0879f8 885 phy_data = PHY_AUTO_NEG;
mbed_official 554:edd95c0879f8 886 } else {
mbed_official 554:edd95c0879f8 887 phy_data = (((unsigned short) speed << 13) |
mbed_official 554:edd95c0879f8 888 ((unsigned short) duplex << 8));
mbed_official 554:edd95c0879f8 889 }
mbed_official 554:edd95c0879f8 890
mbed_official 554:edd95c0879f8 891 phy_write(PHY_REG_BMCR, phy_data);
mbed_official 554:edd95c0879f8 892
mbed_official 554:edd95c0879f8 893 for(tout = 100; tout; tout--) { __NOP(); } /* A short delay */
mbed_official 554:edd95c0879f8 894
mbed_official 554:edd95c0879f8 895 switch(phy_id) {
mbed_official 554:edd95c0879f8 896 case DP83848C_ID:
mbed_official 554:edd95c0879f8 897 phy_data = phy_read(PHY_REG_STS);
mbed_official 554:edd95c0879f8 898
mbed_official 554:edd95c0879f8 899 if(phy_data & PHY_STS_DUPLEX) {
mbed_official 554:edd95c0879f8 900 LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
mbed_official 554:edd95c0879f8 901 LPC_EMAC->Command |= CR_FULL_DUP;
mbed_official 554:edd95c0879f8 902 LPC_EMAC->IPGT = IPGT_FULL_DUP;
mbed_official 554:edd95c0879f8 903 } else {
mbed_official 554:edd95c0879f8 904 LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP;
mbed_official 554:edd95c0879f8 905 LPC_EMAC->Command &= ~CR_FULL_DUP;
mbed_official 554:edd95c0879f8 906 LPC_EMAC->IPGT = IPGT_HALF_DUP;
mbed_official 554:edd95c0879f8 907 }
mbed_official 554:edd95c0879f8 908
mbed_official 554:edd95c0879f8 909 if(phy_data & PHY_STS_SPEED) {
mbed_official 554:edd95c0879f8 910 LPC_EMAC->SUPP &= ~SUPP_SPEED;
mbed_official 554:edd95c0879f8 911 } else {
mbed_official 554:edd95c0879f8 912 LPC_EMAC->SUPP |= SUPP_SPEED;
mbed_official 554:edd95c0879f8 913 }
mbed_official 554:edd95c0879f8 914 break;
mbed_official 554:edd95c0879f8 915
mbed_official 554:edd95c0879f8 916 case LAN8720_ID:
mbed_official 554:edd95c0879f8 917 phy_data = phy_read(PHY_REG_SCSR);
mbed_official 554:edd95c0879f8 918
mbed_official 554:edd95c0879f8 919 if (phy_data & PHY_SCSR_DUPLEX) {
mbed_official 554:edd95c0879f8 920 LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
mbed_official 554:edd95c0879f8 921 LPC_EMAC->Command |= CR_FULL_DUP;
mbed_official 554:edd95c0879f8 922 LPC_EMAC->IPGT = IPGT_FULL_DUP;
mbed_official 554:edd95c0879f8 923 } else {
mbed_official 554:edd95c0879f8 924 LPC_EMAC->Command &= ~CR_FULL_DUP;
mbed_official 554:edd95c0879f8 925 LPC_EMAC->IPGT = IPGT_HALF_DUP;
mbed_official 554:edd95c0879f8 926 }
mbed_official 554:edd95c0879f8 927
mbed_official 554:edd95c0879f8 928 if(phy_data & PHY_SCSR_100MBIT) {
mbed_official 554:edd95c0879f8 929 LPC_EMAC->SUPP |= SUPP_SPEED;
mbed_official 554:edd95c0879f8 930 } else {
mbed_official 554:edd95c0879f8 931 LPC_EMAC->SUPP &= ~SUPP_SPEED;
mbed_official 554:edd95c0879f8 932 }
mbed_official 554:edd95c0879f8 933 break;
mbed_official 554:edd95c0879f8 934 }
mbed_official 554:edd95c0879f8 935 }