From 3dbbfbef9eb23dcaa0822105201cafa27ccba61a Mon Sep 17 00:00:00 2001 From: "Jean-Philippe (JP) Cornil" Date: Sun, 3 Nov 2024 22:48:47 +0100 Subject: [PATCH] Add firmware example + some formating cleanup --- examples/board_sh1106/README | 65 ++++++++++++++++ examples/board_sh1106/firmware_no_mmcu.elf | Bin 0 -> 51864 bytes examples/parts/sh1106_virt.c | 86 ++++++++++----------- 3 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 examples/board_sh1106/README create mode 100755 examples/board_sh1106/firmware_no_mmcu.elf diff --git a/examples/board_sh1106/README b/examples/board_sh1106/README new file mode 100644 index 00000000..dfae12e7 --- /dev/null +++ b/examples/board_sh1106/README @@ -0,0 +1,65 @@ +SH1106 OLED demo (navigation menu for a motor controller) +========================================================= +See detailed description of the emulated system here https://github.com/jpcornil-git/Cone2Hank + +- Use arrows to navigate menu +- to select +- to start,pause or stop (long press) motor +- 'v' to start/stop VCD traces +- 'q' or ESC to quit + +NOTE: Emulation may be slightly slower than realtime and a keypress has to be long enough to cope with that. + +Usage +===== +Command line options: + +$ sh1106demo.elf --help +Usage: sh1106demo.elf [...] + [--help|-h|-?] Display this usage message and exit + [--list-cores] List all supported AVR cores and exit + [-v] Raise verbosity level + (can be passed more than once) + [--freq|-f ] Sets the frequency for an .hex firmware + [--mcu|-m ] Sets the MCU type for an .hex firmware + [--gdb|-g []] Listen for gdb connection on (default 1234) + [--output|-o ] VCD file to save signal traces (default gtkwave_trace.vcd) + [--start-vcd|-s Start VCD output from reset + [--pc-trace|-p Add PC to VCD traces + [--add-trace|-at ] + Add signal to be included in VCD output + An ELF file (can include debugging syms) + +Examples +======== +Execute firmware.elf (with no .mmcu section -> -m and -f required) on system + +$ sh1106demo.elf -m atmega32u4 -f 16000000 firmware_no_mmcu.elf + +Start system and wait for gdb to connect, load firmware, ... + +$ sh1106demo.elf -m atmega32u4 -f 16000000 -g + +Execute firmware.elf on system and trace signals in a VCD file + +1. .mmcu section of the firmware includes something like: + + #include "avr_mcu_section.h" + + extern void *__brkval; + + AVR_MCU (F_CPU, "atmega32u4" ); + AVR_MCU_VOLTAGES(3300, 3300, 3300); + AVR_MCU_VCD_FILE("simavr.vcd", 10000000); + + const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { + { AVR_MCU_VCD_SYMBOL("Encoder"), .what = (void*) &PIND, .mask=(1<1yVe${wQ4uOeP8RXT9uiE0AZ0#79wgz zv}(1zt+usRtvYtKy{)5Nu6A`$TXCrj5(E|Hea=h*F>QbM-p}X#ql1|_^F8N0=Q-y* zXM4_b#)2`E#v+6W_vJ%OCfsiW0Mwl#2w!*(AXJ2eNFtPkLh!e_Bf#_P+2Rj}^MN0Z zKW7ehkb>VS0PxSx<%j*%^8oW9g&({UKYI8pYzur9Hp_qUo7P=n`wV`67IsvRKgaLH z{yF|vtUTL}uWe5hI?>dUnK! zg;@(n#Ee)sA|`71hT%~$Q`b+8iFu*mg%~1gcoflo<)bU@L{uVn{dlEaJARm7aPPir z`u5fp`1<<8tyjh~!>+u`Vn$Y+V74F(NZFGrj97@vXyD2oCdcLa_BM00w+P#}-)JGM7aNtd7kB*}oV8F4C| zDlS7eM3*r$Toyi4B3&(&4Qs@07rq;2l+@bbsZt`ml3L`o?5LdNE$tQ z$dJ*aM<>B8sbI)cPdyby$TrA*qF#M<>*@lTRJxiNyS}4n#_1$cVy2gz_aS9DQk3! z9#5_a8#-mml<7kuwdq5rJoVHxf*7+dlkgd{ek6g$tkbQB3Rur4^-AK`JvC(v&hNUX z)&w}`x*7xq)SCa&{ zzP+{MAJ?gd2*L)pA)1g=ZyeEtBn`Mr5HDlF=@%X!4>#Eq0{-^lzxFBc2j$UDfYi4W zAXV7aPPB)F@F6_BwgJ`x-tezIJlrX53lEPBi3@>$ao`(=qwx@*00@KlH3ZYcF5zky zUO{?+01g&O5N%Q?rV@$iIk86zkiu7s;ED`)lXrp(*uc@^a2mJ`w80H9U@`<43U7xX zf+v9O_~P*ePY4R6+m-kNp&2r|ZQ{g<12*{h`1$#4fWMhjCS=Y8kKt0?22~Fg27Rh` zUD;I~({Dn*m`N+pib>juk3X)}j$b`q`@xK7#y&a%s*%_LqrirK_!>Prcl2mo&cx9= z-ROxqI!FvjI1aS3>6z6$Pw>gb-R?I}9Ol2=ySMVLkJdoHF>m zOA%DMi5~{)JeE?Tx|pzMMRSBcj(Otl2GKi-~Aw{j_?yo7h?*LL+}?$ z7r)CC1TZ7(U?@aN_=ONr9SmrF2%jh-1d|mmm5h*@2^rLacX-j|W8$c}d(B8l|Xl0I(n zfp^BQJ2BBEK2X|8x>>=*C+>GC(U*BuP8d7i=j#gbyQ=`C#587>62il9w*)YDC(z>VDu^DewRc%8Pc5y%X7W^`E?zu3M$&I4H4=2NMnbqkmS`U z*Ska(EYl%6pa_f31iYpBr$rD+ZP7VZwsZ95Cgs^*DWYXM94}=g!xF{ec+Nx@ZC?iq*4sPxafmIbfhjs1vgUWBSoZ66#^Iuh)xB>d64)9ex<_Ln@I= z!@#G(2k9~s29X3pJ`$93GIX}2h?aaPuP z!AhJV&U|&~mqS|(Wrk>fOtj!n6oJ-Q${C_vgM?Z zn!;r!!*vny6)H+3D~LQU(7e^HQ6PIlx`-)+p0+Nx^9`GZZUh-fH-w+YbS6 zbB_h*#LQBxiZM|o2|XKMr#_&5r`zaIhqSQS$ffq=wA>yvK4^OEL9{4nee73AZvV3| zucApo&&M7@3xZx2!W^NF{spyH(G$_R^8ZLJ`gwULwa~w$g;PC^Z)zRfyQn?ED$U~G1)8PfXeHflZZKakv*r`#x6C!>N^^mEsX5o2 zWzH~b%rbi$Qc>z-LGSuMxX-E&!kYnOB>l6bBq6jh<4~(j&ym)vgo?gJ=rv|8Dk9o1 z+=*+xBw;9@v}yEjI_pmo9oAa6LmMO!99kYdw*1LT0aQsA-VdH9*NAP%_i? zgh@lLu(wMYGlV8Do4RWt9R4He(-JB)h{0)oAt{9Wza$}+ui*Ekgo3xzlF}PiPG-mQ z7-zxKIN$IS!t&umHc?z^CYQ|}M@w@HvgCH98JB>}E~ZLCN+k)=eCZ_;_>$R!ZJ+p= zAEMNT3XOK7GAIX4lalOS0)tBr5tt ziI)CIGBR?q|GQ3Hw)SOpP55cKAI*@~MuLQpW(bL@DpywbF(pSkH#Xoh=)}#|Pb8%E zV<=&$0r)-K?$4`B(RK7Px*Xix<8;>xzSH@055kxSsE`h}E%xtOMTI(9WkX!UDfFoFA*HB**f8L`$#kxENZQOBR z%CsWF7;3!1nkdgQ%+J<>)HM=Vc2QL;o3yF$Hxgu0W~Z_%wK9GjQ?KEC{kPyMW{tkh zIqO?^a@n`DKBm7+sO729U|YNY4dDEyvOVr5;JfH|=^OO#3ApXaog^npHwkZdS+R%y zziIB}BQy_Fy^$kQtpusNL5GIQm^1cY5`MB)o)BwNX8$F*mBrkexi*2vM4HU5$^v<% zOAeFPrJ_py`Z* zQHinI7|NNF<$Or}ZM2;%O{Eg56RkEXluk*Z9;Ke3a;dzF%dZtf$p_n7Q+zZBQZA|+ zQwZo?K7;YqM_y_yE|BwCOog#B!^Ce+rJ>GnjhVXU@D0XRQ>Cdo;cTOsf;<>7<*TN< zCX%YI!0(+@HbU&7{B=_s_-(2%CCK>${cuQ#S3%lM38Vps2<301{d&wZ=6Ey{stgT1 z!ix2$^y>R%b~7c$q*Fd&|2$R9^8^={nDfKD$mbtZmOD?d9^5(KXAksyj}=q6!baGS zvVS&L$ln<-Iy||g8sIA8;jO89Yz7da#RA>OR&$bWV z^0{Rk?q7m!LjrEH<&m*|p}c}G*Wk8GTJW5pp6GSohkM6&AlAO?=0ua>$#S*yn{F`;;UkBGhjE2bTZ2&gUnb=6*qvt` zEL~HF416~52lP2IX3)A?-vhqO zc#=++(wwOeX-$_hmj2Q+mH|@EGEmA}1_2c{P|*MtEl^4OBb7n4FQ&4ZXDn)nsezbU zh?yp(IJTpe;?cL24YBNyhFEH)GW(ykA6(02NUH1_cOAWe-i$gSVQVh>=PdSCrmJR$q@Rz{) zz*~XC75J|$&`%Mf=%(lcZjGYwAUUt_nE$a(%6N1oXTT_XtXUX$$$2D<#b>N0g0Yqm zSbj)?oFQUmfRz$;0#*W2jl)#{R!*D)%uL|8X27Ze+eCaNVh|T&TL9Zkd?a8vF2-H~ zY%6gXFh+4u&Lg)LLzZs#|kCus;!8ly~oO~Xt-p?@K=I~}+q@SVV9YB<$Xo93Iz$HV;& z?=DxF9jA_cC}*HC#+YgxVI(7I{~iAC_|I!P-610i+f;>;iZb>!4l_2e-XWP=G5YTM zde+^#M1JtBmxMh1B3p!75hb|RflCjr$7COJ?KjzoTigY|0nU?LzlIMZ&cgbS;Tmq< zjJU`>@cV#2l?UUNlgY<O$>uU)-lAH5sTv!$*cX)>Fz~y1#-UjkIxIM1qVA5sBj^nQsbIfAQ}6p%eZ=8(zp&S}d`x{umDij>6*c>Vw!$wo@heoM zbj0nc-M{NK<>9z%=(A-%_rZO3IYJDf{K9^%rJN>{%dIvSt#<@kNB$>Th$#^$k@l^$ zDdBq;rJVw$eg6}shq&tVE^98(EbE)BGAv~AI(O!>Ic2z%dQ*d`eC<$vrnWCn7n8;P zi{p!B_OxPEv9(waF3o?TAHl291rFtVt+roID35=2VsoXba;;&$VIulk9aXF}3`QTM z{Dh`grP9OcXB<7dLf!LSPexVYIZ(7il*@A`y9w{2RGv9GDJ3W6J?>xI@`9Gfh9<5n zURWFv5$UJkKRS60dfmIlSBtH}`d~AZNo!d{F^jNt;5E8}KX7ty#gU3>FbASSrOb(I z$GXa#-`FrF>Qj6Qn?Rp}wG;=rAGhHV;3{>OYBO9nq^0ys*@}8k&d3^4sVSS7n$5jX z_IO!?skP!_P*dz^dYisNkF`AWskPLMpp~&}%jTCAf^J}ISy|cDin|rtsRNX*UC%Uf zC&HF8Z-p&pVuab9h8kiN^)mBKYfYw#%@uMxoSZOuJ-h{V@XFpn1FCFvx?>Fe6#ad-Lr`bBpd65jJE#{ufF53!Ty_`r zG7m7{Md?*9n$xNV&_m18t7d^~v^kTT)HRBq*j2_CFmqDR+&|XOLz{*=iIin_6^00i`SSw zi;(d-YzlJE;kx$jCvSu zYl=4(>HZq6?85wV!E{t@uoKF~Y zjhOlnZl}=Zaesm7UMsm*A~Qvsu>T_CdgEynY)cGIF=0Amxx^Zg&MU>`#mCtN+W7*9 zZD>fJBBg6uDh+moz~iQjDx<7kUq!hJJOIpr^(oZKuE0<%bcmPqKA{|5R}<<~?Dg ze%Ke&!id;Qb!47oL*mty7lS$9A3SOFMf<4)#yvO{tHe z4>jjC+fY*UP=S(Pc?(e5jow8+uJKtJQks3S6#bw%)*E%w_ikf ze?nYuecJV$?{iMECW{fS%i{>IzIs+QupKEiVIz!}a+~JAn4{r6EO8fWIJAQihEzkF{33nmX(HYkv_+pHIycZ>Os9?*l5_AT9LXC z&DX5fD7wb_KF7a8ZKUvg1tU0Ik6oa^RFZON9M0WEMN^D2H!kaY7Vl{cGxRll%l7^s=Qwy@Mn%gd zy_Nm@^pESAp5}YQsiLLQHe?3vP@;A|ujgd;?GU0T{RSGB^L*B;%7dB%u_;zmRTR0Y zi3Fc{$~>!Fg7+5i9z%#l3VILHDgiymFOqytFX-p;IfL-LdY$J;YGVOuAgKztms}>T z?-NG2e*oHC7PQecXSUY+lz?uMq2DLY&_`hX{Q*%5EA5e+&@o!n~?f{ zECIfhWmt*>Jq~x0)pI9U19!|zKXJkO1KO@U5O)LJpzc%GBJcT!IL%xlvlhm2+)~C< zIb60iK&rE*0N*12D7g`K?KZ<&8TV7-&f*>zw_y~HxZ{UfD3H^DaGIk+e_%}-@0`l) zcx`v*mS=3dFL@Z^BZvI<*X)1OQ{mNQKabVqIz(QsFq}gX!r1mX@~?8hI(??FB3=Ni zzmnn>lt>MvMyj!10{cxC{GI{7Y3g&Ry6Q{wq;Q$@Lv;%pv+Lq|A20X}YPFy^nn&q^Qa*52{?Ib;zAFnL^S|9^lGA%iT>Mt>0`& zHk2D$P@f8IZD#G0wRzl&7YiH2ofK70nmkjUBYzsS9D{+93fgQ4=zy^vY;?!Y?m6_l zutpBH-3|X)b%5WLavt*aO3M6{E2=7RxZR3FG2chkv*(Z% z%I{J7ar!yB%JHAlo@~2nylYekXY^RZRvY?(-9sJ+`t7|~gEz{9pJ!eCoRH^t_&*M- z=7Z=Q>hwDgQflMQq0LoWtsAY?j;+FTiv#Z^Zxh_FIL-*q8b`nXxsS$UB<>rDGwvOh zg@!gE|AgZJk4t`mpijqTIkJOyTs99|3&`wwoR~v#FMTnronbeo!UpAdLVlIahrRtd z*A%u@5p%D#xwM;QV5w2dmr%H04v>-_Evd7mm^rbf;NJg7*w6m~eqw9GJ#^9URS@?a z^ojqL6btU}!F?Wfq{|F=C9*$a6YO1{W`AZm`bX$fe~{EiYMne+Kly$Z2|M!8s|!{J zW|uD>?KVY@cV30vLmWm$X}OwQv-L;G=LqlD{s4OgKT1s9s{=cC3*05R4m7HzNJR%o z;}cB$b?7HP4*sskmtBAMoex^}b3&gWYS}-77Tv_of<1;;yZmvVLL95yRth4$JFruo zDpjRV<3(L>e?zmP#t6k1?*F&8bMHQ7&TPShdQ~#dE&A9K!B>k4o&4gW>o;TCD zp~XqXcolWcc+V)eUv<@Iz44B*)VKu@td(69mt7m$ zZaiSbtt-?~WOA6!a14h-t>wxiU-8f6dsdmyGFa0tuhGK#t(l#rt>&jW^R+!2XK3d) z>M5(ht7scBPrHWCOWWJhMIWZW#U?5T#ub|ECViyU|GB1A>u_s5JF@%aK)uOo60~Ja zk6WL!{=&u^`y27x7>9fRHmY)z6_tI%5)RWXxl`-@ffxpw?x=+`A@=r<(# z_E4~h3AU97VkyS$+89{i2^&cwWtRG`}W0Xf^yo6Y<&?a~Etw+HSj} zcgO7Rz8h0Pj%|A?_H3kTz_sc1$~`#!&N;GYIj;lV!84#Wz%3`(HZQtG*nxMoAz^Kg zM_*OFmYV>rM_g$tD1O6^0?&rO@ssQ9cS{rF7>lFwt%szqgH-Ej(0wNr3#pNw?VHGPxYtf zLmm>6L!EP|mnelzrhRy)?t--(#4z-!&_1>P~#8-73Z;Ls4Ee|i9I z>vxwuk=S;y-biNu6ql&>9E!EXSfce&`kU+)*h!p4tpZ8@Gv05&uJ;|G<=z$USYl1d z6j&@Y1bkWebK%Xx_KuxEw{?ZAxe|JTjqodjUn%?yoJGi4oK-3G2o;C69g+!rZUa6m z{)Ep3)XUT#$9Bx2yVMtQD;_HK&RxfHgvY;D)M%~*%?!+9Qd%Q=@=H^(`~8%jRiA3l z`cf^OG9$F<;YDKO1`2k!FM=f35tSQA-~n5bY}`QRlh)5AHFPBnbI0RKbDTNKPPVsz zJmNUmSBwMhjyP1_uWV=TJS9_O&9G)!bD@te0GX??zGXdOZLqcrvspZXE^=T?XPk3v zJz{9@#ms}2ItDB``! z#VWA#)PkL79~jk!!z!!7;7K9G`jLdNekj3xvuGzp!YUTqU!L?|!@7OFtuf`!oRgwG zrj%?3yOQH*;R^*>*d7z_Rg5?(T4Y{ho4EF{UhtQT8=E1G194R7 zc$T_Ig4B*Fk+KAgmwJai5}3*`-(4a`(_^I@@JqDrX&_4LQzk z()I+)Wh?;%TMZ?B|FmJ5oPV3We7%vQxHPWnQcpTQVL6ZOowdO21r+K?p;gu!1a4=Q zxy9NwEgP?p)@x8N*N93JY5iI92iKO zI}S>J7PlN`a__J-ATP3p^!d(8)2533V98Hf31qe+wB721_FE>bITN1BET8F&}~GW<&cGBWThZ;zT&uoXF4REN08P}B_(xRI6NIQpj>RKj@nFX|Isd|G@P`;B(B2^){VC)+kGPr9kGth>0&A%U0cN^A0MngtT8y>H zKj)U&+8#h!9|U{?t)@L7#PT3u*lD)}xNU&t&id1$)QRJEr_@oQ38zJwyUq%`+|KT& zzdqdv(s%sy%xh~osYf4!`xSS8LV}f;8LY&%gO%8RuoBbKhb0MIf--gRv}V!1Ph~v} z{6i=!gt9^?>oHhoK5P>xh9s?kTESA#3YLP_lM;7-f%}QhzM*%0g3?DA@xS)s$-A#( zVNQqpJJ318Y&lh8qKexk%w~$t-fSpQnhYfrwxmIhG$)K;xupgZMdg_ccwI+_#xliP z9jqlmry|VdUIE>T+JJj8JgT@k^X$nwIn-;XwRG2C{SVw>&Pe(&QBpt-k~=3dd~*qC z5%(}r&19O~xrKS(iQD`grUY7;jrptovoqBah*iRn={YS}hZ@e11LV$E7@d>sf4Hfn z|DD?yHQw0IkOSpTBU1wRDyC#W_3dEWBi+uhB}3)Ta%M<#$>6?xwzFhVC{GUVd)ojl z2Q;&mWXV*fWQg4PGD8lH=E)&){t%2w$r2K@y2}|3TokuaNm>D+j}kohYi?T>X?T<& z9~sJXPI8#sxrQkjCg-=Z_~Zem7yv!4T*A@+mhkjBi5%oz4(Ah;4DLnb;CIzW&XB|9 zu*X>f_nmCXBe<1wbbu?R00~&0=U^QL*7lkK#}xW9SVN2vQExkoHPZ-e2np$?$Z5?S zxJ5pZ6fEhU1RklYK(iASxfgs4oiR_{GS;8}%Wxzu0WJ1(pe-e>zeozN;TbBPb@q1Y zj}l)(3rGR_KXVqDSz(0+ZS13FgJSc+TK(VE}XQVqow zft5Bs9e_3Zi~ZTuvzi;h_tlLt`24_O-oL#|$N7OM4IYOU`%?+{BtgSNmdp4A!SBFv zGkg7#lf!y|lABiOC--xO2D@Rm;gCUnJ&j8+S47ffNun)ntR){NF zxZ}8@3&#~**xqq1@c1*x$?vUj}Xb1u8N9@Kn+}IUjeFNquuS-fhsOsx5 zRYRRfwNRi6J3DovzQRpyh6l9}>zhF1pORu&C5oJtVfqHQ#83u{VW;6;!wjwr{BfH5 zA^cksLr3_ZP@API@ZHtXp4eoIsA{uBbmSvU$WN#v80;`T`Fw7@)prq`QSQ2drx18_vAM44>X3k+KGMp`9im+W#^*N+WFMZ**pKSGh}z<4$JG*>$cYouUEZpe7$8~S-p*;-y+`%d$Z)S*ams) z`x4H2NW#$vpf7n_QV6R|+?IVf~%#4zhU=QaBq=5KxtJ42=5YXQ0Jy#dE1`?X9TS4g_)$EHq>`-3$}hGX$S1I zZIUKM4)velEaI-DHmB~n`Ywmy)MP1WOGuX-tV1Oo60!D5v3fb@P`4pkPwJ_Q7S3)c zG;D+?E=AK-$RXGYb}0=jErx!{URGGPliR00kn&E^j-oirJKRF`Qp?6mr__4xy!ryH zrBAu^QFu*#9!(Ww>S;$8;Th%t?UaFlp2{u1KcUd7t(J|J;>#AUtFSK+?kN1#!bJ-1 z2*;MICbf;LR!0k=q8wPaHd*j{(t%58ir{|A(Y@*e%bS*NjyO2o>CHu}pvT4XaSj0= z)?jG68(poi4HeakHD~-y%y|VoanAMEH`QVJu@@B?deQwdL8 z3z7N=ed(`T#2P3H137lbj~3!bLB6q0shh)Fx5Qht63(KLENEB;tqYg-kO0nnNWz=n zmvmbHokI>mzqAQXr^ubp!!8)}#@RPchMxtC!=D*RMYy2XlRMWk;#rjmJU(S2_Hg*z z3D%^#_q-A-PB`81pofZ0PIrmpTTS4eZ0?s7I7Yy0sDFZUU$8}!wLo?ur`L0|VG z^pW_vLskwwclj~6&niC#cKNQ9NWl+N#rp(m$%W$-^oY+w5A5ED+95m6oU2Nq&p}Uy z^>$qyNuU+%D`*7&YA3M`JptBmSzrnGf?y4Yd((4hlORnFTpIiu*lTS;`nT}z8mt4I zXP9U`*8TNK9hf?yE}L6$bvbZ&H@pPST;Nj$?owWQ4eQZXMU=ZFY!aMS(ZIZ13#S+l z!JPbk$+sZ$!>wv-7a_GUN2E}P5e_H9mdg12mbe>>EuZn40;gWXh#EO@t*{OCejy|4 zO*Hz2+^o5&t5W55F)r)`faLzj7P-KuAOXa&zZu+~=Y zEQ49j|FT;JvS1MUpa?uGUc}=3&Wpx-epnXqo*#a0>8K6Rz6v>g#StOYPb8d9bMFB@ z4x@9SQRw}V-dI*})|n@~W4SU4r?fgHF1ADBioi$iymuO(oZ2C4IgM%j%7Ttx*tK-m zPD{s*UMl--her2XVZ9v+Jqgx*;{L=v9=O|5w7`E9Xbf>a!X2UYb?Po$qZ(aOsU@6N zE&sI(XXIXkKJX-1j@o{kuMW0NOG)}I4Xm%Sfum1TT2a1rxwR6?Wm?K^WQXUcDRZ`& z(cEo#N9c2~^*jr`_bb*|#6>j1UOU$Bd7s%aTlPsv%U+3*yL96gwl>`z1zJ2uKp&RLpXc8y@Bm^AwX5PBltj!_VPzysl5EQ7*n+U z!ZF-Dx%(j#jLUICt@m(X3B~f#ThKp?F6SS#%yRp@n=3n7QPUQGhNNp@G}|GSf)=L7 z5nNMd>kb$XYo#T1+y1b2cZbGp_ci-=^FJl~&2LIRfpqsN2>LBa2)!S)O5!;waZdJ_ ztd_$Xp6xJ)>RK9J+S}MK5^HuoEc&MCa#3^9ZkVndgdX!f3ARWmrz0G2TAYsnsUTr= zH^b;2Y@4HC%IC;K9wnVzRk$^#SB)K z-di^0MhCgUJqPZ8u{{VuY+*+lCmUxOR~aKvAC%Z_V8GabsR3`JTJ#v`-12>w`^uc} zuxZ9L?O}dj!d~9U4XZkj;;P)zaUMMl92y}{81LGFSF^2XoH5&!Z(3pc7;Mmg3upzeCPL@UyEP1)07?X=g}}a89=%11>%2VhJnUwyvn;W6 zapdEfv@m+)0iSvbj{=1r_4{uKiQ8TmN0<;J)PYMk6Y6m<(A)>>&S2ZU0NndbW%r;( z*H>`tM`F5iek}99rcBb+AZMGU`1Jl|;k55HXeoHS$2JVm{(+ZJ;3UQpCd^~HK+ZuP zteO*^Jd^Z0AQSIO+E6(3wJY@bdd#uPyjP+%?~@SpKY{Z%J0$Qt%tXrRF3?AAg}n(A z$XzoN4m26dU^qE91WwKkmGYKh(pEH+I_ug6>I(g)oJSp}Dey=ko+x#X6yg{mYBBNI zxM*i1>Z%Xdlk{N7;SjLE8VVLz!=$IWeIIZw;9kIix_?C+y7;4CowQLZbEcfc^Kh|T zUq9U_v{2l$=hTl;Pv)kmdtU0#WmKvwC;U2@o4#}W&aZ_&HPm5*bAJk_^km`Fw7kN) z74{q+?hWf}@6;|gjiE5%psTpM_jd`*Ll0?JKn%A?iCrh&`QXe~EYb zUln>t@e3X}XX#aUcGmAyS7cPEK_@Mg&$Y?i=&n=XJuoW>TB4sv_pfkMnJwj-V>e^x#Lb|D8g7$VX*s~lAml z2*-RL&Uzy}%ZvxB0BjL}zXpJ3n^M7gqLH1a{TxE$6FJeY5g0k}3L(UaN21QSslY$R zbhh_P*G_Vw&ut35XyGSRl!%Ca^+bz zqAlzn_g2Nwp8Ky4@2$H1-Q$jXZ*~5)6(Gx0)C}kw+$mB~XJJ1N+igTU@HsQQd)to_ zcX|g#<#~mS5JE;e9uD;gtbH3(@Jehf_pSP@Yc65r#;bEurWB1XYAO1yNIc!t-9aj8 z;WU1jQ1-Yq#C_$zn#qYf7IM4z?Bse;#rlfUiY*oR^wj)D73|i=CroH`rCl0QDt?D% za_Pv@l0<`zPALz5rAJ9nbu3+n;;{VhV z#M%2_)uyM^OSgj|w96{T|56C2hLV^FGlM0-v)tZ@81gKMPwf?6H-jBxu&pngTgJ14 z#TRG6>SeaDauM;@(O8gZ(OTb6u=PoR^1#+T*iPTQ!+#QJ$f88aI{4KAZXt}+2VlqW zbr`wcaE)A8moTpa`luD#Aa!%xMhV3OipLZ`UHqbc zrXG*aQ@zILJ!lrRDLhIS{tM3lwnmfxI_Db8bdE_axOd@U4#dG6=pyK_y}9@fMqsR| z!ny-IQpQ-CQG`BH9|G%fab5@dGnhp@25W`LqL9*1kl~)fH!W1KLY!QcVx8>3^Pr5X zZXL6rKhBH9xgS2K|6Xa+mUyPe5e`Oj9!7H8Z+)Q@GU0S$AHB9Hv*^j9grWgOV~U0FXsOc0llotu*74$F9`3s)MxaTkU+aE2$h#U&qh%Wl~^pz*z+fW{5 z-SCCm-UiPdL!8)3h@)$yJiT421*=B9gQj&#uv39g@h8Fw+w;wMuLRpcnHuj2 z-xYX(LKz*EL-|l$C~P~%@%Uct3~}VccPJE~1HrnG^ePs)_vU4G!dfE@v2K?-Sxi5N z$KTr-!tX^tqRr?Sx`0~INwxvqVa*VRgs@++570$rQygWbt?^)wHq?-0ILE5!SEO2c zn=~Og6Kv>%k(O2>t#zAJWqk$gycO^sgfRU~C$>-0(IF@sw&WAL4-DiWCJ!+$MmG6x zcdEN*1mf{%HU9>B0;D@Ja-jcs{t4)&vVocosNr;LSf1m!t%6k_;ke4f=_?1;^=yYy z+YhDoJHq7_;;41H$0Rp@n6{kHXLz8-0X19>GW#`jI`V>lee*=>S!x@~?3&|ypyevM zXSimVKu@PXR(=FA(+zoYn zg?y^;2;iCa(A!!^PIHK5JM6&#ufWB2;Nk=J8^ebNTyvQAsmSjkEu8xjs+tk_-zRu9vz03(Op1K5)OO0T@jYz z|NopZmN0b2(gksraKu}>!cIHp@Q>W(S%DiXaAO5-tX;v9_D=N!)^dzG*1Ea64|z~# z@2$Z|+!2haj$v)u-OYD4E05!^Sox|Q_j))9Td?it6gXpk2HQINw@J=C;Zy*UZP(eg z_MY~PtgNiuEcjB5owP5r=i3XiDzj?fJ=oSQbr;)w%3!{ zYcF` zLTb21k0BQFv;*ww-hnY>C)n0eaCVZ8eY?XYvt#Nxb^ZeN-I0g6Am;@NuZnT-KPZNvY7#=6$_!? zt$|h_uk0T;I&NRw-ll@w%}&I8(UN@Tfu`>n@#{QC!6R5q9by{xLFn(J`4t$jbr;St2&A8mOX~efpMIHI6$^E>gL`lcO6w&Uu zBeU1JzW8%APUPhXl=+PALJ0-lj4Ns3gxro)&$As6@`Cdot101Yrf%X7YpVMk%GuA? z@$Rn%b>ojfIfpX`v^12(V9f!r=*G1-7fz9t^m#vbD1SKPOBXlq*uQVV^7C-JsJF=( z$31Vn8nhpGG*wrR_OaS;1LtDxG={dacb!L-q0YSa?hIaI;#;w4O{;;t0b^uhfDM12Aj(hf zC%%P6bny%K^MyCDPGdFan_y#zJKCpaD$n=(J%gKY!;iVCJgO9>Dv5u4m?+EOdPbDI zOZLt76)oftt#h;89q#KE^LT~rphm8i*a$@^*dRQ~A64p{C&2nK556nt&KsOLv~unK z%#LefTDjM8>k5X}r8G-ysLed>#x(@#hgruy9I5e@q&yI^I09&$QId`gYHRYliBNSNBhj_^HQIGfvGvJ_Z*Pqhug6o zN?Me)ch#YZSmJOCUe;upqtm)qeyAt9GYx076#_FLS7idBgYo=!FHuH^q zNy0=P_crbpjN8iI7A*hd{~`ZZ>@~S3TOK5Pwt*VZV|)fB=-+lT7q{t}j5O#SR2{v* z!(m1H>vphl!F?>&BQ((MFgN{9qXFBxEU>Xt0CoZF{jgPLJDiNaV0jspqj@$z<_C2H z#K_S+K=rm=bT4`!J%*k_?{32A($ojYfnGyDKrem)M$&dOEGl7Cy#O;6tPyRs;jf$i zgb=gXnhAO3;QL(nU=Dz_frP3K-rj^c#MTiYo*L-<11Nm;FFDpfpUH(lZ0+@S@7M~R$*N> zAHK>ksLh92+ECDdS3ipMNl=@ETlFY_QNT*N{n8zSxE`Mk^*Xq<|ASQK$rSv}v*pcG zRC4D$_7K85GPoq3vE2skEJ>LR!4UH@`+uht2`TB(cOLQk*^F0zzV{7Cp;dI&wws251ZyF@$Ut(I}bnZe1pJ~8zSIl!$YWqJj)DAdV z^KcK0^VJX5le-|FPo|$ze-TxlGAd;d>>$+JbgiF<>zo4~_%i8j5~eBj!G$xO0Jl>%m+S9$**Sa5TqQR{yCh1D`md0olU7}_#AYY_=|bBk=`SxZ-gI{ z9%#v8ajrVFhmbQ1`%Ox{?OP!i#=%1y6H@yYe66k=gc`>?O9t-cTZFy0$>6;$-$Ls1Y+tvk>a<)CxV~+@%?^MQ&3a8y-g&jEE}ipX@V8c4;d>p*hf1=u zq#lKI2e-}@I5J~P2jGThM}p)SY^zy=&0t%_7N!=hmOGcTw>|3AVAF>)O*ttm*(Xz` zMd=~uOW0Od$d}o&ii>(~0;X4$*=KSnsIuvqVn6qtE z*2LlO0STD-Vbs0qjMB(8*HIZo-Ip_Q4ax=z&Us&e{zg2lq;C&r@Hq_OWCpCBhCA`O z0~T68UIB#|gcBB3HE?qL5-Xfl(O@lfZPO3zU9_)Hk~XJNl}0tz+m>3F6fAL#%x`5K z;6|Kzmm7X&u5xvpDQSk)P5Gqw!6AJ@AkG*KI^eLl_l z%WXWD9jh6)O!s`I^&L)m=JS@@>{v|}yie>O#ZP!X?Y{2GOsmhCy)D<+ce&ldnFKsf zz%vrUA?&6Iv*G}?pKYq^L?-sbUsx%Ov&U_Z{qMhv^hNg{13UND<+gq$Lrcb&b*J`GhpE%bv$36Veuvz&+S*zC{}&K-gzMTVg>PoN z+!I1_1D8bZ?9#6IG^`=)v#?8H=fZA>eHx|=-WyR7_EeZM>{jU7(C(qB(Ky0?8~U-X zn&=mV7&oHS-QSITBNE3h=(e)kOOeY3_s`w_-ED8=rpPzHBVWt-hS2@9toGCoVO0C~ zaX;$%?^cDpN}MDq90{%)ehUJE{C)f<`-l2#{4tUd85X%D^3$-u$kvFf5mS~C6J{-% zO#}rHQ&!GaMMbM#oHu)kYWVCWFV0>ug6OqU)oUfbC-qv{*A=2$_lLtgwQ9wZl`4Ea zsv@3PwRpzt6{@9kR4-zf=+$dwuU@@o%_1f*n>~9Lkm-vty;YF#ic7$D=|(? zS*97i^ra=l;{rBw>5>;$EL}uQ&i}`3;idv)&iuKnR^-1pf9VndnngT0d*$pG#k*=$ z_7q~25Qb1`RK%03mModSWG<1NziK5=|3{iSoftQ2)G$@jxF@FcRSj16S8MU-@d@~z zJDhHTU*^+K!W}LWei*>tPRADn!e7G|>OB9&#k1$;_fKCnK=6uzyAR=nuft zxP6Enz_J*B?VtKT9_ser0sfHLj!TT++Trg9CH2Sr?F@6r&x88$_`d~Q=|9oM?Y{~9 z2X#<~|Iq|$)<<}k3e}IDK9Cy%$t1WT`uI!3;o;jIZtW7nPX$kch=(8Yl@J6)`1chM z90-s+0zUE#Vh5KCNd`nNrszWY0TS?tXPCZ#1nNAINq{KEcp{Gj5;V~hc><8&EKlS# zAj+pakyC(#JnM;k4oK(>Pvi?g!sZJI&L!mHOF+6T^$ar=knn$ahRFn^>&u>Dbbv&V zo=65Dkw#BsJRnhJp2#>rqG?ZLEFj$+p2!$Lx^MGDMgtPF%M)1wNbDP)$Us1PyzPmM z0wnHzPXx?o3DpTt1Wap*o}YRm7C_>^5)fDU*Z@iR#uM2DNaFXN$Ywx#UGPM<0@C|e zPoxTvKGy`qB^%2DNrICkaJi5nfb?zgL`XpTJ@7;*K$3k0`E|w81CpW;5EsvdfTV_b zA|-&RqdbvPKr}r(k#az^iJnLiAZdLC#Ff@kK+?6I$RI%a5AsBE02%OzCo%<)ftjAj zQ-BN_=ZVY*Wbosj$O1ryO!h<`1!U-SPh>bC!(Q-276S6fY)|A7K!z{$MCJkV=yFel z0c6B#Pvj&Z83mpQm{1eCB2NSit%=MEPvm1jM%p})0OB4+^^cfb?*8j$gaJdqWEOgQd|3jlW9)1F8oAdi3J zi6j8>#CcC736QK`Jdr+tWMA?`dIOSE?}?}ZdGe+wk_yP=CQl>c^{DJT|AKw0C`6I|ASm~4g>ORtY;Yb$PV#byeD!5 zkmvh&BI^KoA=MKBlX@a|fPlDKj9bhm?wf`&3e)k z$p&QhR8OP;kU7tLBDsLfogpADex3(p-fYh>xSh^l=!xKVx?s5{G6#@_t38pqfGjHT zMDhVyZ1hAX1G1#l6L}7hrInt@V}LBH@l&e6Zr&?mp<`CCIGVfOHbrUK-PTYi8ujS`@JX91jx&rCvpprbyqx* zMnKlz^h9_-HZ*%84S*Ef_e5?2LJBjHj;8xNKokms$w>!v10X%>>Iq#3$be!zp=$sY zqIgf}DnLe*=Bjpy`V!%wZ& zbo`q;bEam|{2BNmu1hre|5$;Mv^lGm%v`CSOlamUT|8T}VD^%Q^OvmDytH)1!j;SN zXU@jqQXyLE$`|wJ!umwBD1XN6MVeW&XUxxEGB|bhkU_bF254}A8LQ?mnkA5hC<9%o z5wLhsWlmP5tJ4P&h!k1fAh5a)SjEc=yoBiB6C8glRxJXn6QN(mY~t0(-ud()r$hFxEH}};+5~;metz= ztN#X8F`IZ1{TA9Pf!V~WiN7tY=>n_&@Dtg@T9Usl zt78RLM}Q&{v-#%Vnbl_mR^JC!ai1FVckWl02&_&7JtbCgVKvs@Rsi$@tK*@|!ffK% z)!&d+6pDHUhd_JsNhBn}fq^5S@+F;4DMAxKY3SRNn9xPz3-U1lLJbRiByd8P3^kMpr1FK?i?H_*o$Nb&~ydISBufn;wW z#T!WV2Grhw#v9Oj18Lqsx;N0@8yMgX4D<#Dc>{yJfg#?&P;X$EH}HrzFx(q>)EgM# z4PE`i$%GJj>5tblFX`^ry!U!$f-J=7 zYF04TBBHRhD-qX1RLP`Ur7N37%R*L^!fc8HQ43dM`Gszg{hj;KefxC}vgPpK zzEs|OzjMw#_uO;OJ@>wkev=LoW`cxFknrvxAsZy*f`ojKFdHOn3lipngzZ7Xl|jOe zAmOSYVP}x=o*?1sAi)e0b_EHAAfXr}l!AnEkYEJ~l^|h0NLUCG>>y!xkgz96s0InO zAfX;4I6*=qNVq0QaDxOdNbrLMJZ)x>L)mTmaKWzmc(4*}Tf50E=`@`v{;7_;r(IXE0znXJm zwC~{j(WNzG`dv%X#@2*rQ67HgjJ|N_{cUoeK}qiyN!wA-X>r zzL!T!?>r&Kj}{@aHT|$=WxsNHVejhZO1k?PK5iwGhXOfQ z#HQ%MwVEw@&f#$_Ec*Sb_9@+S4F7Ju@*+RT_zSH_ zc=;CnUnT$KcGJUWEcZ%yemscRUz>K_A2oe`G)8b@nwHgYof?}<Sv;%s&-3sx>OO>!&UA{Q7U>3DW%OdR4kr1L|h2OQdSokMXpg>#{V z4&ww+4kq%0C~k=21{DN{_PjXgC~k=2bQlMiiNo~i_$&;;o*D$17~hX!4{Na>hqvO~ z@Jw6)2=OYTqUNZmIZ8Fhv(bb&BymXNen>tZog_0LOnYt&MClxoR0m|BH_8%_rhXZt zei@^F!45c1I8GQl;3VNBVeEj%36B#VXZg9n@YqaB$!hgRk1&`fZ$ES8v_-Htsv zFGdG(iVCL^=n~pT6e&g>OceBXHaUSV@9@-2E*_7iST-KdXHzVm+L}S=Orypmh0{c4 zY6hzK!4QW*mZ8YOZji)t`4~SWQ-(Z3AeEv@aTw3Oo6SN~9{aKQy4KKh9~17#s)$rL?D76Y&|G=f>oL z({f{E^z7su5qoZZ`#3o)-Y9R0gt5e-?cvZqehf4IY6?5luP`2(YFn7C(GXG)!{Z8V z3o|^p(zY;vi@i+)L2bk<4{y6Y=pbyW{P)C^U0zLvvo+nK2 zd;S3Omq_`Wfcx=wytptAu{(gz1*Y<(?;+p|fG?ByG2p9#CnbIs__M%KiOIoF0PmFe z3>f|m)KB(P{paE2>l%I|a1jo#Nckz?5xk$Cl9=A!+YelncnSDD=(I7eFU07LyQjfF zSMqNLei8VS64RS>x8m*mti+!Kz8vMxm*u|>e7=T{0#g_%{%?SPi7-QxV1J0MLrDJw z`c(VqrL(6sKD|qpz}x)Gvc5s!?`!-R@B`p0|D}MBfPbpgUjgpl(C&|A;B$e?@GJGl zKLcNnAiYcKe+KxC2)1`g{2cIuT7QSo@eT0HlD`i4G2m0AzVm_mF`lWv`|!^I#y600 zCi-g(_+bs_fsdZa*x6FwH1PdeeOCeh2K)yl|3ko=``hvNN#G$3-vt~2R`neQ9?t82PA$6aQ+;|?v^+U{37s1R7n0`0zMB(f$ArGJMc!}w@Ca|;7QA!CKh z;B(*5#@_|L30T?tbO86C)X9H6@IlCLlKLir4+E?Ic7Xp)!?yw-1*Y*q?WK1Oo&(+? z+xG zV5Z@I8r#5|n5geu;A5~);kN?gtM;%(@P~od_P57N0(cFu;_n20m4=srPtowlfPeL7 zyqdy9e>@C)D}pnR0HFSP7Wiiv3=5Kvd$26~ws!xG0Pg};@pL6H{&rxi{wDAf8on9$ z`@m2SnK1h-@DDWnFTjsNpBitE0Mq(llazl7_<8W(DDC+*@L2^|Td!G{|-{|ms6X#D$u zKLI}VFO`1?_*+{1eh>H|#M~L2A7W1d-v=!8h1hR^)vq5Zf3N*B#_omwlel~zI};f1 zG0XK;AA18Z{-z7+67|tq=1%An_J&v*7=JUR#lH&p5@0ocEZ_w6p-Ujs$F2ij1Qz!6 zv5x}p*YH08AJp)df#0s_`zG*!R^Kt;+aZrBjq6{#p0O*zzgXJ49@x;D_*-vEEo zc%=TKwWivrJ$DjD4iQ_3eHr*g#Dl^|0`iXo-;EpKicf3JuW0y%fc!}a+_NY-@-4(( z3;aKt{F^DTR|cSdYWkmY zy>;g+tpD&Utp7^^{SN|v*HR7&v2O#@97o$GjISRC@H4>ccZvME0sQ9zeEKD^EBk*v z_$MRrsNXcN4~5v7z`Fj!SUcadow2`1eWY&__`6N2o#w0%iv;8^2fpKk;vYXT3rx2U zk-{12-vfN}RpR=Q^!dQY-XrE)!Z!fx_1_4*xU=1!j|0C2lUV}#Nd6EoJwBlPMEVZ{ z9}(4a`@RlLzipw7?EQCOdLPs$Gh51>D& zJ}N&7d_UspNr}gR4{pYq2?>|@X<%hPjh9(qwQa(Q4XoGS1ilOYp^e(RANYfpwd4OF z@B;i#>jl#Pi9q=~1NboTPRP^zO!8j_J^*`F`@afIkC-WKQ~VwQK3i)aU5o4X9RtRU zN;{NU!+s9@Y1sQHFzNp-@HY6D^b!68@TponorY`gAMd2nBokui0IQAgg}}SuZ&f}D ztk-`9u)2S@9`U(VD^LF22}}>b)OcJ7l=lMo1}cxfqK(GS-vZNvC-N8h<8I(bwfOr= zp!_$0kAbh^?|Z;^qy1@=r}qCB@OALNiua!aU#j)*uYud`!5vE|3hipkuLC~o3e2&P zBYmd<>;5zW|&@eakUjyISzYmD|yPt({FGh_|iof*%d>*j+rU;e4 z7?>{-P@eoX2&}i~GT?T9_OWsFn_gc$AfFE49l-yJ@ktxma|`B6dRd6JO{jk!{HHK} zt_3E4G=VAJX(Rit1^!h3K5!_1huJ=0dSM|U`5yuP0LoJcQu*6~X=O+o#s9~&`bgis z;Op)C8t^?Mhyln``Tq#;A18en@3hhQd^*5?9yrXoqP~;pLXBH1@J8VETD}+n*6Y6% z_#V|>l#2)WGr;N_BxHXPxV#JZ=uj!yy9apf9L~{X!VTaCIRhK{`@O`+`UYXb{rM4K zdewyTE$PD(yj;edG)-}m5+`^t!%zHL!*s2AetxaxItuJa8iKv;*cgazVdjqXXf87quNFLS)OQPYuL8l$;_iV) z!S(Tgu`NAB(xZ4#VrH$<;zDN8)|kW0YU7W zLc5@q9U?0>=a-y0+qH}lr=GR0XbUno{B z)I?<_wgrjFA*Z+-oR#S5&CqEVs^;*LYx`Dmf!C~Pm1@&lkk&|=vAM8Vu<`TXsx|Jo zbG(o+R|-U3t5EJN6UCR3_H>fAw6t(~$}q@L@FsmeiHt~%n5A05-9x9tW(iC>i$q&K z^&7q8*CKBw~& zXtC>!rl82GxL28CJ568lQSG!-wpy$j09RG07pl%YH&L7_LrM#UdfloDJFIG9@3dWV z9nV6LmpwE&ZH%^t5JpA9qWIH>1x61a77;Caqk}6IltF~P*qt*>ec%m^uo|zKai0yE z&LX;@>MWThr&;$|nQSAqfp{cU)H6neMqA3RTT}Il!-rn3i7#+raQOw_V)^#SlNHqL zYSrdV94#emuL1o=)b?^E*RtxfjWS9li(0FOM;KCqFGZ7!_>LGS#Htv0LY@_?c6|@0 z>S|!$mQtgMw1m%kWfqyY*YmBKunR33&LC2K%{A1_krMx4*eFWy?~93n7cHf%@`x#h zA|F+P;yd&6Rhbq9r70S~Www;w<)BKtv}Z&o8=G4_JK+}g&LA~yp#+(+m#r!?Bl$I$ zL5J)*`laQBVh<4mCTATu9p5t(R(EFMQJ#bs3Y2^ocJJncG8L_0WOpmmlTHsU7>z!q z@Ls0!YA7C75-fs-7Nd+EUv(q*Qhv)^ccP6OBQ9 zOu_ZF6xzujMR2dkG=_MPjQ_DVM1|NNYeZYDvlX2d8G~HgO9apsE}$GC`c1~a@`Jx* zn|#`>**@c7d8}E%9GtT1^FA^!_;3uyw9e$fuFE1GANNi}QnOYAqsSb%Wiz?f#nKi0v63TQHytG#>xJ&$uave3S>2X-5wGqar>0o-2 z9?MYyA>Q%Ts zZI2Xa4#qmEY?s8mvnUtqXy^DxXrqp zJmH?qXen7QVYTTh?}{{y6ih7$1{t-SuE5ap75SZ>ff7BKf(nAXuEJf8Z&z;^;_Xn= z!(c{-nG>m*u^6r~r_7Pz;h|x3(8LR-X06mTu`Z@%%|L0u85r7vC!*q-25rc1Qwvi8 z*3iP?Bw!Rc6fc03l(&t{W&qfm&XV(E$5 z*aUI}&2Pzix#1vMY2}(S28+0w+Ow@tZBl&UDru?gmpqp@h2G#ZMOJQK22I5hYK2{K z3ni?%@Es?=P%lw=1XNdi2y%z}1S#03f~t1}a~;Q5*+s0h)rGZTP+M?aXG;pNW;S{dftG8+tW@P(*gy{ zjZRwCq0vyb7jaeQ*-?}++sLe2^N|jMwT#7#+3b{WL(_sXjcp3`QeZ*qZ^I6Gu%*0E zuf$u3%rRQ#ka&lEMBw&$JV93Ak;O{uw1Ue~@)j52&GdYyVd4hMyj!S2>mr7c4dA?g};2KY{Bcn_XOulF|U4!JCwPtm}_H3-Zlpq;eX_z(KMcHFkC{z&4iaA7H z#e1_c6Ss?|X3}OVnV!gtTS->K##M3CqD2u5vOInZ2~O}Tq#in5TzuljLQ7ec$o8^V z@o>w41aRGG`y|}Ei5sK;+^@r!wUSsS@u zwa%c1z(Dks*`V8XEyiY?!&~(Nsh9pWG`~o`U9TYddyvr+gR;!bvE86eUXCi*k(QCYP{PN(ENRyO0!6bs0$(%4PI5 z1{O{x3 ziBalp%ta#e)0&UczM8&R1-JhofWGx)YQy-QuR2BC1LsZ$lcGxW5gYLK)-V8Y^j&dW zP-ooj13c{yAd=ZY9qTsC>9~VXtI^#<5PWN3zTO=J2&|1POHs{R(0%_ht zK><5hMJ)Ul6^AAob&lHUsmjaSUI#IH3dNrd;rUOcg6C-Bu@qOJPG2wO=y?onx8T2e zUw|+@_oD4h_)pI`Ngq9r8(3iMhe`=(>huy#?ohvwQ#!zE$wlS)AQ7>VK0GRGZKRL> z<54Al_f9dcfZP=d;3yxJ^7ki{4aD9Dxnmk(oh(C-{xmY%wVSaQ=$!_+Dc&`}>YP|t zUXS-`<#TJoig$x{PV`?KfPFpWZVbr1{bP(>qaNI8Jo14?W}o{O>IF@0s$M$ke!T-i g^z4nEi~kn?$uIQGAFuy*=v)6!jNJw~wJCl73-Jj>RR910 literal 0 HcmV?d00001 diff --git a/examples/parts/sh1106_virt.c b/examples/parts/sh1106_virt.c index 1782fc20..b813cbee 100644 --- a/examples/parts/sh1106_virt.c +++ b/examples/parts/sh1106_virt.c @@ -61,14 +61,14 @@ sh1106_update_command_register (sh1106_t *part) return; case SH1106_VIRT_DISP_NORMAL: sh1106_set_flag (part, SH1106_FLAG_DISPLAY_INVERTED, - 0); + 0); sh1106_set_flag (part, SH1106_FLAG_DIRTY, 1); //printf ("SH1106: DISPLAY NORMAL\n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_DISP_INVERTED: sh1106_set_flag (part, SH1106_FLAG_DISPLAY_INVERTED, - 1); + 1); sh1106_set_flag (part, SH1106_FLAG_DIRTY, 1); //printf ("SH1106: DISPLAY INVERTED\n"); SH1106_CLEAR_COMMAND_REG(part); @@ -86,22 +86,22 @@ sh1106_update_command_register (sh1106_t *part) SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_PAGE_START_ADDR - ... SH1106_VIRT_SET_PAGE_START_ADDR - + SH1106_VIRT_PAGES - 1: + ... SH1106_VIRT_SET_PAGE_START_ADDR + + SH1106_VIRT_PAGES - 1: part->cursor.page = part->spi_data - - SH1106_VIRT_SET_PAGE_START_ADDR; + - SH1106_VIRT_SET_PAGE_START_ADDR; //printf ("SH1106: SET PAGE ADDRESS: 0x%02x\n", part->cursor.page); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COLUMN_LOW_NIBBLE - ... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF: + ... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF: part->spi_data -= SH1106_VIRT_SET_COLUMN_LOW_NIBBLE; part->cursor.column = (part->cursor.column & 0xF0) | (part->spi_data & 0xF); //printf ("SH1106: SET COLUMN LOW NIBBLE: 0x%02x\n",part->spi_data); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE - ... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF: + ... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF: part->spi_data -= SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE; part->cursor.column = (part->cursor.column & 0xF) | ((part->spi_data & 0xF) << 4); //printf ("SH1106: SET COLUMN HIGH NIBBLE: 0x%02x\n", part->spi_data); @@ -109,25 +109,25 @@ sh1106_update_command_register (sh1106_t *part) return; case SH1106_VIRT_SET_SEG_REMAP_0: sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0, - 1); + 1); //printf ("SH1106: SET COLUMN ADDRESS 0 TO OLED SEG0 to \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_SEG_REMAP_131: sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0, - 0); + 0); //printf ("SH1106: SET COLUMN ADDRESS 131 TO OLED SEG0 to \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COM_SCAN_NORMAL: sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL, - 1); + 1); //printf ("SH1106: SET COM OUTPUT SCAN DIRECTION NORMAL \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COM_SCAN_INVERTED: sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL, - 0); + 0); //printf ("SH1106: SET COM OUTPUT SCAN DIRECTION REMAPPED \n"); SH1106_CLEAR_COMMAND_REG(part); return; @@ -356,51 +356,51 @@ void sh1106_connect (sh1106_t * part, sh1106_wiring_t * wiring) { avr_connect_irq ( - avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0), - SPI_IRQ_OUTPUT), - part->irq + IRQ_SH1106_SPI_BYTE_IN); + avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0), + SPI_IRQ_OUTPUT), + part->irq + IRQ_SH1106_SPI_BYTE_IN); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->chip_select.port), - wiring->chip_select.pin), - part->irq + IRQ_SH1106_ENABLE); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->chip_select.port), + wiring->chip_select.pin), + part->irq + IRQ_SH1106_ENABLE); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->data_instruction.port), - wiring->data_instruction.pin), - part->irq + IRQ_SH1106_DATA_INSTRUCTION); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->data_instruction.port), + wiring->data_instruction.pin), + part->irq + IRQ_SH1106_DATA_INSTRUCTION); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->reset.port), - wiring->reset.pin), - part->irq + IRQ_SH1106_RESET); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->reset.port), + wiring->reset.pin), + part->irq + IRQ_SH1106_RESET); } void sh1106_connect_twi (sh1106_t * part, sh1106_wiring_t * wiring) { avr_connect_irq ( - avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT), - part->irq + IRQ_SH1106_TWI_OUT); + avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT), + part->irq + IRQ_SH1106_TWI_OUT); avr_connect_irq ( - part->irq + IRQ_SH1106_TWI_IN, - avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT)); + part->irq + IRQ_SH1106_TWI_IN, + avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT)); if (wiring) { avr_connect_irq ( avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->reset.port), - wiring->reset.pin), - part->irq + IRQ_SH1106_RESET); + AVR_IOCTL_IOPORT_GETIRQ( + wiring->reset.port), + wiring->reset.pin), + part->irq + IRQ_SH1106_RESET); } } @@ -418,7 +418,7 @@ sh1106_init (struct avr_t *avr, struct sh1106_t * part, int width, int height) part->write_cursor_end.page = SH1106_VIRT_PAGES-1; part->write_cursor_end.column = SH1106_VIRT_COLUMNS-1; - AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags); + AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags); /* * Register callbacks on all our IRQs */ @@ -426,13 +426,13 @@ sh1106_init (struct avr_t *avr, struct sh1106_t * part, int width, int height) irq_names); avr_irq_register_notify (part->irq + IRQ_SH1106_SPI_BYTE_IN, - sh1106_spi_in_hook, part); + sh1106_spi_in_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_RESET, - sh1106_reset_hook, part); + sh1106_reset_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_ENABLE, - sh1106_cs_hook, part); + sh1106_cs_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_DATA_INSTRUCTION, - sh1106_di_hook, part); + sh1106_di_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_TWI_OUT, - sh1106_twi_hook, part); + sh1106_twi_hook, part); }