1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-21 09:50:08 -07:00

OpenPlotter support

This commit is contained in:
Peter Antypas 2021-10-19 22:51:41 -07:00
commit bc9b2bf32d
31 changed files with 13399 additions and 157 deletions

View File

@ -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:
<img src="images/uart_breakout.jpg" height="420"/>
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&trade; 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.

BIN
images/uart_breakout.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,774 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="9.6.2">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="0.1" unitdist="mm" unit="mm" style="lines" multiple="1" display="yes" altdistance="5" altunitdist="mil" altunit="mil"/>
<layers>
<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
<layer number="2" name="Route2" color="16" fill="1" visible="no" active="no"/>
<layer number="15" name="Route15" color="23" fill="1" visible="no" active="no"/>
<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="yes"/>
<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
<layer number="20" name="Dimension" color="24" fill="1" visible="yes" active="yes"/>
<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
<layer number="25" name="tNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="26" name="bNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="27" name="tValues" color="7" fill="1" visible="no" active="yes"/>
<layer number="28" name="bValues" color="7" fill="1" visible="no" active="yes"/>
<layer number="29" name="tStop" color="7" fill="3" visible="yes" active="yes"/>
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
<layer number="31" name="tCream" color="7" fill="4" visible="yes" active="yes"/>
<layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
<layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
<layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
<layer number="39" name="tKeepout" color="4" fill="11" visible="yes" active="yes"/>
<layer number="40" name="bKeepout" color="1" fill="11" visible="yes" active="yes"/>
<layer number="41" name="tRestrict" color="4" fill="10" visible="yes" active="yes"/>
<layer number="42" name="bRestrict" color="1" fill="10" visible="yes" active="yes"/>
<layer number="43" name="vRestrict" color="2" fill="10" visible="yes" active="yes"/>
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
<layer number="45" name="Holes" color="7" fill="1" visible="yes" active="yes"/>
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="yes"/>
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="52" name="bDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="88" name="SimResults" color="9" fill="1" visible="no" active="no"/>
<layer number="89" name="SimProbes" color="9" fill="1" visible="no" active="no"/>
<layer number="90" name="Modules" color="5" fill="1" visible="no" active="no"/>
<layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
<layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
<layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
<layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
<layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
<layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
<layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
<layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
<layer number="99" name="SpiceOrder" color="7" fill="1" visible="no" active="no"/>
<layer number="100" name="AssyDwgBottomFrame" color="7" fill="1" visible="yes" active="yes"/>
<layer number="101" name="Patch_Top" color="12" fill="4" visible="yes" active="yes"/>
<layer number="102" name="Vscore" color="7" fill="1" visible="yes" active="yes"/>
<layer number="103" name="tMap" color="7" fill="1" visible="yes" active="yes"/>
<layer number="104" name="Name" color="16" fill="1" visible="yes" active="yes"/>
<layer number="105" name="tPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="106" name="bPlate" color="7" fill="1" visible="yes" active="yes"/>
<layer number="107" name="Crop" color="7" fill="1" visible="yes" active="yes"/>
<layer number="108" name="tplace-old" color="10" fill="1" visible="yes" active="yes"/>
<layer number="109" name="ref-old" color="11" fill="1" visible="yes" active="yes"/>
<layer number="110" name="fp0" color="7" fill="1" visible="yes" active="yes"/>
<layer number="111" name="LPC17xx" color="7" fill="1" visible="yes" active="yes"/>
<layer number="112" name="tSilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="113" name="IDFDebug" color="4" fill="1" visible="yes" active="yes"/>
<layer number="114" name="Badge_Outline" color="7" fill="1" visible="yes" active="yes"/>
<layer number="115" name="ReferenceISLANDS" color="7" fill="1" visible="yes" active="yes"/>
<layer number="116" name="Patch_BOT" color="9" fill="4" visible="yes" active="yes"/>
<layer number="118" name="Rect_Pads" color="7" fill="1" visible="yes" active="yes"/>
<layer number="121" name="_tsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="122" name="_bsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="123" name="tTestmark" color="7" fill="1" visible="yes" active="yes"/>
<layer number="124" name="bTestmark" color="7" fill="1" visible="yes" active="yes"/>
<layer number="125" name="_tNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="126" name="_bNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="127" name="_tValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="128" name="_bValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="129" name="Mask" color="7" fill="1" visible="yes" active="yes"/>
<layer number="131" name="tAdjust" color="7" fill="1" visible="yes" active="yes"/>
<layer number="132" name="bAdjust" color="7" fill="1" visible="yes" active="yes"/>
<layer number="144" name="Drill_legend" color="7" fill="1" visible="yes" active="yes"/>
<layer number="150" name="Notes" color="7" fill="1" visible="yes" active="yes"/>
<layer number="151" name="HeatSink" color="7" fill="1" visible="yes" active="yes"/>
<layer number="152" name="_bDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="153" name="FabDoc1" color="7" fill="1" visible="yes" active="yes"/>
<layer number="154" name="FabDoc2" color="7" fill="1" visible="yes" active="yes"/>
<layer number="155" name="FabDoc3" color="7" fill="1" visible="yes" active="yes"/>
<layer number="199" name="Contour" color="7" fill="1" visible="yes" active="yes"/>
<layer number="200" name="200bmp" color="1" fill="10" visible="yes" active="yes"/>
<layer number="201" name="201bmp" color="2" fill="10" visible="yes" active="yes"/>
<layer number="202" name="202bmp" color="3" fill="10" visible="yes" active="yes"/>
<layer number="203" name="203bmp" color="4" fill="10" visible="yes" active="yes"/>
<layer number="204" name="204bmp" color="5" fill="10" visible="yes" active="yes"/>
<layer number="205" name="205bmp" color="6" fill="10" visible="yes" active="yes"/>
<layer number="206" name="206bmp" color="7" fill="10" visible="yes" active="yes"/>
<layer number="207" name="207bmp" color="8" fill="10" visible="yes" active="yes"/>
<layer number="208" name="208bmp" color="9" fill="10" visible="yes" active="yes"/>
<layer number="209" name="209bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="210" name="210bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="211" name="211bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="212" name="212bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="213" name="213bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="214" name="214bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="215" name="215bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="216" name="216bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="217" name="217bmp" color="18" fill="1" visible="no" active="no"/>
<layer number="218" name="218bmp" color="19" fill="1" visible="no" active="no"/>
<layer number="219" name="219bmp" color="20" fill="1" visible="no" active="no"/>
<layer number="220" name="220bmp" color="21" fill="1" visible="no" active="no"/>
<layer number="221" name="221bmp" color="22" fill="1" visible="no" active="no"/>
<layer number="222" name="222bmp" color="23" fill="1" visible="no" active="no"/>
<layer number="223" name="223bmp" color="24" fill="1" visible="no" active="no"/>
<layer number="224" name="224bmp" color="25" fill="1" visible="no" active="no"/>
<layer number="225" name="225bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="226" name="226bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="227" name="227bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="228" name="228bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="229" name="229bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="230" name="230bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="231" name="231bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="232" name="Eagle3D_PG2" color="7" fill="1" visible="no" active="no"/>
<layer number="233" name="Eagle3D_PG3" color="7" fill="1" visible="no" active="no"/>
<layer number="248" name="Housing" color="7" fill="1" visible="yes" active="yes"/>
<layer number="249" name="Edge" color="7" fill="1" visible="yes" active="yes"/>
<layer number="250" name="Descript" color="3" fill="1" visible="no" active="no"/>
<layer number="251" name="SMDround" color="12" fill="11" visible="no" active="no"/>
<layer number="254" name="cooling" color="7" fill="1" visible="yes" active="yes"/>
<layer number="255" name="routoute" color="7" fill="1" visible="yes" active="yes"/>
</layers>
<board>
<plain>
<wire x1="0" y1="0" x2="55.86" y2="0" width="0" layer="20"/>
<wire x1="55.86" y1="0" x2="55.86" y2="17.45" width="0" layer="20"/>
<wire x1="55.86" y1="17.45" x2="0" y2="17.45" width="0" layer="20"/>
<wire x1="0" y1="17.45" x2="0" y2="0" width="0" layer="20"/>
<text x="1.5" y="15.7" size="0.8128" layer="25" font="vector" rot="SR270">MAIANA(TM)
UART Breakout v2.0
(c)2021 P.Antypas</text>
<circle x="38.1" y="14.5" radius="1.1" width="0.0762" layer="20"/>
<circle x="2.3" y="2.3" radius="1.1" width="0.0762" layer="20"/>
<text x="15.565" y="4.29" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">RX_LED</text>
<text x="18.145" y="4.29" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">GPS_LED</text>
<text x="20.625" y="4.29" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">UART_RX</text>
<text x="23.205" y="4.29" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">UART_TX</text>
<text x="22.485" y="13.39" size="0.8128" layer="25" font="vector" rot="SR270">TX_OFF</text>
<text x="14.85" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">9-18V</text>
<text x="19.95" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">TX_LED</text>
<text x="17.45" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">GND</text>
<text x="30.13" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">GND</text>
<text x="32.63" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">3.3V</text>
<text x="25.09" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">GND</text>
<text x="27.63" y="13.4" size="0.8128" layer="25" font="vector" rot="SR270">GND</text>
<text x="33.3" y="4.3" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">3.3V</text>
<text x="28.2" y="4.3" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">3.3V</text>
<text x="30.7" y="4.3" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">3.3V</text>
<circle x="2.3" y="2.3" radius="2" width="0.0762" layer="21"/>
<circle x="38.1" y="14.5" radius="2" width="0.0762" layer="21"/>
<text x="25.75" y="4.3" size="0.8128" layer="25" font="vector" rot="SR270" align="top-right">GND</text>
</plain>
<libraries>
<library name="MyPassives">
<packages>
<package name="0603">
<smd name="P$1" x="-0.8" y="0" dx="1" dy="1" layer="1"/>
<smd name="P$2" x="0.8" y="0" dx="1" dy="1" layer="1"/>
<wire x1="-0.9" y1="0.4" x2="0.9" y2="0.4" width="0.127" layer="21"/>
<wire x1="0.9" y1="0.4" x2="0.9" y2="-0.4" width="0.127" layer="21"/>
<wire x1="0.9" y1="-0.4" x2="-0.9" y2="-0.4" width="0.127" layer="21"/>
<wire x1="-0.9" y1="-0.4" x2="-0.9" y2="0.4" width="0.127" layer="21"/>
<text x="-1.4" y="0.7" size="0.6096" layer="25" font="vector">&gt;NAME</text>
<text x="-1.4" y="-1.3" size="0.6096" layer="27" font="vector">&gt;VALUE</text>
</package>
</packages>
</library>
<library name="MyDiodes">
<packages>
<package name="SMB-BIDIR">
<wire x1="-2.2606" y1="1.905" x2="2.2606" y2="1.905" width="0.1016" layer="21"/>
<wire x1="-2.2606" y1="-1.905" x2="2.2606" y2="-1.905" width="0.1016" layer="21"/>
<wire x1="-2.2606" y1="-1.905" x2="-2.2606" y2="1.905" width="0.1016" layer="21"/>
<wire x1="2.2606" y1="-1.905" x2="2.2606" y2="1.905" width="0.1016" layer="21"/>
<smd name="C" x="-2.2" y="0" dx="2.4" dy="2.4" layer="1"/>
<smd name="A" x="2.2" y="0" dx="2.4" dy="2.4" layer="1"/>
<text x="-1.259" y="2.259" size="0.6096" layer="25" font="vector">&gt;NAME</text>
<text x="-1.5" y="-2.9" size="0.6096" layer="27" font="vector">&gt;VALUE</text>
</package>
<package name="SOD123">
<description>SOD123 Package</description>
<wire x1="-1.1" y1="0.7" x2="-0.5" y2="0.7" width="0.254" layer="21"/>
<wire x1="-0.5" y1="0.7" x2="1.1" y2="0.7" width="0.254" layer="21"/>
<wire x1="1.1" y1="0.7" x2="1.1" y2="-0.7" width="0.254" layer="21"/>
<wire x1="1.1" y1="-0.7" x2="-0.5" y2="-0.7" width="0.254" layer="21"/>
<wire x1="-0.5" y1="-0.7" x2="-1.1" y2="-0.7" width="0.254" layer="21"/>
<wire x1="-1.1" y1="-0.7" x2="-1.1" y2="0.7" width="0.254" layer="21"/>
<smd name="C" x="-1.9" y="0" dx="1.4" dy="1.4" layer="1"/>
<smd name="A" x="1.9" y="0" dx="1.4" dy="1.4" layer="1"/>
<text x="-1.5" y="1.2" size="0.6096" layer="25" font="vector">&gt;NAME</text>
<wire x1="-0.5" y1="0.7" x2="-0.5" y2="-0.7" width="0.254" layer="21"/>
</package>
</packages>
</library>
<library name="adafruit">
<packages>
<package name="R1206">
<description>&lt;b&gt;RESISTOR&lt;/b&gt;&lt;p&gt;
chip</description>
<wire x1="0.9525" y1="-0.8128" x2="-0.9652" y2="-0.8128" width="0.1524" layer="51"/>
<wire x1="0.9525" y1="0.8128" x2="-0.9652" y2="0.8128" width="0.1524" layer="51"/>
<wire x1="-2.473" y1="0.983" x2="2.473" y2="0.983" width="0.0508" layer="39"/>
<wire x1="2.473" y1="0.983" x2="2.473" y2="-0.983" width="0.0508" layer="39"/>
<wire x1="2.473" y1="-0.983" x2="-2.473" y2="-0.983" width="0.0508" layer="39"/>
<wire x1="-2.473" y1="-0.983" x2="-2.473" y2="0.983" width="0.0508" layer="39"/>
<smd name="2" x="1.422" y="0" dx="1.6" dy="1.803" layer="1"/>
<smd name="1" x="-1.422" y="0" dx="1.6" dy="1.803" layer="1"/>
<text x="-1.397" y="1.143" size="1.27" layer="25">&gt;NAME</text>
<text x="-1.397" y="-2.413" size="1.27" layer="27">&gt;VALUE</text>
<rectangle x1="-1.6891" y1="-0.8763" x2="-0.9525" y2="0.8763" layer="51"/>
<rectangle x1="0.9525" y1="-0.8763" x2="1.6891" y2="0.8763" layer="51"/>
<rectangle x1="-0.3" y1="-0.7" x2="0.3" y2="0.7" layer="35"/>
</package>
</packages>
</library>
<library name="SparkFun-Connectors">
<description>&lt;h3&gt;SparkFun Electronics' preferred foot prints&lt;/h3&gt;
In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.&lt;br&gt;&lt;br&gt;
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.
&lt;br&gt;&lt;br&gt;
&lt;b&gt;Licensing:&lt;/b&gt; Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
&lt;br&gt;&lt;br&gt;
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.</description>
<packages>
<package name="RJ45-8">
<wire x1="-7.62" y1="10" x2="7.62" y2="10" width="0.2032" layer="21"/>
<wire x1="-7.62" y1="-3" x2="-7.62" y2="10" width="0.2032" layer="21"/>
<wire x1="-7.62" y1="-3" x2="7.62" y2="-3" width="0.2032" layer="21"/>
<wire x1="7.62" y1="10" x2="7.62" y2="-3" width="0.2032" layer="21"/>
<wire x1="-7.62" y1="-3" x2="-7.62" y2="-10.8" width="0.2032" layer="51"/>
<wire x1="-7.62" y1="-10.8" x2="7.62" y2="-10.8" width="0.2032" layer="51"/>
<wire x1="7.62" y1="-10.8" x2="7.62" y2="-3" width="0.2032" layer="51"/>
<pad name="8" x="4.445" y="8.89" drill="1" diameter="1.8796"/>
<pad name="7" x="3.175" y="6.35" drill="1" diameter="1.8796"/>
<pad name="6" x="1.905" y="8.89" drill="1" diameter="1.8796"/>
<pad name="4" x="-0.635" y="8.89" drill="1" diameter="1.8796"/>
<pad name="2" x="-3.175" y="8.89" drill="1" diameter="1.8796"/>
<pad name="5" x="0.635" y="6.35" drill="1" diameter="1.8796"/>
<pad name="3" x="-1.905" y="6.35" drill="1" diameter="1.8796"/>
<pad name="1" x="-4.445" y="6.35" drill="1" diameter="1.8796" shape="square"/>
<hole x="-5.715" y="0" drill="3.2"/>
<hole x="5.715" y="0" drill="3.2"/>
</package>
<package name="1X08">
<wire x1="14.605" y1="1.27" x2="15.875" y2="1.27" width="0.2032" layer="21"/>
<wire x1="15.875" y1="1.27" x2="16.51" y2="0.635" width="0.2032" layer="21"/>
<wire x1="16.51" y1="-0.635" x2="15.875" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="11.43" y1="0.635" x2="12.065" y2="1.27" width="0.2032" layer="21"/>
<wire x1="12.065" y1="1.27" x2="13.335" y2="1.27" width="0.2032" layer="21"/>
<wire x1="13.335" y1="1.27" x2="13.97" y2="0.635" width="0.2032" layer="21"/>
<wire x1="13.97" y1="-0.635" x2="13.335" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="13.335" y1="-1.27" x2="12.065" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="12.065" y1="-1.27" x2="11.43" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="14.605" y1="1.27" x2="13.97" y2="0.635" width="0.2032" layer="21"/>
<wire x1="13.97" y1="-0.635" x2="14.605" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="15.875" y1="-1.27" x2="14.605" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="6.985" y1="1.27" x2="8.255" y2="1.27" width="0.2032" layer="21"/>
<wire x1="8.255" y1="1.27" x2="8.89" y2="0.635" width="0.2032" layer="21"/>
<wire x1="8.89" y1="-0.635" x2="8.255" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="8.89" y1="0.635" x2="9.525" y2="1.27" width="0.2032" layer="21"/>
<wire x1="9.525" y1="1.27" x2="10.795" y2="1.27" width="0.2032" layer="21"/>
<wire x1="10.795" y1="1.27" x2="11.43" y2="0.635" width="0.2032" layer="21"/>
<wire x1="11.43" y1="-0.635" x2="10.795" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="10.795" y1="-1.27" x2="9.525" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="9.525" y1="-1.27" x2="8.89" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="3.81" y1="0.635" x2="4.445" y2="1.27" width="0.2032" layer="21"/>
<wire x1="4.445" y1="1.27" x2="5.715" y2="1.27" width="0.2032" layer="21"/>
<wire x1="5.715" y1="1.27" x2="6.35" y2="0.635" width="0.2032" layer="21"/>
<wire x1="6.35" y1="-0.635" x2="5.715" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="5.715" y1="-1.27" x2="4.445" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="4.445" y1="-1.27" x2="3.81" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="6.985" y1="1.27" x2="6.35" y2="0.635" width="0.2032" layer="21"/>
<wire x1="6.35" y1="-0.635" x2="6.985" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="8.255" y1="-1.27" x2="6.985" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="-0.635" y1="1.27" x2="0.635" y2="1.27" width="0.2032" layer="21"/>
<wire x1="0.635" y1="1.27" x2="1.27" y2="0.635" width="0.2032" layer="21"/>
<wire x1="1.27" y1="-0.635" x2="0.635" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="1.27" y1="0.635" x2="1.905" y2="1.27" width="0.2032" layer="21"/>
<wire x1="1.905" y1="1.27" x2="3.175" y2="1.27" width="0.2032" layer="21"/>
<wire x1="3.175" y1="1.27" x2="3.81" y2="0.635" width="0.2032" layer="21"/>
<wire x1="3.81" y1="-0.635" x2="3.175" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="3.175" y1="-1.27" x2="1.905" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="1.905" y1="-1.27" x2="1.27" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="-1.27" y1="0.635" x2="-1.27" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="-0.635" y1="1.27" x2="-1.27" y2="0.635" width="0.2032" layer="21"/>
<wire x1="-1.27" y1="-0.635" x2="-0.635" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="0.635" y1="-1.27" x2="-0.635" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="17.145" y1="1.27" x2="18.415" y2="1.27" width="0.2032" layer="21"/>
<wire x1="18.415" y1="1.27" x2="19.05" y2="0.635" width="0.2032" layer="21"/>
<wire x1="19.05" y1="0.635" x2="19.05" y2="-0.635" width="0.2032" layer="21"/>
<wire x1="19.05" y1="-0.635" x2="18.415" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="17.145" y1="1.27" x2="16.51" y2="0.635" width="0.2032" layer="21"/>
<wire x1="16.51" y1="-0.635" x2="17.145" y2="-1.27" width="0.2032" layer="21"/>
<wire x1="18.415" y1="-1.27" x2="17.145" y2="-1.27" width="0.2032" layer="21"/>
<pad name="1" x="0" y="0" drill="1.016" diameter="1.8796" shape="square" rot="R90"/>
<pad name="2" x="2.54" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="3" x="5.08" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="4" x="7.62" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="5" x="10.16" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="6" x="12.7" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="7" x="15.24" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="8" x="17.78" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<text x="-1.3462" y="1.8288" size="1.27" layer="25" ratio="10">&gt;NAME</text>
<text x="-1.27" y="-3.175" size="1.27" layer="27">&gt;VALUE</text>
<rectangle x1="14.986" y1="-0.254" x2="15.494" y2="0.254" layer="51"/>
<rectangle x1="12.446" y1="-0.254" x2="12.954" y2="0.254" layer="51"/>
<rectangle x1="9.906" y1="-0.254" x2="10.414" y2="0.254" layer="51"/>
<rectangle x1="7.366" y1="-0.254" x2="7.874" y2="0.254" layer="51"/>
<rectangle x1="4.826" y1="-0.254" x2="5.334" y2="0.254" layer="51"/>
<rectangle x1="2.286" y1="-0.254" x2="2.794" y2="0.254" layer="51"/>
<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51"/>
<rectangle x1="17.526" y1="-0.254" x2="18.034" y2="0.254" layer="51"/>
</package>
</packages>
</library>
<library name="microchip">
<description>&lt;b&gt;Microchip PIC Microcontrollers and other Devices&lt;/b&gt;&lt;p&gt;
Based on the following sources :
&lt;ul&gt;
&lt;li&gt;Microchip Data Book, 1993
&lt;li&gt;THE EMERGING WORLD STANDARD, 1995/1996
&lt;li&gt;Microchip, Technical Library CD-ROM, June 1998
&lt;li&gt;www.microchip.com
&lt;/ul&gt;
&lt;author&gt;Created by librarian@cadsoft.de&lt;/author&gt;</description>
<packages>
<package name="SOT23">
<description>&lt;b&gt;SMALL OUTLINE TRANSISTOR&lt;/b&gt;&lt;p&gt;
reflow soldering</description>
<wire x1="-1.973" y1="1.983" x2="1.973" y2="1.983" width="0.0508" layer="39"/>
<wire x1="1.973" y1="-1.983" x2="-1.973" y2="-1.983" width="0.0508" layer="39"/>
<wire x1="-1.973" y1="-1.983" x2="-1.973" y2="1.983" width="0.0508" layer="39"/>
<wire x1="1.973" y1="1.983" x2="1.973" y2="-1.983" width="0.0508" layer="39"/>
<wire x1="1.422" y1="0.66" x2="1.422" y2="-0.66" width="0.1524" layer="51"/>
<wire x1="1.422" y1="-0.66" x2="-1.422" y2="-0.66" width="0.1524" layer="51"/>
<wire x1="-1.422" y1="-0.66" x2="-1.422" y2="0.66" width="0.1524" layer="51"/>
<wire x1="-1.422" y1="0.66" x2="1.422" y2="0.66" width="0.1524" layer="51"/>
<smd name="3" x="0" y="1.1" dx="1" dy="1.4" layer="1"/>
<smd name="2" x="0.95" y="-1.1" dx="1" dy="1.4" layer="1"/>
<smd name="1" x="-0.95" y="-1.1" dx="1" dy="1.4" layer="1"/>
<text x="-1.905" y="1.905" size="1.27" layer="25">&gt;NAME</text>
<text x="-1.905" y="-3.175" size="1.27" layer="27">&gt;VALUE</text>
<rectangle x1="-0.2286" y1="0.7112" x2="0.2286" y2="1.2954" layer="51"/>
<rectangle x1="0.7112" y1="-1.2954" x2="1.1684" y2="-0.7112" layer="51"/>
<rectangle x1="-1.1684" y1="-1.2954" x2="-0.7112" y2="-0.7112" layer="51"/>
<rectangle x1="-0.5001" y1="-0.3" x2="0.5001" y2="0.3" layer="35"/>
</package>
</packages>
</library>
</libraries>
<attributes>
</attributes>
<variantdefs>
<variantdef name="JLCPCB"/>
</variantdefs>
<classes>
<class number="0" name="default" width="0" drill="0">
</class>
</classes>
<designrules name="default *">
<description language="de">&lt;b&gt;EAGLE Design Rules&lt;/b&gt;
&lt;p&gt;
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.</description>
<description language="en">&lt;b&gt;EAGLE Design Rules&lt;/b&gt;
&lt;p&gt;
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.</description>
<param name="layerSetup" value="(1*16)"/>
<param name="mtCopper" value="0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm"/>
<param name="mtIsolate" value="1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm"/>
<param name="mdWireWire" value="6mil"/>
<param name="mdWirePad" value="6mil"/>
<param name="mdWireVia" value="6mil"/>
<param name="mdPadPad" value="6mil"/>
<param name="mdPadVia" value="6mil"/>
<param name="mdViaVia" value="6mil"/>
<param name="mdSmdPad" value="0mil"/>
<param name="mdSmdVia" value="0mil"/>
<param name="mdSmdSmd" value="0mil"/>
<param name="mdViaViaSameLayer" value="6mil"/>
<param name="mnLayersViaInSmd" value="2"/>
<param name="mdCopperDimension" value="15mil"/>
<param name="mdDrill" value="6mil"/>
<param name="mdSmdStop" value="0mil"/>
<param name="msWidth" value="6mil"/>
<param name="msDrill" value="0.3mm"/>
<param name="msMicroVia" value="9.99mm"/>
<param name="msBlindViaRatio" value="0.5"/>
<param name="rvPadTop" value="0.25"/>
<param name="rvPadInner" value="0.25"/>
<param name="rvPadBottom" value="0.25"/>
<param name="rvViaOuter" value="0.25"/>
<param name="rvViaInner" value="0.25"/>
<param name="rvMicroViaOuter" value="0.25"/>
<param name="rvMicroViaInner" value="0.25"/>
<param name="rlMinPadTop" value="10mil"/>
<param name="rlMaxPadTop" value="20mil"/>
<param name="rlMinPadInner" value="10mil"/>
<param name="rlMaxPadInner" value="20mil"/>
<param name="rlMinPadBottom" value="10mil"/>
<param name="rlMaxPadBottom" value="20mil"/>
<param name="rlMinViaOuter" value="8mil"/>
<param name="rlMaxViaOuter" value="20mil"/>
<param name="rlMinViaInner" value="8mil"/>
<param name="rlMaxViaInner" value="20mil"/>
<param name="rlMinMicroViaOuter" value="4mil"/>
<param name="rlMaxMicroViaOuter" value="20mil"/>
<param name="rlMinMicroViaInner" value="4mil"/>
<param name="rlMaxMicroViaInner" value="20mil"/>
<param name="psTop" value="-1"/>
<param name="psBottom" value="-1"/>
<param name="psFirst" value="-1"/>
<param name="psElongationLong" value="100"/>
<param name="psElongationOffset" value="100"/>
<param name="mvStopFrame" value="1"/>
<param name="mvCreamFrame" value="0"/>
<param name="mlMinStopFrame" value="4mil"/>
<param name="mlMaxStopFrame" value="4mil"/>
<param name="mlMinCreamFrame" value="0mil"/>
<param name="mlMaxCreamFrame" value="0mil"/>
<param name="mlViaStopLimit" value="20mil"/>
<param name="srRoundness" value="0"/>
<param name="srMinRoundness" value="0mil"/>
<param name="srMaxRoundness" value="0mil"/>
<param name="slThermalIsolate" value="10mil"/>
<param name="slThermalsForVias" value="0"/>
<param name="dpMaxLengthDifference" value="10mm"/>
<param name="dpGapFactor" value="2.5"/>
<param name="checkAngle" value="0"/>
<param name="checkFont" value="1"/>
<param name="checkRestrict" value="1"/>
<param name="checkStop" value="0"/>
<param name="checkValues" value="0"/>
<param name="checkNames" value="1"/>
<param name="checkWireStubs" value="1"/>
<param name="checkPolygonWidth" value="0"/>
<param name="useDiameter" value="13"/>
<param name="maxErrors" value="50"/>
</designrules>
<autorouter>
<pass name="Default">
<param name="RoutingGrid" value="50mil"/>
<param name="AutoGrid" value="1"/>
<param name="Efforts" value="0"/>
<param name="TopRouterVariant" value="1"/>
<param name="tpViaShape" value="round"/>
<param name="PrefDir.1" value="a"/>
<param name="PrefDir.2" value="0"/>
<param name="PrefDir.3" value="0"/>
<param name="PrefDir.4" value="0"/>
<param name="PrefDir.5" value="0"/>
<param name="PrefDir.6" value="0"/>
<param name="PrefDir.7" value="0"/>
<param name="PrefDir.8" value="0"/>
<param name="PrefDir.9" value="0"/>
<param name="PrefDir.10" value="0"/>
<param name="PrefDir.11" value="0"/>
<param name="PrefDir.12" value="0"/>
<param name="PrefDir.13" value="0"/>
<param name="PrefDir.14" value="0"/>
<param name="PrefDir.15" value="0"/>
<param name="PrefDir.16" value="a"/>
<param name="cfVia" value="8"/>
<param name="cfNonPref" value="5"/>
<param name="cfChangeDir" value="2"/>
<param name="cfOrthStep" value="2"/>
<param name="cfDiagStep" value="3"/>
<param name="cfExtdStep" value="0"/>
<param name="cfBonusStep" value="1"/>
<param name="cfMalusStep" value="1"/>
<param name="cfPadImpact" value="4"/>
<param name="cfSmdImpact" value="4"/>
<param name="cfBusImpact" value="0"/>
<param name="cfHugging" value="3"/>
<param name="cfAvoid" value="4"/>
<param name="cfPolygon" value="10"/>
<param name="cfBase.1" value="0"/>
<param name="cfBase.2" value="1"/>
<param name="cfBase.3" value="1"/>
<param name="cfBase.4" value="1"/>
<param name="cfBase.5" value="1"/>
<param name="cfBase.6" value="1"/>
<param name="cfBase.7" value="1"/>
<param name="cfBase.8" value="1"/>
<param name="cfBase.9" value="1"/>
<param name="cfBase.10" value="1"/>
<param name="cfBase.11" value="1"/>
<param name="cfBase.12" value="1"/>
<param name="cfBase.13" value="1"/>
<param name="cfBase.14" value="1"/>
<param name="cfBase.15" value="1"/>
<param name="cfBase.16" value="0"/>
<param name="mnVias" value="20"/>
<param name="mnSegments" value="9999"/>
<param name="mnExtdSteps" value="9999"/>
<param name="mnRipupLevel" value="10"/>
<param name="mnRipupSteps" value="100"/>
<param name="mnRipupTotal" value="100"/>
</pass>
<pass name="Follow-me" refer="Default" active="yes">
</pass>
<pass name="Busses" refer="Default" active="yes">
<param name="cfNonPref" value="4"/>
<param name="cfBusImpact" value="4"/>
<param name="cfHugging" value="0"/>
<param name="mnVias" value="0"/>
</pass>
<pass name="Route" refer="Default" active="yes">
</pass>
<pass name="Optimize1" refer="Default" active="yes">
<param name="cfVia" value="99"/>
<param name="cfExtdStep" value="10"/>
<param name="cfHugging" value="1"/>
<param name="mnExtdSteps" value="1"/>
<param name="mnRipupLevel" value="0"/>
</pass>
<pass name="Optimize2" refer="Optimize1" active="yes">
<param name="cfNonPref" value="0"/>
<param name="cfChangeDir" value="6"/>
<param name="cfExtdStep" value="0"/>
<param name="cfBonusStep" value="2"/>
<param name="cfMalusStep" value="2"/>
<param name="cfPadImpact" value="2"/>
<param name="cfSmdImpact" value="2"/>
<param name="cfHugging" value="0"/>
</pass>
<pass name="Optimize3" refer="Optimize2" active="yes">
<param name="cfChangeDir" value="8"/>
<param name="cfPadImpact" value="0"/>
<param name="cfSmdImpact" value="0"/>
</pass>
<pass name="Optimize4" refer="Optimize3" active="yes">
<param name="cfChangeDir" value="25"/>
</pass>
</autorouter>
<elements>
<element name="C1" library="MyPassives" package="0603" value="1uF" x="36.185" y="3.045" smashed="yes" rot="R270">
<attribute name="PARTNO" value="CC0603KRX5R8BB105" x="-17.155" y="-12.195" size="1.778" layer="27" rot="R270" display="off"/>
<attribute name="VALUE" x="34.885" y="4.445" size="0.6096" layer="27" font="vector" rot="R270"/>
</element>
<element name="C2" library="MyPassives" package="0603" value="1uF" x="37.785" y="9.53" smashed="yes" rot="R180">
<attribute name="PARTNO" value="CC0603KRX5R8BB105" x="18.735" y="62.87" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="VALUE" x="39.185" y="10.83" size="0.6096" layer="27" font="vector" rot="R180"/>
</element>
<element name="D1" library="MyDiodes" package="SMB-BIDIR" value="SMBJ14CA" x="10.01" y="15.105" smashed="yes">
<attribute name="PARTNO" value="SMBJ14CA" x="35.41" y="-20.455" size="1.778" layer="27" display="off"/>
<attribute name="VALUE" x="8.51" y="12.205" size="0.6096" layer="27" font="vector"/>
</element>
<element name="D2" library="MyDiodes" package="SOD123" value="WSB5508L-2/TR" x="10.735" y="11.21" smashed="yes">
<attribute name="PARTNO" value="WSB5508L-2/TR" x="28.515" y="-24.35" size="1.778" layer="27" display="off"/>
<attribute name="VALUE" x="9.235" y="8.31" size="0.6096" layer="27" font="vector"/>
</element>
<element name="F1" library="adafruit" package="R1206" value="BSMD1206-050-16V" x="10.67" y="8.27" smashed="yes">
<attribute name="PARTNO" value="BSMD1206-050-16V" x="10.67" y="8.27" size="1.778" layer="27" display="off"/>
<attribute name="VALUE" x="9.273" y="5.857" size="0.6096" layer="27" font="vector"/>
</element>
<element name="J2" library="SparkFun-Connectors" package="RJ45-8" value="95501-2821" x="52.07" y="8.89" smashed="yes" rot="R90">
<attribute name="PARTNO" value="95501-2821" x="52.07" y="8.89" size="1.778" layer="27" rot="R90" display="off"/>
<attribute name="PROD_ID" value="CONN-08506" x="63.5" y="30.48" size="1.778" layer="27" rot="R90" display="off"/>
</element>
<element name="JP2" library="SparkFun-Connectors" package="1X08" value="" x="33.02" y="2.54" locked="yes" smashed="yes" rot="R180">
<attribute name="PROD_ID" value="CONN-08438" x="33.02" y="2.54" locked="yes" size="0.8128" layer="27" font="vector" rot="R180" display="off"/>
<attribute name="VALUE" x="34.29" y="5.715" locked="yes" size="1.27" layer="27" rot="R180"/>
</element>
<element name="JP3" library="SparkFun-Connectors" package="1X08" value="" x="33.02" y="15.24" locked="yes" smashed="yes" rot="R180">
<attribute name="PROD_ID" value="CONN-08438" x="33.02" y="15.24" locked="yes" size="0.8128" layer="27" font="vector" rot="R180" display="off"/>
<attribute name="VALUE" x="34.29" y="18.415" locked="yes" size="1.27" layer="27" rot="R180"/>
</element>
<element name="U1" library="microchip" package="SOT23" value="SE8533X2-HF" x="37.5" y="6.8" smashed="yes" rot="R90">
<attribute name="PARTNO" value="SE8533X2-HF" x="37.5" y="6.8" size="1.778" layer="27" rot="R90" display="off"/>
<attribute name="VALUE" x="40.675" y="4.895" size="1.27" layer="27" rot="R90"/>
</element>
</elements>
<signals>
<signal name="GND">
<contactref element="J2" pad="8"/>
<contactref element="D1" pad="C"/>
<contactref element="C1" pad="P$2"/>
<contactref element="C2" pad="P$2"/>
<polygon width="0.254" layer="1">
<vertex x="-1.27" y="19.05"/>
<vertex x="56.71" y="19.05"/>
<vertex x="56.71" y="-1.27"/>
<vertex x="-1.27" y="-1.27"/>
</polygon>
<polygon width="0.254" layer="16">
<vertex x="-2.54" y="20.32"/>
<vertex x="57.48" y="20.32"/>
<vertex x="57.48" y="-3.81"/>
<vertex x="-2.54" y="-3.81"/>
</polygon>
<via x="37.6" y="2.7" extent="1-16" drill="0.3"/>
<via x="40" y="8.7" extent="1-16" drill="0.3"/>
<via x="40" y="6.6" extent="1-16" drill="0.3"/>
<via x="35.8" y="9.5" extent="1-16" drill="0.3"/>
<contactref element="U1" pad="1"/>
<contactref element="JP2" pad="4"/>
<via x="7" y="13.2" extent="1-16" drill="0.3"/>
<via x="8.4" y="13.2" extent="1-16" drill="0.3"/>
<contactref element="JP3" pad="4"/>
<contactref element="JP3" pad="3"/>
<contactref element="JP3" pad="2"/>
<contactref element="JP3" pad="7"/>
<via x="9.7" y="13.2" extent="1-16" drill="0.3"/>
<via x="9.7" y="14.4" extent="1-16" drill="0.3"/>
</signal>
<signal name="TRANSPONDER_UART_TX">
<contactref element="J2" pad="5"/>
<contactref element="JP2" pad="5"/>
<wire x1="22.86" y1="2.54" x2="22.86" y2="5.66" width="0.254" layer="16"/>
<wire x1="41.8621875" y1="10.3886" x2="42.6749875" y2="9.5758" width="0.254" layer="16"/>
<wire x1="45.6692" y1="9.5758" x2="45.72" y2="9.525" width="0.254" layer="16"/>
<wire x1="42.6749875" y1="9.5758" x2="45.6692" y2="9.5758" width="0.254" layer="16"/>
<wire x1="22.86" y1="5.66" x2="27.5886" y2="10.3886" width="0.254" layer="16"/>
<wire x1="27.5886" y1="10.3886" x2="41.8621875" y2="10.3886" width="0.254" layer="16"/>
</signal>
<signal name="12V">
<contactref element="D1" pad="A"/>
<contactref element="D2" pad="A"/>
<contactref element="JP3" pad="8"/>
<wire x1="12.21" y1="15.105" x2="12.7" y2="15.105" width="0.8128" layer="1"/>
<wire x1="12.7" y1="15.105" x2="15.105" y2="15.105" width="0.8128" layer="1"/>
<wire x1="15.105" y1="15.105" x2="15.24" y2="15.24" width="0.8128" layer="1"/>
<wire x1="12.635" y1="11.21" x2="12.635" y2="15.04" width="0.8128" layer="1"/>
<wire x1="12.635" y1="15.04" x2="12.7" y2="15.105" width="0.8128" layer="1"/>
</signal>
<signal name="TX_OFF">
<contactref element="J2" pad="2"/>
<wire x1="43.18" y1="5.715" x2="41.2" y2="7.695" width="0.254" layer="1"/>
<wire x1="41.2" y1="7.695" x2="41.2" y2="10" width="0.254" layer="1"/>
<wire x1="41.2" y1="10" x2="39.7676" y2="11.4324" width="0.254" layer="1"/>
<wire x1="39.7676" y1="11.4324" x2="39.1" y2="11.4324" width="0.254" layer="1"/>
<via x="39.1" y="11.4324" extent="1-16" drill="0.3"/>
<wire x1="39.1" y1="11.4324" x2="22.7876" y2="11.4324" width="0.254" layer="16"/>
<contactref element="JP3" pad="5"/>
<wire x1="22.7876" y1="11.4324" x2="22.2" y2="12.02" width="0.254" layer="16"/>
<wire x1="22.2" y1="12.02" x2="22.2" y2="12.2" width="0.254" layer="16"/>
<via x="22.2" y="12.2" extent="1-16" drill="0.3"/>
<wire x1="22.2" y1="12.2" x2="22.2" y2="14.58" width="0.254" layer="1"/>
<wire x1="22.2" y1="14.58" x2="22.86" y2="15.24" width="0.254" layer="1"/>
</signal>
<signal name="GPS_LED">
<contactref element="J2" pad="4"/>
<contactref element="JP2" pad="7"/>
<wire x1="43.18" y1="8.255" x2="39.725" y2="4.8" width="0.254" layer="16"/>
<wire x1="39.725" y1="4.8" x2="25.6" y2="4.8" width="0.254" layer="16"/>
<wire x1="25.6" y1="4.8" x2="25.4" y2="4.6" width="0.254" layer="16"/>
<via x="25.4" y="4.6" extent="1-16" drill="0.3"/>
<wire x1="25.4" y1="4.6" x2="19.8" y2="4.6" width="0.254" layer="1"/>
<wire x1="19.8" y1="4.6" x2="17.78" y2="2.58" width="0.254" layer="1"/>
<wire x1="17.78" y1="2.58" x2="17.78" y2="2.54" width="0.254" layer="1"/>
</signal>
<signal name="RX_LED">
<contactref element="J2" pad="6"/>
<contactref element="JP2" pad="8"/>
<wire x1="43.18" y1="10.795" x2="23.695" y2="10.795" width="0.254" layer="16"/>
<wire x1="15.44" y1="2.54" x2="15.24" y2="2.54" width="0.254" layer="16"/>
<wire x1="23.695" y1="10.795" x2="15.44" y2="2.54" width="0.254" layer="16"/>
</signal>
<signal name="TX_LED">
<contactref element="J2" pad="7"/>
<contactref element="JP3" pad="6"/>
<wire x1="45.72" y1="12.065" x2="36.9146375" y2="12.065" width="0.254" layer="16"/>
<wire x1="36.9146375" y1="12.065" x2="36.8470375" y2="12.1326" width="0.254" layer="16"/>
<wire x1="23.4274" y1="12.1326" x2="20.32" y2="15.24" width="0.254" layer="16"/>
<wire x1="36.8470375" y1="12.1326" x2="23.4274" y2="12.1326" width="0.254" layer="16"/>
</signal>
<signal name="V_IN">
<contactref element="F1" pad="1"/>
<contactref element="D2" pad="C"/>
<wire x1="8.835" y1="11.21" x2="9.248" y2="10.797" width="0.8128" layer="1"/>
<wire x1="9.248" y1="10.797" x2="9.248" y2="8.27" width="0.8128" layer="1"/>
</signal>
<signal name="TRANSPONDER_UART_RX">
<contactref element="J2" pad="3"/>
<contactref element="JP2" pad="6"/>
<wire x1="45.72" y1="6.985" x2="44.3992" y2="5.6642" width="0.254" layer="16"/>
<wire x1="44.3992" y1="5.6642" x2="44.3992" y2="5.2099875" width="0.254" layer="16"/>
<wire x1="44.3992" y1="5.2099875" x2="40.2892125" y2="1.1" width="0.254" layer="16"/>
<wire x1="21.76" y1="1.1" x2="20.32" y2="2.54" width="0.254" layer="16"/>
<wire x1="40.2892125" y1="1.1" x2="21.76" y2="1.1" width="0.254" layer="16"/>
</signal>
<signal name="V_OUT">
<contactref element="F1" pad="2"/>
<contactref element="C1" pad="P$1"/>
<contactref element="U1" pad="3"/>
<wire x1="18.37" y1="8.3" x2="32.4" y2="8.3" width="0.8128" layer="1"/>
<wire x1="12.092" y1="8.27" x2="18.34" y2="8.27" width="0.8128" layer="1"/>
<wire x1="18.34" y1="8.27" x2="18.37" y2="8.3" width="0.8128" layer="1"/>
<contactref element="J2" pad="1"/>
<wire x1="44.575" y1="3.3" x2="45.72" y2="4.445" width="0.8128" layer="1"/>
<wire x1="36.4" y1="6.8" x2="36.3412" y2="6.7412" width="0.8128" layer="1"/>
<wire x1="38.5597375" y1="3.3" x2="44.575" y2="3.3" width="0.8128" layer="1"/>
<wire x1="33.9" y1="6.8" x2="36.4" y2="6.8" width="0.8128" layer="1"/>
<wire x1="32.4" y1="8.3" x2="33.9" y2="6.8" width="0.8128" layer="1"/>
<wire x1="36.4" y1="6.8" x2="36.4" y2="4.06" width="0.8128" layer="1"/>
<wire x1="36.4" y1="4.06" x2="36.185" y2="3.845" width="0.8128" layer="1"/>
<wire x1="36.185" y1="3.845" x2="38.0147375" y2="3.845" width="0.8128" layer="1"/>
<wire x1="38.0147375" y1="3.845" x2="38.5597375" y2="3.3" width="0.8128" layer="1"/>
</signal>
<signal name="3.3V">
<contactref element="C2" pad="P$1"/>
<contactref element="JP2" pad="2"/>
<contactref element="JP2" pad="1"/>
<contactref element="JP2" pad="3"/>
<contactref element="JP3" pad="1"/>
<wire x1="33.02" y1="15.24" x2="34.76" y2="15.24" width="0.254" layer="1"/>
<wire x1="34.76" y1="15.24" x2="35.685" y2="14.315" width="0.254" layer="1"/>
<wire x1="33.02" y1="2.54" x2="30.48" y2="2.54" width="0.254" layer="1"/>
<wire x1="30.48" y1="2.54" x2="27.94" y2="2.54" width="0.254" layer="1"/>
<wire x1="35.685" y1="12.43" x2="36.4075" y2="11.7075" width="0.254" layer="1"/>
<wire x1="36.4075" y1="11.7075" x2="38.585" y2="9.53" width="0.254" layer="1"/>
<wire x1="35.685" y1="14.315" x2="35.685" y2="12.43" width="0.254" layer="1"/>
<contactref element="U1" pad="2"/>
<wire x1="38.585" y1="9.53" x2="38.6" y2="9.53" width="0.254" layer="1"/>
<wire x1="38.6" y1="9.53" x2="38.6" y2="7.75" width="0.254" layer="1"/>
<wire x1="33.02" y1="2.54" x2="33.02" y2="5.88" width="0.254" layer="1"/>
<wire x1="33.02" y1="5.88" x2="31.9" y2="7" width="0.254" layer="1"/>
<via x="31.9" y="7" extent="1-16" drill="0.3"/>
<wire x1="31.9" y1="7" x2="31.9" y2="9.3" width="0.254" layer="16"/>
<wire x1="31.9" y1="9.3" x2="32.1" y2="9.5" width="0.254" layer="16"/>
<via x="32.1" y="9.5" extent="1-16" drill="0.3"/>
<wire x1="32.1" y1="9.5" x2="34.1" y2="11.5" width="0.254" layer="1"/>
<wire x1="36.2" y1="11.5" x2="36.4075" y2="11.7075" width="0.254" layer="1"/>
<wire x1="34.1" y1="11.5" x2="36.2" y2="11.5" width="0.254" layer="1"/>
</signal>
</signals>
<mfgpreviewcolors>
<mfgpreviewcolor name="soldermaskcolor" color="0xC8008000"/>
<mfgpreviewcolor name="silkscreencolor" color="0xFFFEFEFE"/>
<mfgpreviewcolor name="backgroundcolor" color="0xFF282828"/>
<mfgpreviewcolor name="coppercolor" color="0xFFFFBF00"/>
<mfgpreviewcolor name="substratecolor" color="0xFF786E46"/>
</mfgpreviewcolors>
</board>
</drawing>
<compatibility>
<note version="6.3" minversion="6.2.2" severity="warning">
Since Version 6.2.2 text objects can contain more than one line,
which will not be processed correctly with this version.
</note>
</compatibility>
</eagle>

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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_ */

