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 ksz8895.c
Sergunb 0:8918a71cdbe9 3 * @brief KSZ8895 Ethernet switch
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 "core/net.h"
Sergunb 0:8918a71cdbe9 34 #include "drivers/ksz8895.h"
Sergunb 0:8918a71cdbe9 35 #include "debug.h"
Sergunb 0:8918a71cdbe9 36
Sergunb 0:8918a71cdbe9 37
Sergunb 0:8918a71cdbe9 38 /**
Sergunb 0:8918a71cdbe9 39 * @brief KSZ8895 Ethernet switch driver
Sergunb 0:8918a71cdbe9 40 **/
Sergunb 0:8918a71cdbe9 41
Sergunb 0:8918a71cdbe9 42 const PhyDriver ksz8895PhyDriver =
Sergunb 0:8918a71cdbe9 43 {
Sergunb 0:8918a71cdbe9 44 ksz8895Init,
Sergunb 0:8918a71cdbe9 45 ksz8895Tick,
Sergunb 0:8918a71cdbe9 46 ksz8895EnableIrq,
Sergunb 0:8918a71cdbe9 47 ksz8895DisableIrq,
Sergunb 0:8918a71cdbe9 48 ksz8895EventHandler,
Sergunb 0:8918a71cdbe9 49 };
Sergunb 0:8918a71cdbe9 50
Sergunb 0:8918a71cdbe9 51
Sergunb 0:8918a71cdbe9 52 /**
Sergunb 0:8918a71cdbe9 53 * @brief KSZ8895 Ethernet switch initialization
Sergunb 0:8918a71cdbe9 54 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 55 * @return Error code
Sergunb 0:8918a71cdbe9 56 **/
Sergunb 0:8918a71cdbe9 57
Sergunb 0:8918a71cdbe9 58 error_t ksz8895Init(NetInterface *interface)
Sergunb 0:8918a71cdbe9 59 {
Sergunb 0:8918a71cdbe9 60 uint_t port;
Sergunb 0:8918a71cdbe9 61
Sergunb 0:8918a71cdbe9 62 //Debug message
Sergunb 0:8918a71cdbe9 63 TRACE_INFO("Initializing KSZ8895...\r\n");
Sergunb 0:8918a71cdbe9 64
Sergunb 0:8918a71cdbe9 65 //Loop through ports
Sergunb 0:8918a71cdbe9 66 for(port = KSZ8895_PORT1; port <= KSZ8895_PORT4; port++)
Sergunb 0:8918a71cdbe9 67 {
Sergunb 0:8918a71cdbe9 68 //Debug message
Sergunb 0:8918a71cdbe9 69 TRACE_DEBUG("Port %u:\r\n", port);
Sergunb 0:8918a71cdbe9 70 //Dump PHY registers for debugging purpose
Sergunb 0:8918a71cdbe9 71 ksz8895DumpPhyReg(interface, port);
Sergunb 0:8918a71cdbe9 72 }
Sergunb 0:8918a71cdbe9 73
Sergunb 0:8918a71cdbe9 74 //Force the TCP/IP stack to poll the link state at startup
Sergunb 0:8918a71cdbe9 75 interface->phyEvent = TRUE;
Sergunb 0:8918a71cdbe9 76 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 77 osSetEvent(&netEvent);
Sergunb 0:8918a71cdbe9 78
Sergunb 0:8918a71cdbe9 79 //Successful initialization
Sergunb 0:8918a71cdbe9 80 return NO_ERROR;
Sergunb 0:8918a71cdbe9 81 }
Sergunb 0:8918a71cdbe9 82
Sergunb 0:8918a71cdbe9 83
Sergunb 0:8918a71cdbe9 84 /**
Sergunb 0:8918a71cdbe9 85 * @brief Get link state
Sergunb 0:8918a71cdbe9 86 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 87 * @param[in] port Port number
Sergunb 0:8918a71cdbe9 88 * @return Link state
Sergunb 0:8918a71cdbe9 89 **/
Sergunb 0:8918a71cdbe9 90
Sergunb 0:8918a71cdbe9 91 bool_t ksz8895GetLinkState(NetInterface *interface, uint8_t port)
Sergunb 0:8918a71cdbe9 92 {
Sergunb 0:8918a71cdbe9 93 uint16_t status;
Sergunb 0:8918a71cdbe9 94 bool_t linkState;
Sergunb 0:8918a71cdbe9 95
Sergunb 0:8918a71cdbe9 96 //Check port number
Sergunb 0:8918a71cdbe9 97 if(port >= KSZ8895_PORT1 && port <= KSZ8895_PORT4)
Sergunb 0:8918a71cdbe9 98 {
Sergunb 0:8918a71cdbe9 99 //Get exclusive access
Sergunb 0:8918a71cdbe9 100 osAcquireMutex(&netMutex);
Sergunb 0:8918a71cdbe9 101 //Read status register
Sergunb 0:8918a71cdbe9 102 status = ksz8895ReadPhyReg(interface, port, KSZ8895_PHY_REG_BMSR);
Sergunb 0:8918a71cdbe9 103 //Release exclusive access
Sergunb 0:8918a71cdbe9 104 osReleaseMutex(&netMutex);
Sergunb 0:8918a71cdbe9 105
Sergunb 0:8918a71cdbe9 106 //Retrieve current link state
Sergunb 0:8918a71cdbe9 107 linkState = (status & BMSR_LINK_STATUS) ? TRUE : FALSE;
Sergunb 0:8918a71cdbe9 108 }
Sergunb 0:8918a71cdbe9 109 else
Sergunb 0:8918a71cdbe9 110 {
Sergunb 0:8918a71cdbe9 111 //The specified port number is not valid
Sergunb 0:8918a71cdbe9 112 linkState = FALSE;
Sergunb 0:8918a71cdbe9 113 }
Sergunb 0:8918a71cdbe9 114
Sergunb 0:8918a71cdbe9 115 //Return link status
Sergunb 0:8918a71cdbe9 116 return linkState;
Sergunb 0:8918a71cdbe9 117 }
Sergunb 0:8918a71cdbe9 118
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 /**
Sergunb 0:8918a71cdbe9 121 * @brief KSZ8895 timer handler
Sergunb 0:8918a71cdbe9 122 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 123 **/
Sergunb 0:8918a71cdbe9 124
Sergunb 0:8918a71cdbe9 125 void ksz8895Tick(NetInterface *interface)
Sergunb 0:8918a71cdbe9 126 {
Sergunb 0:8918a71cdbe9 127 uint_t port;
Sergunb 0:8918a71cdbe9 128 uint16_t status;
Sergunb 0:8918a71cdbe9 129 bool_t linkState;
Sergunb 0:8918a71cdbe9 130
Sergunb 0:8918a71cdbe9 131 //Initialize link state
Sergunb 0:8918a71cdbe9 132 linkState = FALSE;
Sergunb 0:8918a71cdbe9 133
Sergunb 0:8918a71cdbe9 134 //Loop through ports
Sergunb 0:8918a71cdbe9 135 for(port = KSZ8895_PORT1; port <= KSZ8895_PORT4; port++)
Sergunb 0:8918a71cdbe9 136 {
Sergunb 0:8918a71cdbe9 137 //Read status register
Sergunb 0:8918a71cdbe9 138 status = ksz8895ReadPhyReg(interface, port, KSZ8895_PHY_REG_BMSR);
Sergunb 0:8918a71cdbe9 139
Sergunb 0:8918a71cdbe9 140 //Retrieve current link state
Sergunb 0:8918a71cdbe9 141 if(status & BMSR_LINK_STATUS)
Sergunb 0:8918a71cdbe9 142 linkState = TRUE;
Sergunb 0:8918a71cdbe9 143 }
Sergunb 0:8918a71cdbe9 144
Sergunb 0:8918a71cdbe9 145 //Link up event?
Sergunb 0:8918a71cdbe9 146 if(linkState)
Sergunb 0:8918a71cdbe9 147 {
Sergunb 0:8918a71cdbe9 148 if(!interface->linkState)
Sergunb 0:8918a71cdbe9 149 {
Sergunb 0:8918a71cdbe9 150 //Set event flag
Sergunb 0:8918a71cdbe9 151 interface->phyEvent = TRUE;
Sergunb 0:8918a71cdbe9 152 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 153 osSetEvent(&netEvent);
Sergunb 0:8918a71cdbe9 154 }
Sergunb 0:8918a71cdbe9 155 }
Sergunb 0:8918a71cdbe9 156 //Link down event?
Sergunb 0:8918a71cdbe9 157 else
Sergunb 0:8918a71cdbe9 158 {
Sergunb 0:8918a71cdbe9 159 if(interface->linkState)
Sergunb 0:8918a71cdbe9 160 {
Sergunb 0:8918a71cdbe9 161 //Set event flag
Sergunb 0:8918a71cdbe9 162 interface->phyEvent = TRUE;
Sergunb 0:8918a71cdbe9 163 //Notify the TCP/IP stack of the event
Sergunb 0:8918a71cdbe9 164 osSetEvent(&netEvent);
Sergunb 0:8918a71cdbe9 165 }
Sergunb 0:8918a71cdbe9 166 }
Sergunb 0:8918a71cdbe9 167 }
Sergunb 0:8918a71cdbe9 168
Sergunb 0:8918a71cdbe9 169
Sergunb 0:8918a71cdbe9 170 /**
Sergunb 0:8918a71cdbe9 171 * @brief Enable interrupts
Sergunb 0:8918a71cdbe9 172 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 173 **/
Sergunb 0:8918a71cdbe9 174
Sergunb 0:8918a71cdbe9 175 void ksz8895EnableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 176 {
Sergunb 0:8918a71cdbe9 177 }
Sergunb 0:8918a71cdbe9 178
Sergunb 0:8918a71cdbe9 179
Sergunb 0:8918a71cdbe9 180 /**
Sergunb 0:8918a71cdbe9 181 * @brief Disable interrupts
Sergunb 0:8918a71cdbe9 182 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 183 **/
Sergunb 0:8918a71cdbe9 184
Sergunb 0:8918a71cdbe9 185 void ksz8895DisableIrq(NetInterface *interface)
Sergunb 0:8918a71cdbe9 186 {
Sergunb 0:8918a71cdbe9 187 }
Sergunb 0:8918a71cdbe9 188
Sergunb 0:8918a71cdbe9 189
Sergunb 0:8918a71cdbe9 190 /**
Sergunb 0:8918a71cdbe9 191 * @brief KSZ8895 event handler
Sergunb 0:8918a71cdbe9 192 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 193 **/
Sergunb 0:8918a71cdbe9 194
Sergunb 0:8918a71cdbe9 195 void ksz8895EventHandler(NetInterface *interface)
Sergunb 0:8918a71cdbe9 196 {
Sergunb 0:8918a71cdbe9 197 uint_t port;
Sergunb 0:8918a71cdbe9 198 uint16_t status;
Sergunb 0:8918a71cdbe9 199 bool_t linkState;
Sergunb 0:8918a71cdbe9 200
Sergunb 0:8918a71cdbe9 201 //Initialize link state
Sergunb 0:8918a71cdbe9 202 linkState = FALSE;
Sergunb 0:8918a71cdbe9 203
Sergunb 0:8918a71cdbe9 204 //Loop through ports
Sergunb 0:8918a71cdbe9 205 for(port = KSZ8895_PORT1; port <= KSZ8895_PORT4; port++)
Sergunb 0:8918a71cdbe9 206 {
Sergunb 0:8918a71cdbe9 207 //Read status register
Sergunb 0:8918a71cdbe9 208 status = ksz8895ReadPhyReg(interface, port, KSZ8895_PHY_REG_BMSR);
Sergunb 0:8918a71cdbe9 209
Sergunb 0:8918a71cdbe9 210 //Retrieve current link state
Sergunb 0:8918a71cdbe9 211 if(status & BMSR_LINK_STATUS)
Sergunb 0:8918a71cdbe9 212 linkState = TRUE;
Sergunb 0:8918a71cdbe9 213 }
Sergunb 0:8918a71cdbe9 214
Sergunb 0:8918a71cdbe9 215 //Link up event?
Sergunb 0:8918a71cdbe9 216 if(linkState)
Sergunb 0:8918a71cdbe9 217 {
Sergunb 0:8918a71cdbe9 218 //Set current speed
Sergunb 0:8918a71cdbe9 219 interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
Sergunb 0:8918a71cdbe9 220 //Set duplex mode
Sergunb 0:8918a71cdbe9 221 interface->duplexMode = NIC_FULL_DUPLEX_MODE;
Sergunb 0:8918a71cdbe9 222
Sergunb 0:8918a71cdbe9 223 //Update link state
Sergunb 0:8918a71cdbe9 224 interface->linkState = TRUE;
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Adjust MAC configuration parameters for proper operation
Sergunb 0:8918a71cdbe9 227 interface->nicDriver->updateMacConfig(interface);
Sergunb 0:8918a71cdbe9 228 }
Sergunb 0:8918a71cdbe9 229 else
Sergunb 0:8918a71cdbe9 230 {
Sergunb 0:8918a71cdbe9 231 //Update link state
Sergunb 0:8918a71cdbe9 232 interface->linkState = FALSE;
Sergunb 0:8918a71cdbe9 233 }
Sergunb 0:8918a71cdbe9 234
Sergunb 0:8918a71cdbe9 235 //Process link state change event
Sergunb 0:8918a71cdbe9 236 nicNotifyLinkChange(interface);
Sergunb 0:8918a71cdbe9 237 }
Sergunb 0:8918a71cdbe9 238
Sergunb 0:8918a71cdbe9 239
Sergunb 0:8918a71cdbe9 240 /**
Sergunb 0:8918a71cdbe9 241 * @brief Write PHY register
Sergunb 0:8918a71cdbe9 242 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 243 * @param[in] port Port number
Sergunb 0:8918a71cdbe9 244 * @param[in] address PHY register address
Sergunb 0:8918a71cdbe9 245 * @param[in] data Register value
Sergunb 0:8918a71cdbe9 246 **/
Sergunb 0:8918a71cdbe9 247
Sergunb 0:8918a71cdbe9 248 void ksz8895WritePhyReg(NetInterface *interface,
Sergunb 0:8918a71cdbe9 249 uint8_t port, uint8_t address, uint16_t data)
Sergunb 0:8918a71cdbe9 250 {
Sergunb 0:8918a71cdbe9 251 //Write the specified PHY register
Sergunb 0:8918a71cdbe9 252 interface->nicDriver->writePhyReg(port, address, data);
Sergunb 0:8918a71cdbe9 253 }
Sergunb 0:8918a71cdbe9 254
Sergunb 0:8918a71cdbe9 255
Sergunb 0:8918a71cdbe9 256 /**
Sergunb 0:8918a71cdbe9 257 * @brief Read PHY register
Sergunb 0:8918a71cdbe9 258 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 259 * @param[in] port Port number
Sergunb 0:8918a71cdbe9 260 * @param[in] address PHY register address
Sergunb 0:8918a71cdbe9 261 * @return Register value
Sergunb 0:8918a71cdbe9 262 **/
Sergunb 0:8918a71cdbe9 263
Sergunb 0:8918a71cdbe9 264 uint16_t ksz8895ReadPhyReg(NetInterface *interface,
Sergunb 0:8918a71cdbe9 265 uint8_t port, uint8_t address)
Sergunb 0:8918a71cdbe9 266 {
Sergunb 0:8918a71cdbe9 267 //Read the specified PHY register
Sergunb 0:8918a71cdbe9 268 return interface->nicDriver->readPhyReg(port, address);
Sergunb 0:8918a71cdbe9 269 }
Sergunb 0:8918a71cdbe9 270
Sergunb 0:8918a71cdbe9 271
Sergunb 0:8918a71cdbe9 272 /**
Sergunb 0:8918a71cdbe9 273 * @brief Dump PHY registers for debugging purpose
Sergunb 0:8918a71cdbe9 274 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 275 * @param[in] port Port number
Sergunb 0:8918a71cdbe9 276 **/
Sergunb 0:8918a71cdbe9 277
Sergunb 0:8918a71cdbe9 278 void ksz8895DumpPhyReg(NetInterface *interface, uint8_t port)
Sergunb 0:8918a71cdbe9 279 {
Sergunb 0:8918a71cdbe9 280 uint8_t i;
Sergunb 0:8918a71cdbe9 281
Sergunb 0:8918a71cdbe9 282 //Loop through PHY registers
Sergunb 0:8918a71cdbe9 283 for(i = 0; i < 32; i++)
Sergunb 0:8918a71cdbe9 284 {
Sergunb 0:8918a71cdbe9 285 //Display current PHY register
Sergunb 0:8918a71cdbe9 286 TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, ksz8895ReadPhyReg(interface, port, i));
Sergunb 0:8918a71cdbe9 287 }
Sergunb 0:8918a71cdbe9 288
Sergunb 0:8918a71cdbe9 289 //Terminate with a line feed
Sergunb 0:8918a71cdbe9 290 TRACE_DEBUG("\r\n");
Sergunb 0:8918a71cdbe9 291 }
Sergunb 0:8918a71cdbe9 292