From 787fc6f78480066fde5dfe68e09a1d1514840dcd Mon Sep 17 00:00:00 2001 From: Tristan Krause Date: Wed, 3 Apr 2019 14:51:33 +0200 Subject: [PATCH] USART revised --- driver/gnuplotscript.gp | 8 +-- driver/test_plot | Bin 37120 -> 37120 bytes firmware/B15F.elf | Bin 19332 -> 16580 bytes firmware/adu.h | 1 + firmware/spi.h | 2 + firmware/usart.cpp | 147 +--------------------------------------- firmware/usart.h | 141 ++++++++++++++++++++++++++------------ 7 files changed, 108 insertions(+), 191 deletions(-) diff --git a/driver/gnuplotscript.gp b/driver/gnuplotscript.gp index a3f7c3e..a53b822 100644 --- a/driver/gnuplotscript.gp +++ b/driver/gnuplotscript.gp @@ -10,10 +10,10 @@ set label at 4,3 'U_{GS} [V] = 460' left set label at 4,7 'U_{GS} [V] = 480' left set label at 3,13 'U_{GS} [V] = 500' left set label at 2,22 'U_{GS} [V] = 520' left -set label at 1,32 'U_{GS} [V] = 540' left -set label at 0,39 'U_{GS} [V] = 560' left -set label at 0,39 'U_{GS} [V] = 580' left -set label at 0,39 'U_{GS} [V] = 600' left +set label at 1,33 'U_{GS} [V] = 540' left +set label at 0,38 'U_{GS} [V] = 560' left +set label at 0,38 'U_{GS} [V] = 580' left +set label at 0,38 'U_{GS} [V] = 600' left unset output set terminal qt unset output diff --git a/driver/test_plot b/driver/test_plot index e4006b17dace925cd849d94c16669c6c0499315e..cdc226e2660df3d76125fe03ff1fbcbf6853f189 100644 GIT binary patch literal 37120 zcmd4ag?m)V+OYdtE1jg1bSJBm6=*_-5RwoqSRlA-Ah^4`ySux)ySv-q?t|OlG7Jub z4f5SpteNXQ`!6`>T)*pno~r7GnLXcr$9H(?sx`{Sm9CN0sByXCnh>Ix<}I>|oti1C z`?IS5uUdmX#jEuDZ&hdQiu}7LHYon@XuTKz-_Mr%-_JV#d-wmxLH=6M;RPGK;UhGv z314n}x%rnLFZ{TX{CVZijUW7lT?8;m4mJmqAgWzL8ED4>|4AT5N#{E`%1;X&b1|R$ z`E&smVi6W&36^3RmSY80Vii_n4c7A6b#y&8C@I87ek z!`pq#`{-}jj{`V}L!2Mtx8x(tM{!IE6DK%7iBmYu*%_Q=K1vR2GCpxMhJJIR7!^Aa3cl6xJ!v}z9XDH6(ZPEE8$ui_9#TN#~>|Y+0!9CG9V)| zAr6_5g*RD|4cXb_k%KuW5|9hIIm@GXw0txlX9Z|M6jD4|Va|#&7gNHu;_M}vOVZM` zG)+VqltmKCE8$uNS`n2{8C6hKglpAkb<{vDC0wgb>!7X@uGOavc-xRR6sfevv@v^A z+LSh@EockwTGH0+ZO|6&*rg849cV{%;$0W^u1dJpjk6xiJ!nt#X6}Q&O1RdKv;G)> zff&sBV7_Ar^H4gB4#xwn99377d%oFKEI+;$UQ|UA%l{TGyhKSH+vCmdg zX>&N6$2^bo`OFKjhBx{gdrt72uCVJD3N+<-lt)XLNwnOLt{9L zrRkJNJw1B{WMYp)W@J$!^=vdd;+04}CrwZy^;~==4|5)xkLE`KB~mZQSs@fg5fnu+ z6h{e^L@AUOY4k*tVJ?d#ltXz`#*S45+?IqQ!o|NFoQQUIG@Qp z3v-yIxyMdRU3pkJ6(eT0hR46U--Z3a4=fXE{I1{dszxUgYc| zy+kkL3a%>A`gMApyBoO0``heylxY1A&hFwq`+fQV5Ag_(@dQut49|J`IK6 zKMfEuUJf{!0}%v%uOBg9!3beCl^CyN?8!u0FE_iJIgF-MV!S+@r(%xaTuRNJhCK?= zh(TJ!au>^8dgctsB%-`Bvd1yUahHW=p;&0_CQbcQqp?$p?#IKUj69+3{=v34W@(n+z`HFD28E#WfYZ0^JWYkXBp4?3Ct5Q ziMz>4tk+cbsUn@%bUK4KGc9wtpUwF^I+wHg+|Q>A=|Z}gF6MqI^D^dTbOl{OS6SB3 zHN06%*I@%T@@6C5ge}ZlxZldW4coDUeJ9<8-Q4e?d+9#9kGuUizw-f)S#mv605LZHy8yAaaHK*6djw65NTd+xgG&_x_@iZq*pt+RHw%j7KEf4at=R60dTAY?ZNhO=Dw8&~pL>Wt2nk2H>%G2_+0xB|Bq?JT=TNUQYv?_ZwT3v~^)e!Nv zTAbBlugzQsb(!m-K68DM!`6^CLSrR|tqEsMnVX}T$Z2cA-h#GbZ^hh(wxR8moVE_^ z9hIE6PQ2@^B-pxAsXKb0CweIfw%)Y2$Ytv*5^Q}$Zd-pk00UKX+Xitrn0W|>@pc#; z&e;fz#3=UBbPUESxozX=1kNYYiG1f|I+;%8Y%23K=4m32Z3gp9CAV!hXR|q*OXp#} zlE=1?F2Z8oEfRTcOX*VfWxQRk=;=UcE9+c?`M z^4WIM9dsAn#rYn(7yIxV`)}Os#{uSpIK+GyM{pF!aDwyW^c0^tshZz*TI9E#Wj;&K zQ|SWp1yR6uiTSdU-*$yw<@_4G#@$VNgWlro7QMs%2lHL#d-R?tXuHq+0FT%o(I@l? zeTrxJ6VLI2^B43LeMMg@g=}x>TfXNV-it!EzuEt$AKAa~_6z$L_J8O%e8&%^pzWt9 z=q;c@7lrsQy8bBZF~dDwHa=RscNQ;K*Opar-uL<`X(v?z+9I7*-t-%&yo^)Ag^nm36k zgCzEHN)hi0v;t=pQ3;h%MJeiCjaEkurKoo;T8r@{@m+n``_R7V z&)lC5q=PV6Dds(t4&{6phGT?M+ zDfW}xou+4SmiZjLpp^8!NH2;~-k0em?yk_QxX$OVv){l?+~VxEQp)=e_CNT{J@&hz zwD&{aKIH5nXOHld{R#V1=0E9kyx{F$>@Vpn_Sf_^`&;^!zQYI3|Hen9l=o-uzA%5` z?km1Af1^L>5BgJ-@)6KQNgqv==68fj`gl=q&b+BF^`&+MaOZ$iDdiK$ol_+G1aW5| zm_3;CXa0RcnI$)Gle4=K#vZ1c=o8Ky&KyA_Xe3R|cco#DLNt3cds^mLCDA86P0v{- z?&6SHHPI(4&BA$hnw>ZCN}^8!drr=C)7+fpQ4)Rf(flZYf=Z%KVOp5CMNkyQ*-N0L zlIT;4vqa`ZS_WlNp6@NsS$XCPsEA6U49facp;g(dp$2bi(3+^Nl<}#{SzYG(v_5a^ z^O=TJYQkA#+LZfdXs(p;X-Qjh-kP>WJKnVsNj~kFJ1Av*I`Tc8(1mwhIqOEdD`kCp zviCx7_CB-^?aSMK7{DwI;(U;5lFv{&%rcxeBblYqycx|thIuT;vrkaU_)O;KG>Nmx zN|Mi1-c9A_IGueu^GwWAl6>ZHHW%~x?0mYAF63^pnv-Z*pQTvNzKri!!MqZylq8=u zbS>71az5+n2HtH@P4d}HH}jdToNeKLJNq`(ay~mb-_5?8?xFiE`+2*cvxDph>0x?^ z&m5tLMR}j&^ced|-koCprJT{4px2+q<_DT=cwe!R5I zX_?dU*;w}U%;{+c-ezLX#GILCrdg4l_wmTioP+b6N(J9sG#6)iXkO&A6rcrB$WnwB z=DUm0V!SUwODYw7OR<+`F3o)+%CaZX@|=~Y6=_AzDxor}uvei~xvRlkoz|kY`T5mi zuESkj)aOiUpjyedA$N_@guA9_W@%1aaNZKF&>C$xYa=T8wx?1D&N`wq-_@CRL05F= zu7{-;?ZsIi+K2X|{rHal%>C&A3}PNc2V*GnP}R!5Bd9bIqd6Z<$Ix*YuT=7#NGFKO zzLV%=I*sq2%Dd_8)7Ymo&tjfM=g>KH9+eg-m3$X+wn(Y$yI555UCO+a&n}}Ylq$X} z>1y7uQL6Z^7ZvUNxi*OZLt~b7c)=U|pEuzPJN)2p37}2{A_#`XMS~Fn6UpqFlAKCz zyRL-Ml<*)Nsq9`#1b>ntf;p1@D~dT9F?Rl3Akrch>Fhq#M>W0OS7bm&WI~)`r*@IW z?x$p>QZ~Ck{6r2KkDT^^|0LKQLdu2Qb|(Tw9-5Cz`IR6VBnqIAo!|dQVZ}vVqNqJs zDQ4&I0Dx?9l(6%60oX%TOVeMH(PSdgo?MhcS-YFMX$qyBJxnA)w!Ga#Q;G_-f<2u7 z3{xRoRHl{f5uy?*+fyr5?2$sMW>2G3w?~Vr_9#)^9;4K-rxpLIX^$1P?CFqR)I@E2 z2IdSjBQl9P_Bdn`b?upHX4QK3tfHPh8*?_*`u2EH-=1AGqz&ykkW(~3LwhcoOEf}b zdmfrwwXr=f%_o}J^P_-jQ+pxK3W{d-!lEgf*^6>sl)0GFoVKu+;JgGaDVn3Dy_A|; z*%N6Zdl}IRt?gw|j=4N%6;NKZu~+1*BCX7MC0YelQJuZ2Xlt*A8tgS`P0`L?3$;-P zbyYjq>vLC6w6`~4Zy-9@8?!g0jnIVirf7!d>{2t)$=*VAL}z(r&an?Lm9{IDf-c09i zn&@qxL1%F`i_TVh+2^s(*-z3_Y944m!+wUl^YpA3XurVuMP&dTh(Y!%?3d_OdWBx6*Hj1D zZ}R3gpT8*v+waiZ^bhXtaehyAu>B$PBRu5pF=tQkRCNfIhT8w6&y}I}7xWePZ}6J= zEuVW!-_iH@!2FSZ=KizlVEY%&zOjGhyS}M;sGnf}$^26c_0z-<4E6J(x){cv^d0Kw z!|bCvl>b8@4fFG-0m?8x2Mt6J?+gTr5q=@mC5HQjiot#+ccIE~KmHCN=8=9WXc%W< zyb0rdID0sADjGo}I7`EQBy*H9!Y?g*6rWAY9?N}tnx1CjGntsB%*=7T$;R6(G%NSn zk%PPJ>pq<>oFA%_BznFkMXO-T}9qjxtgH>4Scp_hs+T+@B7>Am%}I2p!D#4Z%>1U?0KxDAn`|m34Uw2Tg|?neS>8SZ#FY;;clat;)c%zQ~hppFWph5_}%6HE_V-kbC3InoIm31F@1uk%49m# z?>Xmx(!b~nJ|n%t8}>K!13&H?G0pEi^E>*H^AGeh{erK2*H`ZT!8d#r)BS$X@4Wdb zruyq*GN$-@DO3G@#Uy{5n8xooPG+9!@5i|x^;f3(2XY=DruzqR9>_Zvb#WIAli8%9 z$~6CE+`E~>ICt|I5B0F8;yY4`8UB$pf;SP|rB-J6r=c;tNylAU?$Ys@^z0d!({mT6 z_L=@!XdHVM&f~;P|LnZU&K$2y_s_vyP9z{VXL-5L!<-idnDg=D7v#Kv>P+UD{zbSe z##wO`WiN(O%%zd2I>W!L>MZ|qv@G`(`K}6lM+N3ee7-Vs6E2=4cQwhv;3R#`9^%EDSI=tWN*&ig12p$ThVs3Jvyk)^zX=b zv=?*yJJU|wcj0qgXg73Mo$cR)_Tsz`dh>n#dE1Y9fa+}j!E_LB26Hxu`(gB#S^gur z8_7PFU#^kdjpp4Lj8*3NPvmZrWhy_XN&H-<@NOz*a6VPc^`FIe%;NnV)!EE*{AY7M zk2ecApU1w4w~N>pV-a^tI9tKla_(1P74r(tS8=|EH_}?H$42hfakq(g8^k>SEu3vq zo#Vfac{`uk&izg*?ZzJLRp$Ed<8D8*bWoY=e~7aqeD=(rX|0~Q_agF`DGLO#pzsb+>4*LzU(Em33UEWCd@Q7cQ z`Xt`!^tkB_-!6_)IFAlJAJ1;p`FWY*9cA-db=#haY$xj9eZ zvw4{Fah{Lnrv+#s?h5jADM|~o7o$aZTb%pioR{RR1bb=rlC%sh!&w>bl28tn_)Iym zB%m^P6?s#Qy)v!JUX8akX>EQkHF;Z`y@ps8P@lavpQ$GnIr!`N5dVX}y-s+6zud0y zr?rK|9}X-0Zl3y_gE}pN)Udc{FhUTDWEM9~fiR@BcxX6MAp(&|4J3V$7dmT}mXBw7yTEfpMoLaKzysA8$+@E1~b)NlmAU(`e`W~nyn zpf10{>!CgxC{EQz%uO6l1d7JADQ$-4Xn~fFAOwn5Xzef%B-+w8kZp$!4i^m35uKQ& z&gg=!j$oymBSds#?m?wq=&hL46n)T738l#pDhAR4bTAzR*&z=8DF6(`aEx%cm647V zs-vhh8e<$`Vl2ifDQQYE9uplNWfGMpJHnNzj#Od_reV5+-v@A{W=<_;SZ2{#j!0#; zBaN72nM>z6q7bdjcf<&30TyDBBdxN;!G9NEi6fn|lrF<^M|xyXT}fB6uXbb(F2ac%!S2o*bliMbQGmUX>nRi9HNIEC1^=S z&PN@kIV-Jt)R9QbsQHAWtT=|_j&d|foTMjk(or52nJb7>^t7Xra>h}aRu*R+RZyL~ zYE-I@n&OP3hB$`{j@shcf&awNk{NzxOnIo%{~UB#3TC9F^=(J+VLIT{&Xy-%jrtG zlCI%yg?Qmu%f1flRi8UHaJOFk<=7~mJ2qhp`xZ67q%R!XxZ5gT;+10u`!4ofbSL{B z=G}BJ_j|-^$9~TDinos6m=AD%fF7bpxIZM`(ASQm${WWC&X03;0w-~nH>ddQd3u)p zJnzo2UtqpKf2SA4JI5vFi{gXh3cW1eJFd~I^aj1ID(4T5+q}Ig{&w8LJ?`#ucb~I+ z+&xtLC&wes9*9ql$DBPDA05v*f5!YLo^t+|nm;*S(ihynrY|{v&HR?{eakGpXa9ir z;U44*1Sf9|b{7K0cV{pS;d9Bj3uaHo9?F~K%6F%mGyVx6r-yU? z2_R<#4d*P9dNkoo#aU{#|KRM0GluVqqG|a|EMmk@XL_1e)0~-TM(#56CL^DXV~(R) z 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 literal 37120 zcmd4ahg%hA+o=6}h6OBOEtrLaEMb9E5fu@8!44J>3-(^I_uhN&z4zXG?XOd%o&$0i2z4!5Z&+EG9o&`ysH*ZXgPe_FtwNv9N)UMRDSz3}Jgea@H zi@ajDqKjJItn&ZWY}_xY`hfpddDfxyzk9{TN&k-KeewT)xBUOUYya=w|BHk1dqIU8 zEO3X1P^cn2d1A2g)RU(MFP?aD!{E({7f%h|{7-N5|N96ZVUz#g&j0i^`3bww;9z%9 ze`MmRjsVF|WEOrRkl9JINSX+uE=dz1d_pL5R)is(JwkGbNE(G`K0O;^kexjiIhb=w z{vwV&jyX5t`7ZJxFLPd+5BZr3(1Iw0!crztlosPzF}~|W=He*9ToR>F8f7>uOOud{ za*{48(29~SQur;d#GEGSqB5<5s;Gu^RF`y7lh)#XZPYSg!x}yhrq8EB|-iP+1{pbKX zfDSYbrb94P3KYY6KAd?ZMq#uRD8_O=mOt9#*(YG4X)>K61&XOWpT<0$&cIB}!fedJ zT%OItd@NvJNEcx-^J4x}w3IHT%jpWN#45=t)^KkP&(^W8qZ{Z3x)Gb1H`6WH#=MR0 z;QkJ}6T7e*dw8}N`Pg>?}P;&(ZVr z0xmLN!ev}#H(bMY_M7x3y-jb^JM=E@;XWR4_7IQo3m$X!1W%cN#WOsYg2Zq1C0rDSvOem zfK_Bckm3bz_`n7`eBlTF44^o;>yJ#(*#nRnfp8)V=RpW&b|Hj0lx9U3!V!T;MDZ*d z*_dOH9kIy4Sx)3a9C9Pxlt;Lf1mt7SM+B`h!&l0LDOf4aUXr;a&r6{+ z%5YW|Nl0cdhw{u7XhoWWROU)ZW3G%UsLEcArc*;rKDQ=&E!0LG)I~kXr8J-ox!1_l zguN+qQxT#xXKv2i0vTw<-io%NZD>2%UUDfNxZjDnv*c2`@VqO!p*wo;yeI92-ssD{ zzO*0uV*mzX5C&rihVsrZIvgV~5~HLLWegq5^Ko=MCSalzqD-cfMW`~BPQ!G}kV2GM zyknTdK8Mbu^XPmmz#{g=Qi!sIeHrsIx*RL8605LU3RTw9by$xL*vQx2L^n&J%2v9K zv+bsx?7OgA3RU*feb|o!IEX`1sB(lJ#W5+Xa-1ILb57EeBCB$W`7}L)pE>)P{T$BY zBKt+oFVoBHSLs!H4c9rpL2uGqxWltM?01>(;XWSVAs*ouJjN3|#WU_cqc3>x1^o># z@rv`;^mqD({(-l6hxhov`A2-hXZA1nllf2jjs8Wy)9)fo`CDY=FE+BO3RJkk0(W?b zP-IoDQkd#ZePH9PG!GJxk7xO4eiT4K6hdJXK~W@{iqjG(#XF^F z8Cr&xMG}%x4&_k+6_LuFR9XpXsEjI7xLS>-qdID!rU+MS(b}{Qtt*AA^=Sh%d>LJi6l zNcA$GahZ3o(yN?Zr#I+LDN?<~v)j0Xdz{^)_wfJ^@d%GOe@vg?DW0)EqtEFJ`Ws&2 zHM`+=<~R5QZ}ATA@c|$437_#rM5$ltpZF$4so&{$&i@vX{GcP!O_8G9+^7ZaBErps zdcrEA+`Oo_6y;`Pw=?^~kD0&XmmJhzM7!yn2Ou+_k(o0mvy%oPnAwF8DatJ?4U?kW z!g(HnDE4S6$}NUw=PVXEm~&D?9CI9vr|~oo5|EEQA1y!&@VykGh1iSmy%eFvXfc|I z;yf=wOPNa3GDzZ`B%URs9D8{w+N~l@;VhL_LK^of(<-QnYCKCvb<{A`;=DHMpe|?i zP@lPh6z$fCHbxUPm7?96bEgG!23ktdZml?L!`z0pqwS?=w+`%`m^;xfw5zEbdk^Lw zBAZ(;+FOct>q`y&c;255paU_8c@TGpU?}@=e%ppKkK}wL9c3EBvoRvZZ5$ns2|S-j zCt)(CU@CW~(dl#sok3?}Hs-L;p>r`G3)mN$7SknCjN4Ma#&YHrQjFV5?ykaWtl`;O zx}In2nKv>UHnDHU7Hq?I&UVlpbQj%4_n7vw@56rf131X%9HNJD1V?#x3_md+$4TZB zBD>pZX2TiN&zzs*UBd+_yW1stndeue7`JQe*SU9{-VoW1AK?EF{*qkqe}V=7t0ydQ zhlk0NTHysB*euF_>=sq{nly`>_=kmBgg-J_+$G)OAq)YMC-oGW5ooarr^QRkV(}J+ zAc-FXSZpE~E{mPoMF>JIzSIx=T>yky_-g=!S@`P!gjx9O0E;e#TLMIcg+B*KPRgGL zELlwaxxf-EMO$1V+7iMXLPL>NWV3`xF_v%I8SCyrsZh`loxp{6-B%y1*uXVOB$`rohniuOEvbYB7r7Y(or2X zP>b{0QXZPuQkS!OrUra&L*_5XuErU55f}xxZ!*Hpf zWdzSgVl>ajV60ToGLExxqL5`G`$XnRm?#QcrqC&zPovZ544%(mp2<85bJ*v|7P8Fa zd_ER(wvaB83R#xWCEQs?m(vxdRqU(y8f)0s&~@zV=z8`IbQ9euiqImKE$my_w=!?T zcI?1T&UbUZhwhb%SoX8;XFh;~Qc=rc?jFHW_9LR0@dFG4s61_sN(5v(+pLL!2hE&XQi{8dvp55WuJ?4A#J{~eZ!b4Hq@|Zs6>zsw8)6X49xF<^=iy)e%UGZ&>rX(COe#ZdyK*h}(WY34F0E0uIlrb&FQ^0Yk9E1)7$ zkcvu3LlvG^p;b{0>8OqxsKv9Id`2Bwo7Uy5F0D@+NTu8x(MFs#MpNddv>BSC1zK{J zAxgWqVs1s-vbSY!hxX`zj_4$ncJD&FqMKCOy(jm3GWSAn^pQ%t_oMyzy#5$~ff$4# zoDY#L<35~uIP(apjQeQz(adA%7*WQ39P>CjflkCEsf_zno=@R?I-N#ma6Vm>b)Q9N z(m8Z4=JR|W&lfN+pbN1GOW2ptWpo)`julubm33dmXRKjfL)V!$uy0`AL^op#wqhH$ zV~14MeHY!$y}f+)UgrIDpGa~)Am=3aL-Y{O590`q;wR32q9^DHdXoF6=xLl`J}V`= zU*NOOGhg8R0=>e1NwzF=vimjWYxFw3$(>;2?!82 znVB6mbo3;a^8{mI?zts?aWzc*@_fqkQt z;<1VQn?$O|R`xB-+vzs;opdMrF1m|-H}hWXW8Y5?;2`q>QOV;F&ky4$XGiHzoF8XC zNl&n!Vm>XUdYoZDi*xMfd454k^|;8{WzH_sE4aq_HF|?y=WE>L*)81W?3PILxW{~t z`My-i;~{;>y~E3ksfZL$Au4&Qa!&JfW46GPa}R3e+*71^db4}8+o+A& z;Rgr1CTq-To|%|+-qD#eBM?r`oHUs8VCE3n%AQ$yH$+tS4C5@TsNxwxBe)kyqi8hE zMq?0b%1I4zJd308G@j<=GZXl%yv+GID5>4g3H0H{*3ayHC?pI^4&TOcGTHLM4Ssms&v@Ys%)<8=0 zY{=f2XHD6g$fkKVqZ#Zi_^@SjoJa z=c}04(6w}(Y`W)0<_*{+s#y8)|Nr10zX=s?;D_XbzYLc6KX-!vcndFh!v{8#o%%t8 z1OCVa-IUp?2ty#8$RhF2|E&KArY@_S6hcFhmA}zo2tzm`5oL9!?y}J|2HCA1CQsR% zR!?EbWwrh%jybp0OUh&Q7KQ}mHRZGV2txrBwA!dm6q4-JE()WF)mJKN^%F&z6KQd) z_MZ|~hbW0srqWh_VJK_OBqdpO@s9u+Ad*qenpu>W0%@SAXmv^{G}W2~L9%JI5-MAR zMVd8)IfRC?hlr|H{#+o1$yT$5i)z*|QJq$|Mj%q8qq;SkMv0pAAK7R&QOg=5)v?Bk z+Scr%t~Don4pE2JvF4KMTH`p66ZNgRMLlag&4YN+z?zpmLAIeaAI*<^q7iLmEhrjV z3!yM`A<@KIgcg= zg*Azmr{y`Xz??!WidNQCn#x`YX{ao^6;JZs2VBdNW$DQzM;Sex@+GoEMA=Ikvw&!DZOj@CA`wJ_Sr z+7|85-qeX_9htk(PNIvoEBCsH&eYJw+Jkl%U9G*i)04dyb06AUbhGwl?#Dd9G>{JD zdFQ=>6S5m_&tj1c? z2A-`KeWVR^6XzR6KkH`ZE!ZmhTDQ|3QeW#%x|=(@Ip52?hr9cj_v0Y@L3)TD;`|8n z5!wFMqoTj{7>=`_}Sr-u%BZ-M=!_@v|gf@*ssuwVvzMJ_pgY7 z*6Z}D>_F>Hp5MZ4X`uBU&+akbr}w$@koh5fBn`6u!sk5Y*;CG+a`r3xGik8(1$`j~ zTVHYhn;2q!&HjoS-f;ew{T<%2f1n>Y`zQ^ue&L-@VyN{`&cD#V=r`_tr{C!hIS=y^ zVhDzMxrxF2P2Ry??qU!fN{4!R^2`cv&b_D)Y_Q7?^YZ16AG3q!8gnLQe=*D}fCjKT zInT_Vg$B|f&a#N%ULowkG?aTTF~TdHhVeX%vq>s=!`>xdQhqh|ylD%xRoe<})fYSC#WFhIkK1&+sHJg17 zW{U}!=rxaf3)mM*(a_^or z+3Nvk4|w(vzcBwopK|93ea>h8%GnF{U&T~voK5w5#k;TZim&rKXTQ_8+dT5h1reSje3ZQn9N@+PNGx2 zy_mf?_lB34=Iz6oAJ2T*?d*Q+{@ig;opYTzfM)^hfs~*9=N-&>pqTFM;+c!HP?}Ym z;vK?y7-w1etO)LgvuER3G;|Nit~}oqc9p{FjjV!_e7qJ<<2BNV*>9^=6o{mPGg@+XRuG_ zd?xcuS!15zFt2 zHP(oE-W%CB@Ohi*7Hs9&7WN&?+nIN9ZztW!*)G#wKF6@1^ZlG1=I#M8*ZT-PM2~TP zl=EZUIl|XC!G4Nor*Vq2(>N>5@jlP9bIj*)0hib>@)=i{ukaby*sszX>^JBw_M7xB zpLL6ScjP?R`#yaj&GmjHJD<+=e$4!s@8JoaF~8vbXL6qB{hH5sE*5yd;`}!;-}?=H z&9gVW_XplGzvcWRU;6|5NA?fg|H8e`oPWVL&i}#>?tBvqd<4(FQ$@_hJRdhPo6hGS zBF~dNs0X{1dU3~#+Ncj_zSKrFYVa3xd>rgL4PX!8E{$^eJKraqvv9tjNE$)2aW_gV^vS_zX6GyxIgpF{Ie8vOTsEh`rJl;>V~_7wICG?hJ# zxe~1+yNE87s&Q6>v+C?Mc()cc)Zw%1p+3**ai_kt$fqIC>Wd{ljoBNDB{qKi|34IV zeu|yor`AaPV|T$n`V#!@ZNU$T1%JsWyulw5$wuw)g9ZouO_`{U%m_3&X%+;-g%E@y zt0|0zBf`ed140y{kqt4DDjRE4g&`+$Np7;aZEnI4k37h0v%pQ{qlWw_h(aigB9gmo zF`K(EB-%Vgaaxj=q@}2#G|JdKrLr^`=FNQayeL8|tG0XAP;L5t>MLY8Oq>%;qbaqXjZdEp2|n&C7{jXV}8TOj|g@#B4eXb8HcEo=4}}A`v0xW1%gIMu`QsXlWr`WXmQkrb}!w z$Sy6V%dp%QiyYDlTTWqEiB+~-(rR0rSZ&MAoLhD+`+8fvSZB*4t*0Ao37jR+d~)7Q zH%a+rx7zZHt+oOvB(~7))R?#13X2`Kf?}7gD05NfqGBhEeYdTc*keniiL!fbC74Sv zmlS)k-&RWO!+u*CT1NH&J!nf32VnG&Eg9vIB#zoD(DLF4jM;F^mO@jdW421{X{aQQ z)8n?vs3M)PRijnKNn5%&fs?ixvS(~HnQMwuwpyqu&QRm*XIouy+Ez!LrG|612DCos z4Wx6nMzk^Kjl>1|kEY_httoSJG!vKTC0h$|(bkeZgSn-+Ot0G7vbSb#%UK)tcH)Z3 zn6KM9h->twts`?MbY|~NyV9<*H*7tadx#shZsIn*W$Vq{Q}(8<5AXJsZrKKMe*klT zafjZq4d%{3I!MlUY{Pjrlz9Z_L&ZIMm$Q4ek#vN(ZyUut8e^D8ieGHwn8z`X$2jrO zHbFeFO{7!U4O1~mJf@GN={%dso$0(gi+L93bLd<;n|pJykmvKn6Wb!r7s&lFeaimC zwv_jlNss9h+j6Yr&Pv&*wl%WP=u_J|tY=>p>Is1+M1^Y|p7vh8M74vKS z!TBrp_k8AS@sa*vd&~PDc=i#WWZyG?uzh9z%$=`1|4RSFH_m_XHNMM!unX}I3wQq( zpY87Aom~~5>=yBn`J>&_$6I{0YwSL0PN+Y-v#vINZPP1_*Li|O)*rUWZdk*#( z&U4XN*)N=Zv&XZ?(FE?r%iTEpZZE)|m-h>BH!piW6y$j!6h;xA6&63}4|{R;M4p%C zosyiF;hj?KWjQa)UXHzt_}iY$S$X#IG)YnH6=_A@Po-&`r*fwfs`6e{&MGUyo=&T9 zw+5|7YjVE^=XKcYqBe6q&g!EfdwurCv;lV;F*i`$>`nR1ChX1Fn^Qvua|Uh2vzCf# zZ^Pc2w&koHI&$8QcRTaB?G=l?GiP17(+yp@*F)A~??roXuMh3Ty?(SGcl%2!b+Zq^ zAl?~_As8xau@9#sFq(Hp(Q$muQGCW2?vGMD>|>cnE1vdAeAaly-97;mF-h{UPv!Yk z?oH*+4CZNc4xck!u~G{>r1{MAnCDBL_60m&!r3D3FJfM-c-fcp%&?4kC0&gb%xn2t zD;0118t$#*{szuBVl(F(IN!p&iEd}##+@z9TNNMsPUaoVyLo3f^Bz8HhvIAB&%BTG z1M~nr#Q72K9G3OAACtA&PjGfrvDuIFS;u(qBzI4;pP^^DbB6h6<_mnzMVw>5OwV)o zqGGpSW4^&>TvGh(S9x}w&$(&3#eR!B4|slu-r*g?BR=o0qS=4p-UIe0>`$2=Ge72Y zp7GvuJY#>!v)`CsO1}2r>1)p4$okpe^ZYIQ2ln@}cBUMClj^=zl+3=>+0*%) z+PqVpy(Z_iQJ4F5Xg!|Q<-8smve)M`8gbT;Hla;9YsuGatT=r$m@_zQMO(19kqz?g zz}INc+@5Fcc&|M=F?ZxMyKvrxcBh?{EWSNB?@IgfP7gk#k9-!)o|!q2I(-LlX8`*^ z_CXlRK7eGbp&Vzv_OJD)D%^Oo>^FW|El^BIfjGP;y!%ecQBE3ty}RdhAh$OieY z>xeNoddjc*mQ(DN0@)&*(pBn1p7&L!wDtS_YC_v-aW_jGkoR+dY-e3^dh}1h4@~h zSNPi3&$cy|aU@Axpqll(TMX8|}5>Xr_P*QUfrDz%Yud>WZNJcqS zKt-fz7HScx%xUyrRhSJ`QB89f>9hu|4x=?uOY;!5XCfiG&41) zEi_LlgSJF#w2`c`?fJO?!E3%Z(mXkMZ_jP^t?^hO`_ML*43>Q4t?AO@R; z(4m@-G>i_%2#mxijOK3$jizI%VI0O|qG=MHj47I3no6geW@x@*2JHc^ORyBn_z$9CIrB=o0;@C!G_i)Rq3h{7tk?YIypeemHnVT0Td852mI?l1 z2i-w;(Vf_hJ=m-1$RzgDeK;Tmh=cSHj^L;kARW^(i(|~k>2Z2O3zYLIYB zEkt@sf5kH`6d~dTeL-JpS;cS6ujniKJ2kv9z16~m;T_(aKGIM4tc6Qo=vOU5e9>CDUYDPAW&sYZa7oT6tPdsi;*{D!^z8XK7k0O;u906lOyur4oA;tuk|( zQklIft;$|it16q$Ttlm(RA;ZQr7P)LbyQPoX*D=cr!{GHr4Fs7)lzEHI<$^fTdJqk zQR*?*r}ee^N?qngT0Ny9b3?5WXZ4iEw1L);HlYoarnIrvm^N0LX-$Llh%W|8|}$?ccqKgi}UVEH?0rt#okBhOuL(UXnlFsmwf>3uk@hZwSnlb z^rAi4`)ETsAIv_KeF*z7r8je5Z8-CAI+Bj0qv;4`fHq3$j{(|Pr5_!nP2kyBWuP_= z<1s-Rq)n91hG>(N!P->LCMiR;X`D@=(>a^24AExuIWySja6UsBPK~o++C142)R>2B z3uH%X3z_FCW3)x`Y&0FIEmlThw6+9Gv7CJ+=S!6F+A2AZ(N-wqwAH+~lC$-kt(G05 zZQyJpHemy28?lYg*i5(b&Nghv7G;vQi#uDD$=Xh3g0@5M6SdvSL~RdtbG}EJqV3~+ zKMr7@GF3Z756gX;c2Jq79p&C3Wx95R`6uolqbKMI?jGm-49`z-b{eOY8PqUS`!>XrH)a_{jcM&P%j!@_f1WCue^uOSQlFjBm;^x>Wn2EOn@S#$U=x zxbS37BMe(Sd?WBMOo#rDoY%0vP&JFoO^Tb#XWC$aqi8#zMT8A`%ypYpc>~o zcQs{=BNO*BbME9k6MGis0A;Nsm^};6_*FodS2& zUq~^|HaQYGFUp+AT|;r^qRJLWDYhexqWh=Hh>eG5WtEcR6 zG@$jBosLGdAvH8cbM7^z8M3<_ZFs-Avdht$dl||eM|(b_E$?^Wc{}cPkn>JQXP$TE zS!edn-0!UHcJz>EyB$3_>#FQ^^pX31x&yl${b?^{A2sIPj=}7Mm}$EdiqBcc`6|xWaCZ&e$g>TcZ(v`q9CK{t`DW&=eD-GLC&wP%+pHXS>}21CeS8ml z=mGBS;r=1IkIy+m_j2zL?;c`5%AJF9KkoR6v*S3y*$JMV#0ft89AEnsJ&lvfNymBa zoZ~akv5%1no&Nv>h z-{<{@y#IjDe9Zoc{VDqs`YWIRRMwbJJ6^Cqr?2QM&R^3P%Fm8B^bPxa-uqoS>-fy~ z@Q%;>%5Td%xu0~rRn9xU@%)qA&+_byzu?|iCj}{+W~u{=w{7 zxSxfupM~eaaIuH+UO3Of_!=(mW#u!%c*d{(!+eovm;57XHqK&rH<~#Y@8sm&c;3my z{d|0HIk=x!Ij!^K|No(|t8fGV`n<%ywk8bxYbt`D#xD4&SrY%)SMZMjgfINS4|603 z^+zV?$c#WZO<8CVTnI6R(lCUZB4{L{5RDjQN31C)&4oBqJk4WDpm~uG1yB%$Ohsr> z6hoq}$QGw1P|{S2mN6w!Lo&*tyskM2HHG{#^o#_=zIjH44xlh_SYOjGGJOvenOB_ zyeK~phPZv_dV$%}3)U=$gl)S|X-CL}}YSS9J78^_(=|R>5LpY2hrenHY9AiFCkJA&>a0;hQXXwwmFYMwxJqM!~*)P*e zFnR^oa2+=!Kk6rL;WqBzuIV1V&);l&Kp#=VFL;b6c#2|p=U;bk_kHVzXF&8;Y1b$As8+_Pzs@;x>E_^EQ~oE5$xeG8ii@_OG-qf~KbCv;{KsaM_mB&)GEdcW$WEt*8G25{DzlkqGaKgUxsX$thXtlZoGrv+DNc5&9;XA9ulbOl!G@yM;L(eo&)c)pH(E&F=9o-@M+Y+~O`4O_5P&r1`OZP?DflYIyCZn_J* z^?Y*POZT$xr-lQ1e&kgS(?je>=n=gD3d$a%$2dEw7gBy=K0!~?Q}h%)OV84CdSN*m zJ;&Jvy~uwq>P3}{?3d|fy%>rp*KnQvI{S4!QMy5I>cyqooZn--CwUk zYp4#rrj&{E%z7-A_|)rAmdLnw1rY6#OC()wzI z-k9?SYNXys4M!xqAqvsRrZ;77LK~?$n6vB6&{)kyV>yqb#vG?-@VuECueVTh>n+(^ zsCj6-l%eL;Td4`itGAKO&s;!n$KFoOr+472y_%o7px#z3tas+Domxci#GOuRA-xOd zojLEM7Ugbny&GqpXjioub1}UK=Uvp2%q8^hQb}5h^OAZm_8w|!y{A-G@2!@R`m*;? zlk~n)GBuRf`=LJuaXvt;K+DqSuC9;a&PcU}KAwA{Wz#vUrBC8~tXf;2$k{lxjx<)S$6iODAZyI^ z^=aIhOed=i^r>_@&!#g^Qyc0t*=J#f+K4vLXG@LrIqY-P#`;{$lWj_y=nF7kZAP2X z7W#5NV}Y8Xui*Y7xi{69urFg?rncn#-x_l(eHCYGc)pr>jnrCSC)-wEtG3nGtH$0= z-@v?4?j7_kY8!nsXItqewIh26eLMROdDe+`Ku3KS-9`7%-D)R&FWsYd*7tL^TkWPF zquRPCYvB%k%xPjUVe&rhg5Iq%2ZS3jxt zX78(?;rt|L=XiEX9iX4*{4D!L&d>4ug4zeh-cP@z_SY}Vd7yrcXBXAM`gQipvi&(5 zsNdu>uCw2k9jf0@hv~P}A?!owF#Q2{ZmA>m`|42r4t>b^L*_@gFZU7p6Sr+{*upmp^lVZa{d}Gx%)~QtG{J8yiv#SY@Gg%ciyUF=~(?EcRu3- z=U;gKnX~umB>j^*foGFAo50y*{hK;o|E`V;P66eVqQcIx)aa9naZh zIx)Z^O$u;VCk1#iyL0X-O$o44Z+P*po#(!ivCj<9IJc|Q1N=GjqnWtlpqV-MS7!w1 z>a>6Wb|+syP>tO!+S(OCguJd0!xXO5P4<^;shXmxf# zHbkp)19I{_TAd$|ozKc9Ys?D+a;ftIa`QYFXF1sucpfJ^KOm2~ARsT#3-K9+QGh#z zxm$qqg4`)2yC|R-=Y~Y~M0HU>5p@asl7JH2DW)z9C@w7zD9iJb%t@Rlaj&epG@y*S zJfOU~I3SrhmFMNyE7MfYDyS<0QrJ^znmk{|vtE5R>SBlsmLgcba2oWk4WL-}cd!WVwvA3+L-DHAp52tXj5 zrYtlF!3Z&h(lCUZB4{L{5RDjQH^tH%$b~plJk4WDpm~uG1yB%$OoeF?6hoq^I4y}% zrqZ-5l8}sYC~vAjD>@YjkxC7fP#INBRcSS(qXud^`SCxkO$~KWm%SdXM;p+FXk=Sp=?1nX1XWBpwo3I&M|6>)~oK~?NJFpYGup4`@7yGau2XN5o z1*<(r(GDn;4A** z{2ToX-|+)~JMH|U9(F~63O87szLGn$C$qr{FL;}Ls13gGg9Zouoqn>Js6j^n0^vj! zQxJ7IHTWr^$jTgwFoYw*6iK5^*=P)6kpnrM4rodoax)v^k;jym=5zYPp%g$t6k<0N zW-dw%#gK^NC}Aq)%%m7fqYP(Bv@9)0lTjWOP!TCeMJ1#;b!1X1qYA3B8`4eHX${mu zZBrd*fKnIr*c(UzvW+=2G(l5SbK1h0`9B%VEzt^XqyVKIHFQ8nbTW0OUC_-LD0QcX z9_WeQ=!3rKXX@{CDuw~^)lV=)fnG0_>MOrVo6nRzmu zN~hB4)G*UDi_VsUl{wB}WiIo4I-f42hDBH+1u4tvGAwtxq!rAou!em#jIPBxtatL? z1VA@p6Z0mzg&MXpZ>QVoPHNcY3`K~thwi5Ps9`@2;2;j+FpfC0N=NB2{Dk8;fs;6e z(@y?50M0P~ObzF79v5&Cmv9+ZaMc-(Fy%VEPH$4fE!@T(+{Ha-1j3aEc*tycgkSIk zPffqlXU<6FIekG5zu_fb;Wd7DMoDkzA9#y*oPTsiEAN>F zG8^(CKMJ6rGY+}b!qiX{#n=;_xoK|M;DZ<^U!!T zg&HbJ@oHsSne(d71hootHKa4A(;C!J3$>-ZY8_e+^__X82Gr1yvnI4LnmF?zzuJ^G zqs?dwnn7F9mT2WHAm=vBZJFCS3nIVTfw=?iOgqyqoEvjD+Ku*b7E-&@Ug*u-6TNxX zm-clQmhHzpKq^cNs{=6zL!=_Kh&l|zF@m#^7{xpqW1K~4QCdVD=Pag63mI}Tz11eEWko%Np(KY7Ge?m686Pd!oCbE zu#(;ADr#8cEG4aVmZqiEby$xLQW;uC-N?MzSytUdx6&fyzV?V)uocSa@K~Fg=Fqc!$($k!sb*9jA z>Un2H^=HnEUcg1p4VRd&;41SKTy>@*jX71lVY=n4q~2n_gS*_h$8%$T;H=DCN%lVd z#aTst$g^KKH)f+x=u`a4{0z^TUpTAEzI0Y&uBQIR+3%da#_#OEJJY2%%mboW-!`V9&)I?`+HSmTq}zjGWt>?I_>Rk0P>Y_dxprNS|ZHy*phUTUg zGy|>B8f{!EIp0YQyRaL3uowHV9|v#{hg_cU5J%_{ zddzg3-EaaYaSEqRXXsg+!+BhAS>Y)z(M$9Sy+W_jtMod(ft$Exx=ruk9`54-9!g%+ zOFY6a>`(A3p0OLA;{|@hOT5Bs{Ej#H!}QkWE#5JIz(>hje4?K@|AMdh)AWsg#}EAN z@&Uit6I8gt0(X~>NRAJ||w`BFbP;Eznu5#X}HN6AbLfp8)S!Ehl2p~z|q zqY;Qi6rz#MWtU=TcJ>@J7CD*Ys3AAvkp~ILi+srM@`YU~NDI=!v@k774aH2wX$h1x zm8NA-7D=XZEYyI#n;OtY zXl!aio1wYnkj-#8lnnOPXoI%whIY*Dsi7k}p)Z#Sj*(I(nn@YOJcb&^VjRZ1bYxN{nI_XIn2KpUn@(rYf6Zc_!)}<1 z`KASQAr@h=X(?TX<*oo}1zm|%oUNgTwOEJs*no}Lgw3wZ2vD|S8@97=r#q=(7j|P0 z_F^CQ;{Xog5DvQnr6bJ8n2*upIKgZlwzZsE4+t}Bajm-#+5JitRd!Y_D?CwPiq@eI#hLDCE6mw3hgTFRolp@u&=e@6}P z@c|$437_%B6|8(U{mK3pv*9~_;BQwjzwmFcsz8OC%Y|UoofAKk5abF)i0Yy)8j7q4V>g5&f<2l>!Du$bAUk4_1G%KEY8=h& z%8F1m4>cqpFY=*)sSq_3aq-^Q354V3Z+p7Ws!trls8p$g{u{qQ)mjU zL=9=Ef~ux;n(m4~xLSkOptWf&T8A3yq8@ug+5in*ky0b(CTPlTXwIC0mdqJ2+6rx? zD77tZ?}}2}(GJwm5uMN(UC~(*YRd%7$ol2p!D5Va$dR z?1qudqo`pt#$p`COEKyMmmxc{sgs!vQ!$Nw2Az(X%(Lk%7@foYIdmQtU?CQ9wh%^_ zU@4ZlVr7@pIEVA53$8fzBJ(9&#uawMRb0b$S8l|q zH~+t~?mf=ODi7fJ@Ao{I8DnP5)tLF2IcChv&zL(iF5R>dWs!2rk`=8KR)rLbC}Qd2 zQY0bDWud4A_Pzo+>}ua|*c*kk>~ zy4Z_-td$1xo&AhUaR3K#h_%D?2#zxTA1$M0fdc0jdYm4kC+P`DPcc6oC`7(<9v4_U z&s<#8@}0}{5`M!Ku3w{9>2(Tzk$91FBT(e};lO3BQlLI9a;qT33Z){PYetb9!8n4o z>NE<{=s*K4hQ=Ze@kl_Tl|+-cw^pFoO=c`jp^BzLF;1sxff5w!aR%cI##smk8qyNC zF6uF_$2`}{qxs0=T0UfM#-;^}%G|{$@|Puj1UCRrW2mXOx=rdFM54$aiam5?9V7%D=05j@*~Sb#qR0hJ1a_ zTi-(=&ysV<8RhxjcQx|;J}n!~#Jtap}1`nsIgydzWd zZ13FWvw0QXfw|XPm$S&{-5(L?i7{vQB(q8A=RZ#<4ZcmhwNFZ!XsHGn>4JwpdtgXmy9iy?SU@n?SwwT98* zcmXeBr1cUVh0)4|<9h{TFcz<}Hja+RKQMv0n26W#I^MvWn1sogf~j~5Z(|y!;~mUU zm3;5gnRF(dMa68qk2#o&dHB$pPZwaJwTLdpM_7W7vGk_OzGaM;tIFD^bOrO3RD6b2 zSdBIKH`d~Fth3hBFR)Qn(Ka#O%y={1g0C2VO~0jLEB=G;u+7>|zsC;zp!l;t-HBb; z&0OqZyw}=C_p>HSaR3LcL-a6?;3&$hU+8faiV)vPdXk>T8JuN)2GVo5fQ$GQm#oY5 z3a;Xs3PY&xI=!Jn{eCzqOmk@^R7MqqAQWM!YE`2Vh(weXO=A#?I8_y4{&>_tB5JZG zlB{G}3n@s2LT#j3=`;hG$U@M{R^k3^#yK>H=FvP_K=UCjLVYwqu~kAFp)s1^Hr%eN zA>4l_?qV#O;%+V6-;9dpxEC$Z(z>6vQW2=;Z;du+%Us%yK7e+N+oJgi=>hMC(#%E&>w%d2GFPR33+n9#w%%{^Cco#GA9&59#*>n!x$6U4u>cFPNW~!9zZf5333Kr=KEYBf zV|_V3Wh_?UUs#FHunMcOM#Un=zm~40>*zYVfo`B1=|=h`-Gt59g0HM^=(pIa;=tbp z#5QbazMbx%JLnHo{D_^*cT=$kKVdKSVLyIGsdbPZQt^oMAE8I+QIs(*qsOQ?juXsJ zQE?h)a2DrO0^Nw)sEK5i=p-Rv)nYA`v9i)=x>bi}BFhTWy2w^Fk?7(~)*UXFSYYbU|0E8|&Q}cc(q5coaR+3y-nhn~KNL2T!1{)sOa9 zwGeQgq66sDDn*Y6G9QG&cosugmp+H*F%-jC8;%zkkDw#yNIH^^qNBA`=Vdy^8cScr zIE=>xm5LN+B3{EATB`0O#*?`&reLa4&RcXErZbklgBgrx(3x~5okeF`bC}O%Eau?@ z%*O&O#3KCDTC8e2iy1GW;uC8rUB>!y>RG{frL~H#*3xL2vxf2KTAJ>9#v52)k1wzZ zUs{{#7JQ9wv~=CAjK9M+m5wxLI~Ct!2mXs6u~XI2-Nkq}W3h+vUhKnu{ESl8#Q_|| zAsogL97UOyp?i$+ah2hmuujrbtevH2AU%ikxS%q%i(J3V{1WraxWf1<71y;4*GF%t zOxICauAjQ7gvzLbP}W0e7^)(ixrop*-6$%eRS;QjEMgFc1T9E|ZVkpYsYpV=N}(xS zQ>w0;$~cYIhBTdd2F=uhZjg$)$VNTnsBF}A^H6|%El9K7Ts_X#*JQnbHCdN?b1Pi; zuF1N`>|^$mHTm4F_m%H2>*jMo{S0r9JkIZ(DUZ*~In9~8bCy@Gd!Lhgyz|ML%)M(; z^L>MQ?T`DJ`^+`(-v8e(n|D`!9yzDCzr0U#P2Qn-uAIfYU+$CrymxN)E`Lw*J>@D|r&o^t{&y4p>?@Sff ZbNGyTUimX*?tM48*Zlm+-rha7zXN;@p0EG_ diff --git a/firmware/B15F.elf b/firmware/B15F.elf index 931fc11be1acda21ee6af7577223276b68dc007a..b96caae04affc14dfa5f1dfc2655d33c6b7136cd 100755 GIT binary patch delta 4285 zcmai&3s6+o8OP7Pu z7c5#ahUF}3)6_bSZE2dRRg%`s5JbmUQglgbQ*BVMN*Z6d;G}9g)b0Pf5B9PXCwJ!F zbAI1B=X;&k&Tif%9G8W9x7hM@ASb7I#!$xSwJ^p+yaL|yU?%ugxffM>6G)`LQVL{f zr8`o$= zSg2LYR#Cnd03VK{(jGjgmX2VtwW+aQ=@asIb$fd)-Y;){KT>9g3y$ChNgHu4&iR)I zyi81;F-PhSIf5&soA_2)zra_vcH!G(y@Kxt)=T)Fw|<829qV~~6Y{7~64LBWp3Ou2GGB%`R5=PIAxEsc#^+imrqv;U%Yjh99(+@z zZf#13(kg6G8$}e=)|?qykf+2JfqFa8bD0vAZP8^~!hR%HP0(s~QA-j@VDq{)Bdc2R z^ES4%+s}`(TGWp*SHlUm`HG((XHp~II4o_Y)aYOQo3cK^RV_8XCG-imD;}2B%Ymf- zg}xHPsJp5s?xZ&IwNu!;_()k^AYYm2oXWj{ldMm;>g>(**5n07c;%kFz-{5W+@mP- zB4vJgbgH{2qd|sQuRsy=cO*}ivm&ePflw(MEtR_;Mk1vPw=%`+ubez|O`?B^%h-$M5g z%IQ#_>bzSfSG_fwo8j_EStaV-2+J>5jjH6!oJZYKW2bPSqP0J)*uK0a@zX&E%8!(7 zc)Z3fj~vzD7|+`VufjWwk9Q%4?i~Oi0T4Qb)V5Pf!*|(8U~pUzQpN$~%R9&V!kG0k2Fd$o4gw54n0m zy~4-RtZB>sLjMLiJz;fNlWmWGWr9(olGfzRc)hg=WtOt?N|Z{K zRZ5his%flAoo;@rq{zTklalG&yC!*wl}9DcaZA>`#4DXNom?MraE9 zlgm#G&-N8tw~p83#n#<=ZNBxkU>IB4Uu)V^Dg0qihy5_#q}nY6fSC{BOj6l$SCd?b>kpE@k&!LTV$A0(sjAMU}`PdIOHTnaUZ0j;V zuf#!E$(*fpq)$;V0*`tTq)2oT#7lG$+)*!r^Xf(LfqD^CsTaWt^&)7p(nTO!aS<%T z?b05))pb{K)h5*@*A^-Blp}(+tlEX?pqIPW>bF|EP^`1IV%mj5owZdF6ra&qoB5#V zYA6u7lwDvc@IFy6sktb-I>pj4gt6zFKb-VOK`a`|*H4}+dXxFd$xr(v7h^fN;*;^? z;C0;p^PG&0(RnX;e;i{^==?r78NU-2=zI!%$<(fZSt4V{s2}v*Lph9Oc-&x-et$$% zWG>bl`Ig9hY>dR%a>!`F1a$aUJY#cpE&-brECMgJGDbgNsQ+^C132`8&TGMKsMF&@ zdo7rL`xyK>_u;CyX z>;q30qvN51t?PH7H{t>p;YE^E2S)e+uR>v#E_e()2?oETb18Tel&0xi0X7U$N>|44 zdTvrtHVXbK8YF;Bt#nEua!4TmTrFMvC- zh>d_Yfb%h>7R)K>^9>m96ImSuPnrzY59olDfj65LO;b#JGk7Yds0a>I#Am_R)#wl* zmi$F<8eU@;{TFq{Wco0d4{=(NuDyd9y9og)$OMluZOeQxt%Fj%y##DLG^Y!}`y7mo z*V|tLn^XQ1@XwHu$$IqWSVVv0oOlg< z7VWexDdk(hMufB|IXDj|;C{4|zTIHWVeEerya&O62*K%CFzfUI?cfEbIlKYhj)QBv z-rh%ycEh1mY(e93BM3#WJB5lyCI=Bh^rfHitfTxMk zU9uBwHn0zT7VlDh{Nb4P<2sXl)qxHO{se0!`hbgIV_Q+mZ^iI^aHNn%)A-&xbIwb=E{2GqTMmu~|&w&kS$NGbdc<452Fe#)(v>Ut;UK*>q32b)oUGO19 zoq_RW;B-v;Iq-CoLl1bw=xw(GOj~yWdXU3wz|FbSekHi_A6vU-;SYYiZq}-G(^s!rzrOil;k1P2 z#m|1@@+0-OiPJNOwHwI(Uzaf@1c0|X`VIPlW^L@SkGWyGCRj|coJhZe9i13{|762 Bm+$}p delta 5998 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 8) & 0xFF; UBRR0L = ((F_CPU / (8UL * BAUDRATE))-1) & 0xFF; - - send_active = false; } void USART::clearInputBuffer() volatile @@ -38,7 +36,7 @@ void USART::initRX(void) volatile void USART::initTX(void) volatile { - while(send_active); + while(active); send_pos = 0; send_crc = 0; } @@ -71,7 +69,7 @@ void USART::handleTX(void) volatile } else { - send_active = false; + active = false; } } @@ -82,7 +80,7 @@ void USART::flush(void) volatile send_len = send_pos; send_pos = 0; - send_active = true; + active = true; handleTX(); } @@ -122,28 +120,6 @@ void USART::writeCRC(void) volatile writeByte(send_crc); } -uint8_t USART::writeBlock(uint8_t* ptr, uint8_t len) volatile -{ - writeByte(len); - - uint8_t crc = 0; - while(len--) - { - writeByte(*ptr); - crc ^= *ptr++; - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - } - - writeByte(crc); - - return readByte(); -} - uint8_t USART::readByte() volatile { return receive_buffer[receive_pos++]; @@ -155,120 +131,3 @@ uint16_t USART::readInt() volatile v |= readByte() << 8; return v; } - - - -void USART::nextByte(uint8_t byte) volatile -{ - switch(seq) - { - case IDLE: - { - if(byte > MAX_BLOCK_SIZE) - { - clearInputBuffer(); - writeByte(MSG_FAIL); - seq = BlockSequence::IDLE; - } - else - { - block_buffer[0] = byte; - crc = 0; - block_pos = 0; - seq = BlockSequence::LEN; - } - break; - } - case LEN: - { - block_buffer[block_pos] = byte; - seq = BlockSequence::DATA; - break; - } - case DATA: - { - block_buffer[block_pos] = byte; - crc ^= byte; - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - if(block_pos == block_buffer[0]) - seq = BlockSequence::CRC; - else if(block_pos >= block_buffer[0]) - { - clearInputBuffer(); - writeByte(MSG_FAIL); - seq = BlockSequence::IDLE; - } - break; - } - case CRC: - { - block_buffer[block_pos] = byte; - crc ^= byte; - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - seq = BlockSequence::END; - break; - } - case END: - { - clearInputBuffer(); - writeByte(crc == 0 ? MSG_OK : MSG_FAIL); - seq = BlockSequence::IDLE; - break; - } - - - } - block_pos++; -} - -void USART::readBlock(uint8_t* ptr, uint8_t offset) volatile -{ - ptr += offset; - uint8_t crc = 0x7F; - do - { - uint8_t len = readByte(); - - if(len == 0x80) // out of sync, war bereits stoppbyte - { - writeByte(MSG_FAIL); - continue; - } - else if(len > MAX_BLOCK_SIZE) - len = 0; - - crc = 0; - - for(uint8_t k = 0; k <= len; k++) // len + 1 Durchgänge (+ crc) - { - uint8_t next = readByte(); - - crc ^= next; - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - - if(k < len) - ptr[k] = next; - } - - - clearInputBuffer(); // leere Eingangspuffer - - writeByte(crc == 0 ? MSG_OK : MSG_FAIL); - } - while(crc != 0); -} diff --git a/firmware/usart.h b/firmware/usart.h index 1cca1e4..a817197 100644 --- a/firmware/usart.h +++ b/firmware/usart.h @@ -3,77 +3,132 @@ #include #include -#include -#include class USART; #include "global_vars.h" #include "requests.h" - -enum BlockSequence -{ - IDLE = 0, - LEN = 1, - DATA = 2, - CRC = 3, - END = 4, -}; - class USART { public: - // Steuerung + + /******************************* + * Steuerung der Schnittstelle * + *******************************/ + + /** + * Initialisiert die SPI Register + */ void init(void) volatile; - void clearInputBuffer(void) volatile; + + /** + * Verwirft Daten im Hardware-Eingangspuffer + */ + void clearInputBuffer(void) volatile; + + /** + * Bereitet Empfang der nächsten Request vor + */ void initRX(void) volatile; + + /** + * Bereitet Ausgangspuffer für nächste Ãœbertragung vor + */ void initTX(void) volatile; + + /** + * Behandlungsroutine für USART0_RX interrupt + */ void handleRX(void) volatile; + + /** + * Behandlungsroutine für USART0_TX interrupt + */ void handleTX(void) volatile; + + /** + * Startet Senden des Ausgangspuffers + */ void flush(void) volatile; + + /*******************************/ - // Sendefunktionen - void writeByte(uint8_t) volatile; - void writeInt(uint16_t) volatile; - void writeStr(const char*, uint8_t) volatile; + + + /****************** + * Sendfunktionen * + ******************/ + + /** + * Fügt ein Byte dem Ausgangspuffer hinzu + * \param b das Byte + */ + void writeByte(uint8_t b) volatile; + + /** + * Fügt ein Integer dem Ausgangspuffer hinzu + * \param v das Integer + */ + void writeInt(uint16_t v) volatile; + + /** + * Fügt ein String dem Ausgangspuffer hinzu + * \param str der String + * \param len Anzahl zu sendender Character + */ + void writeStr(const char* str, uint8_t len) volatile; + + /** + * Fügt den aktuellen CRC Wert dem Ausgangspuffer hinzu + */ void writeCRC(void) volatile; + + /******************/ + + + + /********************** + * Empfangsfunktionen * + **********************/ - // Empfangsfunktionen + /** + * Liest ein Byte aus dem Eingangspuffer + * \return gelesenes Byte + */ uint8_t readByte(void) volatile; + + /** + * Liest ein Integer aus dem Eingangspuffer + * \return gelesenes Integer + */ uint16_t readInt(void) volatile; - - - // Blockgedöns - void nextByte(uint8_t byte) volatile; - uint8_t writeBlock(uint8_t*, uint8_t) volatile; - void readBlock(uint8_t*, uint8_t) volatile; - uint8_t block_pos = 0; - + /**********************/ - - // constants + // public constants constexpr static uint8_t MSG_OK = 0xFF; constexpr static uint8_t MSG_FAIL = 0xFE; + +private: + // Eingangspuffer + volatile uint8_t receive_buffer[128]; + volatile uint8_t receive_pos; + + // Ausgangspuffer + volatile uint8_t send_buffer[128]; + volatile uint8_t send_pos; + volatile uint8_t send_len; + volatile uint8_t send_crc; + + // semaphore + volatile bool active = false; + + // constants constexpr static uint32_t BAUDRATE = 115200; // 38400 constexpr static uint8_t CRC7_POLY = 0x91; constexpr static uint8_t MAX_BLOCK_SIZE = 64; constexpr static uint8_t BLOCK_END = 0x80; constexpr static uint16_t US_PER_BIT = 1000000 / BAUDRATE; - -private: - uint8_t block_buffer[MAX_BLOCK_SIZE + 3]; // don't store BLOCK_END byte - uint8_t crc; - - volatile BlockSequence seq = BlockSequence::IDLE; - - volatile uint8_t receive_buffer[128]; - volatile uint8_t receive_pos; - volatile uint8_t send_buffer[128]; - volatile uint8_t send_pos; - volatile uint8_t send_len; - volatile uint8_t send_crc; - volatile bool send_active; }; #endif // USART_H