diff options
author | root <root@ka-ata-killa.panaceas.james.local> | 2021-11-21 17:27:02 +0000 |
---|---|---|
committer | root <root@ka-ata-killa.panaceas.james.local> | 2021-11-21 17:27:02 +0000 |
commit | 64f632692fe2a164830a363f8db158a8a2ae33de (patch) | |
tree | c2106d606b7e355ede93ff2a04848224a480dbc7 | |
download | metric_clock-64f632692fe2a164830a363f8db158a8a2ae33de.tar.gz metric_clock-64f632692fe2a164830a363f8db158a8a2ae33de.tar.bz2 metric_clock-64f632692fe2a164830a363f8db158a8a2ae33de.zip |
first workingish cut
47 files changed, 5626 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..981d79a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "stm32/libopencm3"] + path = stm32/libopencm3 + url = git://git.panaceas.org/stm32/libopencm3 diff --git a/dial/base.jpg b/dial/base.jpg Binary files differnew file mode 100644 index 0000000..adaa1ef --- /dev/null +++ b/dial/base.jpg diff --git a/dial/base.svg b/dial/base.svg new file mode 100644 index 0000000..3866756 --- /dev/null +++ b/dial/base.svg @@ -0,0 +1,851 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="base.svg"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.1123202" + inkscape:cx="478.78127" + inkscape:cy="590.94566" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + inkscape:window-width="3044" + inkscape:window-height="1702" + inkscape:window-x="653" + inkscape:window-y="223" + inkscape:window-maximized="1" + showguides="false" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="image" + style="display:none"> + <image + sodipodi:absref="/root/projects/metric_clock/base.jpg" + xlink:href="base.jpg" + style="fill:#ff0000;stroke:#000000" + y="37.229919" + x="8.6489792" + id="image929" + preserveAspectRatio="none" + height="194.02777" + width="194.02777" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1378" + cx="105.49754" + cy="134.01634" + r="71.176346" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="old pips" + style="display:none"> + <g + id="g1842"> + <g + id="g1141"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1135" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1137" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1147" + transform="rotate(7.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1143" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1145" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1153" + transform="rotate(14.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1149" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1151" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1159" + transform="rotate(21.6,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1155" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1157" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1165" + transform="rotate(28.8,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1161" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1163" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1171" + transform="rotate(36,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1167" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1169" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1177" + transform="rotate(43.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1173" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1175" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1183" + transform="rotate(50.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1179" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1181" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1189" + transform="rotate(57.6,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1185" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1187" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1195" + transform="rotate(64.8,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1191" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1193" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1201" + transform="rotate(72,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1197" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1199" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1207" + transform="rotate(79.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1203" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1205" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1213" + transform="rotate(86.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1209" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1211" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1237" + transform="matrix(-0.06302185,1.0017036,-1.0017036,-0.06302185,246.6788,36.874562)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1233" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1235" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1243" + transform="matrix(-0.18807164,0.98590605,-0.98590605,-0.18807164,257.76399,55.32396)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1239" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1241" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1249" + transform="matrix(-0.31015544,0.95456027,-0.95456027,-0.31015544,266.44943,75.017219)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1245" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1247" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1255" + transform="matrix(-0.42734789,0.90816049,-0.90816049,-0.42734789,272.59816,95.643766)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1251" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1253" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1261" + transform="matrix(-0.53780081,0.84743848,-0.84743848,-0.53780081,276.11322,116.87831)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1257" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1259" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1267" + transform="matrix(-0.6397723,0.77335186,-0.77335186,-0.6397723,276.93917,138.38596)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1263" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1265" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1273" + transform="matrix(-0.73165419,0.68706902,-0.68706902,-0.73165419,275.06298,159.82754)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1269" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1271" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1279" + transform="matrix(-0.81199746,0.58995069,-0.58995069,-0.81199746,270.51424,180.8649)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1275" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1277" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1285" + transform="matrix(-0.87953505,0.48352848,-0.48352848,-0.87953505,263.36469,201.16626)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1281" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1283" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1291" + transform="matrix(-0.93320184,0.36948075,-0.36948075,-0.93320184,253.72709,220.41147)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1287" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1289" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1297" + transform="matrix(-0.97215148,0.24960607,-0.24960607,-0.97215148,241.7534,238.297)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1293" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1295" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1303" + transform="matrix(-0.99576972,0.12579497,-0.12579497,-0.99576972,227.63249,254.5408)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1299" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1301" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + </g> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1845" + cx="105.49754" + cy="134.01634" + r="71.176346" /> + <g + id="g1939" + style="display:inline"> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1933" + cx="105.33971" + cy="134.17418" + r="71.176346" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1935" + cx="105.33971" + cy="134.17418" + r="68.756615" /> + </g> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <g + id="g995" + transform="translate(0.00821436,0.04586345)" + style="stroke:#000000"> + <path + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 142.62011,171.00294 c -0.77532,0.8116 -1.74601,1.45294 -1.69031,2.60136 l -0.0451,12.04127 -1.00434,1.41555 1.36953,1.46493 c 0.73978,-0.78263 1.87134,-1.76247 1.86355,-2.60431 l -0.0436,-12.18219 0.82224,-1.20249 z" + id="path951" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path960" + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 138.45302,178.09954 8.05529,0.0319 0.002,0.12594 c 0,1.11333 -0.76094,2.01586 -1.69962,2.01586 v 0 l -7.44358,-0.0173 -0.59615,-0.002 c 0,-1.11332 0.74339,-2.15445 1.68206,-2.15445 z" + sodipodi:nodetypes="ccccccccc" /> + </g> + <path + id="path1018" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 165.42907,147.14224 c 1.48292,1.79487 1.95406,4.21946 1.25123,6.43907 -0.70283,2.21961 -2.48366,3.93112 -4.72941,4.54532 l -0.41085,-1.88943 c 1.88114,-0.6989 3.18124,-2.4315 3.32643,-4.43302 0.14519,-2.00152 -0.89125,-3.90361 -2.65184,-4.86668 l -0.004,-0.0635 c 1.06407,-0.16125 1.95224,-0.89667 2.30911,-1.912 0.35687,-1.01533 0.12416,-2.14472 -0.60501,-2.93627 l 1.42625,-1.34002 c 1.01902,0.76829 1.62025,1.96881 1.62512,3.245 0.005,1.27619 -0.58718,2.48126 -1.6003,3.25731" + sodipodi:nodetypes="csccsccsccsc" /> + <path + id="path1054" + style="fill:#ff0000;stroke:#000000;stroke-width:0.189676px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 160.27638,119.48712 h 3.39357 l -0.7927,2.0749 h -5.70621 l 4.71175,-11.02413 c 0.46026,-1.02664 0.47591,-1.96296 -0.0376,-2.83449 -0.5135,-0.87153 -1.44963,-1.4065 -2.46119,-1.4065 v -1.96032 c 1.72867,0 3.32844,0.91422 4.20597,2.4036 0.87753,1.48938 0.79014,3.18621 0.0642,4.84389 z" + sodipodi:nodetypes="cccccsccscc" /> + <path + id="path1063" + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 139.20258,92.443022 c 0.0227,1.492933 -0.71046,2.184358 -1.71218,3.088513 l -1.36412,-1.379764 0.91515,-1.290498 c 0.0752,-4.613157 0.0727,-7.122012 0.0727,-11.735567 -0.0227,-1.492933 0.71046,-2.184358 1.71218,-3.088513 l 1.36412,1.379764 -0.91515,1.290498 c -0.0752,4.613157 -0.0727,7.122012 -0.0727,11.735567 z" + sodipodi:nodetypes="ccccccccc" /> + <g + id="g1110" + transform="translate(0.08439634,0.03638421)"> + <path + id="path1066" + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 99.335085,82.703014 c 0.0227,1.49293 -0.71046,2.18436 -1.71218,3.08851 l -1.36412,-1.37976 0.91515,-1.2905 c 0.0752,-4.613159 0.0727,-7.122014 0.0727,-11.735569 -0.0227,-1.492933 0.71046,-2.184358 1.71218,-3.088513 l 1.364125,1.379764 -0.915155,1.290498 c -0.0752,4.613157 -0.0727,7.122012 -0.0727,11.73557 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1104" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.34794,77.22145 c -0.009,-4.008906 -1.45649,-5.885766 -2.94934,-7.436765 -1.49285,1.551 -2.94034,3.427859 -2.94934,7.436765 0.009,4.008906 1.45649,5.885765 2.94934,7.436764 1.49285,-1.551 2.94072,-3.427858 2.94934,-7.436764 z m -7.75346,-10e-7 c 0,-3.970502 1.39203,-7.485929 3.44361,-8.696446 h 2.72102 c 2.05158,1.210517 3.44361,4.725944 3.44361,8.696446 m 0,0 c 0,3.970503 -1.39203,7.48593 -3.44361,8.696447 h -2.72102 c -2.05158,-1.210517 -3.44361,-4.725944 -3.44361,-8.696447" /> + </g> + <path + id="circle1126" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 69.659555,85.08518 -1.894017,-0.0277 c 0.222034,-2.890953 1.399433,-5.625912 3.346761,-7.774126 2.178503,2.403238 3.385124,5.53093 3.385124,8.774604 0,3.243674 -1.061988,6.152795 -3.24049,8.556033 l -1.497126,-1.379597 c 1.712443,-1.977148 2.655035,-4.505188 2.655035,-7.065439 0,-1.819926 -0.484876,-3.663385 -1.407554,-5.296014 -0.732977,1.296964 -1.191703,2.730677 -1.347733,4.212239 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1133" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 72.650668,180.22034 1.894017,0.0277 c -0.222034,2.89095 -1.399433,5.62591 -3.346761,7.77413 -2.178503,-2.40324 -3.385124,-5.53093 -3.385124,-8.77461 0,-3.24367 1.061988,-6.15279 3.24049,-8.55603 l 1.497126,1.3796 c -1.712443,1.97715 -2.655035,4.50519 -2.655035,7.06544 0,1.81992 0.484876,3.66338 1.407554,5.29601 0.732977,-1.29696 1.191703,-2.73068 1.347733,-4.21224 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1322" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 50.287154,117.66409 c 0,2.16984 -1.759002,3.92884 -3.92884,3.92884 v -2.1373 c 0.98944,0 1.791539,-0.8021 1.791539,-1.79154 v -9.54908 c 0,-2.16984 1.759002,-3.92884 3.92884,-3.92884 v 2.1373 c -0.98944,0 -1.791539,0.8021 -1.791539,1.79154 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1349" + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 51.538753,140.65131 h -6.110409 l -0.778053,2.10287 h 3.465667 l -1.624213,3.02055 c -2.095652,3.62916 -1.593366,8.50944 1.333431,12.13361 l 1.546982,-1.28068 c -2.503817,-2.94881 -2.765529,-7.3652 -0.973802,-9.89319 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1367" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.6004,185.91358 c 1.97118,-0.2694 3.9338,0.54911 5.12947,2.13924 1.19567,1.59013 1.43712,3.70284 0.63105,5.52174 -0.80607,1.8189 -2.53341,3.05912 -4.51455,3.24141 l 0.18078,1.96467 c 3.59307,-0.33061 6.43467,-3.18511 6.749,-6.77964 0.31433,-3.59454 -1.9887,-6.89892 -5.46986,-7.84814 l 0.23909,-0.51828 h 3.32706 l 0.77138,-2.12989 h -5.54686 z" + sodipodi:nodetypes="cssccscccccc" /> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1907" + cx="105.33971" + cy="134.17418" + r="71.176346" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1912" + cx="105.33971" + cy="134.17418" + r="68.756615" /> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1916" + cx="105.33971" + cy="134.17418" + r="68.756615" /> + <path + id="path1950" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 36.583092,134.17418 c 0,-1.44015 0.04525,-2.87995 0.135675,-4.31726 l -2.414956,-0.15194 c -0.09361,1.48789 -0.14045,2.97836 -0.14045,4.4692 z m 137.377558,4.31726 c 0.0904,-1.43731 0.13567,-2.87711 0.13567,-4.31726 h 2.41973 c 0,1.49084 -0.0468,2.98131 -0.14045,4.4692 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1957" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 37.125258,125.55669 c 0.180499,-1.42879 0.405847,-2.85157 0.675702,-4.26621 l -2.37687,-0.45342 c -0.279354,1.46443 -0.51263,2.93727 -0.699482,4.41636 z m 135.753202,21.50119 c 0.26983,-1.41464 0.49519,-2.83742 0.67569,-4.26621 l 2.40065,0.30327 c -0.18685,1.47909 -0.42008,2.95194 -0.69948,4.41636 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1959" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 38.743207,117.07511 c 0.358151,-1.39491 0.760043,-2.77822 1.205072,-4.14789 l -2.3013,-0.74774 c -0.460692,1.41786 -0.876725,2.84986 -1.247482,4.29386 z m 131.987933,38.34603 c 0.445,-1.36967 0.84691,-2.75298 1.20506,-4.14789 l 2.34371,0.60177 c -0.37075,1.444 -0.78675,2.87601 -1.24748,4.29386 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1961" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 41.411423,108.86318 c 0.530154,-1.33901 1.102253,-2.66105 1.715437,-3.96414 l -2.189436,-1.03028 c -0.634766,1.34895 -1.226994,2.71751 -1.77581,4.10366 z m 126.141137,54.58614 c 0.61316,-1.30309 1.18527,-2.62513 1.71543,-3.96414 l 2.2498,0.89076 c -0.54881,1.38615 -1.141,2.75473 -1.7758,4.10366 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1963" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 45.087826,101.05043 c 0.693797,-1.262014 1.427079,-2.501921 2.198749,-3.717883 l -2.043045,-1.29656 c -0.798827,1.258751 -1.557913,2.542294 -2.276131,3.848728 z m 118.305014,69.96539 c 0.77165,-1.21598 1.50495,-2.45588 2.19875,-3.71789 l 2.12042,1.16572 c -0.71822,1.30643 -1.47727,2.58999 -2.27613,3.84872 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1965" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 49.714437,93.760055 c 0.846497,-1.165102 1.729401,-2.303331 2.647384,-3.412986 l -1.86443,-1.542401 c -0.950294,1.14871 -1.864262,2.326988 -2.740558,3.533108 z M 158.3176,178.0013 c 0.91796,-1.10967 1.80087,-2.24789 2.64737,-3.413 l 1.95761,1.42228 c -0.8763,1.20612 -1.79023,2.38443 -2.74056,3.53311 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1967" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.218289,87.107043 c 0.985853,-1.049828 2.004448,-2.068419 3.054274,-3.054276 l -1.656418,-1.763909 c -1.086767,1.02054 -2.141211,2.074986 -3.16176,3.161759 z M 152.40686,184.2956 c 1.0498,-0.98587 2.06841,-2.00446 3.05426,-3.05428 l 1.7639,1.65642 c -1.02054,1.08678 -2.07496,2.14125 -3.16176,3.16176 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1969" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 61.512592,81.196297 c 1.10965,-0.91798 2.247882,-1.800882 3.412988,-2.647385 l -1.422277,-1.95761 c -1.206111,0.876293 -2.384393,1.790264 -3.533107,2.740562 z M 145.75384,189.79945 c 1.16508,-0.84651 2.30333,-1.72941 3.41298,-2.64739 l 1.54239,1.86443 c -1.14871,0.9503 -2.32697,1.86431 -3.5331,2.74057 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1971" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 45.087826,101.05043 c 0.693798,-1.262014 1.42708,-2.501921 2.198749,-3.717883 l -2.043044,-1.29656 c -0.798828,1.258751 -1.557914,2.542295 -2.276131,3.848728 z m 118.305014,69.96539 c 0.77165,-1.21598 1.50495,-2.45588 2.19875,-3.71789 l 2.12042,1.16572 c -0.71822,1.30643 -1.47727,2.58999 -2.27613,3.84872 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1973" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 49.714437,93.760055 c 0.846498,-1.165102 1.729401,-2.303331 2.647385,-3.412986 l -1.86443,-1.542401 c -0.950295,1.14871 -1.864262,2.326988 -2.740559,3.533108 z M 158.3176,178.0013 c 0.91796,-1.10967 1.80087,-2.24789 2.64737,-3.413 l 1.95761,1.42228 c -0.8763,1.20612 -1.79023,2.38443 -2.74056,3.53311 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1975" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.218289,87.107043 c 0.985853,-1.049828 2.004449,-2.068419 3.054274,-3.054276 l -1.656418,-1.763909 c -1.086767,1.02054 -2.14121,2.074986 -3.16176,3.161759 z M 152.40686,184.2956 c 1.0498,-0.98587 2.06841,-2.00446 3.05426,-3.05428 l 1.7639,1.65642 c -1.02054,1.08678 -2.07496,2.14125 -3.16175,3.16176 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1977" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 61.512592,81.196297 c 1.109651,-0.91798 2.247883,-1.800882 3.412988,-2.647385 l -1.422276,-1.95761 c -1.206111,0.876293 -2.384394,1.790264 -3.533108,2.740562 z M 145.75384,189.79945 c 1.16508,-0.84651 2.30333,-1.72941 3.41298,-2.64739 l 1.54239,1.86443 c -1.14871,0.9503 -2.32697,1.86431 -3.5331,2.74057 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1979" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 68.49807,76.121052 c 1.215959,-0.771672 2.455868,-1.504949 3.717882,-2.19875 l -1.165711,-2.120429 c -1.306426,0.718215 -2.589969,1.477299 -3.848728,2.276132 z m 69.96539,118.305018 c 1.262,-0.69383 2.50193,-1.42709 3.71789,-2.19876 l 1.29654,2.04305 c -1.25875,0.79883 -2.54227,1.55794 -3.84872,2.27612 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1981" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 76.064565,71.961335 c 1.303083,-0.613184 2.625124,-1.185279 3.964139,-1.715436 l -0.890755,-2.249812 c -1.386145,0.548815 -2.754701,1.14104 -4.103658,1.775812 z M 130.65071,198.10247 c 1.339,-0.53018 2.66105,-1.10226 3.96414,-1.71545 l 1.03027,2.18944 c -1.34896,0.63477 -2.71749,1.22704 -4.10366,1.77581 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1983" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 84.09274,68.782757 c 1.369668,-0.445033 2.75298,-0.846919 4.147889,-1.205075 l -0.60176,-2.34371 c -1.44399,0.370752 -2.87599,0.786787 -4.29386,1.247481 z m 38.34605,131.987933 c 1.39489,-0.35818 2.77822,-0.76006 4.14788,-1.20509 l 0.74773,2.3013 c -1.41787,0.46071 -2.84986,0.87677 -4.29386,1.24748 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1985" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 92.456003,66.635434 c 1.414634,-0.269854 2.837416,-0.495199 4.266212,-0.675701 L 96.41895,63.559079 c -1.47908,0.186853 -2.951926,0.42013 -4.416361,0.699485 z M 113.9572,202.38863 c 1.42878,-0.18052 2.85158,-0.40585 4.26621,-0.67571 l 0.45341,2.37687 c -1.46443,0.27936 -2.93728,0.51268 -4.41636,0.69949 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1987" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 68.498069,76.121052 c 1.21596,-0.771671 2.455869,-1.504949 3.717882,-2.19875 l -1.16571,-2.120428 c -1.306427,0.718214 -2.589971,1.477299 -3.848728,2.276132 z M 138.46346,194.42607 c 1.262,-0.69383 2.50193,-1.42709 3.71789,-2.19876 l 1.29654,2.04305 c -1.25875,0.79883 -2.54227,1.55794 -3.84872,2.27612 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1989" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 76.064564,71.961335 c 1.303084,-0.613183 2.625124,-1.185279 3.96414,-1.715435 l -0.890755,-2.249812 c -1.386145,0.548814 -2.754701,1.14104 -4.103658,1.775811 z M 130.65071,198.10247 c 1.339,-0.53018 2.66105,-1.10226 3.96414,-1.71545 l 1.03027,2.18944 c -1.34896,0.63477 -2.7175,1.22704 -4.10366,1.77581 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1991" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 84.092739,68.782757 c 1.369668,-0.445033 2.752981,-0.846919 4.14789,-1.205075 l -0.601761,-2.34371 c -1.44399,0.370752 -2.875989,0.786788 -4.29386,1.247481 z M 122.43879,200.77069 c 1.39489,-0.35818 2.77822,-0.76006 4.14788,-1.20509 l 0.74773,2.3013 c -1.41787,0.46071 -2.84986,0.87677 -4.29385,1.24749 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1993" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 92.456003,66.635434 c 1.414634,-0.269853 2.837416,-0.495199 4.266211,-0.675701 L 96.41895,63.559079 c -1.47908,0.186853 -2.951927,0.42013 -4.416362,0.699485 z M 113.9572,202.38863 c 1.42878,-0.18052 2.85158,-0.40585 4.26621,-0.67571 l 0.45341,2.37687 c -1.46443,0.27936 -2.93728,0.51268 -4.41636,0.69949 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1995" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.02244,65.553243 c 1.43731,-0.09043 2.87711,-0.135673 4.31726,-0.135676 l 1e-5,-2.419732 c -1.49084,10e-7 -2.9813,0.04684 -4.4692,0.140451 z M 105.3397,202.9308 c 1.44016,-3e-5 2.87997,-0.0453 4.31728,-0.13568 l 0.15192,2.41495 c -1.48789,0.0936 -2.97836,0.14049 -4.46919,0.14045 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1997" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 109.65697,65.553242 c 1.4373,0.09043 2.87143,0.225995 4.30022,0.406491 l 0.30328,-2.40065 c -1.47908,-0.18685 -2.96366,-0.327187 -4.45157,-0.420797 z M 96.722219,202.38864 c 1.428791,0.18047 2.862914,0.31605 4.300231,0.40648 l -0.15194,2.41495 c -1.487908,-0.0936 -2.972488,-0.23389 -4.45157,-0.4208 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1999" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 118.22341,66.635436 c 1.41464,0.269857 2.82046,0.584097 4.21537,0.942245 l 0.60176,-2.343709 c -1.44399,-0.370755 -2.89928,-0.696052 -4.36371,-0.975407 z M 88.240634,200.77069 c 1.394906,0.35812 2.800734,0.67238 4.215371,0.94223 l -0.453419,2.37687 c -1.464437,-0.27934 -2.919738,-0.60461 -4.363716,-0.97541 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2001" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 126.58667,68.782755 c 1.36966,0.44503 2.72501,0.932989 4.06403,1.463142 l 0.89077,-2.249808 c -1.38614,-0.548812 -2.78919,-1.053939 -4.20706,-1.514635 z M 80.028711,198.10247 c 1.339016,0.53013 2.694379,1.01811 4.064034,1.46313 l -0.747739,2.3013 c -1.417873,-0.46069 -2.820944,-0.96578 -4.207068,-1.51463 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2003" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.02244,65.553244 c 1.43731,-0.09043 2.87711,-0.135673 4.31726,-0.135676 l 0,-2.41973 c -1.49083,-1e-6 -2.9813,0.04684 -4.4692,0.140451 z m 4.31726,137.377566 c 1.44016,-4e-5 2.87997,-0.0453 4.31727,-0.13569 l 0.15192,2.41496 c -1.48789,0.0936 -2.97835,0.14048 -4.46918,0.14044 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2005" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 109.65697,65.553243 c 1.4373,0.09043 2.87142,0.225995 4.30022,0.406492 l 0.30328,-2.40065 c -1.47908,-0.186851 -2.96366,-0.327186 -4.45157,-0.420797 z M 96.722218,202.38864 c 1.42879,0.18047 2.862913,0.31605 4.300222,0.40648 l -0.15193,2.41495 c -1.487909,-0.0936 -2.972498,-0.2339 -4.451572,-0.42079 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2007" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 118.2234,66.635437 c 1.41465,0.269857 2.82047,0.584098 4.21538,0.942246 l 0.60176,-2.34371 c -1.44399,-0.370755 -2.89929,-0.69605 -4.36372,-0.975407 z M 88.240632,200.77069 c 1.394906,0.35812 2.800735,0.67238 4.215372,0.94223 l -0.453419,2.37687 c -1.464438,-0.27934 -2.919739,-0.60461 -4.363712,-0.97539 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2009" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 126.58667,68.782756 c 1.36965,0.445031 2.72501,0.93299 4.06403,1.463142 l 0.89077,-2.249808 c -1.38614,-0.548812 -2.78919,-1.053939 -4.20707,-1.514635 z M 80.02871,198.10247 c 1.339016,0.53013 2.694378,1.01811 4.064034,1.46313 l -0.74774,2.3013 c -1.417872,-0.46069 -2.820943,-0.96578 -4.207067,-1.51463 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2011" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 134.61484,71.961338 c 1.30309,0.613185 2.5866,1.267167 3.84861,1.960962 l 1.16572,-2.120423 c -1.30643,-0.718217 -2.63509,-1.395206 -3.98405,-2.029975 z M 72.215945,194.42606 c 1.262036,0.69378 2.54556,1.34774 3.848625,1.96097 l -1.030282,2.18943 c -1.34894,-0.63478 -2.677639,-1.31173 -3.984044,-2.02997 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2013" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 142.18134,76.121053 c 1.21595,0.771669 2.40738,1.581363 3.57248,2.427858 l 1.42229,-1.9576 c -1.20611,-0.87629 -2.43945,-1.71447 -3.69822,-2.513307 z M 64.925576,189.79946 c 1.165117,0.84648 2.356533,1.65618 3.572498,2.42786 l -1.296557,2.04304 c -1.258772,-0.79883 -2.492134,-1.63697 -3.698219,-2.51331 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2015" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 149.16682,81.196301 c 1.10965,0.917986 2.1902,1.870615 3.24003,2.856466 l 1.65641,-1.763908 c -1.08676,-1.020543 -2.20533,-2.006694 -3.35404,-2.956989 z M 58.27256,184.29561 c 1.04984,0.98582 2.13038,1.93847 3.240035,2.85645 l -1.5424,1.86443 c -1.148723,-0.95028 -2.267313,-1.93642 -3.354046,-2.95699 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2017" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 155.46112,87.107042 c 0.98585,1.049822 1.93847,2.130368 2.85646,3.240023 l 1.86444,-1.54239 c -0.95029,-1.148706 -1.93644,-2.267277 -2.95699,-3.354052 z M 52.361822,178.0013 c 0.917996,1.10964 1.870624,2.19021 2.856472,3.24002 l -1.763909,1.65642 c -1.020552,-1.08677 -2.006744,-2.20532 -2.957003,-3.35405 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2019" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 134.61484,71.961339 c 1.30309,0.613185 2.5866,1.267167 3.84861,1.960962 l 1.16571,-2.120426 c -1.30642,-0.718213 -2.63509,-1.395206 -3.98405,-2.029975 z M 72.215941,194.42607 c 1.262041,0.69377 2.54556,1.34774 3.848621,1.96096 l -1.030287,2.18943 c -1.34894,-0.63477 -2.677625,-1.31173 -3.98403,-2.02997 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2021" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 142.18134,76.121055 c 1.21595,0.771669 2.40737,1.581358 3.57248,2.427858 l 1.42229,-1.957599 c -1.20611,-0.876291 -2.43945,-1.71447 -3.69822,-2.513308 z M 64.925576,189.79946 c 1.165116,0.84647 2.356531,1.65618 3.57249,2.42785 l -1.296548,2.04305 c -1.258773,-0.79883 -2.492138,-1.63698 -3.698226,-2.51331 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2023" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 149.16681,81.196298 c 1.10966,0.91799 2.1902,1.87062 3.24003,2.856471 l 1.65642,-1.763909 c -1.08676,-1.020542 -2.20534,-2.006697 -3.35405,-2.956994 z M 58.272559,184.29561 c 1.04984,0.98582 2.130381,1.93847 3.240036,2.85645 l -1.5424,1.86443 c -1.148724,-0.95028 -2.267314,-1.93642 -3.354053,-2.95697 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2025" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 155.46112,87.107044 c 0.98584,1.049817 1.93847,2.130369 2.85646,3.240022 l 1.86444,-1.54239 c -0.95029,-1.148706 -1.93644,-2.267276 -2.957,-3.354056 z M 52.361821,178.0013 c 0.917997,1.10964 1.870624,2.19021 2.856472,3.24002 l -1.763909,1.65642 c -1.020552,-1.08677 -2.006743,-2.20532 -2.957002,-3.35405 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2027" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 160.96497,93.760057 c 0.8465,1.165106 1.65619,2.356531 2.42786,3.572486 l 2.04305,-1.296551 c -0.79883,-1.258756 -1.637,-2.492093 -2.5133,-3.698212 z M 47.286567,171.01581 c 0.7717,1.21596 1.581413,2.40737 2.427872,3.5725 l -1.957609,1.42227 c -0.876278,-1.20611 -1.714503,-2.43944 -2.513299,-3.6982 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2029" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 165.59158,101.05043 c 0.69379,1.26201 1.34778,2.54552 1.96096,3.84861 l 2.18944,-1.03027 c -0.63476,-1.34895 -1.31175,-2.67761 -2.02998,-3.984058 z m -122.46473,62.3989 c 0.613205,1.30308 1.267175,2.58659 1.960973,3.84862 l -2.120423,1.1657 c -0.718231,-1.30643 -1.395258,-2.63508 -2.029978,-3.98406 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2031" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 169.26799,108.86319 c 0.53015,1.33901 1.01811,2.69437 1.46314,4.06403 l 2.30129,-0.74774 c -0.46068,-1.41786 -0.96581,-2.82091 -1.51462,-4.20705 z M 39.948267,155.42116 c 0.44506,1.36964 0.933002,2.72501 1.463159,4.06402 l -2.249811,0.89076 c -0.548833,-1.38614 -1.053984,-2.78919 -1.514632,-4.20706 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2033" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 171.9362,117.07511 c 0.35815,1.3949 0.67238,2.80072 0.94224,4.21536 l 2.37688,-0.4534 c -0.27936,-1.46443 -0.60465,-2.91972 -0.97541,-4.36372 z M 37.800955,147.05789 c 0.269873,1.41463 0.584099,2.82048 0.942254,4.21537 l -2.343712,0.60176 c -0.370761,-1.444 -0.696102,-2.89929 -0.975415,-4.36372 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2035" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 173.55415,125.5567 c 0.1805,1.42878 0.31605,2.8629 0.40648,4.30021 l 2.41497,-0.15192 c -0.0936,-1.4879 -0.23395,-2.97248 -0.4208,-4.45156 z M 36.718762,138.49145 c 0.09045,1.4373 0.225993,2.87145 0.406498,4.30022 l -2.400652,0.30327 c -0.186856,-1.47908 -0.327235,-2.96367 -0.420804,-4.45156 z" + sodipodi:nodetypes="cccccccccc" /> + </g> +</svg> diff --git a/dial/try1.svg b/dial/try1.svg new file mode 100644 index 0000000..9cfb1a7 --- /dev/null +++ b/dial/try1.svg @@ -0,0 +1,860 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="try1.svg"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.74681796" + inkscape:cx="416.08367" + inkscape:cy="907.46405" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + inkscape:window-width="3044" + inkscape:window-height="1702" + inkscape:window-x="651" + inkscape:window-y="199" + inkscape:window-maximized="1" + showguides="false" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="image" + style="display:none"> + <image + sodipodi:absref="/root/projects/metric_clock/base.jpg" + xlink:href="base.jpg" + style="fill:#ff0000;stroke:#000000" + y="37.229919" + x="8.6489792" + id="image929" + preserveAspectRatio="none" + height="194.02777" + width="194.02777" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1378" + cx="105.49754" + cy="134.01634" + r="71.176346" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="old pips" + style="display:none"> + <g + id="g1842"> + <g + id="g1141"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1135" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1137" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1147" + transform="rotate(7.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1143" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1145" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1153" + transform="rotate(14.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1149" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1151" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1159" + transform="rotate(21.6,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1155" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1157" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1165" + transform="rotate(28.8,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1161" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1163" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1171" + transform="rotate(36,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1167" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1169" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1177" + transform="rotate(43.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1173" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1175" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1183" + transform="rotate(50.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1179" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1181" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1189" + transform="rotate(57.6,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1185" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1187" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1195" + transform="rotate(64.8,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1191" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1193" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1201" + transform="rotate(72,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1197" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1199" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1207" + transform="rotate(79.2,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1203" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1205" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1213" + transform="rotate(86.4,105.599,134.19615)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1209" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1211" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1237" + transform="matrix(-0.06302185,1.0017036,-1.0017036,-0.06302185,246.6788,36.874562)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1233" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1235" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1243" + transform="matrix(-0.18807164,0.98590605,-0.98590605,-0.18807164,257.76399,55.32396)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1239" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1241" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1249" + transform="matrix(-0.31015544,0.95456027,-0.95456027,-0.31015544,266.44943,75.017219)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1245" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1247" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1255" + transform="matrix(-0.42734789,0.90816049,-0.90816049,-0.42734789,272.59816,95.643766)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1251" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1253" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1261" + transform="matrix(-0.53780081,0.84743848,-0.84743848,-0.53780081,276.11322,116.87831)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1257" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1259" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1267" + transform="matrix(-0.6397723,0.77335186,-0.77335186,-0.6397723,276.93917,138.38596)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1263" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1265" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1273" + transform="matrix(-0.73165419,0.68706902,-0.68706902,-0.73165419,275.06298,159.82754)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1269" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1271" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1279" + transform="matrix(-0.81199746,0.58995069,-0.58995069,-0.81199746,270.51424,180.8649)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1275" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1277" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1285" + transform="matrix(-0.87953505,0.48352848,-0.48352848,-0.87953505,263.36469,201.16626)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1281" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1283" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1291" + transform="matrix(-0.93320184,0.36948075,-0.36948075,-0.93320184,253.72709,220.41147)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1287" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1289" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1297" + transform="matrix(-0.97215148,0.24960607,-0.24960607,-0.97215148,241.7534,238.297)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1293" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1295" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + <g + id="g1303" + transform="matrix(-0.99576972,0.12579497,-0.12579497,-0.99576972,227.63249,254.5408)"> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1299" + width="3.9854157" + height="2.1983638" + x="103.73463" + y="62.477757" /> + <rect + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="rect1301" + width="3.9854157" + height="2.1983638" + x="103.47796" + y="203.71619" /> + </g> + </g> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1845" + cx="105.49754" + cy="134.01634" + r="71.176346" /> + <g + id="g1939" + style="display:inline"> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.197022;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1933" + cx="105.33971" + cy="134.17418" + r="71.176346" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.190324;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1935" + cx="105.33971" + cy="134.17418" + r="68.756615" /> + </g> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <g + id="g2214" + style="fill:#000000"> + <g + id="g995" + transform="matrix(1.3967804,0,0,1.3967804,-39.841068,-37.660351)" + style="stroke:#000000;fill:#000000"> + <path + style="fill:#000000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 142.62011,171.00294 c -0.77532,0.8116 -1.74601,1.45294 -1.69031,2.60136 l -0.0451,12.04127 -1.00434,1.41555 1.36953,1.46493 c 0.73978,-0.78263 1.87134,-1.76247 1.86355,-2.60431 l -0.0436,-12.18219 0.82224,-1.20249 z" + id="path951" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path960" + style="fill:#000000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 138.45302,178.09954 8.05529,0.0319 0.002,0.12594 c 0,1.11333 -0.76094,2.01586 -1.69962,2.01586 v 0 l -7.44358,-0.0173 -0.59615,-0.002 c 0,-1.11332 0.74339,-2.15445 1.68206,-2.15445 z" + sodipodi:nodetypes="ccccccccc" /> + </g> + <path + id="path1018" + style="fill:#000000;stroke:#000000;stroke-width:0.279356;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 191.21554,167.80098 c 2.07131,2.50704 2.72939,5.89366 1.74769,8.99397 -0.9817,3.10031 -3.46912,5.49091 -6.60594,6.34882 l -0.57387,-2.63912 c 2.62754,-0.97621 4.44349,-3.39627 4.64629,-6.19196 0.2028,-2.79568 -1.24488,-5.45248 -3.70404,-6.79768 l -0.006,-0.0887 c 1.48627,-0.22523 2.72685,-1.25245 3.22532,-2.67064 0.49847,-1.41819 0.17342,-2.9957 -0.84507,-4.10133 l 1.99216,-1.87171 c 1.42335,1.07313 2.26313,2.75 2.26993,4.53255 0.007,1.78256 -0.82016,3.46578 -2.23526,4.54975" + sodipodi:nodetypes="csccsccsccsc" /> + <path + id="path1054" + style="fill:#000000;stroke:#000000;stroke-width:0.264936px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 184.01836,129.17286 h 4.74008 l -1.10723,2.89817 h -7.97032 l 6.58128,-15.39828 c 0.64288,-1.43399 0.66474,-2.74183 -0.0525,-3.95916 -0.71725,-1.21734 -2.02482,-1.96458 -3.43774,-1.96458 v -2.73813 c 2.41457,0 4.6491,1.27696 5.87481,3.3573 1.22572,2.08034 1.10365,4.45043 0.0897,6.76585 z" + sodipodi:nodetypes="cccccsccscc" /> + <path + id="path1063" + style="fill:#000000;stroke:#000000;stroke-width:0.369564px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 154.58289,91.398189 c 0.0317,2.0853 -0.99235,3.051069 -2.39154,4.313975 l -1.90537,-1.927228 1.27826,-1.802542 c 0.10504,-6.443567 0.10155,-9.947887 0.10155,-16.39201 -0.0317,-2.085299 0.99235,-3.051068 2.39154,-4.313974 l 1.90537,1.927227 -1.27826,1.802542 c -0.10504,6.443568 -0.10155,9.947887 -0.10155,16.39201 z" + sodipodi:nodetypes="ccccccccc" /> + <g + id="g1110" + transform="matrix(1.3967804,0,0,1.3967804,-39.734659,-37.673591)" + style="fill:#000000"> + <path + id="path1066" + style="fill:#000000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 99.335085,82.703014 c 0.0227,1.49293 -0.71046,2.18436 -1.71218,3.08851 l -1.36412,-1.37976 0.91515,-1.2905 c 0.0752,-4.613159 0.0727,-7.122014 0.0727,-11.735569 -0.0227,-1.492933 0.71046,-2.184358 1.71218,-3.088513 l 1.364125,1.379764 -0.915155,1.290498 c -0.0752,4.613157 -0.0727,7.122012 -0.0727,11.73557 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1104" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.34794,77.22145 c -0.009,-4.008906 -1.45649,-5.885766 -2.94934,-7.436765 -1.49285,1.551 -2.94034,3.427859 -2.94934,7.436765 0.009,4.008906 1.45649,5.885765 2.94934,7.436764 1.49285,-1.551 2.94072,-3.427858 2.94934,-7.436764 z m -7.75346,-10e-7 c 0,-3.970502 1.39203,-7.485929 3.44361,-8.696446 h 2.72102 c 2.05158,1.210517 3.44361,4.725944 3.44361,8.696446 m 0,0 c 0,3.970503 -1.39203,7.48593 -3.44361,8.696447 h -2.72102 c -2.05158,-1.210517 -3.44361,-4.725944 -3.44361,-8.696447" /> + </g> + <path + id="circle1126" + style="fill:#000000;stroke:#000000;stroke-width:0.279356;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 57.446559,81.1209 -2.645526,-0.03869 c 0.310133,-4.038027 1.954701,-7.858164 4.67469,-10.858747 3.042891,3.356796 4.728275,7.725495 4.728275,12.256195 0,4.5307 -1.483364,8.594103 -4.526253,11.950899 l -2.091156,-1.926994 c 2.391907,-2.761641 3.708501,-6.292758 3.708501,-9.868867 0,-2.542037 -0.677265,-5.116944 -1.966044,-7.397368 -1.023808,1.811574 -1.664547,3.814156 -1.882487,5.883573 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1133" + style="fill:#000000;stroke:#000000;stroke-width:0.279356;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 61.624487,214.00383 2.645526,0.0387 c -0.310133,4.03802 -1.954701,7.85816 -4.67469,10.85875 -3.042891,-3.3568 -4.728275,-7.72549 -4.728275,-12.2562 0,-4.5307 1.483364,-8.5941 4.526253,-11.9509 l 2.091156,1.927 c -2.391907,2.76164 -3.708501,6.29276 -3.708501,9.86887 0,2.54203 0.677266,5.11694 1.966044,7.39736 1.023808,-1.81157 1.664547,-3.81416 1.882487,-5.88357 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1322" + style="fill:#000000;stroke:#000000;stroke-width:0.279356;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 30.387569,126.62648 c 0,3.03079 -2.456939,5.48773 -5.487727,5.48773 v -2.98534 c 1.382031,0 2.502387,-1.12036 2.502387,-2.50239 v -13.33797 c 0,-3.03079 2.456939,-5.48772 5.487727,-5.48772 v 2.98534 c -1.382031,0 -2.502387,1.12035 -2.502387,2.50238 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1349" + style="fill:#000000;stroke:#000000;stroke-width:0.369564px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 32.135778,158.73458 h -8.534899 l -1.08677,2.93725 h 4.840776 l -2.268669,4.21904 c -2.927165,5.06914 -2.225582,11.88582 1.86251,16.94799 l 2.160795,-1.78883 c -3.497283,-4.11884 -3.862837,-10.28756 -1.360188,-13.81861 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1367" + style="fill:#000000;stroke:#000000;stroke-width:0.279356;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 102.06091,221.95603 c 2.7533,-0.37629 5.49465,0.76699 7.16474,2.98805 1.67009,2.22106 2.00734,5.17206 0.88144,7.71266 -1.12591,2.5406 -3.53862,4.27292 -6.30584,4.52754 l 0.25251,2.74421 c 5.01873,-0.46179 8.98782,-4.4489 9.42687,-9.46967 0.43905,-5.02078 -2.77777,-9.63627 -7.64019,-10.96213 l 0.33396,-0.72392 h 4.64717 l 1.07745,-2.97499 h -7.74775 z" + sodipodi:nodetypes="cssccscccccc" /> + </g> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.275196;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1907" + cx="107.2839" + cy="149.68745" + r="99.417725" /> + <circle + style="display:inline;fill:none;stroke:#ff0000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1912" + cx="107.2839" + cy="149.68745" + r="96.037895" /> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1916" + cx="107.2839" + cy="149.68745" + r="96.037895" /> + <path + id="path1963" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 23.12525,103.42085 c 0.969082,-1.76276 1.993316,-3.494636 3.071169,-5.193068 l -2.853685,-1.81101 c -1.115786,1.758199 -2.176062,3.551027 -3.179255,5.375828 z m 165.24612,97.72628 c 1.07783,-1.69845 2.10209,-3.43032 3.07118,-5.19307 l 2.96176,1.62825 c -1.0032,1.8248 -2.06343,3.61765 -3.17926,5.37582 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1965" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 29.587609,93.237795 c 1.182371,-1.627392 2.415594,-3.217247 3.697814,-4.767192 l -2.604199,-2.154395 c -1.327352,1.604495 -2.603965,3.250291 -3.827958,4.934976 z M 181.28238,210.90432 c 1.28219,-1.54997 2.51542,-3.13981 3.69779,-4.76722 l 2.73435,1.98662 c -1.22399,1.68468 -2.50055,3.33052 -3.82796,4.93498 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1967" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 37.275282,83.944998 c 1.37702,-1.466379 2.799773,-2.889127 4.26615,-4.266152 L 39.22778,77.215052 c -1.517975,1.42547 -2.990802,2.8983 -4.416285,4.416283 z M 173.02637,219.69607 c 1.46634,-1.37704 2.88912,-2.79979 4.26613,-4.26616 l 2.46378,2.31366 c -1.42547,1.51799 -2.89826,2.99085 -4.41628,4.41628 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1969" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.067041,75.688984 c 1.549937,-1.282216 3.139797,-2.515436 4.767195,-3.697815 l -1.986609,-2.734352 c -1.684672,1.223989 -3.330473,2.500606 -4.934975,3.827964 z M 163.73356,227.38374 c 1.62737,-1.18239 3.21725,-2.41561 4.76719,-3.69782 l 2.15438,2.6042 c -1.6045,1.32736 -3.25027,2.60403 -4.93497,3.82797 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1979" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.82422,68.599981 c 1.698427,-1.077856 3.430308,-2.102083 5.193064,-3.07117 l -1.628242,-2.961774 c -1.82479,1.003189 -3.617618,2.063462 -5.375828,3.179256 z m 97.72629,165.246129 c 1.76273,-0.96913 3.49464,-1.99333 5.19307,-3.07118 l 1.81098,2.85369 c -1.75819,1.11579 -3.55099,2.1761 -5.37581,3.17924 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1981" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 66.392952,62.78977 c 1.82012,-0.856483 3.666721,-1.655574 5.537031,-2.396087 L 70.685794,57.25119 c -1.93614,0.766574 -3.847712,1.593782 -5.731909,2.480419 z m 76.244858,176.19147 c 1.87029,-0.74055 3.7169,-1.53962 5.53703,-2.39611 l 1.43906,3.05817 c -1.8842,0.88663 -3.79573,1.7139 -5.73191,2.48041 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1983" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 77.606549,58.349995 c 1.913125,-0.621614 3.845309,-1.18296 5.79369,-1.683225 l -0.840527,-3.273648 c -2.016936,0.517859 -4.017126,1.098968 -5.997579,1.742457 z M 131.16756,242.70815 c 1.94836,-0.5003 3.88056,-1.06163 5.79368,-1.68324 l 1.04441,3.21441 c -1.98045,0.64351 -3.98063,1.22465 -5.99758,1.74245 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1985" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 89.288191,55.350656 c 1.975933,-0.376927 3.963247,-0.691684 5.958961,-0.943806 l -0.423594,-3.353186 c -2.06595,0.260992 -4.123193,0.586829 -6.168687,0.977027 z M 119.32064,244.96806 c 1.99569,-0.25215 3.98303,-0.56688 5.95896,-0.94382 l 0.63331,3.31997 c -2.04548,0.3902 -4.10273,0.7161 -6.16868,0.97703 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1995" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.25362,53.839073 c 2.00761,-0.126311 4.01869,-0.189505 6.03027,-0.18951 l 1e-5,-3.379834 c -2.08238,2e-6 -4.16422,0.06543 -6.24249,0.196179 z m 6.03027,191.886277 c 2.01158,-4e-5 4.02268,-0.0633 6.03029,-0.18951 l 0.2122,3.37315 c -2.07826,0.13074 -4.16012,0.19624 -6.24248,0.19618 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1997" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.31416,53.839072 c 2.0076,0.12631 4.01076,0.315665 6.00647,0.567778 l 0.42361,-3.353181 c -2.06595,-0.260988 -4.13958,-0.457008 -6.21786,-0.587761 z M 95.247158,244.96807 c 1.995707,0.25208 3.998862,0.44146 6.006482,0.56777 l -0.21223,3.37315 c -2.078281,-0.13074 -4.151914,-0.32669 -6.217866,-0.58776 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1999" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 125.2796,55.350659 c 1.97594,0.376931 3.93956,0.815855 5.88795,1.316109 l 0.84052,-3.273646 c -2.01693,-0.517864 -4.04965,-0.972232 -6.09514,-1.36243 z M 83.400246,242.70815 c 1.948377,0.50022 3.91201,0.93917 5.887948,1.31609 l -0.633327,3.31997 c -2.045497,-0.39018 -4.078233,-0.84451 -6.095153,-1.36244 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2001" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 136.96124,58.349992 c 1.91311,0.621609 3.80624,1.303181 5.67656,2.043688 l 1.24421,-3.142488 c -1.93614,-0.766569 -3.89589,-1.472121 -5.87634,-2.115612 z M 71.929993,238.98124 c 1.870311,0.74047 3.763456,1.42207 5.676563,2.04367 l -1.044427,3.21441 c -1.980457,-0.64349 -3.940239,-1.34899 -5.87635,-2.11561 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2011" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 148.17483,62.789774 c 1.82013,0.856485 3.61291,1.769955 5.37566,2.739034 l 1.62826,-2.961766 c -1.8248,-1.003191 -3.68065,-1.948796 -5.56485,-2.835429 z M 61.017275,233.8461 c 1.762787,0.96906 3.555588,1.88249 5.375684,2.73904 l -1.439078,3.05816 c -1.884173,-0.88665 -3.740074,-1.8322 -5.564835,-2.83543 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2013" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 158.74357,68.599983 c 1.69841,1.077852 3.36258,2.208817 4.98997,3.391184 l 1.98662,-2.734337 c -1.68467,-1.223985 -3.40737,-2.394738 -5.1656,-3.510538 z M 50.83423,227.38375 c 1.627413,1.18235 3.291559,2.31332 4.989995,3.39119 l -1.811005,2.85368 c -1.758228,-1.11579 -3.480964,-2.28649 -5.1656,-3.51054 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2015" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 168.50075,75.68899 c 1.54994,1.282225 3.05923,2.612838 4.52561,3.989856 L 175.34,77.215053 c -1.51797,-1.425474 -3.08036,-2.80291 -4.68486,-4.130264 z M 41.541428,219.69608 c 1.466396,1.37698 2.975673,2.70762 4.525617,3.98984 l -2.154394,2.6042 c -1.604514,-1.32734 -3.166938,-2.70476 -4.684866,-4.13027 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2017" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 177.2925,83.944997 c 1.37702,1.466371 2.70762,2.975656 3.98985,4.525601 l 2.60421,-2.154381 c -1.32734,-1.60449 -2.70478,-3.166888 -4.13026,-4.684874 z M 33.285425,210.90432 c 1.282238,1.54992 2.612851,3.05924 3.989864,4.52559 l -2.463794,2.31366 c -1.425487,-1.51798 -2.80298,-3.08035 -4.130284,-4.68487 z" + sodipodi:nodetypes="cccccccccc" /> + <g + id="g2198" + style="fill:#000000"> + <path + id="path1950" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 11.246004,149.68745 c 0,-2.01157 0.0632,-4.02265 0.189508,-6.03026 l -3.3731631,-0.21223 c -0.1307527,2.07826 -0.1961779,4.16012 -0.1961779,6.24249 z m 191.886276,6.03027 c 0.12627,-2.00761 0.18951,-4.01869 0.18951,-6.03027 h 3.37983 c 0,2.08238 -0.0654,4.16424 -0.19618,6.24249 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1957" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 12.003291,137.65071 c 0.252117,-1.9957 0.566879,-3.98302 0.943807,-5.95896 l -3.3199654,-0.63332 c -0.3901962,2.04548 -0.7160315,4.10272 -0.9770227,6.16868 z M 201.6207,167.68315 c 0.3769,-1.97594 0.69167,-3.96325 0.94379,-5.95896 l 3.35318,0.42361 c -0.26098,2.06596 -0.58676,4.12321 -0.97702,6.16868 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1959" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 14.26321,125.80381 c 0.500258,-1.94839 1.061613,-3.88057 1.683221,-5.79369 l -3.214411,-1.04443 c -0.643485,1.98044 -1.224592,3.98063 -1.742458,5.99758 z m 184.35816,53.56098 c 0.62157,-1.91313 1.18295,-3.84531 1.6832,-5.79369 l 3.27365,0.84054 c -0.51786,2.01695 -1.09892,4.01715 -1.74246,5.99758 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1961" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 17.990122,114.33354 c 0.740509,-1.8703 1.539605,-3.7169 2.396089,-5.53703 l -3.058162,-1.43907 c -0.886628,1.88418 -1.713841,3.79576 -2.480416,5.73191 z m 176.191468,76.24485 c 0.85645,-1.82013 1.65556,-3.66673 2.39608,-5.53703 l 3.14248,1.2442 c -0.76657,1.93614 -1.59373,3.84775 -2.48041,5.73191 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1971" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 23.12525,103.42085 c 0.969083,-1.76276 1.993317,-3.494636 3.071169,-5.193068 l -2.853684,-1.81101 C 22.226948,98.174971 21.166672,99.9678 20.16348,101.7926 Z m 165.24612,97.72628 c 1.07783,-1.69845 2.10209,-3.43032 3.07118,-5.19307 l 2.96176,1.62825 c -1.0032,1.8248 -2.06343,3.61765 -3.17926,5.37582 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1973" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 29.587609,93.237795 c 1.182372,-1.627392 2.415594,-3.217247 3.697816,-4.767192 l -2.6042,-2.154395 c -1.327353,1.604495 -2.603964,3.250291 -3.827959,4.934976 z M 181.28238,210.90432 c 1.28219,-1.54997 2.51542,-3.13981 3.69779,-4.76722 l 2.73435,1.98662 c -1.22399,1.68468 -2.50055,3.33052 -3.82796,4.93498 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1975" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 37.275282,83.944998 c 1.37702,-1.466379 2.799775,-2.889127 4.26615,-4.266152 L 39.22778,77.215052 c -1.517975,1.42547 -2.990801,2.8983 -4.416285,4.416283 z M 173.02637,219.69607 c 1.46634,-1.37704 2.88912,-2.79979 4.26613,-4.26616 l 2.46378,2.31366 c -1.42547,1.51799 -2.89826,2.99085 -4.41627,4.41628 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1977" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.067041,75.688984 c 1.549939,-1.282216 3.139799,-2.515436 4.767195,-3.697815 l -1.986608,-2.734352 c -1.684672,1.223989 -3.330474,2.500606 -4.934976,3.827964 z M 163.73356,227.38374 c 1.62737,-1.18239 3.21725,-2.41561 4.76719,-3.69782 l 2.15438,2.6042 c -1.6045,1.32736 -3.25027,2.60403 -4.93497,3.82797 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1987" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.824218,68.599981 c 1.698429,-1.077854 3.43031,-2.102083 5.193065,-3.07117 l -1.628241,-2.961773 c -1.824792,1.003188 -3.617621,2.063463 -5.375828,3.179257 z M 153.55051,233.84611 c 1.76273,-0.96913 3.49464,-1.99333 5.19307,-3.07118 l 1.81098,2.85369 c -1.75819,1.11579 -3.55099,2.1761 -5.37581,3.17924 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1989" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 66.39295,62.78977 c 1.820122,-0.856482 3.666722,-1.655574 5.537033,-2.396086 l -1.244189,-3.142493 c -1.93614,0.766573 -3.847712,1.593782 -5.731909,2.480418 z m 76.24486,176.19147 c 1.87029,-0.74055 3.7169,-1.53962 5.53703,-2.39611 l 1.43906,3.05817 c -1.8842,0.88663 -3.79575,1.7139 -5.73191,2.48041 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1991" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 77.606548,58.349995 c 1.913125,-0.621614 3.84531,-1.18296 5.793691,-1.683225 l -0.840528,-3.273648 c -2.016937,0.517859 -4.017125,1.09897 -5.997579,1.742457 z M 131.16756,242.70815 c 1.94836,-0.5003 3.88056,-1.06163 5.79368,-1.68324 l 1.04441,3.21441 c -1.98045,0.64351 -3.98063,1.22465 -5.99756,1.74247 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1993" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 89.288191,55.350656 c 1.975933,-0.376925 3.963247,-0.691684 5.95896,-0.943806 l -0.423593,-3.353186 c -2.06595,0.260992 -4.123194,0.586829 -6.168688,0.977027 z M 119.32064,244.96806 c 1.99569,-0.25215 3.98303,-0.56688 5.95896,-0.94382 l 0.63331,3.31997 c -2.04548,0.3902 -4.10273,0.7161 -6.16868,0.97703 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2003" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.25362,53.839074 c 2.00761,-0.12631 4.01869,-0.189505 6.03027,-0.189509 v -3.379832 c -2.08237,-1e-6 -4.16423,0.06543 -6.24249,0.19618 z m 6.03027,191.886296 c 2.01158,-6e-5 4.02268,-0.0633 6.03027,-0.18953 l 0.2122,3.37317 c -2.07825,0.13073 -4.1601,0.19622 -6.24246,0.19616 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2005" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.31416,53.839073 c 2.0076,0.126311 4.01075,0.315665 6.00647,0.56778 l 0.42361,-3.353181 c -2.06595,-0.26099 -4.13958,-0.457007 -6.21786,-0.587761 z M 95.247156,244.96807 c 1.995706,0.25208 3.998861,0.44146 6.006464,0.56777 l -0.21221,3.37315 c -2.078283,-0.13074 -4.151928,-0.32671 -6.217869,-0.58775 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2007" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 125.27959,55.35066 c 1.97595,0.376931 3.93957,0.815857 5.88796,1.316111 l 0.84052,-3.273648 c -2.01693,-0.517863 -4.04967,-0.972229 -6.09516,-1.362429 z M 83.400243,242.70815 c 1.948378,0.50022 3.912012,0.93917 5.887949,1.31609 l -0.633327,3.31997 c -2.045498,-0.39018 -4.078234,-0.84451 -6.095147,-1.36241 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2009" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 136.96124,58.349993 c 1.9131,0.621611 3.80624,1.303183 5.67656,2.043689 l 1.24421,-3.142488 c -1.93614,-0.76657 -3.89589,-1.472122 -5.87636,-2.115613 z M 71.929992,238.98124 c 1.870311,0.74047 3.763454,1.42207 5.676563,2.04367 l -1.044429,3.21441 c -1.980456,-0.64349 -3.940238,-1.34899 -5.876349,-2.11561 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2019" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 148.17483,62.789776 c 1.82013,0.856485 3.61291,1.769954 5.37566,2.739033 l 1.62824,-2.961769 c -1.82478,-1.003186 -3.68064,-1.948797 -5.56484,-2.83543 z M 61.017269,233.84611 c 1.762794,0.96905 3.555588,1.8825 5.375678,2.73903 l -1.439084,3.05816 c -1.884173,-0.88664 -3.740054,-1.8322 -5.564815,-2.83543 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2021" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 158.74357,68.599986 c 1.69841,1.077852 3.36256,2.20881 4.98997,3.391184 l 1.98662,-2.734336 c -1.68467,-1.223986 -3.40737,-2.394738 -5.1656,-3.510539 z M 50.83423,227.38375 c 1.627411,1.18234 3.291556,2.31332 4.989984,3.39118 l -1.810993,2.85369 c -1.758229,-1.11579 -3.480969,-2.2865 -5.165609,-3.51054 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2023" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 168.50073,75.688986 c 1.54996,1.28223 3.05923,2.612845 4.52561,3.989862 L 175.34,77.215055 c -1.51797,-1.425473 -3.08038,-2.802915 -4.68487,-4.130271 z M 41.541426,219.69608 c 1.466396,1.37698 2.975675,2.70762 4.525619,3.98984 l -2.154394,2.6042 c -1.604515,-1.32734 -3.16694,-2.70476 -4.684876,-4.13024 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2025" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 177.2925,83.945 c 1.37701,1.466364 2.70762,2.975657 3.98985,4.525599 l 2.60421,-2.15438 c -1.32734,-1.60449 -2.70478,-3.166887 -4.13028,-4.68488 z M 33.285423,210.90432 c 1.28224,1.54992 2.612851,3.05924 3.989864,4.52559 l -2.463793,2.31366 c -1.425487,-1.51798 -2.802979,-3.08035 -4.130283,-4.68487 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2027" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 184.98017,93.237798 c 1.18238,1.627397 2.31334,3.291556 3.39119,4.989978 l 2.85369,-1.810997 c -1.11579,-1.758205 -2.28653,-3.480906 -3.51053,-5.16559 z M 26.196408,201.14712 c 1.077895,1.69843 2.208887,3.36257 3.391204,4.99 l -2.73435,1.9866 c -1.223968,-1.68467 -2.394784,-3.40737 -3.510527,-5.16558 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2029" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 191.44253,103.42085 c 0.96907,1.76275 1.88255,3.55553 2.73903,5.37566 l 3.05817,-1.43906 c -0.88662,-1.88419 -1.83223,-3.74003 -2.83544,-5.56485 z M 20.386197,190.57841 c 0.856513,1.82012 1.769965,3.6129 2.739048,5.37568 l -2.961765,1.62822 c -1.003211,-1.82479 -1.948869,-3.68063 -2.835433,-5.56485 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2031" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 196.57767,114.33356 c 0.7405,1.8703 1.42207,3.76344 2.04368,5.67656 l 3.2144,-1.04443 c -0.64347,-1.98044 -1.34902,-3.94019 -2.11559,-5.87633 z M 15.946414,179.36482 c 0.621651,1.91308 1.303199,3.80624 2.043712,5.67654 l -3.142492,1.2442 c -0.766599,-1.93614 -1.472184,-3.89589 -2.115608,-5.87634 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2033" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 200.30457,125.80381 c 0.50026,1.94837 0.93917,3.91199 1.3161,5.88793 l 3.31998,-0.6333 c -0.3902,-2.04549 -0.84456,-4.07821 -1.36243,-6.09516 z M 12.947091,167.68317 c 0.376953,1.97592 0.815858,3.93959 1.316122,5.88794 l -3.273651,0.84053 c -0.517872,-2.01695 -0.972302,-4.04967 -1.3624406,-6.09516 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2035" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.265841;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 202.56449,137.65073 c 0.25212,1.99569 0.44146,3.99884 0.56777,6.00644 l 3.37318,-0.21219 c -0.13074,-2.07827 -0.32678,-4.15191 -0.58777,-6.21786 z m -191.128985,18.067 c 0.126339,2.00759 0.315663,4.01079 0.567789,6.00646 l -3.3531841,0.42361 c -0.2609968,-2.06595 -0.4570755,-4.1396 -0.5877708,-6.21786 z" + sodipodi:nodetypes="cccccccccc" /> + </g> + </g> +</svg> diff --git a/dial/try2.svg b/dial/try2.svg new file mode 100644 index 0000000..fd61d07 --- /dev/null +++ b/dial/try2.svg @@ -0,0 +1,299 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="try2.svg"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.9872718" + inkscape:cx="445.90903" + inkscape:cy="522.79404" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + inkscape:window-width="3926" + inkscape:window-height="2029" + inkscape:window-x="-94" + inkscape:window-y="194" + inkscape:window-maximized="1" + showguides="false" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="image" + style="display:none"> + <image + sodipodi:absref="/root/projects/metric_clock/base.jpg" + xlink:href="base.jpg" + style="fill:#ff0000;stroke:#000000" + y="37.184856" + x="3.8290849" + id="image929" + preserveAspectRatio="none" + height="194.02777" + width="194.02777" /> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1916" + cx="100.63864" + cy="134.26129" + r="68.959427" /> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1907" + cx="100.63864" + cy="134.26129" + r="71.386292" /> + <g + id="g2198" + style="fill:#ff0000;stroke-width:0.2785345;stroke-miterlimit:4;stroke-dasharray:none" + transform="matrix(0.71804391,0,0,0.71804391,23.604096,26.779127)"> + <path + id="path1950" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 11.246004,149.68745 c 0,-2.01157 0.0632,-4.02265 0.189508,-6.03026 l -3.3731631,-0.21223 c -0.1307527,2.07826 -0.1961779,4.16012 -0.1961779,6.24249 z m 191.886276,6.03027 c 0.12627,-2.00761 0.18951,-4.01869 0.18951,-6.03027 h 3.37983 c 0,2.08238 -0.0654,4.16424 -0.19618,6.24249 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1957" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 12.003291,137.65071 c 0.252117,-1.9957 0.566879,-3.98302 0.943807,-5.95896 l -3.3199654,-0.63332 c -0.3901962,2.04548 -0.7160315,4.10272 -0.9770227,6.16868 z M 201.6207,167.68315 c 0.3769,-1.97594 0.69167,-3.96325 0.94379,-5.95896 l 3.35318,0.42361 c -0.26098,2.06596 -0.58676,4.12321 -0.97702,6.16868 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1959" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 14.26321,125.80381 c 0.500258,-1.94839 1.061613,-3.88057 1.683221,-5.79369 l -3.214411,-1.04443 c -0.643485,1.98044 -1.224592,3.98063 -1.742458,5.99758 z m 184.35816,53.56098 c 0.62157,-1.91313 1.18295,-3.84531 1.6832,-5.79369 l 3.27365,0.84054 c -0.51786,2.01695 -1.09892,4.01715 -1.74246,5.99758 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1961" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 17.990122,114.33354 c 0.740509,-1.8703 1.539605,-3.7169 2.396089,-5.53703 l -3.058162,-1.43907 c -0.886628,1.88418 -1.713841,3.79576 -2.480416,5.73191 z m 176.191468,76.24485 c 0.85645,-1.82013 1.65556,-3.66673 2.39608,-5.53703 l 3.14248,1.2442 c -0.76657,1.93614 -1.59373,3.84775 -2.48041,5.73191 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1971" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 23.12525,103.42085 c 0.969083,-1.76276 1.993317,-3.494636 3.071169,-5.193068 l -2.853684,-1.81101 C 22.226948,98.174971 21.166672,99.9678 20.16348,101.7926 Z m 165.24612,97.72628 c 1.07783,-1.69845 2.10209,-3.43032 3.07118,-5.19307 l 2.96176,1.62825 c -1.0032,1.8248 -2.06343,3.61765 -3.17926,5.37582 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1973" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 29.587609,93.237795 c 1.182372,-1.627392 2.415594,-3.217247 3.697816,-4.767192 l -2.6042,-2.154395 c -1.327353,1.604495 -2.603964,3.250291 -3.827959,4.934976 z M 181.28238,210.90432 c 1.28219,-1.54997 2.51542,-3.13981 3.69779,-4.76722 l 2.73435,1.98662 c -1.22399,1.68468 -2.50055,3.33052 -3.82796,4.93498 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1975" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 37.275282,83.944998 c 1.37702,-1.466379 2.799775,-2.889127 4.26615,-4.266152 L 39.22778,77.215052 c -1.517975,1.42547 -2.990801,2.8983 -4.416285,4.416283 z M 173.02637,219.69607 c 1.46634,-1.37704 2.88912,-2.79979 4.26613,-4.26616 l 2.46378,2.31366 c -1.42547,1.51799 -2.89826,2.99085 -4.41627,4.41628 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1977" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.067041,75.688984 c 1.549939,-1.282216 3.139799,-2.515436 4.767195,-3.697815 l -1.986608,-2.734352 c -1.684672,1.223989 -3.330474,2.500606 -4.934976,3.827964 z M 163.73356,227.38374 c 1.62737,-1.18239 3.21725,-2.41561 4.76719,-3.69782 l 2.15438,2.6042 c -1.6045,1.32736 -3.25027,2.60403 -4.93497,3.82797 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1987" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.824218,68.599981 c 1.698429,-1.077854 3.43031,-2.102083 5.193065,-3.07117 l -1.628241,-2.961773 c -1.824792,1.003188 -3.617621,2.063463 -5.375828,3.179257 z M 153.55051,233.84611 c 1.76273,-0.96913 3.49464,-1.99333 5.19307,-3.07118 l 1.81098,2.85369 c -1.75819,1.11579 -3.55099,2.1761 -5.37581,3.17924 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1989" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 66.39295,62.78977 c 1.820122,-0.856482 3.666722,-1.655574 5.537033,-2.396086 l -1.244189,-3.142493 c -1.93614,0.766573 -3.847712,1.593782 -5.731909,2.480418 z m 76.24486,176.19147 c 1.87029,-0.74055 3.7169,-1.53962 5.53703,-2.39611 l 1.43906,3.05817 c -1.8842,0.88663 -3.79575,1.7139 -5.73191,2.48041 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1991" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 77.606548,58.349995 c 1.913125,-0.621614 3.84531,-1.18296 5.793691,-1.683225 l -0.840528,-3.273648 c -2.016937,0.517859 -4.017125,1.09897 -5.997579,1.742457 z M 131.16756,242.70815 c 1.94836,-0.5003 3.88056,-1.06163 5.79368,-1.68324 l 1.04441,3.21441 c -1.98045,0.64351 -3.98063,1.22465 -5.99756,1.74247 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1993" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 89.288191,55.350656 c 1.975933,-0.376925 3.963247,-0.691684 5.95896,-0.943806 l -0.423593,-3.353186 c -2.06595,0.260992 -4.123194,0.586829 -6.168688,0.977027 z M 119.32064,244.96806 c 1.99569,-0.25215 3.98303,-0.56688 5.95896,-0.94382 l 0.63331,3.31997 c -2.04548,0.3902 -4.10273,0.7161 -6.16868,0.97703 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2003" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.25362,53.839074 c 2.00761,-0.12631 4.01869,-0.189505 6.03027,-0.189509 v -3.379832 c -2.08237,-1e-6 -4.16423,0.06543 -6.24249,0.19618 z m 6.03027,191.886296 c 2.01158,-6e-5 4.02268,-0.0633 6.03027,-0.18953 l 0.2122,3.37317 c -2.07825,0.13073 -4.1601,0.19622 -6.24246,0.19616 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2005" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.31416,53.839073 c 2.0076,0.126311 4.01075,0.315665 6.00647,0.56778 l 0.42361,-3.353181 c -2.06595,-0.26099 -4.13958,-0.457007 -6.21786,-0.587761 z M 95.247156,244.96807 c 1.995706,0.25208 3.998861,0.44146 6.006464,0.56777 l -0.21221,3.37315 c -2.078283,-0.13074 -4.151928,-0.32671 -6.217869,-0.58775 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2007" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 125.27959,55.35066 c 1.97595,0.376931 3.93957,0.815857 5.88796,1.316111 l 0.84052,-3.273648 c -2.01693,-0.517863 -4.04967,-0.972229 -6.09516,-1.362429 z M 83.400243,242.70815 c 1.948378,0.50022 3.912012,0.93917 5.887949,1.31609 l -0.633327,3.31997 c -2.045498,-0.39018 -4.078234,-0.84451 -6.095147,-1.36241 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2009" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 136.96124,58.349993 c 1.9131,0.621611 3.80624,1.303183 5.67656,2.043689 l 1.24421,-3.142488 c -1.93614,-0.76657 -3.89589,-1.472122 -5.87636,-2.115613 z M 71.929992,238.98124 c 1.870311,0.74047 3.763454,1.42207 5.676563,2.04367 l -1.044429,3.21441 c -1.980456,-0.64349 -3.940238,-1.34899 -5.876349,-2.11561 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2019" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 148.17483,62.789776 c 1.82013,0.856485 3.61291,1.769954 5.37566,2.739033 l 1.62824,-2.961769 c -1.82478,-1.003186 -3.68064,-1.948797 -5.56484,-2.83543 z M 61.017269,233.84611 c 1.762794,0.96905 3.555588,1.8825 5.375678,2.73903 l -1.439084,3.05816 c -1.884173,-0.88664 -3.740054,-1.8322 -5.564815,-2.83543 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2021" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 158.74357,68.599986 c 1.69841,1.077852 3.36256,2.20881 4.98997,3.391184 l 1.98662,-2.734336 c -1.68467,-1.223986 -3.40737,-2.394738 -5.1656,-3.510539 z M 50.83423,227.38375 c 1.627411,1.18234 3.291556,2.31332 4.989984,3.39118 l -1.810993,2.85369 c -1.758229,-1.11579 -3.480969,-2.2865 -5.165609,-3.51054 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2023" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 168.50073,75.688986 c 1.54996,1.28223 3.05923,2.612845 4.52561,3.989862 L 175.34,77.215055 c -1.51797,-1.425473 -3.08038,-2.802915 -4.68487,-4.130271 z M 41.541426,219.69608 c 1.466396,1.37698 2.975675,2.70762 4.525619,3.98984 l -2.154394,2.6042 c -1.604515,-1.32734 -3.16694,-2.70476 -4.684876,-4.13024 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2025" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 177.2925,83.945 c 1.37701,1.466364 2.70762,2.975657 3.98985,4.525599 l 2.60421,-2.15438 c -1.32734,-1.60449 -2.70478,-3.166887 -4.13028,-4.68488 z M 33.285423,210.90432 c 1.28224,1.54992 2.612851,3.05924 3.989864,4.52559 l -2.463793,2.31366 c -1.425487,-1.51798 -2.802979,-3.08035 -4.130283,-4.68487 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2027" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 184.98017,93.237798 c 1.18238,1.627397 2.31334,3.291556 3.39119,4.989978 l 2.85369,-1.810997 c -1.11579,-1.758205 -2.28653,-3.480906 -3.51053,-5.16559 z M 26.196408,201.14712 c 1.077895,1.69843 2.208887,3.36257 3.391204,4.99 l -2.73435,1.9866 c -1.223968,-1.68467 -2.394784,-3.40737 -3.510527,-5.16558 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2029" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 191.44253,103.42085 c 0.96907,1.76275 1.88255,3.55553 2.73903,5.37566 l 3.05817,-1.43906 c -0.88662,-1.88419 -1.83223,-3.74003 -2.83544,-5.56485 z M 20.386197,190.57841 c 0.856513,1.82012 1.769965,3.6129 2.739048,5.37568 l -2.961765,1.62822 c -1.003211,-1.82479 -1.948869,-3.68063 -2.835433,-5.56485 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2031" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 196.57767,114.33356 c 0.7405,1.8703 1.42207,3.76344 2.04368,5.67656 l 3.2144,-1.04443 c -0.64347,-1.98044 -1.34902,-3.94019 -2.11559,-5.87633 z M 15.946414,179.36482 c 0.621651,1.91308 1.303199,3.80624 2.043712,5.67654 l -3.142492,1.2442 c -0.766599,-1.93614 -1.472184,-3.89589 -2.115608,-5.87634 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2033" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 200.30457,125.80381 c 0.50026,1.94837 0.93917,3.91199 1.3161,5.88793 l 3.31998,-0.6333 c -0.3902,-2.04549 -0.84456,-4.07821 -1.36243,-6.09516 z M 12.947091,167.68317 c 0.376953,1.97592 0.815858,3.93959 1.316122,5.88794 l -3.273651,0.84053 c -0.517872,-2.01695 -0.972302,-4.04967 -1.3624406,-6.09516 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2035" + style="display:inline;fill:#ff0000;stroke:#000000;stroke-width:0.2785345;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 202.56449,137.65073 c 0.25212,1.99569 0.44146,3.99884 0.56777,6.00644 l 3.37318,-0.21219 c -0.13074,-2.07827 -0.32678,-4.15191 -0.58777,-6.21786 z m -191.128985,18.067 c 0.126339,2.00759 0.315663,4.01079 0.567789,6.00646 l -3.3531841,0.42361 c -0.2609968,-2.06595 -0.4570755,-4.1396 -0.5877708,-6.21786 z" + sodipodi:nodetypes="cccccccccc" /> + </g> + <path + id="path1322" + style="fill:#ff0000;stroke:#800080;stroke-width:0.20059;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -9.1630385,117.43187 c 0.915852,1.97414 0.05794,4.31695 -1.9162025,5.2328 l -0.902116,-1.94454 c 0.900203,-0.41762 1.291407,-1.48594 0.873781,-2.38614 l -4.030503,-8.68785 c -0.915851,-1.97414 -0.05793,-4.31694 1.916207,-5.23279 l 0.902116,1.94454 c -0.900203,0.41762 -1.291411,1.48593 -0.873785,2.38613 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path2891" + style="fill:#ff0000;stroke:#000000;stroke-width:0.20059;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -21.026462,118.153 c 0,2.17624 -1.76419,3.94043 -3.940429,3.94043 v -2.1436 c 0.992359,0 1.796824,-0.80447 1.796824,-1.79683 v -9.57725 c 0,-2.17624 1.76419,-3.94042 3.940429,-3.94042 v 2.1436 c -0.992359,0 -1.796824,0.80446 -1.796824,1.79682 z" + sodipodi:nodetypes="ccccccccc" /> + <g + id="g3120" + style="fill:#ff0000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none"> + <path + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 138.03726,171.24469 c -0.77761,0.81399 -1.75116,1.45722 -1.6953,2.60903 l -0.0452,12.07679 -1.00731,1.41973 1.37357,1.46925 c 0.74197,-0.78494 1.87686,-1.76767 1.86905,-2.612 l -0.0437,-12.21812 0.82467,-1.20604 z" + id="path951" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path960" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 133.85787,178.36222 8.07906,0.032 0.002,0.12631 c 0,1.11661 -0.76318,2.0218 -1.70463,2.0218 v 0 l -7.46554,-0.0173 -0.59791,-0.002 c 0,-1.11661 0.74559,-2.16081 1.68702,-2.16081 z" + sodipodi:nodetypes="ccccccccc" /> + </g> + <path + id="path1018" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 160.90525,147.2676 c 1.48729,1.80016 1.95982,4.23191 1.25492,6.45806 -0.70491,2.22616 -2.49098,3.94272 -4.74336,4.55874 l -0.41206,-1.89501 c 1.88669,-0.70096 3.19062,-2.43867 3.33624,-4.4461 0.14562,-2.00742 -0.89388,-3.91512 -2.65966,-4.88103 l -0.004,-0.0637 c 1.06721,-0.16173 1.958,-0.89931 2.31592,-1.91764 0.35792,-1.01832 0.12452,-2.15104 -0.6068,-2.94493 l 1.43046,-1.34397 c 1.02203,0.77055 1.62503,1.97462 1.62991,3.25457 0.005,1.27995 -0.58891,2.48858 -1.60502,3.26692" + sodipodi:nodetypes="csccsccsccsc" /> + <path + id="path1054" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 155.73736,119.53091 h 3.40358 l -0.79504,2.08102 h -5.72304 l 4.72565,-11.05665 c 0.46162,-1.02966 0.47732,-1.96875 -0.0377,-2.84285 -0.51502,-0.8741 -1.45391,-1.41065 -2.46845,-1.41065 v -1.9661 c 1.73376,0 3.33826,0.91691 4.21837,2.41069 0.88012,1.49378 0.79247,3.1956 0.0644,4.85818 z" + sodipodi:nodetypes="cccccsccscc" /> + <path + id="path1063" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 134.6014,92.40704 c 0.0228,1.497337 -0.71255,2.190802 -1.71723,3.097623 l -1.36814,-1.383834 0.91785,-1.294304 c 0.0754,-4.626764 0.0729,-7.14302 0.0729,-11.770183 -0.0228,-1.497336 0.71255,-2.190801 1.71723,-3.097623 l 1.36814,1.383834 -0.91784,1.294304 c -0.0754,4.626765 -0.0729,7.14302 -0.0729,11.770183 z" + sodipodi:nodetypes="ccccccccc" /> + <g + id="g1110" + transform="matrix(1.0029497,0,0,1.0029497,-4.9271339,-0.27216559)" + style="fill:#ff0000;stroke-width:0.199412;stroke-miterlimit:4;stroke-dasharray:none"> + <path + id="path1066" + style="fill:#ff0000;stroke:#000000;stroke-width:0.199412;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 99.335085,82.703014 c 0.0227,1.49293 -0.71046,2.18436 -1.71218,3.08851 l -1.36412,-1.37976 0.91515,-1.2905 c 0.0752,-4.613159 0.0727,-7.122014 0.0727,-11.735569 -0.0227,-1.492933 0.71046,-2.184358 1.71218,-3.088513 l 1.364125,1.379764 -0.915155,1.290498 c -0.0752,4.613157 -0.0727,7.122012 -0.0727,11.73557 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1104" + style="fill:#ff0000;stroke:#000000;stroke-width:0.199412;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.34794,77.22145 c -0.009,-4.008906 -1.45649,-5.885766 -2.94934,-7.436765 -1.49285,1.551 -2.94034,3.427859 -2.94934,7.436765 0.009,4.008906 1.45649,5.885765 2.94934,7.436764 1.49285,-1.551 2.94072,-3.427858 2.94934,-7.436764 z m -7.75346,-10e-7 c 0,-3.970502 1.39203,-7.485929 3.44361,-8.696446 h 2.72102 c 2.05158,1.210517 3.44361,4.725944 3.44361,8.696446 m 0,0 c 0,3.970503 -1.39203,7.48593 -3.44361,8.696447 h -2.72102 c -2.05158,-1.210517 -3.44361,-4.725944 -3.44361,-8.696447" /> + </g> + <path + id="circle1126" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 64.853248,85.027495 -1.899604,-0.02778 c 0.222689,-2.899481 1.403561,-5.642507 3.356633,-7.797057 2.184929,2.410327 3.395109,5.547245 3.395109,8.800486 0,3.253242 -1.065121,6.170943 -3.250049,8.58127 l -1.501541,-1.383666 c 1.717494,-1.982979 2.662866,-4.518476 2.662866,-7.08628 0,-1.825294 -0.486306,-3.67419 -1.411706,-5.311635 -0.735139,1.30079 -1.195218,2.738732 -1.351708,4.224664 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1133" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 67.853184,180.44327 1.899603,0.0278 c -0.222689,2.89948 -1.403561,5.64251 -3.356632,7.79706 -2.18493,-2.41033 -3.395109,-5.54724 -3.395109,-8.80049 0,-3.25324 1.06512,-6.17094 3.250048,-8.58127 l 1.501542,1.38367 c -1.717494,1.98298 -2.662867,4.51848 -2.662867,7.08628 0,1.82529 0.486307,3.67419 1.411706,5.31163 0.735139,-1.30078 1.195218,-2.73873 1.351709,-4.22466 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1349" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 46.678996,140.75753 h -6.128433 l -0.780348,2.10907 h 3.47589 l -1.629004,3.02946 c -2.101833,3.63986 -1.598066,8.53454 1.337364,12.1694 L 44.50601,156.781 c -2.511202,-2.95751 -2.773686,-7.38692 -0.976674,-9.92237 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1367" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 96.888311,186.1533 c 1.97699,-0.27019 3.945399,0.55074 5.144599,2.14555 1.1992,1.59482 1.44136,3.71377 0.63291,5.53803 -0.80845,1.82426 -2.54088,3.06815 -4.527869,3.25097 l 0.181314,1.97047 c 3.603665,-0.33159 6.453645,-3.19451 6.768905,-6.79964 0.31526,-3.60514 -1.99456,-6.91927 -5.485991,-7.87129 l 0.239798,-0.51981 h 3.336873 l 0.77366,-2.13617 h -5.563229 z" + sodipodi:nodetypes="cssccscccccc" /> + <path + id="path2903" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.878234,104.783 c -1.346097,-0.23347 -2.717168,0.2461 -3.624294,1.26767 -0.907126,1.02155 -1.221185,2.43972 -0.830183,3.74876 l 1.852962,6.81017 c 0.181143,0.60644 0.03565,1.26345 -0.384603,1.73671 -0.420249,0.47327 -1.05543,0.69543 -1.679042,0.58728 l -0.371582,2.14248 c 1.346097,0.23347 2.717168,-0.2461 3.624295,-1.26767 0.907126,-1.02155 1.221185,-2.43972 0.830183,-3.74876 l -1.852962,-6.81017 c -0.181143,-0.60644 -0.03565,-1.26345 0.384603,-1.73671 0.420249,-0.47327 1.05543,-0.69543 1.679042,-0.58728 z" + sodipodi:nodetypes="csccsccsccscc" /> + <path + id="path3188" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -3.6524867,104.83764 c -1.366193,0 -2.635148,0.7068 -3.354361,1.86836 -0.719214,1.16155 -0.786313,2.61252 -0.177369,3.83549 l 2.989454,6.39336 c 0.28211,0.56657 0.251026,1.23877 -0.08217,1.77689 -0.333194,0.53812 -0.921068,0.86556 -1.553989,0.86556 l -1e-6,2.17447 c 1.366193,0 2.635148,-0.7068 3.354362,-1.86836 0.719214,-1.16155 0.786313,-2.61252 0.177369,-3.83549 l -2.989454,-6.39336 c -0.28211,-0.56657 -0.251026,-1.23877 0.08217,-1.77689 0.333194,-0.53812 0.921068,-0.86556 1.553989,-0.86556 z" + sodipodi:nodetypes="csccsccsccscc" /> + </g> +</svg> diff --git a/dial/try3.svg b/dial/try3.svg new file mode 100644 index 0000000..fe0f89c --- /dev/null +++ b/dial/try3.svg @@ -0,0 +1,328 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)" + sodipodi:docname="try3.svg"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.1123202" + inkscape:cx="498.87637" + inkscape:cy="545.626" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + showgrid="false" + inkscape:window-width="3801" + inkscape:window-height="2031" + inkscape:window-x="15" + inkscape:window-y="68" + inkscape:window-maximized="1" + showguides="false" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="image" + style="display:none"> + <image + sodipodi:absref="/root/projects/metric_clock/base.jpg" + xlink:href="base.jpg" + style="fill:#ff0000;stroke:#000000" + y="37.184856" + x="3.8290849" + id="image929" + preserveAspectRatio="none" + height="194.02777" + width="194.02777" /> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline"> + <path + id="path1322" + style="fill:#ff0000;stroke:#800080;stroke-width:0.20059;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -42.569444,101.38292 c 0.915852,1.97414 0.05794,4.31695 -1.916203,5.2328 l -0.902116,-1.94454 c 0.900203,-0.41762 1.291407,-1.48594 0.873781,-2.38614 l -4.030503,-8.687855 c -0.915851,-1.97414 -0.05793,-4.31694 1.916207,-5.23279 l 0.902116,1.94454 c -0.900203,0.41762 -1.291411,1.48593 -0.873785,2.38613 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path2891" + style="fill:#ff0000;stroke:#000000;stroke-width:0.20059;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -54.432868,102.10405 c 0,2.17624 -1.76419,3.94043 -3.940429,3.94043 v -2.1436 c 0.992359,0 1.796824,-0.80447 1.796824,-1.79683 v -9.577255 c 0,-2.17624 1.76419,-3.94042 3.940429,-3.94042 v 2.1436 c -0.992359,0 -1.796824,0.80446 -1.796824,1.79682 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path3188" + style="fill:#ff0000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m -37.058892,88.788685 c -1.366193,0 -2.635148,0.7068 -3.354361,1.86836 -0.719214,1.16155 -0.786313,2.61252 -0.177369,3.83549 l 2.989454,6.393365 c 0.28211,0.56657 0.251026,1.23877 -0.08217,1.77689 -0.333194,0.53812 -0.921068,0.86556 -1.553989,0.86556 l -10e-7,2.17447 c 1.366193,0 2.635148,-0.7068 3.354362,-1.86836 0.719214,-1.16155 0.786313,-2.61252 0.177369,-3.835495 l -2.989454,-6.39336 c -0.28211,-0.56657 -0.251026,-1.23877 0.08217,-1.77689 0.333194,-0.53812 0.921068,-0.86556 1.553989,-0.86556 z" + sodipodi:nodetypes="csccsccsccscc" /> + <g + id="g3554" + transform="matrix(0.98923371,0,0,0.98923371,1.501849,0.57564236)"> + <g + id="g3212" + transform="matrix(1.3758923,0,0,1.3758923,-34.238319,-40.900596)"> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1916" + cx="100.63864" + cy="134.26129" + r="68.959427" /> + <circle + style="display:inline;fill:none;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="circle1907" + cx="100.63864" + cy="134.26129" + r="71.386292" /> + </g> + <g + id="g3505" + style="fill:#000000"> + <g + id="g2198" + style="fill:#000000;stroke-width:0.278535;stroke-miterlimit:4;stroke-dasharray:none" + transform="matrix(0.98795109,0,0,0.98795109,-1.7616251,-4.0554014)"> + <path + id="path1950" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 11.246004,149.68745 c 0,-2.01157 0.0632,-4.02265 0.189508,-6.03026 l -3.3731631,-0.21223 c -0.1307527,2.07826 -0.1961779,4.16012 -0.1961779,6.24249 z m 191.886276,6.03027 c 0.12627,-2.00761 0.18951,-4.01869 0.18951,-6.03027 h 3.37983 c 0,2.08238 -0.0654,4.16424 -0.19618,6.24249 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1957" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 12.003291,137.65071 c 0.252117,-1.9957 0.566879,-3.98302 0.943807,-5.95896 l -3.3199654,-0.63332 c -0.3901962,2.04548 -0.7160315,4.10272 -0.9770227,6.16868 z M 201.6207,167.68315 c 0.3769,-1.97594 0.69167,-3.96325 0.94379,-5.95896 l 3.35318,0.42361 c -0.26098,2.06596 -0.58676,4.12321 -0.97702,6.16868 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1959" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 14.26321,125.80381 c 0.500258,-1.94839 1.061613,-3.88057 1.683221,-5.79369 l -3.214411,-1.04443 c -0.643485,1.98044 -1.224592,3.98063 -1.742458,5.99758 z m 184.35816,53.56098 c 0.62157,-1.91313 1.18295,-3.84531 1.6832,-5.79369 l 3.27365,0.84054 c -0.51786,2.01695 -1.09892,4.01715 -1.74246,5.99758 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1961" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 17.990122,114.33354 c 0.740509,-1.8703 1.539605,-3.7169 2.396089,-5.53703 l -3.058162,-1.43907 c -0.886628,1.88418 -1.713841,3.79576 -2.480416,5.73191 z m 176.191468,76.24485 c 0.85645,-1.82013 1.65556,-3.66673 2.39608,-5.53703 l 3.14248,1.2442 c -0.76657,1.93614 -1.59373,3.84775 -2.48041,5.73191 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1971" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 23.12525,103.42085 c 0.969083,-1.76276 1.993317,-3.494636 3.071169,-5.193068 l -2.853684,-1.81101 C 22.226948,98.174971 21.166672,99.9678 20.16348,101.7926 Z m 165.24612,97.72628 c 1.07783,-1.69845 2.10209,-3.43032 3.07118,-5.19307 l 2.96176,1.62825 c -1.0032,1.8248 -2.06343,3.61765 -3.17926,5.37582 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1973" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 29.587609,93.237795 c 1.182372,-1.627392 2.415594,-3.217247 3.697816,-4.767192 l -2.6042,-2.154395 c -1.327353,1.604495 -2.603964,3.250291 -3.827959,4.934976 z M 181.28238,210.90432 c 1.28219,-1.54997 2.51542,-3.13981 3.69779,-4.76722 l 2.73435,1.98662 c -1.22399,1.68468 -2.50055,3.33052 -3.82796,4.93498 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1975" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 37.275282,83.944998 c 1.37702,-1.466379 2.799775,-2.889127 4.26615,-4.266152 L 39.22778,77.215052 c -1.517975,1.42547 -2.990801,2.8983 -4.416285,4.416283 z M 173.02637,219.69607 c 1.46634,-1.37704 2.88912,-2.79979 4.26613,-4.26616 l 2.46378,2.31366 c -1.42547,1.51799 -2.89826,2.99085 -4.41627,4.41628 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1977" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.067041,75.688984 c 1.549939,-1.282216 3.139799,-2.515436 4.767195,-3.697815 l -1.986608,-2.734352 c -1.684672,1.223989 -3.330474,2.500606 -4.934976,3.827964 z M 163.73356,227.38374 c 1.62737,-1.18239 3.21725,-2.41561 4.76719,-3.69782 l 2.15438,2.6042 c -1.6045,1.32736 -3.25027,2.60403 -4.93497,3.82797 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1987" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.824218,68.599981 c 1.698429,-1.077854 3.43031,-2.102083 5.193065,-3.07117 l -1.628241,-2.961773 c -1.824792,1.003188 -3.617621,2.063463 -5.375828,3.179257 z M 153.55051,233.84611 c 1.76273,-0.96913 3.49464,-1.99333 5.19307,-3.07118 l 1.81098,2.85369 c -1.75819,1.11579 -3.55099,2.1761 -5.37581,3.17924 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1989" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 66.39295,62.78977 c 1.820122,-0.856482 3.666722,-1.655574 5.537033,-2.396086 l -1.244189,-3.142493 c -1.93614,0.766573 -3.847712,1.593782 -5.731909,2.480418 z m 76.24486,176.19147 c 1.87029,-0.74055 3.7169,-1.53962 5.53703,-2.39611 l 1.43906,3.05817 c -1.8842,0.88663 -3.79575,1.7139 -5.73191,2.48041 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1991" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 77.606548,58.349995 c 1.913125,-0.621614 3.84531,-1.18296 5.793691,-1.683225 l -0.840528,-3.273648 c -2.016937,0.517859 -4.017125,1.09897 -5.997579,1.742457 z M 131.16756,242.70815 c 1.94836,-0.5003 3.88056,-1.06163 5.79368,-1.68324 l 1.04441,3.21441 c -1.98045,0.64351 -3.98063,1.22465 -5.99756,1.74247 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path1993" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 89.288191,55.350656 c 1.975933,-0.376925 3.963247,-0.691684 5.95896,-0.943806 l -0.423593,-3.353186 c -2.06595,0.260992 -4.123194,0.586829 -6.168688,0.977027 z M 119.32064,244.96806 c 1.99569,-0.25215 3.98303,-0.56688 5.95896,-0.94382 l 0.63331,3.31997 c -2.04548,0.3902 -4.10273,0.7161 -6.16868,0.97703 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2003" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 101.25362,53.839074 c 2.00761,-0.12631 4.01869,-0.189505 6.03027,-0.189509 v -3.379832 c -2.08237,-1e-6 -4.16423,0.06543 -6.24249,0.19618 z m 6.03027,191.886296 c 2.01158,-6e-5 4.02268,-0.0633 6.03027,-0.18953 l 0.2122,3.37317 c -2.07825,0.13073 -4.1601,0.19622 -6.24246,0.19616 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2005" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.31416,53.839073 c 2.0076,0.126311 4.01075,0.315665 6.00647,0.56778 l 0.42361,-3.353181 c -2.06595,-0.26099 -4.13958,-0.457007 -6.21786,-0.587761 z M 95.247156,244.96807 c 1.995706,0.25208 3.998861,0.44146 6.006464,0.56777 l -0.21221,3.37315 c -2.078283,-0.13074 -4.151928,-0.32671 -6.217869,-0.58775 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2007" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 125.27959,55.35066 c 1.97595,0.376931 3.93957,0.815857 5.88796,1.316111 l 0.84052,-3.273648 c -2.01693,-0.517863 -4.04967,-0.972229 -6.09516,-1.362429 z M 83.400243,242.70815 c 1.948378,0.50022 3.912012,0.93917 5.887949,1.31609 l -0.633327,3.31997 c -2.045498,-0.39018 -4.078234,-0.84451 -6.095147,-1.36241 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2009" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 136.96124,58.349993 c 1.9131,0.621611 3.80624,1.303183 5.67656,2.043689 l 1.24421,-3.142488 c -1.93614,-0.76657 -3.89589,-1.472122 -5.87636,-2.115613 z M 71.929992,238.98124 c 1.870311,0.74047 3.763454,1.42207 5.676563,2.04367 l -1.044429,3.21441 c -1.980456,-0.64349 -3.940238,-1.34899 -5.876349,-2.11561 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2019" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 148.17483,62.789776 c 1.82013,0.856485 3.61291,1.769954 5.37566,2.739033 l 1.62824,-2.961769 c -1.82478,-1.003186 -3.68064,-1.948797 -5.56484,-2.83543 z M 61.017269,233.84611 c 1.762794,0.96905 3.555588,1.8825 5.375678,2.73903 l -1.439084,3.05816 c -1.884173,-0.88664 -3.740054,-1.8322 -5.564815,-2.83543 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2021" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 158.74357,68.599986 c 1.69841,1.077852 3.36256,2.20881 4.98997,3.391184 l 1.98662,-2.734336 c -1.68467,-1.223986 -3.40737,-2.394738 -5.1656,-3.510539 z M 50.83423,227.38375 c 1.627411,1.18234 3.291556,2.31332 4.989984,3.39118 l -1.810993,2.85369 c -1.758229,-1.11579 -3.480969,-2.2865 -5.165609,-3.51054 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2023" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 168.50073,75.688986 c 1.54996,1.28223 3.05923,2.612845 4.52561,3.989862 L 175.34,77.215055 c -1.51797,-1.425473 -3.08038,-2.802915 -4.68487,-4.130271 z M 41.541426,219.69608 c 1.466396,1.37698 2.975675,2.70762 4.525619,3.98984 l -2.154394,2.6042 c -1.604515,-1.32734 -3.16694,-2.70476 -4.684876,-4.13024 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2025" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 177.2925,83.945 c 1.37701,1.466364 2.70762,2.975657 3.98985,4.525599 l 2.60421,-2.15438 c -1.32734,-1.60449 -2.70478,-3.166887 -4.13028,-4.68488 z M 33.285423,210.90432 c 1.28224,1.54992 2.612851,3.05924 3.989864,4.52559 l -2.463793,2.31366 c -1.425487,-1.51798 -2.802979,-3.08035 -4.130283,-4.68487 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2027" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 184.98017,93.237798 c 1.18238,1.627397 2.31334,3.291556 3.39119,4.989978 l 2.85369,-1.810997 c -1.11579,-1.758205 -2.28653,-3.480906 -3.51053,-5.16559 z M 26.196408,201.14712 c 1.077895,1.69843 2.208887,3.36257 3.391204,4.99 l -2.73435,1.9866 c -1.223968,-1.68467 -2.394784,-3.40737 -3.510527,-5.16558 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2029" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 191.44253,103.42085 c 0.96907,1.76275 1.88255,3.55553 2.73903,5.37566 l 3.05817,-1.43906 c -0.88662,-1.88419 -1.83223,-3.74003 -2.83544,-5.56485 z M 20.386197,190.57841 c 0.856513,1.82012 1.769965,3.6129 2.739048,5.37568 l -2.961765,1.62822 c -1.003211,-1.82479 -1.948869,-3.68063 -2.835433,-5.56485 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2031" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 196.57767,114.33356 c 0.7405,1.8703 1.42207,3.76344 2.04368,5.67656 l 3.2144,-1.04443 c -0.64347,-1.98044 -1.34902,-3.94019 -2.11559,-5.87633 z M 15.946414,179.36482 c 0.621651,1.91308 1.303199,3.80624 2.043712,5.67654 l -3.142492,1.2442 c -0.766599,-1.93614 -1.472184,-3.89589 -2.115608,-5.87634 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2033" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 200.30457,125.80381 c 0.50026,1.94837 0.93917,3.91199 1.3161,5.88793 l 3.31998,-0.6333 c -0.3902,-2.04549 -0.84456,-4.07821 -1.36243,-6.09516 z M 12.947091,167.68317 c 0.376953,1.97592 0.815858,3.93959 1.316122,5.88794 l -3.273651,0.84053 c -0.517872,-2.01695 -0.972302,-4.04967 -1.3624406,-6.09516 z" + sodipodi:nodetypes="cccccccccc" /> + <path + id="path2035" + style="display:inline;fill:#000000;stroke:#000000;stroke-width:0.278535;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 202.56449,137.65073 c 0.25212,1.99569 0.44146,3.99884 0.56777,6.00644 l 3.37318,-0.21219 c -0.13074,-2.07827 -0.32678,-4.15191 -0.58777,-6.21786 z m -191.128985,18.067 c 0.126339,2.00759 0.315663,4.01079 0.567789,6.00646 l -3.3531841,0.42361 c -0.2609968,-2.06595 -0.4570755,-4.1396 -0.5877708,-6.21786 z" + sodipodi:nodetypes="cccccccccc" /> + </g> + <g + id="g3208" + transform="matrix(1.3758923,0,0,1.3758923,-34.238319,-40.900596)" + style="fill:#000000"> + <g + id="g3120" + style="fill:#000000;stroke-width:0.2;stroke-miterlimit:4;stroke-dasharray:none"> + <path + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 138.03726,171.24469 c -0.77761,0.81399 -1.75116,1.45722 -1.6953,2.60903 l -0.0452,12.07679 -1.00731,1.41973 1.37357,1.46925 c 0.74197,-0.78494 1.87686,-1.76767 1.86905,-2.612 l -0.0437,-12.21812 0.82467,-1.20604 z" + id="path951" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path960" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 133.85787,178.36222 8.07906,0.032 0.002,0.12631 c 0,1.11661 -0.76318,2.0218 -1.70463,2.0218 v 0 l -7.46554,-0.0173 -0.59791,-0.002 c 0,-1.11661 0.74559,-2.16081 1.68702,-2.16081 z" + sodipodi:nodetypes="ccccccccc" /> + </g> + <path + id="path1018" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 160.90525,147.2676 c 1.48729,1.80016 1.95982,4.23191 1.25492,6.45806 -0.70491,2.22616 -2.49098,3.94272 -4.74336,4.55874 l -0.41206,-1.89501 c 1.88669,-0.70096 3.19062,-2.43867 3.33624,-4.4461 0.14562,-2.00742 -0.89388,-3.91512 -2.65966,-4.88103 l -0.004,-0.0637 c 1.06721,-0.16173 1.958,-0.89931 2.31592,-1.91764 0.35792,-1.01832 0.12452,-2.15104 -0.6068,-2.94493 l 1.43046,-1.34397 c 1.02203,0.77055 1.62503,1.97462 1.62991,3.25457 0.005,1.27995 -0.58891,2.48858 -1.60502,3.26692" + sodipodi:nodetypes="csccsccsccsc" /> + <path + id="path1054" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 155.73736,119.53091 h 3.40358 l -0.79504,2.08102 h -5.72304 l 4.72565,-11.05665 c 0.46162,-1.02966 0.47732,-1.96875 -0.0377,-2.84285 -0.51502,-0.8741 -1.45391,-1.41065 -2.46845,-1.41065 v -1.9661 c 1.73376,0 3.33826,0.91691 4.21837,2.41069 0.88012,1.49378 0.79247,3.1956 0.0644,4.85818 z" + sodipodi:nodetypes="cccccsccscc" /> + <path + id="path1063" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 134.6014,92.40704 c 0.0228,1.497337 -0.71255,2.190802 -1.71723,3.097623 l -1.36814,-1.383834 0.91785,-1.294304 c 0.0754,-4.626764 0.0729,-7.14302 0.0729,-11.770183 -0.0228,-1.497336 0.71255,-2.190801 1.71723,-3.097623 l 1.36814,1.383834 -0.91784,1.294304 c -0.0754,4.626765 -0.0729,7.14302 -0.0729,11.770183 z" + sodipodi:nodetypes="ccccccccc" /> + <g + id="g1110" + transform="matrix(1.0029497,0,0,1.0029497,-4.9271339,-0.27216559)" + style="fill:#000000;stroke-width:0.199412;stroke-miterlimit:4;stroke-dasharray:none"> + <path + id="path1066" + style="fill:#000000;stroke:#000000;stroke-width:0.199412;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 99.335085,82.703014 c 0.0227,1.49293 -0.71046,2.18436 -1.71218,3.08851 l -1.36412,-1.37976 0.91515,-1.2905 c 0.0752,-4.613159 0.0727,-7.122014 0.0727,-11.735569 -0.0227,-1.492933 0.71046,-2.184358 1.71218,-3.088513 l 1.364125,1.379764 -0.915155,1.290498 c -0.0752,4.613157 -0.0727,7.122012 -0.0727,11.73557 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1104" + style="fill:#000000;stroke:#000000;stroke-width:0.199412;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 113.34794,77.22145 c -0.009,-4.008906 -1.45649,-5.885766 -2.94934,-7.436765 -1.49285,1.551 -2.94034,3.427859 -2.94934,7.436765 0.009,4.008906 1.45649,5.885765 2.94934,7.436764 1.49285,-1.551 2.94072,-3.427858 2.94934,-7.436764 z m -7.75346,-10e-7 c 0,-3.970502 1.39203,-7.485929 3.44361,-8.696446 h 2.72102 c 2.05158,1.210517 3.44361,4.725944 3.44361,8.696446 m 0,0 c 0,3.970503 -1.39203,7.48593 -3.44361,8.696447 h -2.72102 c -2.05158,-1.210517 -3.44361,-4.725944 -3.44361,-8.696447" /> + </g> + <path + id="circle1126" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 64.853248,85.027495 -1.899604,-0.02778 c 0.222689,-2.899481 1.403561,-5.642507 3.356633,-7.797057 2.184929,2.410327 3.395109,5.547245 3.395109,8.800486 0,3.253242 -1.065121,6.170943 -3.250049,8.58127 l -1.501541,-1.383666 c 1.717494,-1.982979 2.662866,-4.518476 2.662866,-7.08628 0,-1.825294 -0.486306,-3.67419 -1.411706,-5.311635 -0.735139,1.30079 -1.195218,2.738732 -1.351708,4.224664 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1133" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 67.853184,180.44327 1.899603,0.0278 c -0.222689,2.89948 -1.403561,5.64251 -3.356632,7.79706 -2.18493,-2.41033 -3.395109,-5.54724 -3.395109,-8.80049 0,-3.25324 1.06512,-6.17094 3.250048,-8.58127 l 1.501542,1.38367 c -1.717494,1.98298 -2.662867,4.51848 -2.662867,7.08628 0,1.82529 0.486307,3.67419 1.411706,5.31163 0.735139,-1.30078 1.195218,-2.73873 1.351709,-4.22466 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1349" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 46.678996,140.75753 h -6.128433 l -0.780348,2.10907 h 3.47589 l -1.629004,3.02946 c -2.101833,3.63986 -1.598066,8.53454 1.337364,12.1694 L 44.50601,156.781 c -2.511202,-2.95751 -2.773686,-7.38692 -0.976674,-9.92237 z" + sodipodi:nodetypes="ccccccccc" /> + <path + id="path1367" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 96.888311,186.1533 c 1.97699,-0.27019 3.945399,0.55074 5.144599,2.14555 1.1992,1.59482 1.44136,3.71377 0.63291,5.53803 -0.80845,1.82426 -2.54088,3.06815 -4.527869,3.25097 l 0.181314,1.97047 c 3.603665,-0.33159 6.453645,-3.19451 6.768905,-6.79964 0.31526,-3.60514 -1.99456,-6.91927 -5.485991,-7.87129 l 0.239798,-0.51981 h 3.336873 l 0.77366,-2.13617 h -5.563229 z" + sodipodi:nodetypes="cssccscccccc" /> + <path + id="path2903" + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + d="m 46.878234,104.783 c -1.346097,-0.23347 -2.717168,0.2461 -3.624294,1.26767 -0.907126,1.02155 -1.221185,2.43972 -0.830183,3.74876 l 1.852962,6.81017 c 0.181143,0.60644 0.03565,1.26345 -0.384603,1.73671 -0.420249,0.47327 -1.05543,0.69543 -1.679042,0.58728 l -0.371582,2.14248 c 1.346097,0.23347 2.717168,-0.2461 3.624295,-1.26767 0.907126,-1.02155 1.221185,-2.43972 0.830183,-3.74876 l -1.852962,-6.81017 c -0.181143,-0.60644 -0.03565,-1.26345 0.384603,-1.73671 0.420249,-0.47327 1.05543,-0.69543 1.679042,-0.58728 z" + sodipodi:nodetypes="csccsccsccscc" /> + </g> + </g> + <circle + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="path3190" + cx="104.22961" + cy="143.82848" + r="101.99923" /> + <circle + style="fill:#000000;stroke:#000000;stroke-width:0.2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" + id="path3192" + cx="104.22961" + cy="143.82848" + r="1.0175619" /> + </g> + </g> +</svg> diff --git a/stm32/.gitignore b/stm32/.gitignore new file mode 100644 index 0000000..ac9bbcd --- /dev/null +++ b/stm32/.gitignore @@ -0,0 +1,10 @@ +*.o +*.a +*.d +*.elf +*.map +*.hex +*~ +*.dfu +*.bin +*.orig diff --git a/stm32/Makefile.include b/stm32/Makefile.include new file mode 100644 index 0000000..389aa68 --- /dev/null +++ b/stm32/Makefile.include @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = opencm3_stm32f1 +DEFS = -DSTM32F1 + +FP_FLAGS ?= -msoft-float +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd + +################################################################################ +# OpenOCD specific variables + +OOCD ?= openocd +OOCD_INTERFACE ?= ../oocd/interface/stlink-v2.cfg +#OOCD_INTERFACE ?= ../oocd/interface/j-link.cfg +OOCD_BOARD ?= ../oocd/board/STM32F103R_BOARD.cfg + +################################################################################ +# Black Magic Probe specific variables +# Set the BMP_PORT to a serial port and then BMP is used for flashing +BMP_PORT ?= + +################################################################################ +# texane/stlink specific variables +#STLINK_PORT ?= :4242 + + +include ../Makefile.rules diff --git a/stm32/Makefile.rules b/stm32/Makefile.rules new file mode 100644 index 0000000..6e9fe6c --- /dev/null +++ b/stm32/Makefile.rules @@ -0,0 +1,251 @@ +# +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> +## Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +NULL := 2>/dev/null +endif + +############################################################################### +# Executables + +PREFIX ?= arm-none-eabi + +CC := $(PREFIX)-gcc +CXX := $(PREFIX)-g++ +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +STFLASH = $(shell which st-flash) +STYLECHECK := /checkpatch.pl +STYLECHECKFLAGS := --no-tree -f --terse --mailback +STYLECHECKFILES := $(shell find . -name '*.[ch]') + + +############################################################################### +# Source files + +LDSCRIPT ?= $(BINARY).ld + +#OBJS += $(BINARY).o + + +ifeq ($(strip $(OPENCM3_DIR)),) +# user has not specified the library path, so we try to detect it + +# where we search for the library +LIBPATHS := ./libopencm3 ../libopencm3 + +OPENCM3_DIR := $(wildcard $(LIBPATHS:=/locm3.sublime-project)) +OPENCM3_DIR := $(firstword $(dir $(OPENCM3_DIR))) + +ifeq ($(strip $(OPENCM3_DIR)),) +$(warning Cannot find libopencm3 library in the standard search paths.) +$(error Please specify it through OPENCM3_DIR variable!) +endif +endif + +ifeq ($(V),1) +$(info Using $(OPENCM3_DIR) path to library) +endif + +INCLUDE_DIR = $(OPENCM3_DIR)/include +LIB_DIR = $(OPENCM3_DIR)/lib +SCRIPT_DIR = $(OPENCM3_DIR)/scripts + +############################################################################### +# C flags + +CFLAGS += -Os -g +CFLAGS += -Wextra -Wimplicit-function-declaration +CFLAGS += -Wmissing-prototypes -Wstrict-prototypes +CFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C++ flags + +CXXFLAGS += -Os -g +CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ +CXXFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C & C++ preprocessor common flags + +CPPFLAGS += -MD +CPPFLAGS += -Wall -Wundef + +INCLUDES = -I$(INCLUDE_DIR) +DEFINES = $(DEFS) + +CPPFLAGS += $(INCLUDES) $(DEFINES) + +############################################################################### +# Linker flags + +LDFLAGS += --static -nostartfiles +LDFLAGS += -L$(LIB_DIR) +LDFLAGS += -T$(LDSCRIPT) +LDFLAGS += -Wl,-Map=$(*).map +LDFLAGS += -Wl,--gc-sections +ifeq ($(V),99) +LDFLAGS += -Wl,--print-gc-sections +endif + +############################################################################### +# Used libraries + +LDLIBS += -l$(LIBNAME) +LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group + +############################################################################### +############################################################################### +############################################################################### + +.SUFFIXES: .elf .bin .hex .srec .list .map .images .dfu +.SECONDEXPANSION: +.SECONDARY: + +all: elf + +elf: $(BINARY).elf +bin: $(BINARY).bin +hex: $(BINARY).hex +srec: $(BINARY).srec +list: $(BINARY).list + +images: $(BINARY).images +flash: $(BINARY).flash + +%.images: %.bin %.hex %.srec %.list %.map %.dfu + @#printf "*** $* images generated ***\n" + +%.bin: %.elf + @#printf " OBJCOPY $(*).bin\n" + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.hex: %.elf + @#printf " OBJCOPY $(*).hex\n" + $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex + +#%.dfu: %.elf +# @#printf " OBJCOPY $(*).dfu\n" +# $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).dfu + +%.srec: %.elf + @#printf " OBJCOPY $(*).srec\n" + $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec + +%.list: %.elf + @#printf " OBJDUMP $(*).list\n" + $(Q)$(OBJDUMP) -S $(*).elf > $(*).list + +fish: + echo %.elf %.map: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + echo $(BINARY).elf + +%.elf %.map: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + @#printf " LD $(*).elf\n" + $(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(*).elf + +%.o: %.c + @#printf " CC $(*).c\n" + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).c + +%.o: %.cxx + @#printf " CXX $(*).cxx\n" + $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).cxx + +%.o: %.cpp + @#printf " CXX $(*).cpp\n" + $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).cpp + +clean: + @#printf " CLEAN\n" + $(Q)$(RM) *.o *.d *.elf *.bin *.hex *.srec *.list *.map *~ *.dfu *.orig + +stylecheck: $(STYLECHECKFILES:=.stylecheck) +styleclean: $(STYLECHECKFILES:=.styleclean) + +# the cat is due to multithreaded nature - we like to have consistent chunks of text on the output +%.stylecheck: % + $(Q)$(SCRIPT_DIR)$(STYLECHECK) $(STYLECHECKFLAGS) $* > $*.stylecheck; \ + if [ -s $*.stylecheck ]; then \ + cat $*.stylecheck; \ + else \ + rm -f $*.stylecheck; \ + fi; + +%.styleclean: + $(Q)rm -f $*.stylecheck; + + +%.stlink-flash: %.bin + @printf " FLASH $<\n" + $(Q)$(STFLASH) write $(*).bin 0x8000000 + +ifeq ($(STLINK_PORT),) +ifeq ($(BMP_PORT),) +ifeq ($(OOCD_SERIAL),) +%.flash: %.hex + @printf " FLASH $<\n" + @# IMPORTANT: Don't use "resume", only "reset" will work correctly! + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + -c "init" -c "reset init" \ + -c "flash write_image erase $(*).hex" \ + -c "reset" \ + -c "shutdown" $(NULL) +else +%.flash: %.hex + @printf " FLASH $<\n" + @# IMPORTANT: Don't use "resume", only "reset" will work correctly! + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + -c "ft2232_serial $(OOCD_SERIAL)" \ + -c "init" -c "reset init" \ + -c "flash write_image erase $(*).hex" \ + -c "reset" \ + -c "shutdown" $(NULL) +endif +else +%.flash: %.elf + @printf " GDB $(*).elf (flash)\n" + $(Q)$(GDB) --batch \ + -ex 'target extended-remote $(BMP_PORT)' \ + -x $(SCRIPT_DIR)/black_magic_probe_flash.scr \ + $(*).elf +endif +else +%.flash: %.elf + @printf " GDB $(*).elf (flash)\n" + $(Q)$(GDB) --batch \ + -ex 'target extended-remote $(STLINK_PORT)' \ + -x $(SCRIPT_DIR)/stlink_flash.scr \ + $(*).elf +endif + +.PHONY: images clean stylecheck styleclean elf bin hex srec list + +-include $(OBJS:.o=.d) diff --git a/stm32/app/Makefile b/stm32/app/Makefile new file mode 100644 index 0000000..997011f --- /dev/null +++ b/stm32/app/Makefile @@ -0,0 +1,80 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +CPROTO=cproto +PROG=clock + +LDLIBS+=-lm + +V=1 +default: ${PROG}.elf + +CSRCS= main.c cdcacm.c dfu.c ring.c usart.c ticker.c dummy_kb.c usb.c rtc.c time_fn.c events.c hands.c motor.c +HSRCS = project.h + + +BINARY = ${PROG} +OBJS = ${CSRCS:%.c=%.o} + +include ../Makefile.include + +DID=$(shell printf '\#include "id.h"\nID_PRODUCT' | ${CC} -I.. -E - | grep -v ^\# ) +VID=$(shell printf '\#include "id.h"\nID_VENDOR' | ${CC} -I.. -E - | grep -v ^\# ) + +INCLUDES += -I.. + + +%.bin: %.elf + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.dfu:%.bin + ../tools/dfuse-pack.py -D 0x483:0xff03 -b 0x08002000:$< $@ + +dfu:${PROG}.bin + dfu-util -R -a 0 -d 0483:ff03,0483:df11 -s 0x08002000:leave -D $< + +program: ${PROG}.elf + echo halt | nc -t localhost 4444 + echo flash write_image erase ${PWD}/$< 0x2000 | nc -t localhost 4444 + echo reset run | nc -t localhost 4444 + +ds: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + +debug: ${PROG}.elf + ${PREFIX}-gdb -x gdb.script ${PROG}.elf + +reset: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + -c "init" -c "reset run" \ + -c shutdown + + + + +protos: + echo -n > prototypes.h + ${CPROTO} $(INCLUDES) $(DEFINES) -e -v ${CSRCS} > prototypes.h.tmp + mv -f prototypes.h.tmp prototypes.h + + +tidy: + astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} || astyle -A3 -s2 -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} diff --git a/stm32/app/asm_fns.h b/stm32/app/asm_fns.h new file mode 100644 index 0000000..b0d10d9 --- /dev/null +++ b/stm32/app/asm_fns.h @@ -0,0 +1,4 @@ +static inline void compiler_mb(void) { +asm volatile (""); +} + diff --git a/stm32/app/board.h b/stm32/app/board.h new file mode 100644 index 0000000..41eeafc --- /dev/null +++ b/stm32/app/board.h @@ -0,0 +1,15 @@ + +#define LED1 GPIO8 +#define LED1_PORT GPIOB + +#define LED2 GPIO9 +#define LED2_PORT GPIOB + + +#define USART1_TX GPIO_USART1_TX +#define USART1_TX_PORT GPIOA + +#define USART1_RX GPIO_USART1_RX +#define USART1_RX_PORT GPIOA + + diff --git a/stm32/app/cdcacm.c b/stm32/app/cdcacm.c new file mode 100644 index 0000000..0b4a4e3 --- /dev/null +++ b/stm32/app/cdcacm.c @@ -0,0 +1,221 @@ +#include "project.h" + + +#define BUFFER_SIZE 512 + +ring_t cdcacm_rx_ring; +static uint8_t cdcacm_rx_ring_buf[BUFFER_SIZE]; + +ring_t cdcacm_tx_ring; +static uint8_t cdcacm_tx_ring_buf[BUFFER_SIZE]; + +static int cdcacm_ready = 0; + +#define COMM_EP 0x83 +#define DATA_IN 0x01 +#define DATA_OUT 0x82 + +static const struct usb_endpoint_descriptor comm_endp[] = { + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = COMM_EP, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, + } +}; + +static const struct usb_endpoint_descriptor data_endp[] = { + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = DATA_IN, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, + }, + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = DATA_OUT, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, + } +}; + +static const struct { + struct usb_cdc_header_descriptor header; + struct usb_cdc_call_management_descriptor call_mgmt; + struct usb_cdc_acm_descriptor acm; + struct usb_cdc_union_descriptor cdc_union; +} __attribute__ ((packed)) cdcacm_functional_descriptors = { + .header = { + .bFunctionLength = sizeof (struct usb_cdc_header_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_HEADER, + .bcdCDC = 0x0110, + }, + .call_mgmt = { + .bFunctionLength = + sizeof (struct usb_cdc_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 3, + }, + .acm = { + .bFunctionLength = sizeof (struct usb_cdc_acm_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof (struct usb_cdc_union_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_UNION, + .bControlInterface = 2, + .bSubordinateInterface0 = 3, + } +}; + +const struct usb_interface_descriptor comm_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 2, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, + .iInterface = 0, + .endpoint = comm_endp, + .extra = &cdcacm_functional_descriptors, + .extralen = sizeof (cdcacm_functional_descriptors) +}; + +const struct usb_interface_descriptor data_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 3, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + .endpoint = data_endp, +}; + + +const struct usb_iface_assoc_descriptor cdc_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_CDC_PROTOCOL_AT, + .iFunction = 6, +}; + + + +enum usbd_request_return_codes +cdcacm_control_request (usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) { + (void) complete; + (void) buf; + (void) usbd_dev; + + + switch (req->bRequest) + { + case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { + /* + * This Linux cdc_acm driver requires this to be implemented + * even though it's optional in the CDC spec, and we don't + * advertise it in the ACM functional descriptor. + */ + return USBD_REQ_HANDLED; + } + + case USB_CDC_REQ_SET_LINE_CODING: + if (*len < sizeof (struct usb_cdc_line_coding)) + return USBD_REQ_NOTSUPP; + + return USBD_REQ_HANDLED; + } + + return USBD_REQ_NEXT_CALLBACK; +} + + + +void cdcacm_tick (void) +{ + unsigned ep = DATA_OUT; + uint8_t buf[16]; + uint8_t *ptr = buf; + size_t n = 0; + + if (!cdcacm_ready) + return; + + if (ring_empty (&cdcacm_tx_ring)) + return; + + /* Return if endpoint is already enabled. */ + if ((*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) + return; + + while (!ring_read_byte (&cdcacm_tx_ring, ptr++)) { + n++; + + if (n == sizeof (buf)) break; + } + + usbd_ep_write_packet (usb_device, ep, buf, n); +} + +int cdcacm_write (char *ptr, int len) +{ + int ret; + + ret = ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len); + return ret; +} + + + +static void cdcacm_data_rx_cb (usbd_device *usbd_dev, uint8_t ep) +{ + (void) ep; + uint8_t buf[64]; + int len = usbd_ep_read_packet (usbd_dev, DATA_IN, buf, 64); + + if (len) + ring_write (&cdcacm_rx_ring, buf, len); +} + +void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue) +{ + (void) wValue; + + usbd_ep_setup (usbd_dev, DATA_IN, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup (usbd_dev, DATA_OUT, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup (usbd_dev, COMM_EP, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + cdcacm_ready = 1; +} + +void cdcacm_rings_init (void) +{ + ring_init (&cdcacm_rx_ring, cdcacm_rx_ring_buf, sizeof (cdcacm_rx_ring_buf)); + ring_init (&cdcacm_tx_ring, cdcacm_tx_ring_buf, sizeof (cdcacm_tx_ring_buf)); +} + + diff --git a/stm32/app/clock.ld b/stm32/app/clock.ld new file mode 100644 index 0000000..20cbff9 --- /dev/null +++ b/stm32/app/clock.ld @@ -0,0 +1,43 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Linker script for Olimex STM32-H103 (STM32F103RBT6, 128K flash, 20K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE cortex-m-generic.ld + +dfu_shared_location = ORIGIN(ram) + LENGTH(ram) - 1024; + +/* PROVIDE(_stack = dfu_shared_location ); */ + +SECTIONS +{ + .dfu_shared dfu_shared_location :{ + dfu_flag = .; + } +} + + diff --git a/stm32/app/dfu.c b/stm32/app/dfu.c new file mode 100644 index 0000000..29a2428 --- /dev/null +++ b/stm32/app/dfu.c @@ -0,0 +1,86 @@ +#include "project.h" + +const struct usb_dfu_descriptor dfu_function = { + .bLength = sizeof (struct usb_dfu_descriptor), + .bDescriptorType = DFU_FUNCTIONAL, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, + .wDetachTimeout = 255, + .wTransferSize = 1024, + .bcdDFUVersion = 0x011A, +}; + +const struct usb_interface_descriptor dfu_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = 0xFE, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 1, + .iInterface = 4, + .extra = &dfu_function, + .extralen = sizeof (dfu_function), +}; + + +const struct usb_iface_assoc_descriptor dfu_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 1, + .bInterfaceCount = 1, + .bFunctionClass = 0xfe, + .bFunctionSubClass = 1, + .bFunctionProtocol = 1, + .iFunction = 5, +}; + + +static void +dfu_detach_complete (usbd_device *usbd_dev, struct usb_setup_data *req) +{ + (void) req; + (void) usbd_dev; + dfu_flag = 0xfee1dead; + + scb_reset_core(); +} + +enum usbd_request_return_codes +dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len, + usbd_control_complete_callback *complete) { + (void) buf; + (void) len; + (void) usbd_dev; + + if ((req->bmRequestType & 0x7F) != 0x21) + return USBD_REQ_NEXT_CALLBACK; + + switch (req->bRequest) + { + case DFU_GETSTATUS: { + (*buf) [0] = DFU_STATUS_OK; + (*buf) [1] = 0; + (*buf) [2] = 0; + (*buf) [3] = 0; + (*buf) [4] = STATE_APP_IDLE; + (*buf) [5] = 0; /* iString not used here */ + *len = 6; + return USBD_REQ_HANDLED; + } + + case DFU_GETSTATE: + /* Return state with no state transision. */ + *buf[0] = STATE_APP_IDLE; + *len = 1; + return USBD_REQ_HANDLED; + + case DFU_DETACH: + *complete = dfu_detach_complete; + return USBD_REQ_HANDLED; + } + + return USBD_REQ_NEXT_CALLBACK; +} + diff --git a/stm32/app/dummy_kb.c b/stm32/app/dummy_kb.c new file mode 100644 index 0000000..a1d61c7 --- /dev/null +++ b/stm32/app/dummy_kb.c @@ -0,0 +1,26 @@ +#include "project.h" + +const struct usb_interface_descriptor dummy_kb_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + + +const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 0, + .bInterfaceCount = 1, + .bFunctionClass = 0xff, + .bFunctionSubClass = 0, + .bFunctionProtocol = 0, + .iFunction = 4, +}; + diff --git a/stm32/app/events.c b/stm32/app/events.c new file mode 100644 index 0000000..2ad9b47 --- /dev/null +++ b/stm32/app/events.c @@ -0,0 +1,101 @@ +#include "project.h" + +#define D2R(a) ((a)*(M_PI/180.)) + + + + +// shamelessly stolen from Meeus Astronmical Algorithms Chapter 27 table 27.B +// chapter 25 is probably more tractable, but this is easier to code up + +static double mean_vernal_equinox (unsigned year) +{ + double y = year; + y -= 2000; + y *= 0.001; + return 2451623.80984 + 365242.37404 * y + 0.05169 * (y * y) - 0.00411 * (y * y * y) - 0.00057 * (y * y * y * y); +} + +static double mean_summer_solstice (unsigned year) +{ + double y = year; + y -= 2000; + y *= 0.001; + return 2451716.56767 + 365241.62603 * y + 0.00325 * (y * y) + 0.00888 * (y * y * y) - 0.00030 * (y * y * y * y); +} + +static double mean_autumnal_equinox (unsigned year) +{ + double y = year; + y -= 2000; + y *= 0.001; + return 2451810.21715 + 365242.01767 * y - 0.11575 * (y * y) + 0.00337 * (y * y * y) + 0.00078 * (y * y * y * y); +} + +static double mean_winter_solstice (unsigned year) +{ + double y = year; + y -= 2000; + y *= 0.001; + return 2451900.05952 + 365242.74049 * y - 0.06223 * (y * y) - 0.00823 * (y * y * y) + 0.00032 * (y * y * y * y); +} + + +static double orbital_periodic_terms (double t) +{ +#define N 24 + const double A[N] = {485, 203, 199, 182, 156, 136, 77, 74, 70, 58, 52, 50, 45, + 44, 29, 18, 17, 16, 14, 12, 12, 12, 9, 8 + }; + const double B[N] = {D2R (324.96), D2R (337.23), D2R (342.08), D2R (27.85), + D2R (73.14), D2R (171.52), D2R (222.54), D2R (296.72), + D2R (243.58), D2R (119.81), D2R (297.17), D2R (21.02), + D2R (247.54), D2R (325.15), D2R (60.93), D2R (155.12), + D2R (288.79), D2R (198.04), D2R (199.76), D2R (95.39), + D2R (287.11), D2R (320.81), D2R (227.73), D2R (15.45) + }; + const double C[N] = {D2R (1934.136), D2R (32964.467), D2R (20.186), + D2R (445267.112), D2R (45036.886), D2R (22518.443), + D2R (65928.934), D2R (3034.906), D2R (9037.513), + D2R (33718.147), D2R (150.678), D2R (2281.226), + D2R (29929.562), D2R (31555.956), D2R (4443.417), + D2R (67555.328), D2R (4562.452), D2R (62894.029), + D2R (31436.921), D2R (14577.848), D2R (31931.756), + D2R (34777.259), D2R (1222.114), D2R (16859.074) + }; + double s = 0; + unsigned i; + + for (i = 0; i < N; ++i) + s += A[i] * cos (B[i] + (C[i] * t)); + + return s; +} + + +static double mean_to_real (double j0) +{ + + double t = (j0 - 2451545.) / 36525.; + double w = D2R ((35999.373 * t) - 2.47); + double dl = 1 + 0.0334 * cos (w) + 0.0007 * cos (2. * w); + double s = orbital_periodic_terms (t); + +#if 0 + printf ("j0=%.6f\r\n", j0); + printf ("t=%.6f\r\n", t); + printf ("w=%.6f\r\n", w); + printf ("dl=%.6f\r\n", dl); + printf ("s=%.6f\r\n", s); +#endif + + return j0 + ((0.00001 * s) / dl); +} + + + +double autumnal_equinox (unsigned y) +{ + return mean_to_real (mean_autumnal_equinox (y)); + // return mean_to_real (mean_summer_solstice (y)); +} diff --git a/stm32/app/gdb.script b/stm32/app/gdb.script new file mode 100644 index 0000000..7cf9d09 --- /dev/null +++ b/stm32/app/gdb.script @@ -0,0 +1,2 @@ +target remote localhost:3333 +cont diff --git a/stm32/app/hands.c b/stm32/app/hands.c new file mode 100644 index 0000000..5414d9e --- /dev/null +++ b/stm32/app/hands.c @@ -0,0 +1,90 @@ +#include "project.h" + + +unsigned hands_pos[HANDS]; +unsigned hands_ready; + + +static unsigned calc_minute_pos (MTIME *m) +{ + uint64_t p; + + p = m->minute; + p *= 100; + p += m->second; + p *= 1000; + p += m->nanosecond / 1000000; + + p *= MOTOR_STEPS; + p /= 10000000; + + + + return (unsigned) p; + +} + +static unsigned calc_hour_pos (MTIME *m) +{ + uint64_t p; + + p = m->hour; + p *= 100; + p += m->minute; + p *= 100; + p += m->second; + p *= 1000; + p += m->nanosecond / 1000000; + + p *= MOTOR_STEPS; + p /= 100000000; + + + + return (unsigned) p; +} + + + + +void hands_tick (void) +{ + EPOCH e; + UTC u; + MTIME m; + static unsigned old_pos[HANDS]; + unsigned i, p; + + + static uint32_t last; + + if ((ticks - last) < 100) return; + + last = ticks; + + if (!rtc_ready) return; + + + e = rtc_get(); + u = time_epoch_to_utc (e); + m = time_to_metric (e, u); + + + hands_pos[0] = calc_hour_pos (&m); + hands_pos[1] = calc_minute_pos (&m); + hands_ready = 1; + + for (i = 0, p = 0; i < HANDS; ++i) { + if (hands_pos[i] != old_pos[i]) p++; + + old_pos[i] = hands_pos[i]; + + } + + if (p) { + time_print_utc ("UTC: ", &u, NULL); + time_print_metric ("Metric: ", &m, NULL); + printf ("Hands: hour %4d/%4d min %4d/%4d\r\n", hands_pos[0], MOTOR_STEPS, hands_pos[1], MOTOR_STEPS); + } + +} diff --git a/stm32/app/main.c b/stm32/app/main.c new file mode 100644 index 0000000..4722479 --- /dev/null +++ b/stm32/app/main.c @@ -0,0 +1,50 @@ +#include "project.h" + + + + + +int main (void) +{ + /*set up pll */ + rcc_clock_setup_pll (&rcc_hse_configs[RCC_HSE_CONFIG]); + + /*turn on clocks to periferals */ + rcc_periph_clock_enable (RCC_GPIOA); + rcc_periph_clock_enable (RCC_GPIOB); + rcc_periph_clock_enable (RCC_GPIOC); + rcc_periph_clock_enable (RCC_USART1); + rcc_periph_clock_enable (RCC_AFIO); + rcc_periph_clock_enable (RCC_PWR); + rcc_periph_clock_enable (RCC_BKP); + pwr_disable_backup_domain_write_protect(); + DWT_CTRL |= DWT_CTRL_CYCCNTENA; + + + nvic_set_priority (NVIC_SYSTICK_IRQ, 0x80); + nvic_set_priority (NVIC_USART1_IRQ, 0x40); + nvic_set_priority (NVIC_USB_HP_CAN_TX_IRQ, 0x40); + nvic_set_priority (NVIC_USB_LP_CAN_RX0_IRQ, 0x40); + nvic_set_priority (NVIC_RTC_IRQ, 0x10); + + MAP_OUTPUT_OD (LED1); + MAP_OUTPUT_OD (LED2); + + + usart_init(); + cdcacm_rings_init(); + rtc_init(); + + printf ("Startup:\r\n"); + + motor_init(); + ticker_init(); + usb_init(); + + + for (;;); + + + return 0; +} + diff --git a/stm32/app/motor.c b/stm32/app/motor.c new file mode 100644 index 0000000..392089b --- /dev/null +++ b/stm32/app/motor.c @@ -0,0 +1,75 @@ +#include "project.h" + + +static unsigned motor_pos[HANDS]; + + +static void coils (unsigned m, int a, int b, int c, int d) +{ + printf ("Motor %d: %+d %+d\r\n", m, a - b, c - d); +} + +static void step (unsigned m, int d) +{ + unsigned s = motor_pos[m]; + + if (d < 0) d += MOTOR_STEPS; + + s += d; + s %= MOTOR_STEPS; + + coils (m, !! ((s + 6) & 4), !! ((s + 1) & 4), !! ((s + 4) & 4), !! ((s + 7) & 4)); + + if (!m) + BKP_DR8 = motor_pos[0] = s; + else + BKP_DR9 = motor_pos[1] = s; + + +} + + + + + +void motor_tick (void) +{ + static uint32_t last; + unsigned i, d; + + if ((ticks - last) < 10) return; + + last = ticks; + + if (!hands_ready) return; + + //printf("HANDS: %d -> %d %d -> %d\r\n",hands_pos[0],motor_pos[0],hands_pos[1],motor_pos[1]); + + + for (i = 0; i < HANDS; ++i) { + d = MOTOR_STEPS + hands_pos[i]; + d -= motor_pos[i]; + d %= MOTOR_STEPS; + + if (d) { + if (d < (MOTOR_STEPS / 2)) + step (i, 1); + else + step (i, -1); + } + } +} + + + + +void motor_init (void) +{ + + motor_pos[0] = BKP_DR8; + motor_pos[1] = BKP_DR9; + + step (0, 0); + step (1, 0); + +} diff --git a/stm32/app/pins.h b/stm32/app/pins.h new file mode 100644 index 0000000..954396f --- /dev/null +++ b/stm32/app/pins.h @@ -0,0 +1,54 @@ +#ifndef _PINS_H_ +#define _PINS_H_ + +/* st seem to change these with every chip revision */ + +#define MAP_ANA(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, a ); \ + } while (0) + +#define MAP_AF(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, a ); \ + } while (0) + +/* STM32F1 doesn't have AF pull up, but also doesn't disconnect af inputs so just use regular pull up */ +#define MAP_AF_PU(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, a); \ + gpio_set( a ## _PORT, a); \ + } while (0) + +#define MAP_AF_OD(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, a ); \ + } while (0) + + +#define MAP_OUTPUT_PP(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, a ); \ + } while (0) + + +#define MAP_OUTPUT_OD(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, a ); \ + } while (0) + + +/* STM32F1 madly uses the output register to drive the other end of the resistor, so pull up */ +/* requires us to write a 1 there */ + +#define MAP_INPUT_PU(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, a); \ + gpio_set( a ## _PORT, a); \ + } while (0) + + +#define MAP_INPUT(a) do { \ + gpio_set_mode( a ## _PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, a); \ + } while (0) + + +#define CLEAR(a) gpio_clear( a ## _PORT, a) +#define SET(a) gpio_set( a ## _PORT, a) +#define GET(a) gpio_get( a ## _PORT, a) +#define TOGGLE(a) gpio_toggle( a ## _PORT, a) + +#endif diff --git a/stm32/app/project.h b/stm32/app/project.h new file mode 100644 index 0000000..fd71876 --- /dev/null +++ b/stm32/app/project.h @@ -0,0 +1,50 @@ +#include <stdlib.h> +#include <math.h> +#include <stdio.h> +#include <errno.h> + +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/usart.h> +#include <libopencm3/stm32/i2c.h> +#include <libopencm3/stm32/st_usbfs.h> +#include <libopencm3/stm32/rtc.h> +#include <libopencm3/stm32/pwr.h> +#include <libopencm3/stm32/f1/bkp.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/cortex.h> +#include <libopencm3/cm3/scb.h> +#include <libopencm3/cm3/dwt.h> +#include <libopencm3/usb/usbd.h> +#include <libopencm3/usb/hid.h> +#include <libopencm3/usb/dfu.h> +#include <libopencm3/usb/cdc.h> +#include <id.h> + + + +#define RCC_HSE_CONFIG RCC_CLOCK_HSE8_72MHZ +#define US (72) +#define MS (US * 1000) +#define HZ (MS * 1000) +#define MS_TO_TICKS(a) ((a) *2) + +#define TRACE do { printf("%s:%d\r\n",__FILE__,__LINE__); } while (0) + +#define DWT_FREQ 48000000 + +#define HANDS 2 +#define MOTOR_STEPS (1080 * 2) + +#include "board.h" +#include "ring.h" +#include "pins.h" +#include "time_fn.h" +#include "asm_fns.h" + +#include "prototypes.h" + + + +extern uint32_t dfu_flag; diff --git a/stm32/app/prototypes.h b/stm32/app/prototypes.h new file mode 100644 index 0000000..751ba25 --- /dev/null +++ b/stm32/app/prototypes.h @@ -0,0 +1,81 @@ +/* main.c */ +extern int main(void); +/* cdcacm.c */ +extern ring_t cdcacm_rx_ring; +extern ring_t cdcacm_tx_ring; +extern const struct usb_interface_descriptor comm_iface; +extern const struct usb_interface_descriptor data_iface; +extern const struct usb_iface_assoc_descriptor cdc_iface_assoc; +extern enum usbd_request_return_codes cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete); +extern void cdcacm_tick(void); +extern int cdcacm_write(char *ptr, int len); +extern void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue); +extern void cdcacm_rings_init(void); +/* dfu.c */ +extern const struct usb_dfu_descriptor dfu_function; +extern const struct usb_interface_descriptor dfu_iface; +extern const struct usb_iface_assoc_descriptor dfu_iface_assoc; +extern enum usbd_request_return_codes dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete); +/* ring.c */ +extern void ring_init(ring_t *r, uint8_t *buf, size_t len); +extern int ring_write_byte(ring_t *r, uint8_t c); +extern int ring_empty(ring_t *r); +extern int ring_read_byte(ring_t *r, uint8_t *c); +extern int ring_write(ring_t *r, uint8_t *buf, size_t len); +/* usart.c */ +extern ring_t usart_rx_ring; +extern ring_t usart_tx_ring; +extern void usart1_isr(void); +extern void usart_kick(void); +extern int _write(int file, char *ptr, int len); +extern void usart_init(void); +/* ticker.c */ +extern volatile uint32_t ticks; +extern unsigned led2; +extern void delay_us(uint32_t d); +extern void sys_tick_handler(void); +extern void ticker_init(void); +extern void delay_ms(uint32_t d); +/* dummy_kb.c */ +extern const struct usb_interface_descriptor dummy_kb_iface; +extern const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc; +/* usb.c */ +extern uint8_t usbd_control_buffer[128]; +extern usbd_device *usb_device; +extern void usb_hp_can_tx_isr(void); +extern void usb_lp_can_rx0_isr(void); +extern void usb_init(void); +/* rtc.c */ +extern volatile unsigned rtc_ready; +extern void rtc_isr(void); +extern EPOCH rtc_get(void); +extern void rtc_init(void); +/* time_fn.c */ +extern EPOCH time_epoch_sub(EPOCH a, EPOCH b); +extern EPOCH time_epoch_add(EPOCH a, EPOCH b); +extern UTC time_epoch_to_utc(EPOCH epoch); +extern EPOCH time_utc_to_epoch(UTC u); +extern void utc_to_str(char *dst, UTC *u); +extern void time_print_utc(const char *p, UTC *u, const char *t); +extern void time_print_epoch(const char *p, EPOCH e, const char *t); +extern double time_utc_to_tjd(UTC u); +extern EPOCH time_tjd_to_epoch(double tjd); +extern UTC time_tjd_to_utc(double tjd); +extern RA ra_normalize(RA r); +extern RA time_utc_to_ra(UTC u); +extern RA time_st_to_ra(ST st); +extern ST time_ra_to_st(RA r); +extern ST time_utc_to_lst(UTC u, double lon); +extern MTIME time_to_metric(EPOCH e, UTC u); +extern MTIME time_utc_to_metric(UTC u); +extern MTIME time_epoch_to_metric(EPOCH e); +extern void time_print_metric(const char *p, MTIME *m, const char *t); +/* events.c */ +extern double autumnal_equinox(unsigned y); +/* hands.c */ +extern unsigned hands_pos[2]; +extern unsigned hands_ready; +extern void hands_tick(void); +/* motor.c */ +extern void motor_tick(void); +extern void motor_init(void); diff --git a/stm32/app/ring.c b/stm32/app/ring.c new file mode 100644 index 0000000..26bba3a --- /dev/null +++ b/stm32/app/ring.c @@ -0,0 +1,64 @@ +#include "project.h" + + +static inline size_t +ring_next (ring_t *r, size_t p) +{ + p++; + + if (p >= r->size) + p -= r->size; + + return p; +} + +void +ring_init (ring_t *r, uint8_t *buf, size_t len) +{ + r->data = buf; + r->size = len; + r->write = 0; + r->read = 0; +} + +int +ring_write_byte (ring_t *r, uint8_t c) +{ + size_t n = ring_next (r, r->write); + + if (n == r->read) + return -1; + + r->data[r->write] = c; + r->write = n; + return 0; +} + +int ring_empty (ring_t *r) +{ + return (r->read == r->write); +} + +int +ring_read_byte (ring_t *r, uint8_t *c) +{ + size_t n = ring_next (r, r->read); + + if (r->read == r->write) + return -1; + + *c = r->data[r->read]; + r->read = n; + return 0; +} + +int +ring_write (ring_t *r, uint8_t *buf, size_t len) +{ + while (len--) { + if (ring_write_byte (r, * (buf++))) + return -1; + } + + return 0; +} diff --git a/stm32/app/ring.h b/stm32/app/ring.h new file mode 100644 index 0000000..ba8887b --- /dev/null +++ b/stm32/app/ring.h @@ -0,0 +1,7 @@ +typedef struct ring +{ + uint8_t *data; + size_t size; + size_t write; + size_t read; +} ring_t; diff --git a/stm32/app/rtc.c b/stm32/app/rtc.c new file mode 100644 index 0000000..0030cfd --- /dev/null +++ b/stm32/app/rtc.c @@ -0,0 +1,170 @@ +#include "project.h" + +static volatile uint32_t hz = HZ; +static volatile uint32_t cycle_ref; +static volatile uint32_t rtc_ref; + +#define RTC_IN_LH 0x21f7 +#define RTC_IN_UH 0x6a6d + +static EPOCH rtc_offset; +static uint16_t rtc_half; + +volatile unsigned rtc_ready; + + + + +static EPOCH bkp_read_off (void) +{ + EPOCH e; + uint64_t v; + + v = BKP_DR1 & 0xffff; + v <<= 16; + v |= (BKP_DR2 & 0xffff); + v <<= 16; + v |= (BKP_DR3 & 0xffff); + v <<= 16; + v |= (BKP_DR4 & 0xffff); + + e.s = (int64_t) v; + + v = BKP_DR5 & 0xffff; + v <<= 16; + v |= (BKP_DR6 & 0xffff); + + e.ns = (int64_t) v; + + return e; +} + +static void bkp_write_off (EPOCH e) +{ + uint64_t v; + + v = (uint64_t) e.s; + + BKP_DR4 = (uint16_t) (v & 0xffff); + v >>= 16; + BKP_DR3 = (uint16_t) (v & 0xffff); + v >>= 16; + BKP_DR2 = (uint16_t) (v & 0xffff); + v >>= 16; + BKP_DR1 = (uint16_t) (v & 0xffff); + + v = (uint64_t) e.ns; + + BKP_DR6 = (uint16_t) (v & 0xffff); + v >>= 16; + BKP_DR5 = (uint16_t) (v & 0xffff); + +} + + + +void rtc_isr (void) +{ + uint32_t now; + static uint32_t then; + uint32_t v; + static int warm_up = 3; + + + now = DWT_CYCCNT; + compiler_mb(); + rtc_clear_flag (RTC_SEC); + + v = rtc_get_counter_val(); + + TOGGLE (LED1); + + cycle_ref = now; + + if (warm_up) warm_up--; + else hz = now - then; + + + switch (rtc_half) { + case RTC_IN_LH: + if (! (v & 0x8000000)) break; + + BKP_DR7 = rtc_half = RTC_IN_UH; + break; + + case RTC_IN_UH: + if (v & 0x8000000) break; + + BKP_DR7 = rtc_half = RTC_IN_LH; + rtc_offset.s += 0x100000000ULL; + bkp_write_off (rtc_offset); + break; + + default: + if (v & 0x8000000) + BKP_DR7 = rtc_half = RTC_IN_UH; + else + BKP_DR7 = rtc_half = RTC_IN_LH; + } + + + compiler_mb(); + rtc_ref = v; + rtc_ready = 1; + + + // printf ("Ctr %d %u %u\r\n", (int) v, (int) (now - then),(unsigned) rtc_offset.s); + + then = now; +} + + +EPOCH rtc_get (void) +{ + EPOCH e, o; + uint32_t h, c, r1, r2; + uint32_t now = DWT_CYCCNT; + + do { + r1 = rtc_ref; + compiler_mb(); + c = cycle_ref; + h = hz; + o = rtc_offset; + compiler_mb(); + r2 = rtc_ref; + } while (r1 != r2); + + now -= c; + + e.ns = now; + e.ns *= 1000000000ULL; + + if (h) e.ns /= h; + else e.ns /= HZ; + + e.s = r1; + + return time_epoch_add (e, o); +} + + +void rtc_init (void) +{ + rtc_offset = bkp_read_off(); + rtc_half = BKP_DR7; + +#if 1 + rtc_offset.s = 1637490753; + rtc_offset.ns = 498866999; + bkp_write_off (rtc_offset); +#endif + + + rtc_auto_awake (RCC_LSE, 0x7fff); //32768Hz + rtc_interrupt_enable (RTC_SEC); + nvic_enable_irq (NVIC_RTC_IRQ); + +} + + diff --git a/stm32/app/ticker.c b/stm32/app/ticker.c new file mode 100644 index 0000000..f124307 --- /dev/null +++ b/stm32/app/ticker.c @@ -0,0 +1,74 @@ +#include "project.h" + + +volatile uint32_t ticks; +static uint32_t scale = 7; + +unsigned led2 = 1000; + + + +void +delay_us (uint32_t d) +{ + d *= scale; + + while (d--) + __asm__ ("nop"); +} + +void +sys_tick_handler (void) +{ + ticks++; + cdcacm_tick(); + hands_tick(); + motor_tick(); + + if (led2) + led2--; + + if (led2) + CLEAR (LED2); + + else + SET (LED2); +} + +void +ticker_init (void) +{ + uint32_t v, w; + /*Start periodic timer */ + systick_set_clocksource (STK_CSR_CLKSOURCE_AHB_DIV8); + /* 72MHz / 8 = > 9Mhz */ + systick_set_reload (9000); + /* 9MHz / 9000 => 1kHz */ + systick_interrupt_enable(); + systick_counter_enable(); + + /*Calibrate the delay loop */ + do { + scale--; + v = ticks; + + while (v == ticks) + ; + + delay_us (1000); + w = ticks; + v++; + w -= v; + } while (w); + +} + + +void delay_ms (uint32_t d) +{ + uint32_t v = ticks; + + while ((ticks - v) < d); +} + + diff --git a/stm32/app/time_fn.c b/stm32/app/time_fn.c new file mode 100644 index 0000000..825d90f --- /dev/null +++ b/stm32/app/time_fn.c @@ -0,0 +1,650 @@ +#include <math.h> +#include "project.h" + +static int is_leap (unsigned year) +{ + if (year % 4) + return 0; + + if (year % 100) + return 1; + + if (year % 400) + return 0; + + return 1; +} + +EPOCH time_epoch_sub (EPOCH a, EPOCH b) +{ + EPOCH ret; + + ret.ns = a.ns - b.ns; + ret.s = a.s - b.s; + + if (!ret.s) return ret; + + if (ret.ns < 0) { + ret.s--; + ret.ns += 1000000000; + } + + return ret; +} + + +EPOCH time_epoch_add (EPOCH a, EPOCH b) +{ + EPOCH ret; + + ret.ns = a.ns + b.ns; + ret.s = a.s + b.s; + + while (ret.ns > 1000000000) { + ret.s++; + ret.ns -= 1000000000; + } + + return ret; +} + + +UTC time_epoch_to_utc (EPOCH epoch) +{ + UTC u = {0}; + uint64_t day; + unsigned y400, y100, y4; + + day = epoch.s / 86400; + epoch.s -= day * 86400; + + day += 134774; + + u.wday = day % 7; + u.wday++; + + + y400 = day / 146097; /*146097 days in 400 years */ + day -= (y400 * 146097); + + y100 = day / 36524; /*36524 days in 100 years */ + day -= (y100 * 36524); + + y4 = day / 1461; /*1461 days in 4 years */ + day -= (y4 * 1461); + + /* This may look redundant but 31 Dec in year 4 is special case */ + if (day < 1095) { /*1095 days in 3 years */ + u.year = day / 365; /*365 days in a year */ + day -= (365 * u.year); + } else { + u.year = 3; + day -= 1095; + } + + + /* Now put it all back together */ + u.year += 1601; + u.year += 4 * y4; + u.year += 100 * y100; + u.year += 400 * y400; + + + u.jday = day + 1; + + u.is_leap = is_leap (u.year); + + + if (!u.is_leap) { + /*Days and months for ordinary years */ + if (u.jday < 32) { + u.month = 1; + u.mday = u.jday; + } else if (u.jday < 60) { + u.month = 2; + u.mday = u.jday - 31; + } else if (u.jday < 91) { + u.month = 3; + u.mday = u.jday - 59; + } else if (u.jday < 121) { + u.month = 4; + u.mday = u.jday - 90; + } else if (u.jday < 152) { + u.month = 5; + u.mday = u.jday - 120; + } else if (u.jday < 182) { + u.month = 6; + u.mday = u.jday - 151; + } else if (u.jday < 213) { + u.month = 7; + u.mday = u.jday - 181; + } else if (u.jday < 244) { + u.month = 8; + u.mday = u.jday - 212; + } else if (u.jday < 274) { + u.month = 9; + u.mday = u.jday - 243; + } else if (u.jday < 305) { + u.month = 10; + u.mday = u.jday - 273; + } else if (u.jday < 335) { + u.month = 11; + u.mday = u.jday - 304; + } else { + u.month = 12; + u.mday = u.jday - 334; + } + } else { + /*And leap years */ + if (u.jday < 32) { + u.month = 1; + u.mday = u.jday; + } else if (u.jday < 61) { + u.month = 2; + u.mday = u.jday - 31; + } else if (u.jday < 92) { + u.month = 3; + u.mday = u.jday - 60; + } else if (u.jday < 122) { + u.month = 4; + u.mday = u.jday - 91; + } else if (u.jday < 153) { + u.month = 5; + u.mday = u.jday - 121; + } else if (u.jday < 183) { + u.month = 6; + u.mday = u.jday - 152; + } else if (u.jday < 214) { + u.month = 7; + u.mday = u.jday - 182; + } else if (u.jday < 245) { + u.month = 8; + u.mday = u.jday - 213; + } else if (u.jday < 275) { + u.month = 9; + u.mday = u.jday - 244; + } else if (u.jday < 306) { + u.month = 10; + u.mday = u.jday - 274; + } else if (u.jday < 336) { + u.month = 11; + u.mday = u.jday - 305; + } else { + u.month = 12; + u.mday = u.jday - 335; + } + } + + u.hour = epoch.s / 3600; + epoch.s -= u.hour * 3600; + u.minute = epoch.s / 60; + epoch.s -= u.minute * 60; + u.second = epoch.s; + + u.nanosecond = epoch.ns; + + return u; +} + +EPOCH time_utc_to_epoch (UTC u) +{ + unsigned y400; + unsigned y100; + unsigned y4; + + EPOCH ret; + + static int const mdays[] = + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static int const lmdays[] = + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; + + u.is_leap = is_leap (u.year); + + if (u.year < 100) u.year += 2000; + + + if (!u.jday) { + if (u.is_leap) + u.jday = u.mday + lmdays[u.month]; + else + u.jday = u.mday + mdays[u.month]; + } + + u.year -= 1601; + y400 = u.year / 400; + u.year -= y400 * 400; + y100 = u.year / 100; + u.year -= y100 * 100; + y4 = u.year / 4; + u.year -= y4 * 4; + + + + ret.s = u.jday - 1; + ret.s += u.year * 365; + ret.s += y4 * 1461; + ret.s += y100 * 36524; + ret.s += y400 * 146097; + + ret.s -= 134774; + + ret.s *= 86400; + + ret.s += u.second; + ret.s += u.minute * 60; + ret.s += u.hour * 3600; + + ret.ns = u.nanosecond; + + return ret; +} + +void utc_to_str (char *dst, UTC *u) +{ + const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"}; + const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + sprintf (dst, "%s %04d-%s-%02d %02d:%02d:%02d.%09d", dname[u->wday], u->year, mname[u->month], u->mday, u->hour, u->minute, u->second, u->nanosecond); +} + + +void time_print_utc (const char *p, UTC *u, const char *t) +{ + const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"}; + const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d %s\r\n", p ? p : "", dname[u->wday], u->year, mname[u->month], u->mday, u->hour, u->minute, u->second, u->nanosecond, t ? t : ""); +} + +void time_print_epoch (const char *p, EPOCH e, const char *t) +{ + UTC u = time_epoch_to_utc (e); + time_print_utc (p, &u, t); +} + + +double +time_utc_to_tjd (UTC u) +{ + unsigned y400; + unsigned y100; + unsigned y4; + + double ret; + unsigned jd; + + static int const mdays[] = + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static int const lmdays[] = + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; + + u.is_leap = is_leap (u.year); + + if (u.year < 100) + u.year += 2000; + + + if (!u.jday) { + if (u.is_leap) + u.jday = u.mday + lmdays[u.month]; + else + u.jday = u.mday + mdays[u.month]; + } + + u.year -= 1601; + y400 = u.year / 400; + u.year -= y400 * 400; + y100 = u.year / 100; + u.year -= y100 * 100; + y4 = u.year / 4; + u.year -= y4 * 4; + + jd = u.jday - 1; + jd += u.year * 365; + jd += y4 * 1461; + jd += y100 * 36524; + jd += y400 * 146097; + + + jd += 2305813; + jd -= 2451545; + + + + ret = (double) u.nanosecond; + ret /= 1000000000.; + ret += (double) u.second; + ret /= 60.; + ret += (double) u.minute; + ret /= 60.; + ret += (double) u.hour; + ret /= 24.; + + ret += .5; + + ret += (double) jd; + + return ret; +} + + +EPOCH time_tjd_to_epoch (double tjd) +{ + EPOCH e; + + + tjd -= 2440587.5; + + tjd *= 86400.; + e.s = (uint64_t) floor (tjd); + + tjd -= (double) e.s; + + tjd *= 1000000000.; + e.ns = (unsigned) floor (tjd); + + return e; +} + +UTC time_tjd_to_utc (double tjd) +{ + return time_epoch_to_utc (time_tjd_to_epoch (tjd)); +} + + + +RA ra_normalize (RA r) +{ + + while (r.ra < 0.) { + r.ra += 360.; + r.days--; + } + + if (r.ra >= 3600.0) { + r.days = (unsigned) (floor (r.ra / 360.) + .5); + r.ra = remainder (r.ra, 360.); + } else while (r.ra >= 360.0) { + r.ra -= 360.; + r.days++; + } + + return r; +} + + +RA time_utc_to_ra (UTC u) +{ + RA r; + double tjd = time_utc_to_tjd (u); + double T = tjd / 36525.; + + r.ra = + 280.46061837 + (360.98564736629 * tjd) + (0.000387933 * T * T) - + (T * T * T / 38710000.0); + + r.days = 0; + + return ra_normalize (r); +} + + + +RA time_st_to_ra (ST st) +{ + RA r; + unsigned i; + + r.days = st.days; + + i = st.hour; + i *= 60; + i += st.minute; + i *= 60; + i += st.second; + + r.ra = (double) st.nanosecond; + r.ra /= 1000000000.; + r.ra += (double) i; + + r.ra /= 240.; + + return r; +} + + + +ST +time_ra_to_st (RA r) +{ + ST ret; + unsigned i; + + r = ra_normalize (r); + + ret.days = r.days; + + r.ra *= 240.0; + + i = (int) (floor (r.ra) + .5); + r.ra -= (double) i; + r.ra *= 1000000000.; + + ret.nanosecond = (unsigned) (r.ra + .5); + ret.second = i % 60; + i /= 60; + ret.minute = i % 60; + i /= 60; + ret.hour = i; + + + return ret; +} + + + +ST time_utc_to_lst (UTC u, double lon) +{ + RA r; + + r = time_utc_to_ra (u); + + r.ra += lon; + + return time_ra_to_st (r); +} + + + +#if 0 +int time_ra_cmp (double a, double b) +{ + return (ra_normalize (a - b) < 180.) ? -1 : 1;; +} + + +/*Find the next occuring time for RA tra */ + +static int test_side (EPOCH m, double tra) +{ + + double ra; + UTC u; + + u = time_epoch_to_utc (m); + ra = time_utc_to_ra (u); + + return time_ra_cmp (ra, tra); +} + + +EPOCH time_ra_to_next_epoch (EPOCH l, double tra) +{ + EPOCH r, m; + unsigned n; + + int dog = 48; + + printf ("time_ra_to_next_epoch %.9f\n", tra); + + /* XXX: we should use newton raphson, but */ + /* 1) we're on team hooke */ + /* 2) we want to limit the domain of solutions */ + /* So IB works better */ + + + while ((test_side (l, tra) != 1) && dog--) + l.s += 3600; + + r = l; + + while ((test_side (r, tra) != -1) && dog--) + r.s += 3600; + + for (n = 0; n < 64; ++n) { + + m = time_epoch_sub (r, l); + + if (m.s < 0) { + m.s = 0; + m.ns = 0; + break; + } + + if (m.s & 1) + m.ns += 1000000000; + + m.s /= 2; + m.ns /= 2; + + m = time_epoch_add (l, m); + + if (test_side (m, tra) < 0) + r = m; + else + l = m; + } + + return m; +} + +#endif + + + + + +/* + * Returns the EPOCH for the start of the metric year which + * starts in the custumary year y + * + * the metric year begins on the autumnal equinox (at the paris observatory natch.) + */ +static EPOCH start_of_year (unsigned y) +{ + double tjd = autumnal_equinox (y); + UTC u; + + tjd += (2.3372305555 / 360); /* Offset of paris meridian from greenwich */ + + u = time_tjd_to_utc (tjd); + + u.hour = + u.minute = + u.second = + u.nanosecond = 0; + + return time_utc_to_epoch (u); +} + +MTIME time_to_metric (EPOCH e, UTC u) +{ + MTIME ret; + + static EPOCH year_start, year_end; + static unsigned year; + + unsigned s; + unsigned d; + + double fd; + + EPOCH equinox; + + if ((e.s > year_end.s) || (e.s < year_start.s)) { + /*calculate the equinox in this customary year */ + + equinox = start_of_year (u.year); + + if (e.s < equinox.s) { + year_start = start_of_year (u.year - 1); + year_end = equinox; + year = u.year - 1792; + } else { + year_start = equinox; + year_end = start_of_year (u.year + 1); + year = u.year - 1791; + } + } + + ret.year = year; + + e = time_epoch_sub (e, year_start); + s = e.s; + d = s / 86400; + s -= d * 86400; + + ret.jday = d; + + ret.month = (d / 30) + 1; + ret.mday = (d % 30) + 1; + ret.wday = d % 10; + + /* Now for the horror of time of day */ + + fd = (double) e.ns; + fd /= 1000000000.; + fd += (double) s; + fd /= 86400.; + fd *= 100000; + + s = (int) fd; + fd -= (double) s; + fd *= 1000000000.; + + ret.nanosecond = (int) fd; + + ret.second = s % 100; + s -= ret.second; + s /= 100; + + ret.minute = s % 100; + s -= ret.minute; + s /= 100; + + ret.hour = s; + + return ret; +} + + +MTIME time_utc_to_metric (UTC u) +{ + return time_to_metric (time_utc_to_epoch (u), u); +} + + +MTIME time_epoch_to_metric (EPOCH e) +{ + return time_to_metric (e, time_epoch_to_utc (e)); +} + + + +void time_print_metric (const char *p, MTIME *m, const char *t) +{ + const char *dname[] = {"Pri", "Duo", "Tri", "Qua", "Qui", "Sex", "Sep", "Oct", "Non", "Dec" }; + const char *mname[] = {"", "Ven", "Bru", "Fri", "Niv", "Plu", "Ven", "Ger", "Flo", "Pra", "Mes", "The", "Fru", "San"}; + printf ("%s%s %03d-%s-%02d %01d:%02d:%02d.%09d %s\r\n", p ? p : "", dname[m->wday], m->year, mname[m->month], m->mday, m->hour, m->minute, m->second, m->nanosecond, t ? t : ""); +} + + diff --git a/stm32/app/time_fn.h b/stm32/app/time_fn.h new file mode 100644 index 0000000..0775a0f --- /dev/null +++ b/stm32/app/time_fn.h @@ -0,0 +1,47 @@ +typedef struct { + unsigned year; + unsigned is_leap; + unsigned jday; + unsigned month; + unsigned mday; + unsigned wday; + unsigned hour; + unsigned minute; + unsigned second; + unsigned nanosecond; +} UTC; + +typedef struct { + int64_t s; + int64_t ns; +} EPOCH; + + +typedef struct { + unsigned days; + double ra; +} RA; + +typedef struct { + unsigned days; + unsigned hour; + unsigned minute; + unsigned second; + unsigned nanosecond; +} ST; + + +typedef struct { + unsigned year; + unsigned is_leap; + unsigned jday; + unsigned month; + unsigned mday; + unsigned wday; + unsigned hour; + unsigned minute; + unsigned second; + unsigned nanosecond; +} MTIME; + + diff --git a/stm32/app/usart.c b/stm32/app/usart.c new file mode 100644 index 0000000..6b44656 --- /dev/null +++ b/stm32/app/usart.c @@ -0,0 +1,88 @@ +#include "project.h" + +#define BUFFER_SIZE 512 + +ring_t usart_rx_ring; +static uint8_t usart_rx_ring_buf[BUFFER_SIZE]; + +ring_t usart_tx_ring; +static uint8_t usart_tx_ring_buf[BUFFER_SIZE]; + +void +usart1_isr (void) +{ + uint8_t data; + + /* Check if we were called because of RXNE. */ + if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART1) & USART_SR_RXNE) != 0)) { + /* Retrieve the data from the peripheral. */ + data = usart_recv (USART1); + ring_write_byte (&usart_rx_ring, data); + } + + /* Check if we were called because of TXE. */ + if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART1) & USART_SR_TXE) != 0)) { + if (ring_read_byte (&usart_tx_ring, &data)) { + /*No more data, Disable the TXE interrupt, it's no longer needed. */ + USART_CR1 (USART1) &= ~USART_CR1_TXEIE; + } else + usart_send (USART1, data); + } +} + +void usart_kick (void) +{ + if (!ring_empty (&usart_tx_ring)) + USART_CR1 (USART1) |= USART_CR1_TXEIE; +} + + +int +_write (int file, char *ptr, int len) +{ + int ret; + + if (file == 1) { + ret = ring_write (&usart_tx_ring, (uint8_t *) ptr, len); + usart_kick(); + ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len); + + if (ret < 0) + ret = -ret; + + return ret; + } + + errno = EIO; + return -1; +} + + + + +void +usart_init (void) +{ + ring_init (&usart_rx_ring, usart_rx_ring_buf, sizeof (usart_rx_ring_buf)); + ring_init (&usart_tx_ring, usart_tx_ring_buf, sizeof (usart_tx_ring_buf)); + /* Enable the USART1 interrupt. */ + nvic_enable_irq (NVIC_USART1_IRQ); + + MAP_AF (USART1_TX); + MAP_AF_PU (USART1_RX); + + /* Setup UART1 parameters. */ + usart_set_baudrate (USART1, 115200); + usart_set_databits (USART1, 8); + usart_set_stopbits (USART1, USART_STOPBITS_1); + usart_set_parity (USART1, USART_PARITY_NONE); + usart_set_flow_control (USART1, USART_FLOWCONTROL_NONE); + usart_set_mode (USART1, USART_MODE_TX_RX); + + /* Enable USART1 Receive interrupt. */ + USART_CR1 (USART1) |= USART_CR1_RXNEIE; + /* Finally enable USART1. */ + usart_enable (USART1); +} diff --git a/stm32/app/usb.c b/stm32/app/usb.c new file mode 100644 index 0000000..e644270 --- /dev/null +++ b/stm32/app/usb.c @@ -0,0 +1,148 @@ +#include "project.h" + +#define USB_DM GPIO11 +#define USB_DM_PORT GPIOA +#define USB_DP GPIO12 +#define USB_DP_PORT GPIOA + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; +usbd_device *usb_device; + +static const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0xef, + .bDeviceSubClass = 0x02, + .bDeviceProtocol = 0x01, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0xff03, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + + +static const struct usb_interface ifaces[] = { + { + .num_altsetting = 1, + .altsetting = &dummy_kb_iface, + .iface_assoc = &dummy_kb_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &dfu_iface, + .iface_assoc = &dfu_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &comm_iface, + .iface_assoc = &cdc_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &data_iface, + }, +}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 4, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces, +}; +#define N_USB_STRINGS (sizeof(usb_strings)/sizeof(usb_strings[0])) + +static const char *usb_strings[] = { + VENDOR_NAME, /*1*/ + PRODUCT_NAME, /*2*/ + SERIAL_NUMBER, /*3*/ + "dummy device", /*4*/ + "DFU interface", /*5*/ + "Debug interface", /*6*/ +}; + +void usb_hp_can_tx_isr (void) +{ + usbd_poll (usb_device); +} + +void usb_lp_can_rx0_isr (void) +{ + usbd_poll (usb_device); +} + +static enum usbd_request_return_codes control_request (usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) +{ + enum usbd_request_return_codes ret; + + ret = dfu_control_request (usbd_dev, req, buf, len, complete); + + if (ret != USBD_REQ_NEXT_CALLBACK) + return ret; + + ret = cdcacm_control_request (usbd_dev, req, buf, len, complete); + + if (ret != USBD_REQ_NEXT_CALLBACK) + return ret; + + return USBD_REQ_NOTSUPP; +} + +static void set_config (usbd_device *usbd_dev, uint16_t wValue) +{ + + cdcacm_set_config (usbd_dev, wValue); + + usbd_register_control_callback (usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + control_request); + +} + + + +void usb_init (void) +{ + /*Force USB reset */ + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); + gpio_clear (GPIOA, GPIO12); + gpio_clear (GPIOA, GPIO13); + delay_us (50000); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO11); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12); + + + usb_device = usbd_init (&st_usbfs_v1_usb_driver, + &dev, + &config, + usb_strings, + N_USB_STRINGS, + usbd_control_buffer, + sizeof (usbd_control_buffer)); + + usbd_register_set_config_callback (usb_device, set_config); + + nvic_enable_irq (NVIC_USB_HP_CAN_TX_IRQ); + nvic_enable_irq (NVIC_USB_LP_CAN_RX0_IRQ); + + + +} + + diff --git a/stm32/boot/Makefile b/stm32/boot/Makefile new file mode 100644 index 0000000..4891184 --- /dev/null +++ b/stm32/boot/Makefile @@ -0,0 +1,48 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + + +CSRCS=usbdfu.c +PROG = usbdfu + +CPROTO=cproto +V=1 +BINARY = ${PROG} +OBJS = ${CSRCS:%.c=%.o} + +include ../Makefile.include + +CFLAGS += -I.. + +ds: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + +debug: ${PROG}.elf + ${PREFIX}-gdb -x gdb.script ${PROG}.elf + +reset: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + -c "init" -c "reset run" \ + -c shutdown + +tidy: + astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} || astyle -A3 -s2 -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} + diff --git a/stm32/boot/gdb.script b/stm32/boot/gdb.script new file mode 100644 index 0000000..7cf9d09 --- /dev/null +++ b/stm32/boot/gdb.script @@ -0,0 +1,2 @@ +target remote localhost:3333 +cont diff --git a/stm32/boot/project.h b/stm32/boot/project.h new file mode 100644 index 0000000..0323569 --- /dev/null +++ b/stm32/boot/project.h @@ -0,0 +1,23 @@ +#include <stdlib.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/usart.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/usb/usbd.h> +#include <libopencm3/usb/hid.h> + +#define INCLUDE_DFU_INTERFACE + + +#ifdef INCLUDE_DFU_INTERFACE +#include <libopencm3/cm3/scb.h> +#include <libopencm3/usb/dfu.h> +#endif + +#include <stdio.h> +#include <errno.h> + +#include "ring.h" + +#include "prototypes.h" diff --git a/stm32/boot/prototypes.h b/stm32/boot/prototypes.h new file mode 100644 index 0000000..45d399c --- /dev/null +++ b/stm32/boot/prototypes.h @@ -0,0 +1,18 @@ +/* usbdfu.c */ +extern uint8_t usbd_control_buffer[1024]; +extern const struct usb_device_descriptor dev; +extern const struct usb_dfu_descriptor dfu_function; +extern const struct usb_interface_descriptor iface; +extern const struct usb_interface ifaces[]; +extern const struct usb_config_descriptor config; +extern int main(void); +/* ring.c */ +extern void ring_init(ring_t *r, uint8_t *buf, size_t len); +extern int ring_write_byte(ring_t *r, uint8_t c); +extern int ring_read_byte(ring_t *r, uint8_t *c); +extern int ring_write(ring_t *r, uint8_t *buf, size_t len); +/* usart.c */ +extern void usart1_isr(void); +extern int _write(int file, char *ptr, int len); +extern void usart_queue(uint8_t d); +extern void usart_init(void); diff --git a/stm32/boot/usbdfu.c b/stm32/boot/usbdfu.c new file mode 100644 index 0000000..7cba7f9 --- /dev/null +++ b/stm32/boot/usbdfu.c @@ -0,0 +1,334 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/flash.h> +#include <libopencm3/cm3/scb.h> +#include <libopencm3/usb/usbd.h> +#include <libopencm3/usb/dfu.h> + +#include <id.h> + +#define APP_ADDRESS 0x08002000 + +/* Commands sent with wBlockNum == 0 as per ST implementation. */ +#define CMD_SETADDR 0x21 +#define CMD_ERASE 0x41 + +void usb_set_config (usbd_device *usbd_dev, uint16_t wValue); + +/* We need a special large control buffer for this device: */ +uint8_t usbd_control_buffer[1024]; + +static enum dfu_state usbdfu_state = STATE_DFU_IDLE; + +extern uint32_t dfu_flag; + +static struct { + uint8_t buf[sizeof (usbd_control_buffer)]; + uint16_t len; + uint32_t addr; + uint16_t blocknum; +} prog; + +const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0xdf11, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +const struct usb_dfu_descriptor dfu_function = { + .bLength = sizeof (struct usb_dfu_descriptor), + .bDescriptorType = DFU_FUNCTIONAL, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, + .wDetachTimeout = 255, + .wTransferSize = 1024, + .bcdDFUVersion = 0x011A, +}; + +const struct usb_interface_descriptor iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = 0xFE, /* Device Firmware Upgrade */ + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 2, + + /* The ST Microelectronics DfuSe application needs this string. + * The format isn't documented... */ + .iInterface = 4, + + .extra = &dfu_function, + .extralen = sizeof (dfu_function), +}; + +const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = &iface, + } +}; + +const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xC0, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + VENDOR_NAME, + PRODUCT_NAME " (dfu mode)", + SERIAL_NUMBER, + /* This string is used by ST Microelectronics' DfuSe utility. */ + "@Internal Flash /0x08000000/8*001Ka,56*001Kg", +}; +#define N_USB_STRINGS (sizeof(usb_strings)/sizeof(usb_strings[0])) + +static void +delay_us (uint32_t d) +{ + d *= 7; + + while (d--) + __asm__ ("nop"); +} + + +static uint8_t usbdfu_getstatus (usbd_device *usbd_dev, uint32_t *bwPollTimeout) +{ + (void)usbd_dev; + + switch (usbdfu_state) { + case STATE_DFU_DNLOAD_SYNC: + usbdfu_state = STATE_DFU_DNBUSY; + *bwPollTimeout = 100; + return DFU_STATUS_OK; + + case STATE_DFU_MANIFEST_SYNC: + /* Device will reset when read is complete. */ + usbdfu_state = STATE_DFU_MANIFEST; + return DFU_STATUS_OK; + + default: + return DFU_STATUS_OK; + } +} + +static void usbdfu_getstatus_complete (usbd_device *usbd_dev, struct usb_setup_data *req) +{ + int i; + (void)req; + (void)usbd_dev; + + switch (usbdfu_state) { + case STATE_DFU_DNBUSY: + flash_unlock(); + + if (prog.blocknum == 0) { + switch (prog.buf[0]) { + case CMD_ERASE: { + uint32_t *dat = (uint32_t *) (prog.buf + 1); + flash_erase_page (*dat); + } + break; + + case CMD_SETADDR: { + uint32_t *dat = (uint32_t *) (prog.buf + 1); + prog.addr = *dat; + } + } + } else { + uint32_t baseaddr = prog.addr + ((prog.blocknum - 2) * + dfu_function.wTransferSize); + + for (i = 0; i < prog.len; i += 2) { + uint16_t *dat = (uint16_t *) (prog.buf + i); + flash_program_half_word (baseaddr + i, + *dat); + } + } + + flash_lock(); + + /* Jump straight to dfuDNLOAD-IDLE, skipping dfuDNLOAD-SYNC. */ + usbdfu_state = STATE_DFU_DNLOAD_IDLE; + return; + + case STATE_DFU_MANIFEST: + /* USB device must detach, we just reset... */ + scb_reset_system(); + return; /* Will never return. */ + + default: + ; + } + +} + +static enum usbd_request_return_codes usbdfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, + uint16_t *len, usbd_control_complete_callback *complete) +{ + + if ((req->bmRequestType & 0x7F) != 0x21) + return USBD_REQ_NEXT_CALLBACK; + + switch (req->bRequest) { + case DFU_DNLOAD: + if ((len == NULL) || (*len == 0)) { + usbdfu_state = STATE_DFU_MANIFEST_SYNC; + } else { + /* Copy download data for use on GET_STATUS. */ + prog.blocknum = req->wValue; + prog.len = *len; + memcpy (prog.buf, *buf, *len); + usbdfu_state = STATE_DFU_DNLOAD_SYNC; + } + return USBD_REQ_HANDLED; + + case DFU_CLRSTATUS: + + /* Clear error and return to dfuIDLE. */ + if (usbdfu_state == STATE_DFU_ERROR) + usbdfu_state = STATE_DFU_IDLE; + + return USBD_REQ_HANDLED; + + case DFU_ABORT: + /* Abort returns to dfuIDLE state. */ + usbdfu_state = STATE_DFU_IDLE; + return USBD_REQ_HANDLED; + + case DFU_UPLOAD: + /* Upload not supported for now. */ + return USBD_REQ_NOTSUPP; + + case DFU_GETSTATUS: { + uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ + (*buf)[0] = usbdfu_getstatus (usbd_dev, &bwPollTimeout); + (*buf)[1] = bwPollTimeout & 0xFF; + (*buf)[2] = (bwPollTimeout >> 8) & 0xFF; + (*buf)[3] = (bwPollTimeout >> 16) & 0xFF; + (*buf)[4] = usbdfu_state; + (*buf)[5] = 0; /* iString not used here */ + *len = 6; + *complete = usbdfu_getstatus_complete; + return USBD_REQ_HANDLED; + } + + case DFU_GETSTATE: + /* Return state with no state transision. */ + *buf[0] = usbdfu_state; + *len = 1; + return USBD_REQ_HANDLED; + } + + return USBD_REQ_NEXT_CALLBACK; +} + +static void usb_reset (void) +{ + /*Force USB reset */ + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); + gpio_clear (GPIOA, GPIO11); + gpio_clear (GPIOA, GPIO12); + + delay_us (5000); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO11); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12); +} + + +void +usb_set_config (usbd_device *usbd_dev, uint16_t wValue) +{ + (void) wValue; + (void) usbd_dev; + + usbd_register_control_callback ( + usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + usbdfu_control_request); + +} + +int main (void) +{ + usbd_device *usbd_dev; + + rcc_periph_clock_enable (RCC_GPIOA); + rcc_periph_reset_pulse (RST_USB); + + if (dfu_flag != 0xfee1dead) { + /* Boot the application if it's valid. */ + if ((* (volatile uint32_t *)APP_ADDRESS & 0x2FFE0000) == 0x20000000) { + /* Set vector table base address. */ + SCB_VTOR = APP_ADDRESS & 0xFFFF; + /* Initialise master stack pointer. */ + asm volatile ("msr msp, %0"::"g" + (* (volatile uint32_t *)APP_ADDRESS)); + /* Jump to application. */ + (* (void (* *)()) (APP_ADDRESS + 4))(); + } + } + + usb_reset(); + + dfu_flag = 0; + + rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_HSI_48MHZ]); + + rcc_periph_clock_enable (RCC_GPIOC); + + gpio_set_mode (GPIOC, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); + gpio_set (GPIOC, GPIO11); + + + usbd_dev = usbd_init (&st_usbfs_v1_usb_driver, &dev, &config, usb_strings, N_USB_STRINGS, usbd_control_buffer, sizeof (usbd_control_buffer)); + + usbd_register_set_config_callback (usbd_dev, usb_set_config); + + gpio_clear (GPIOC, GPIO11); + + while (1) + usbd_poll (usbd_dev); +} diff --git a/stm32/boot/usbdfu.ld b/stm32/boot/usbdfu.ld new file mode 100644 index 0000000..498bcea --- /dev/null +++ b/stm32/boot/usbdfu.ld @@ -0,0 +1,40 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Linker script for Olimex STM32-H103 (STM32F103RBT6, 128K flash, 20K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE cortex-m-generic.ld + +dfu_shared_location = ORIGIN(ram) + LENGTH(ram) - 1024; + +SECTIONS +{ + .dfu_shared dfu_shared_location :{ + dfu_flag = .; + } +} + diff --git a/stm32/docs/Astronomical Algorithms.pdf b/stm32/docs/Astronomical Algorithms.pdf Binary files differnew file mode 100644 index 0000000..52cc63a --- /dev/null +++ b/stm32/docs/Astronomical Algorithms.pdf diff --git a/stm32/docs/rm0008.pdf b/stm32/docs/rm0008.pdf Binary files differnew file mode 100644 index 0000000..8f3d0e1 --- /dev/null +++ b/stm32/docs/rm0008.pdf diff --git a/stm32/id.h b/stm32/id.h new file mode 100644 index 0000000..d27ecf7 --- /dev/null +++ b/stm32/id.h @@ -0,0 +1,4 @@ +#define VENDOR_NAME "HP" +#define PRODUCT_NAME "DDC Debug Dongle" +#define SERIAL_NUMBER "Serialy McSerialFace" + diff --git a/stm32/libopencm3 b/stm32/libopencm3 new file mode 160000 +Subproject a9cc6953817e0de1cad06662ce58a81607cd796 diff --git a/stm32/oocd/board/STM32F103R_BOARD.cfg b/stm32/oocd/board/STM32F103R_BOARD.cfg new file mode 100644 index 0000000..11217d2 --- /dev/null +++ b/stm32/oocd/board/STM32F103R_BOARD.cfg @@ -0,0 +1,6 @@ +# + +source [find target/stm32f1x.cfg] + +adapter_khz 500 + diff --git a/stm32/oocd/interface/j-link.cfg b/stm32/oocd/interface/j-link.cfg new file mode 100644 index 0000000..3e95768 --- /dev/null +++ b/stm32/oocd/interface/j-link.cfg @@ -0,0 +1,5 @@ +# +telnet_port 4444 +gdb_port 3333 + +source [find interface/jlink.cfg] diff --git a/stm32/oocd/interface/stlink-v2.cfg b/stm32/oocd/interface/stlink-v2.cfg new file mode 100644 index 0000000..0985230 --- /dev/null +++ b/stm32/oocd/interface/stlink-v2.cfg @@ -0,0 +1,11 @@ +# +telnet_port 4444 +gdb_port 3333 + +#interface hla +#hla_layout stlink +#hla_device_desc "ST-LINK/V2" +#hla_vid_pid 0x0483 0x3748 + +source [find interface/stlink-v2.cfg] + diff --git a/stm32/oocd/stm32-f103.cfg b/stm32/oocd/stm32-f103.cfg new file mode 100644 index 0000000..0809223 --- /dev/null +++ b/stm32/oocd/stm32-f103.cfg @@ -0,0 +1,6 @@ +# +telnet_port 4444 +gdb_port 3333 + +source [find interface/jlink.cfg] +source [find target/stm32f1x.cfg] diff --git a/stm32/tools/dfuse-pack.py b/stm32/tools/dfuse-pack.py new file mode 100755 index 0000000..c0a5f0a --- /dev/null +++ b/stm32/tools/dfuse-pack.py @@ -0,0 +1,256 @@ +#!/usr/bin/python + +# Written by Antonio Galea - 2010/11/18 +# Distributed under Gnu LGPL 3.0 +# see http://www.gnu.org/licenses/lgpl-3.0.txt + +import sys,struct,zlib,os +import binascii +from optparse import OptionParser + +try: + from intelhex import IntelHex +except ImportError: + IntelHex = None + +DEFAULT_DEVICE="0x0483:0xdf11" +DEFAULT_NAME=b'ST...' + +# Prefix and Suffix sizes are derived from ST's DfuSe File Format Specification (UM0391), DFU revision 1.1a +PREFIX_SIZE=11 +SUFFIX_SIZE=16 + +def named(tuple,names): + return dict(list(zip(names.split(),tuple))) +def consume(fmt,data,names): + n = struct.calcsize(fmt) + return named(struct.unpack(fmt,data[:n]),names),data[n:] +def cstring(bytestring): + return bytestring.partition(b'\0')[0] +def compute_crc(data): + return 0xFFFFFFFF & -zlib.crc32(data) -1 + +def parse(file,dump_images=False): + print('File: "%s"' % file) + data = open(file,'rb').read() + crc = compute_crc(data[:-4]) + prefix, data = consume('<5sBIB',data,'signature version size targets') + print('%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix) + for t in range(prefix['targets']): + tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements') + tprefix['num'] = t + if tprefix['named']: + tprefix['name'] = cstring(tprefix['name']) + else: + tprefix['name'] = '' + print('%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix) + tsize = tprefix['size'] + target, data = data[:tsize], data[tsize:] + for e in range(tprefix['elements']): + eprefix, target = consume('<2I',target,'address size') + eprefix['num'] = e + print(' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix) + esize = eprefix['size'] + image, target = target[:esize], target[esize:] + if dump_images: + out = '%s.target%d.image%d.bin' % (file,t,e) + open(out,'wb').write(image) + print(' DUMPED IMAGE TO "%s"' % out) + if len(target): + print("target %d: PARSE ERROR" % t) + suffix = named(struct.unpack('<4H3sBI',data[:SUFFIX_SIZE]),'device product vendor dfu ufd len crc') + print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix) + if crc != suffix['crc']: + print("CRC ERROR: computed crc32 is 0x%08x" % crc) + data = data[SUFFIX_SIZE:] + if data: + print("PARSE ERROR") + +def checkbin(binfile): + data = open(binfile,'rb').read() + if (len(data) < SUFFIX_SIZE): + return + crc = compute_crc(data[:-4]) + suffix = named(struct.unpack('<4H3sBI',data[-SUFFIX_SIZE:]),'device product vendor dfu ufd len crc') + if crc == suffix['crc'] and suffix['ufd'] == b'UFD': + print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix) + print("It looks like the file %s has a DFU suffix!" % binfile) + print("Please remove any DFU suffix and retry.") + sys.exit(1) + +def build(file,targets,name=DEFAULT_NAME,device=DEFAULT_DEVICE): + data = b'' + for t,target in enumerate(targets): + tdata = b'' + for image in target: + tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data'] + ealt = image['alt'] + tdata = struct.pack('<6sBI255s2I',b'Target',ealt,1,name,len(tdata),len(target)) + tdata + data += tdata + data = struct.pack('<5sBIB',b'DfuSe',1,PREFIX_SIZE + len(data) + SUFFIX_SIZE,len(targets)) + data + v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)] + data += struct.pack('<4H3sB',0,d,v,0x011a,b'UFD',SUFFIX_SIZE) + crc = compute_crc(data) + data += struct.pack('<I',crc) + open(file,'wb').write(data) + +if __name__=="__main__": + usage = """ +%prog [-d|--dump] infile.dfu +%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu +%prog {-s|--build-s19} file.s19 [{-D|--device}=vendor:device] outfile.dfu +%prog {-i|--build-ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu""" + parser = OptionParser(usage=usage) + parser.add_option("-b", "--build", action="append", dest="binfiles", + help="Include a raw binary file, to be loaded at the specified address. The BINFILES argument is of the form address:path-to-file. The address can have @X appended where X is the alternate interface number for this binary file. Note that the binary files must not have any DFU suffix!", metavar="BINFILES") + parser.add_option("-i", "--build-ihex", action="append", dest="hexfiles", + help="build a DFU file from given Intel HEX HEXFILES", metavar="HEXFILES") + parser.add_option("-s", "--build-s19", type="string", dest="s19files", + help="build a DFU file from given S19 S-record S19FILE", metavar="S19FILE") + parser.add_option("-D", "--device", action="store", dest="device", + help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE") + parser.add_option("-a", "--alt-intf", action="store", dest="alt", + help="build for alternate interface number ALTINTF, defaults to 0", metavar="ALTINTF") + parser.add_option("-d", "--dump", action="store_true", dest="dump_images", + default=False, help="dump contained images to current directory") + (options, args) = parser.parse_args() + + targets = [] + + if options.alt: + try: + default_alt = int(options.alt) + except ValueError: + print("Alternate interface option argument %s invalid." % options.alt) + sys.exit(1) + else: + default_alt = 0 + + if (options.binfiles or options.hexfiles) and len(args)==1: + target = [] + old_ealt = None + + if options.binfiles: + for arg in options.binfiles: + try: + address,binfile = arg.split(':',1) + except ValueError: + print("Address:file couple '%s' invalid." % arg) + sys.exit(1) + try: + address,alts = address.split('@',1) + if alts: + try: + ealt = int(alts) + except ValueError: + print("Alternate interface number %s invalid." % alts) + sys.exit(1) + else: + ealt = default_alt + except ValueError: + ealt = default_alt + try: + address = int(address,0) & 0xFFFFFFFF + except ValueError: + print("Address %s invalid." % address) + sys.exit(1) + if not os.path.isfile(binfile): + print("Unreadable file '%s'." % binfile) + sys.exit(1) + checkbin(binfile) + if old_ealt is not None and ealt != old_ealt: + targets.append(target) + target = [] + target.append({ 'address': address, 'alt': ealt, 'data': open(binfile,'rb').read() }) + old_ealt = ealt + targets.append(target) + + if options.hexfiles: + if not IntelHex: + print("Error: IntelHex python module could not be found") + sys.exit(1) + for hexf in options.hexfiles: + ih = IntelHex(hexf) + for (address,end) in ih.segments(): + try: + address = address & 0xFFFFFFFF + except ValueError: + print("Address %s invalid." % address) + sys.exit(1) + target.append({ 'address': address, 'alt': default_alt, 'data': ih.tobinstr(start=address, end=end-1)}) + targets.append(target) + + outfile = args[0] + device = DEFAULT_DEVICE + if options.device: + device=options.device + try: + v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)] + except: + print("Invalid device '%s'." % device) + sys.exit(1) + build(outfile,targets,DEFAULT_NAME,device) + elif options.s19files and len(args)==1: + address = 0 + data = "" + target = [] + name = DEFAULT_NAME + with open(options.s19files) as f: + lines = f.readlines() + for line in lines: + curaddress = 0 + curdata = "" + line = line.rstrip() + if line.startswith ( "S0" ): + name = binascii.a2b_hex(line[8:len(line) - 2]) + elif line.startswith ( "S3" ): + try: + curaddress = int(line[4:12], 16) & 0xFFFFFFFF + except ValueError: + print("Address %s invalid." % address) + sys.exit(1) + curdata = binascii.unhexlify(line[12:-2]) + elif line.startswith ( "S2" ): + try: + curaddress = int(line[4:10], 16) & 0xFFFFFFFF + except ValueError: + print("Address %s invalid." % address) + sys.exit(1) + curdata = binascii.unhexlify(line[10:-2]) + elif line.startswith ( "S1" ): + try: + curaddress = int(line[4:8], 16) & 0xFFFFFFFF + except ValueError: + print("Address %s invalid." % address) + sys.exit(1) + curdata = binascii.unhexlify(line[8:-2]) + if address == 0: + address = curaddress + data = curdata + elif address + len(data) != curaddress: + target.append({ 'address': address, 'alt': default_alt, 'data': data }) + address = curaddress + data = curdata + else: + data += curdata + outfile = args[0] + device = DEFAULT_DEVICE + if options.device: + device=options.device + try: + v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)] + except: + print("Invalid device '%s'." % device) + sys.exit(1) + build(outfile,[target],name,device) + elif len(args)==1: + infile = args[0] + if not os.path.isfile(infile): + print("Unreadable file '%s'." % infile) + sys.exit(1) + parse(infile, dump_images=options.dump_images) + else: + parser.print_help() + if not IntelHex: + print("Note: Intel hex files support requires the IntelHex python module") + sys.exit(1) |