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 mk6x_eth.c
Sergunb 0:8918a71cdbe9 3 * @brief Freescale Kinetis K60/K64/K65/K66 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 //MK60N512MD100 device?
Sergunb 0:8918a71cdbe9 33 #if defined(MK60N512MD100)
Sergunb 0:8918a71cdbe9 34 #include "mk60n512md100.h"
Sergunb 0:8918a71cdbe9 35 //MK60D10 device?
Sergunb 0:8918a71cdbe9 36 #elif defined(MK60D10)
Sergunb 0:8918a71cdbe9 37 #include "mk60d10.h"
Sergunb 0:8918a71cdbe9 38 //MK60F12 device?
Sergunb 0:8918a71cdbe9 39 #elif defined(MK60F12)
Sergunb 0:8918a71cdbe9 40 #include "mk60f12.h"
Sergunb 0:8918a71cdbe9 41 //MK64F12 device?
Sergunb 0:8918a71cdbe9 42 #elif defined(MK64F12)
Sergunb 0:8918a71cdbe9 43 #include "mk64f12.h"
Sergunb 0:8918a71cdbe9 44 //MK65F18 device?
Sergunb 0:8918a71cdbe9 45 #elif defined(MK65F18)
Sergunb 0:8918a71cdbe9 46 #include "mk65f18.h"
Sergunb 0:8918a71cdbe9 47 //MK66F18 device?
Sergunb 0:8918a71cdbe9 48 #elif defined(MK66F18)
Sergunb 0:8918a71cdbe9 49 #include "mk66f18.h"
Sergunb 0:8918a71cdbe9 50 #endif
Sergunb 0:8918a71cdbe9 51
Sergunb 0:8918a71cdbe9 52 //Dependencies
Sergunb 0:8918a71cdbe9 53 #include "core/net.h"
Sergunb 0:8918a71cdbe9 54 #include "drivers/mk6x_eth.h"
Sergunb 0:8918a71cdbe9 55 #include "debug.h"
Sergunb 0:8918a71cdbe9 56
Sergunb 0:8918a71cdbe9 57 //Underlying network interface
Sergunb 0:8918a71cdbe9 58 static NetInterface *nicDriverInterface;
Sergunb 0:8918a71cdbe9 59
Sergunb 0:8918a71cdbe9 60 //IAR EWARM compiler?
Sergunb 0:8918a71cdbe9 61 #if defined(__ICCARM__)
Sergunb 0:8918a71cdbe9 62
Sergunb 0:8918a71cdbe9 63 //TX buffer
Sergunb 0:8918a71cdbe9 64 #pragma data_alignment = 16
Sergunb 0:8918a71cdbe9 65 static uint8_t txBuffer[MK6X_ETH_TX_BUFFER_COUNT][MK6X_ETH_TX_BUFFER_SIZE];
Sergunb 0:8918a71cdbe9 66 //RX buffer
Sergunb 0:8918a71cdbe9 67 #pragma data_alignment = 16
Sergunb 0:8918a71cdbe9 68 static uint8_t rxBuffer[MK6X_ETH_RX_BUFFER_COUNT][MK6X_ETH_RX_BUFFER_SIZE];
Sergunb 0:8918a71cdbe9 69 //TX buffer descriptors
Sergunb 0:8918a71cdbe9 70 #pragma data_alignment = 16
Sergunb 0:8918a71cdbe9 71 static uint16_t txBufferDesc[MK6X_ETH_TX_BUFFER_COUNT][16];
Sergunb 0:8918a71cdbe9 72 //RX buffer descriptors
Sergunb 0:8918a71cdbe9 73 #pragma data_alignment = 16
Sergunb 0:8918a71cdbe9 74 static uint16_t rxBufferDesc[MK6X_ETH_RX_BUFFER_COUNT][16];
Sergunb 0:8918a71cdbe9 75
Sergunb 0:8918a71cdbe9 76 //ARM or GCC compiler?
Sergunb 0:8918a71cdbe9 77 #else
Sergunb 0:8918a71cdbe9 78
Sergunb 0:8918a71cdbe9 79 //TX buffer
Sergunb 0:8918a71cdbe9 80 static uint8_t txBuffer[MK6X_ETH_TX_BUFFER_COUNT][MK6X_ETH_TX_BUFFER_SIZE]
Sergunb 0:8918a71cdbe9 81 __attribute__((aligned(16)));
Sergunb 0:8918a71cdbe9 82 //RX buffer
Sergunb 0:8918a71cdbe9 83 static uint8_t rxBuffer[MK6X_ETH_RX_BUFFER_COUNT][MK6X_ETH_RX_BUFFER_SIZE]
Sergunb 0:8918a71cdbe9 84 __attribute__((aligned(16)));
Sergunb 0:8918a71cdbe9 85 //TX buffer descriptors
Sergunb 0:8918a71cdbe9 86 static uint16_t txBufferDesc[MK6X_ETH_TX_BUFFER_COUNT][16]
Sergunb 0:8918a71cdbe9 87 __attribute__((aligned(16)));
Sergunb 0:8918a71cdbe9 88 //RX buffer descriptors
Sergunb 0:8918a71cdbe9 89 static uint16_t rxBufferDesc[MK6X_ETH_RX_BUFFER_COUNT][16]
Sergunb 0:8918a71cdbe9 90 __attribute__((aligned(16)));
Sergunb 0:8918a71cdbe9 91
Sergunb 0:8918a71cdbe9 92 #endif
Sergunb 0:8918a71cdbe9 93
Sergunb 0:8918a71cdbe9 94 //TX buffer index
Sergunb 0:8918a71cdbe9 95 static uint_t txBufferIndex;
Sergunb 0:8918a71cdbe9 96 //RX buffer index
Sergunb 0:8918a71cdbe9 97 static uint_t rxBufferIndex;
Sergunb 0:8918a71cdbe9 98
Sergunb 0:8918a71cdbe9 99
Sergunb 0:8918a71cdbe9 100 /**
Sergunb 0:8918a71cdbe9 101 * @brief Kinetis K6x Ethernet MAC driver
Sergunb 0:8918a71cdbe9 102 **/
Sergunb 0:8918a71cdbe9 103
Sergunb 0:8918a71cdbe9 104 const NicDriver mk6xEthDriver =
Sergunb 0:8918a71cdbe9 105 {
Sergunb 0:8918a71cdbe9 106 NIC_TYPE_ETHERNET,
Sergunb 0:8918a71cdbe9 107 ETH_MTU,
Sergunb 0:8918a71cdbe9 108 mk6xEthInit,
Sergunb 0:8918a71cdbe9 109 mk6xEthTick,
Sergunb 0:8918a71cdbe9 110 mk6xEthEnableIrq,
Sergunb 0:8918a71cdbe9 111 mk6xEthDisableIrq,
Sergunb 0:8918a71cdbe9 112 mk6xEthEventHandler,
Sergunb 0:8918a71cdbe9 113 mk6xEthSendPacket,
Sergunb 0:8918a71cdbe9 114 mk6xEthSetMulticastFilter,
Sergunb 0:8918a71cdbe9 115 mk6xEthUpdateMacConfig,
Sergunb 0:8918a71cdbe9 116 mk6xEthWritePhyReg,
Sergunb 0:8918a71cdbe9 117 mk6xEthReadPhyReg,
Sergunb 0:8918a71cdbe9 118 TRUE,
Sergunb 0:8918a71cdbe9 119 TRUE,
Sergunb 0:8918a71cdbe9 120 TRUE,
Sergunb 0:8918a71cdbe9 121 FALSE
Sergunb 0:8918a71cdbe9 122 };
Sergunb 0:8918a71cdbe9 123
Sergunb 0:8918a71cdbe9 124
Sergunb 0:8918a71cdbe9 125 /**
Sergunb 0:8918a71cdbe9 126 * @brief Kinetis K6x Ethernet MAC initialization
Sergunb 0:8918a71cdbe9 127 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 128 * @return Error code
Sergunb 0:8918a71cdbe9 129 **/
Sergunb 0:8918a71cdbe9 130
Sergunb 0:8918a71cdbe9 131 error_t mk6xEthInit(NetInterface *interface)
Sergunb 0:8918a71cdbe9 132 {
Sergunb 0:8918a71cdbe9 133 error_t error;
Sergunb 0:8918a71cdbe9 134 uint32_t value;
Sergunb 0:8918a71cdbe9 135
Sergunb 0:8918a71cdbe9 136 //Debug message
Sergunb 0:8918a71cdbe9 137 TRACE_INFO("Initializing Kinetis K6x Ethernet MAC...\r\n");
Sergunb 0:8918a71cdbe9 138
Sergunb 0:8918a71cdbe9 139 //Save underlying network interface
Sergunb 0:8918a71cdbe9 140 nicDriverInterface = interface;
Sergunb 0:8918a71cdbe9 141
Sergunb 0:8918a71cdbe9 142 //Disable MPU
Sergunb 0:8918a71cdbe9 143 MPU->CESR &= ~MPU_CESR_VLD_MASK;
Sergunb 0:8918a71cdbe9 144
Sergunb 0:8918a71cdbe9 145 //Enable external reference clock
Sergunb 0:8918a71cdbe9 146 OSC->CR |= OSC_CR_ERCLKEN_MASK;
Sergunb 0:8918a71cdbe9 147 //Enable ENET peripheral clock
Sergunb 0:8918a71cdbe9 148 SIM->SCGC2 |= SIM_SCGC2_ENET_MASK;
Sergunb 0:8918a71cdbe9 149
Sergunb 0:8918a71cdbe9 150 //GPIO configuration
Sergunb 0:8918a71cdbe9 151 mk6xEthInitGpio(interface);
Sergunb 0:8918a71cdbe9 152
Sergunb 0:8918a71cdbe9 153 //Reset ENET module
Sergunb 0:8918a71cdbe9 154 ENET->ECR = ENET_ECR_RESET_MASK;
Sergunb 0:8918a71cdbe9 155 //Wait for the reset to complete
Sergunb 0:8918a71cdbe9 156 while(ENET->ECR & ENET_ECR_RESET_MASK);
Sergunb 0:8918a71cdbe9 157
Sergunb 0:8918a71cdbe9 158 //Receive control register
Sergunb 0:8918a71cdbe9 159 ENET->RCR = ENET_RCR_MAX_FL(1518) | ENET_RCR_RMII_MODE_MASK | ENET_RCR_MII_MODE_MASK;
Sergunb 0:8918a71cdbe9 160 //Transmit control register
Sergunb 0:8918a71cdbe9 161 ENET->TCR = 0;
Sergunb 0:8918a71cdbe9 162 //Configure MDC clock frequency
Sergunb 0:8918a71cdbe9 163 ENET->MSCR = ENET_MSCR_MII_SPEED(59);
Sergunb 0:8918a71cdbe9 164
Sergunb 0:8918a71cdbe9 165 //PHY transceiver initialization
Sergunb 0:8918a71cdbe9 166 error = interface->phyDriver->init(interface);
Sergunb 0:8918a71cdbe9 167 //Failed to initialize PHY transceiver?
Sergunb 0:8918a71cdbe9 168 if(error)
Sergunb 0:8918a71cdbe9 169 return error;
Sergunb 0:8918a71cdbe9 170
Sergunb 0:8918a71cdbe9 171 //Set the MAC address (upper 16 bits)
Sergunb 0:8918a71cdbe9 172 value = interface->macAddr.b[5];
Sergunb 0:8918a71cdbe9 173 value |= (interface->macAddr.b[4] << 8);
Sergunb 0:8918a71cdbe9 174 ENET->PAUR = ENET_PAUR_PADDR2(value) | ENET_PAUR_TYPE(0x8808);
Sergunb 0:8918a71cdbe9 175
Sergunb 0:8918a71cdbe9 176 //Set the MAC address (lower 32 bits)
Sergunb 0:8918a71cdbe9 177 value = interface->macAddr.b[3];
Sergunb 0:8918a71cdbe9 178 value |= (interface->macAddr.b[2] << 8);
Sergunb 0:8918a71cdbe9 179 value |= (interface->macAddr.b[1] << 16);
Sergunb 0:8918a71cdbe9 180 value |= (interface->macAddr.b[0] << 24);
Sergunb 0:8918a71cdbe9 181 ENET->PALR = ENET_PALR_PADDR1(value);
Sergunb 0:8918a71cdbe9 182
Sergunb 0:8918a71cdbe9 183 //Hash table for unicast address filtering
Sergunb 0:8918a71cdbe9 184 ENET->IALR = 0;
Sergunb 0:8918a71cdbe9 185 ENET->IAUR = 0;
Sergunb 0:8918a71cdbe9 186 //Hash table for multicast address filtering
Sergunb 0:8918a71cdbe9 187 ENET->GALR = 0;
Sergunb 0:8918a71cdbe9 188 ENET->GAUR = 0;
Sergunb 0:8918a71cdbe9 189
Sergunb 0:8918a71cdbe9 190 //Disable transmit accelerator functions
Sergunb 0:8918a71cdbe9 191 ENET->TACC = 0;
Sergunb 0:8918a71cdbe9 192 //Disable receive accelerator functions
Sergunb 0:8918a71cdbe9 193 ENET->RACC = 0;
Sergunb 0:8918a71cdbe9 194
Sergunb 0:8918a71cdbe9 195 //Use enhanced buffer descriptors
Sergunb 0:8918a71cdbe9 196 ENET->ECR = ENET_ECR_EN1588_MASK;
Sergunb 0:8918a71cdbe9 197 //Clear MIC counters
Sergunb 0:8918a71cdbe9 198 ENET->MIBC = ENET_MIBC_MIB_CLEAR_MASK;
Sergunb 0:8918a71cdbe9 199
Sergunb 0:8918a71cdbe9 200 //Initialize buffer descriptors
Sergunb 0:8918a71cdbe9 201 mk6xEthInitBufferDesc(interface);
Sergunb 0:8918a71cdbe9 202
Sergunb 0:8918a71cdbe9 203 //Clear any pending interrupts
Sergunb 0:8918a71cdbe9 204 ENET->EIR = 0xFFFFFFFF;
Sergunb 0:8918a71cdbe9 205 //Enable desired interrupts
Sergunb 0:8918a71cdbe9 206 ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
Sergunb 0:8918a71cdbe9 207
Sergunb 0:8918a71cdbe9 208 //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
Sergunb 0:8918a71cdbe9 209 NVIC_SetPriorityGrouping(MK6X_ETH_IRQ_PRIORITY_GROUPING);
Sergunb 0:8918a71cdbe9 210
Sergunb 0:8918a71cdbe9 211 //Configure ENET transmit interrupt priority
Sergunb 0:8918a71cdbe9 212 NVIC_SetPriority(ENET_Transmit_IRQn, NVIC_EncodePriority(MK6X_ETH_IRQ_PRIORITY_GROUPING,
Sergunb 0:8918a71cdbe9 213 MK6X_ETH_IRQ_GROUP_PRIORITY, MK6X_ETH_IRQ_SUB_PRIORITY));
Sergunb 0:8918a71cdbe9 214
Sergunb 0:8918a71cdbe9 215 //Configure ENET receive interrupt priority
Sergunb 0:8918a71cdbe9 216 NVIC_SetPriority(ENET_Receive_IRQn, NVIC_EncodePriority(MK6X_ETH_IRQ_PRIORITY_GROUPING,
Sergunb 0:8918a71cdbe9 217 MK6X_ETH_IRQ_GROUP_PRIORITY, MK6X_ETH_IRQ_SUB_PRIORITY));
Sergunb 0:8918a71cdbe9 218
Sergunb 0:8918a71cdbe9 219 //Configure ENET error interrupt priority
Sergunb 0:8918a71cdbe9 220 NVIC_SetPriority(ENET_Error_IRQn, NVIC_EncodePriority(MK6X_ETH_IRQ_PRIORITY_GROUPING,
Sergunb 0:8918a71cdbe9 221 MK6X_ETH_IRQ_GROUP_PRIORITY, MK6X_ETH_IRQ_SUB_PRIORITY));
Sergunb 0:8918a71cdbe9 222
Sergunb 0:8918a71cdbe9 223 //Enable Ethernet MAC
Sergunb 0:8918a71cdbe9 224 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
Sergunb 0:8918a71cdbe9 225 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 226 ENET->RDAR = ENET_RDAR_RDAR_MASK;
Sergunb 0:8918a71cdbe9 227
Sergunb 0:8918a71cdbe9 228 //Accept any packets from the upper layer
Sergunb 0:8918a71cdbe9 229 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 230
Sergunb 0:8918a71cdbe9 231 //Successful initialization
Sergunb 0:8918a71cdbe9 232 return NO_ERROR;
Sergunb 0:8918a71cdbe9 233 }
Sergunb 0:8918a71cdbe9 234
Sergunb 0:8918a71cdbe9 235
Sergunb 0:8918a71cdbe9 236 //FRDM-K64F, FRDM-K66F, TWR-K60N512, TWR-K60F120M,
Sergunb 0:8918a71cdbe9 237 //TWR-K64F120M or TWR-K65F180M evaluation board?
Sergunb 0:8918a71cdbe9 238 #if defined(USE_FRDM_K64F) || defined(USE_FRDM_K66F) || \
Sergunb 0:8918a71cdbe9 239 defined(USE_TWR_K60N512) || defined(USE_TWR_K60F120M) || \
Sergunb 0:8918a71cdbe9 240 defined(USE_TWR_K64F120M) || defined(USE_TWR_K65F180M)
Sergunb 0:8918a71cdbe9 241
Sergunb 0:8918a71cdbe9 242 /**
Sergunb 0:8918a71cdbe9 243 * @brief GPIO configuration
Sergunb 0:8918a71cdbe9 244 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 245 **/
Sergunb 0:8918a71cdbe9 246
Sergunb 0:8918a71cdbe9 247 void mk6xEthInitGpio(NetInterface *interface)
Sergunb 0:8918a71cdbe9 248 {
Sergunb 0:8918a71cdbe9 249 //TWR-K60N512 or TWR-K60F120M evaluation board?
Sergunb 0:8918a71cdbe9 250 #if defined(USE_TWR_K60N512) || defined(USE_TWR_K60F120M)
Sergunb 0:8918a71cdbe9 251 //Enable PORTA and PORTB peripheral clocks
Sergunb 0:8918a71cdbe9 252 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK;
Sergunb 0:8918a71cdbe9 253
Sergunb 0:8918a71cdbe9 254 //Configure RMII0_RXER (PTA5)
Sergunb 0:8918a71cdbe9 255 PORTA->PCR[5] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK;
Sergunb 0:8918a71cdbe9 256 //Configure RMII0_RXD1 (PTA12)
Sergunb 0:8918a71cdbe9 257 PORTA->PCR[12] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 258 //Configure RMII0_RXD0 (PTA13)
Sergunb 0:8918a71cdbe9 259 PORTA->PCR[13] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 260 //Configure RMII0_CRS_DV (PTA14)
Sergunb 0:8918a71cdbe9 261 PORTA->PCR[14] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 262 //Configure RMII0_TXEN (PTA15)
Sergunb 0:8918a71cdbe9 263 PORTA->PCR[15] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 264 //Configure RMII0_TXD0 (PTA16)
Sergunb 0:8918a71cdbe9 265 PORTA->PCR[16] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 266 //Configure RMII0_TXD1 (PTA17)
Sergunb 0:8918a71cdbe9 267 PORTA->PCR[17] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 268
Sergunb 0:8918a71cdbe9 269 //Configure RMII0_MDIO (PTB0)
Sergunb 0:8918a71cdbe9 270 PORTB->PCR[0] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
Sergunb 0:8918a71cdbe9 271 //Configure RMII0_MDC (PTB1)
Sergunb 0:8918a71cdbe9 272 PORTB->PCR[1] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 273
Sergunb 0:8918a71cdbe9 274 //FRDM-K64F or TWR-K64F120M evaluation board?
Sergunb 0:8918a71cdbe9 275 #elif defined(USE_FRDM_K64F) || defined(USE_TWR_K64F120M)
Sergunb 0:8918a71cdbe9 276 //Enable PORTA and PORTB peripheral clocks
Sergunb 0:8918a71cdbe9 277 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK;
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Configure RMII0_RXER (PTA5)
Sergunb 0:8918a71cdbe9 280 PORTA->PCR[5] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK;
Sergunb 0:8918a71cdbe9 281 //Configure RMII0_RXD1 (PTA12)
Sergunb 0:8918a71cdbe9 282 PORTA->PCR[12] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 283 //Configure RMII0_RXD0 (PTA13)
Sergunb 0:8918a71cdbe9 284 PORTA->PCR[13] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 285 //Configure RMII0_CRS_DV (PTA14)
Sergunb 0:8918a71cdbe9 286 PORTA->PCR[14] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 287 //Configure RMII0_TXEN (PTA15)
Sergunb 0:8918a71cdbe9 288 PORTA->PCR[15] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 289 //Configure RMII0_TXD0 (PTA16)
Sergunb 0:8918a71cdbe9 290 PORTA->PCR[16] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 291 //Configure RMII0_TXD1 (PTA17)
Sergunb 0:8918a71cdbe9 292 PORTA->PCR[17] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 293
Sergunb 0:8918a71cdbe9 294 //Configure RMII0_MDIO (PTB0)
Sergunb 0:8918a71cdbe9 295 PORTB->PCR[0] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
Sergunb 0:8918a71cdbe9 296 //Configure RMII0_MDC (PTB1)
Sergunb 0:8918a71cdbe9 297 PORTB->PCR[1] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 298
Sergunb 0:8918a71cdbe9 299 //Select RMII clock source (EXTAL)
Sergunb 0:8918a71cdbe9 300 SIM->SOPT2 &= ~SIM_SOPT2_RMIISRC_MASK;
Sergunb 0:8918a71cdbe9 301
Sergunb 0:8918a71cdbe9 302 //TWR-K65F180M evaluation board?
Sergunb 0:8918a71cdbe9 303 #elif defined(USE_TWR_K65F180M)
Sergunb 0:8918a71cdbe9 304 //Enable PORTA and PORTE peripheral clocks
Sergunb 0:8918a71cdbe9 305 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTE_MASK;
Sergunb 0:8918a71cdbe9 306
Sergunb 0:8918a71cdbe9 307 //Configure RMII0_RXER (PTA5)
Sergunb 0:8918a71cdbe9 308 PORTA->PCR[5] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK;
Sergunb 0:8918a71cdbe9 309 //Configure RMII0_MDIO (PTA7)
Sergunb 0:8918a71cdbe9 310 PORTA->PCR[7] = PORT_PCR_MUX(5) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
Sergunb 0:8918a71cdbe9 311 //Configure RMII0_MDC (PTA8)
Sergunb 0:8918a71cdbe9 312 PORTA->PCR[8] = PORT_PCR_MUX(5);
Sergunb 0:8918a71cdbe9 313 //Configure RMII0_RXD1 (PTA12)
Sergunb 0:8918a71cdbe9 314 PORTA->PCR[12] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 315 //Configure RMII0_RXD0 (PTA13)
Sergunb 0:8918a71cdbe9 316 PORTA->PCR[13] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 317 //Configure RMII0_CRS_DV (PTA14)
Sergunb 0:8918a71cdbe9 318 PORTA->PCR[14] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 319 //Configure RMII0_TXEN (PTA15)
Sergunb 0:8918a71cdbe9 320 PORTA->PCR[15] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 321 //Configure RMII0_TXD0 (PTA16)
Sergunb 0:8918a71cdbe9 322 PORTA->PCR[16] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 323 //Configure RMII0_TXD1 (PTA17)
Sergunb 0:8918a71cdbe9 324 PORTA->PCR[17] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 325
Sergunb 0:8918a71cdbe9 326 //Configure ENET_1588_CLKIN (PTE26)
Sergunb 0:8918a71cdbe9 327 PORTE->PCR[26] = PORT_PCR_MUX(2);
Sergunb 0:8918a71cdbe9 328
Sergunb 0:8918a71cdbe9 329 //Select RMII clock source (ENET_1588_CLKIN)
Sergunb 0:8918a71cdbe9 330 SIM->SOPT2 |= SIM_SOPT2_RMIISRC_MASK;
Sergunb 0:8918a71cdbe9 331
Sergunb 0:8918a71cdbe9 332 //FRDM-K66F evaluation board?
Sergunb 0:8918a71cdbe9 333 #elif defined(USE_FRDM_K66F)
Sergunb 0:8918a71cdbe9 334 //Enable PORTA, PORTB and PORTE peripheral clocks
Sergunb 0:8918a71cdbe9 335 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK |
Sergunb 0:8918a71cdbe9 336 SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTE_MASK;
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338 //Configure RMII0_RXER (PTA5)
Sergunb 0:8918a71cdbe9 339 PORTA->PCR[5] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK;
Sergunb 0:8918a71cdbe9 340 //Configure RMII0_RXD1 (PTA12)
Sergunb 0:8918a71cdbe9 341 PORTA->PCR[12] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 342 //Configure RMII0_RXD0 (PTA13)
Sergunb 0:8918a71cdbe9 343 PORTA->PCR[13] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 344 //Configure RMII0_CRS_DV (PTA14)
Sergunb 0:8918a71cdbe9 345 PORTA->PCR[14] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 346 //Configure RMII0_TXEN (PTA15)
Sergunb 0:8918a71cdbe9 347 PORTA->PCR[15] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 348 //Configure RMII0_TXD0 (PTA16)
Sergunb 0:8918a71cdbe9 349 PORTA->PCR[16] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 350 //Configure RMII0_TXD1 (PTA17)
Sergunb 0:8918a71cdbe9 351 PORTA->PCR[17] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 352
Sergunb 0:8918a71cdbe9 353 //Configure RMII0_MDIO (PTB0)
Sergunb 0:8918a71cdbe9 354 PORTB->PCR[0] = PORT_PCR_MUX(4) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
Sergunb 0:8918a71cdbe9 355 //Configure RMII0_MDC (PTB1)
Sergunb 0:8918a71cdbe9 356 PORTB->PCR[1] = PORT_PCR_MUX(4);
Sergunb 0:8918a71cdbe9 357
Sergunb 0:8918a71cdbe9 358 //Configure ENET_1588_CLKIN (PTE26)
Sergunb 0:8918a71cdbe9 359 PORTE->PCR[26] = PORT_PCR_MUX(2);
Sergunb 0:8918a71cdbe9 360
Sergunb 0:8918a71cdbe9 361 //Select RMII clock source (ENET_1588_CLKIN)
Sergunb 0:8918a71cdbe9 362 SIM->SOPT2 |= SIM_SOPT2_RMIISRC_MASK;
Sergunb 0:8918a71cdbe9 363 #endif
Sergunb 0:8918a71cdbe9 364 }
Sergunb 0:8918a71cdbe9 365
Sergunb 0:8918a71cdbe9 366 #endif
Sergunb 0:8918a71cdbe9 367
Sergunb 0:8918a71cdbe9 368
Sergunb 0:8918a71cdbe9 369 /**
Sergunb 0:8918a71cdbe9 370 * @brief Initialize buffer descriptors
Sergunb 0:8918a71cdbe9 371 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 372 **/
Sergunb 0:8918a71cdbe9 373
Sergunb 0:8918a71cdbe9 374 void mk6xEthInitBufferDesc(NetInterface *interface)
Sergunb 0:8918a71cdbe9 375 {
Sergunb 0:8918a71cdbe9 376 uint_t i;
Sergunb 0:8918a71cdbe9 377 uint32_t address;
Sergunb 0:8918a71cdbe9 378
Sergunb 0:8918a71cdbe9 379 //Clear TX and RX buffer descriptors
Sergunb 0:8918a71cdbe9 380 memset(txBufferDesc, 0, sizeof(txBufferDesc));
Sergunb 0:8918a71cdbe9 381 memset(rxBufferDesc, 0, sizeof(rxBufferDesc));
Sergunb 0:8918a71cdbe9 382
Sergunb 0:8918a71cdbe9 383 //Initialize TX buffer descriptors
Sergunb 0:8918a71cdbe9 384 for(i = 0; i < MK6X_ETH_TX_BUFFER_COUNT; i++)
Sergunb 0:8918a71cdbe9 385 {
Sergunb 0:8918a71cdbe9 386 //Calculate the address of the current TX buffer
Sergunb 0:8918a71cdbe9 387 address = (uint32_t) txBuffer[i];
Sergunb 0:8918a71cdbe9 388 //Transmit buffer address
Sergunb 0:8918a71cdbe9 389 txBufferDesc[i][2] = htobe16(address >> 16);
Sergunb 0:8918a71cdbe9 390 txBufferDesc[i][3] = htobe16(address & 0xFFFF);
Sergunb 0:8918a71cdbe9 391 //Generate interrupts
Sergunb 0:8918a71cdbe9 392 txBufferDesc[i][4] = HTOBE16(ENET_TBD4_INT);
Sergunb 0:8918a71cdbe9 393 }
Sergunb 0:8918a71cdbe9 394
Sergunb 0:8918a71cdbe9 395 //Mark the last descriptor entry with the wrap flag
Sergunb 0:8918a71cdbe9 396 txBufferDesc[i - 1][0] |= HTOBE16(ENET_TBD0_W);
Sergunb 0:8918a71cdbe9 397 //Initialize TX buffer index
Sergunb 0:8918a71cdbe9 398 txBufferIndex = 0;
Sergunb 0:8918a71cdbe9 399
Sergunb 0:8918a71cdbe9 400 //Initialize RX buffer descriptors
Sergunb 0:8918a71cdbe9 401 for(i = 0; i < MK6X_ETH_RX_BUFFER_COUNT; i++)
Sergunb 0:8918a71cdbe9 402 {
Sergunb 0:8918a71cdbe9 403 //Calculate the address of the current RX buffer
Sergunb 0:8918a71cdbe9 404 address = (uint32_t) rxBuffer[i];
Sergunb 0:8918a71cdbe9 405 //The descriptor is initially owned by the DMA
Sergunb 0:8918a71cdbe9 406 rxBufferDesc[i][0] = HTOBE16(ENET_RBD0_E);
Sergunb 0:8918a71cdbe9 407 //Receive buffer address
Sergunb 0:8918a71cdbe9 408 rxBufferDesc[i][2] = htobe16(address >> 16);
Sergunb 0:8918a71cdbe9 409 rxBufferDesc[i][3] = htobe16(address & 0xFFFF);
Sergunb 0:8918a71cdbe9 410 //Generate interrupts
Sergunb 0:8918a71cdbe9 411 rxBufferDesc[i][4] = HTOBE16(ENET_RBD4_INT);
Sergunb 0:8918a71cdbe9 412 }
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414 //Mark the last descriptor entry with the wrap flag
Sergunb 0:8918a71cdbe9 415 rxBufferDesc[i - 1][0] |= HTOBE16(ENET_RBD0_W);
Sergunb 0:8918a71cdbe9 416 //Initialize RX buffer index
Sergunb 0:8918a71cdbe9 417 rxBufferIndex = 0;
Sergunb 0:8918a71cdbe9 418
Sergunb 0:8918a71cdbe9 419 //Start location of the TX descriptor list
Sergunb 0:8918a71cdbe9 420 ENET->TDSR = (uint32_t) txBufferDesc;
Sergunb 0:8918a71cdbe9 421 //Start location of the RX descriptor list
Sergunb 0:8918a71cdbe9 422 ENET->RDSR = (uint32_t) rxBufferDesc;
Sergunb 0:8918a71cdbe9 423 //Maximum receive buffer size
Sergunb 0:8918a71cdbe9 424 ENET->MRBR = MK6X_ETH_RX_BUFFER_SIZE;
Sergunb 0:8918a71cdbe9 425 }
Sergunb 0:8918a71cdbe9 426
Sergunb 0:8918a71cdbe9 427
Sergunb 0:8918a71cdbe9 428 /**
Sergunb 0:8918a71cdbe9 429 * @brief Kinetis K6x Ethernet MAC timer handler
Sergunb 0:8918a71cdbe9 430 *
Sergunb 0:8918a71cdbe9 431 * This routine is periodically called by the TCP/IP stack to
Sergunb 0:8918a71cdbe9 432 * handle periodic operations such as polling the link state
Sergunb 0:8918a71cdbe9 433 *
Sergunb 0:8918a71cdbe9 434 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 435 **/
Sergunb 0:8918a71cdbe9 436
Sergunb 0:8918a71cdbe9 437 void mk6xEthTick(NetInterface *interface)
Sergunb 0:8918a71cdbe9 438 {
Sergunb 0:8918a71cdbe9 439 //Handle periodic operations
Sergunb 0:8918a71cdbe9 440 interface->phyDriver->tick(interface);
Sergunb 0:8918a71cdbe9 441 }
Sergunb 0:8918a71cdbe9 442
Sergunb 0:8918a71cdbe9 443
Sergunb 0:8918a71cdbe9 444 /**
Sergunb 0:8918a71cdbe9 445 * @brief Enable interrupts
Sergunb 0:8918a71cdbe9 446 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 447 **/
Sergunb 0:8918a71cdbe9 448
Sergunb 0:8918a71cdbe9 449 void mk6xEthEnableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 450 {
Sergunb 0:8918a71cdbe9 451 //Enable Ethernet MAC interrupts
Sergunb 0:8918a71cdbe9 452 NVIC_EnableIRQ(ENET_Transmit_IRQn);
Sergunb 0:8918a71cdbe9 453 NVIC_EnableIRQ(ENET_Receive_IRQn);
Sergunb 0:8918a71cdbe9 454 NVIC_EnableIRQ(ENET_Error_IRQn);
Sergunb 0:8918a71cdbe9 455 //Enable Ethernet PHY interrupts
Sergunb 0:8918a71cdbe9 456 interface->phyDriver->enableIrq(interface);
Sergunb 0:8918a71cdbe9 457 }
Sergunb 0:8918a71cdbe9 458
Sergunb 0:8918a71cdbe9 459
Sergunb 0:8918a71cdbe9 460 /**
Sergunb 0:8918a71cdbe9 461 * @brief Disable interrupts
Sergunb 0:8918a71cdbe9 462 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 463 **/
Sergunb 0:8918a71cdbe9 464
Sergunb 0:8918a71cdbe9 465 void mk6xEthDisableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 466 {
Sergunb 0:8918a71cdbe9 467 //Disable Ethernet MAC interrupts
Sergunb 0:8918a71cdbe9 468 NVIC_DisableIRQ(ENET_Transmit_IRQn);
Sergunb 0:8918a71cdbe9 469 NVIC_DisableIRQ(ENET_Receive_IRQn);
Sergunb 0:8918a71cdbe9 470 NVIC_DisableIRQ(ENET_Error_IRQn);
Sergunb 0:8918a71cdbe9 471 //Disable Ethernet PHY interrupts
Sergunb 0:8918a71cdbe9 472 interface->phyDriver->disableIrq(interface);
Sergunb 0:8918a71cdbe9 473 }
Sergunb 0:8918a71cdbe9 474
Sergunb 0:8918a71cdbe9 475
Sergunb 0:8918a71cdbe9 476 /**
Sergunb 0:8918a71cdbe9 477 * @brief Ethernet MAC transmit interrupt
Sergunb 0:8918a71cdbe9 478 **/
Sergunb 0:8918a71cdbe9 479
Sergunb 0:8918a71cdbe9 480 void ENET_Transmit_IRQHandler(void)
Sergunb 0:8918a71cdbe9 481 {
Sergunb 0:8918a71cdbe9 482 bool_t flag;
Sergunb 0:8918a71cdbe9 483
Sergunb 0:8918a71cdbe9 484 //Enter interrupt service routine
Sergunb 0:8918a71cdbe9 485 osEnterIsr();
Sergunb 0:8918a71cdbe9 486
Sergunb 0:8918a71cdbe9 487 //This flag will be set if a higher priority task must be woken
Sergunb 0:8918a71cdbe9 488 flag = FALSE;
Sergunb 0:8918a71cdbe9 489
Sergunb 0:8918a71cdbe9 490 //A packet has been transmitted?
Sergunb 0:8918a71cdbe9 491 if(ENET->EIR & ENET_EIR_TXF_MASK)
Sergunb 0:8918a71cdbe9 492 {
Sergunb 0:8918a71cdbe9 493 //Clear TXF interrupt flag
Sergunb 0:8918a71cdbe9 494 ENET->EIR = ENET_EIR_TXF_MASK;
Sergunb 0:8918a71cdbe9 495
Sergunb 0:8918a71cdbe9 496 //Check whether the TX buffer is available for writing
Sergunb 0:8918a71cdbe9 497 if(!(txBufferDesc[txBufferIndex][0] & HTOBE16(ENET_TBD0_R)))
Sergunb 0:8918a71cdbe9 498 {
Sergunb 0:8918a71cdbe9 499 //Notify the TCP/IP stack that the transmitter is ready to send
Sergunb 0:8918a71cdbe9 500 flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
Sergunb 0:8918a71cdbe9 501 }
Sergunb 0:8918a71cdbe9 502
Sergunb 0:8918a71cdbe9 503 //Instruct the DMA to poll the transmit descriptor list
Sergunb 0:8918a71cdbe9 504 ENET->TDAR = ENET_TDAR_TDAR_MASK;
Sergunb 0:8918a71cdbe9 505 }
Sergunb 0:8918a71cdbe9 506
Sergunb 0:8918a71cdbe9 507 //Leave interrupt service routine
Sergunb 0:8918a71cdbe9 508 osExitIsr(flag);
Sergunb 0:8918a71cdbe9 509 }
Sergunb 0:8918a71cdbe9 510
Sergunb 0:8918a71cdbe9 511
Sergunb 0:8918a71cdbe9 512 /**
Sergunb 0:8918a71cdbe9 513 * @brief Ethernet MAC receive interrupt
Sergunb 0:8918a71cdbe9 514 **/
Sergunb 0:8918a71cdbe9 515
Sergunb 0:8918a71cdbe9 516 void ENET_Receive_IRQHandler(void)
Sergunb 0:8918a71cdbe9 517 {
Sergunb 0:8918a71cdbe9 518 bool_t flag;
Sergunb 0:8918a71cdbe9 519
Sergunb 0:8918a71cdbe9 520 //Enter interrupt service routine
Sergunb 0:8918a71cdbe9 521 osEnterIsr();
Sergunb 0:8918a71cdbe9 522
Sergunb 0:8918a71cdbe9 523 //This flag will be set if a higher priority task must be woken
Sergunb 0:8918a71cdbe9 524 flag = FALSE;
Sergunb 0:8918a71cdbe9 525
Sergunb 0:8918a71cdbe9 526 //A packet has been received?
Sergunb 0:8918a71cdbe9 527 if(ENET->EIR & ENET_EIR_RXF_MASK)
Sergunb 0:8918a71cdbe9 528 {
Sergunb 0:8918a71cdbe9 529 //Disable RXF interrupt
Sergunb 0:8918a71cdbe9 530 ENET->EIMR &= ~ENET_EIMR_RXF_MASK;
Sergunb 0:8918a71cdbe9 531
Sergunb 0:8918a71cdbe9 532 //Set event flag
Sergunb 0:8918a71cdbe9 533 nicDriverInterface->nicEvent = TRUE;
Sergunb 0:8918a71cdbe9 534 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 535 flag = osSetEventFromIsr(&netEvent);
Sergunb 0:8918a71cdbe9 536 }
Sergunb 0:8918a71cdbe9 537
Sergunb 0:8918a71cdbe9 538 //Leave interrupt service routine
Sergunb 0:8918a71cdbe9 539 osExitIsr(flag);
Sergunb 0:8918a71cdbe9 540 }
Sergunb 0:8918a71cdbe9 541
Sergunb 0:8918a71cdbe9 542
Sergunb 0:8918a71cdbe9 543 /**
Sergunb 0:8918a71cdbe9 544 * @brief Ethernet MAC error interrupt
Sergunb 0:8918a71cdbe9 545 **/
Sergunb 0:8918a71cdbe9 546
Sergunb 0:8918a71cdbe9 547 void ENET_Error_IRQHandler(void)
Sergunb 0:8918a71cdbe9 548 {
Sergunb 0:8918a71cdbe9 549 bool_t flag;
Sergunb 0:8918a71cdbe9 550
Sergunb 0:8918a71cdbe9 551 //Enter interrupt service routine
Sergunb 0:8918a71cdbe9 552 osEnterIsr();
Sergunb 0:8918a71cdbe9 553
Sergunb 0:8918a71cdbe9 554 //This flag will be set if a higher priority task must be woken
Sergunb 0:8918a71cdbe9 555 flag = FALSE;
Sergunb 0:8918a71cdbe9 556
Sergunb 0:8918a71cdbe9 557 //System bus error?
Sergunb 0:8918a71cdbe9 558 if(ENET->EIR & ENET_EIR_EBERR_MASK)
Sergunb 0:8918a71cdbe9 559 {
Sergunb 0:8918a71cdbe9 560 //Disable EBERR interrupt
Sergunb 0:8918a71cdbe9 561 ENET->EIMR &= ~ENET_EIMR_EBERR_MASK;
Sergunb 0:8918a71cdbe9 562
Sergunb 0:8918a71cdbe9 563 //Set event flag
Sergunb 0:8918a71cdbe9 564 nicDriverInterface->nicEvent = TRUE;
Sergunb 0:8918a71cdbe9 565 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 566 flag |= osSetEventFromIsr(&netEvent);
Sergunb 0:8918a71cdbe9 567 }
Sergunb 0:8918a71cdbe9 568
Sergunb 0:8918a71cdbe9 569 //Leave interrupt service routine
Sergunb 0:8918a71cdbe9 570 osExitIsr(flag);
Sergunb 0:8918a71cdbe9 571 }
Sergunb 0:8918a71cdbe9 572
Sergunb 0:8918a71cdbe9 573
Sergunb 0:8918a71cdbe9 574 /**
Sergunb 0:8918a71cdbe9 575 * @brief Kinetis K6x Ethernet MAC event handler
Sergunb 0:8918a71cdbe9 576 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 577 **/
Sergunb 0:8918a71cdbe9 578
Sergunb 0:8918a71cdbe9 579 void mk6xEthEventHandler(NetInterface *interface)
Sergunb 0:8918a71cdbe9 580 {
Sergunb 0:8918a71cdbe9 581 error_t error;
Sergunb 0:8918a71cdbe9 582 uint32_t status;
Sergunb 0:8918a71cdbe9 583
Sergunb 0:8918a71cdbe9 584 //Read interrupt event register
Sergunb 0:8918a71cdbe9 585 status = ENET->EIR;
Sergunb 0:8918a71cdbe9 586
Sergunb 0:8918a71cdbe9 587 //Packet received?
Sergunb 0:8918a71cdbe9 588 if(status & ENET_EIR_RXF_MASK)
Sergunb 0:8918a71cdbe9 589 {
Sergunb 0:8918a71cdbe9 590 //Clear RXF interrupt flag
Sergunb 0:8918a71cdbe9 591 ENET->EIR = ENET_EIR_RXF_MASK;
Sergunb 0:8918a71cdbe9 592
Sergunb 0:8918a71cdbe9 593 //Process all pending packets
Sergunb 0:8918a71cdbe9 594 do
Sergunb 0:8918a71cdbe9 595 {
Sergunb 0:8918a71cdbe9 596 //Read incoming packet
Sergunb 0:8918a71cdbe9 597 error = mk6xEthReceivePacket(interface);
Sergunb 0:8918a71cdbe9 598
Sergunb 0:8918a71cdbe9 599 //No more data in the receive buffer?
Sergunb 0:8918a71cdbe9 600 } while(error != ERROR_BUFFER_EMPTY);
Sergunb 0:8918a71cdbe9 601 }
Sergunb 0:8918a71cdbe9 602
Sergunb 0:8918a71cdbe9 603 //System bus error?
Sergunb 0:8918a71cdbe9 604 if(status & ENET_EIR_EBERR_MASK)
Sergunb 0:8918a71cdbe9 605 {
Sergunb 0:8918a71cdbe9 606 //Clear EBERR interrupt flag
Sergunb 0:8918a71cdbe9 607 ENET->EIR = ENET_EIR_EBERR_MASK;
Sergunb 0:8918a71cdbe9 608
Sergunb 0:8918a71cdbe9 609 //Disable Ethernet MAC
Sergunb 0:8918a71cdbe9 610 ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
Sergunb 0:8918a71cdbe9 611 //Reset buffer descriptors
Sergunb 0:8918a71cdbe9 612 mk6xEthInitBufferDesc(interface);
Sergunb 0:8918a71cdbe9 613 //Resume normal operation
Sergunb 0:8918a71cdbe9 614 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
Sergunb 0:8918a71cdbe9 615 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 616 ENET->RDAR = ENET_RDAR_RDAR_MASK;
Sergunb 0:8918a71cdbe9 617 }
Sergunb 0:8918a71cdbe9 618
Sergunb 0:8918a71cdbe9 619 //Re-enable Ethernet MAC interrupts
Sergunb 0:8918a71cdbe9 620 ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
Sergunb 0:8918a71cdbe9 621 }
Sergunb 0:8918a71cdbe9 622
Sergunb 0:8918a71cdbe9 623
Sergunb 0:8918a71cdbe9 624 /**
Sergunb 0:8918a71cdbe9 625 * @brief Send a packet
Sergunb 0:8918a71cdbe9 626 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 627 * @param[in] buffer Multi-part buffer containing the data to send
Sergunb 0:8918a71cdbe9 628 * @param[in] offset Offset to the first data byte
Sergunb 0:8918a71cdbe9 629 * @return Error code
Sergunb 0:8918a71cdbe9 630 **/
Sergunb 0:8918a71cdbe9 631
Sergunb 0:8918a71cdbe9 632 error_t mk6xEthSendPacket(NetInterface *interface,
Sergunb 0:8918a71cdbe9 633 const NetBuffer *buffer, size_t offset)
Sergunb 0:8918a71cdbe9 634 {
Sergunb 0:8918a71cdbe9 635 size_t length;
Sergunb 0:8918a71cdbe9 636
Sergunb 0:8918a71cdbe9 637 //Retrieve the length of the packet
Sergunb 0:8918a71cdbe9 638 length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 639
Sergunb 0:8918a71cdbe9 640 //Check the frame length
Sergunb 0:8918a71cdbe9 641 if(length > MK6X_ETH_TX_BUFFER_SIZE)
Sergunb 0:8918a71cdbe9 642 {
Sergunb 0:8918a71cdbe9 643 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 644 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 645 //Report an error
Sergunb 0:8918a71cdbe9 646 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 647 }
Sergunb 0:8918a71cdbe9 648
Sergunb 0:8918a71cdbe9 649 //Make sure the current buffer is available for writing
Sergunb 0:8918a71cdbe9 650 if(txBufferDesc[txBufferIndex][0] & HTOBE16(ENET_TBD0_R))
Sergunb 0:8918a71cdbe9 651 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 652
Sergunb 0:8918a71cdbe9 653 //Copy user data to the transmit buffer
Sergunb 0:8918a71cdbe9 654 netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
Sergunb 0:8918a71cdbe9 655
Sergunb 0:8918a71cdbe9 656 //Set frame length
Sergunb 0:8918a71cdbe9 657 txBufferDesc[txBufferIndex][1] = HTOBE16(length);
Sergunb 0:8918a71cdbe9 658 //Clear BDU flag
Sergunb 0:8918a71cdbe9 659 txBufferDesc[txBufferIndex][8] = 0;
Sergunb 0:8918a71cdbe9 660
Sergunb 0:8918a71cdbe9 661 //Check current index
Sergunb 0:8918a71cdbe9 662 if(txBufferIndex < (MK6X_ETH_TX_BUFFER_COUNT - 1))
Sergunb 0:8918a71cdbe9 663 {
Sergunb 0:8918a71cdbe9 664 //Give the ownership of the descriptor to the DMA engine
Sergunb 0:8918a71cdbe9 665 txBufferDesc[txBufferIndex][0] = HTOBE16(ENET_TBD0_R |
Sergunb 0:8918a71cdbe9 666 ENET_TBD0_L | ENET_TBD0_TC);
Sergunb 0:8918a71cdbe9 667
Sergunb 0:8918a71cdbe9 668 //Point to the next buffer
Sergunb 0:8918a71cdbe9 669 txBufferIndex++;
Sergunb 0:8918a71cdbe9 670 }
Sergunb 0:8918a71cdbe9 671 else
Sergunb 0:8918a71cdbe9 672 {
Sergunb 0:8918a71cdbe9 673 //Give the ownership of the descriptor to the DMA engine
Sergunb 0:8918a71cdbe9 674 txBufferDesc[txBufferIndex][0] = HTOBE16(ENET_TBD0_R |
Sergunb 0:8918a71cdbe9 675 ENET_TBD0_W | ENET_TBD0_L | ENET_TBD0_TC);
Sergunb 0:8918a71cdbe9 676
Sergunb 0:8918a71cdbe9 677 //Wrap around
Sergunb 0:8918a71cdbe9 678 txBufferIndex = 0;
Sergunb 0:8918a71cdbe9 679 }
Sergunb 0:8918a71cdbe9 680
Sergunb 0:8918a71cdbe9 681 //Instruct the DMA to poll the transmit descriptor list
Sergunb 0:8918a71cdbe9 682 ENET->TDAR = ENET_TDAR_TDAR_MASK;
Sergunb 0:8918a71cdbe9 683
Sergunb 0:8918a71cdbe9 684 //Check whether the next buffer is available for writing
Sergunb 0:8918a71cdbe9 685 if(!(txBufferDesc[txBufferIndex][0] & HTOBE16(ENET_TBD0_R)))
Sergunb 0:8918a71cdbe9 686 {
Sergunb 0:8918a71cdbe9 687 //The transmitter can accept another packet
Sergunb 0:8918a71cdbe9 688 osSetEvent(&interface->nicTxEvent);
Sergunb 0:8918a71cdbe9 689 }
Sergunb 0:8918a71cdbe9 690
Sergunb 0:8918a71cdbe9 691 //Successful processing
Sergunb 0:8918a71cdbe9 692 return NO_ERROR;
Sergunb 0:8918a71cdbe9 693 }
Sergunb 0:8918a71cdbe9 694
Sergunb 0:8918a71cdbe9 695
Sergunb 0:8918a71cdbe9 696 /**
Sergunb 0:8918a71cdbe9 697 * @brief Receive a packet
Sergunb 0:8918a71cdbe9 698 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 699 * @return Error code
Sergunb 0:8918a71cdbe9 700 **/
Sergunb 0:8918a71cdbe9 701
Sergunb 0:8918a71cdbe9 702 error_t mk6xEthReceivePacket(NetInterface *interface)
Sergunb 0:8918a71cdbe9 703 {
Sergunb 0:8918a71cdbe9 704 error_t error;
Sergunb 0:8918a71cdbe9 705 size_t n;
Sergunb 0:8918a71cdbe9 706
Sergunb 0:8918a71cdbe9 707 //Make sure the current buffer is available for reading
Sergunb 0:8918a71cdbe9 708 if(!(rxBufferDesc[rxBufferIndex][0] & HTOBE16(ENET_RBD0_E)))
Sergunb 0:8918a71cdbe9 709 {
Sergunb 0:8918a71cdbe9 710 //The frame should not span multiple buffers
Sergunb 0:8918a71cdbe9 711 if(rxBufferDesc[rxBufferIndex][0] & HTOBE16(ENET_RBD0_L))
Sergunb 0:8918a71cdbe9 712 {
Sergunb 0:8918a71cdbe9 713 //Check whether an error occurred
Sergunb 0:8918a71cdbe9 714 if(!(rxBufferDesc[rxBufferIndex][0] & HTOBE16(ENET_RBD0_LG |
Sergunb 0:8918a71cdbe9 715 ENET_RBD0_NO | ENET_RBD0_CR | ENET_RBD0_OV | ENET_RBD0_TR)))
Sergunb 0:8918a71cdbe9 716 {
Sergunb 0:8918a71cdbe9 717 //Retrieve the length of the frame
Sergunb 0:8918a71cdbe9 718 n = betoh16(rxBufferDesc[rxBufferIndex][1]);
Sergunb 0:8918a71cdbe9 719 //Limit the number of data to read
Sergunb 0:8918a71cdbe9 720 n = MIN(n, MK6X_ETH_RX_BUFFER_SIZE);
Sergunb 0:8918a71cdbe9 721
Sergunb 0:8918a71cdbe9 722 //Pass the packet to the upper layer
Sergunb 0:8918a71cdbe9 723 nicProcessPacket(interface, rxBuffer[rxBufferIndex], n);
Sergunb 0:8918a71cdbe9 724
Sergunb 0:8918a71cdbe9 725 //Valid packet received
Sergunb 0:8918a71cdbe9 726 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 727 }
Sergunb 0:8918a71cdbe9 728 else
Sergunb 0:8918a71cdbe9 729 {
Sergunb 0:8918a71cdbe9 730 //The received packet contains an error
Sergunb 0:8918a71cdbe9 731 error = ERROR_INVALID_PACKET;
Sergunb 0:8918a71cdbe9 732 }
Sergunb 0:8918a71cdbe9 733 }
Sergunb 0:8918a71cdbe9 734 else
Sergunb 0:8918a71cdbe9 735 {
Sergunb 0:8918a71cdbe9 736 //The packet is not valid
Sergunb 0:8918a71cdbe9 737 error = ERROR_INVALID_PACKET;
Sergunb 0:8918a71cdbe9 738 }
Sergunb 0:8918a71cdbe9 739
Sergunb 0:8918a71cdbe9 740 //Clear BDU flag
Sergunb 0:8918a71cdbe9 741 rxBufferDesc[rxBufferIndex][8] = 0;
Sergunb 0:8918a71cdbe9 742
Sergunb 0:8918a71cdbe9 743 //Check current index
Sergunb 0:8918a71cdbe9 744 if(rxBufferIndex < (MK6X_ETH_RX_BUFFER_COUNT - 1))
Sergunb 0:8918a71cdbe9 745 {
Sergunb 0:8918a71cdbe9 746 //Give the ownership of the descriptor back to the DMA engine
Sergunb 0:8918a71cdbe9 747 rxBufferDesc[rxBufferIndex][0] = HTOBE16(ENET_RBD0_E);
Sergunb 0:8918a71cdbe9 748 //Point to the next buffer
Sergunb 0:8918a71cdbe9 749 rxBufferIndex++;
Sergunb 0:8918a71cdbe9 750 }
Sergunb 0:8918a71cdbe9 751 else
Sergunb 0:8918a71cdbe9 752 {
Sergunb 0:8918a71cdbe9 753 //Give the ownership of the descriptor back to the DMA engine
Sergunb 0:8918a71cdbe9 754 rxBufferDesc[rxBufferIndex][0] = HTOBE16(ENET_RBD0_E | ENET_RBD0_W);
Sergunb 0:8918a71cdbe9 755 //Wrap around
Sergunb 0:8918a71cdbe9 756 rxBufferIndex = 0;
Sergunb 0:8918a71cdbe9 757 }
Sergunb 0:8918a71cdbe9 758
Sergunb 0:8918a71cdbe9 759 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 760 ENET->RDAR = ENET_RDAR_RDAR_MASK;
Sergunb 0:8918a71cdbe9 761 }
Sergunb 0:8918a71cdbe9 762 else
Sergunb 0:8918a71cdbe9 763 {
Sergunb 0:8918a71cdbe9 764 //No more data in the receive buffer
Sergunb 0:8918a71cdbe9 765 error = ERROR_BUFFER_EMPTY;
Sergunb 0:8918a71cdbe9 766 }
Sergunb 0:8918a71cdbe9 767
Sergunb 0:8918a71cdbe9 768 //Return status code
Sergunb 0:8918a71cdbe9 769 return error;
Sergunb 0:8918a71cdbe9 770 }
Sergunb 0:8918a71cdbe9 771
Sergunb 0:8918a71cdbe9 772
Sergunb 0:8918a71cdbe9 773 /**
Sergunb 0:8918a71cdbe9 774 * @brief Configure multicast MAC address filtering
Sergunb 0:8918a71cdbe9 775 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 776 * @return Error code
Sergunb 0:8918a71cdbe9 777 **/
Sergunb 0:8918a71cdbe9 778
Sergunb 0:8918a71cdbe9 779 error_t mk6xEthSetMulticastFilter(NetInterface *interface)
Sergunb 0:8918a71cdbe9 780 {
Sergunb 0:8918a71cdbe9 781 uint_t i;
Sergunb 0:8918a71cdbe9 782 uint_t k;
Sergunb 0:8918a71cdbe9 783 uint32_t crc;
Sergunb 0:8918a71cdbe9 784 uint32_t hashTable[2];
Sergunb 0:8918a71cdbe9 785 MacFilterEntry *entry;
Sergunb 0:8918a71cdbe9 786
Sergunb 0:8918a71cdbe9 787 //Debug message
Sergunb 0:8918a71cdbe9 788 TRACE_DEBUG("Updating Kinetis K6x hash table...\r\n");
Sergunb 0:8918a71cdbe9 789
Sergunb 0:8918a71cdbe9 790 //Clear hash table
Sergunb 0:8918a71cdbe9 791 hashTable[0] = 0;
Sergunb 0:8918a71cdbe9 792 hashTable[1] = 0;
Sergunb 0:8918a71cdbe9 793
Sergunb 0:8918a71cdbe9 794 //The MAC filter table contains the multicast MAC addresses
Sergunb 0:8918a71cdbe9 795 //to accept when receiving an Ethernet frame
Sergunb 0:8918a71cdbe9 796 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
Sergunb 0:8918a71cdbe9 797 {
Sergunb 0:8918a71cdbe9 798 //Point to the current entry
Sergunb 0:8918a71cdbe9 799 entry = &interface->macMulticastFilter[i];
Sergunb 0:8918a71cdbe9 800
Sergunb 0:8918a71cdbe9 801 //Valid entry?
Sergunb 0:8918a71cdbe9 802 if(entry->refCount > 0)
Sergunb 0:8918a71cdbe9 803 {
Sergunb 0:8918a71cdbe9 804 //Compute CRC over the current MAC address
Sergunb 0:8918a71cdbe9 805 crc = mk6xEthCalcCrc(&entry->addr, sizeof(MacAddr));
Sergunb 0:8918a71cdbe9 806
Sergunb 0:8918a71cdbe9 807 //The upper 6 bits in the CRC register are used to index the
Sergunb 0:8918a71cdbe9 808 //contents of the hash table
Sergunb 0:8918a71cdbe9 809 k = (crc >> 26) & 0x3F;
Sergunb 0:8918a71cdbe9 810
Sergunb 0:8918a71cdbe9 811 //Update hash table contents
Sergunb 0:8918a71cdbe9 812 hashTable[k / 32] |= (1 << (k % 32));
Sergunb 0:8918a71cdbe9 813 }
Sergunb 0:8918a71cdbe9 814 }
Sergunb 0:8918a71cdbe9 815
Sergunb 0:8918a71cdbe9 816 //Write the hash table
Sergunb 0:8918a71cdbe9 817 ENET->GALR = hashTable[0];
Sergunb 0:8918a71cdbe9 818 ENET->GAUR = hashTable[1];
Sergunb 0:8918a71cdbe9 819
Sergunb 0:8918a71cdbe9 820 //Debug message
Sergunb 0:8918a71cdbe9 821 TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", ENET->GALR);
Sergunb 0:8918a71cdbe9 822 TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", ENET->GAUR);
Sergunb 0:8918a71cdbe9 823
Sergunb 0:8918a71cdbe9 824 //Successful processing
Sergunb 0:8918a71cdbe9 825 return NO_ERROR;
Sergunb 0:8918a71cdbe9 826 }
Sergunb 0:8918a71cdbe9 827
Sergunb 0:8918a71cdbe9 828
Sergunb 0:8918a71cdbe9 829 /**
Sergunb 0:8918a71cdbe9 830 * @brief Adjust MAC configuration parameters for proper operation
Sergunb 0:8918a71cdbe9 831 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 832 * @return Error code
Sergunb 0:8918a71cdbe9 833 **/
Sergunb 0:8918a71cdbe9 834
Sergunb 0:8918a71cdbe9 835 error_t mk6xEthUpdateMacConfig(NetInterface *interface)
Sergunb 0:8918a71cdbe9 836 {
Sergunb 0:8918a71cdbe9 837 //Disable Ethernet MAC while modifying configuration registers
Sergunb 0:8918a71cdbe9 838 ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
Sergunb 0:8918a71cdbe9 839
Sergunb 0:8918a71cdbe9 840 //10BASE-T or 100BASE-TX operation mode?
Sergunb 0:8918a71cdbe9 841 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
Sergunb 0:8918a71cdbe9 842 {
Sergunb 0:8918a71cdbe9 843 //100 Mbps operation
Sergunb 0:8918a71cdbe9 844 ENET->RCR &= ~ENET_RCR_RMII_10T_MASK;
Sergunb 0:8918a71cdbe9 845 }
Sergunb 0:8918a71cdbe9 846 else
Sergunb 0:8918a71cdbe9 847 {
Sergunb 0:8918a71cdbe9 848 //10 Mbps operation
Sergunb 0:8918a71cdbe9 849 ENET->RCR |= ENET_RCR_RMII_10T_MASK;
Sergunb 0:8918a71cdbe9 850 }
Sergunb 0:8918a71cdbe9 851
Sergunb 0:8918a71cdbe9 852 //Half-duplex or full-duplex mode?
Sergunb 0:8918a71cdbe9 853 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
Sergunb 0:8918a71cdbe9 854 {
Sergunb 0:8918a71cdbe9 855 //Full-duplex mode
Sergunb 0:8918a71cdbe9 856 ENET->TCR |= ENET_TCR_FDEN_MASK;
Sergunb 0:8918a71cdbe9 857 //Receive path operates independently of transmit
Sergunb 0:8918a71cdbe9 858 ENET->RCR &= ~ENET_RCR_DRT_MASK;
Sergunb 0:8918a71cdbe9 859 }
Sergunb 0:8918a71cdbe9 860 else
Sergunb 0:8918a71cdbe9 861 {
Sergunb 0:8918a71cdbe9 862 //Half-duplex mode
Sergunb 0:8918a71cdbe9 863 ENET->TCR &= ~ENET_TCR_FDEN_MASK;
Sergunb 0:8918a71cdbe9 864 //Disable reception of frames while transmitting
Sergunb 0:8918a71cdbe9 865 ENET->RCR |= ENET_RCR_DRT_MASK;
Sergunb 0:8918a71cdbe9 866 }
Sergunb 0:8918a71cdbe9 867
Sergunb 0:8918a71cdbe9 868 //Reset buffer descriptors
Sergunb 0:8918a71cdbe9 869 mk6xEthInitBufferDesc(interface);
Sergunb 0:8918a71cdbe9 870
Sergunb 0:8918a71cdbe9 871 //Re-enable Ethernet MAC
Sergunb 0:8918a71cdbe9 872 ENET->ECR |= ENET_ECR_ETHEREN_MASK;
Sergunb 0:8918a71cdbe9 873 //Instruct the DMA to poll the receive descriptor list
Sergunb 0:8918a71cdbe9 874 ENET->RDAR = ENET_RDAR_RDAR_MASK;
Sergunb 0:8918a71cdbe9 875
Sergunb 0:8918a71cdbe9 876 //Successful processing
Sergunb 0:8918a71cdbe9 877 return NO_ERROR;
Sergunb 0:8918a71cdbe9 878 }
Sergunb 0:8918a71cdbe9 879
Sergunb 0:8918a71cdbe9 880
Sergunb 0:8918a71cdbe9 881 /**
Sergunb 0:8918a71cdbe9 882 * @brief Write PHY register
Sergunb 0:8918a71cdbe9 883 * @param[in] phyAddr PHY address
Sergunb 0:8918a71cdbe9 884 * @param[in] regAddr Register address
Sergunb 0:8918a71cdbe9 885 * @param[in] data Register value
Sergunb 0:8918a71cdbe9 886 **/
Sergunb 0:8918a71cdbe9 887
Sergunb 0:8918a71cdbe9 888 void mk6xEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Sergunb 0:8918a71cdbe9 889 {
Sergunb 0:8918a71cdbe9 890 uint32_t value;
Sergunb 0:8918a71cdbe9 891
Sergunb 0:8918a71cdbe9 892 //Set up a write operation
Sergunb 0:8918a71cdbe9 893 value = ENET_MMFR_ST(1) | ENET_MMFR_OP(1) | ENET_MMFR_TA(2);
Sergunb 0:8918a71cdbe9 894 //PHY address
Sergunb 0:8918a71cdbe9 895 value |= ENET_MMFR_PA(phyAddr);
Sergunb 0:8918a71cdbe9 896 //Register address
Sergunb 0:8918a71cdbe9 897 value |= ENET_MMFR_RA(regAddr);
Sergunb 0:8918a71cdbe9 898 //Register value
Sergunb 0:8918a71cdbe9 899 value |= ENET_MMFR_DATA(data);
Sergunb 0:8918a71cdbe9 900
Sergunb 0:8918a71cdbe9 901 //Clear MII interrupt flag
Sergunb 0:8918a71cdbe9 902 ENET->EIR = ENET_EIR_MII_MASK;
Sergunb 0:8918a71cdbe9 903 //Start a write operation
Sergunb 0:8918a71cdbe9 904 ENET->MMFR = value;
Sergunb 0:8918a71cdbe9 905 //Wait for the write to complete
Sergunb 0:8918a71cdbe9 906 while(!(ENET->EIR & ENET_EIR_MII_MASK));
Sergunb 0:8918a71cdbe9 907 }
Sergunb 0:8918a71cdbe9 908
Sergunb 0:8918a71cdbe9 909
Sergunb 0:8918a71cdbe9 910 /**
Sergunb 0:8918a71cdbe9 911 * @brief Read PHY register
Sergunb 0:8918a71cdbe9 912 * @param[in] phyAddr PHY address
Sergunb 0:8918a71cdbe9 913 * @param[in] regAddr Register address
Sergunb 0:8918a71cdbe9 914 * @return Register value
Sergunb 0:8918a71cdbe9 915 **/
Sergunb 0:8918a71cdbe9 916
Sergunb 0:8918a71cdbe9 917 uint16_t mk6xEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Sergunb 0:8918a71cdbe9 918 {
Sergunb 0:8918a71cdbe9 919 uint32_t value;
Sergunb 0:8918a71cdbe9 920
Sergunb 0:8918a71cdbe9 921 //Set up a read operation
Sergunb 0:8918a71cdbe9 922 value = ENET_MMFR_ST(1) | ENET_MMFR_OP(2) | ENET_MMFR_TA(2);
Sergunb 0:8918a71cdbe9 923 //PHY address
Sergunb 0:8918a71cdbe9 924 value |= ENET_MMFR_PA(phyAddr);
Sergunb 0:8918a71cdbe9 925 //Register address
Sergunb 0:8918a71cdbe9 926 value |= ENET_MMFR_RA(regAddr);
Sergunb 0:8918a71cdbe9 927
Sergunb 0:8918a71cdbe9 928 //Clear MII interrupt flag
Sergunb 0:8918a71cdbe9 929 ENET->EIR = ENET_EIR_MII_MASK;
Sergunb 0:8918a71cdbe9 930 //Start a read operation
Sergunb 0:8918a71cdbe9 931 ENET->MMFR = value;
Sergunb 0:8918a71cdbe9 932 //Wait for the read to complete
Sergunb 0:8918a71cdbe9 933 while(!(ENET->EIR & ENET_EIR_MII_MASK));
Sergunb 0:8918a71cdbe9 934
Sergunb 0:8918a71cdbe9 935 //Return PHY register contents
Sergunb 0:8918a71cdbe9 936 return ENET->MMFR & ENET_MMFR_DATA_MASK;
Sergunb 0:8918a71cdbe9 937 }
Sergunb 0:8918a71cdbe9 938
Sergunb 0:8918a71cdbe9 939
Sergunb 0:8918a71cdbe9 940 /**
Sergunb 0:8918a71cdbe9 941 * @brief CRC calculation
Sergunb 0:8918a71cdbe9 942 * @param[in] data Pointer to the data over which to calculate the CRC
Sergunb 0:8918a71cdbe9 943 * @param[in] length Number of bytes to process
Sergunb 0:8918a71cdbe9 944 * @return Resulting CRC value
Sergunb 0:8918a71cdbe9 945 **/
Sergunb 0:8918a71cdbe9 946
Sergunb 0:8918a71cdbe9 947 uint32_t mk6xEthCalcCrc(const void *data, size_t length)
Sergunb 0:8918a71cdbe9 948 {
Sergunb 0:8918a71cdbe9 949 uint_t i;
Sergunb 0:8918a71cdbe9 950 uint_t j;
Sergunb 0:8918a71cdbe9 951
Sergunb 0:8918a71cdbe9 952 //Point to the data over which to calculate the CRC
Sergunb 0:8918a71cdbe9 953 const uint8_t *p = (uint8_t *) data;
Sergunb 0:8918a71cdbe9 954 //CRC preset value
Sergunb 0:8918a71cdbe9 955 uint32_t crc = 0xFFFFFFFF;
Sergunb 0:8918a71cdbe9 956
Sergunb 0:8918a71cdbe9 957 //Loop through data
Sergunb 0:8918a71cdbe9 958 for(i = 0; i < length; i++)
Sergunb 0:8918a71cdbe9 959 {
Sergunb 0:8918a71cdbe9 960 //Update CRC value
Sergunb 0:8918a71cdbe9 961 crc ^= p[i];
Sergunb 0:8918a71cdbe9 962 //The message is processed bit by bit
Sergunb 0:8918a71cdbe9 963 for(j = 0; j < 8; j++)
Sergunb 0:8918a71cdbe9 964 {
Sergunb 0:8918a71cdbe9 965 if(crc & 0x00000001)
Sergunb 0:8918a71cdbe9 966 crc = (crc >> 1) ^ 0xEDB88320;
Sergunb 0:8918a71cdbe9 967 else
Sergunb 0:8918a71cdbe9 968 crc = crc >> 1;
Sergunb 0:8918a71cdbe9 969 }
Sergunb 0:8918a71cdbe9 970 }
Sergunb 0:8918a71cdbe9 971
Sergunb 0:8918a71cdbe9 972 //Return CRC value
Sergunb 0:8918a71cdbe9 973 return crc;
Sergunb 0:8918a71cdbe9 974 }
Sergunb 0:8918a71cdbe9 975