View File

@ -44,6 +44,7 @@ public:
void init();
void enable();
void disable();
bool isEnabled();
void onRX(char c);
void onPPS();
void startTimer();

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;

View File

@ -22,13 +22,14 @@
#include <stdint.h>
#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 <bsp_10_9.hpp>
#elif BOARD_REV == 110
#include <bsp_11_0.hpp>
#elif BOARD_REV == 113
#include <bsp_11_3.hpp>
#endif

View File

@ -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 <https://www.gnu.org/licenses/>
*/
#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_ */

View File

@ -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

View File

@ -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,6 +242,7 @@ def enter_dfu(portname):
s = p.readline()
p.close()
return len(s) == 0
"""
if __name__ == '__main__':
if len(sys.argv) < 4:

View File

@ -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

View File

@ -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<string> 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

View File

@ -23,11 +23,15 @@
#include "config.h"
#include "EventQueue.hpp"
#include <stdio.h>
#include <bsp/bsp.hpp>
// These are not defined in ANY CMSIS or HAL header, WTF ST???
#define OTP_ADDRESS 0x1FFF7000
#define OTP_SIZE 0x00000400
#define CONFIG_FLAGS_MAGIC 0x2092ED2C
#if 0
static StationData __THIS_STATION__ = {
STATION_DATA_MAGIC,
@ -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() )
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();
bsp_write_station_data(data);
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;
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

View File

@ -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!

View File

@ -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();
}
}

View File

@ -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<TXPacket*>(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()));
#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);
}
else
{
//DBG("RadioManager rejected TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel()));
#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)

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
*/
*/
#include "TXScheduler.hpp"
@ -29,6 +29,7 @@
#include <stdlib.h>
#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,25 +163,34 @@ 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;
}
@ -175,13 +207,21 @@ 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;
}
@ -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;
}

View File

@ -25,10 +25,10 @@
#include "EZRadioPRO.h"
#include "AISChannels.h"
#include "bsp.hpp"
#include "TXErrors.h"
#include <stdio.h>
#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();
}

View File

@ -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;

View File

@ -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 <https://www.gnu.org/licenses/>
*/
#include "bsp.hpp"
#include <stm32l4xx_hal.h>
#include "printf_serial.h"
#include <string.h>
#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

View File

@ -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();
}
}