Mbed library for ENC28J60 Ethernet modules. Full support for TCP/IP and UDP Server, Client and HTTP server (webserver). DHCP and DNS is included.

Dependents:   mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more

Library for ENC28J60 Ethernet modules.

/media/uploads/hudakz/enc28j60_module01.jpg

Ported to mbed from Norbert Truchsess's UIPEthernet library for Arduino. Thank you Norbert!

  • Full support for persistent (streaming) TCP/IP and UDP connections Client and Server each, ARP, ICMP, DHCP and DNS.
  • Works with both Mbed OS 2 and Mbed OS 5.

Usage:

  • Import the library into your project.
  • Add #include "UipEthernet.h" to main.cpp
  • Create one instance of the UipEthernet class initialized with the MAC address you'd like to use and SPI pins of the connected Mbed board.

Example programs:

Import programWebSwitch_ENC28J60

HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Import programHTTPServer_Echo_ENC28J60

A simple HTTP server echoing received requests. Ethernet connection is over an ENC28J60 board. Usage: Type the server's IP address into you web browser and hit <ENTER>.

Import programTcpServer_ENC28J60

Simple TCP/IP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programTcpClient_ENC28J60

Simple TCP/IP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpServer_ENC28J60

Simple UDP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpClient_ENC28J60

Simple UDP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programMQTT_Hello_ENC28J60

MQTT Client example program. Ethernet connection is via an ENC28J60 module.

