diff --git a/README.md b/README.md
index 33a39a1..0ec9afa 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,12 @@ The transmitter is based on a power MOSFET found in handheld VHF radios and outp
The unit runs on 12V and exposes a 3.3V UART for connecting to the rest of the boat's system. The UART continuously sends GPS and AIS data in NMEA0183 format at 38.4Kbps. The breakout boxes pictured above deliver this stream via USB, NME0183 (RS422) or NMEA 2000 (CAN). All 3 breakouts feature **galvanic isolation** of their USB connection to avoid causing unintended problems with laptops and other devices whose power supplies are meant to "float".
+In addition, there is now a "bare bones" UART breakout:
+
+
+
+This provides the simplest, lowest cost interface to a Raspberry Pi (assuming the UART is available).
+
For the circuit to transmit, it must be configured with persistent station data (MMSI, call sign, name, dimensions, etc). This is stored in MCU flash and is provisioned over a USB/serial connection via a command line interface. If station data is not provisioned, the device will simply run as a 2 channel receiver.
The unit implements SOTDMA synchronization based on the very acurate 1 PPS signal from the GNSS and the UTC clock. It does not synchronize itself to other stations because practical experience has shown that it's literally the "wild west" out there. There are many commercial class A systems in operation today with really crappy time slot management, so it's best not to rely on any of them. MAIANA™ behaves as a class B though, so it will not attempt to reserve time slots. It will just transmit autonomously and independently, based on Clear Channel Assessment, at the schedule permitted for class B devices.
diff --git a/images/uart_breakout.jpg b/images/uart_breakout.jpg
new file mode 100644
index 0000000..fec1d1b
Binary files /dev/null and b/images/uart_breakout.jpg differ
diff --git a/latest/CAD/Board-11.3/transponder-11.3.0-Schematic.pdf b/latest/CAD/Board-11.3/transponder-11.3.0-Schematic.pdf
new file mode 100644
index 0000000..8a3129f
Binary files /dev/null and b/latest/CAD/Board-11.3/transponder-11.3.0-Schematic.pdf differ
diff --git a/latest/CAD/Board-11.3/transponder-11.3.0-gerbers.zip b/latest/CAD/Board-11.3/transponder-11.3.0-gerbers.zip
new file mode 100644
index 0000000..c74eac5
Binary files /dev/null and b/latest/CAD/Board-11.3/transponder-11.3.0-gerbers.zip differ
diff --git a/latest/CAD/Board-11.3/transponder-11.3.0.brd b/latest/CAD/Board-11.3/transponder-11.3.0.brd
new file mode 100644
index 0000000..e1aec6d
--- /dev/null
+++ b/latest/CAD/Board-11.3/transponder-11.3.0.brd
@@ -0,0 +1,3218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+©2015-2021
+P. Antypas
+JLCJLCJLCJLC
+
+
+
+
+MAIANA™
+
+Rev 11.3.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+<b>SMA Antenna Connector</b><p>
+This is a footprint for an edge mount RF antenna. Works pretty well with SMA type connectors but may also work with other edge mount RF connectors. Keep in mind, these edge mount connectors assume you are using a 0.062" PCB thickness.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+<b>Johanson Technology, Inc.</b> Filters<p>
+www.johansontechnology.com<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Test Pins/Pads</b><p>
+Cream on SMD OFF.<br>
+new: Attribute TP_SIGNAL_NAME<br>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Small Signal Transistors</b><p>
+Packages from :<br>
+www.infineon.com; <br>
+www.semiconductors.com;<br>
+www.irf.com<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+SOD323 Package
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>EAGLE Design Rules</b>
+<p>
+Die Standard-Design-Rules sind so gewählt, dass sie für
+die meisten Anwendungen passen. Sollte ihre Platine
+besondere Anforderungen haben, treffen Sie die erforderlichen
+Einstellungen hier und speichern die Design Rules unter
+einem neuen Namen ab.
+<b>EAGLE Design Rules</b>
+<p>
+The default Design Rules have been set to cover
+a wide range of applications. Your particular design
+may have different requirements, so please make the
+necessary adjustments and save your customized
+design rules under a new name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+
+
+
diff --git a/latest/CAD/Board-11.3/transponder-11.3.0.sch b/latest/CAD/Board-11.3/transponder-11.3.0.sch
new file mode 100644
index 0000000..f8418e7
--- /dev/null
+++ b/latest/CAD/Board-11.3/transponder-11.3.0.sch
@@ -0,0 +1,6049 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+D
+S
+G
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dual N-Channel MOSFET
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8 CHANNEL LOW CAPACITANCE TVS DIODE ARRAY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Common Anode Zener Diode, 3.6V
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Frames for Sheet and Layout</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>DRAWING_NAME
+>LAST_DATE_TIME
+>SHEET
+Sheet:
+
+
+
+
+
+<b>FRAME</b><p>
+DIN A4, landscape with location and doc. field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Supply Symbols</b><p>
+GND, VCC, 0V, +5V, -5V, etc.<p>
+Please keep in mind, that these devices are necessary for the
+automatic wiring of the supply signals.<p>
+The pin name defined in the symbol is identical to the net which is to be wired automatically.<p>
+In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MMIC Wideband Amplifier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Johanson Technology, Inc.</b> Filters<p>
+www.johansontechnology.com<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+SMD Ceramic GNSS Antenna
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+<b>SMA Antenna Connector</b><p>
+This is a footprint for an edge mount RF antenna. Works pretty well with SMA type connectors but may also work with other edge mount RF connectors. Keep in mind, these edge mount connectors assume you are using a 0.062" PCB thickness.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+Header for OS4000-T
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place.
+You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line).
+This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace"
+to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers.
+Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also,
+if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment
+will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+No outline in silkscreen
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+>Name
+>Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>Name
+>Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+>Name
+>Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Org
+Blu
+Brn
+W/Grn
+Grn
+
+
+
+
+<b>SMA Antenna Connector</b>
+End launch SMA connector. The paste layer has been removed so that the connector can be hand soldered onto the board after reflow.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Header 5</b>
+Standard 5-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08230 with associated crimp pins and housings.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>RJ45 Jack</b>
+Simple RJ45, 8-pin connection - connector for common Cat5, Cat5e, and Cat6 Ethernet cables. Footprint not yet proven in production. Connector sku is PRT-00643; Breakout PCB sku is BOB-00716.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+Gnd
+
+
+
+
+
+
+
+
+Classic 4-pin 3.2 x 2.5mm crystal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Test Pins/Pads</b><p>
+Cream on SMD OFF.<br>
+new: Attribute TP_SIGNAL_NAME<br>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>TEST PAD</b>
+
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+
+
+
+
+
+
+
+
+
+
+>NAME
+>TP_SIGNAL_NAME
+
+
+
+
+
+<b>Test pad</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+Standard SMD inductor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Standard SMD capacitor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Standard SMD resistor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+Miniature tactile switch, 4-lead SMD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+1A Adjustable LDO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Signal Transistors</b><p>
+Packages from :<br>
+www.infineon.com; <br>
+www.semiconductors.com;<br>
+www.irf.com<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+<b>P-CHANNEL MOS FET</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+GPS Module
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+SOD123 Package
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+SOD323 Package
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+SMA Package
+
+
+
+
+
+
+
+>NAME
+
+
+
+SMB package
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+Bidirectional TVS diode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Standard SMD Schottky diode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+SPDT RF Switch, CMOS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+1KB I2C EEPROM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Connections & Power
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+V_PA is set to 8V
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MCU & EEPROM
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+The MCU can be any of L412/L422/L431/L432.
+This connector will accommodate either SEGGER or
+STLINK adapters that need a reference voltage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+EEPROM
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+LNA & Bandpass
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+This 3-pole Chebyshev has a measured insertion loss of only 2.6dB in the passband.
+It is sharp enough to bring FM radio and aviation aids (~200MHz)
+near or below the AIS band, but not selective enough to decimate VHF television
+between 174 and 180MHz.
+If this becomes an issue a notch filter will need to be inserted after the amplifier.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RF Backend
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+The design uses a Class E configuration for 162MHz.
+Practical testing proved that it yields adequate power
+to drive the PA stage.
+
+Any of these ICs will work here:
+Si4463
+Si4460
+Si4467
+
+Firmware sets the TX power level differently for each.
+For RX, both IC inputs are configured as single-ended with no matching network.
+Practical field testing suggests there is no need for one.
+
+Any of these ICs can work here: Si4460, Si4467, Si4362, Si4463.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RF Power Amplifier
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+This power amplifier adds almost 20dB of gain for a total
+conducted output power of +33dBm.
+
+It is based on the reference designs in the datasheet, but
+includes a narrowband input matching network to reduce BOM
+and a very steep Chebyshev low pass filter to deal with a
+pesky 2nd harmonic that falls in the restricted aviation band (324MHz).
+
+The MOSFET drain is always powered, but the gate bias voltage
+is turned on via R11, R12, C11 and L17. The RC delay is essential for suppressing
+spurious emissions during ramp up and ramp down.
+
+This MOSFET is at End Of Life. NXP recommends the AFT05MS004N
+as a replacement, but it's not a drop-in; it will need different
+matching networks, biasing and input power.
+
+Last time buy for this MOSFET is end of 2021 and there is ample supply,
+so there is no rush to design it out.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+GPS
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Antenna Switch
+MAIANA™ AIS Transponder
+Copyright © 2015-2020 Peter Antypas
+Licensed under GPLv3
+This switch does not need DC blocking caps.
+
+RFSW_CTRL must be low during RX.
+
+The 9 test pads here form a footprint for a
+coaxial pogo pin probe in the test jig.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+
+
+
diff --git a/latest/CAD/UARTBreakout/UARTBreakout-2.0-Gerbers.zip b/latest/CAD/UARTBreakout/UARTBreakout-2.0-Gerbers.zip
new file mode 100644
index 0000000..1378750
Binary files /dev/null and b/latest/CAD/UARTBreakout/UARTBreakout-2.0-Gerbers.zip differ
diff --git a/latest/CAD/UARTBreakout/UARTBreakout-2.0-Schematic.pdf b/latest/CAD/UARTBreakout/UARTBreakout-2.0-Schematic.pdf
new file mode 100644
index 0000000..a550ba7
Binary files /dev/null and b/latest/CAD/UARTBreakout/UARTBreakout-2.0-Schematic.pdf differ
diff --git a/latest/CAD/UARTBreakout/UARTBreakout-2.0.brd b/latest/CAD/UARTBreakout/UARTBreakout-2.0.brd
new file mode 100644
index 0000000..fe70160
--- /dev/null
+++ b/latest/CAD/UARTBreakout/UARTBreakout-2.0.brd
@@ -0,0 +1,774 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MAIANA(TM)
+UART Breakout v2.0
+(c)2021 P.Antypas
+
+
+RX_LED
+GPS_LED
+UART_RX
+UART_TX
+TX_OFF
+9-18V
+TX_LED
+GND
+GND
+3.3V
+GND
+GND
+3.3V
+3.3V
+3.3V
+
+
+GND
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+SOD123 Package
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+chip
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Microchip PIC Microcontrollers and other Devices</b><p>
+Based on the following sources :
+<ul>
+<li>Microchip Data Book, 1993
+<li>THE EMERGING WORLD STANDARD, 1995/1996
+<li>Microchip, Technical Library CD-ROM, June 1998
+<li>www.microchip.com
+</ul>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>SMALL OUTLINE TRANSISTOR</b><p>
+reflow soldering
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>EAGLE Design Rules</b>
+<p>
+Die Standard-Design-Rules sind so gewählt, dass sie für
+die meisten Anwendungen passen. Sollte ihre Platine
+besondere Anforderungen haben, treffen Sie die erforderlichen
+Einstellungen hier und speichern die Design Rules unter
+einem neuen Namen ab.
+<b>EAGLE Design Rules</b>
+<p>
+The default Design Rules have been set to cover
+a wide range of applications. Your particular design
+may have different requirements, so please make the
+necessary adjustments and save your customized
+design rules under a new name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+
+
+
diff --git a/latest/CAD/UARTBreakout/UARTBreakout-2.0.sch b/latest/CAD/UARTBreakout/UARTBreakout-2.0.sch
new file mode 100644
index 0000000..0adaa81
--- /dev/null
+++ b/latest/CAD/UARTBreakout/UARTBreakout-2.0.sch
@@ -0,0 +1,2051 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Frames for Sheet and Layout</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>DRAWING_NAME
+>LAST_DATE_TIME
+>SHEET
+Sheet:
+
+
+
+
+
+<b>FRAME</b><p>
+DIN A4, landscape with location and doc. field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Supply Symbols</b><p>
+GND, VCC, 0V, +5V, -5V, etc.<p>
+Please keep in mind, that these devices are necessary for the
+automatic wiring of the supply signals.<p>
+The pin name defined in the symbol is identical to the net which is to be wired automatically.<p>
+In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+SMA Package
+
+
+
+
+
+
+
+>NAME
+
+
+
+SMB package
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+SOD123 Package
+
+
+
+
+
+
+
+
+>NAME
+
+
+
+SOD323 Package
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+Bidirectional TVS diode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Standard SMD Schottky diode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Multilayer SMD
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+<b>RESISTOR</b><p>
+chip
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+PTC fuses, resettable thermistors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h3>SparkFun Electronics' preferred foot prints</h3>
+In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br>
+We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
+<br><br>
+<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
+<br><br>
+You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+JST crimp connector: 1mm pitch, top entry
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>Name
+>Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Org
+Blu
+Brn
+W/Grn
+Grn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+<b>RJ45 Jack</b>
+Simple RJ45, 8-pin connection - connector for common Cat5, Cat5e, and Cat6 Ethernet cables. Footprint not yet proven in production. Connector sku is PRT-00643; Breakout PCB sku is BOB-00716.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Header 8</b>
+Standard 8-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+Standard SMD capacitor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Microchip PIC Microcontrollers and other Devices</b><p>
+Based on the following sources :
+<ul>
+<li>Microchip Data Book, 1993
+<li>THE EMERGING WORLD STANDARD, 1995/1996
+<li>Microchip, Technical Library CD-ROM, June 1998
+<li>www.microchip.com
+</ul>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>SMALL OUTLINE TRANSISTOR</b><p>
+reflow soldering
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+80mA High Voltage Automotive LDO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MAIANA™ AIS Transponder
+Copyright © 2015-2021 Peter Antypas
+Licensed under GPLv3
+Basic Breakout
+Battery input w/ ESD and
+reverse polarity protection.
+
+(Working voltage range: 9-18V)
+
+RJ45 connector from exterior unit
+External pin headers
+TRANSPONDER_UART_TX: 3.3V UART output from transponder board
+TRANSPONDER_UART_RX: 3.3V UART input into transponder board
+RX_LED: Open drain output, pulled low for 20ms during packet RX
+TX_LED: Open drain output, pulled low to indicate TX enabled, toggled during TX event
+GPS_LED: Open drain output, pulled low when GNSS has valid position fix
+TX_OFF: Input. Drive with 3.3V or higher to disable TX. Leave floating if not needed.
+
+A 3.3V/80mA rail is made available for LEDs,
+a TX_DISABLE signal or other optional components.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+
+
+
diff --git a/latest/Firmware/Transponder/Inc/ConfigFlags.h b/latest/Firmware/Transponder/Inc/ConfigFlags.h
new file mode 100644
index 0000000..864e803
--- /dev/null
+++ b/latest/Firmware/Transponder/Inc/ConfigFlags.h
@@ -0,0 +1,26 @@
+/*
+ * ConfigFlags.h
+ *
+ * Created on: Oct 11, 2021
+ * Author: peter
+ */
+
+#ifndef INC_CONFIGFLAGS_H_
+#define INC_CONFIGFLAGS_H_
+
+typedef struct
+{
+ uint32_t magic;
+ uint32_t reserved;
+ uint32_t flags[5];
+} ConfigFlags;
+
+typedef union
+{
+ ConfigFlags config;
+ uint64_t dw[4];
+} ConfigPage;
+
+
+
+#endif /* INC_CONFIGFLAGS_H_ */
diff --git a/latest/Firmware/Transponder/Inc/Configuration.hpp b/latest/Firmware/Transponder/Inc/Configuration.hpp
index c76de47..9ccdf5d 100644
--- a/latest/Firmware/Transponder/Inc/Configuration.hpp
+++ b/latest/Firmware/Transponder/Inc/Configuration.hpp
@@ -22,13 +22,9 @@
#include "StationData.h"
#include "OTPData.h"
+#include "config.h"
+#include "ConfigFlags.h"
-// This should be plenty big (no need to be a whole flash page though)
-typedef union
-{
- StationData station;
- uint64_t dw[128];
-} ConfigPage;
class Configuration
@@ -46,11 +42,27 @@ public:
void reportOTPData();
const OTPData *readOTP();
bool writeOTP(const OTPData &data);
+ void reportSystemData();
+ void enableTX();
+ void disableTX();
+ bool isTXEnabled();
+
private:
+
Configuration();
- bool erasePage();
- bool writePage();
+ //bool eraseStationDataPage();
+ //bool writeStationDataPage();
+ //bool eraseConfigFlags();
+
+ //bool readConfigFlags();
+ //bool writeConfigFlags();
+ //bool erasePage(uint32_t address);
+
uint32_t nextAvailableOTPSlot();
+ const char *hwRev();
+ const char *serNum();
+private:
+ ConfigFlags mFlags = {0};
};
#endif /* CONFIGURATION_HPP_ */
diff --git a/latest/Firmware/Transponder/Inc/GPS.hpp b/latest/Firmware/Transponder/Inc/GPS.hpp
index ea86bf6..8aa2886 100644
--- a/latest/Firmware/Transponder/Inc/GPS.hpp
+++ b/latest/Firmware/Transponder/Inc/GPS.hpp
@@ -44,6 +44,7 @@ public:
void init();
void enable();
void disable();
+ bool isEnabled();
void onRX(char c);
void onPPS();
void startTimer();
diff --git a/latest/Firmware/Transponder/Inc/TXErrors.h b/latest/Firmware/Transponder/Inc/TXErrors.h
new file mode 100644
index 0000000..7cdd891
--- /dev/null
+++ b/latest/Firmware/Transponder/Inc/TXErrors.h
@@ -0,0 +1,21 @@
+/*
+ * TXErrors.h
+ *
+ * Created on: Sep 18, 2021
+ * Author: peter
+ */
+
+#ifndef INC_TXERRORS_H_
+#define INC_TXERRORS_H_
+
+typedef enum
+{
+ TX_NO_ERROR = 0,
+ TX_ALLOC_ERROR,
+ TX_QUEUE_FULL,
+ TX_PACKET_TOO_OLD,
+} TXErrorCode;
+
+
+
+#endif /* INC_TXERRORS_H_ */
diff --git a/latest/Firmware/Transponder/Inc/TXPowerSettings.h b/latest/Firmware/Transponder/Inc/TXPowerSettings.h
index 2227b63..7b79c0f 100644
--- a/latest/Firmware/Transponder/Inc/TXPowerSettings.h
+++ b/latest/Firmware/Transponder/Inc/TXPowerSettings.h
@@ -31,12 +31,5 @@ typedef struct {
}
pa_params;
-#if 0
-static const pa_params POWER_TABLE[] = {
- {0x4467, 0x48, 0x20, 0x00},
- {0x4460, 0x48, 0x20, 0x00},
- {0x4463, 0x48, 0x12, 0x00}
-};
-#endif
#endif /* TXPOWERSETTINGS_H_ */
diff --git a/latest/Firmware/Transponder/Inc/TXScheduler.hpp b/latest/Firmware/Transponder/Inc/TXScheduler.hpp
index c685cd7..86dc3c4 100644
--- a/latest/Firmware/Transponder/Inc/TXScheduler.hpp
+++ b/latest/Firmware/Transponder/Inc/TXScheduler.hpp
@@ -25,11 +25,13 @@ public:
void startTXTesting();
void queueMessage18(VHFChannel channel);
void queueMessage24(VHFChannel channel);
+ void reportTXStatus();
bool isTXAllowed();
private:
TXScheduler ();
virtual ~TXScheduler ();
time_t positionReportTimeInterval();
+ void sendNMEASentence(const char *sentence);
private:
VHFChannel mPositionReportChannel;
VHFChannel mStaticDataChannel;
diff --git a/latest/Firmware/Transponder/Inc/bsp/bsp.hpp b/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
index 1543d58..467be38 100644
--- a/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
+++ b/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
@@ -22,13 +22,14 @@
#include
#include "config.h"
-
+#include "StationData.h"
+#include "ConfigFlags.h"
// See the bottom section for the proper BOARD_REV symbol format and either modify this header
// or define a different symbol in the preprocessor to build for a different board
#ifndef BOARD_REV
-#define BOARD_REV 110
+#define BOARD_REV 113
#endif
/**
@@ -48,7 +49,8 @@ void bsp_enter_dfu();
void bsp_gnss_on();
void bsp_gnss_off();
bool bsp_is_tx_disabled();
-
+bool bsp_is_tx_hardwired();
+bool bsp_is_gnss_on();
void bsp_rx_led_on();
void bsp_rx_led_off();
void bsp_tx_led_on();
@@ -56,6 +58,20 @@ void bsp_tx_led_off();
void bsp_gps_led_on();
void bsp_gps_led_off();
+/**
+ * Station data persistence related
+ */
+void bsp_read_station_data(StationData *data);
+void bsp_write_station_data(const StationData &data);
+void bsp_erase_station_data();
+bool bsp_is_station_data_provisioned();
+
+/**
+ * Configuration flag persistence
+ */
+void bsp_read_config_flags(ConfigFlags *flags);
+void bsp_write_config_flags(const ConfigFlags &flags);
+void bsp_erase_config_flags();
// Callback for processing UART input (interrupt)
typedef void(*char_input_cb)(char c);
@@ -84,6 +100,9 @@ void bsp_set_sotdma_timer_value(uint32_t v);
uint8_t bsp_tx_spi_byte(uint8_t b);
+
+extern const char *BSP_HW_REV;
+
// BSP headers go here
#if BOARD_REV == 93
@@ -96,6 +115,8 @@ uint8_t bsp_tx_spi_byte(uint8_t b);
#include
#elif BOARD_REV == 110
#include
+#elif BOARD_REV == 113
+#include
#endif
diff --git a/latest/Firmware/Transponder/Inc/bsp/bsp_11_3.hpp b/latest/Firmware/Transponder/Inc/bsp/bsp_11_3.hpp
new file mode 100644
index 0000000..5b60afe
--- /dev/null
+++ b/latest/Firmware/Transponder/Inc/bsp/bsp_11_3.hpp
@@ -0,0 +1,97 @@
+/*
+ Copyright (c) 2016-2020 Peter Antypas
+
+ This file is part of the MAIANA™ transponder firmware.
+
+ The firmware is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+*/
+
+#ifndef INC_BSP_10_7_HPP_
+#define INC_BSP_10_7_HPP_
+
+
+
+// GPIO Pin definitions
+#define GNSS_EN_PORT GPIOC
+#define GNSS_EN_PIN GPIO_PIN_14
+
+#define TRX_IC_CLK_PORT GPIOC
+#define TRX_IC_CLK_PIN GPIO_PIN_15
+
+#define CS2_PORT GPIOA
+#define CS2_PIN GPIO_PIN_0
+
+#define RX_EVT_PORT GPIOA
+#define RX_EVT_PIN GPIO_PIN_1
+
+#define GNSS_1PPS_PORT GPIOA
+#define GNSS_1PPS_PIN GPIO_PIN_2
+
+#define GNSS_NMEA_RX_PORT GPIOA
+#define GNSS_NMEA_RX_PIN GPIO_PIN_3
+
+#define CS1_PORT GPIOA
+#define CS1_PIN GPIO_PIN_4
+
+#define SCK_PORT GPIOA
+#define SCK_PIN GPIO_PIN_5
+
+#define MISO_PORT GPIOA
+#define MISO_PIN GPIO_PIN_6
+
+#define MOSI_PORT GPIOA
+#define MOSI_PIN GPIO_PIN_7
+
+#define SDN1_PORT GPIOB
+#define SDN1_PIN GPIO_PIN_0
+
+#define TRX_IC_DATA_PORT GPIOB
+#define TRX_IC_DATA_PIN GPIO_PIN_1
+
+#define PA_BIAS_PORT GPIOA
+#define PA_BIAS_PIN GPIO_PIN_8
+
+#define UART_TX_PORT GPIOA
+#define UART_TX_PIN GPIO_PIN_9
+
+#define UART_RX_PORT GPIOA
+#define UART_RX_PIN GPIO_PIN_10
+
+#define GNSS_STATE_PORT GPIOA
+#define GNSS_STATE_PIN GPIO_PIN_11
+
+#define TX_DISABLE_PORT GPIOA
+#define TX_DISABLE_PIN GPIO_PIN_12
+
+#define SDN2_PORT GPIOA
+#define SDN2_PIN GPIO_PIN_15
+
+#define RX_IC_CLK_PORT GPIOB
+#define RX_IC_CLK_PIN GPIO_PIN_3
+
+#define RX_IC_DATA_PORT GPIOB
+#define RX_IC_DATA_PIN GPIO_PIN_4
+
+#define TX_EVT_PORT GPIOB
+#define TX_EVT_PIN GPIO_PIN_5
+
+#define I2C_SCL_PORT GPIOB
+#define I2C_SCL_PIN GPIO_PIN_6
+
+#define I2C_SDA_PORT GPIOB
+#define I2C_SDA_PIN GPIO_PIN_7
+
+
+
+#endif /* INC_BSP_5_0_HPP_ */
diff --git a/latest/Firmware/Transponder/Inc/config.h b/latest/Firmware/Transponder/Inc/config.h
index 218ebce..ef94bdb 100644
--- a/latest/Firmware/Transponder/Inc/config.h
+++ b/latest/Firmware/Transponder/Inc/config.h
@@ -25,8 +25,8 @@
#include "TXPowerSettings.h"
-// Set to non-zero to enable transmission support
-#define ENABLE_TX 1
+#define FW_REV "3.3.0"
+
/*
* Defining this symbol forces all output (NMEA + debug) to a high-speed USART for tunneling to an application that demuxes it.
@@ -54,6 +54,8 @@
// Maximum allowed backlog in TX queue
#define MAX_TX_PACKETS_IN_QUEUE 4
+// Set to true to emit proprietary NMEA sentences for debugging TX scheduling. Not useful in production.
+#define REPORT_TX_SCHEDULING 0
// Set to true to force RSSI sampling at every SOTDMA timer slot on both channels
#define FULL_RSSI_SAMPLING 1
@@ -72,7 +74,7 @@
#define MIN_MSG_18_TX_INTERVAL 30
#define MAX_MSG_18_TX_INTERVAL 180
-// Default interval for message 24 A&B (static data report)
+// Default interval for message 24 A&B (static data report) = 6 minutes
#define MSG_24_TX_INTERVAL 360
// The spec calls for Class B transmitters to listen for the first 20 bits of each frame before transmitting.
@@ -86,9 +88,21 @@
#define DFU_FLAG_MAGIC 0xa191feed
#define CLI_FLAG_MAGIC 0x209a388d
-#define CONFIGURATION_ADDRESS 0x0800F800
+#define CONFIGURATION_FLAG_ADDRESS 0x0800F000
+#define OTP_DATA 1
+#define ENABLE_WDT 1
+/**
+ * This is a bit of a pain, but in the legacy breakout boards the TX LED
+ * was manipulated by both a hardware switch and the GPIO, so the MCU logic is reversed.
+ *
+ * The only way to support those legacy boards is to build a separate binary
+ * with this switch predefined as 1. There is no automated way to detect which kind of breakout MAIANA has.
+ */
+#ifndef LEGACY_BREAKOUTS
+#define LEGACY_BREAKOUTS 1
+#endif
/**
* This is a bit of a pain, but in the legacy breakout boards the TX LED
diff --git a/latest/Firmware/Transponder/Python/bootloader.py b/latest/Firmware/Transponder/Python/bootloader.py
index e53ad4d..9e944f4 100644
--- a/latest/Firmware/Transponder/Python/bootloader.py
+++ b/latest/Firmware/Transponder/Python/bootloader.py
@@ -131,7 +131,14 @@ def send_data(packet):
def send_get():
- if not send_command(GET):
+ success = False
+ for i in range(2):
+ if send_command(GET):
+ success = True
+ break
+ time.sleep(.2)
+
+ if not success:
print "Failed to send command GET"
return (False, [])
@@ -224,7 +231,7 @@ def boot(address):
return True
-
+"""
def enter_dfu(portname):
p = serial.Serial(portname, 38400, timeout=2, parity=serial.PARITY_NONE, stopbits=1)
if not p.is_open:
@@ -235,7 +242,8 @@ def enter_dfu(portname):
s = p.readline()
p.close()
return len(s) == 0
-
+"""
+
if __name__ == '__main__':
if len(sys.argv) < 4:
print "Usage: {0} port image address".format(sys.argv[0])
diff --git a/latest/Firmware/Transponder/STM32L4xx_FLASH.ld b/latest/Firmware/Transponder/STM32L4xx_FLASH.ld
index 14ea4f2..391e32e 100644
--- a/latest/Firmware/Transponder/STM32L4xx_FLASH.ld
+++ b/latest/Firmware/Transponder/STM32L4xx_FLASH.ld
@@ -154,7 +154,7 @@ SECTIONS
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
-
+ *(.code_in_ram) /* code executing from RAM */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
diff --git a/latest/Firmware/Transponder/Src/CommandProcessor.cpp b/latest/Firmware/Transponder/Src/CommandProcessor.cpp
index 4ce613d..f0357a6 100644
--- a/latest/Firmware/Transponder/Src/CommandProcessor.cpp
+++ b/latest/Firmware/Transponder/Src/CommandProcessor.cpp
@@ -124,6 +124,10 @@ void CommandProcessor::processCommand(const char *buff)
{
Configuration::instance().reportStationData();
}
+ else if ( s.find("sys?") == 0 )
+ {
+ Configuration::instance().reportSystemData();
+ }
else if ( s.find("dfu") == 0 )
{
jumpToBootloader();
@@ -137,6 +141,20 @@ void CommandProcessor::processCommand(const char *buff)
{
fireTestPacket();
}
+ else if ( s.find("tx on") == 0 )
+ {
+ Configuration::instance().enableTX();
+ TXScheduler::instance().reportTXStatus();
+ }
+ else if ( s.find("tx off") == 0 )
+ {
+ Configuration::instance().disableTX();
+ TXScheduler::instance().reportTXStatus();
+ }
+ else if ( s.find("tx?") == 0 )
+ {
+ TXScheduler::instance().reportTXStatus();
+ }
else if (s.find("reboot") == 0 )
{
bsp_reboot();
@@ -157,6 +175,7 @@ void CommandProcessor::processCommand(const char *buff)
{
TXScheduler::instance().queueMessage24(CH_87);
}
+#if OTP_DATA
else if ( s.find("otp?") == 0 )
{
dumpOTPData();
@@ -165,6 +184,7 @@ void CommandProcessor::processCommand(const char *buff)
{
writeOTPData(s);
}
+#endif
}
void CommandProcessor::enterCLIMode()
@@ -178,6 +198,7 @@ void CommandProcessor::jumpToBootloader()
bsp_enter_dfu();
}
+#if OTP_DATA
void CommandProcessor::dumpOTPData()
{
Configuration::instance().reportOTPData();
@@ -191,18 +212,21 @@ void CommandProcessor::writeOTPData(const std::string &s)
vector tokens;
Utils::tokenize(params, ' ', tokens);
- if ( tokens.size() < 2 )
+ if ( tokens.size() < 1 )
return;
OTPData data;
+ memset(&data, 0, sizeof data);
+
data.magic = OTP_MAGIC;
data.rev = OTP_REV;
- strlcpy(data.serialnum, tokens[0].c_str(), sizeof data.serialnum);
- strlcpy(data.hwrev, tokens[1].c_str(), sizeof data.hwrev);
+ strlcpy(data.hwrev, tokens[0].c_str(), sizeof data.hwrev);
+ if ( tokens.size() > 1 )
+ strlcpy(data.serialnum, tokens[1].c_str(), sizeof data.serialnum);
bool result = Configuration::instance().writeOTP(data);
if ( result )
dumpOTPData();
}
-
+#endif
diff --git a/latest/Firmware/Transponder/Src/Configuration.cpp b/latest/Firmware/Transponder/Src/Configuration.cpp
index a095e63..5bc352e 100644
--- a/latest/Firmware/Transponder/Src/Configuration.cpp
+++ b/latest/Firmware/Transponder/Src/Configuration.cpp
@@ -23,10 +23,14 @@
#include "config.h"
#include "EventQueue.hpp"
#include
+#include
+
// These are not defined in ANY CMSIS or HAL header, WTF ST???
-#define OTP_ADDRESS 0x1FFF7000
-#define OTP_SIZE 0x00000400
+#define OTP_ADDRESS 0x1FFF7000
+#define OTP_SIZE 0x00000400
+
+#define CONFIG_FLAGS_MAGIC 0x2092ED2C
#if 0
static StationData __THIS_STATION__ = {
@@ -42,7 +46,7 @@ static StationData __THIS_STATION__ = {
};
#endif
-static ConfigPage __page;
+//static StationDataPage __page;
Configuration &Configuration::instance()
{
@@ -60,9 +64,65 @@ void Configuration::init()
bool cliBootMode = *(uint32_t*)BOOTMODE_ADDRESS == CLI_FLAG_MAGIC;
if ( !cliBootMode )
{
- reportOTPData();
+ reportSystemData();
reportStationData();
}
+
+ bsp_read_config_flags(&mFlags);
+}
+
+void Configuration::enableTX()
+{
+ // For now, the only flag in use is a TX switch bit which is set to 0
+ mFlags = {CONFIG_FLAGS_MAGIC, 0, {0}};
+ bsp_write_config_flags(mFlags);
+}
+
+void Configuration::disableTX()
+{
+ // For now, the only flag in use is a TX switch bit which is set to 1
+ mFlags = {CONFIG_FLAGS_MAGIC, 0, {0}};
+ mFlags.flags[0] = 0x01;
+ bsp_write_config_flags(mFlags);
+}
+
+bool Configuration::isTXEnabled()
+{
+ if ( mFlags.magic != CONFIG_FLAGS_MAGIC )
+ return true;
+
+ // Bit 0 in word 0 inhibits transmission
+ return (mFlags.flags[0] & 0x01) == 0;
+}
+
+const char *Configuration::hwRev()
+{
+ const OTPData *otp = readOTP();
+ if ( otp )
+ return otp->hwrev;
+ else
+ return BSP_HW_REV;
+}
+
+const char *Configuration::serNum()
+{
+ const OTPData *otp = readOTP();
+ if ( otp )
+ return otp->serialnum;
+ else
+ return "";
+}
+
+void Configuration::reportSystemData()
+{
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
+
+ sprintf(e->nmeaBuffer.sentence, "$PAISYS,%s,%s,%s*", hwRev(), FW_REV, serNum());
+
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
}
void Configuration::reportStationData()
@@ -72,6 +132,9 @@ void Configuration::reportStationData()
memset(&d, 0, sizeof d);
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
+
sprintf(e->nmeaBuffer.sentence,
"$PAISTN,%lu,%s,%s,%d,%d,%d,%d,%d*",
d.mmsi,
@@ -89,101 +152,54 @@ void Configuration::reportStationData()
bool Configuration::isStationDataProvisioned()
{
- StationData d;
- return readStationData(d);
+ return bsp_is_station_data_provisioned();
}
+#if OTP_DATA
void Configuration::reportOTPData()
{
const OTPData *data = readOTP();
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
- if ( data == nullptr )
+ if ( data )
{
- strcpy(e->nmeaBuffer.sentence, "$PAISYS,,*");
+ sprintf(e->nmeaBuffer.sentence, "$PAIOTP,%s,%s*", data->serialnum, data->hwrev);
}
else
{
- sprintf(e->nmeaBuffer.sentence, "$PAISYS,%s,%s*", data->serialnum, data->hwrev);
+ strcpy(e->nmeaBuffer.sentence, "$PAIOTP,,*");
}
-
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
+
}
-
-bool Configuration::erasePage()
-{
- uint32_t page = (CONFIGURATION_ADDRESS - FLASH_BASE) / FLASH_PAGE_SIZE;
-
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
- HAL_FLASH_Unlock();
-
- FLASH_EraseInitTypeDef erase;
- erase.TypeErase = FLASH_TYPEERASE_PAGES;
- erase.Banks = FLASH_BANK_1;
- erase.Page = page;
- erase.NbPages = 1;
-
- uint32_t errPage;
- HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &errPage);
- if ( status != HAL_OK )
- {
- HAL_FLASH_Lock();
- return false;
- }
-
- HAL_FLASH_Lock();
- return true;
-}
+#endif
void Configuration::resetToDefaults()
{
- if ( erasePage() )
- reportStationData();
+ bsp_erase_station_data();
+ reportStationData();
+ mFlags = {0};
+ bsp_erase_config_flags();
}
bool Configuration::writeStationData(const StationData &data)
{
- if ( !erasePage() )
- return false;
-
- memcpy(&__page.station, &data, sizeof data);
- if ( erasePage() )
- {
- bool success = writePage();
- reportStationData();
- return success;
- }
- else
- {
- return false;
- }
-}
-
-bool Configuration::writePage()
-{
- uint32_t pageAddress = CONFIGURATION_ADDRESS;
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
- HAL_FLASH_Unlock();
- HAL_StatusTypeDef status = HAL_OK;
- for ( uint32_t dw = 0; dw < sizeof __page/8; ++dw )
- {
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, pageAddress + dw*8, __page.dw[dw]);
- if ( status != HAL_OK )
- break;
- }
- HAL_FLASH_Lock();
-
- return status == HAL_OK;
+ bsp_write_station_data(data);
+ reportStationData();
+ return true;
}
bool Configuration::readStationData(StationData &data)
{
- memcpy(&__page, (const void*)CONFIGURATION_ADDRESS, sizeof __page);
- memcpy(&data, &__page.station, sizeof data);
+ bsp_read_station_data(&data);
return data.magic == STATION_DATA_MAGIC;
}
+
+#if OTP_DATA
const OTPData *Configuration::readOTP()
{
uint32_t address = nextAvailableOTPSlot();
@@ -231,6 +247,7 @@ uint32_t Configuration::nextAvailableOTPSlot()
return OTP_ADDRESS+OTP_SIZE;
}
+#endif
diff --git a/latest/Firmware/Transponder/Src/GPS.cpp b/latest/Firmware/Transponder/Src/GPS.cpp
index fb5f9d6..693be4f 100644
--- a/latest/Firmware/Transponder/Src/GPS.cpp
+++ b/latest/Firmware/Transponder/Src/GPS.cpp
@@ -101,6 +101,11 @@ void GPS::disable()
bsp_gps_led_off();
}
+bool GPS::isEnabled()
+{
+ return bsp_is_gnss_on();
+}
+
void GPS::onRX(char c)
{
// This code is called in interrupt mode, do as little as possible!
diff --git a/latest/Firmware/Transponder/Src/LEDManager.cpp b/latest/Firmware/Transponder/Src/LEDManager.cpp
index 80480aa..be2d9ef 100644
--- a/latest/Firmware/Transponder/Src/LEDManager.cpp
+++ b/latest/Firmware/Transponder/Src/LEDManager.cpp
@@ -41,6 +41,11 @@ void tickCB()
void LEDManager::init()
{
+ if ( TXScheduler::instance().isTXAllowed() )
+ bsp_tx_led_on();
+ else
+ bsp_tx_led_off();
+
bsp_set_tick_callback(tickCB);
}
@@ -54,13 +59,14 @@ void LEDManager::onTick()
bsp_rx_led_off();
}
- if ( count2++ == 250 )
+
+ if ( count2++ == 200 )
{
count2 = 1;
- if ( !TXScheduler::instance().isTXAllowed() )
- bsp_tx_led_off();
- else
+ if ( TXScheduler::instance().isTXAllowed() )
bsp_tx_led_on();
+ else
+ bsp_tx_led_off();
}
}
diff --git a/latest/Firmware/Transponder/Src/RadioManager.cpp b/latest/Firmware/Transponder/Src/RadioManager.cpp
index ccc7cb3..2e863ce 100644
--- a/latest/Firmware/Transponder/Src/RadioManager.cpp
+++ b/latest/Firmware/Transponder/Src/RadioManager.cpp
@@ -21,7 +21,7 @@
#include "RadioManager.hpp"
#include "NoiseFloorDetector.hpp"
#include "bsp.hpp"
-
+#include "TXErrors.h"
void rxClockCB();
void trxClockCB();
@@ -39,7 +39,6 @@ RadioManager::RadioManager()
mTransceiverIC = NULL;
mReceiverIC = NULL;
mInitializing = true;
- //mTXQueue = new CircularQueue(4);
mUTC = 0;
EventQueue::instance().addObserver(this, CLOCK_EVENT);
}
@@ -52,14 +51,12 @@ bool RadioManager::initialized()
void RadioManager::init()
{
NoiseFloorDetector::instance();
- //DBG("Initializing RF IC 1\r\n");
mTransceiverIC = new Transceiver(SDN1_PORT, SDN1_PIN,
CS1_PORT, CS1_PIN,
TRX_IC_DATA_PORT, TRX_IC_DATA_PIN,
TRX_IC_CLK_PORT, TRX_IC_CLK_PIN, 0);
mTransceiverIC->init();
- //DBG("Initializing RF IC 2\r\n");
mReceiverIC = new Receiver(SDN2_PORT, SDN2_PIN,
CS2_PORT, CS2_PIN,
RX_IC_DATA_PORT, RX_IC_DATA_PIN,
@@ -67,7 +64,6 @@ void RadioManager::init()
mReceiverIC->init();
mInitializing = false;
- //DBG("Radio ICs initialized\r\n");
}
void RadioManager::transmitCW(VHFChannel channel)
@@ -77,7 +73,6 @@ void RadioManager::transmitCW(VHFChannel channel)
void RadioManager::start()
{
- //DBG("Radio Manager starting\r\n");
configureInterrupts();
if ( mTransceiverIC )
mTransceiverIC->startReceiving(CH_87, true);
@@ -86,7 +81,6 @@ void RadioManager::start()
mReceiverIC->startReceiving(CH_88, true);
GPS::instance().setDelegate(this);
- //DBG("Radio Manager started\r\n");
}
void RadioManager::stop()
@@ -122,14 +116,11 @@ void RadioManager::processEvent(const Event &e)
// Do we need to swap channels?
if ( txChannel != mTransceiverIC->channel() )
{
- //DBG("RadioManager swapping channels for ICs\r\n");
// The receiver needs to be explicitly told to switch channels
if ( mReceiverIC )
mReceiverIC->switchToChannel(alternateChannel(txChannel));
}
- //DBG("RadioManager assigned TX packet\r\n");
-
// The transceiver will switch channel if the packet channel is different
mTransceiverIC->assignTXPacket(packet);
}
@@ -174,15 +165,32 @@ void RadioManager::timeSlotStarted(uint32_t slotNumber)
void RadioManager::scheduleTransmission(TXPacket *packet)
{
- if ( mTXQueue.push(packet) )
+#if REPORT_TX_SCHEDULING
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+#endif
+ if ( !mTXQueue.push(packet) )
{
- //DBG("RadioManager queued TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel()));
- }
- else
- {
- //DBG("RadioManager rejected TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel()));
+#if REPORT_TX_SCHEDULING
+ if ( e )
+ {
+ sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", packet->messageType(), TX_QUEUE_FULL);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
+ }
+#endif
TXPacketPool::instance().deleteTXPacket(packet);
}
+#if REPORT_TX_SCHEDULING
+ else
+ {
+ if ( e )
+ {
+ sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", packet->messageType(), TX_NO_ERROR);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
+ }
+ }
+#endif
}
void RadioManager::sendTestPacketNow(TXPacket *packet)
diff --git a/latest/Firmware/Transponder/Src/TXScheduler.cpp b/latest/Firmware/Transponder/Src/TXScheduler.cpp
index ab06042..27fa91b 100644
--- a/latest/Firmware/Transponder/Src/TXScheduler.cpp
+++ b/latest/Firmware/Transponder/Src/TXScheduler.cpp
@@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see
-*/
+ */
#include "TXScheduler.hpp"
@@ -29,6 +29,7 @@
#include
#include "RadioManager.hpp"
#include "ChannelManager.hpp"
+#include "TXErrors.h"
#include "printf_serial.h"
#include "bsp.hpp"
@@ -53,20 +54,44 @@ TXScheduler::TXScheduler ()
void TXScheduler::init()
{
- if ( Configuration::instance().readStationData(mStationData) )
- {
- DBG("Successfully loaded Station Data \r\n");
- }
- else
- {
- DBG("Failed to read Station Data !!!\r\n");
- }
+ bool cliBootMode = *(uint32_t*)BOOTMODE_ADDRESS == CLI_FLAG_MAGIC;
+ if ( !cliBootMode )
+ reportTXStatus();
}
TXScheduler::~TXScheduler ()
{
}
+void TXScheduler::reportTXStatus()
+{
+ bool hwSwitchOff = bsp_is_tx_disabled();
+ bool softSwitch = Configuration::instance().isTXEnabled();
+ bool hasStation = Configuration::instance().isStationDataProvisioned();
+
+ bool status = hwSwitchOff ? false : (softSwitch && hasStation);
+
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
+
+ sprintf(e->nmeaBuffer.sentence, "$PAITXCFG,%d,%d,%d,%d,%d*", bsp_is_tx_hardwired(), !hwSwitchOff, softSwitch, hasStation, status);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
+}
+
+bool TXScheduler::isTXAllowed()
+{
+ bool hwSwitchOff = bsp_is_tx_disabled();
+ if ( hwSwitchOff )
+ return false;
+
+ bool softSwitch = Configuration::instance().isTXEnabled();
+ bool hasStation = Configuration::instance().isStationDataProvisioned();
+
+ return softSwitch && hasStation;
+}
+
void TXScheduler::processEvent(const Event &e)
{
switch(e.type)
@@ -84,10 +109,9 @@ void TXScheduler::processEvent(const Event &e)
if ( !RadioManager::instance().initialized() || mUTC == 0 )
return;
- if ( bsp_is_tx_disabled() )
+ if ( !isTXAllowed() )
return;
-
// Using a moving average of SOG to determine transmission rate
static float alpha = 0.2;
mAvgSpeed = mAvgSpeed * (1.0 - alpha) + mLastGPSFix.speed * alpha;
@@ -122,7 +146,6 @@ void TXScheduler::processEvent(const Event &e)
mUTC = e.clock.utc;
- //DBG("Clock Event\r\n");
break;
}
@@ -140,27 +163,36 @@ void TXScheduler::processEvent(const Event &e)
}
-/**
- * This method may be called in EITHER thread OR interrupt context,
- * so we keep it very lean ...
- */
-
-bool TXScheduler::isTXAllowed()
+void TXScheduler::sendNMEASentence(const char *sentence)
{
- return (mStationData.magic == STATION_DATA_MAGIC) && !bsp_is_tx_disabled();
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
+
+ strlcpy(e->nmeaBuffer.sentence, sentence, sizeof e->nmeaBuffer.sentence);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
}
void TXScheduler::queueMessage18(VHFChannel channel)
{
+#if REPORT_TX_SCHEDULING
+ char sentence[48];
+#endif
+
// If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC )
return;
TXPacket *p1 = TXPacketPool::instance().newTXPacket(channel);
- if ( !p1 ) {
- //DBG("Unable to allocate TX packet for message 18, will try again later\r\n");
+ if ( !p1 )
+ {
+#if REPORT_TX_SCHEDULING
+ sprintf(sentence, "$PAISCHTX,18,%d*", TX_ALLOC_ERROR);
+ sendNMEASentence(sentence);
+#endif
return;
- }
+ }
AISMessage18 msg;
msg.latitude = mLastGPSFix.lat;
@@ -175,15 +207,23 @@ void TXScheduler::queueMessage18(VHFChannel channel)
void TXScheduler::queueMessage24(VHFChannel channel)
{
+#if REPORT_TX_SCHEDULING
+ char sentence[48];
+#endif
+
// If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC )
return;
TXPacket *p2 = TXPacketPool::instance().newTXPacket(channel);
- if ( !p2 ) {
- //DBG("Unable to allocate TX packet for 24A\r\n");
+ if ( !p2 )
+ {
+#if REPORT_TX_SCHEDULING
+ sprintf(sentence, "$PAISCHTX,24A,%d*", TX_ALLOC_ERROR);
+ sendNMEASentence(sentence);
+#endif
return;
- }
+ }
AISMessage24A msg2;
msg2.encode(mStationData, *p2);
@@ -193,7 +233,10 @@ void TXScheduler::queueMessage24(VHFChannel channel)
TXPacket *p3 = TXPacketPool::instance().newTXPacket(channel);
if ( !p3 )
{
- //DBG("Unable to allocate TX packet for 24B\r\n");
+#if REPORT_TX_SCHEDULING
+ sprintf(sentence, "$PAISCHTX,24B,%d*", TX_ALLOC_ERROR);
+ sendNMEASentence(sentence);
+#endif
return;
}
diff --git a/latest/Firmware/Transponder/Src/Transceiver.cpp b/latest/Firmware/Transponder/Src/Transceiver.cpp
index ad27843..572265a 100644
--- a/latest/Firmware/Transponder/Src/Transceiver.cpp
+++ b/latest/Firmware/Transponder/Src/Transceiver.cpp
@@ -25,10 +25,10 @@
#include "EZRadioPRO.h"
#include "AISChannels.h"
#include "bsp.hpp"
+#include "TXErrors.h"
#include
#include "TXScheduler.hpp"
-
Transceiver::Transceiver(GPIO_TypeDef *sdnPort, uint32_t sdnPin, GPIO_TypeDef *csPort,
uint32_t csPin, GPIO_TypeDef *dataPort, uint32_t dataPin,
GPIO_TypeDef *clockPort, uint32_t clockPin, int chipId)
@@ -93,7 +93,7 @@ void Transceiver::configure()
break;
default:
pwr.pa_mode = 0x48;
- pwr.pa_level = 0x20;
+ pwr.pa_level = 0x1C;
pwr.pa_bias_clkduty = 0x00;
break;
}
@@ -157,7 +157,7 @@ void Transceiver::configureGPIOsForTX()
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x04; // RX/TX bit data
gpiocfg.GPIO2 = 0x1F; // RX/TX bit clock
- gpiocfg.GPIO3 = 0x21; // RX_STATE; high in RX, low in TX
+ gpiocfg.GPIO3 = 0x20; // RX_STATE; high in TX, low in RX
gpiocfg.NIRQ = 0x00; // No change
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change
@@ -217,12 +217,21 @@ void Transceiver::onBitClock()
else if ( mUTC && mUTC - mTXPacket->timestamp() >= MIN_MSG_18_TX_INTERVAL )
{
// The packet is way too old. Discard it.
+#if REPORT_TX_SCHEDULING
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( e )
+ {
+ sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", mTXPacket->messageType(), TX_PACKET_TOO_OLD);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
+ }
+#endif
TXPacketPool::instance().deleteTXPacket(mTXPacket);
mTXPacket = NULL;
}
else if ( mUTC - mLastTXTime < MIN_TX_INTERVAL )
{
- // Got to wait a bit ...
+ // It's not time to transmit yet
return;
}
else if ( mUTC && mSlotBitNumber == CCA_SLOT_BIT && mTXPacket->channel() == mChannel )
@@ -319,7 +328,7 @@ void Transceiver::configureGPIOsForRX()
gpiocfg.GPIO0 = 0x00; // No change
gpiocfg.GPIO1 = 0x14; // RX data bits
gpiocfg.GPIO2 = 0x1F; // RX/TX data clock
- gpiocfg.GPIO3 = 0x21; // RX_STATE; high during RX and low during TX
+ gpiocfg.GPIO3 = 0x20; // RX_STATE; high during TX and low during RX
gpiocfg.NIRQ = 0x00; // No change
gpiocfg.SDO = 0x00; // No change
gpiocfg.GENCFG = 0x00; // No change
@@ -335,7 +344,5 @@ void Transceiver::reportTXEvent()
snprintf(e->nmeaBuffer.sentence, sizeof e->nmeaBuffer.sentence, "$PAITX,%c,%s*", AIS_CHANNELS[mTXPacket->channel()].designation, mTXPacket->messageType());
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
-
- // We turn off the led and the LEDManager will turn it back on in 100ms or so
bsp_tx_led_off();
}
diff --git a/latest/Firmware/Transponder/Src/bsp/bsp_11_0.cpp b/latest/Firmware/Transponder/Src/bsp/bsp_11_0.cpp
index 1c1998a..6ef2908 100644
--- a/latest/Firmware/Transponder/Src/bsp/bsp_11_0.cpp
+++ b/latest/Firmware/Transponder/Src/bsp/bsp_11_0.cpp
@@ -27,6 +27,11 @@
#if BOARD_REV==110
+#define STATION_DATA_ADDRESS 0x0800F800
+
+
+const char *BSP_HW_REV = "11.x";
+
SPI_HandleTypeDef hspi1;
IWDG_HandleTypeDef hiwdg;
UART_HandleTypeDef huart2;
@@ -43,7 +48,12 @@ irq_callback trxClockCallback = nullptr;
irq_callback rxClockCallback = nullptr;
irq_callback tickCallback = nullptr;
-#define EEPROM_ADDRESS 0x50 << 1
+// This should be plenty big (no need to be a whole flash page)
+typedef union
+{
+ StationData station;
+ uint64_t dw[32];
+} StationDataPage;
typedef struct
{
@@ -317,6 +327,78 @@ void HAL_MspInit(void)
/* USER CODE END MspInit 1 */
}
+bool bsp_is_tx_hardwired()
+{
+ // Always true for this board. It will get more involved later. Or maybe never ...
+ return true;
+}
+
+void bsp_read_station_data(StationData *data)
+{
+ memcpy(data, (const uint8_t*)STATION_DATA_ADDRESS, sizeof(StationData));
+}
+
+void bsp_write_station_data(const StationData &data)
+{
+ bsp_erase_station_data();
+ StationDataPage page;
+ page.station = data;
+ page.station.magic = STATION_DATA_MAGIC;
+
+ uint32_t pageAddress = STATION_DATA_ADDRESS;
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
+ HAL_FLASH_Unlock();
+ HAL_StatusTypeDef status = HAL_OK;
+ for ( uint32_t dw = 0; dw < sizeof page/8; ++dw )
+ {
+ status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, pageAddress + dw*8, page.dw[dw]);
+ if ( status != HAL_OK )
+ break;
+ }
+ HAL_FLASH_Lock();
+}
+
+void bsp_erase_station_data()
+{
+ uint32_t page = (STATION_DATA_ADDRESS - FLASH_BASE) / FLASH_PAGE_SIZE;
+
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
+ if ( HAL_FLASH_Unlock() != HAL_OK )
+ return;
+
+ FLASH_EraseInitTypeDef erase;
+ erase.TypeErase = FLASH_TYPEERASE_PAGES;
+ erase.Banks = FLASH_BANK_1;
+ erase.Page = page;
+ erase.NbPages = 1;
+
+ uint32_t errPage;
+ HAL_FLASHEx_Erase(&erase, &errPage);
+ HAL_FLASH_Lock();
+}
+
+bool bsp_is_station_data_provisioned()
+{
+ const StationData *d = (const StationData *)STATION_DATA_ADDRESS;
+ return d->magic == STATION_DATA_MAGIC;
+}
+
+void bsp_read_config_flags(ConfigFlags *flags)
+{
+ // Not implemented
+}
+
+void bsp_write_config_flags(const ConfigFlags &flags)
+{
+ // Not implemented
+}
+
+
+void bsp_erase_config_flags()
+{
+ // Not implemented
+}
+
void bsp_set_rx_mode()
{
HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_RESET); // Kill the RF MOSFET bias voltage
@@ -394,6 +476,10 @@ void bsp_gnss_off()
HAL_GPIO_WritePin(GNSS_EN_PORT, GNSS_EN_PIN, GPIO_PIN_SET);
}
+bool bsp_is_gnss_on()
+{
+ return HAL_GPIO_ReadPin(GNSS_EN_PORT, GNSS_EN_PIN) == GPIO_PIN_SET;
+}
void USART_putc(USART_TypeDef* USARTx, char c)
{
@@ -417,7 +503,7 @@ void bsp_write_string(const char *s)
void bsp_start_wdt()
{
IWDG_InitTypeDef iwdg;
- iwdg.Prescaler = IWDG_PRESCALER_64;
+ iwdg.Prescaler = IWDG_PRESCALER_16;
iwdg.Reload = 0x0fff;
iwdg.Window = 0x0fff;
diff --git a/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp b/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp
new file mode 100644
index 0000000..9913ab7
--- /dev/null
+++ b/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp
@@ -0,0 +1,750 @@
+/*
+ Copyright (c) 2016-2020 Peter Antypas
+
+ This file is part of the MAIANA™ transponder firmware.
+
+ The firmware is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+*/
+
+
+
+#include "bsp.hpp"
+#include
+#include "printf_serial.h"
+#include
+
+
+
+#if BOARD_REV==113
+
+#define EEPROM_ADDRESS (0x50 << 1)
+#define EEPROM_STATION_ADDRESS 0x00
+#define EEPROM_CONFIG_ADDRESS 0x40
+#define STATION_DATA_FLASH_ADDRESS 0x0800F800
+
+const char *BSP_HW_REV = "11.x";
+
+I2C_HandleTypeDef hi2c1;
+SPI_HandleTypeDef hspi1;
+IWDG_HandleTypeDef hiwdg;
+UART_HandleTypeDef huart2;
+UART_HandleTypeDef huart1;
+TIM_HandleTypeDef htim2;
+
+void SystemClock_Config();
+
+char_input_cb gnssInputCallback = nullptr;
+char_input_cb terminalInputCallback = nullptr;
+irq_callback ppsCallback = nullptr;
+irq_callback sotdmaCallback = nullptr;
+irq_callback trxClockCallback = nullptr;
+irq_callback rxClockCallback = nullptr;
+irq_callback tickCallback = nullptr;
+
+// This should be plenty big (no need to be a whole flash page)
+typedef union
+{
+ StationData station;
+ uint64_t dw[32];
+} StationDataPage;
+
+StationData __station = {0};
+
+typedef struct
+{
+ GPIO_TypeDef *port;
+ GPIO_InitTypeDef gpio;
+ GPIO_PinState init;
+} GPIO;
+
+static const GPIO __gpios[] = {
+ {GNSS_EN_PORT, {GNSS_EN_PIN, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
+ {TRX_IC_CLK_PORT, {TRX_IC_CLK_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {TX_DISABLE_PORT, {TX_DISABLE_PIN, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
+ {CS2_PORT, {CS2_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, 0}, GPIO_PIN_SET},
+ {RX_EVT_PORT, {RX_EVT_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {GNSS_1PPS_PORT, {GNSS_1PPS_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {GNSS_NMEA_RX_PORT, {GNSS_NMEA_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART2}, GPIO_PIN_RESET},
+ {CS1_PORT, {CS1_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, 0}, GPIO_PIN_SET},
+ {SCK_PORT, {SCK_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
+ {MISO_PORT, {MISO_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
+ {MOSI_PORT, {MOSI_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_HIGH, GPIO_AF5_SPI1}, GPIO_PIN_SET},
+ {SDN1_PORT, {SDN1_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
+ {TRX_IC_DATA_PORT, {TRX_IC_DATA_PIN, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {TX_EVT_PORT, {TX_EVT_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {UART_TX_PORT, {UART_TX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART1}, GPIO_PIN_RESET},
+ {UART_RX_PORT, {UART_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_SPEED_LOW, GPIO_AF7_USART1}, GPIO_PIN_RESET},
+ {GNSS_STATE_PORT, {GNSS_STATE_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {SDN2_PORT, {SDN2_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_SET},
+ {RX_IC_CLK_PORT, {RX_IC_CLK_PIN, GPIO_MODE_IT_RISING, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {RX_IC_DATA_PORT, {RX_IC_DATA_PIN, GPIO_MODE_INPUT, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {PA_BIAS_PORT, {PA_BIAS_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW, 0}, GPIO_PIN_RESET},
+ {I2C_SCL_PORT, {I2C_SCL_PIN, GPIO_MODE_AF_OD, GPIO_PULLUP, GPIO_SPEED_HIGH, GPIO_AF4_I2C1}, GPIO_PIN_SET},
+ {I2C_SDA_PORT, {I2C_SDA_PIN, GPIO_MODE_AF_OD, GPIO_PULLUP, GPIO_SPEED_HIGH, GPIO_AF4_I2C1}, GPIO_PIN_SET},
+};
+
+extern "C"
+{
+ void Error_Handler(uint8_t i)
+ {
+ asm("BKPT 0");
+ printf_serial_now("[ERROR %d]\r\n", i);
+ //printf_serial_now("[ERROR] ***** System error handler resetting *****\r\n");
+ //NVIC_SystemReset();
+ }
+}
+
+
+void gpio_pin_init();
+
+void bsp_hw_init()
+{
+ HAL_Init();
+ SystemClock_Config();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+
+ __HAL_RCC_USART2_CLK_ENABLE();
+ __HAL_RCC_USART1_CLK_ENABLE();
+ __HAL_RCC_SPI1_CLK_ENABLE();
+ __HAL_RCC_TIM2_CLK_ENABLE();
+ __HAL_RCC_I2C1_CLK_ENABLE();
+
+ gpio_pin_init();
+
+
+
+ // USART1 (main UART)
+ huart1.Instance = USART1;
+ huart1.Init.BaudRate = 38400;
+ huart1.Init.WordLength = UART_WORDLENGTH_8B;
+ huart1.Init.StopBits = UART_STOPBITS_1;
+ huart1.Init.Parity = UART_PARITY_NONE;
+ huart1.Init.Mode = UART_MODE_TX_RX;
+ huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart1.Init.OverSampling = UART_OVERSAMPLING_16;
+ huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+ huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+ HAL_UART_Init(&huart1);
+
+ HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
+ HAL_NVIC_EnableIRQ(USART1_IRQn);
+ __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
+
+
+ // SPI
+
+ hspi1.Instance = SPI1;
+ hspi1.Init.Mode = SPI_MODE_MASTER;
+ hspi1.Init.Direction = SPI_DIRECTION_2LINES;
+ hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
+ hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
+ hspi1.Init.NSS = SPI_NSS_SOFT;
+ hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
+ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
+ hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+ hspi1.Init.CRCPolynomial = 7;
+ hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
+ hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
+
+ if (HAL_SPI_Init(&hspi1) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ __HAL_SPI_ENABLE(&hspi1);
+
+
+ // I2C
+ hi2c1.Instance = I2C1;
+ hi2c1.Init.Timing = 0x00702991;
+ hi2c1.Init.OwnAddress1 = 0;
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c1.Init.OwnAddress2 = 0;
+ hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+ /** Configure Analogue filter
+ */
+ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+ /** Configure Digital filter
+ */
+ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ // USART2 (GNSS, RX only)
+ huart2.Instance = USART2;
+ huart2.Init.BaudRate = 9600;
+ huart2.Init.WordLength = UART_WORDLENGTH_8B;
+ huart2.Init.StopBits = UART_STOPBITS_1;
+ huart2.Init.Parity = UART_PARITY_NONE;
+ huart2.Init.Mode = UART_MODE_TX_RX;
+ huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+ huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+ huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+ HAL_UART_Init(&huart2);
+
+ HAL_NVIC_SetPriority(USART2_IRQn, 7, 0);
+ HAL_NVIC_EnableIRQ(USART2_IRQn);
+ __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
+
+ // TIM2 for SOTDMA (37.5Hz)
+ uint32_t period = (SystemCoreClock / 37.5) - 1;
+
+ __HAL_RCC_TIM2_CLK_ENABLE();
+ htim2.Instance = TIM2;
+ htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ htim2.Init.Prescaler = 0;
+ htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+ htim2.Init.Period = period;
+ htim2.Init.RepetitionCounter = 0;
+
+ HAL_TIM_Base_Init(&htim2);
+
+ // 1PPS signal
+ HAL_NVIC_SetPriority(EXTI2_IRQn, 6, 0);
+ HAL_NVIC_EnableIRQ(EXTI2_IRQn);
+
+ // SOTDMA
+ HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
+ HAL_NVIC_EnableIRQ(TIM2_IRQn);
+
+ // RF IC clock interrupts
+ HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 0);
+ HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
+
+ HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0);
+ HAL_NVIC_EnableIRQ(EXTI3_IRQn);
+
+ bsp_read_station_data(&__station);
+}
+
+
+
+void SystemClock_Config()
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+ RCC_PeriphCLKInitTypeDef PeriphClkInit;
+
+ /**Initializes the CPU, AHB and APB bus clocks
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+ RCC_OscInitStruct.PLL.PLLM = 1;
+ RCC_OscInitStruct.PLL.PLLN = 10; // 80 MHz
+#if defined(STM32L432xx) || defined(STM32L431xx)
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
+#endif
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ /**Initializes the CPU, AHB and APB bus clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
+ PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_HSI;
+ PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ /**Configure the main internal regulator output voltage
+ */
+ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
+ {
+ Error_Handler(0);
+ }
+
+ /**Configure the Systick interrupt time
+ */
+ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
+
+ /**Configure the Systick
+ */
+ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+
+ /* SysTick_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+
+}
+
+void gpio_pin_init()
+{
+ for ( unsigned i = 0; i < sizeof __gpios / sizeof(GPIO); ++i )
+ {
+ const GPIO* io = &__gpios[i];
+ if ( io->gpio.Mode == GPIO_MODE_OUTPUT_PP || io->gpio.Mode == GPIO_MODE_OUTPUT_OD )
+ {
+ HAL_GPIO_WritePin(io->port, io->gpio.Pin, io->init);
+ }
+ HAL_GPIO_Init(io->port, (GPIO_InitTypeDef*)&io->gpio);
+ }
+}
+
+void HAL_MspInit(void)
+{
+ /* USER CODE BEGIN MspInit 0 */
+
+ /* USER CODE END MspInit 0 */
+
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /**
+ * Some of these interrupts will be managed and configured in FreeRTOS
+ */
+
+ /* System interrupt init*/
+ /* MemoryManagement_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
+ /* BusFault_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
+ /* UsageFault_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
+ /* SVCall_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(SVCall_IRQn, 10, 0);
+ /* DebugMonitor_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
+ /* PendSV_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(PendSV_IRQn, 10, 0);
+ /* SysTick_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+
+ /* USER CODE BEGIN MspInit 1 */
+
+ /* USER CODE END MspInit 1 */
+}
+
+bool bsp_is_tx_hardwired()
+{
+ // Always true for this board. It will get more involved later. Or maybe never ...
+ return true;
+}
+
+void bsp_erase_flash_station_data()
+{
+ uint32_t page = (STATION_DATA_FLASH_ADDRESS - FLASH_BASE) / FLASH_PAGE_SIZE;
+
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
+ if ( HAL_FLASH_Unlock() != HAL_OK )
+ return;
+
+ FLASH_EraseInitTypeDef erase;
+ erase.TypeErase = FLASH_TYPEERASE_PAGES;
+ erase.Banks = FLASH_BANK_1;
+ erase.Page = page;
+ erase.NbPages = 1;
+
+ uint32_t errPage;
+ HAL_FLASHEx_Erase(&erase, &errPage);
+ HAL_FLASH_Lock();
+}
+
+
+void bsp_read_station_data(StationData *data)
+{
+ /**
+ * If there is legacy data in MCU flash, migrate it automatically to EEPROM!!!
+ */
+
+ StationData *__d = (StationData*)STATION_DATA_FLASH_ADDRESS;
+ if ( __d->magic == STATION_DATA_MAGIC )
+ {
+ bsp_write_station_data(*__d);
+ bsp_erase_flash_station_data();
+ }
+
+ uint8_t *d = (uint8_t*)data;
+ for ( uint8_t i = 0; i < sizeof (StationData); ++i, ++d )
+ {
+ HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS|1, i+EEPROM_STATION_ADDRESS, 1, d, 1, 5);
+ }
+}
+
+void bsp_write_station_data(const StationData &data)
+{
+ __station = data;
+ uint8_t *d = (uint8_t*)&__station;
+ for ( uint8_t i = 0; i < sizeof (StationData); ++i, ++d )
+ {
+ HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, i+EEPROM_STATION_ADDRESS, 1, d, 1, 5);
+ HAL_Delay(5);
+ }
+}
+
+void bsp_erase_station_data()
+{
+ bsp_write_station_data({0});
+}
+
+bool bsp_is_station_data_provisioned()
+{
+ return __station.magic == STATION_DATA_MAGIC;
+}
+
+void bsp_read_config_flags(ConfigFlags *flags)
+{
+ uint8_t *d = (uint8_t*)flags;
+ for ( uint8_t i = 0; i < sizeof (ConfigFlags); ++i, ++d )
+ {
+ HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS|1, i+EEPROM_CONFIG_ADDRESS, 1, d, 1, 5);
+ }
+}
+
+void bsp_write_config_flags(const ConfigFlags &flags)
+{
+ ConfigFlags __f = flags;
+ uint8_t *d = (uint8_t*)&__f;
+ for ( uint8_t i = 0; i < sizeof (ConfigFlags); ++i, ++d )
+ {
+ HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, i+EEPROM_CONFIG_ADDRESS, 1, d, 1, 5);
+ HAL_Delay(5);
+ }
+}
+
+
+void bsp_erase_config_flags()
+{
+ bsp_write_config_flags({0});
+}
+
+void bsp_set_rx_mode()
+{
+ HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_RESET); // Kill the RF MOSFET bias voltage
+ GPIO_InitTypeDef gpio;
+ gpio.Pin = TRX_IC_DATA_PIN;
+ gpio.Mode = GPIO_MODE_INPUT;
+ gpio.Speed = GPIO_SPEED_FREQ_LOW;
+ gpio.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(TRX_IC_DATA_PORT, &gpio);
+}
+
+void bsp_rx_led_on()
+{
+ HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_SET);
+}
+
+void bsp_rx_led_off()
+{
+ HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_RESET);
+}
+
+void bsp_tx_led_on()
+{
+#if LEGACY_BREAKOUTS
+ HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_RESET);
+#else
+ HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_SET);
+#endif
+}
+
+void bsp_tx_led_off()
+{
+#if LEGACY_BREAKOUTS
+ HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_SET);
+#else
+ HAL_GPIO_WritePin(TX_EVT_PORT, TX_EVT_PIN, GPIO_PIN_RESET);
+#endif
+}
+
+void bsp_gps_led_on()
+{
+ HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, GPIO_PIN_SET);
+}
+
+void bsp_gps_led_off()
+{
+ HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, GPIO_PIN_RESET);
+}
+
+void bsp_set_tx_mode()
+{
+ GPIO_InitTypeDef gpio;
+ gpio.Pin = TRX_IC_DATA_PIN;
+ gpio.Mode = GPIO_MODE_OUTPUT_PP;
+ gpio.Speed = GPIO_SPEED_FREQ_LOW;
+ gpio.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(TRX_IC_DATA_PORT, &gpio);
+
+ HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_SET); // RF MOSFET bias voltage
+}
+
+void bsp_gnss_on()
+{
+ HAL_GPIO_WritePin(GNSS_EN_PORT, GNSS_EN_PIN, GPIO_PIN_RESET);
+}
+
+void bsp_gnss_off()
+{
+ HAL_GPIO_WritePin(GNSS_EN_PORT, GNSS_EN_PIN, GPIO_PIN_SET);
+}
+
+bool bsp_is_gnss_on()
+{
+ return HAL_GPIO_ReadPin(GNSS_EN_PORT, GNSS_EN_PIN) == GPIO_PIN_SET;
+}
+
+void USART_putc(USART_TypeDef* USARTx, char c)
+{
+ while ( !(USARTx->ISR & USART_ISR_TXE) )
+ ;
+
+ USARTx->TDR = c;
+}
+
+void bsp_write_char(char c)
+{
+ USART_putc(USART1, c);
+}
+
+void bsp_write_string(const char *s)
+{
+ for ( int i = 0; s[i] != 0; ++i )
+ USART_putc(USART1, s[i]);
+}
+
+void bsp_start_wdt()
+{
+ IWDG_InitTypeDef iwdg;
+ iwdg.Prescaler = IWDG_PRESCALER_16;
+ iwdg.Reload = 0x0fff;
+ iwdg.Window = 0x0fff;
+
+ hiwdg.Instance = IWDG;
+ hiwdg.Init = iwdg;
+
+ HAL_IWDG_Init(&hiwdg);
+}
+
+void bsp_refresh_wdt()
+{
+ HAL_IWDG_Refresh(&hiwdg);
+}
+
+void bsp_set_gnss_input_callback(char_input_cb cb)
+{
+ gnssInputCallback = cb;
+}
+
+void bsp_set_terminal_input_callback(char_input_cb cb)
+{
+ terminalInputCallback = cb;
+}
+
+void bsp_set_tick_callback(irq_callback cb)
+{
+ tickCallback = cb;
+}
+
+void bsp_start_sotdma_timer()
+{
+ HAL_TIM_Base_Start_IT(&htim2);
+}
+
+void bsp_stop_sotdma_timer()
+{
+ HAL_TIM_Base_Stop_IT(&htim2);
+}
+
+void bsp_set_gnss_1pps_callback(irq_callback cb)
+{
+ ppsCallback = cb;
+}
+
+void bsp_set_trx_clk_callback(irq_callback cb)
+{
+ trxClockCallback = cb;
+}
+
+void bsp_set_rx_clk_callback(irq_callback cb)
+{
+ rxClockCallback = cb;
+}
+
+void bsp_set_gnss_sotdma_timer_callback(irq_callback cb)
+{
+ sotdmaCallback = cb;
+}
+
+uint32_t bsp_get_sotdma_timer_value()
+{
+ return TIM2->CNT;
+}
+
+void bsp_set_sotdma_timer_value(uint32_t v)
+{
+ TIM2->CNT = v;
+}
+
+uint32_t bsp_get_system_clock()
+{
+ return SystemCoreClock;
+}
+
+uint8_t bsp_tx_spi_byte(uint8_t data)
+{
+ uint8_t result = 0;
+ HAL_SPI_TransmitReceive(&hspi1, &data, &result, 1, 2);
+ return result;
+}
+
+void bsp_reboot()
+{
+ NVIC_SystemReset();
+}
+
+bool bsp_is_tx_disabled()
+{
+ return HAL_GPIO_ReadPin(TX_DISABLE_PORT, TX_DISABLE_PIN) == GPIO_PIN_RESET;
+}
+
+void bsp_enter_dfu()
+{
+ // Cut off the GPS signals immediately to prevent its UART from transmitting and hijacking the bootloader upon reset
+ bsp_gnss_off();
+
+ HAL_Delay(1000);
+
+ // This flag simply tells main() to jump to the ROM bootloader immediately upon reset, before initializing anything
+ *(uint32_t*)BOOTMODE_ADDRESS = DFU_FLAG_MAGIC;
+
+ bsp_reboot();
+}
+
+void bsp_signal_rx_event()
+{
+ HAL_GPIO_WritePin(RX_EVT_PORT, RX_EVT_PIN, GPIO_PIN_SET);
+}
+
+
+void bsp_signal_gps_status(bool tracking)
+{
+ HAL_GPIO_WritePin(GNSS_STATE_PORT, GNSS_STATE_PIN, tracking ? GPIO_PIN_SET: GPIO_PIN_RESET);
+}
+
+extern "C"
+{
+
+ void USART1_IRQHandler(void)
+ {
+ if ( __HAL_UART_GET_IT(&huart1, UART_IT_RXNE) )
+ {
+ __HAL_UART_CLEAR_IT(&huart1, UART_IT_RXNE);
+ char c = USART1->RDR;
+ if ( terminalInputCallback )
+ terminalInputCallback(c);
+ }
+ }
+
+ void EXTI2_IRQHandler(void)
+ {
+ if ( __HAL_GPIO_EXTI_GET_IT(GNSS_1PPS_PIN) != RESET )
+ {
+ __HAL_GPIO_EXTI_CLEAR_IT(GNSS_1PPS_PIN);
+ if ( ppsCallback )
+ ppsCallback();
+ }
+ }
+
+ void USART2_IRQHandler()
+ {
+ if ( __HAL_UART_GET_IT(&huart2, UART_IT_RXNE) )
+ {
+ __HAL_UART_CLEAR_IT(&huart2, UART_IT_RXNE);
+ char c = (char)USART2->RDR;
+ if ( gnssInputCallback )
+ gnssInputCallback(c);
+ }
+ }
+
+
+ void TIM2_IRQHandler(void)
+ {
+ if(__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);
+ if ( sotdmaCallback )
+ sotdmaCallback();
+ }
+ }
+ }
+
+ void EXTI3_IRQHandler(void)
+ {
+ if ( __HAL_GPIO_EXTI_GET_IT(RX_IC_CLK_PIN) != RESET )
+ {
+ __HAL_GPIO_EXTI_CLEAR_IT(RX_IC_CLK_PIN);
+ if ( rxClockCallback )
+ rxClockCallback();
+ }
+ }
+
+ void EXTI15_10_IRQHandler(void)
+ {
+ if ( __HAL_GPIO_EXTI_GET_IT(TRX_IC_CLK_PIN) != RESET )
+ {
+ __HAL_GPIO_EXTI_CLEAR_IT(TRX_IC_CLK_PIN);
+ if ( trxClockCallback )
+ trxClockCallback();
+ }
+ }
+
+ void HAL_SYSTICK_Callback()
+ {
+ if ( tickCallback )
+ tickCallback();
+ }
+
+}
+
+#endif
diff --git a/latest/Firmware/Transponder/Src/main.cpp b/latest/Firmware/Transponder/Src/main.cpp
index d604d78..621d523 100644
--- a/latest/Firmware/Transponder/Src/main.cpp
+++ b/latest/Firmware/Transponder/Src/main.cpp
@@ -56,13 +56,12 @@ void mainLoop()
Configuration::instance().init();
DataTerminal::instance().init();
CommandProcessor::instance().init();
- LEDManager::instance().init();
-
RXPacketProcessor packetProcessor;
GPS::instance().init();
TXPacketPool::instance().init();
TXScheduler::instance().init();
RadioManager::instance().init();
+ LEDManager::instance().init();
if ( !cliBootMode )
{
@@ -76,11 +75,15 @@ void mainLoop()
*(uint32_t*)BOOTMODE_ADDRESS = 0;
+#if ENABLE_WDT
bsp_start_wdt();
+#endif
while (1)
{
EventQueue::instance().dispatch();
+#if ENABLE_WDT
bsp_refresh_wdt();
+#endif
__WFI();
}
}