Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file s7g2_eth.c
Sergunb 0:8918a71cdbe9 3 * @brief Renesas Synergy S7G2 Ethernet MAC controller
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneTCP Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL NIC_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include "bsp_irq_cfg.h"
Sergunb 0:8918a71cdbe9 34 #include "r7fs7g2x.h"
Sergunb 0:8918a71cdbe9 35 #include "core/net.h"
Sergunb 0:8918a71cdbe9 36 #include "drivers/s7g2_eth.h"
Sergunb 0:8918a71cdbe9 37 #include "debug.h"
Sergunb 0:8918a71cdbe9 38
Sergunb 0:8918a71cdbe9 39 //Underlying network interface
Sergunb 0:8918a71cdbe9 40 static NetInterface *nicDriverInterface;
Sergunb 0:8918a71cdbe9 41
Sergunb 0:8918a71cdbe9 42 //IAR EWARM compiler?
Sergunb 0:8918a71cdbe9 43 #if defined(__ICCARM__)
Sergunb 0:8918a71cdbe9 44
Sergunb 0:8918a71cdbe9 45 //Transmit buffer
Sergunb 0:8918a71cdbe9 46 #pragma data_alignment = 32
Sergunb 0:8918a71cdbe9 47 static uint8_t txBuffer[S7G2_ETH_TX_BUFFER_COUNT][S7G2_ETH_TX_BUFFER_SIZE];
Sergunb 0:8918a71cdbe9 48 //Receive buffer
Sergunb 0:8918a71cdbe9 49 #pragma data_alignment = 32
Sergunb 0:8918a71cdbe9 50 static uint8_t rxBuffer[S7G2_ETH_RX_BUFFER_COUNT][S7G2_ETH_RX_BUFFER_SIZE];
Sergunb 0:8918a71cdbe9 51 //Transmit DMA descriptors
Sergunb 0:8918a71cdbe9 52 #pragma data_alignment = 32
Sergunb 0:8918a71cdbe9 53 static S7g2TxDmaDesc txDmaDesc[S7G2_ETH_TX_BUFFER_COUNT];
Sergunb 0:8918a71cdbe9 54 //Receive DMA descriptors
Sergunb 0:8918a71cdbe9 55 #pragma data_alignment = 32
Sergunb 0:8918a71cdbe9 56 static S7g2RxDmaDesc rxDmaDesc[S7G2_ETH_RX_BUFFER_COUNT];
Sergunb 0:8918a71cdbe9 57
Sergunb 0:8918a71cdbe9 58 //ARM or GCC compiler?
Sergunb 0:8918a71cdbe9 59 #else
Sergunb 0:8918a71cdbe9 60
Sergunb 0:8918a71cdbe9 61 //Transmit buffer
Sergunb 0:8918a71cdbe9 62 static uint8_t txBuffer[S7G2_ETH_TX_BUFFER_COUNT][S7G2_ETH_TX_BUFFER_SIZE]
Sergunb 0:8918a71cdbe9 63 __attribute__((aligned(32)));
Sergunb 0:8918a71cdbe9 64 //Receive buffer
Sergunb 0:8918a71cdbe9 65 static uint8_t rxBuffer[S7G2_ETH_RX_BUFFER_COUNT][S7G2_ETH_RX_BUFFER_SIZE]
Sergunb 0:8918a71cdbe9 66 __attribute__((aligned(32)));
Sergunb 0:8918a71cdbe9 67 //Transmit DMA descriptors
Sergunb 0:8918a71cdbe9 68 static S7g2TxDmaDesc txDmaDesc[S7G2_ETH_TX_BUFFER_COUNT]
Sergunb 0:8918a71cdbe9 69 __attribute__((aligned(32)));
Sergunb 0:8918a71cdbe9 70 //Receive DMA descriptors
Sergunb 0:8918a71cdbe9 71 static S7g2RxDmaDesc rxDmaDesc[S7G2_ETH_RX_BUFFER_COUNT]
Sergunb 0:8918a71cdbe9 72 __attribute__((aligned(32)));
Sergunb 0:8918a71cdbe9 73
Sergunb 0:8918a71cdbe9 74 #endif
Sergunb 0:8918a71cdbe9 75
Sergunb 0:8918a71cdbe9 76 //Current transmit descriptor
Sergunb 0:8918a71cdbe9 77 static uint_t txIndex;
Sergunb 0:8918a71cdbe9 78 //Current receive descriptor
Sergunb 0:8918a71cdbe9 79 static uint_t rxIndex;
Sergunb 0:8918a71cdbe9 80
Sergunb 0:8918a71cdbe9 81
Sergunb 0:8918a71cdbe9 82 /**
Sergunb 0:8918a71cdbe9 83 * @brief S7G2 Ethernet MAC driver
Sergunb 0:8918a71cdbe9 84 **/
Sergunb 0:8918a71cdbe9 85
Sergunb 0:8918a71cdbe9 86 const NicDriver s7g2EthDriver =
Sergunb 0:8918a71cdbe9 87 {
Sergunb 0:8918a71cdbe9 88 NIC_TYPE_ETHERNET,
Sergunb 0:8918a71cdbe9 89 ETH_MTU,
Sergunb 0:8918a71cdbe9 90 s7g2EthInit,
Sergunb 0:8918a71cdbe9 91 s7g2EthTick,
Sergunb 0:8918a71cdbe9 92 s7g2EthEnableIrq,
Sergunb 0:8918a71cdbe9 93 s7g2EthDisableIrq,
Sergunb 0:8918a71cdbe9 94 s7g2EthEventHandler,
Sergunb 0:8918a71cdbe9 95 s7g2EthSendPacket,
Sergunb 0:8918a71cdbe9 96 s7g2EthSetMulticastFilter,
Sergunb 0:8918a71cdbe9 97 s7g2EthUpdateMacConfig,
Sergunb 0:8918a71cdbe9 98 s7g2EthWritePhyReg,
Sergunb 0:8918a71cdbe9 99 s7g2EthReadPhyReg,
Sergunb 0:8918a71cdbe9 100 TRUE,
Sergunb 0:8918a71cdbe9 101 TRUE,
Sergunb 0:8918a71cdbe9 102 TRUE,
Sergunb 0:8918a71cdbe9 103 TRUE
Sergunb 0:8918a71cdbe9 104 };
Sergunb 0:8918a71cdbe9 105
Sergunb 0:8918a71cdbe9 106
Sergunb 0:8918a71cdbe9 107 /**
Sergunb 0:8918a71cdbe9 108 * @brief S7G2 Ethernet MAC initialization
Sergunb 0:8918a71cdbe9 109 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 110 * @return Error code
Sergunb 0:8918a71cdbe9 111 **/
Sergunb 0:8918a71cdbe9 112
Sergunb 0:8918a71cdbe9 113 error_t s7g2EthInit(NetInterface *interface)
Sergunb 0:8918a71cdbe9 114 {
Sergunb 0:8918a71cdbe9 115 error_t error;
Sergunb 0:8918a71cdbe9 116
Sergunb 0:8918a71cdbe9 117 //Debug message
Sergunb 0:8918a71cdbe9 118 TRACE_INFO("Initializing S7G2 Ethernet MAC...\r\n");
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 //Save underlying network interface
Sergunb 0:8918a71cdbe9 121 nicDriverInterface = interface;
Sergunb 0:8918a71cdbe9 122
Sergunb 0:8918a71cdbe9 123 //Disable protection
Sergunb 0:8918a71cdbe9 124 R_SYSTEM->PRCR = 0xA50B;
Sergunb 0:8918a71cdbe9 125 //Cancel EDMAC1 module stop state
Sergunb 0:8918a71cdbe9 126 R_MSTP->MSTPCRB_b.MSTPB14 = 0;
Sergunb 0:8918a71cdbe9 127 //Enable protection
Sergunb 0:8918a71cdbe9 128 R_SYSTEM->PRCR = 0xA500;
Sergunb 0:8918a71cdbe9 129
Sergunb 0:8918a71cdbe9 130 //GPIO configuration
Sergunb 0:8918a71cdbe9 131 s7g2EthInitGpio(interface);
Sergunb 0:8918a71cdbe9 132
Sergunb 0:8918a71cdbe9 133 //Reset EDMAC1 module
Sergunb 0:8918a71cdbe9 134 R_EDMAC1->EDMR_b.SWR = 1;
Sergunb 0:8918a71cdbe9 135 sleep(10);
Sergunb 0:8918a71cdbe9 136
Sergunb 0:8918a71cdbe9 137 //PHY transceiver initialization
Sergunb 0:8918a71cdbe9 138 error = interface->phyDriver->init(interface);
Sergunb 0:8918a71cdbe9 139 //Failed to initialize PHY transceiver?
Sergunb 0:8918a71cdbe9 140 if(error)
Sergunb 0:8918a71cdbe9 141 return error;
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 //Initialize DMA descriptor lists
Sergunb 0:8918a71cdbe9 144 s7g2EthInitDmaDesc(interface);
Sergunb 0:8918a71cdbe9 145
Sergunb 0:8918a71cdbe9 146 //Maximum frame length that can be accepted
Sergunb 0:8918a71cdbe9 147 R_ETHERC1->RFLR = 1518;
Sergunb 0:8918a71cdbe9 148 //Set default inter packet gap (96-bit time)
Sergunb 0:8918a71cdbe9 149 R_ETHERC1->IPGR = 0x14;
Sergunb 0:8918a71cdbe9 150
Sergunb 0:8918a71cdbe9 151 //Set the upper 32 bits of the MAC address
Sergunb 0:8918a71cdbe9 152 R_ETHERC1->MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
Sergunb 0:8918a71cdbe9 153 (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
Sergunb 0:8918a71cdbe9 154
Sergunb 0:8918a71cdbe9 155 //Set the lower 16 bits of the MAC address
Sergunb 0:8918a71cdbe9 156 R_ETHERC1->MALR_b.MALR = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
Sergunb 0:8918a71cdbe9 157
Sergunb 0:8918a71cdbe9 158 //Set descriptor length (16 bytes)
Sergunb 0:8918a71cdbe9 159 R_EDMAC1->EDMR_b.DL = 0;
Sergunb 0:8918a71cdbe9 160 //Select little endian mode
Sergunb 0:8918a71cdbe9 161 R_EDMAC1->EDMR_b.DE = 1;
Sergunb 0:8918a71cdbe9 162 //Use store and forward mode
Sergunb 0:8918a71cdbe9 163 R_EDMAC1->TFTR_b.TFT = 0;
Sergunb 0:8918a71cdbe9 164
Sergunb 0:8918a71cdbe9 165 //Set transmit FIFO size (2048 bytes)
Sergunb 0:8918a71cdbe9 166 R_EDMAC1->FDR_b.TFD = 7;
Sergunb 0:8918a71cdbe9 167 //Set receive FIFO size (2048 bytes)
Sergunb 0:8918a71cdbe9 168 R_EDMAC1->FDR_b.RFD = 7;
Sergunb 0:8918a71cdbe9 169
Sergunb 0:8918a71cdbe9 170 //Enable continuous reception of multiple frames
Sergunb 0:8918a71cdbe9 171 R_EDMAC1->RMCR_b.RNR = 1;
Sergunb 0:8918a71cdbe9 172
Sergunb 0:8918a71cdbe9 173 //Accept transmit interrupt notifications
Sergunb 0:8918a71cdbe9 174 R_EDMAC1->TRIMD_b.TIM = 0;
Sergunb 0:8918a71cdbe9 175 R_EDMAC1->TRIMD_b.TIS = 1;
Sergunb 0:8918a71cdbe9 176
Sergunb 0:8918a71cdbe9 177 //Disable all EDMAC interrupts
Sergunb 0:8918a71cdbe9 178 R_EDMAC1->EESIPR = 0;
Sergunb 0:8918a71cdbe9 179 //Enable only the desired EDMAC interrupts
Sergunb 0:8918a71cdbe9 180 R_EDMAC1->EESIPR_b.TWBIP = 1;
Sergunb 0:8918a71cdbe9 181 R_EDMAC1->EESIPR_b.FRIP = 1;
Sergunb 0:8918a71cdbe9 182
Sergunb 0:8918a71cdbe9 183 //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
Sergunb 0:8918a71cdbe9 184 NVIC_SetPriorityGrouping(S7G2_ETH_IRQ_PRIORITY_GROUPING);
Sergunb 0:8918a71cdbe9 185
Sergunb 0:8918a71cdbe9 186 //Configure EDMAC interrupt priority
Sergunb 0:8918a71cdbe9 187 NVIC_SetPriority(ETHER_EINT1_IRQn, NVIC_EncodePriority(S7G2_ETH_IRQ_PRIORITY_GROUPING,
Sergunb 0:8918a71cdbe9 188 S7G2_ETH_IRQ_GROUP_PRIORITY, S7G2_ETH_IRQ_SUB_PRIORITY));
Sergunb 0:8918a71cdbe9 189
Sergunb 0:8918a71cdbe9 190 //Enable transmission and reception
Sergunb 0:8918a71cdbe9 191 R_ETHERC1->ECMR_b.TE = 1;
Sergunb 0:8918a71cdbe9 192 R_ETHERC1->ECMR_b.RE = 1;
Sergunb 0:8918a71cdbe9 193
Sergunb 0:8918a71cdbe9 194 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 195 R_EDMAC1->EDRRR_b.RR = 1;
Sergunb 0:8918a71cdbe9 196
Sergunb 0:8918a71cdbe9 197 //Accept any packets from the upper layer
Sergunb 0:8918a71cdbe9 198 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 199
Sergunb 0:8918a71cdbe9 200 //Successful initialization
Sergunb 0:8918a71cdbe9 201 return NO_ERROR;
Sergunb 0:8918a71cdbe9 202 }
Sergunb 0:8918a71cdbe9 203
Sergunb 0:8918a71cdbe9 204
Sergunb 0:8918a71cdbe9 205 //SK-S7G2 evaluation board?
Sergunb 0:8918a71cdbe9 206 #if defined(USE_SK_S7G2)
Sergunb 0:8918a71cdbe9 207
Sergunb 0:8918a71cdbe9 208 /**
Sergunb 0:8918a71cdbe9 209 * @brief GPIO configuration
Sergunb 0:8918a71cdbe9 210 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 211 **/
Sergunb 0:8918a71cdbe9 212
Sergunb 0:8918a71cdbe9 213 void s7g2EthInitGpio(NetInterface *interface)
Sergunb 0:8918a71cdbe9 214 {
Sergunb 0:8918a71cdbe9 215 //Unlock PFS registers
Sergunb 0:8918a71cdbe9 216 R_PMISC->PWPR_b.BOWI = 0;
Sergunb 0:8918a71cdbe9 217 R_PMISC->PWPR_b.PSFWE = 1;
Sergunb 0:8918a71cdbe9 218
Sergunb 0:8918a71cdbe9 219 //Select RMII interface mode
Sergunb 0:8918a71cdbe9 220 R_PMISC->PFENET_b.PHYMODE1 = 0;
Sergunb 0:8918a71cdbe9 221
Sergunb 0:8918a71cdbe9 222 //Configure ET1_MDC (P4_3)
Sergunb 0:8918a71cdbe9 223 R_PFS->P403PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 224 R_PFS->P403PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Configure ET1_MDIO (P4_4)
Sergunb 0:8918a71cdbe9 227 R_PFS->P404PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 228 R_PFS->P404PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 229
Sergunb 0:8918a71cdbe9 230 //Configure RMII1_TXD_EN (P4_5)
Sergunb 0:8918a71cdbe9 231 R_PFS->P405PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 232 R_PFS->P405PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 233
Sergunb 0:8918a71cdbe9 234 //Configure RMII1_TXD1 (P4_6)
Sergunb 0:8918a71cdbe9 235 R_PFS->P406PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 236 R_PFS->P406PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 237
Sergunb 0:8918a71cdbe9 238 //Configure RMII1_TXD0 (P7_0)
Sergunb 0:8918a71cdbe9 239 R_PFS->P700PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 240 R_PFS->P700PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 241
Sergunb 0:8918a71cdbe9 242 //Configure REF50CK1 (P7_1)
Sergunb 0:8918a71cdbe9 243 R_PFS->P701PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 244 R_PFS->P701PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 245
Sergunb 0:8918a71cdbe9 246 //Configure RMII1_RXD0 (P7_2)
Sergunb 0:8918a71cdbe9 247 R_PFS->P702PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 248 R_PFS->P702PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 249
Sergunb 0:8918a71cdbe9 250 //Configure RMII1_RXD1 (P7_3)
Sergunb 0:8918a71cdbe9 251 R_PFS->P703PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 252 R_PFS->P703PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 253
Sergunb 0:8918a71cdbe9 254 //Configure RMII1_RX_ER (P7_4)
Sergunb 0:8918a71cdbe9 255 R_PFS->P704PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 256 R_PFS->P704PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 257
Sergunb 0:8918a71cdbe9 258 //Configure RMII1_CRS_DV (P7_5)
Sergunb 0:8918a71cdbe9 259 R_PFS->P705PFS_b.PMR = 1;
Sergunb 0:8918a71cdbe9 260 R_PFS->P705PFS_b.PSEL = 23;
Sergunb 0:8918a71cdbe9 261
Sergunb 0:8918a71cdbe9 262 //Lock PFS registers
Sergunb 0:8918a71cdbe9 263 R_PMISC->PWPR_b.PSFWE = 0;
Sergunb 0:8918a71cdbe9 264 R_PMISC->PWPR_b.BOWI = 1;
Sergunb 0:8918a71cdbe9 265 }
Sergunb 0:8918a71cdbe9 266
Sergunb 0:8918a71cdbe9 267 #endif
Sergunb 0:8918a71cdbe9 268
Sergunb 0:8918a71cdbe9 269
Sergunb 0:8918a71cdbe9 270 /**
Sergunb 0:8918a71cdbe9 271 * @brief Initialize DMA descriptor lists
Sergunb 0:8918a71cdbe9 272 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 273 **/
Sergunb 0:8918a71cdbe9 274
Sergunb 0:8918a71cdbe9 275 void s7g2EthInitDmaDesc(NetInterface *interface)
Sergunb 0:8918a71cdbe9 276 {
Sergunb 0:8918a71cdbe9 277 uint_t i;
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Initialize TX descriptors
Sergunb 0:8918a71cdbe9 280 for(i = 0; i < S7G2_ETH_TX_BUFFER_COUNT; i++)
Sergunb 0:8918a71cdbe9 281 {
Sergunb 0:8918a71cdbe9 282 //The descriptor is initially owned by the application
Sergunb 0:8918a71cdbe9 283 txDmaDesc[i].td0 = 0;
Sergunb 0:8918a71cdbe9 284 //Transmit buffer length
Sergunb 0:8918a71cdbe9 285 txDmaDesc[i].td1 = 0;
Sergunb 0:8918a71cdbe9 286 //Transmit buffer address
Sergunb 0:8918a71cdbe9 287 txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
Sergunb 0:8918a71cdbe9 288 //Clear padding field
Sergunb 0:8918a71cdbe9 289 txDmaDesc[i].padding = 0;
Sergunb 0:8918a71cdbe9 290 }
Sergunb 0:8918a71cdbe9 291
Sergunb 0:8918a71cdbe9 292 //Mark the last descriptor entry with the TDLE flag
Sergunb 0:8918a71cdbe9 293 txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
Sergunb 0:8918a71cdbe9 294 //Initialize TX descriptor index
Sergunb 0:8918a71cdbe9 295 txIndex = 0;
Sergunb 0:8918a71cdbe9 296
Sergunb 0:8918a71cdbe9 297 //Initialize RX descriptors
Sergunb 0:8918a71cdbe9 298 for(i = 0; i < S7G2_ETH_RX_BUFFER_COUNT; i++)
Sergunb 0:8918a71cdbe9 299 {
Sergunb 0:8918a71cdbe9 300 //The descriptor is initially owned by the DMA
Sergunb 0:8918a71cdbe9 301 rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
Sergunb 0:8918a71cdbe9 302 //Receive buffer length
Sergunb 0:8918a71cdbe9 303 rxDmaDesc[i].rd1 = (S7G2_ETH_RX_BUFFER_SIZE << 16) & EDMAC_RD1_RBL;
Sergunb 0:8918a71cdbe9 304 //Receive buffer address
Sergunb 0:8918a71cdbe9 305 rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
Sergunb 0:8918a71cdbe9 306 //Clear padding field
Sergunb 0:8918a71cdbe9 307 rxDmaDesc[i].padding = 0;
Sergunb 0:8918a71cdbe9 308 }
Sergunb 0:8918a71cdbe9 309
Sergunb 0:8918a71cdbe9 310 //Mark the last descriptor entry with the RDLE flag
Sergunb 0:8918a71cdbe9 311 rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
Sergunb 0:8918a71cdbe9 312 //Initialize RX descriptor index
Sergunb 0:8918a71cdbe9 313 rxIndex = 0;
Sergunb 0:8918a71cdbe9 314
Sergunb 0:8918a71cdbe9 315 //Start address of the TX descriptor list
Sergunb 0:8918a71cdbe9 316 R_EDMAC1->TDLAR = (uint32_t) txDmaDesc;
Sergunb 0:8918a71cdbe9 317 //Start address of the RX descriptor list
Sergunb 0:8918a71cdbe9 318 R_EDMAC1->RDLAR = (uint32_t) rxDmaDesc;
Sergunb 0:8918a71cdbe9 319 }
Sergunb 0:8918a71cdbe9 320
Sergunb 0:8918a71cdbe9 321
Sergunb 0:8918a71cdbe9 322 /**
Sergunb 0:8918a71cdbe9 323 * @brief S7G2 Ethernet MAC timer handler
Sergunb 0:8918a71cdbe9 324 *
Sergunb 0:8918a71cdbe9 325 * This routine is periodically called by the TCP/IP stack to
Sergunb 0:8918a71cdbe9 326 * handle periodic operations such as polling the link state
Sergunb 0:8918a71cdbe9 327 *
Sergunb 0:8918a71cdbe9 328 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 329 **/
Sergunb 0:8918a71cdbe9 330
Sergunb 0:8918a71cdbe9 331 void s7g2EthTick(NetInterface *interface)
Sergunb 0:8918a71cdbe9 332 {
Sergunb 0:8918a71cdbe9 333 //Handle periodic operations
Sergunb 0:8918a71cdbe9 334 interface->phyDriver->tick(interface);
Sergunb 0:8918a71cdbe9 335 }
Sergunb 0:8918a71cdbe9 336
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338 /**
Sergunb 0:8918a71cdbe9 339 * @brief Enable interrupts
Sergunb 0:8918a71cdbe9 340 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 341 **/
Sergunb 0:8918a71cdbe9 342
Sergunb 0:8918a71cdbe9 343 void s7g2EthEnableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 344 {
Sergunb 0:8918a71cdbe9 345 //Enable Ethernet MAC interrupts
Sergunb 0:8918a71cdbe9 346 NVIC_EnableIRQ(ETHER_EINT1_IRQn);
Sergunb 0:8918a71cdbe9 347 //Enable Ethernet PHY interrupts
Sergunb 0:8918a71cdbe9 348 interface->phyDriver->enableIrq(interface);
Sergunb 0:8918a71cdbe9 349 }
Sergunb 0:8918a71cdbe9 350
Sergunb 0:8918a71cdbe9 351
Sergunb 0:8918a71cdbe9 352 /**
Sergunb 0:8918a71cdbe9 353 * @brief Disable interrupts
Sergunb 0:8918a71cdbe9 354 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 355 **/
Sergunb 0:8918a71cdbe9 356
Sergunb 0:8918a71cdbe9 357 void s7g2EthDisableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 358 {
Sergunb 0:8918a71cdbe9 359 //Disable Ethernet MAC interrupts
Sergunb 0:8918a71cdbe9 360 NVIC_DisableIRQ(ETHER_EINT1_IRQn);
Sergunb 0:8918a71cdbe9 361 //Disable Ethernet PHY interrupts
Sergunb 0:8918a71cdbe9 362 interface->phyDriver->disableIrq(interface);
Sergunb 0:8918a71cdbe9 363 }
Sergunb 0:8918a71cdbe9 364
Sergunb 0:8918a71cdbe9 365
Sergunb 0:8918a71cdbe9 366 /**
Sergunb 0:8918a71cdbe9 367 * @brief S7G2 Ethernet MAC interrupt service routine
Sergunb 0:8918a71cdbe9 368 **/
Sergunb 0:8918a71cdbe9 369
Sergunb 0:8918a71cdbe9 370 void ETHER_EINT1_IRQHandler(void)
Sergunb 0:8918a71cdbe9 371 {
Sergunb 0:8918a71cdbe9 372 bool_t flag;
Sergunb 0:8918a71cdbe9 373 uint32_t status;
Sergunb 0:8918a71cdbe9 374
Sergunb 0:8918a71cdbe9 375 //Enter interrupt service routine
Sergunb 0:8918a71cdbe9 376 osEnterIsr();
Sergunb 0:8918a71cdbe9 377
Sergunb 0:8918a71cdbe9 378 //This flag will be set if a higher priority task must be woken
Sergunb 0:8918a71cdbe9 379 flag = FALSE;
Sergunb 0:8918a71cdbe9 380
Sergunb 0:8918a71cdbe9 381 //Read interrupt status register
Sergunb 0:8918a71cdbe9 382 status = R_EDMAC1->EESR;
Sergunb 0:8918a71cdbe9 383
Sergunb 0:8918a71cdbe9 384 //A packet has been transmitted?
Sergunb 0:8918a71cdbe9 385 if(status & EDMAC_EESR_TWB)
Sergunb 0:8918a71cdbe9 386 {
Sergunb 0:8918a71cdbe9 387 //Clear TWB interrupt flag
Sergunb 0:8918a71cdbe9 388 R_EDMAC1->EESR = EDMAC_EESR_TWB;
Sergunb 0:8918a71cdbe9 389
Sergunb 0:8918a71cdbe9 390 //Check whether the TX buffer is available for writing
Sergunb 0:8918a71cdbe9 391 if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT))
Sergunb 0:8918a71cdbe9 392 {
Sergunb 0:8918a71cdbe9 393 //Notify the TCP/IP stack that the transmitter is ready to send
Sergunb 0:8918a71cdbe9 394 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
Sergunb 0:8918a71cdbe9 395 }
Sergunb 0:8918a71cdbe9 396 }
Sergunb 0:8918a71cdbe9 397
Sergunb 0:8918a71cdbe9 398 //A packet has been received?
Sergunb 0:8918a71cdbe9 399 if(status & EDMAC_EESR_FR)
Sergunb 0:8918a71cdbe9 400 {
Sergunb 0:8918a71cdbe9 401 //Disable FR interrupts
Sergunb 0:8918a71cdbe9 402 R_EDMAC1->EESIPR_b.FRIP = 0;
Sergunb 0:8918a71cdbe9 403
Sergunb 0:8918a71cdbe9 404 //Set event flag
Sergunb 0:8918a71cdbe9 405 nicDriverInterface->nicEvent = TRUE;
Sergunb 0:8918a71cdbe9 406 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 407 flag |= osSetEventFromIsr(&netEvent);
Sergunb 0:8918a71cdbe9 408 }
Sergunb 0:8918a71cdbe9 409
Sergunb 0:8918a71cdbe9 410 //Clear IR flag
Sergunb 0:8918a71cdbe9 411 R_ICU->IELSRn_b[ETHER_EINT1_IRQn].IR = 0;
Sergunb 0:8918a71cdbe9 412
Sergunb 0:8918a71cdbe9 413 //Leave interrupt service routine
Sergunb 0:8918a71cdbe9 414 osExitIsr(flag);
Sergunb 0:8918a71cdbe9 415 }
Sergunb 0:8918a71cdbe9 416
Sergunb 0:8918a71cdbe9 417
Sergunb 0:8918a71cdbe9 418 /**
Sergunb 0:8918a71cdbe9 419 * @brief S7G2 Ethernet MAC event handler
Sergunb 0:8918a71cdbe9 420 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 421 **/
Sergunb 0:8918a71cdbe9 422
Sergunb 0:8918a71cdbe9 423 void s7g2EthEventHandler(NetInterface *interface)
Sergunb 0:8918a71cdbe9 424 {
Sergunb 0:8918a71cdbe9 425 error_t error;
Sergunb 0:8918a71cdbe9 426
Sergunb 0:8918a71cdbe9 427 //Packet received?
Sergunb 0:8918a71cdbe9 428 if(R_EDMAC1->EESR & EDMAC_EESR_FR)
Sergunb 0:8918a71cdbe9 429 {
Sergunb 0:8918a71cdbe9 430 //Clear FR interrupt flag
Sergunb 0:8918a71cdbe9 431 R_EDMAC1->EESR = EDMAC_EESR_FR;
Sergunb 0:8918a71cdbe9 432
Sergunb 0:8918a71cdbe9 433 //Process all pending packets
Sergunb 0:8918a71cdbe9 434 do
Sergunb 0:8918a71cdbe9 435 {
Sergunb 0:8918a71cdbe9 436 //Read incoming packet
Sergunb 0:8918a71cdbe9 437 error = s7g2EthReceivePacket(interface);
Sergunb 0:8918a71cdbe9 438
Sergunb 0:8918a71cdbe9 439 //No more data in the receive buffer?
Sergunb 0:8918a71cdbe9 440 } while(error != ERROR_BUFFER_EMPTY);
Sergunb 0:8918a71cdbe9 441 }
Sergunb 0:8918a71cdbe9 442
Sergunb 0:8918a71cdbe9 443 //Re-enable EDMAC interrupts
Sergunb 0:8918a71cdbe9 444 R_EDMAC1->EESIPR_b.TWBIP = 1;
Sergunb 0:8918a71cdbe9 445 R_EDMAC1->EESIPR_b.FRIP = 1;
Sergunb 0:8918a71cdbe9 446 }
Sergunb 0:8918a71cdbe9 447
Sergunb 0:8918a71cdbe9 448
Sergunb 0:8918a71cdbe9 449 /**
Sergunb 0:8918a71cdbe9 450 * @brief Send a packet
Sergunb 0:8918a71cdbe9 451 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 452 * @param[in] buffer Multi-part buffer containing the data to send
Sergunb 0:8918a71cdbe9 453 * @param[in] offset Offset to the first data byte
Sergunb 0:8918a71cdbe9 454 * @return Error code
Sergunb 0:8918a71cdbe9 455 **/
Sergunb 0:8918a71cdbe9 456
Sergunb 0:8918a71cdbe9 457 error_t s7g2EthSendPacket(NetInterface *interface,
Sergunb 0:8918a71cdbe9 458 const NetBuffer *buffer, size_t offset)
Sergunb 0:8918a71cdbe9 459 {
Sergunb 0:8918a71cdbe9 460 //Retrieve the length of the packet
Sergunb 0:8918a71cdbe9 461 size_t length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 462
Sergunb 0:8918a71cdbe9 463 //Check the frame length
Sergunb 0:8918a71cdbe9 464 if(length > S7G2_ETH_TX_BUFFER_SIZE)
Sergunb 0:8918a71cdbe9 465 {
Sergunb 0:8918a71cdbe9 466 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 467 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 468 //Report an error
Sergunb 0:8918a71cdbe9 469 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 470 }
Sergunb 0:8918a71cdbe9 471
Sergunb 0:8918a71cdbe9 472 //Make sure the current buffer is available for writing
Sergunb 0:8918a71cdbe9 473 if(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT)
Sergunb 0:8918a71cdbe9 474 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 475
Sergunb 0:8918a71cdbe9 476 //Copy user data to the transmit buffer
Sergunb 0:8918a71cdbe9 477 netBufferRead(txBuffer[txIndex], buffer, offset, length);
Sergunb 0:8918a71cdbe9 478
Sergunb 0:8918a71cdbe9 479 //Write the number of bytes to send
Sergunb 0:8918a71cdbe9 480 txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
Sergunb 0:8918a71cdbe9 481
Sergunb 0:8918a71cdbe9 482 //Check current index
Sergunb 0:8918a71cdbe9 483 if(txIndex < (S7G2_ETH_TX_BUFFER_COUNT - 1))
Sergunb 0:8918a71cdbe9 484 {
Sergunb 0:8918a71cdbe9 485 //Give the ownership of the descriptor to the DMA engine
Sergunb 0:8918a71cdbe9 486 txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
Sergunb 0:8918a71cdbe9 487 EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI;
Sergunb 0:8918a71cdbe9 488
Sergunb 0:8918a71cdbe9 489 //Point to the next descriptor
Sergunb 0:8918a71cdbe9 490 txIndex++;
Sergunb 0:8918a71cdbe9 491 }
Sergunb 0:8918a71cdbe9 492 else
Sergunb 0:8918a71cdbe9 493 {
Sergunb 0:8918a71cdbe9 494 //Give the ownership of the descriptor to the DMA engine
Sergunb 0:8918a71cdbe9 495 txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
Sergunb 0:8918a71cdbe9 496 EDMAC_TD0_TFP_SOF | EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI;
Sergunb 0:8918a71cdbe9 497
Sergunb 0:8918a71cdbe9 498 //Wrap around
Sergunb 0:8918a71cdbe9 499 txIndex = 0;
Sergunb 0:8918a71cdbe9 500 }
Sergunb 0:8918a71cdbe9 501
Sergunb 0:8918a71cdbe9 502 //Instruct the DMA to poll the transmit descriptor list
Sergunb 0:8918a71cdbe9 503 R_EDMAC1->EDTRR_b.TR = 1;
Sergunb 0:8918a71cdbe9 504
Sergunb 0:8918a71cdbe9 505 //Check whether the next buffer is available for writing
Sergunb 0:8918a71cdbe9 506 if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT))
Sergunb 0:8918a71cdbe9 507 {
Sergunb 0:8918a71cdbe9 508 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 509 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 510 }
Sergunb 0:8918a71cdbe9 511
Sergunb 0:8918a71cdbe9 512 //Successful write operation
Sergunb 0:8918a71cdbe9 513 return NO_ERROR;
Sergunb 0:8918a71cdbe9 514 }
Sergunb 0:8918a71cdbe9 515
Sergunb 0:8918a71cdbe9 516
Sergunb 0:8918a71cdbe9 517 /**
Sergunb 0:8918a71cdbe9 518 * @brief Receive a packet
Sergunb 0:8918a71cdbe9 519 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 520 * @return Error code
Sergunb 0:8918a71cdbe9 521 **/
Sergunb 0:8918a71cdbe9 522
Sergunb 0:8918a71cdbe9 523 error_t s7g2EthReceivePacket(NetInterface *interface)
Sergunb 0:8918a71cdbe9 524 {
Sergunb 0:8918a71cdbe9 525 error_t error;
Sergunb 0:8918a71cdbe9 526 size_t n;
Sergunb 0:8918a71cdbe9 527
Sergunb 0:8918a71cdbe9 528 //The current buffer is available for reading?
Sergunb 0:8918a71cdbe9 529 if(!(rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT))
Sergunb 0:8918a71cdbe9 530 {
Sergunb 0:8918a71cdbe9 531 //SOF and EOF flags should be set
Sergunb 0:8918a71cdbe9 532 if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) &&
Sergunb 0:8918a71cdbe9 533 (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF))
Sergunb 0:8918a71cdbe9 534 {
Sergunb 0:8918a71cdbe9 535 //Make sure no error occurred
Sergunb 0:8918a71cdbe9 536 if(!(rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)))
Sergunb 0:8918a71cdbe9 537 {
Sergunb 0:8918a71cdbe9 538 //Retrieve the length of the frame
Sergunb 0:8918a71cdbe9 539 n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
Sergunb 0:8918a71cdbe9 540 //Limit the number of data to read
Sergunb 0:8918a71cdbe9 541 n = MIN(n, S7G2_ETH_RX_BUFFER_SIZE);
Sergunb 0:8918a71cdbe9 542
Sergunb 0:8918a71cdbe9 543 //Pass the packet to the upper layer
Sergunb 0:8918a71cdbe9 544 nicProcessPacket(interface, rxBuffer[rxIndex], n);
Sergunb 0:8918a71cdbe9 545
Sergunb 0:8918a71cdbe9 546 //Valid packet received
Sergunb 0:8918a71cdbe9 547 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 548 }
Sergunb 0:8918a71cdbe9 549 else
Sergunb 0:8918a71cdbe9 550 {
Sergunb 0:8918a71cdbe9 551 //The received packet contains an error
Sergunb 0:8918a71cdbe9 552 error = ERROR_INVALID_PACKET;
Sergunb 0:8918a71cdbe9 553 }
Sergunb 0:8918a71cdbe9 554 }
Sergunb 0:8918a71cdbe9 555 else
Sergunb 0:8918a71cdbe9 556 {
Sergunb 0:8918a71cdbe9 557 //The packet is not valid
Sergunb 0:8918a71cdbe9 558 error = ERROR_INVALID_PACKET;
Sergunb 0:8918a71cdbe9 559 }
Sergunb 0:8918a71cdbe9 560
Sergunb 0:8918a71cdbe9 561 //Check current index
Sergunb 0:8918a71cdbe9 562 if(rxIndex < (S7G2_ETH_RX_BUFFER_COUNT - 1))
Sergunb 0:8918a71cdbe9 563 {
Sergunb 0:8918a71cdbe9 564 //Give the ownership of the descriptor back to the DMA
Sergunb 0:8918a71cdbe9 565 rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
Sergunb 0:8918a71cdbe9 566 //Point to the next descriptor
Sergunb 0:8918a71cdbe9 567 rxIndex++;
Sergunb 0:8918a71cdbe9 568 }
Sergunb 0:8918a71cdbe9 569 else
Sergunb 0:8918a71cdbe9 570 {
Sergunb 0:8918a71cdbe9 571 //Give the ownership of the descriptor back to the DMA
Sergunb 0:8918a71cdbe9 572 rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
Sergunb 0:8918a71cdbe9 573 //Wrap around
Sergunb 0:8918a71cdbe9 574 rxIndex = 0;
Sergunb 0:8918a71cdbe9 575 }
Sergunb 0:8918a71cdbe9 576
Sergunb 0:8918a71cdbe9 577 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 578 R_EDMAC1->EDRRR_b.RR = 1;
Sergunb 0:8918a71cdbe9 579 }
Sergunb 0:8918a71cdbe9 580 else
Sergunb 0:8918a71cdbe9 581 {
Sergunb 0:8918a71cdbe9 582 //No more data in the receive buffer
Sergunb 0:8918a71cdbe9 583 error = ERROR_BUFFER_EMPTY;
Sergunb 0:8918a71cdbe9 584 }
Sergunb 0:8918a71cdbe9 585
Sergunb 0:8918a71cdbe9 586 //Return status code
Sergunb 0:8918a71cdbe9 587 return error;
Sergunb 0:8918a71cdbe9 588 }
Sergunb 0:8918a71cdbe9 589
Sergunb 0:8918a71cdbe9 590
Sergunb 0:8918a71cdbe9 591 /**
Sergunb 0:8918a71cdbe9 592 * @brief Configure multicast MAC address filtering
Sergunb 0:8918a71cdbe9 593 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 594 * @return Error code
Sergunb 0:8918a71cdbe9 595 **/
Sergunb 0:8918a71cdbe9 596
Sergunb 0:8918a71cdbe9 597 error_t s7g2EthSetMulticastFilter(NetInterface *interface)
Sergunb 0:8918a71cdbe9 598 {
Sergunb 0:8918a71cdbe9 599 uint_t i;
Sergunb 0:8918a71cdbe9 600 bool_t acceptMulticast;
Sergunb 0:8918a71cdbe9 601
Sergunb 0:8918a71cdbe9 602 //This flag will be set if multicast addresses should be accepted
Sergunb 0:8918a71cdbe9 603 acceptMulticast = FALSE;
Sergunb 0:8918a71cdbe9 604
Sergunb 0:8918a71cdbe9 605 //The MAC filter table contains the multicast MAC addresses
Sergunb 0:8918a71cdbe9 606 //to accept when receiving an Ethernet frame
Sergunb 0:8918a71cdbe9 607 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
Sergunb 0:8918a71cdbe9 608 {
Sergunb 0:8918a71cdbe9 609 //Valid entry?
Sergunb 0:8918a71cdbe9 610 if(interface->macMulticastFilter[i].refCount > 0)
Sergunb 0:8918a71cdbe9 611 {
Sergunb 0:8918a71cdbe9 612 //Accept multicast addresses
Sergunb 0:8918a71cdbe9 613 acceptMulticast = TRUE;
Sergunb 0:8918a71cdbe9 614 //We are done
Sergunb 0:8918a71cdbe9 615 break;
Sergunb 0:8918a71cdbe9 616 }
Sergunb 0:8918a71cdbe9 617 }
Sergunb 0:8918a71cdbe9 618
Sergunb 0:8918a71cdbe9 619 //Enable the reception of multicast frames if necessary
Sergunb 0:8918a71cdbe9 620 if(acceptMulticast)
Sergunb 0:8918a71cdbe9 621 R_EDMAC1->EESR_b.RMAF = 1;
Sergunb 0:8918a71cdbe9 622 else
Sergunb 0:8918a71cdbe9 623 R_EDMAC1->EESR_b.RMAF = 0;
Sergunb 0:8918a71cdbe9 624
Sergunb 0:8918a71cdbe9 625 //Successful processing
Sergunb 0:8918a71cdbe9 626 return NO_ERROR;
Sergunb 0:8918a71cdbe9 627 }
Sergunb 0:8918a71cdbe9 628
Sergunb 0:8918a71cdbe9 629
Sergunb 0:8918a71cdbe9 630 /**
Sergunb 0:8918a71cdbe9 631 * @brief Adjust MAC configuration parameters for proper operation
Sergunb 0:8918a71cdbe9 632 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 633 * @return Error code
Sergunb 0:8918a71cdbe9 634 **/
Sergunb 0:8918a71cdbe9 635
Sergunb 0:8918a71cdbe9 636 error_t s7g2EthUpdateMacConfig(NetInterface *interface)
Sergunb 0:8918a71cdbe9 637 {
Sergunb 0:8918a71cdbe9 638 //10BASE-T or 100BASE-TX operation mode?
Sergunb 0:8918a71cdbe9 639 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
Sergunb 0:8918a71cdbe9 640 R_ETHERC1->ECMR_b.RTM = 1;
Sergunb 0:8918a71cdbe9 641 else
Sergunb 0:8918a71cdbe9 642 R_ETHERC1->ECMR_b.RTM = 0;
Sergunb 0:8918a71cdbe9 643
Sergunb 0:8918a71cdbe9 644 //Half-duplex or full-duplex mode?
Sergunb 0:8918a71cdbe9 645 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
Sergunb 0:8918a71cdbe9 646 R_ETHERC1->ECMR_b.DM = 1;
Sergunb 0:8918a71cdbe9 647 else
Sergunb 0:8918a71cdbe9 648 R_ETHERC1->ECMR_b.DM = 0;
Sergunb 0:8918a71cdbe9 649
Sergunb 0:8918a71cdbe9 650 //Successful processing
Sergunb 0:8918a71cdbe9 651 return NO_ERROR;
Sergunb 0:8918a71cdbe9 652 }
Sergunb 0:8918a71cdbe9 653
Sergunb 0:8918a71cdbe9 654
Sergunb 0:8918a71cdbe9 655 /**
Sergunb 0:8918a71cdbe9 656 * @brief Write PHY register
Sergunb 0:8918a71cdbe9 657 * @param[in] phyAddr PHY address
Sergunb 0:8918a71cdbe9 658 * @param[in] regAddr Register address
Sergunb 0:8918a71cdbe9 659 * @param[in] data Register value
Sergunb 0:8918a71cdbe9 660 **/
Sergunb 0:8918a71cdbe9 661
Sergunb 0:8918a71cdbe9 662 void s7g2EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Sergunb 0:8918a71cdbe9 663 {
Sergunb 0:8918a71cdbe9 664 //Synchronization pattern
Sergunb 0:8918a71cdbe9 665 s7g2EthWriteSmi(SMI_SYNC, 32);
Sergunb 0:8918a71cdbe9 666 //Start of frame
Sergunb 0:8918a71cdbe9 667 s7g2EthWriteSmi(SMI_START, 2);
Sergunb 0:8918a71cdbe9 668 //Set up a write operation
Sergunb 0:8918a71cdbe9 669 s7g2EthWriteSmi(SMI_WRITE, 2);
Sergunb 0:8918a71cdbe9 670 //Write PHY address
Sergunb 0:8918a71cdbe9 671 s7g2EthWriteSmi(phyAddr, 5);
Sergunb 0:8918a71cdbe9 672 //Write register address
Sergunb 0:8918a71cdbe9 673 s7g2EthWriteSmi(regAddr, 5);
Sergunb 0:8918a71cdbe9 674 //Turnaround
Sergunb 0:8918a71cdbe9 675 s7g2EthWriteSmi(SMI_TA, 2);
Sergunb 0:8918a71cdbe9 676 //Write register value
Sergunb 0:8918a71cdbe9 677 s7g2EthWriteSmi(data, 16);
Sergunb 0:8918a71cdbe9 678 //Release MDIO
Sergunb 0:8918a71cdbe9 679 s7g2EthReadSmi(1);
Sergunb 0:8918a71cdbe9 680 }
Sergunb 0:8918a71cdbe9 681
Sergunb 0:8918a71cdbe9 682
Sergunb 0:8918a71cdbe9 683 /**
Sergunb 0:8918a71cdbe9 684 * @brief Read PHY register
Sergunb 0:8918a71cdbe9 685 * @param[in] phyAddr PHY address
Sergunb 0:8918a71cdbe9 686 * @param[in] regAddr Register address
Sergunb 0:8918a71cdbe9 687 * @return Register value
Sergunb 0:8918a71cdbe9 688 **/
Sergunb 0:8918a71cdbe9 689
Sergunb 0:8918a71cdbe9 690 uint16_t s7g2EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Sergunb 0:8918a71cdbe9 691 {
Sergunb 0:8918a71cdbe9 692 uint16_t data;
Sergunb 0:8918a71cdbe9 693
Sergunb 0:8918a71cdbe9 694 //Synchronization pattern
Sergunb 0:8918a71cdbe9 695 s7g2EthWriteSmi(SMI_SYNC, 32);
Sergunb 0:8918a71cdbe9 696 //Start of frame
Sergunb 0:8918a71cdbe9 697 s7g2EthWriteSmi(SMI_START, 2);
Sergunb 0:8918a71cdbe9 698 //Set up a read operation
Sergunb 0:8918a71cdbe9 699 s7g2EthWriteSmi(SMI_READ, 2);
Sergunb 0:8918a71cdbe9 700 //Write PHY address
Sergunb 0:8918a71cdbe9 701 s7g2EthWriteSmi(phyAddr, 5);
Sergunb 0:8918a71cdbe9 702 //Write register address
Sergunb 0:8918a71cdbe9 703 s7g2EthWriteSmi(regAddr, 5);
Sergunb 0:8918a71cdbe9 704 //Turnaround to avoid contention
Sergunb 0:8918a71cdbe9 705 s7g2EthReadSmi(1);
Sergunb 0:8918a71cdbe9 706 //Read register value
Sergunb 0:8918a71cdbe9 707 data = s7g2EthReadSmi(16);
Sergunb 0:8918a71cdbe9 708 //Force the PHY to release the MDIO pin
Sergunb 0:8918a71cdbe9 709 s7g2EthReadSmi(1);
Sergunb 0:8918a71cdbe9 710
Sergunb 0:8918a71cdbe9 711 //Return PHY register contents
Sergunb 0:8918a71cdbe9 712 return data;
Sergunb 0:8918a71cdbe9 713 }
Sergunb 0:8918a71cdbe9 714
Sergunb 0:8918a71cdbe9 715
Sergunb 0:8918a71cdbe9 716 /**
Sergunb 0:8918a71cdbe9 717 * @brief SMI write operation
Sergunb 0:8918a71cdbe9 718 * @param[in] data Raw data to be written
Sergunb 0:8918a71cdbe9 719 * @param[in] length Number of bits to be written
Sergunb 0:8918a71cdbe9 720 **/
Sergunb 0:8918a71cdbe9 721
Sergunb 0:8918a71cdbe9 722 void s7g2EthWriteSmi(uint32_t data, uint_t length)
Sergunb 0:8918a71cdbe9 723 {
Sergunb 0:8918a71cdbe9 724 //Skip the most significant bits since they are meaningless
Sergunb 0:8918a71cdbe9 725 data <<= 32 - length;
Sergunb 0:8918a71cdbe9 726
Sergunb 0:8918a71cdbe9 727 //Configure MDIO as an output
Sergunb 0:8918a71cdbe9 728 R_ETHERC1->PIR_b.MMD = 1;
Sergunb 0:8918a71cdbe9 729
Sergunb 0:8918a71cdbe9 730 //Write the specified number of bits
Sergunb 0:8918a71cdbe9 731 while(length--)
Sergunb 0:8918a71cdbe9 732 {
Sergunb 0:8918a71cdbe9 733 //Write MDIO
Sergunb 0:8918a71cdbe9 734 if(data & 0x80000000)
Sergunb 0:8918a71cdbe9 735 R_ETHERC1->PIR_b.MDO = 1;
Sergunb 0:8918a71cdbe9 736 else
Sergunb 0:8918a71cdbe9 737 R_ETHERC1->PIR_b.MDO = 0;
Sergunb 0:8918a71cdbe9 738
Sergunb 0:8918a71cdbe9 739 //Assert MDC
Sergunb 0:8918a71cdbe9 740 usleep(1);
Sergunb 0:8918a71cdbe9 741 R_ETHERC1->PIR_b.MDC = 1;
Sergunb 0:8918a71cdbe9 742 //Deassert MDC
Sergunb 0:8918a71cdbe9 743 usleep(1);
Sergunb 0:8918a71cdbe9 744 R_ETHERC1->PIR_b.MDC = 0;
Sergunb 0:8918a71cdbe9 745
Sergunb 0:8918a71cdbe9 746 //Rotate data
Sergunb 0:8918a71cdbe9 747 data <<= 1;
Sergunb 0:8918a71cdbe9 748 }
Sergunb 0:8918a71cdbe9 749 }
Sergunb 0:8918a71cdbe9 750
Sergunb 0:8918a71cdbe9 751
Sergunb 0:8918a71cdbe9 752 /**
Sergunb 0:8918a71cdbe9 753 * @brief SMI read operation
Sergunb 0:8918a71cdbe9 754 * @param[in] length Number of bits to be read
Sergunb 0:8918a71cdbe9 755 * @return Data resulting from the MDIO read operation
Sergunb 0:8918a71cdbe9 756 **/
Sergunb 0:8918a71cdbe9 757
Sergunb 0:8918a71cdbe9 758 uint32_t s7g2EthReadSmi(uint_t length)
Sergunb 0:8918a71cdbe9 759 {
Sergunb 0:8918a71cdbe9 760 uint32_t data = 0;
Sergunb 0:8918a71cdbe9 761
Sergunb 0:8918a71cdbe9 762 //Configure MDIO as an input
Sergunb 0:8918a71cdbe9 763 R_ETHERC1->PIR_b.MMD = 0;
Sergunb 0:8918a71cdbe9 764
Sergunb 0:8918a71cdbe9 765 //Read the specified number of bits
Sergunb 0:8918a71cdbe9 766 while(length--)
Sergunb 0:8918a71cdbe9 767 {
Sergunb 0:8918a71cdbe9 768 //Rotate data
Sergunb 0:8918a71cdbe9 769 data <<= 1;
Sergunb 0:8918a71cdbe9 770
Sergunb 0:8918a71cdbe9 771 //Assert MDC
Sergunb 0:8918a71cdbe9 772 R_ETHERC1->PIR_b.MDC = 1;
Sergunb 0:8918a71cdbe9 773 usleep(1);
Sergunb 0:8918a71cdbe9 774 //Deassert MDC
Sergunb 0:8918a71cdbe9 775 R_ETHERC1->PIR_b.MDC = 0;
Sergunb 0:8918a71cdbe9 776 usleep(1);
Sergunb 0:8918a71cdbe9 777
Sergunb 0:8918a71cdbe9 778 //Check MDIO state
Sergunb 0:8918a71cdbe9 779 if(R_ETHERC1->PIR_b.MDI)
Sergunb 0:8918a71cdbe9 780 data |= 0x00000001;
Sergunb 0:8918a71cdbe9 781 }
Sergunb 0:8918a71cdbe9 782
Sergunb 0:8918a71cdbe9 783 //Return the received data
Sergunb 0:8918a71cdbe9 784 return data;
Sergunb 0:8918a71cdbe9 785 }
Sergunb 0:8918a71cdbe9 786