diff --git a/README.rst b/README.rst index b8e9368..ab42fc8 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,10 @@ Introduction :target: https://travis-ci.com/adafruit/Adafruit_CircuitPython_ESP32SPI :alt: Build Status -CircuitPython driver library for using ESP32 as WiFi co-processor using SPI +CircuitPython driver library for using ESP32 as WiFi co-processor using SPI. +The companion firmware `is available on GitHub +`_. Please be sure to check the example code for +any specific firmware version dependencies that may exist. Dependencies diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py index 76e6cc8..fe0af99 100644 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -82,6 +82,10 @@ _SEND_DATA_TCP_CMD = const(0x44) _GET_DATABUF_TCP_CMD = const(0x45) +_SET_ENT_IDENT_CMD = const(0x4A) +_SET_ENT_UNAME_CMD = const(0x4B) +_SET_ENT_PASSWD_CMD = const(0x4C) +_SET_ENT_ENABLE_CMD = const(0x4F) _START_CMD = const(0xE0) _END_CMD = const(0xEE) @@ -376,6 +380,30 @@ def wifi_set_passphrase(self, ssid, passphrase): if resp[0][0] != 1: raise RuntimeError("Failed to set passphrase") + def wifi_set_entidentity(self, ident): + """Sets the WPA2 Enterprise anonymous identity""" + resp = self._send_command_get_response(_SET_ENT_IDENT_CMD, [ident]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise anonymous identity") + + def wifi_set_entusername(self, username): + """Sets the desired WPA2 Enterprise username""" + resp = self._send_command_get_response(_SET_ENT_UNAME_CMD, [username]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise username") + + def wifi_set_entpassword(self, password): + """Sets the desired WPA2 Enterprise password""" + resp = self._send_command_get_response(_SET_ENT_PASSWD_CMD, [password]) + if resp[0][0] != 1: + raise RuntimeError("Failed to set enterprise password") + + def wifi_set_entenable(self): + """Enables WPA2 Enterprise mode""" + resp = self._send_command_get_response(_SET_ENT_ENABLE_CMD) + if resp[0][0] != 1: + raise RuntimeError("Failed to enable enterprise mode") + @property def ssid(self): """The name of the access point we're connected to""" diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py new file mode 100644 index 0000000..d8d2a14 --- /dev/null +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -0,0 +1,90 @@ +# Example code implementing WPA2 Enterprise mode +# +# This code requires firmware version 1.3.0, or newer, running +# on the ESP32 WiFi co-processor. The latest firmware, and wiring +# info if you are using something other than a PyPortal, can be found +# in the Adafruit Learning System: +# https://learn.adafruit.com/adding-a-wifi-co-processor-to-circuitpython-esp8266-esp32/firmware-files#esp32-only-spi-firmware-3-8 + +import re +import time +import board +import busio +from digitalio import DigitalInOut + +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_esp32spi.adafruit_esp32spi_requests as requests + +# Version number comparison code. Credit to gnud on stackoverflow +# (https://stackoverflow.com/a/1714190), swapping out cmp() to +# support Python 3.x and thus, CircuitPython +def version_compare(version1, version2): + def normalize(v): + return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")] + return (normalize(version1) > normalize(version2)) - (normalize(version1) < normalize(version2)) + +print("ESP32 SPI WPA2 Enterprise test") + +# For running on the PyPortal, use this block +esp32_cs = DigitalInOut(board.ESP_CS) +esp32_ready = DigitalInOut(board.ESP_BUSY) +esp32_reset = DigitalInOut(board.ESP_RESET) + +# For a board that doesn't have the ESP pin definitions, use this block and +# set the pins as needed. +#esp32_cs = DigitalInOut(board.D8) +#esp32_ready = DigitalInOut(board.D5) +#esp32_reset = DigitalInOut(board.D7) + +spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) + +requests.set_interface(esp) + +if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: + print("ESP32 found and in idle mode") + +# Get the ESP32 fw version number, remove trailing byte off the returned bytearray +# and then convert it to a string for prettier printing and later comparison +firmware_version = ''.join([chr(b) for b in esp.firmware_version[:-1]]) +print("Firmware vers.", firmware_version) + +print("MAC addr:", [hex(i) for i in esp.MAC_address]) + +# WPA2 Enterprise support was added in fw ver 1.3.0. Check that the ESP32 +# is running at least that version, otherwise, bail out +assert version_compare(firmware_version, "1.3.0") >= 0, ( + "Incorrect ESP32 firmware version; >= 1.3.0 required.") + +# Set up the SSID you would like to connect to +# Note that we need to call wifi_set_network prior +# to calling wifi_set_enable. +esp.wifi_set_network(b'YOUR_SSID_HERE') + +# If your WPA2 Enterprise network requires an anonymous +# identity to be set, you may set that here +esp.wifi_set_entidentity(b'') + +# Set the WPA2 Enterprise username you'd like to use +esp.wifi_set_entusername(b'MY_USERNAME') + +# Set the WPA2 Enterprise password you'd like to use +esp.wifi_set_entpassword(b'MY_PASSWORD') + +# Once the network settings have been configured, +# we need to enable WPA2 Enterprise mode on the ESP32 +esp.wifi_set_entenable() + +# Wait for the network to come up +print("Connecting to AP...") +while not esp.is_connected: + print(".", end = "") + time.sleep(2) + +print("") +print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi) +print("My IP address is", esp.pretty_ip(esp.ip_address)) +print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) +print("Ping google.com: %d ms" % esp.ping("google.com")) + +print("Done!")