Committer:
hudakz
Date:
Sat Sep 07 17:42:42 2019 +0000
Revision:
15:53715cc81c63
Parent:
14:7648334eb41b
Child:
16:269f652b4d0b
Timeout parameter added for the 'connect' function, SPI speed reduced from 20 to 10 Mb/s, debug messages fixed ...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 9:a156d3de5647 1 /*
hudakz 9:a156d3de5647 2 UIPEthernet.cpp - Arduino implementation of a UIP wrapper class.
hudakz 9:a156d3de5647 3 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
hudakz 9:a156d3de5647 4 All rights reserved.
hudakz 9:a156d3de5647 5
hudakz 9:a156d3de5647 6 Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
hudakz 9:a156d3de5647 7
hudakz 9:a156d3de5647 8 This program is free software: you can redistribute it and/or modify
hudakz 9:a156d3de5647 9 it under the terms of the GNU General Public License as published by
hudakz 9:a156d3de5647 10 the Free Software Foundation, either version 3 of the License, or
hudakz 9:a156d3de5647 11 (at your option) any later version.
hudakz 9:a156d3de5647 12
hudakz 9:a156d3de5647 13 This program is distributed in the hope that it will be useful,
hudakz 9:a156d3de5647 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 9:a156d3de5647 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 9:a156d3de5647 16 GNU General Public License for more details.
hudakz 9:a156d3de5647 17
hudakz 9:a156d3de5647 18 You should have received a copy of the GNU General Public License
hudakz 9:a156d3de5647 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 9:a156d3de5647 20 */
hudakz 9:a156d3de5647 21 #include "mbed.h"
hudakz 9:a156d3de5647 22 #include "UipEthernet.h"
hudakz 11:647d53d146f1 23 #include "utility/Enc28j60Eth.h"
hudakz 9:a156d3de5647 24 #include "UdpSocket.h"
hudakz 9:a156d3de5647 25
hudakz 9:a156d3de5647 26 extern "C"
hudakz 9:a156d3de5647 27 {
hudakz 9:a156d3de5647 28 #include "utility/uip-conf.h"
hudakz 9:a156d3de5647 29 #include "utility/uip.h"
hudakz 9:a156d3de5647 30 #include "utility/uip_arp.h"
hudakz 9:a156d3de5647 31 #include "utility/uip_timer.h"
hudakz 9:a156d3de5647 32 }
hudakz 9:a156d3de5647 33 #define ETH_HDR ((struct uip_eth_hdr*) &uip_buf[0])
hudakz 9:a156d3de5647 34
hudakz 9:a156d3de5647 35 UipEthernet* UipEthernet:: ethernet = NULL;
hudakz 9:a156d3de5647 36 memhandle UipEthernet:: inPacket(NOBLOCK);
hudakz 9:a156d3de5647 37 memhandle UipEthernet:: uipPacket(NOBLOCK);
hudakz 9:a156d3de5647 38 uint8_t UipEthernet:: uipHeaderLen(0);
hudakz 9:a156d3de5647 39 uint8_t UipEthernet:: packetState(0);
hudakz 9:a156d3de5647 40 IpAddress UipEthernet:: dnsServerAddress;
hudakz 9:a156d3de5647 41
hudakz 9:a156d3de5647 42 /**
hudakz 9:a156d3de5647 43 * @brief
hudakz 9:a156d3de5647 44 * @note
hudakz 9:a156d3de5647 45 * @param
hudakz 9:a156d3de5647 46 * @retval
hudakz 9:a156d3de5647 47 */
hudakz 9:a156d3de5647 48 void enc28j60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len)
hudakz 9:a156d3de5647 49 {
hudakz 11:647d53d146f1 50 //as ENC28J60 DMA is unable to copy single byte:
hudakz 9:a156d3de5647 51 if (len == 1) {
hudakz 11:647d53d146f1 52 UipEthernet::ethernet->enc28j60Eth.writeByte(dest, UipEthernet::ethernet->enc28j60Eth.readByte(src));
hudakz 9:a156d3de5647 53 }
hudakz 9:a156d3de5647 54 else {
hudakz 9:a156d3de5647 55 // calculate address of last byte
hudakz 9:a156d3de5647 56 len += src - 1;
hudakz 9:a156d3de5647 57
hudakz 9:a156d3de5647 58 /* 1. Appropriately program the EDMAST, EDMAND
hudakz 9:a156d3de5647 59 and EDMADST register pairs. The EDMAST
hudakz 9:a156d3de5647 60 registers should point to the first byte to copy
hudakz 9:a156d3de5647 61 from, the EDMAND registers should point to the
hudakz 9:a156d3de5647 62 last byte to copy and the EDMADST registers
hudakz 9:a156d3de5647 63 should point to the first byte in the destination
hudakz 9:a156d3de5647 64 range. The destination range will always be
hudakz 9:a156d3de5647 65 linear, never wrapping at any values except from
hudakz 9:a156d3de5647 66 8191 to 0 (the 8-Kbyte memory boundary).
hudakz 9:a156d3de5647 67 Extreme care should be taken when
hudakz 9:a156d3de5647 68 programming the start and end pointers to
hudakz 9:a156d3de5647 69 prevent a never ending DMA operation which
hudakz 9:a156d3de5647 70 would overwrite the entire 8-Kbyte buffer.
hudakz 9:a156d3de5647 71 */
hudakz 11:647d53d146f1 72 UipEthernet::ethernet->enc28j60Eth.writeRegPair(EDMASTL, src);
hudakz 11:647d53d146f1 73 UipEthernet::ethernet->enc28j60Eth.writeRegPair(EDMADSTL, dest);
hudakz 9:a156d3de5647 74
hudakz 11:647d53d146f1 75 if ((src <= RXEND_INIT) && (len > RXEND_INIT))
hudakz 11:647d53d146f1 76 len -= ((RXEND_INIT + 1) - RXSTART_INIT);
hudakz 11:647d53d146f1 77 UipEthernet::ethernet->enc28j60Eth.writeRegPair(EDMANDL, len);
hudakz 9:a156d3de5647 78
hudakz 9:a156d3de5647 79 /* 2. If an interrupt at the end of the copy process is
hudakz 9:a156d3de5647 80 desired, set EIE.DMAIE and EIE.INTIE and
hudakz 9:a156d3de5647 81 clear EIR.DMAIF.
hudakz 9:a156d3de5647 82
hudakz 9:a156d3de5647 83 3. Verify that ECON1.CSUMEN is clear. */
hudakz 11:647d53d146f1 84 UipEthernet::ethernet->enc28j60Eth.writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
hudakz 9:a156d3de5647 85
hudakz 9:a156d3de5647 86 /* 4. Start the DMA copy by setting ECON1.DMAST. */
hudakz 11:647d53d146f1 87 UipEthernet::ethernet->enc28j60Eth.writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
hudakz 9:a156d3de5647 88
hudakz 9:a156d3de5647 89 // wait until runnig DMA is completed
hudakz 11:647d53d146f1 90 while (UipEthernet::ethernet->enc28j60Eth.readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
hudakz 9:a156d3de5647 91 }
hudakz 9:a156d3de5647 92 }
hudakz 9:a156d3de5647 93
hudakz 9:a156d3de5647 94 /*
hudakz 9:a156d3de5647 95 * Because UIP isn't encapsulated within a class we have to use global
hudakz 9:a156d3de5647 96 * variables, so we can only have one TCP/IP stack per program.
hudakz 9:a156d3de5647 97 */
hudakz 9:a156d3de5647 98 UipEthernet::UipEthernet(const uint8_t mac[6], PinName mosi, PinName miso, PinName sck, PinName cs) :
hudakz 11:647d53d146f1 99 enc28j60Eth(mosi, miso, sck, cs),
hudakz 9:a156d3de5647 100 _mac(new uint8_t[6]),
hudakz 9:a156d3de5647 101 _ip(),
hudakz 9:a156d3de5647 102 _dns(),
hudakz 9:a156d3de5647 103 _gateway(),
hudakz 9:a156d3de5647 104 _subnet()
hudakz 9:a156d3de5647 105 {
hudakz 9:a156d3de5647 106 for (uint8_t i = 0; i < 6; i++)
hudakz 9:a156d3de5647 107 _mac[i] = mac[i];
hudakz 9:a156d3de5647 108 }
hudakz 9:a156d3de5647 109
hudakz 9:a156d3de5647 110 /**
hudakz 9:a156d3de5647 111 * @brief
hudakz 9:a156d3de5647 112 * @note
hudakz 9:a156d3de5647 113 * @param
hudakz 9:a156d3de5647 114 * @retval
hudakz 9:a156d3de5647 115 */
hudakz 15:53715cc81c63 116 int UipEthernet::connect(unsigned long timeout)
hudakz 9:a156d3de5647 117 {
hudakz 9:a156d3de5647 118 // Inicialize static pointer to the UIPEthernet instance
hudakz 9:a156d3de5647 119 ethernet = this;
hudakz 9:a156d3de5647 120
hudakz 9:a156d3de5647 121 // Initialise the basic info
hudakz 9:a156d3de5647 122 init(_mac);
hudakz 9:a156d3de5647 123
hudakz 9:a156d3de5647 124 // If no local IP address has been set ask DHCP server to provide one
hudakz 9:a156d3de5647 125 if (_ip == IpAddress()) {
hudakz 9:a156d3de5647 126 // Now try to get our config info from a DHCP server
hudakz 15:53715cc81c63 127 int ret = dhcpClient.begin((uint8_t*)_mac, timeout);
hudakz 9:a156d3de5647 128
hudakz 9:a156d3de5647 129 if (ret == 1) {
hudakz 9:a156d3de5647 130 // We've successfully found a DHCP server and got our configuration info, so set things
hudakz 9:a156d3de5647 131 // accordingly
hudakz 9:a156d3de5647 132 set_network
hudakz 9:a156d3de5647 133 (
hudakz 9:a156d3de5647 134 dhcpClient.getLocalIp(),
hudakz 9:a156d3de5647 135 dhcpClient.getDnsServerIp(),
hudakz 9:a156d3de5647 136 dhcpClient.getGatewayIp(),
hudakz 9:a156d3de5647 137 dhcpClient.getSubnetMask()
hudakz 9:a156d3de5647 138 );
hudakz 14:7648334eb41b 139
hudakz 14:7648334eb41b 140 return 0;
hudakz 9:a156d3de5647 141 }
hudakz 9:a156d3de5647 142
hudakz 14:7648334eb41b 143 return -1;
hudakz 9:a156d3de5647 144 }
hudakz 9:a156d3de5647 145 else {
hudakz 14:7648334eb41b 146 return 0;
hudakz 9:a156d3de5647 147 }
hudakz 9:a156d3de5647 148 }
hudakz 11:647d53d146f1 149
hudakz 11:647d53d146f1 150 /**
hudakz 11:647d53d146f1 151 * @brief
hudakz 11:647d53d146f1 152 * @note
hudakz 11:647d53d146f1 153 * @param
hudakz 11:647d53d146f1 154 * @retval
hudakz 11:647d53d146f1 155 */
hudakz 13:95c00132cd98 156 void UipEthernet::disconnect()
hudakz 13:95c00132cd98 157 {
hudakz 13:95c00132cd98 158 ethernet = NULL;
hudakz 13:95c00132cd98 159 }
hudakz 13:95c00132cd98 160
hudakz 13:95c00132cd98 161 /**
hudakz 13:95c00132cd98 162 * @brief
hudakz 13:95c00132cd98 163 * @note
hudakz 13:95c00132cd98 164 * @param
hudakz 13:95c00132cd98 165 * @retval
hudakz 13:95c00132cd98 166 */
hudakz 11:647d53d146f1 167 void UipEthernet::set_network(const char *ip_address, const char *netmask, const char *gateway)
hudakz 11:647d53d146f1 168 {
hudakz 11:647d53d146f1 169 _ip = IpAddress(ip_address, strlen(ip_address));
hudakz 11:647d53d146f1 170 _dns = _ip;
hudakz 11:647d53d146f1 171 _dns[3] = 1;
hudakz 11:647d53d146f1 172 _gateway = IpAddress(gateway, strlen(gateway));
hudakz 11:647d53d146f1 173 _subnet = IpAddress(netmask, strlen(netmask));
hudakz 11:647d53d146f1 174 set_network(_ip, _dns, _gateway, _subnet);
hudakz 11:647d53d146f1 175 }
hudakz 9:a156d3de5647 176
hudakz 9:a156d3de5647 177 /**
hudakz 9:a156d3de5647 178 * @brief
hudakz 9:a156d3de5647 179 * @note
hudakz 9:a156d3de5647 180 * @param
hudakz 9:a156d3de5647 181 * @retval
hudakz 9:a156d3de5647 182 */
hudakz 9:a156d3de5647 183 void UipEthernet::set_network(uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4)
hudakz 9:a156d3de5647 184 {
hudakz 9:a156d3de5647 185 _ip = IpAddress(octet1, octet2, octet3, octet4);
hudakz 9:a156d3de5647 186 set_network(_ip);
hudakz 9:a156d3de5647 187 }
hudakz 9:a156d3de5647 188
hudakz 9:a156d3de5647 189 /**
hudakz 9:a156d3de5647 190 * @brief
hudakz 9:a156d3de5647 191 * @note
hudakz 9:a156d3de5647 192 * @param
hudakz 9:a156d3de5647 193 * @retval
hudakz 9:a156d3de5647 194 */
hudakz 9:a156d3de5647 195 void UipEthernet::set_network(IpAddress ip)
hudakz 9:a156d3de5647 196 {
hudakz 9:a156d3de5647 197 _ip = ip;
hudakz 9:a156d3de5647 198 _dns = ip;
hudakz 9:a156d3de5647 199 _dns[3] = 1;
hudakz 9:a156d3de5647 200 set_network(ip, dns);
hudakz 9:a156d3de5647 201 }
hudakz 9:a156d3de5647 202
hudakz 9:a156d3de5647 203 /**
hudakz 9:a156d3de5647 204 * @brief
hudakz 9:a156d3de5647 205 * @note
hudakz 9:a156d3de5647 206 * @param
hudakz 9:a156d3de5647 207 * @retval
hudakz 9:a156d3de5647 208 */
hudakz 9:a156d3de5647 209 void UipEthernet::set_network(IpAddress ip, IpAddress dns)
hudakz 9:a156d3de5647 210 {
hudakz 9:a156d3de5647 211 _ip = ip;
hudakz 9:a156d3de5647 212 _dns = dns;
hudakz 9:a156d3de5647 213 _gateway = ip;
hudakz 9:a156d3de5647 214 _gateway[3] = 1;
hudakz 9:a156d3de5647 215 set_network(ip, dns, _gateway);
hudakz 9:a156d3de5647 216 }
hudakz 9:a156d3de5647 217
hudakz 9:a156d3de5647 218 /**
hudakz 9:a156d3de5647 219 * @brief
hudakz 9:a156d3de5647 220 * @note
hudakz 9:a156d3de5647 221 * @param
hudakz 9:a156d3de5647 222 * @retval
hudakz 9:a156d3de5647 223 */
hudakz 9:a156d3de5647 224 void UipEthernet::set_network(IpAddress ip, IpAddress dns, IpAddress gateway)
hudakz 9:a156d3de5647 225 {
hudakz 9:a156d3de5647 226 _ip = ip;
hudakz 9:a156d3de5647 227 _dns = dns;
hudakz 9:a156d3de5647 228 _gateway = gateway;
hudakz 9:a156d3de5647 229 _subnet = IpAddress(255, 255, 255, 0);
hudakz 11:647d53d146f1 230 set_network(_ip, _dns, _gateway, _subnet);
hudakz 9:a156d3de5647 231 }
hudakz 9:a156d3de5647 232
hudakz 9:a156d3de5647 233 /**
hudakz 9:a156d3de5647 234 * @brief
hudakz 9:a156d3de5647 235 * @note
hudakz 9:a156d3de5647 236 * @param
hudakz 9:a156d3de5647 237 * @retval
hudakz 9:a156d3de5647 238 */
hudakz 9:a156d3de5647 239 void UipEthernet::set_network(IpAddress ip, IpAddress dns, IpAddress gateway, IpAddress subnet)
hudakz 9:a156d3de5647 240 {
hudakz 9:a156d3de5647 241 uip_ipaddr_t ipaddr;
hudakz 9:a156d3de5647 242
hudakz 9:a156d3de5647 243 uip_ip_addr(ipaddr, ip);
hudakz 9:a156d3de5647 244 uip_sethostaddr(ipaddr);
hudakz 9:a156d3de5647 245
hudakz 9:a156d3de5647 246 uip_ip_addr(ipaddr, gateway);
hudakz 9:a156d3de5647 247 uip_setdraddr(ipaddr);
hudakz 9:a156d3de5647 248
hudakz 9:a156d3de5647 249 uip_ip_addr(ipaddr, subnet);
hudakz 9:a156d3de5647 250 uip_setnetmask(ipaddr);
hudakz 9:a156d3de5647 251
hudakz 9:a156d3de5647 252 dnsServerAddress = dns;
hudakz 9:a156d3de5647 253 }
hudakz 9:a156d3de5647 254
hudakz 9:a156d3de5647 255 /**
hudakz 9:a156d3de5647 256 * @brief
hudakz 9:a156d3de5647 257 * @note
hudakz 9:a156d3de5647 258 * @param
hudakz 9:a156d3de5647 259 * @retval
hudakz 9:a156d3de5647 260 */
hudakz 9:a156d3de5647 261 IpAddress UipEthernet::localIP()
hudakz 9:a156d3de5647 262 {
hudakz 9:a156d3de5647 263 uip_ipaddr_t a;
hudakz 9:a156d3de5647 264
hudakz 9:a156d3de5647 265 uip_gethostaddr(a);
hudakz 9:a156d3de5647 266 return ip_addr_uip(a);
hudakz 9:a156d3de5647 267 }
hudakz 9:a156d3de5647 268
hudakz 9:a156d3de5647 269 /**
hudakz 9:a156d3de5647 270 * @brief
hudakz 9:a156d3de5647 271 * @note
hudakz 9:a156d3de5647 272 * @param
hudakz 9:a156d3de5647 273 * @retval
hudakz 9:a156d3de5647 274 */
hudakz 9:a156d3de5647 275 IpAddress UipEthernet::subnetMask()
hudakz 9:a156d3de5647 276 {
hudakz 9:a156d3de5647 277 uip_ipaddr_t a;
hudakz 9:a156d3de5647 278
hudakz 9:a156d3de5647 279 uip_getnetmask(a);
hudakz 9:a156d3de5647 280 return ip_addr_uip(a);
hudakz 9:a156d3de5647 281 }
hudakz 9:a156d3de5647 282
hudakz 9:a156d3de5647 283 /**
hudakz 9:a156d3de5647 284 * @brief
hudakz 9:a156d3de5647 285 * @note
hudakz 9:a156d3de5647 286 * @param
hudakz 9:a156d3de5647 287 * @retval
hudakz 9:a156d3de5647 288 */
hudakz 9:a156d3de5647 289 IpAddress UipEthernet::gatewayIP()
hudakz 9:a156d3de5647 290 {
hudakz 9:a156d3de5647 291 uip_ipaddr_t a;
hudakz 9:a156d3de5647 292
hudakz 9:a156d3de5647 293 uip_getdraddr(a);
hudakz 9:a156d3de5647 294 return ip_addr_uip(a);
hudakz 9:a156d3de5647 295 }
hudakz 9:a156d3de5647 296
hudakz 9:a156d3de5647 297 /**
hudakz 9:a156d3de5647 298 * @brief
hudakz 9:a156d3de5647 299 * @note
hudakz 9:a156d3de5647 300 * @param
hudakz 9:a156d3de5647 301 * @retval
hudakz 9:a156d3de5647 302 */
hudakz 9:a156d3de5647 303 IpAddress UipEthernet::dnsServerIP()
hudakz 9:a156d3de5647 304 {
hudakz 9:a156d3de5647 305 return dnsServerAddress;
hudakz 9:a156d3de5647 306 }
hudakz 9:a156d3de5647 307
hudakz 9:a156d3de5647 308 /**
hudakz 9:a156d3de5647 309 * @brief
hudakz 9:a156d3de5647 310 * @note
hudakz 9:a156d3de5647 311 * @param
hudakz 9:a156d3de5647 312 * @retval
hudakz 9:a156d3de5647 313 */
hudakz 9:a156d3de5647 314 const char* UipEthernet::get_ip_address()
hudakz 9:a156d3de5647 315 {
hudakz 9:a156d3de5647 316 static char buf[16];
hudakz 9:a156d3de5647 317 return localIP().toString(buf);
hudakz 9:a156d3de5647 318 }
hudakz 9:a156d3de5647 319
hudakz 9:a156d3de5647 320 /**
hudakz 9:a156d3de5647 321 * @brief
hudakz 9:a156d3de5647 322 * @note
hudakz 9:a156d3de5647 323 * @param
hudakz 9:a156d3de5647 324 * @retval
hudakz 9:a156d3de5647 325 */
hudakz 9:a156d3de5647 326 const char* UipEthernet::get_netmask()
hudakz 9:a156d3de5647 327 {
hudakz 9:a156d3de5647 328 static char buf[16];
hudakz 9:a156d3de5647 329 return subnetMask().toString(buf);
hudakz 9:a156d3de5647 330 }
hudakz 9:a156d3de5647 331
hudakz 9:a156d3de5647 332 /**
hudakz 9:a156d3de5647 333 * @brief
hudakz 9:a156d3de5647 334 * @note
hudakz 9:a156d3de5647 335 * @param
hudakz 9:a156d3de5647 336 * @retval
hudakz 9:a156d3de5647 337 */
hudakz 9:a156d3de5647 338 const char* UipEthernet::get_gateway()
hudakz 9:a156d3de5647 339 {
hudakz 9:a156d3de5647 340 static char buf[16];
hudakz 9:a156d3de5647 341 return gatewayIP().toString(buf);
hudakz 9:a156d3de5647 342 }
hudakz 9:a156d3de5647 343
hudakz 9:a156d3de5647 344 /**
hudakz 9:a156d3de5647 345 * @brief
hudakz 9:a156d3de5647 346 * @note
hudakz 9:a156d3de5647 347 * @param
hudakz 9:a156d3de5647 348 * @retval
hudakz 9:a156d3de5647 349 */
hudakz 9:a156d3de5647 350 void UipEthernet::tick()
hudakz 9:a156d3de5647 351 {
hudakz 9:a156d3de5647 352 if (inPacket == NOBLOCK) {
hudakz 11:647d53d146f1 353 inPacket = enc28j60Eth.receivePacket();
hudakz 9:a156d3de5647 354 #ifdef UIPETHERNET_DEBUG
hudakz 15:53715cc81c63 355 if (inPacket != NOBLOCK) {
hudakz 15:53715cc81c63 356 printf("--------------\r\nreceivePacket: %d\r\n", inPacket);
hudakz 9:a156d3de5647 357 }
hudakz 9:a156d3de5647 358 #endif
hudakz 9:a156d3de5647 359 }
hudakz 9:a156d3de5647 360
hudakz 9:a156d3de5647 361 if (inPacket != NOBLOCK) {
hudakz 9:a156d3de5647 362 packetState = UIPETHERNET_FREEPACKET;
hudakz 11:647d53d146f1 363 uip_len = enc28j60Eth.blockSize(inPacket);
hudakz 9:a156d3de5647 364 if (uip_len > 0) {
hudakz 11:647d53d146f1 365 enc28j60Eth.readPacket(inPacket, 0, (uint8_t*)uip_buf, UIP_BUFSIZE);
hudakz 9:a156d3de5647 366 if (ETH_HDR->type == HTONS(UIP_ETHTYPE_IP)) {
hudakz 9:a156d3de5647 367 uipPacket = inPacket; //required for upper_layer_checksum of in_packet!
hudakz 9:a156d3de5647 368 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 369 printf("readPacket type IP, uip_len: %d\r\n", uip_len);
hudakz 9:a156d3de5647 370 #endif
hudakz 9:a156d3de5647 371 uip_arp_ipin();
hudakz 9:a156d3de5647 372 uip_input();
hudakz 9:a156d3de5647 373 if (uip_len > 0) {
hudakz 9:a156d3de5647 374 uip_arp_out();
hudakz 9:a156d3de5647 375 network_send();
hudakz 9:a156d3de5647 376 }
hudakz 9:a156d3de5647 377 }
hudakz 9:a156d3de5647 378 else
hudakz 9:a156d3de5647 379 if (ETH_HDR->type == HTONS(UIP_ETHTYPE_ARP))
hudakz 9:a156d3de5647 380 {
hudakz 9:a156d3de5647 381 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 382 printf("readPacket type ARP, uip_len: %d\r\n", uip_len);
hudakz 9:a156d3de5647 383 #endif
hudakz 9:a156d3de5647 384 uip_arp_arpin();
hudakz 9:a156d3de5647 385 if (uip_len > 0) {
hudakz 9:a156d3de5647 386 network_send();
hudakz 9:a156d3de5647 387 }
hudakz 9:a156d3de5647 388 }
hudakz 9:a156d3de5647 389 }
hudakz 9:a156d3de5647 390
hudakz 9:a156d3de5647 391 if (inPacket != NOBLOCK && (packetState & UIPETHERNET_FREEPACKET))
hudakz 9:a156d3de5647 392 {
hudakz 9:a156d3de5647 393 #ifdef UIPETHERNET_DEBUG
hudakz 15:53715cc81c63 394 printf("freeing packet: %d\r\n", inPacket);
hudakz 9:a156d3de5647 395 #endif
hudakz 11:647d53d146f1 396 enc28j60Eth.freePacket();
hudakz 9:a156d3de5647 397 inPacket = NOBLOCK;
hudakz 9:a156d3de5647 398 }
hudakz 9:a156d3de5647 399 }
hudakz 9:a156d3de5647 400
hudakz 9:a156d3de5647 401 bool periodic = periodicTimer.read_ms() > UIP_PERIODIC_TIMEOUT;
hudakz 9:a156d3de5647 402
hudakz 9:a156d3de5647 403 for (int i = 0; i < UIP_CONNS; i++) {
hudakz 9:a156d3de5647 404 uip_conn = &uip_conns[i];
hudakz 9:a156d3de5647 405 if (periodic) {
hudakz 9:a156d3de5647 406 uip_process(UIP_TIMER);
hudakz 9:a156d3de5647 407 }
hudakz 9:a156d3de5647 408 else {
hudakz 9:a156d3de5647 409 uip_userdata_t* data = (uip_userdata_t*)uip_conn->appstate;
hudakz 9:a156d3de5647 410 if (data != NULL) {
hudakz 9:a156d3de5647 411 if (data->pollTimer.read_ms() >= UIP_CLIENT_TIMEOUT) {
hudakz 9:a156d3de5647 412 uip_process(UIP_POLL_REQUEST);
hudakz 9:a156d3de5647 413 data->pollTimer.stop();
hudakz 9:a156d3de5647 414 data->pollTimer.reset();
hudakz 9:a156d3de5647 415 }
hudakz 9:a156d3de5647 416 }
hudakz 9:a156d3de5647 417 else
hudakz 9:a156d3de5647 418 continue;
hudakz 9:a156d3de5647 419 }
hudakz 9:a156d3de5647 420
hudakz 9:a156d3de5647 421 // If the above function invocation resulted in data that
hudakz 9:a156d3de5647 422 // should be sent out on the Enc28J60Network, the global variable
hudakz 9:a156d3de5647 423 // uip_len is set to a value > 0.
hudakz 9:a156d3de5647 424 if (uip_len > 0) {
hudakz 9:a156d3de5647 425 uip_arp_out();
hudakz 9:a156d3de5647 426 network_send();
hudakz 9:a156d3de5647 427 }
hudakz 9:a156d3de5647 428 }
hudakz 9:a156d3de5647 429
hudakz 9:a156d3de5647 430 if (periodic) {
hudakz 9:a156d3de5647 431 periodicTimer.reset();
hudakz 9:a156d3de5647 432 #if UIP_UDP
hudakz 9:a156d3de5647 433 for (int i = 0; i < UIP_UDP_CONNS; i++) {
hudakz 9:a156d3de5647 434 uip_udp_periodic(i);
hudakz 9:a156d3de5647 435
hudakz 9:a156d3de5647 436 // If the above function invocation resulted in data that
hudakz 9:a156d3de5647 437 // should be sent out on the Enc28J60Network, the global variable
hudakz 9:a156d3de5647 438 // uip_len is set to a value > 0.
hudakz 9:a156d3de5647 439 if (uip_len > 0) {
hudakz 9:a156d3de5647 440 UdpSocket::_send((uip_udp_userdata_t *) (uip_udp_conns[i].appstate));
hudakz 9:a156d3de5647 441 }
hudakz 9:a156d3de5647 442 }
hudakz 9:a156d3de5647 443 #endif // UIP_UDP
hudakz 9:a156d3de5647 444 }
hudakz 9:a156d3de5647 445 }
hudakz 9:a156d3de5647 446
hudakz 9:a156d3de5647 447 /**
hudakz 9:a156d3de5647 448 * @brief
hudakz 9:a156d3de5647 449 * @note
hudakz 9:a156d3de5647 450 * @param
hudakz 9:a156d3de5647 451 * @retval
hudakz 9:a156d3de5647 452 */
hudakz 9:a156d3de5647 453 bool UipEthernet::network_send()
hudakz 9:a156d3de5647 454 {
hudakz 9:a156d3de5647 455 if (packetState & UIPETHERNET_SENDPACKET)
hudakz 9:a156d3de5647 456 {
hudakz 9:a156d3de5647 457 #ifdef UIPETHERNET_DEBUG
hudakz 15:53715cc81c63 458 printf("Enc28J60Network_send uipPacket: %d, hdrlen: %d\r\n", inPacket, uipHeaderLen);
hudakz 9:a156d3de5647 459 #endif
hudakz 11:647d53d146f1 460 enc28j60Eth.writePacket(uipPacket, 0, uip_buf, uipHeaderLen);
hudakz 9:a156d3de5647 461 packetState &= ~UIPETHERNET_SENDPACKET;
hudakz 9:a156d3de5647 462 goto sendandfree;
hudakz 9:a156d3de5647 463 }
hudakz 9:a156d3de5647 464
hudakz 11:647d53d146f1 465 uipPacket = Enc28j60Eth::allocBlock(uip_len);
hudakz 9:a156d3de5647 466 if (uipPacket != NOBLOCK)
hudakz 9:a156d3de5647 467 {
hudakz 9:a156d3de5647 468 #ifdef UIPETHERNET_DEBUG
hudakz 15:53715cc81c63 469 printf("Enc28J60Network_send uip_buf (uip_len): %d, packet: %d\r\n", uip_len, uipPacket);
hudakz 9:a156d3de5647 470 #endif
hudakz 11:647d53d146f1 471 enc28j60Eth.writePacket(uipPacket, 0, uip_buf, uip_len);
hudakz 9:a156d3de5647 472 goto sendandfree;
hudakz 9:a156d3de5647 473 }
hudakz 9:a156d3de5647 474
hudakz 15:53715cc81c63 475 #ifdef UIPETHERNET_DEBUG
hudakz 15:53715cc81c63 476 printf("Enc28J60Network_send return false\r\n");
hudakz 15:53715cc81c63 477 #endif
hudakz 9:a156d3de5647 478 return false;
hudakz 9:a156d3de5647 479 sendandfree:
hudakz 11:647d53d146f1 480 enc28j60Eth.sendPacket(uipPacket);
hudakz 11:647d53d146f1 481 Enc28j60Eth::freeBlock(uipPacket);
hudakz 9:a156d3de5647 482 uipPacket = NOBLOCK;
hudakz 9:a156d3de5647 483 return true;
hudakz 9:a156d3de5647 484 }
hudakz 9:a156d3de5647 485
hudakz 9:a156d3de5647 486 /**
hudakz 9:a156d3de5647 487 * @brief
hudakz 9:a156d3de5647 488 * @note
hudakz 9:a156d3de5647 489 * @param
hudakz 9:a156d3de5647 490 * @retval
hudakz 9:a156d3de5647 491 */
hudakz 9:a156d3de5647 492 void UipEthernet::init(const uint8_t* mac)
hudakz 9:a156d3de5647 493 {
hudakz 9:a156d3de5647 494 periodicTimer.start();
hudakz 9:a156d3de5647 495
hudakz 11:647d53d146f1 496 enc28j60Eth.init((uint8_t*)mac);
hudakz 9:a156d3de5647 497 uip_seteth_addr(mac);
hudakz 9:a156d3de5647 498
hudakz 9:a156d3de5647 499 uip_init();
hudakz 9:a156d3de5647 500 uip_arp_init();
hudakz 9:a156d3de5647 501 }
hudakz 9:a156d3de5647 502
hudakz 9:a156d3de5647 503 /**
hudakz 9:a156d3de5647 504 * @brief
hudakz 9:a156d3de5647 505 * @note
hudakz 9:a156d3de5647 506 * @param
hudakz 9:a156d3de5647 507 * @retval
hudakz 9:a156d3de5647 508 */
hudakz 9:a156d3de5647 509 //void UIPEthernet::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
hudakz 9:a156d3de5647 510 //{
hudakz 9:a156d3de5647 511 // uip_ipaddr_t ipaddr;
hudakz 9:a156d3de5647 512 // uip_ip_addr(ipaddr, ip);
hudakz 9:a156d3de5647 513 // uip_sethostaddr(ipaddr);
hudakz 9:a156d3de5647 514 // uip_ip_addr(ipaddr, gateway);
hudakz 9:a156d3de5647 515 // uip_setdraddr(ipaddr);
hudakz 9:a156d3de5647 516 // uip_ip_addr(ipaddr, subnet);
hudakz 9:a156d3de5647 517 // uip_setnetmask(ipaddr);
hudakz 9:a156d3de5647 518 // dnsServerAddress = dns;
hudakz 9:a156d3de5647 519 //}
hudakz 9:a156d3de5647 520
hudakz 9:a156d3de5647 521 /**
hudakz 9:a156d3de5647 522 * @brief
hudakz 9:a156d3de5647 523 * @note
hudakz 9:a156d3de5647 524 * @param
hudakz 9:a156d3de5647 525 * @retval
hudakz 9:a156d3de5647 526 */
hudakz 9:a156d3de5647 527 uint16_t UipEthernet::chksum(uint16_t sum, const uint8_t* data, uint16_t len)
hudakz 9:a156d3de5647 528 {
hudakz 9:a156d3de5647 529 uint16_t t;
hudakz 9:a156d3de5647 530 const uint8_t* dataptr;
hudakz 9:a156d3de5647 531 const uint8_t* last_byte;
hudakz 9:a156d3de5647 532
hudakz 9:a156d3de5647 533 dataptr = data;
hudakz 9:a156d3de5647 534 last_byte = data + len - 1;
hudakz 9:a156d3de5647 535
hudakz 9:a156d3de5647 536 while (dataptr < last_byte) {
hudakz 9:a156d3de5647 537 /* At least two more bytes */
hudakz 9:a156d3de5647 538 t = (dataptr[0] << 8) + dataptr[1];
hudakz 9:a156d3de5647 539 sum += t;
hudakz 9:a156d3de5647 540 if (sum < t) {
hudakz 9:a156d3de5647 541 sum++; /* carry */
hudakz 9:a156d3de5647 542 }
hudakz 9:a156d3de5647 543
hudakz 9:a156d3de5647 544 dataptr += 2;
hudakz 9:a156d3de5647 545 }
hudakz 9:a156d3de5647 546
hudakz 9:a156d3de5647 547 if (dataptr == last_byte) {
hudakz 9:a156d3de5647 548 t = (dataptr[0] << 8) + 0;
hudakz 9:a156d3de5647 549 sum += t;
hudakz 9:a156d3de5647 550 if (sum < t) {
hudakz 9:a156d3de5647 551 sum++; /* carry */
hudakz 9:a156d3de5647 552 }
hudakz 9:a156d3de5647 553 }
hudakz 9:a156d3de5647 554
hudakz 9:a156d3de5647 555 /* Return sum in host byte order. */
hudakz 9:a156d3de5647 556 return sum;
hudakz 9:a156d3de5647 557 }
hudakz 9:a156d3de5647 558
hudakz 9:a156d3de5647 559 /**
hudakz 9:a156d3de5647 560 * @brief
hudakz 9:a156d3de5647 561 * @note
hudakz 9:a156d3de5647 562 * @param
hudakz 9:a156d3de5647 563 * @retval
hudakz 9:a156d3de5647 564 */
hudakz 9:a156d3de5647 565 uint16_t UipEthernet::ipchksum()
hudakz 9:a156d3de5647 566 {
hudakz 9:a156d3de5647 567 uint16_t sum;
hudakz 9:a156d3de5647 568
hudakz 9:a156d3de5647 569 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
hudakz 9:a156d3de5647 570 return(sum == 0) ? 0xffff : htons(sum);
hudakz 9:a156d3de5647 571 }
hudakz 9:a156d3de5647 572
hudakz 9:a156d3de5647 573 uint16_t
hudakz 9:a156d3de5647 574 #if UIP_UDP
hudakz 9:a156d3de5647 575 UipEthernet::upper_layer_chksum(uint8_t proto)
hudakz 9:a156d3de5647 576 #else
hudakz 9:a156d3de5647 577 uip_tcpchksum()
hudakz 9:a156d3de5647 578 #endif
hudakz 9:a156d3de5647 579 {
hudakz 9:a156d3de5647 580 uint16_t upper_layer_len;
hudakz 9:a156d3de5647 581 uint16_t sum;
hudakz 9:a156d3de5647 582
hudakz 9:a156d3de5647 583 #if UIP_CONF_IPV6
hudakz 9:a156d3de5647 584 upper_layer_len = (((u16_t) (BUF->len[0]) << 8) + BUF->len[1]);
hudakz 9:a156d3de5647 585 #else /* UIP_CONF_IPV6 */
hudakz 9:a156d3de5647 586 upper_layer_len = (((u16_t) (BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
hudakz 9:a156d3de5647 587 #endif /* UIP_CONF_IPV6 */
hudakz 9:a156d3de5647 588
hudakz 9:a156d3de5647 589 /* First sum pseudoheader. */
hudakz 9:a156d3de5647 590
hudakz 9:a156d3de5647 591 /* IP protocol and length fields. This addition cannot carry. */
hudakz 9:a156d3de5647 592 #if UIP_UDP
hudakz 9:a156d3de5647 593 sum = upper_layer_len + proto;
hudakz 9:a156d3de5647 594 #else
hudakz 9:a156d3de5647 595 sum = upper_layer_len + UIP_PROTO_TCP;
hudakz 9:a156d3de5647 596 #endif
hudakz 9:a156d3de5647 597 /* Sum IP source and destination addresses. */
hudakz 9:a156d3de5647 598
hudakz 9:a156d3de5647 599 sum = UipEthernet::chksum(sum, (u8_t*) &BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
hudakz 9:a156d3de5647 600
hudakz 9:a156d3de5647 601 uint8_t upper_layer_memlen;
hudakz 9:a156d3de5647 602 #if UIP_UDP
hudakz 9:a156d3de5647 603 switch (proto) {
hudakz 9:a156d3de5647 604 // case UIP_PROTO_ICMP:
hudakz 9:a156d3de5647 605 // case UIP_PROTO_ICMP6:
hudakz 9:a156d3de5647 606 // upper_layer_memlen = upper_layer_len;
hudakz 9:a156d3de5647 607 // break;
hudakz 9:a156d3de5647 608 case UIP_PROTO_UDP:
hudakz 9:a156d3de5647 609 upper_layer_memlen = UIP_UDPH_LEN;
hudakz 9:a156d3de5647 610 break;
hudakz 9:a156d3de5647 611
hudakz 9:a156d3de5647 612 default:
hudakz 9:a156d3de5647 613 // case UIP_PROTO_TCP:
hudakz 9:a156d3de5647 614 #endif
hudakz 9:a156d3de5647 615 upper_layer_memlen = (BUF->tcpoffset >> 4) << 2;
hudakz 9:a156d3de5647 616 #if UIP_UDP
hudakz 9:a156d3de5647 617 break;
hudakz 9:a156d3de5647 618 }
hudakz 9:a156d3de5647 619 #endif
hudakz 9:a156d3de5647 620 sum = UipEthernet::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen);
hudakz 9:a156d3de5647 621 #ifdef UIPETHERNET_DEBUG_CHKSUM
hudakz 9:a156d3de5647 622 printf
hudakz 9:a156d3de5647 623 (
hudakz 9:a156d3de5647 624 "chksum uip_buf[%d-%d]: %d\r\n", UIP_IPH_LEN +
hudakz 9:a156d3de5647 625 UIP_LLH_LEN, UIP_IPH_LEN +
hudakz 9:a156d3de5647 626 UIP_LLH_LEN +
hudakz 9:a156d3de5647 627 upper_layer_memlen, htons(sum)
hudakz 9:a156d3de5647 628 );
hudakz 9:a156d3de5647 629 #endif
hudakz 9:a156d3de5647 630 if (upper_layer_memlen < upper_layer_len) {
hudakz 11:647d53d146f1 631 sum = enc28j60Eth.chksum
hudakz 9:a156d3de5647 632 (
hudakz 9:a156d3de5647 633 sum, UipEthernet::uipPacket, UIP_IPH_LEN +
hudakz 9:a156d3de5647 634 UIP_LLH_LEN +
hudakz 9:a156d3de5647 635 upper_layer_memlen, upper_layer_len -
hudakz 9:a156d3de5647 636 upper_layer_memlen
hudakz 9:a156d3de5647 637 );
hudakz 9:a156d3de5647 638 #ifdef UIPETHERNET_DEBUG_CHKSUM
hudakz 9:a156d3de5647 639 printf
hudakz 9:a156d3de5647 640 (
hudakz 15:53715cc81c63 641 "chksum uipPacket(%d)[%d-%d]: %d\r\n", uipPacket, UIP_IPH_LEN +
hudakz 9:a156d3de5647 642 UIP_LLH_LEN +
hudakz 9:a156d3de5647 643 upper_layer_memlen, UIP_IPH_LEN +
hudakz 9:a156d3de5647 644 UIP_LLH_LEN +
hudakz 9:a156d3de5647 645 upper_layer_len, htons(sum)
hudakz 9:a156d3de5647 646 );
hudakz 9:a156d3de5647 647 #endif
hudakz 9:a156d3de5647 648 }
hudakz 9:a156d3de5647 649 return(sum == 0) ? 0xffff : htons(sum);
hudakz 9:a156d3de5647 650 }
hudakz 9:a156d3de5647 651
hudakz 9:a156d3de5647 652 /**
hudakz 9:a156d3de5647 653 * @brief
hudakz 9:a156d3de5647 654 * @note
hudakz 9:a156d3de5647 655 * @param
hudakz 9:a156d3de5647 656 * @retval
hudakz 9:a156d3de5647 657 */
hudakz 9:a156d3de5647 658 uint16_t uip_ipchksum()
hudakz 9:a156d3de5647 659 {
hudakz 9:a156d3de5647 660 return UipEthernet::ethernet->ipchksum();
hudakz 9:a156d3de5647 661 }
hudakz 9:a156d3de5647 662
hudakz 9:a156d3de5647 663 #if UIP_UDP
hudakz 9:a156d3de5647 664
hudakz 9:a156d3de5647 665 /**
hudakz 9:a156d3de5647 666 * @brief
hudakz 9:a156d3de5647 667 * @note
hudakz 9:a156d3de5647 668 * @param
hudakz 9:a156d3de5647 669 * @retval
hudakz 9:a156d3de5647 670 */
hudakz 9:a156d3de5647 671 uint16_t uip_tcpchksum()
hudakz 9:a156d3de5647 672 {
hudakz 9:a156d3de5647 673 uint16_t sum = UipEthernet::ethernet->upper_layer_chksum(UIP_PROTO_TCP);
hudakz 9:a156d3de5647 674
hudakz 9:a156d3de5647 675 return sum;
hudakz 9:a156d3de5647 676 }
hudakz 9:a156d3de5647 677
hudakz 9:a156d3de5647 678 /**
hudakz 9:a156d3de5647 679 * @brief
hudakz 9:a156d3de5647 680 * @note
hudakz 9:a156d3de5647 681 * @param
hudakz 9:a156d3de5647 682 * @retval
hudakz 9:a156d3de5647 683 */
hudakz 9:a156d3de5647 684 uint16_t uip_udpchksum()
hudakz 9:a156d3de5647 685 {
hudakz 9:a156d3de5647 686 uint16_t sum = UipEthernet::ethernet->upper_layer_chksum(UIP_PROTO_UDP);
hudakz 9:a156d3de5647 687
hudakz 9:a156d3de5647 688 return sum;
hudakz 9:a156d3de5647 689 }
hudakz 11:647d53d146f1 690
hudakz 9:a156d3de5647 691 #endif