added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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 }