diff --git a/docs/_static/e32-443t37s-wiring.png b/docs/_static/e32-443t37s-wiring.png
index 62da154..0d67711 100644
Binary files a/docs/_static/e32-443t37s-wiring.png and b/docs/_static/e32-443t37s-wiring.png differ
diff --git a/docs/_static/ebyte-graph-tx-modes.jpg b/docs/_static/ebyte-graph-tx-modes.jpg
new file mode 100644
index 0000000..b783b5b
Binary files /dev/null and b/docs/_static/ebyte-graph-tx-modes.jpg differ
diff --git a/docs/_static/lora-phy-size-limit-mention.png b/docs/_static/lora-phy-size-limit-mention.png
new file mode 100644
index 0000000..d0a2c3f
Binary files /dev/null and b/docs/_static/lora-phy-size-limit-mention.png differ
diff --git a/docs/_static/wiring_blackpill.png b/docs/_static/wiring_blackpill.png
new file mode 100644
index 0000000..9cd9afa
Binary files /dev/null and b/docs/_static/wiring_blackpill.png differ
diff --git a/docs/_static/wiring_esp32s3.png b/docs/_static/wiring_esp32s3.png
new file mode 100644
index 0000000..9f86954
Binary files /dev/null and b/docs/_static/wiring_esp32s3.png differ
diff --git a/docs/conf.py b/docs/conf.py
index 63bacaa..bd357b1 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -40,6 +40,6 @@
html_css_files = ["extra_styles.css"]
# The short X.Y version.
-version = "0.7"
+version = "0.8"
# The full version, including alpha/beta/rc tags.
-release = "0.7.0"
+release = "0.8.0"
diff --git a/docs/examples_error_handling.rst b/docs/examples_error_handling.rst
new file mode 100644
index 0000000..cdfa154
--- /dev/null
+++ b/docs/examples_error_handling.rst
@@ -0,0 +1,35 @@
+Error Handling ⚠️ Must-read ⚠️
+------------------------------
+These examples will show you how to recover from errors returned by the ``E32Device`` class.
+
+Config Changes
+^^^^^^^^^^^^^^
+If you get an ``E32GenericError`` exception when changing the module's config, you will need to follow this procedure.
+
+**Expected error:**
+
+ ``E32GenericError: The module didn't return the new config !``
+
+**Resolution procedure:**
+
+* Catch error in a ``try except`` block.
+
+* Reset the module via ``E32Device.reset()``.
+
+* Wait some time for it to restart.
+
+* Re-apply the config with ``E32Device.update_config()``.
+
+* Go back into the original mode.
+
+* Retry the code that raised the error
+
+**Warning:**
+
+ Failure to follow the procedure WILL result in a module that no longer applies new operating parameters
+ given to it !
+
+.. literalinclude:: ../examples/error_handling.py
+ :caption: examples/error_handling.py
+ :emphasize-lines: 24-45
+ :linenos:
diff --git a/docs/examples_transmit_transparent.rst b/docs/examples_transmit_transparent.rst
index 31a3faa..9cff040 100644
--- a/docs/examples_transmit_transparent.rst
+++ b/docs/examples_transmit_transparent.rst
@@ -16,6 +16,18 @@ due to RF regulations.**
:emphasize-lines: 19,22,26-40
:linenos:
+Monitor
+^^^^^^^
+Monitors channel `4` for messages by using the `0xFFFF` address.
+
+⚠️ **Received messages may be truncated at specific lengths depending on the frequencies and operating parameters used
+due to RF regulations.**
+
+.. literalinclude:: ../examples/transmit_transparent/monitor.py
+ :caption: examples/transmit_transparent/monitor.py
+ :emphasize-lines: 19,22,26-40
+ :linenos:
+
Sender
^^^^^^
Sends a message to any modules on channel `4` with the `0x1337` address.
@@ -27,3 +39,16 @@ due to RF regulations.**
:caption: examples/transmit_transparent/sender.py
:emphasize-lines: 19,22,27,30,35-38
:linenos:
+
+
+Broadcast
+^^^^^^^^^
+Broadcasts a messages to all modules on channel `4` by using the `0xFFFF` address.
+
+⚠️ **Sent messages may be truncated at specific lengths depending on the frequencies and operating parameters used
+due to RF regulations.**
+
+.. literalinclude:: ../examples/transmit_transparent/broadcast.py
+ :caption: examples/transmit_transparent/broadcast.py
+ :emphasize-lines: 19,22,27,30,35-38
+ :linenos:
diff --git a/docs/examples_wiring.rst b/docs/examples_wiring.rst
index 3708758..fc3b090 100644
--- a/docs/examples_wiring.rst
+++ b/docs/examples_wiring.rst
@@ -7,18 +7,22 @@ The pictures in this section will be changed to better ones soon.
ESP32-S3
^^^^^^^^
-TODO
+In this example, the E32-433T20DC module is connected to a ESP32-S3.
-.. image:: _static/wiring_esp32s3_temp.jpg
- :width: 80%
- :alt: Picture of a E32-433T20D connected to an ESP32-S3.
+This MCU serves as an example for MCU's that don't restrict certain functionalities such as UART to specific pins.
+
+The only issue that could be pointed out is the fact it is powered by 3.3V which could cause power dips more easily.
+
+.. image:: _static/wiring_esp32s3.png
+ :width: 90%
+ :alt: Schematic of an E32-433T20D connected to an ESP32-S3.
:align: center
-:raw-html:`[Insert caption here...]`
+:raw-html:`Configuration used in all sender examples.`
STM32 Black Pill
^^^^^^^^^^^^^^^^
-In this example, E32 module is connected to a STM32F411CE Black Pill.
+In this example, the E32-433T20DC module is connected to a STM32F411CE Black Pill.
This MCU requires the some specific pins to be used for the UART bus.
:raw-html:`
`
@@ -38,12 +42,12 @@ The MCU's `USART1` pins are both used out-of-the-box, so we'll need to use the `
| **AUX** | ``board.B7`` | ``PB7`` | Generic I/O | Any input pin |
+---------+--------------+-----------+---------------+------------------+
-.. image:: _static/wiring_blackpill_temp.jpg
- :width: 80%
- :alt: Picture of a E32-433T20D connected to a STM32F411CE Black Pill.
+.. image:: _static/wiring_blackpill.png
+ :width: 90%
+ :alt: Schematic of an E32-433T20D connected to a STM32F411CE Black Pill.
:align: center
-:raw-html:`[Insert caption here...]`
+:raw-html:`Configuration used in all receiver examples.`
Other boards
^^^^^^^^^^^^
diff --git a/docs/index.rst b/docs/index.rst
index dcd9017..6c03533 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -27,6 +27,7 @@ Table of Contents
examples_uart
examples_transmit_fixed
examples_transmit_transparent
+ examples_error_handling
.. toctree::
:maxdepth: 2
diff --git a/docs/introduction.rst b/docs/introduction.rst
index 9151054..a426001 100644
--- a/docs/introduction.rst
+++ b/docs/introduction.rst
@@ -8,7 +8,7 @@
CircuitPython Ebyte E32 Library
===============================
-CircuitPython driver for Ebyte's E32 LoRa modules.
+CircuitPython driver for Ebyte's E32 UART LoRa modules that use the SX1278/SX1276 chipsets.
Legal Preamble
^^^^^^^^^^^^^^
@@ -23,7 +23,6 @@ Features
- Extra support on a per-frequency and per-power basis:
- More descriptive constants for TX power.
- - Channel <-> frequency converters.
- Maximum packet size calculators. (TODO)
- Entirely optional via separate modules.
@@ -44,9 +43,9 @@ Limitations
- All LoRa packets are glued back-to-back when received.
- **No LoraWAN support**
-- Missing extra support for some modules:
+- Missing support for some modules:
- - Modules with `170`, `400`, `868`, `900`, and `915` prefix. *(Will improve overtime)*
+ - Modules with ``170``, ``400`` and ``900`` prefix. *(Will improve overtime)*
Dependencies
^^^^^^^^^^^^
diff --git a/docs/technical_details_e32.rst b/docs/technical_details_e32.rst
index 702f659..2dd41e4 100644
--- a/docs/technical_details_e32.rst
+++ b/docs/technical_details_e32.rst
@@ -178,6 +178,25 @@ The ``E32-433T27D`` variant is mentioned in the `E32 V1.30 User Manual
and on its `product page `_
but no proper datasheet could be found for it.
+Transmission Modes
+^^^^^^^^^^^^^^^^^^
+The E32 modules support 2 modes of communication named `"Transparent"` and `"Fixed"`.
+
+The main characteristic of `"Fixed"` mode is that it requires you to prepend you message with a target
+address and channel.
+
+And for `"Transparent"` mode, you can broadcast as well as monitor.
+
+Please note that Ebyte's infographic shown below doesn't state that modules in `"Transparent"` modes needs
+to be set on the same channel and address, but you absolutely need to.
+
+.. image:: _static/ebyte-graph-tx-modes.jpg
+ :width: 80%
+ :alt: Ebyte E32 modules transmissions modes infographic
+ :align: center
+
+:raw-html:`E32 Transmission modes. Credit: Ebyte's official store on aliexpress.com`
+
Datasheets
^^^^^^^^^^
All datasheets are hosted by Ebyte on *ebyte.com* and *cdebyte.com* unless specified otherwise.
diff --git a/docs/technical_details_lora.rst b/docs/technical_details_lora.rst
index d1c7c69..fa75e61 100644
--- a/docs/technical_details_lora.rst
+++ b/docs/technical_details_lora.rst
@@ -1,7 +1,77 @@
-LoRa (TODO)
------------
-TODO
+.. role:: raw-html(raw)
+ :format: html
-Spreading Factor
-^^^^^^^^^^^^^^^^
-TODO
+LoRa
+----
+LoRa is a RF modulation technology engineered to be quite resilient to allow long-distance communications with a
+relatively low power-consumption.
+
+It is also referred to as `LoRa PHY`.
+
+Max Message Length
+^^^^^^^^^^^^^^^^^^
+⚠️ **Do not confuse with LoRaWAN limits** ⚠️
+
+Due to some legal limitations regarding the maximum RF air-time that can be used by LoRa, there is a limit to how
+long each packet can be.
+
+If given more data than what should be transmitted in a single packet, the E32 modules will segment that data
+and transfer it as individual packets.
+
+This automatic segmentation can be a problem in fixed transmissions since it completely erase the target address and
+channel from any subsequent packet.
+
+This limit can be **somewhat** ignored when using transparent communications since the message doesn't
+contain the target address and channel, but steps should be taken to not rely on this behaviour.
+
+Official limits
+"""""""""""""""
+I couldn't find any concrete limits for packet size on LoRa PHY.
+
+All I know is that is depends on a maximum air-time limit enforced by local RF laws which is defined by the
+air data rate and some other parameters.
+
+As of now, you should try different sizes at your desired operating settings in fixed mode to find that limit.
+
+Here is an excerpt from the `"LoraWAN Regional Parameters RP002-1.0.4"` document:
+
+.. image:: _static/lora-phy-size-limit-mention.png
+ :width: 80%
+ :alt: Mention of PHY restrictions influencing LoRaWAN max packet size.
+ :align: center
+
+:raw-html:`Mention of PHY restrictions finfluencing LoRaWAN max packet size.`
+
+Observed limits
+"""""""""""""""
+TODO: Check if it depends on the spread factor or just operating parameters and region.
+
+If you can, please contribute to these tables by raising an issue.
+
+Documentation
+"""""""""""""
+
+* `LoRaWAN Packet Size Considerations (By The Things Network) `_
+
+Spreading Factor (SF)
+^^^^^^^^^^^^^^^^^^^^^
+The spreading factor is a mechanism that influence the air data rate, time-on-air and the receiver's sensitivity.
+:raw-html:`
`
+It can be one of 6 values between ``SF7`` and ``SF12``.
+
+I can't for the life of me give you a clear and concise explanation or table of these values and their effect
+as well as the operating parameters that would be appropriate for them.
+:raw-html:`
`
+**Absolutely nobody who should be able to** can make a document that is concise, complete and
+doesn't expect the reader to glue bits and pieces from 20+ different documents to get a complete view that
+doesn't only cover part of these SF values because of some arcane reasons.
+
+Here are some links to documentation I'd recommend on the subject:
+
+* `Spreading Factors (By The Things Network) `_
+
+* `Spreading Factor (By iotjourney.orange.com) `_
+
+* `LoRa SF explained (By blog.ttulka.com) `_
+
+Good luck.
diff --git a/docs/technical_details_lorawan.rst b/docs/technical_details_lorawan.rst
index f60aa5a..11d8116 100644
--- a/docs/technical_details_lorawan.rst
+++ b/docs/technical_details_lorawan.rst
@@ -3,6 +3,10 @@
LoRaWAN
-------
+⚠️ **LoRaWAN isn't supported by this project !** ⚠️
+
+Technical details
+^^^^^^^^^^^^^^^^^
This section will only contain some basic information about some of LoRaWAN's mechanisms.
We strongly recommend you consult the documentation provided by `The Things Network` and `LoRa Alliance`
diff --git a/docs/technical_details_preamble.rst b/docs/technical_details_preamble.rst
index 43cd2f5..01d4976 100644
--- a/docs/technical_details_preamble.rst
+++ b/docs/technical_details_preamble.rst
@@ -27,6 +27,8 @@ If you need a simple example to motivate you into ready this section, read the f
Depending on the frequencies, region and data rates, **a LoRa packet cannot be larger than 11 bytes** under
unfavorable conditions, **or 250 bytes** under favorable ones.
+You can go to ??? for more information on this limitation.
+
.. _ref-legal-aside:
Legal Aside
diff --git a/ebyte_e32/__init__.py b/ebyte_e32/__init__.py
index a3041db..c88d6c9 100644
--- a/ebyte_e32/__init__.py
+++ b/ebyte_e32/__init__.py
@@ -296,22 +296,9 @@ class E32Device:
"""
_m0: DigitalInOut
- """M0 pin used to set the module's mode."""
-
_m1: DigitalInOut
- """M1 pin used to set the module's mode."""
-
_aux: Optional[DigitalInOut]
- """
- AUX pin used by the module to indicate its working status or to wake up the MCU.
-
- May be left floating and ignored during normal operations.
- """
-
_uart: UART
- """
- UART connection to the E32 module.
- """
_uart_pin_tx: Pin
_uart_pin_rx: Pin
@@ -424,7 +411,7 @@ def flush_uart(self):
"""
self._uart.reset_input_buffer()
- def wait_aux(self, max_wait_ms: int = 150):
+ def wait_aux(self, max_wait_ms: int = 250):
"""
Wait for the `AUX` pin to go high meaning that the module is ready for communications.
diff --git a/ebyte_e32/__version__.py b/ebyte_e32/__version__.py
index a8378e8..8487d20 100644
--- a/ebyte_e32/__version__.py
+++ b/ebyte_e32/__version__.py
@@ -6,6 +6,6 @@
"""
MAJOR = 0
-MINOR = 7
+MINOR = 8
PATCH = 0
VERSION = f"{MAJOR}.{MINOR}.{PATCH}"
diff --git a/examples/error_handling.py b/examples/error_handling.py
new file mode 100644
index 0000000..d2620ad
--- /dev/null
+++ b/examples/error_handling.py
@@ -0,0 +1,56 @@
+# SPDX-FileCopyrightText: 2023 Herwin Bozet
+#
+# SPDX-License-Identifier: Unlicense
+
+import board
+import time
+
+import ebyte_e32
+import ebyte_e32.exceptions
+
+PIN_M0 = board.B3
+PIN_M1 = board.B4
+PIN_RXD = board.A2 # Pin marked as RX on the module
+PIN_TXD = board.A3 # Pin marked as TX on the module
+PIN_AUX = board.B7
+
+e32 = ebyte_e32.E32Device(PIN_M0, PIN_M1, PIN_AUX, PIN_TXD, PIN_RXD, address=0x1337, channel=0)
+
+# We'll be iterating over each channel
+channel = 0
+while True:
+ print(f"Moving to channel {channel}")
+
+ try:
+ # Can cause errors if the module fails to respond to config request when validating it.
+ e32.channel = channel
+ e32.wait_aux()
+ except ebyte_e32.exceptions.E32GenericError:
+ print("Failed to change !")
+
+ # We reset it and wait more than what AUX indicates.
+ e32.reset(True)
+ time.sleep(2)
+
+ # We re-apply the `E32Device` class' config
+ e32.update_config()
+ e32.wait_aux()
+
+ # Going back to the appropriate mode
+ e32.mode = ebyte_e32.Modes.MODE_NORMAL
+ e32.wait_aux()
+
+ # Retrying to change channels and send the message.
+ time.sleep(1)
+ continue
+
+ e32.send(b'Hello World !')
+ e32.wait_aux()
+
+ time.sleep(2.5)
+
+ channel = channel + 1
+ if channel > ebyte_e32.CHANNEL_MAX:
+ channel = ebyte_e32.CHANNEL_MIN
+
+ time.sleep(2.5)
diff --git a/examples/transmit_transparent/broadcast.py b/examples/transmit_transparent/broadcast.py
new file mode 100644
index 0000000..57b14ce
--- /dev/null
+++ b/examples/transmit_transparent/broadcast.py
@@ -0,0 +1,41 @@
+# SPDX-FileCopyrightText: 2023 Herwin Bozet
+#
+# SPDX-License-Identifier: Unlicense
+
+import board
+import time
+
+import ebyte_e32
+
+PIN_M0 = board.IO13
+PIN_M1 = board.IO12
+PIN_RXD = board.IO11 # Pin marked as RX on the module
+PIN_TXD = board.IO10 # Pin marked as TX on the module
+PIN_AUX = board.IO9
+
+e32 = ebyte_e32.E32Device(PIN_M0, PIN_M1, PIN_AUX, PIN_TXD, PIN_RXD, address=0xFFFF, channel=4)
+
+# Switching to transparent transmission mode.
+e32.tx_mode = ebyte_e32.TransmissionMode.TRANSMISSION_TRANSPARENT
+
+# Switching to mode 0. (Normal mode)
+e32.mode = ebyte_e32.Modes.MODE_NORMAL
+
+# Message content:
+# * Message: b'Hello World !'
+# The target channel is the same as the module's.
+message = b'Hello World !'
+
+# Sending with helper
+e32.send(message)
+
+time.sleep(0.5) # Waiting to prevent RF spamming
+
+# Switching to an empty channel and sending another message.
+e32.channel = 5
+message = b'You shouldn\'t receive this !'
+e32.send(message)
+e32.wait_aux()
+
+# The message may be truncated at specific lengths depending on the frequencies used.
+# Please check the documentation for more information !
diff --git a/examples/transmit_transparent/monitor.py b/examples/transmit_transparent/monitor.py
new file mode 100644
index 0000000..fb8276f
--- /dev/null
+++ b/examples/transmit_transparent/monitor.py
@@ -0,0 +1,44 @@
+# SPDX-FileCopyrightText: 2023 Herwin Bozet
+#
+# SPDX-License-Identifier: Unlicense
+
+import board
+import time
+
+import ebyte_e32
+
+PIN_M0 = board.B3
+PIN_M1 = board.B4
+PIN_RXD = board.A2 # Pin marked as RX on the module
+PIN_TXD = board.A3 # Pin marked as TX on the module
+PIN_AUX = board.B7
+
+e32 = ebyte_e32.E32Device(PIN_M0, PIN_M1, PIN_AUX, PIN_TXD, PIN_RXD, address=0xFFFF, channel=4)
+
+# Switching to transparent transmission mode. (Default)
+e32.tx_mode = ebyte_e32.TransmissionMode.TRANSMISSION_TRANSPARENT
+
+# Switching to mode 0. (Normal mode)
+e32.mode = ebyte_e32.Modes.MODE_NORMAL
+
+print(f"Monitoring messages on channel {e32.channel} ...")
+
+while True:
+ # Checking if the module sent us some data
+ if e32.in_buffer > 0:
+ # Wait for the module to finish receiving data
+ e32.wait_aux()
+
+ # We grab the data, and can process it here
+ data = e32.read()
+
+ # We print it and exit
+ print(f"We received a {len(data)} byte(s) long message:")
+ print(data)
+
+ # If nothing was received, we wait.
+ time.sleep(0.1)
+
+print()
+print("Now exiting...")
+e32.deinit()
diff --git a/examples/transmit_transparent/receiver.py b/examples/transmit_transparent/receiver.py
index cf4d46b..a5ba2a7 100644
--- a/examples/transmit_transparent/receiver.py
+++ b/examples/transmit_transparent/receiver.py
@@ -21,7 +21,7 @@
# Switching to mode 0. (Normal mode)
e32.mode = ebyte_e32.Modes.MODE_NORMAL
-print(f"Waiting for messages... on channel {e32.channel} between devices with the 0x{e32.address:x} address ...")
+print(f"Waiting for messages on channel {e32.channel} between devices with the 0x{e32.address:x} address ...")
while True:
# Checking if the module sent us some data
diff --git a/examples/transmit_transparent/sender.py b/examples/transmit_transparent/sender.py
index 014b845..6914831 100644
--- a/examples/transmit_transparent/sender.py
+++ b/examples/transmit_transparent/sender.py
@@ -15,7 +15,7 @@
e32 = ebyte_e32.E32Device(PIN_M0, PIN_M1, PIN_AUX, PIN_TXD, PIN_RXD, address=0x1337, channel=4)
-# Switching to fixed transmission mode.
+# Switching to transparent transmission mode.
e32.tx_mode = ebyte_e32.TransmissionMode.TRANSMISSION_TRANSPARENT
# Switching to mode 0. (Normal mode)
diff --git a/readme.md b/readme.md
index 8cd5690..8ad93e7 100644
--- a/readme.md
+++ b/readme.md
@@ -1,11 +1,10 @@
# CircuitPython Ebyte E32 Library
-CircuitPython driver for Ebyte's E32 UART LoRa modules.
+CircuitPython driver for Ebyte's E32 UART LoRa modules that use the SX1278/SX1276 chipsets.
## Features
* Supports all standard E32 UART modules.
* Extra support on a per-frequency and per-power basis:
* More descriptive constants for TX power.
- * Channel <-> frequency converters.
* ~~Maximum packet size calculators~~. (TODO)
* Entirely optional via separate modules.
* Minified versions for devices with tiny storage space:
@@ -67,6 +66,7 @@ The same error may be raised when you change any operating setting.
## Links
### Resources
+* [xreef's E32 driver for Arduino](https://github.com/xreef/LoRa_E32_Series_Library)
* [Effevee's E32 driver for MicroPython](https://github.com/effevee/loraE32/)
* [LoRa and LoRaWAN quick overview (By SemTech)](https://lora-developers.semtech.com/documentation/tech-papers-and-guides/lora-and-lorawan)
* [LoRa frequency plan by country (By The Things Network)](https://www.thethingsnetwork.org/docs/lorawan/frequencies-by-country/)