mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
66:fdb3f9f9a72f
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /* mbed Microcontroller Library
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2006-2013 ARM Limited
<> 144:ef7eb2e8f9f7 3 *
<> 144:ef7eb2e8f9f7 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 144:ef7eb2e8f9f7 5 * you may not use this file except in compliance with the License.
<> 144:ef7eb2e8f9f7 6 * You may obtain a copy of the License at
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Unless required by applicable law or agreed to in writing, software
<> 144:ef7eb2e8f9f7 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 144:ef7eb2e8f9f7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 144:ef7eb2e8f9f7 13 * See the License for the specific language governing permissions and
<> 144:ef7eb2e8f9f7 14 * limitations under the License.
<> 144:ef7eb2e8f9f7 15 */
<> 144:ef7eb2e8f9f7 16 #include <string.h>
<> 144:ef7eb2e8f9f7 17 #include "ethernet_api.h"
<> 144:ef7eb2e8f9f7 18 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 19 #include "mbed_interface.h"
<> 144:ef7eb2e8f9f7 20 #include "toolchain.h"
<> 144:ef7eb2e8f9f7 21 #include "mbed_error.h"
<> 144:ef7eb2e8f9f7 22 #include "ether_iodefine.h"
<> 144:ef7eb2e8f9f7 23 #include "ethernetext_api.h"
<> 144:ef7eb2e8f9f7 24
<> 144:ef7eb2e8f9f7 25 /* Descriptor info */
<> 144:ef7eb2e8f9f7 26 #define NUM_OF_TX_DESCRIPTOR (16)
<> 144:ef7eb2e8f9f7 27 #define NUM_OF_RX_DESCRIPTOR (16)
<> 144:ef7eb2e8f9f7 28 #define SIZE_OF_BUFFER (1600) /* Must be an integral multiple of 32 */
<> 144:ef7eb2e8f9f7 29 #define MAX_SEND_SIZE (1514)
<> 144:ef7eb2e8f9f7 30 /* Ethernet Descriptor Value Define */
<> 144:ef7eb2e8f9f7 31 #define TD0_TFP_TOP_BOTTOM (0x30000000)
<> 144:ef7eb2e8f9f7 32 #define TD0_TACT (0x80000000)
<> 144:ef7eb2e8f9f7 33 #define TD0_TDLE (0x40000000)
<> 144:ef7eb2e8f9f7 34 #define RD0_RACT (0x80000000)
<> 144:ef7eb2e8f9f7 35 #define RD0_RDLE (0x40000000)
<> 144:ef7eb2e8f9f7 36 #define RD0_RFE (0x08000000)
<> 144:ef7eb2e8f9f7 37 #define RD0_RCSE (0x04000000)
<> 144:ef7eb2e8f9f7 38 #define RD0_RFS (0x03FF0000)
<> 144:ef7eb2e8f9f7 39 #define RD0_RCS (0x0000FFFF)
<> 144:ef7eb2e8f9f7 40 #define RD0_RFS_RFOF (0x02000000)
<> 144:ef7eb2e8f9f7 41 #define RD0_RFS_RUAF (0x00400000)
<> 144:ef7eb2e8f9f7 42 #define RD0_RFS_RRF (0x00100000)
<> 144:ef7eb2e8f9f7 43 #define RD0_RFS_RTLF (0x00080000)
<> 144:ef7eb2e8f9f7 44 #define RD0_RFS_RTSF (0x00040000)
<> 144:ef7eb2e8f9f7 45 #define RD0_RFS_PRE (0x00020000)
<> 144:ef7eb2e8f9f7 46 #define RD0_RFS_CERF (0x00010000)
<> 144:ef7eb2e8f9f7 47 #define RD0_RFS_ERROR (RD0_RFS_RFOF | RD0_RFS_RUAF | RD0_RFS_RRF | RD0_RFS_RTLF | \
<> 144:ef7eb2e8f9f7 48 RD0_RFS_RTSF | RD0_RFS_PRE | RD0_RFS_CERF)
<> 144:ef7eb2e8f9f7 49 #define RD1_RDL_MSK (0x0000FFFF)
<> 144:ef7eb2e8f9f7 50 /* PHY Register */
<> 144:ef7eb2e8f9f7 51 #define BASIC_MODE_CONTROL_REG (0)
<> 144:ef7eb2e8f9f7 52 #define BASIC_MODE_STATUS_REG (1)
<> 144:ef7eb2e8f9f7 53 #define PHY_IDENTIFIER1_REG (2)
<> 144:ef7eb2e8f9f7 54 #define PHY_IDENTIFIER2_REG (3)
<> 144:ef7eb2e8f9f7 55 #define PHY_SP_CTL_STS_REG (31)
<> 144:ef7eb2e8f9f7 56 /* MII management interface access */
<> 144:ef7eb2e8f9f7 57 #define PHY_ADDR (0) /* Confirm the pin connection of the PHY-LSI */
<> 144:ef7eb2e8f9f7 58 #define PHY_ST (1)
<> 144:ef7eb2e8f9f7 59 #define PHY_WRITE (1)
<> 144:ef7eb2e8f9f7 60 #define PHY_READ (2)
<> 144:ef7eb2e8f9f7 61 #define MDC_WAIT (6) /* 400ns/4 */
<> 144:ef7eb2e8f9f7 62 #define BASIC_STS_MSK_LINK (0x0004) /* Link Status */
<> 144:ef7eb2e8f9f7 63 #define BASIC_STS_MSK_AUTO_CMP (0x0020) /* Auto-Negotiate Complete */
<> 144:ef7eb2e8f9f7 64 #define M_PHY_ID (0xFFFFFFF0)
<> 144:ef7eb2e8f9f7 65 #define PHY_ID_LAN8710A (0x0007C0F0)
<> 144:ef7eb2e8f9f7 66 /* ETHERPIR0 */
<> 144:ef7eb2e8f9f7 67 #define PIR0_MDI (0x00000008)
<> 144:ef7eb2e8f9f7 68 #define PIR0_MDO (0x00000004)
<> 144:ef7eb2e8f9f7 69 #define PIR0_MMD (0x00000002)
<> 144:ef7eb2e8f9f7 70 #define PIR0_MDC (0x00000001)
<> 144:ef7eb2e8f9f7 71 #define PIR0_MDC_HIGH (0x00000001)
<> 144:ef7eb2e8f9f7 72 #define PIR0_MDC_LOW (0x00000000)
<> 144:ef7eb2e8f9f7 73 /* ETHEREDRRR0 */
<> 144:ef7eb2e8f9f7 74 #define EDRRR0_RR (0x00000001)
<> 144:ef7eb2e8f9f7 75 /* ETHEREDTRR0 */
<> 144:ef7eb2e8f9f7 76 #define EDTRR0_TR (0x00000003)
<> 144:ef7eb2e8f9f7 77 /* software wait */
<> 144:ef7eb2e8f9f7 78 #define LOOP_100us (6700) /* Loop counter for software wait 6666=100us/((1/400MHz)*6cyc) */
<> 144:ef7eb2e8f9f7 79
<> 144:ef7eb2e8f9f7 80 #define EDMAC_EESIPR_INI_RECV (0x0205001F) /* 0x02000000 : Detect reception suspended */
<> 144:ef7eb2e8f9f7 81 /* 0x00040000 : Detect frame reception */
<> 144:ef7eb2e8f9f7 82 /* 0x00010000 : Receive FIFO overflow */
<> 144:ef7eb2e8f9f7 83 /* 0x00000010 : Residual bit frame reception */
<> 144:ef7eb2e8f9f7 84 /* 0x00000008 : Long frame reception */
<> 144:ef7eb2e8f9f7 85 /* 0x00000004 : Short frame reception */
<> 144:ef7eb2e8f9f7 86 /* 0x00000002 : PHY-LSI reception error */
<> 144:ef7eb2e8f9f7 87 /* 0x00000001 : Receive frame CRC error */
<> 144:ef7eb2e8f9f7 88 #define EDMAC_EESIPR_INI_EtherC (0x00400000) /* 0x00400000 : E-MAC status register */
<> 144:ef7eb2e8f9f7 89
<> 144:ef7eb2e8f9f7 90 /* Send descriptor */
<> 144:ef7eb2e8f9f7 91 typedef struct tag_edmac_send_desc {
<> 144:ef7eb2e8f9f7 92 uint32_t td0;
<> 144:ef7eb2e8f9f7 93 uint32_t td1;
<> 144:ef7eb2e8f9f7 94 uint8_t *td2;
<> 144:ef7eb2e8f9f7 95 uint32_t padding4;
<> 144:ef7eb2e8f9f7 96 } edmac_send_desc_t;
<> 144:ef7eb2e8f9f7 97
<> 144:ef7eb2e8f9f7 98 /* Receive descriptor */
<> 144:ef7eb2e8f9f7 99 typedef struct tag_edmac_recv_desc {
<> 144:ef7eb2e8f9f7 100 uint32_t rd0;
<> 144:ef7eb2e8f9f7 101 uint32_t rd1;
<> 144:ef7eb2e8f9f7 102 uint8_t *rd2;
<> 144:ef7eb2e8f9f7 103 uint32_t padding4;
<> 144:ef7eb2e8f9f7 104 } edmac_recv_desc_t;
<> 144:ef7eb2e8f9f7 105
<> 144:ef7eb2e8f9f7 106 /* memory */
<> 144:ef7eb2e8f9f7 107 /* The whole transmit/receive descriptors (must be allocated in 16-byte boundaries) */
<> 144:ef7eb2e8f9f7 108 /* Transmit/receive buffers (must be allocated in 16-byte boundaries) */
<> 144:ef7eb2e8f9f7 109 #if defined(__ICCARM__)
<> 144:ef7eb2e8f9f7 110 #pragma data_alignment=16
<> 144:ef7eb2e8f9f7 111 static uint8_t ethernet_nc_memory[(sizeof(edmac_send_desc_t) * NUM_OF_TX_DESCRIPTOR) +
<> 144:ef7eb2e8f9f7 112 (sizeof(edmac_recv_desc_t) * NUM_OF_RX_DESCRIPTOR) +
<> 144:ef7eb2e8f9f7 113 (NUM_OF_TX_DESCRIPTOR * SIZE_OF_BUFFER) +
<> 144:ef7eb2e8f9f7 114 (NUM_OF_RX_DESCRIPTOR * SIZE_OF_BUFFER)] //16 bytes aligned!
<> 144:ef7eb2e8f9f7 115 @ ".mirrorram";
<> 144:ef7eb2e8f9f7 116 #else
<> 144:ef7eb2e8f9f7 117 static uint8_t ethernet_nc_memory[(sizeof(edmac_send_desc_t) * NUM_OF_TX_DESCRIPTOR) +
<> 144:ef7eb2e8f9f7 118 (sizeof(edmac_recv_desc_t) * NUM_OF_RX_DESCRIPTOR) +
<> 144:ef7eb2e8f9f7 119 (NUM_OF_TX_DESCRIPTOR * SIZE_OF_BUFFER) +
<> 144:ef7eb2e8f9f7 120 (NUM_OF_RX_DESCRIPTOR * SIZE_OF_BUFFER)]
<> 144:ef7eb2e8f9f7 121 __attribute((section("NC_BSS"),aligned(16))); //16 bytes aligned!
<> 144:ef7eb2e8f9f7 122 #endif
<> 144:ef7eb2e8f9f7 123 static int32_t rx_read_offset; /* read offset */
<> 144:ef7eb2e8f9f7 124 static int32_t tx_wite_offset; /* write offset */
<> 144:ef7eb2e8f9f7 125 static uint32_t send_top_index;
<> 144:ef7eb2e8f9f7 126 static uint32_t recv_top_index;
<> 144:ef7eb2e8f9f7 127 static int32_t Interrupt_priority;
<> 144:ef7eb2e8f9f7 128 static edmac_send_desc_t *p_eth_desc_dsend = NULL;
<> 144:ef7eb2e8f9f7 129 static edmac_recv_desc_t *p_eth_desc_drecv = NULL;
<> 144:ef7eb2e8f9f7 130 static edmac_recv_desc_t *p_recv_end_desc = NULL;
<> 144:ef7eb2e8f9f7 131 static ethernetext_cb_fnc *p_recv_cb_fnc = NULL;
<> 144:ef7eb2e8f9f7 132 static char mac_addr[6] = {0x00, 0x02, 0xF7, 0xF0, 0x00, 0x00}; /* MAC Address */
<> 144:ef7eb2e8f9f7 133 static uint32_t phy_id = 0;
<> 144:ef7eb2e8f9f7 134 static uint32_t start_stop = 1; /* 0:stop 1:start */
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 /* function */
<> 144:ef7eb2e8f9f7 137 static void lan_reg_reset(void);
<> 144:ef7eb2e8f9f7 138 static void lan_desc_create(void);
<> 144:ef7eb2e8f9f7 139 static void lan_reg_set(int32_t link);
<> 144:ef7eb2e8f9f7 140 static uint16_t phy_reg_read(uint16_t reg_addr);
<> 144:ef7eb2e8f9f7 141 static void phy_reg_write(uint16_t reg_addr, uint16_t data);
<> 144:ef7eb2e8f9f7 142 static void mii_preamble(void);
<> 144:ef7eb2e8f9f7 143 static void mii_cmd(uint16_t reg_addr, uint32_t option);
<> 144:ef7eb2e8f9f7 144 static void mii_reg_read(uint16_t *data);
<> 144:ef7eb2e8f9f7 145 static void mii_reg_write(uint16_t data);
<> 144:ef7eb2e8f9f7 146 static void mii_z(void);
<> 144:ef7eb2e8f9f7 147 static void mii_write_1(void);
<> 144:ef7eb2e8f9f7 148 static void mii_write_0(void);
<> 144:ef7eb2e8f9f7 149 static void set_ether_pir(uint32_t set_data);
<> 144:ef7eb2e8f9f7 150 static void wait_100us(int32_t wait_cnt);
<> 144:ef7eb2e8f9f7 151
<> 144:ef7eb2e8f9f7 152
<> 144:ef7eb2e8f9f7 153 int ethernetext_init(ethernet_cfg_t *p_ethcfg) {
<> 144:ef7eb2e8f9f7 154 int32_t i;
<> 144:ef7eb2e8f9f7 155 uint16_t val;
<> 144:ef7eb2e8f9f7 156
<> 144:ef7eb2e8f9f7 157 CPGSTBCR7 &= ~(CPG_STBCR7_BIT_MSTP74); /* enable ETHER clock */
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /* P4_2(PHY Reset) */
<> 144:ef7eb2e8f9f7 160 GPIOP4 &= ~0x0004; /* Outputs low level */
<> 144:ef7eb2e8f9f7 161 GPIOPMC4 &= ~0x0004; /* Port mode */
<> 144:ef7eb2e8f9f7 162 GPIOPM4 &= ~0x0004; /* Output mode */
<> 144:ef7eb2e8f9f7 163
<> 144:ef7eb2e8f9f7 164 /* GPIO P1 P1_14(ET_COL) */
<> 144:ef7eb2e8f9f7 165 GPIOPMC1 |= 0x4000;
<> 144:ef7eb2e8f9f7 166 GPIOPFCAE1 &= ~0x4000;
<> 144:ef7eb2e8f9f7 167 GPIOPFCE1 |= 0x4000;
<> 144:ef7eb2e8f9f7 168 GPIOPFC1 |= 0x4000;
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 /* P3_0(ET_TXCLK), P3_3(ET_MDIO), P3_4(ET_RXCLK), P3_5(ET_RXER), P3_6(ET_RXDV) */
<> 144:ef7eb2e8f9f7 171 GPIOPMC3 |= 0x0079;
<> 144:ef7eb2e8f9f7 172 GPIOPFCAE3 &= ~0x0079;
<> 144:ef7eb2e8f9f7 173 GPIOPFCE3 &= ~0x0079;
<> 144:ef7eb2e8f9f7 174 GPIOPFC3 |= 0x0079;
<> 144:ef7eb2e8f9f7 175 GPIOPIPC3 |= 0x0079;
<> 144:ef7eb2e8f9f7 176
<> 144:ef7eb2e8f9f7 177 /* P5_9(ET_MDC) */
<> 144:ef7eb2e8f9f7 178 GPIOPMC5 |= 0x0200;
<> 144:ef7eb2e8f9f7 179 GPIOPFCAE5 &= ~0x0200;
<> 144:ef7eb2e8f9f7 180 GPIOPFCE5 &= ~0x0200;
<> 144:ef7eb2e8f9f7 181 GPIOPFC5 |= 0x0200;
<> 144:ef7eb2e8f9f7 182 GPIOPIPC5 |= 0x0200;
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 /* P10_1(ET_TXER), P10_2(ET_TXEN), P10_3(ET_CRS), P10_4(ET_TXD0), P10_5(ET_TXD1) */
<> 144:ef7eb2e8f9f7 185 /* P10_6(ET_TXD2), P10_7(ET_TXD3), P10_8(ET_RXD0), P10_9(ET_RXD1), P10_10(ET_RXD2), P10_11(ET_RXD3) */
<> 144:ef7eb2e8f9f7 186 GPIOPMC10 |= 0x0FFE;
<> 144:ef7eb2e8f9f7 187 GPIOPFCAE10 &= ~0x0FFE;
<> 144:ef7eb2e8f9f7 188 GPIOPFCE10 |= 0x0FFE;
<> 144:ef7eb2e8f9f7 189 GPIOPFC10 |= 0x0FFE;
<> 144:ef7eb2e8f9f7 190 GPIOPIPC10 |= 0x0FFE;
<> 144:ef7eb2e8f9f7 191
<> 144:ef7eb2e8f9f7 192 /* Resets the E-MAC,E-DMAC */
<> 144:ef7eb2e8f9f7 193 lan_reg_reset();
<> 144:ef7eb2e8f9f7 194
<> 144:ef7eb2e8f9f7 195 /* PHY Reset */
<> 144:ef7eb2e8f9f7 196 GPIOP4 &= ~0x0004; /* P4_2 Outputs low level */
<> 144:ef7eb2e8f9f7 197 wait_100us(250); /* 25msec */
<> 144:ef7eb2e8f9f7 198 GPIOP4 |= 0x0004; /* P4_2 Outputs high level */
<> 144:ef7eb2e8f9f7 199 wait_100us(100); /* 10msec */
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 /* Resets the PHY-LSI */
<> 144:ef7eb2e8f9f7 202 phy_reg_write(BASIC_MODE_CONTROL_REG, 0x8000);
<> 144:ef7eb2e8f9f7 203 for (i = 10000; i > 0; i--) {
<> 144:ef7eb2e8f9f7 204 val = phy_reg_read(BASIC_MODE_CONTROL_REG);
<> 144:ef7eb2e8f9f7 205 if (((uint32_t)val & 0x8000uL) == 0) {
<> 144:ef7eb2e8f9f7 206 break; /* Reset complete */
<> 144:ef7eb2e8f9f7 207 }
<> 144:ef7eb2e8f9f7 208 }
<> 144:ef7eb2e8f9f7 209
<> 144:ef7eb2e8f9f7 210 phy_id = ((uint32_t)phy_reg_read(PHY_IDENTIFIER1_REG) << 16)
<> 144:ef7eb2e8f9f7 211 | (uint32_t)phy_reg_read(PHY_IDENTIFIER2_REG);
<> 144:ef7eb2e8f9f7 212
<> 144:ef7eb2e8f9f7 213 Interrupt_priority = p_ethcfg->int_priority;
<> 144:ef7eb2e8f9f7 214 p_recv_cb_fnc = p_ethcfg->recv_cb;
<> 144:ef7eb2e8f9f7 215 start_stop = 1;
<> 144:ef7eb2e8f9f7 216
<> 144:ef7eb2e8f9f7 217 if (p_ethcfg->ether_mac != NULL) {
<> 144:ef7eb2e8f9f7 218 (void)memcpy(mac_addr, p_ethcfg->ether_mac, sizeof(mac_addr));
<> 144:ef7eb2e8f9f7 219 } else {
<> 144:ef7eb2e8f9f7 220 ethernet_address(mac_addr); /* Get MAC Address */
<> 144:ef7eb2e8f9f7 221 }
<> 144:ef7eb2e8f9f7 222
<> 144:ef7eb2e8f9f7 223 return 0;
<> 144:ef7eb2e8f9f7 224 }
<> 144:ef7eb2e8f9f7 225
<> 144:ef7eb2e8f9f7 226 void ethernetext_start_stop(int32_t mode) {
<> 144:ef7eb2e8f9f7 227 if (mode == 1) {
<> 144:ef7eb2e8f9f7 228 /* start */
<> 144:ef7eb2e8f9f7 229 ETHEREDTRR0 |= EDTRR0_TR;
<> 144:ef7eb2e8f9f7 230 ETHEREDRRR0 |= EDRRR0_RR;
<> 144:ef7eb2e8f9f7 231 start_stop = 1;
<> 144:ef7eb2e8f9f7 232 } else {
<> 144:ef7eb2e8f9f7 233 /* stop */
<> 144:ef7eb2e8f9f7 234 ETHEREDTRR0 &= ~EDTRR0_TR;
<> 144:ef7eb2e8f9f7 235 ETHEREDRRR0 &= ~EDRRR0_RR;
<> 144:ef7eb2e8f9f7 236 start_stop = 0;
<> 144:ef7eb2e8f9f7 237 }
<> 144:ef7eb2e8f9f7 238 }
<> 144:ef7eb2e8f9f7 239
<> 144:ef7eb2e8f9f7 240 int ethernetext_chk_link_mode(void) {
<> 144:ef7eb2e8f9f7 241 int32_t link;
<> 144:ef7eb2e8f9f7 242 uint16_t data;
<> 144:ef7eb2e8f9f7 243
<> 144:ef7eb2e8f9f7 244 if ((phy_id & M_PHY_ID) == PHY_ID_LAN8710A) {
<> 144:ef7eb2e8f9f7 245 data = phy_reg_read(PHY_SP_CTL_STS_REG);
<> 144:ef7eb2e8f9f7 246 switch (((uint32_t)data >> 2) & 0x00000007) {
<> 144:ef7eb2e8f9f7 247 case 0x0001:
<> 144:ef7eb2e8f9f7 248 link = HALF_10M;
<> 144:ef7eb2e8f9f7 249 break;
<> 144:ef7eb2e8f9f7 250 case 0x0005:
<> 144:ef7eb2e8f9f7 251 link = FULL_10M;
<> 144:ef7eb2e8f9f7 252 break;
<> 144:ef7eb2e8f9f7 253 case 0x0002:
<> 144:ef7eb2e8f9f7 254 link = HALF_TX;
<> 144:ef7eb2e8f9f7 255 break;
<> 144:ef7eb2e8f9f7 256 case 0x0006:
<> 144:ef7eb2e8f9f7 257 link = FULL_TX;
<> 144:ef7eb2e8f9f7 258 break;
<> 144:ef7eb2e8f9f7 259 default:
<> 144:ef7eb2e8f9f7 260 link = NEGO_FAIL;
<> 144:ef7eb2e8f9f7 261 break;
<> 144:ef7eb2e8f9f7 262 }
<> 144:ef7eb2e8f9f7 263 } else {
<> 144:ef7eb2e8f9f7 264 link = NEGO_FAIL;
<> 144:ef7eb2e8f9f7 265 }
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 return link;
<> 144:ef7eb2e8f9f7 268 }
<> 144:ef7eb2e8f9f7 269
<> 144:ef7eb2e8f9f7 270 void ethernetext_set_link_mode(int32_t link) {
<> 144:ef7eb2e8f9f7 271 lan_reg_reset(); /* Resets the E-MAC,E-DMAC */
<> 144:ef7eb2e8f9f7 272 lan_desc_create(); /* Initialize of buffer memory */
<> 144:ef7eb2e8f9f7 273 lan_reg_set(link); /* E-DMAC, E-MAC initialization */
<> 144:ef7eb2e8f9f7 274 }
<> 144:ef7eb2e8f9f7 275
<> 144:ef7eb2e8f9f7 276 int ethernet_init() {
<> 144:ef7eb2e8f9f7 277 ethernet_cfg_t ethcfg;
<> 144:ef7eb2e8f9f7 278
<> 144:ef7eb2e8f9f7 279 ethcfg.int_priority = 5;
<> 144:ef7eb2e8f9f7 280 ethcfg.recv_cb = NULL;
<> 144:ef7eb2e8f9f7 281 ethcfg.ether_mac = NULL;
<> 144:ef7eb2e8f9f7 282 ethernetext_init(&ethcfg);
<> 144:ef7eb2e8f9f7 283 ethernet_set_link(-1, 0); /* Auto-Negotiation */
<> 144:ef7eb2e8f9f7 284
<> 144:ef7eb2e8f9f7 285 return 0;
<> 144:ef7eb2e8f9f7 286 }
<> 144:ef7eb2e8f9f7 287
<> 144:ef7eb2e8f9f7 288 void ethernet_free() {
<> 144:ef7eb2e8f9f7 289 ETHERARSTR |= 0x00000001; /* ETHER software reset */
<> 144:ef7eb2e8f9f7 290 CPGSTBCR7 |= CPG_STBCR7_BIT_MSTP74; /* disable ETHER clock */
<> 144:ef7eb2e8f9f7 291 }
<> 144:ef7eb2e8f9f7 292
<> 144:ef7eb2e8f9f7 293 int ethernet_write(const char *data, int slen) {
<> 144:ef7eb2e8f9f7 294 edmac_send_desc_t *p_send_desc;
<> 144:ef7eb2e8f9f7 295 int32_t copy_size;
<> 144:ef7eb2e8f9f7 296
<> 144:ef7eb2e8f9f7 297 if ((p_eth_desc_dsend == NULL) || (data == NULL) || (slen < 0)
<> 144:ef7eb2e8f9f7 298 || (tx_wite_offset < 0) || (tx_wite_offset >= MAX_SEND_SIZE)) {
<> 144:ef7eb2e8f9f7 299 copy_size = 0;
<> 144:ef7eb2e8f9f7 300 } else {
<> 144:ef7eb2e8f9f7 301 p_send_desc = &p_eth_desc_dsend[send_top_index]; /* Current descriptor */
<> 144:ef7eb2e8f9f7 302 if ((p_send_desc->td0 & TD0_TACT) != 0) {
<> 144:ef7eb2e8f9f7 303 copy_size = 0;
<> 144:ef7eb2e8f9f7 304 } else {
<> 144:ef7eb2e8f9f7 305 copy_size = MAX_SEND_SIZE - tx_wite_offset;
<> 144:ef7eb2e8f9f7 306 if (copy_size > slen) {
<> 144:ef7eb2e8f9f7 307 copy_size = slen;
<> 144:ef7eb2e8f9f7 308 }
<> 144:ef7eb2e8f9f7 309 (void)memcpy(&p_send_desc->td2[tx_wite_offset], data, copy_size);
<> 144:ef7eb2e8f9f7 310 tx_wite_offset += copy_size;
<> 144:ef7eb2e8f9f7 311 }
<> 144:ef7eb2e8f9f7 312 }
<> 144:ef7eb2e8f9f7 313
<> 144:ef7eb2e8f9f7 314 return copy_size;
<> 144:ef7eb2e8f9f7 315 }
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 int ethernet_send() {
<> 144:ef7eb2e8f9f7 318 edmac_send_desc_t *p_send_desc;
<> 144:ef7eb2e8f9f7 319 int32_t ret;
<> 144:ef7eb2e8f9f7 320
<> 144:ef7eb2e8f9f7 321 if ((p_eth_desc_dsend == NULL) || (tx_wite_offset <= 0)) {
<> 144:ef7eb2e8f9f7 322 ret = 0;
<> 144:ef7eb2e8f9f7 323 } else {
<> 144:ef7eb2e8f9f7 324 /* Transfer 1 frame */
<> 144:ef7eb2e8f9f7 325 p_send_desc = &p_eth_desc_dsend[send_top_index]; /* Current descriptor */
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 /* Sets the frame length */
<> 144:ef7eb2e8f9f7 328 p_send_desc->td1 = ((uint32_t)tx_wite_offset << 16);
<> 144:ef7eb2e8f9f7 329 tx_wite_offset = 0;
<> 144:ef7eb2e8f9f7 330
<> 144:ef7eb2e8f9f7 331 /* Sets the transmit descriptor to transmit again */
<> 144:ef7eb2e8f9f7 332 p_send_desc->td0 &= (TD0_TACT | TD0_TDLE | TD0_TFP_TOP_BOTTOM);
<> 144:ef7eb2e8f9f7 333 p_send_desc->td0 |= TD0_TACT;
<> 144:ef7eb2e8f9f7 334 if ((start_stop == 1) && ((ETHEREDTRR0 & EDTRR0_TR) != EDTRR0_TR)) {
<> 144:ef7eb2e8f9f7 335 ETHEREDTRR0 |= EDTRR0_TR;
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337
<> 144:ef7eb2e8f9f7 338 /* Update the current descriptor */
<> 144:ef7eb2e8f9f7 339 send_top_index++;
<> 144:ef7eb2e8f9f7 340 if (send_top_index >= NUM_OF_TX_DESCRIPTOR) {
<> 144:ef7eb2e8f9f7 341 send_top_index = 0;
<> 144:ef7eb2e8f9f7 342 }
<> 144:ef7eb2e8f9f7 343 ret = 1;
<> 144:ef7eb2e8f9f7 344 }
<> 144:ef7eb2e8f9f7 345
<> 144:ef7eb2e8f9f7 346 return ret;
<> 144:ef7eb2e8f9f7 347 }
<> 144:ef7eb2e8f9f7 348
<> 144:ef7eb2e8f9f7 349 int ethernet_receive() {
<> 144:ef7eb2e8f9f7 350 edmac_recv_desc_t *p_recv_desc;
<> 144:ef7eb2e8f9f7 351 int32_t receive_size = 0;
<> 144:ef7eb2e8f9f7 352
<> 144:ef7eb2e8f9f7 353 if (p_eth_desc_drecv != NULL) {
<> 144:ef7eb2e8f9f7 354 if (p_recv_end_desc != NULL) {
<> 144:ef7eb2e8f9f7 355 /* Sets the receive descriptor to receive again */
<> 144:ef7eb2e8f9f7 356 p_recv_end_desc->rd0 &= (RD0_RACT | RD0_RDLE);
<> 144:ef7eb2e8f9f7 357 p_recv_end_desc->rd0 |= RD0_RACT;
<> 144:ef7eb2e8f9f7 358 if ((start_stop == 1) && ((ETHEREDRRR0 & EDRRR0_RR) == 0)) {
<> 144:ef7eb2e8f9f7 359 ETHEREDRRR0 |= EDRRR0_RR;
<> 144:ef7eb2e8f9f7 360 }
<> 144:ef7eb2e8f9f7 361 p_recv_end_desc = NULL;
<> 144:ef7eb2e8f9f7 362 }
<> 144:ef7eb2e8f9f7 363
<> 144:ef7eb2e8f9f7 364 p_recv_desc = &p_eth_desc_drecv[recv_top_index]; /* Current descriptor */
<> 144:ef7eb2e8f9f7 365 if ((p_recv_desc->rd0 & RD0_RACT) == 0) {
<> 144:ef7eb2e8f9f7 366 /* Receives 1 frame */
<> 144:ef7eb2e8f9f7 367 if (((p_recv_desc->rd0 & RD0_RFE) != 0) && ((p_recv_desc->rd0 & RD0_RFS_ERROR) != 0)) {
<> 144:ef7eb2e8f9f7 368 /* Receive frame error */
<> 144:ef7eb2e8f9f7 369 /* Sets the receive descriptor to receive again */
<> 144:ef7eb2e8f9f7 370 p_recv_desc->rd0 &= (RD0_RACT | RD0_RDLE);
<> 144:ef7eb2e8f9f7 371 p_recv_desc->rd0 |= RD0_RACT;
<> 144:ef7eb2e8f9f7 372 if ((start_stop == 1) && ((ETHEREDRRR0 & EDRRR0_RR) == 0)) {
<> 144:ef7eb2e8f9f7 373 ETHEREDRRR0 |= EDRRR0_RR;
<> 144:ef7eb2e8f9f7 374 }
<> 144:ef7eb2e8f9f7 375 } else {
<> 144:ef7eb2e8f9f7 376 /* Copies the received frame */
<> 144:ef7eb2e8f9f7 377 rx_read_offset = 0;
<> 144:ef7eb2e8f9f7 378 p_recv_end_desc = p_recv_desc;
<> 144:ef7eb2e8f9f7 379 receive_size = (p_recv_desc->rd1 & RD1_RDL_MSK); /* number of bytes received */
<> 144:ef7eb2e8f9f7 380 }
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 /* Update the current descriptor */
<> 144:ef7eb2e8f9f7 383 recv_top_index++;
<> 144:ef7eb2e8f9f7 384 if (recv_top_index >= NUM_OF_TX_DESCRIPTOR) {
<> 144:ef7eb2e8f9f7 385 recv_top_index = 0;
<> 144:ef7eb2e8f9f7 386 }
<> 144:ef7eb2e8f9f7 387 }
<> 144:ef7eb2e8f9f7 388 }
<> 144:ef7eb2e8f9f7 389
<> 144:ef7eb2e8f9f7 390 return receive_size;
<> 144:ef7eb2e8f9f7 391 }
<> 144:ef7eb2e8f9f7 392
<> 144:ef7eb2e8f9f7 393 int ethernet_read(char *data, int dlen) {
<> 144:ef7eb2e8f9f7 394 edmac_recv_desc_t *p_recv_desc = p_recv_end_desc; /* Read top descriptor */
<> 144:ef7eb2e8f9f7 395 int32_t copy_size;
<> 144:ef7eb2e8f9f7 396
<> 144:ef7eb2e8f9f7 397 if ((data == NULL) || (dlen < 0) || (p_recv_desc == NULL)) {
<> 144:ef7eb2e8f9f7 398 copy_size = 0;
<> 144:ef7eb2e8f9f7 399 } else {
<> 144:ef7eb2e8f9f7 400 copy_size = (p_recv_desc->rd1 & RD1_RDL_MSK) - rx_read_offset;
<> 144:ef7eb2e8f9f7 401 if (copy_size > dlen) {
<> 144:ef7eb2e8f9f7 402 copy_size = dlen;
<> 144:ef7eb2e8f9f7 403 }
<> 144:ef7eb2e8f9f7 404 (void)memcpy(data, &p_recv_desc->rd2[rx_read_offset], (size_t)copy_size);
<> 144:ef7eb2e8f9f7 405 rx_read_offset += copy_size;
<> 144:ef7eb2e8f9f7 406 }
<> 144:ef7eb2e8f9f7 407
<> 144:ef7eb2e8f9f7 408 return copy_size;
<> 144:ef7eb2e8f9f7 409 }
<> 144:ef7eb2e8f9f7 410
<> 144:ef7eb2e8f9f7 411 void ethernet_address(char *mac) {
<> 144:ef7eb2e8f9f7 412 if (mac != NULL) {
<> 144:ef7eb2e8f9f7 413 mbed_mac_address(mac); /* Get MAC Address */
<> 144:ef7eb2e8f9f7 414 }
<> 144:ef7eb2e8f9f7 415 }
<> 144:ef7eb2e8f9f7 416
<> 144:ef7eb2e8f9f7 417 int ethernet_link(void) {
<> 144:ef7eb2e8f9f7 418 int32_t ret;
<> 144:ef7eb2e8f9f7 419 uint16_t data;
<> 144:ef7eb2e8f9f7 420
<> 144:ef7eb2e8f9f7 421 data = phy_reg_read(BASIC_MODE_STATUS_REG);
<> 144:ef7eb2e8f9f7 422 if (((uint32_t)data & BASIC_STS_MSK_LINK) != 0) {
<> 144:ef7eb2e8f9f7 423 ret = 1;
<> 144:ef7eb2e8f9f7 424 } else {
<> 144:ef7eb2e8f9f7 425 ret = 0;
<> 144:ef7eb2e8f9f7 426 }
<> 144:ef7eb2e8f9f7 427
<> 144:ef7eb2e8f9f7 428 return ret;
<> 144:ef7eb2e8f9f7 429 }
<> 144:ef7eb2e8f9f7 430
<> 144:ef7eb2e8f9f7 431 void ethernet_set_link(int speed, int duplex) {
<> 144:ef7eb2e8f9f7 432 uint16_t data;
<> 144:ef7eb2e8f9f7 433 int32_t i;
<> 144:ef7eb2e8f9f7 434 int32_t link;
<> 144:ef7eb2e8f9f7 435
<> 144:ef7eb2e8f9f7 436 if ((speed < 0) || (speed > 1)) {
<> 144:ef7eb2e8f9f7 437 data = 0x1000; /* Auto-Negotiation Enable */
<> 144:ef7eb2e8f9f7 438 phy_reg_write(BASIC_MODE_CONTROL_REG, data);
<> 144:ef7eb2e8f9f7 439 for (i = 0; i < 1000; i++) {
<> 144:ef7eb2e8f9f7 440 data = phy_reg_read(BASIC_MODE_STATUS_REG);
<> 144:ef7eb2e8f9f7 441 if (((uint32_t)data & BASIC_STS_MSK_AUTO_CMP) != 0) {
<> 144:ef7eb2e8f9f7 442 break;
<> 144:ef7eb2e8f9f7 443 }
<> 144:ef7eb2e8f9f7 444 wait_100us(10);
<> 144:ef7eb2e8f9f7 445 }
<> 144:ef7eb2e8f9f7 446 } else {
<> 144:ef7eb2e8f9f7 447 data = (uint16_t)(((uint32_t)speed << 13) | ((uint32_t)duplex << 8));
<> 144:ef7eb2e8f9f7 448 phy_reg_write(BASIC_MODE_CONTROL_REG, data);
<> 144:ef7eb2e8f9f7 449 wait_100us(1);
<> 144:ef7eb2e8f9f7 450 }
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 link = ethernetext_chk_link_mode();
<> 144:ef7eb2e8f9f7 453 ethernetext_set_link_mode(link);
<> 144:ef7eb2e8f9f7 454 }
<> 144:ef7eb2e8f9f7 455
<> 144:ef7eb2e8f9f7 456 void INT_Ether(void) {
<> 144:ef7eb2e8f9f7 457 uint32_t stat_edmac;
<> 144:ef7eb2e8f9f7 458 uint32_t stat_etherc;
<> 144:ef7eb2e8f9f7 459
<> 144:ef7eb2e8f9f7 460 /* Clear the interrupt request flag */
<> 144:ef7eb2e8f9f7 461 stat_edmac = (ETHEREESR0 & ETHEREESIPR0); /* Targets are restricted to allowed interrupts */
<> 144:ef7eb2e8f9f7 462 ETHEREESR0 = stat_edmac;
<> 144:ef7eb2e8f9f7 463 /* Reception-related */
<> 144:ef7eb2e8f9f7 464 if (stat_edmac & EDMAC_EESIPR_INI_RECV) {
<> 144:ef7eb2e8f9f7 465 if (p_recv_cb_fnc != NULL) {
<> 144:ef7eb2e8f9f7 466 p_recv_cb_fnc();
<> 144:ef7eb2e8f9f7 467 }
<> 144:ef7eb2e8f9f7 468 }
<> 144:ef7eb2e8f9f7 469 /* E-MAC-related */
<> 144:ef7eb2e8f9f7 470 if (stat_edmac & EDMAC_EESIPR_INI_EtherC) {
<> 144:ef7eb2e8f9f7 471 /* Clear the interrupt request flag */
<> 144:ef7eb2e8f9f7 472 stat_etherc = (ETHERECSR0 & ETHERECSIPR0); /* Targets are restricted to allowed interrupts */
<> 144:ef7eb2e8f9f7 473 ETHERECSR0 = stat_etherc;
<> 144:ef7eb2e8f9f7 474 }
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 static void lan_reg_reset(void) {
<> 144:ef7eb2e8f9f7 478 volatile int32_t j = 400; /* Wait for B dia 256 cycles ((I dia/B dia)*256)/6cyc = 8*256/6 = 342 */
<> 144:ef7eb2e8f9f7 479
<> 144:ef7eb2e8f9f7 480 ETHERARSTR |= 0x00000001; /* ETHER software reset */
<> 144:ef7eb2e8f9f7 481 while (j--) {
<> 144:ef7eb2e8f9f7 482 /* Do Nothing */
<> 144:ef7eb2e8f9f7 483 }
<> 144:ef7eb2e8f9f7 484
<> 144:ef7eb2e8f9f7 485 ETHEREDSR0 |= 0x00000003; /* E-DMAC software reset */
<> 144:ef7eb2e8f9f7 486 ETHEREDMR0 |= 0x00000003; /* Set SWRR and SWRT simultaneously */
<> 144:ef7eb2e8f9f7 487
<> 144:ef7eb2e8f9f7 488 /* Check clear software reset */
<> 144:ef7eb2e8f9f7 489 while ((ETHEREDMR0 & 0x00000003) != 0) {
<> 144:ef7eb2e8f9f7 490 /* Do Nothing */
<> 144:ef7eb2e8f9f7 491 }
<> 144:ef7eb2e8f9f7 492 }
<> 144:ef7eb2e8f9f7 493
<> 144:ef7eb2e8f9f7 494 static void lan_desc_create(void) {
<> 144:ef7eb2e8f9f7 495 int32_t i;
<> 144:ef7eb2e8f9f7 496 uint8_t *p_memory_top;
<> 144:ef7eb2e8f9f7 497
<> 144:ef7eb2e8f9f7 498 (void)memset((void *)ethernet_nc_memory, 0, sizeof(ethernet_nc_memory));
<> 144:ef7eb2e8f9f7 499 p_memory_top = ethernet_nc_memory;
<> 144:ef7eb2e8f9f7 500
<> 144:ef7eb2e8f9f7 501 /* Descriptor area configuration */
<> 144:ef7eb2e8f9f7 502 p_eth_desc_dsend = (edmac_send_desc_t *)p_memory_top;
<> 144:ef7eb2e8f9f7 503 p_memory_top += (sizeof(edmac_send_desc_t) * NUM_OF_TX_DESCRIPTOR);
<> 144:ef7eb2e8f9f7 504 p_eth_desc_drecv = (edmac_recv_desc_t *)p_memory_top;
<> 144:ef7eb2e8f9f7 505 p_memory_top += (sizeof(edmac_recv_desc_t) * NUM_OF_RX_DESCRIPTOR);
<> 144:ef7eb2e8f9f7 506
<> 144:ef7eb2e8f9f7 507 /* Transmit descriptor */
<> 144:ef7eb2e8f9f7 508 for (i = 0; i < NUM_OF_TX_DESCRIPTOR; i++) {
<> 144:ef7eb2e8f9f7 509 p_eth_desc_dsend[i].td2 = p_memory_top; /* TD2 TBA */
<> 144:ef7eb2e8f9f7 510 p_memory_top += SIZE_OF_BUFFER;
<> 144:ef7eb2e8f9f7 511 p_eth_desc_dsend[i].td1 = 0; /* TD1 TDL */
<> 144:ef7eb2e8f9f7 512 p_eth_desc_dsend[i].td0 = TD0_TFP_TOP_BOTTOM; /* TD0:1frame/1buf1buf, transmission disabled */
<> 144:ef7eb2e8f9f7 513 }
<> 144:ef7eb2e8f9f7 514 p_eth_desc_dsend[i - 1].td0 |= TD0_TDLE; /* Set the last descriptor */
<> 144:ef7eb2e8f9f7 515
<> 144:ef7eb2e8f9f7 516 /* Receive descriptor */
<> 144:ef7eb2e8f9f7 517 for (i = 0; i < NUM_OF_RX_DESCRIPTOR; i++) {
<> 144:ef7eb2e8f9f7 518 p_eth_desc_drecv[i].rd2 = p_memory_top; /* RD2 RBA */
<> 144:ef7eb2e8f9f7 519 p_memory_top += SIZE_OF_BUFFER;
<> 144:ef7eb2e8f9f7 520 p_eth_desc_drecv[i].rd1 = ((uint32_t)SIZE_OF_BUFFER << 16); /* RD1 RBL */
<> 144:ef7eb2e8f9f7 521 p_eth_desc_drecv[i].rd0 = RD0_RACT; /* RD0:reception enabled */
<> 144:ef7eb2e8f9f7 522 }
<> 144:ef7eb2e8f9f7 523 p_eth_desc_drecv[i - 1].rd0 |= RD0_RDLE; /* Set the last descriptor */
<> 144:ef7eb2e8f9f7 524
<> 144:ef7eb2e8f9f7 525 /* Initialize descriptor management information */
<> 144:ef7eb2e8f9f7 526 send_top_index = 0;
<> 144:ef7eb2e8f9f7 527 recv_top_index = 0;
<> 144:ef7eb2e8f9f7 528 rx_read_offset = 0;
<> 144:ef7eb2e8f9f7 529 tx_wite_offset = 0;
<> 144:ef7eb2e8f9f7 530 p_recv_end_desc = NULL;
<> 144:ef7eb2e8f9f7 531 }
<> 144:ef7eb2e8f9f7 532
<> 144:ef7eb2e8f9f7 533 static void lan_reg_set(int32_t link) {
<> 144:ef7eb2e8f9f7 534 /* MAC address setting */
<> 144:ef7eb2e8f9f7 535 ETHERMAHR0 = ((uint32_t)mac_addr[0] << 24)
<> 144:ef7eb2e8f9f7 536 | ((uint32_t)mac_addr[1] << 16)
<> 144:ef7eb2e8f9f7 537 | ((uint32_t)mac_addr[2] << 8)
<> 144:ef7eb2e8f9f7 538 | (uint32_t)mac_addr[3];
<> 144:ef7eb2e8f9f7 539 ETHERMALR0 = ((uint32_t)mac_addr[4] << 8)
<> 144:ef7eb2e8f9f7 540 | (uint32_t)mac_addr[5];
<> 144:ef7eb2e8f9f7 541
<> 144:ef7eb2e8f9f7 542 /* E-DMAC */
<> 144:ef7eb2e8f9f7 543 ETHERTDLAR0 = (uint32_t)&p_eth_desc_dsend[0];
<> 144:ef7eb2e8f9f7 544 ETHERRDLAR0 = (uint32_t)&p_eth_desc_drecv[0];
<> 144:ef7eb2e8f9f7 545 ETHERTDFAR0 = (uint32_t)&p_eth_desc_dsend[0];
<> 144:ef7eb2e8f9f7 546 ETHERRDFAR0 = (uint32_t)&p_eth_desc_drecv[0];
<> 144:ef7eb2e8f9f7 547 ETHERTDFXR0 = (uint32_t)&p_eth_desc_dsend[NUM_OF_TX_DESCRIPTOR - 1];
<> 144:ef7eb2e8f9f7 548 ETHERRDFXR0 = (uint32_t)&p_eth_desc_drecv[NUM_OF_RX_DESCRIPTOR - 1];
<> 144:ef7eb2e8f9f7 549 ETHERTDFFR0 |= 0x00000001; /* TDLF Transmit Descriptor Queue Last Flag : Last descriptor (1) */
<> 144:ef7eb2e8f9f7 550 ETHERRDFFR0 |= 0x00000001; /* RDLF Receive Descriptor Queue Last Flag : Last descriptor (1) */
<> 144:ef7eb2e8f9f7 551 ETHEREDMR0 |= 0x00000040; /* Little endian */
<> 144:ef7eb2e8f9f7 552 ETHERTRSCER0 &= ~0x0003009F; /* All clear */
<> 144:ef7eb2e8f9f7 553 ETHERTFTR0 &= ~0x000007FF; /* TFT[10:0] Transmit FIFO Threshold : Store and forward modes (H'000) */
<> 144:ef7eb2e8f9f7 554 ETHERFDR0 |= 0x00000707; /* Transmit FIFO Size:2048 bytes, Receive FIFO Size:2048 bytes */
<> 144:ef7eb2e8f9f7 555 ETHERRMCR0 |= 0x00000001; /* RNC Receive Enable Control : Continuous reception enabled (1) */
<> 144:ef7eb2e8f9f7 556 ETHERFCFTR0 &= ~0x001F00FF;
<> 144:ef7eb2e8f9f7 557 ETHERFCFTR0 |= 0x00070007;
<> 144:ef7eb2e8f9f7 558 ETHERRPADIR0 &= ~0x001FFFFF; /* Padding Size:No padding insertion, Padding Slot:Inserts at first byte */
<> 144:ef7eb2e8f9f7 559
<> 144:ef7eb2e8f9f7 560 /* E-MAC */
<> 144:ef7eb2e8f9f7 561 ETHERECMR0 &= ~0x04BF2063; /* All clear */
<> 144:ef7eb2e8f9f7 562 ETHERRFLR0 &= ~0x0003FFFF; /* RFL[17:0] Receive Frame Length : 1518 bytes (H'00000) */
<> 144:ef7eb2e8f9f7 563 ETHERAPR0 &= ~0x0000FFFF; /* AP[15:0] Automatic PAUSE : Flow control is disabled (H'0000) */
<> 144:ef7eb2e8f9f7 564 ETHERMPR0 &= ~0x0000FFFF; /* MP[15:0] Manual PAUSE : Flow control is disabled (H'0000) */
<> 144:ef7eb2e8f9f7 565 ETHERTPAUSER0 &= ~0x0000FFFF; /* Upper Limit for Automatic PAUSE Frame : Retransmit count is unlimited */
<> 144:ef7eb2e8f9f7 566 ETHERCSMR &= ~0xC000003F; /* The result of checksum is not written back to the receive descriptor */
<> 144:ef7eb2e8f9f7 567 if ((link == FULL_TX) || (link == FULL_10M) || (link == NEGO_FAIL)) {
<> 144:ef7eb2e8f9f7 568 ETHERECMR0 |= 0x00000002; /* Set to full-duplex mode */
<> 144:ef7eb2e8f9f7 569 } else {
<> 144:ef7eb2e8f9f7 570 ETHERECMR0 &= ~0x00000002; /* Set to half-duplex mode */
<> 144:ef7eb2e8f9f7 571 }
<> 144:ef7eb2e8f9f7 572
<> 144:ef7eb2e8f9f7 573 /* Interrupt-related */
<> 144:ef7eb2e8f9f7 574 if (p_recv_cb_fnc != NULL) {
<> 144:ef7eb2e8f9f7 575 ETHEREESR0 |= 0xFF7F009F; /* Clear all status (by writing 1) */
<> 144:ef7eb2e8f9f7 576 ETHEREESIPR0 |= 0x00040000; /* FR Frame Reception (1) */
<> 144:ef7eb2e8f9f7 577 ETHERECSR0 |= 0x00000011; /* Clear all status (clear by writing 1) */
<> 144:ef7eb2e8f9f7 578 ETHERECSIPR0 &= ~0x00000011; /* PFROIP Disable, ICDIP Disable */
<> 144:ef7eb2e8f9f7 579 InterruptHandlerRegister(ETHERI_IRQn, INT_Ether); /* Ethernet interrupt handler registration */
<> 144:ef7eb2e8f9f7 580 GIC_SetPriority(ETHERI_IRQn, Interrupt_priority); /* Ethernet interrupt priority */
<> 144:ef7eb2e8f9f7 581 GIC_EnableIRQ(ETHERI_IRQn); /* Enables the E-DMAC interrupt */
<> 144:ef7eb2e8f9f7 582 }
<> 144:ef7eb2e8f9f7 583
<> 144:ef7eb2e8f9f7 584 ETHERECMR0 |= 0x00000060; /* RE Enable, TE Enable */
<> 144:ef7eb2e8f9f7 585
<> 144:ef7eb2e8f9f7 586 /* Enable transmission/reception */
<> 144:ef7eb2e8f9f7 587 if ((start_stop == 1) && ((ETHEREDRRR0 & 0x00000001) == 0)) {
<> 144:ef7eb2e8f9f7 588 ETHEREDRRR0 |= 0x00000001; /* RR */
<> 144:ef7eb2e8f9f7 589 }
<> 144:ef7eb2e8f9f7 590 }
<> 144:ef7eb2e8f9f7 591
<> 144:ef7eb2e8f9f7 592 static uint16_t phy_reg_read(uint16_t reg_addr) {
<> 144:ef7eb2e8f9f7 593 uint16_t data;
<> 144:ef7eb2e8f9f7 594
<> 144:ef7eb2e8f9f7 595 mii_preamble();
<> 144:ef7eb2e8f9f7 596 mii_cmd(reg_addr, PHY_READ);
<> 144:ef7eb2e8f9f7 597 mii_z();
<> 144:ef7eb2e8f9f7 598 mii_reg_read(&data);
<> 144:ef7eb2e8f9f7 599 mii_z();
<> 144:ef7eb2e8f9f7 600
<> 144:ef7eb2e8f9f7 601 return data;
<> 144:ef7eb2e8f9f7 602 }
<> 144:ef7eb2e8f9f7 603
<> 144:ef7eb2e8f9f7 604 static void phy_reg_write(uint16_t reg_addr, uint16_t data) {
<> 144:ef7eb2e8f9f7 605 mii_preamble();
<> 144:ef7eb2e8f9f7 606 mii_cmd(reg_addr, PHY_WRITE);
<> 144:ef7eb2e8f9f7 607 mii_write_1();
<> 144:ef7eb2e8f9f7 608 mii_write_0();
<> 144:ef7eb2e8f9f7 609 mii_reg_write(data);
<> 144:ef7eb2e8f9f7 610 mii_z();
<> 144:ef7eb2e8f9f7 611 }
<> 144:ef7eb2e8f9f7 612
<> 144:ef7eb2e8f9f7 613 static void mii_preamble(void) {
<> 144:ef7eb2e8f9f7 614 int32_t i = 32;
<> 144:ef7eb2e8f9f7 615
<> 144:ef7eb2e8f9f7 616 for (i = 32; i > 0; i--) {
<> 144:ef7eb2e8f9f7 617 /* 1 is output via the MII (Media Independent Interface) block. */
<> 144:ef7eb2e8f9f7 618 mii_write_1();
<> 144:ef7eb2e8f9f7 619 }
<> 144:ef7eb2e8f9f7 620 }
<> 144:ef7eb2e8f9f7 621
<> 144:ef7eb2e8f9f7 622 static void mii_cmd(uint16_t reg_addr, uint32_t option) {
<> 144:ef7eb2e8f9f7 623 int32_t i;
<> 144:ef7eb2e8f9f7 624 uint16_t data = 0;
<> 144:ef7eb2e8f9f7 625
<> 144:ef7eb2e8f9f7 626 data |= (PHY_ST << 14); /* ST code */
<> 144:ef7eb2e8f9f7 627 data |= (option << 12); /* OP code */
<> 144:ef7eb2e8f9f7 628 data |= (PHY_ADDR << 7); /* PHY Address */
<> 144:ef7eb2e8f9f7 629 data |= (uint16_t)(reg_addr << 2); /* Reg Address */
<> 144:ef7eb2e8f9f7 630 for (i = 14; i > 0; i--) {
<> 144:ef7eb2e8f9f7 631 if ((data & 0x8000) == 0) {
<> 144:ef7eb2e8f9f7 632 mii_write_0();
<> 144:ef7eb2e8f9f7 633 } else {
<> 144:ef7eb2e8f9f7 634 mii_write_1();
<> 144:ef7eb2e8f9f7 635 }
<> 144:ef7eb2e8f9f7 636 data <<= 1;
<> 144:ef7eb2e8f9f7 637 }
<> 144:ef7eb2e8f9f7 638 }
<> 144:ef7eb2e8f9f7 639
<> 144:ef7eb2e8f9f7 640 static void mii_reg_read(uint16_t *data) {
<> 144:ef7eb2e8f9f7 641 int32_t i;
<> 144:ef7eb2e8f9f7 642 uint16_t reg_data = 0;
<> 144:ef7eb2e8f9f7 643
<> 144:ef7eb2e8f9f7 644 /* Data are read in one bit at a time */
<> 144:ef7eb2e8f9f7 645 for (i = 16; i > 0; i--) {
<> 144:ef7eb2e8f9f7 646 set_ether_pir(PIR0_MDC_LOW);
<> 144:ef7eb2e8f9f7 647 set_ether_pir(PIR0_MDC_HIGH);
<> 144:ef7eb2e8f9f7 648 reg_data <<= 1;
<> 144:ef7eb2e8f9f7 649 reg_data |= (uint16_t)((ETHERPIR0 & PIR0_MDI) >> 3); /* MDI read */
<> 144:ef7eb2e8f9f7 650 set_ether_pir(PIR0_MDC_HIGH);
<> 144:ef7eb2e8f9f7 651 set_ether_pir(PIR0_MDC_LOW);
<> 144:ef7eb2e8f9f7 652 }
<> 144:ef7eb2e8f9f7 653 *data = reg_data;
<> 144:ef7eb2e8f9f7 654 }
<> 144:ef7eb2e8f9f7 655
<> 144:ef7eb2e8f9f7 656 static void mii_reg_write(uint16_t data) {
<> 144:ef7eb2e8f9f7 657 int32_t i;
<> 144:ef7eb2e8f9f7 658
<> 144:ef7eb2e8f9f7 659 /* Data are written one bit at a time */
<> 144:ef7eb2e8f9f7 660 for (i = 16; i > 0; i--) {
<> 144:ef7eb2e8f9f7 661 if ((data & 0x8000) == 0) {
<> 144:ef7eb2e8f9f7 662 mii_write_0();
<> 144:ef7eb2e8f9f7 663 } else {
<> 144:ef7eb2e8f9f7 664 mii_write_1();
<> 144:ef7eb2e8f9f7 665 }
<> 144:ef7eb2e8f9f7 666 data <<= 1;
<> 144:ef7eb2e8f9f7 667 }
<> 144:ef7eb2e8f9f7 668 }
<> 144:ef7eb2e8f9f7 669
<> 144:ef7eb2e8f9f7 670 static void mii_z(void) {
<> 144:ef7eb2e8f9f7 671 set_ether_pir(PIR0_MDC_LOW);
<> 144:ef7eb2e8f9f7 672 set_ether_pir(PIR0_MDC_HIGH);
<> 144:ef7eb2e8f9f7 673 set_ether_pir(PIR0_MDC_HIGH);
<> 144:ef7eb2e8f9f7 674 set_ether_pir(PIR0_MDC_LOW);
<> 144:ef7eb2e8f9f7 675 }
<> 144:ef7eb2e8f9f7 676
<> 144:ef7eb2e8f9f7 677 static void mii_write_1(void) {
<> 144:ef7eb2e8f9f7 678 set_ether_pir(PIR0_MDO | PIR0_MMD);
<> 144:ef7eb2e8f9f7 679 set_ether_pir(PIR0_MDO | PIR0_MMD | PIR0_MDC);
<> 144:ef7eb2e8f9f7 680 set_ether_pir(PIR0_MDO | PIR0_MMD | PIR0_MDC);
<> 144:ef7eb2e8f9f7 681 set_ether_pir(PIR0_MDO | PIR0_MMD);
<> 144:ef7eb2e8f9f7 682 }
<> 144:ef7eb2e8f9f7 683
<> 144:ef7eb2e8f9f7 684 static void mii_write_0(void) {
<> 144:ef7eb2e8f9f7 685 set_ether_pir(PIR0_MMD);
<> 144:ef7eb2e8f9f7 686 set_ether_pir(PIR0_MMD | PIR0_MDC);
<> 144:ef7eb2e8f9f7 687 set_ether_pir(PIR0_MMD | PIR0_MDC);
<> 144:ef7eb2e8f9f7 688 set_ether_pir(PIR0_MMD);
<> 144:ef7eb2e8f9f7 689 }
<> 144:ef7eb2e8f9f7 690
<> 144:ef7eb2e8f9f7 691 static void set_ether_pir(uint32_t set_data) {
<> 144:ef7eb2e8f9f7 692 int32_t i;
<> 144:ef7eb2e8f9f7 693
<> 144:ef7eb2e8f9f7 694 for (i = MDC_WAIT; i > 0; i--) {
<> 144:ef7eb2e8f9f7 695 ETHERPIR0 = set_data;
<> 144:ef7eb2e8f9f7 696 }
<> 144:ef7eb2e8f9f7 697 }
<> 144:ef7eb2e8f9f7 698
<> 144:ef7eb2e8f9f7 699 static void wait_100us(int32_t wait_cnt) {
<> 144:ef7eb2e8f9f7 700 volatile int32_t j = LOOP_100us * wait_cnt;
<> 144:ef7eb2e8f9f7 701
<> 144:ef7eb2e8f9f7 702 while (--j) {
<> 144:ef7eb2e8f9f7 703 /* Do Nothing */
<> 144:ef7eb2e8f9f7 704 }
<> 144:ef7eb2e8f9f7 705 }