Skip to content

Commit 3c2f2ac

Browse files
authored
Merge branch 'adafruit:main' into dhcp_error_handling
2 parents 26069ea + 17c9ed8 commit 3c2f2ac

File tree

2 files changed

+189
-48
lines changed

2 files changed

+189
-48
lines changed

adafruit_wiznet5k/adafruit_wiznet5k.py

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def __init__(
187187

188188
# attempt to initialize the module
189189
self._ch_base_msb = 0
190-
assert self._w5100_init() == 1, "Failed to initialize WIZnet module."
190+
assert self._w5xxx_init() == 1, "Failed to initialize WIZnet module."
191191
# Set MAC address
192192
self.mac_address = mac
193193
self.src_port = 0
@@ -449,75 +449,78 @@ def ifconfig(
449449

450450
self._dns = dns_server
451451

452-
def _w5100_init(self) -> int:
452+
def _w5xxx_init(self) -> int:
453453
"""
454454
Detect and initialize a Wiznet5k ethernet module.
455455
456456
:return int: 1 if the initialization succeeds, 0 if it fails.
457457
"""
458+
459+
def _detect_and_reset_w5500() -> bool:
460+
"""
461+
Detect and reset a W5500 chip. Called at startup to initialize the
462+
interface hardware.
463+
464+
:return bool: True if a W5500 chip is detected, False if not.
465+
"""
466+
self._chip_type = "w5500"
467+
# assert self.sw_reset() == 0, "Chip not reset properly!"
468+
self._write_mr(0x08)
469+
# assert self._read_mr()[0] == 0x08, "Expected 0x08."
470+
if self._read_mr()[0] != 0x08:
471+
return False
472+
473+
self._write_mr(0x10)
474+
# assert self._read_mr()[0] == 0x10, "Expected 0x10."
475+
if self._read_mr()[0] != 0x10:
476+
return False
477+
478+
self._write_mr(0x00)
479+
# assert self._read_mr()[0] == 0x00, "Expected 0x00."
480+
if self._read_mr()[0] != 0x00:
481+
return False
482+
483+
if self.read(REG_VERSIONR_W5500, 0x00)[0] != 0x04:
484+
return False
485+
# self._chip_type = "w5500"
486+
# self._ch_base_msb = 0x10
487+
return True
488+
489+
def _detect_and_reset_w5100s() -> bool:
490+
"""
491+
Detect and reset a W5100S chip. Called at startup to initialize the
492+
interface hardware.
493+
494+
:return bool: True if a W5100 chip is detected, False if not.
495+
"""
496+
self._chip_type = "w5100s"
497+
# sw reset
498+
assert self.sw_reset() == 0, "Chip not reset properly!"
499+
if self.read(REG_VERSIONR_W5100S, 0x00)[0] != 0x51:
500+
return False
501+
502+
self._ch_base_msb = 0x0400
503+
return True
504+
458505
time.sleep(1)
459506
self._cs.switch_to_output()
460507
self._cs.value = 1
461508

462509
# Detect if chip is Wiznet W5500
463-
if self.detect_w5500() == 1:
510+
if _detect_and_reset_w5500():
464511
# perform w5500 initialization
465512
for i in range(0, W5200_W5500_MAX_SOCK_NUM):
466513
ctrl_byte = 0x0C + (i << 5)
467514
self.write(0x1E, ctrl_byte, 2)
468515
self.write(0x1F, ctrl_byte, 2)
469516
else:
470517
# Detect if chip is Wiznet W5100S
471-
if self.detect_w5100s() == 1:
518+
if _detect_and_reset_w5100s():
472519
pass
473520
else:
474521
return 0
475522
return 1
476523

477-
def detect_w5500(self) -> int:
478-
"""
479-
Detect W5500 chip.
480-
481-
:return int: 1 if a W5500 chip is detected, -1 if not.
482-
"""
483-
self._chip_type = "w5500"
484-
assert self.sw_reset() == 0, "Chip not reset properly!"
485-
self._write_mr(0x08)
486-
# assert self._read_mr()[0] == 0x08, "Expected 0x08."
487-
if self._read_mr()[0] != 0x08:
488-
return -1
489-
490-
self._write_mr(0x10)
491-
# assert self._read_mr()[0] == 0x10, "Expected 0x10."
492-
if self._read_mr()[0] != 0x10:
493-
return -1
494-
495-
self._write_mr(0x00)
496-
# assert self._read_mr()[0] == 0x00, "Expected 0x00."
497-
if self._read_mr()[0] != 0x00:
498-
return -1
499-
500-
if self.read(REG_VERSIONR_W5500, 0x00)[0] != 0x04:
501-
return -1
502-
# self._chip_type = "w5500"
503-
# self._ch_base_msb = 0x10
504-
return 1
505-
506-
def detect_w5100s(self) -> int:
507-
"""
508-
Detect W5100S chip.
509-
510-
:return int: 1 if a W5100 chip is detected, -1 if not.
511-
"""
512-
self._chip_type = "w5100s"
513-
# sw reset
514-
assert self.sw_reset() == 0, "Chip not reset properly!"
515-
if self.read(REG_VERSIONR_W5100S, 0x00)[0] != 0x51:
516-
return -1
517-
518-
self._ch_base_msb = 0x0400
519-
return 1
520-
521524
def sw_reset(self) -> int:
522525
"""Perform a soft-reset on the Wiznet chip.
523526

examples/wiznet5k_wsgiserver.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# SPDX-FileCopyrightText: 2021 Patrick Van Oosterwijck @ Silicognition LLC
2+
#
3+
# SPDX-License-Identifier: MIT
4+
#
5+
# This demo was tested with the PoE-FeatherWing, which contains a 24AA02E48
6+
# chip to provide a globally unique MAC address, but can also work without
7+
# this chip for testing purposes by using a hard coded MAC.
8+
#
9+
# It also contains a `get_static_file` function that demonstrates how to
10+
# use a generator to serve large static files without using up too much
11+
# memory. To avoid having to put extra files in the repo, it just serves
12+
# `code.py` which isn't very large, but to properly test it, adjust the code
13+
# to serve an image of several 100 kB to see how it works.
14+
#
15+
# There's also an endpoint that demonstrates that `requests` can be used to
16+
# get data from another socket and serve it.
17+
#
18+
19+
import board
20+
import busio
21+
import digitalio
22+
import neopixel
23+
24+
import adafruit_requests as requests
25+
from adafruit_wsgi.wsgi_app import WSGIApp
26+
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
27+
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
28+
import adafruit_wiznet5k.adafruit_wiznet5k_wsgiserver as server
29+
30+
31+
print("Wiznet5k Web Server Test")
32+
33+
34+
def get_mac(i2c_obj):
35+
"Read MAC from 24AA02E48 chip and return it"
36+
mac_addr = bytearray(6)
37+
while not i2c_obj.try_lock():
38+
pass
39+
i2c_obj.writeto(0x50, bytearray((0xFA,)))
40+
i2c_obj.readfrom_into(0x50, mac_addr, start=0, end=6)
41+
i2c_obj.unlock()
42+
return mac_addr
43+
44+
45+
def get_static_file(filename):
46+
"Static file generator"
47+
with open(filename, "rb") as f:
48+
b = None
49+
while b is None or len(b) == 2048:
50+
b = f.read(2048)
51+
yield b
52+
53+
54+
# Status LED
55+
led = neopixel.NeoPixel(board.NEOPIXEL, 1)
56+
led.brightness = 0.3
57+
led[0] = (255, 0, 0)
58+
59+
# Chip Select for PoE-FeatherWing and Adafruit Ethernet FeatherWing
60+
cs = digitalio.DigitalInOut(board.D10)
61+
# Chip Select for Particle Ethernet FeatherWing
62+
# cs = digitalio.DigitalInOut(board.D5)
63+
64+
# Initialize SPI bus
65+
spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
66+
67+
try:
68+
# Initialize the I2C bus to read the MAC
69+
i2c = busio.I2C(board.SCL, board.SDA)
70+
# Read the MAC from the 24AA02E48 chip
71+
mac = get_mac(i2c)
72+
except (RuntimeError, OSError):
73+
# Hard coded MAC if there is no 24AA02E48
74+
mac = b"\xFE\xED\xDE\xAD\xBE\xEF"
75+
76+
# Initialize Ethernet interface with DHCP
77+
eth = WIZNET5K(spi_bus, cs, mac=mac)
78+
79+
# Initialize a requests object with a socket and ethernet interface
80+
requests.set_socket(socket, eth)
81+
82+
83+
# Here we create our application, registering the
84+
# following functions to be called on specific HTTP GET requests routes
85+
86+
web_app = WSGIApp()
87+
88+
89+
@web_app.route("/led/<r>/<g>/<b>")
90+
def led_on(request, r, g, b): # pylint: disable=unused-argument
91+
print("LED handler")
92+
led.fill((int(r), int(g), int(b)))
93+
return ("200 OK", [], ["LED set!"])
94+
95+
96+
@web_app.route("/")
97+
def root(request): # pylint: disable=unused-argument
98+
print("Root WSGI handler")
99+
return ("200 OK", [], ["Root document"])
100+
101+
102+
@web_app.route("/large")
103+
def large(request): # pylint: disable=unused-argument
104+
print("Large pattern handler")
105+
return ("200 OK", [], ["*-.-" * 2000])
106+
107+
108+
@web_app.route("/code")
109+
def code(request): # pylint: disable=unused-argument
110+
print("Static file code.py handler")
111+
return ("200 OK", [], get_static_file("code.py"))
112+
113+
114+
@web_app.route("/btc")
115+
def btc(request): # pylint: disable=unused-argument
116+
print("BTC handler")
117+
r = requests.get("http://api.coindesk.com/v1/bpi/currentprice/USD.json")
118+
result = r.text
119+
r.close()
120+
return ("200 OK", [], [result])
121+
122+
123+
# Here we setup our server, passing in our web_app as the application
124+
server.set_interface(eth)
125+
wsgiServer = server.WSGIServer(80, application=web_app)
126+
127+
print("Open this IP in your browser: ", eth.pretty_ip(eth.ip_address))
128+
129+
# Start the server
130+
wsgiServer.start()
131+
led[0] = (0, 0, 255)
132+
133+
while True:
134+
# Our main loop where we have the server poll for incoming requests
135+
wsgiServer.update_poll()
136+
# Maintain DHCP lease
137+
eth.maintain_dhcp_lease()
138+
# Could do any other background tasks here, like reading sensors

0 commit comments

Comments
 (0)