From c211b0f5fba179fd05af99fcfbed5d32fe130668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Sat, 13 Oct 2012 10:57:57 +0200 Subject: [PATCH 001/227] Cleanup assembly dependencies --- GpioTest/GpioTest.csproj | 12 +++--------- .../Raspberry.IO.GeneralPurpose.csproj | 6 ------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/GpioTest/GpioTest.csproj b/GpioTest/GpioTest.csproj index 801a558..38b275c 100644 --- a/GpioTest/GpioTest.csproj +++ b/GpioTest/GpioTest.csproj @@ -64,15 +64,6 @@ true ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - - - - - - - - - @@ -87,6 +78,9 @@ Raspberry.IO.GeneralPurpose + + + 5t?AY`ncg8Lj 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≷gY;OjTg?1JP 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

cT}# zq04ce)Cw&x+AXu8J?FzeVzxxGa2bHC?W_Fhp+qI%dVN=ez{1P*Z2`079m8*-7n3S8Tm+^j}N6&Sef_{0Fpt*zTCik0t z1C)B88P%edzluPKHMcFe;s$GGlNsFtu$?(py8}8ik)y!!E!Nm=<(b~ue7+-hCu z0hhGyf$mov80S)dQFt4G2{TN4D>+^b81M+nDSv?gGW#QC5YgAG(h*xZ7T-LPEWEvfl)N%FDwxXxTtv5ycuO@T$&A;?v>)*^DrEooW8dkHNXegg><~cIZO)|dDeN)hoj&sB0wfMCnzQd# zI!uQOusxkJbqv__%2hRB0Fbt8u^V(!7Q+A%Xo}D9j~i^&?`DwB(=qju%kbq8I(i0t zy~S!5e1hNS(#TjGs8Kw0{I~%Dsb=|>6&K`yE{}DNpS5uQE~zCHlNs6 zv3Ps_F`1QILfZe8a5(@;qvWlTmvw?s>q=UPD6DusvZ9Ze@CghuLK%9k$*tD~0o|B# z>t5*68m)a2!_LeZ4K~S z`K98@P+uG4yc}O@6JLEA0V!|upCqym26MKGM7kxSW6@`57{q!>G>vD6Q*?St!>xrMorjWDfM}jgI47jp)L1NZ7XFLt{a5734y} z@Vmm3&}>0`6!_WO%($CQStErS$Xw=i^HraAy{{qL^2d?N;#57^&|Dz?Lftrg)_z3> zHHz6qJ9nU?V7VmdI1G&GxHz`q^*r*~8kDs84^Zwos?TNvJXt01y=fgNBtrgl zu8N9PAMYN%{3yegBIShKk>d}KM_VGey7CFUn^;OK;siql<YkDHcQ3(U2)gI_jMfywa(D z9BuRYU<;iFpUgtRJiEeT25l@Vn#rbq{51G<(hXUTweult^may8>M*_U+-Lf4vD$)c zp2YQf%r_N=_sZqE<(ahWrbnie{$k%-xIK29LbilubN}t4b1?jQoYE-NJsfyBJHcc? z;9cbP{v1ZAl8&qbPkwt7{WQdpzpI=xRv(E=vU_J;J|l|H&@sUo^@$k`*3R*8(pyvt zEckiUobCcG9WF9Iqz8txDz(n3InDqyNc5>M`31?yspp|pt0G2_1ZI*)g0VBBWD7W| zmCk-o*~rj&4B<%t3@0zAMJ?)`HX$;7#WTs+BYbonq80*%09TlGPw8vcs2VRnYyqAS z&8d|UCi|Q}s=0IZrysxcULG<>u?wJp-Q@dKrMr4L8cKtW4zJ#{5d;`;{JvE% ze>=lsH5gT5PiM0~VwNRyfMk2q3vhJewGM`xI19+?A*o9|F~;|PD)kff^*mLbY*-^c z3^5&jAa{#Q@)hl^JYEZZkt~Nj6~N%~qzE#$1Q_6XC{ofHuth=nFSgwhd!B>zi zR6oUD%@pbC7g#(m}Sz*G&Y~L3J{`xP5 zb@)(EY~f2>K!#OGoW1{#ihSVr*}SW-?`6r#?vqDVZn0+;YrR=Kv(Q6s&o9k&4qT|P z{L;?mkaC?fmjIGSo;-?>Kku8Fe;b)RzB3O|EQS1O_~$O6b(R6+*gB>d>1B9UFrJhX zg)Fxr_;@2fmMX{7dTpMPG(sRS_V*tH!uVhCRKWbh!;en{M|}ktEZ|I;L7|Tf8a|(6 zu<#V5TCV1vU)1o>iX=r@k>0S7IRNsgekF!y+=5=>QbsE4CD@YKsp)CpeXBzB)DS4; zxm0%PJ7^SEzWr>i_Rxe5M-~w3Dj6>-J(HCxjj_U-n)@68=aqi;sl`fNFru+W*t%M5 z-NvE9tw^;idpE*EDlN)e7u5hoS%!sKP@JI{Baa~1#d_`0mVoatcRYQDCyX%CcTH7B z`u0s~!_m^Zo>#&c23#M97;o4&P^6xWg{H5UR0!7?>!%~!Y$*caXcY`cEO112CTb(0 z!q97qQ#E?=d@>}GpqD)c-vC!tG$4?ij1&eM9p*k6@+`Prhz?Me2amurV@0oO{FfxE z1QJzj{2lfgw5<+`l(qRzoQHfZQ1?oYK~XV@;8|N8?&I%-;B{J!{@+>-qr1s$LQ2~# zT%#bE_%yi{7m!c6kxJZR{&4$ZhN9+|zL|)w{fhSUV9H58I{0%g{m^nYVX=2|ykew{ zs0;?}-I#1Q=(dOh>P z-tLM2x9f6hDR@boY4+Apfwr=GUxn&lcc(zeo?k2T_pZ)P&&Fs)jRRLb=;}YtQa*}j ztn;%vp2ZX~g*Td=A;o3S^NvX#iw|D&ufC-A%%x)M8u<&*-s^MLvz=vYfLG_LS~9i; z=?L0WN)Of?-UNIpU|FeI{>K30EQ&(6wCwlH6oMXg(`egC}^^Xhu?xP zD7^frMN0~Og()KkNO%SG+>gD9Rv zS8$?ozNniniWWsZvVZXuMy))s;_ON>M#ZN3#njeEbMtNkEvxpMma#RAu+DbD%^AuS zrc?G#=r-RsjCtiNO2TM30f*hK`pNaA-I`~lAv(;zV{nmhv~}2voF_9$fB;r;3D#Zc zPzz2@4g-SL#cN><;d0Vxe%(Ixj?ZOk&&B!Vh?F!u=r@eC#YoRg&yE zL!VKh)6q&i4LMYtchw94K1A()r7-l?P|om?CgQ!~>rZp!7_eXK+;QA|Sr7JF?o)T2 zg7g3+;100>1(T%Kacx~?f@WMbRZ1%SjM6F52*|%-^F%KgS{)3=o&?bz{q_1%W`8o4AC>+c_&K^@v1pA=1$q>NlfkHp?JjZ8|L^|^1Ea_%;hB3H7xtw*96D@4F zOlT?@T@{(rlg$8m<2}xqP>P_dOiLo9Xb@hhP^NT@3kTm}yM&bQ`N=kS-5zVVl>J#J z8fSz9ia5Ybe{$F>kJui^yE*%@GVC2VJ3gp_F=YR$op>9*wv7pG7*YwxT6%_Tm7_VO zu|DL`zSP<{kHF-zb@dGI(g0^1sd%$+EF^F+1gOQ{`88!-4z@c^u9a+k89DqOqRQ>? z;V47`GqSy5nimyh4@(2KlF1d&QKB$2Z9xq@nX;~o2pwuqbu|Vy$>;2e>Cb~LN;V|% z{{-3b)3MNHWQi-cg7X$+=xH+?5(OaHr--LYnBfU=u}ZM>GA#TVEI90CuEc}4^21Kg zdT`c7w7=U-3+gsE?@+&T%UE)MRe}rHMr6bT z`2~Yt3to^c{haC=L~1O`bMSN?QX3K;l%N{UnAx|v;GcWbJ)B?X+d546xh;Pn`=Zx> zB^_jdmjQK*kiJ(z30E0H7bDcgjVjrtVnyL?AU*scd zq6id;_K_}lQd*4o={SQe7b817V37T+l@Lu=s!F0B`S3M?op3~O?C8d+n}q&Zxsj6# zPkl_YUqTuO37qi2^OPL^F0t*c=;KU>Mr|nml|%dMQ!GUpQ%s?!XRQ}vQI`}u|Fupt z^xl4D#x+Dm8U&dldnb1@MsTgXF9hSo<9a5O(8gQqv2Var9HF>Av#KUZw)qa(LE0no zA9&#?ukm?trnk<7l0R*)2#gd-+2skG!cLg^h1vy%7vPz_7_Uwkw|Le+?T{x?l>f}6)>RL4VaI`!{i@d`4TqV^vVSlCFY z2|=gq(Vxj>?$ODy#7&>`--I?{UDUxFx19TzGf;GBRs)4a2QbG?NT8ufb2F-Hu&rmAkHqW0$oB6yRoJ-KYyZgj?#^szIsNi_ zoiy#JU2>UsvjBky5$~De_G&azT+iGSo$E?gbanRje3ose<^aaCt`%ccfVp%=6JXQC zM1erhLtGymTy=#8i4y*a=>)w#b549VFZlczY&Eb0fw_GD{;Bj0bE279iq>o3uc{#R zBABM4stS()hFAf7(N+yql4mIO!Nq2PA7c5fBdz4DxUKsdaIfb7SI zYjfT9DV19l9yjnL-WJjX9ZgdtIx+NRwcB&c+AL@68JI1|e2m^(UkY&05a(4jG+UtP z_Eg+pZh`wdXqcV;1D55&cFM(?ae+VO?7>)0Kdq|i!QcJDg304-_q97)3LZX$zB78s zGyayvNZqg(%GGB=GUjclQI7=n}Rd|1D+hnWB z+2}9d!*9)*r9sWhL7p-xOWOj;-z3+<9|M0} z0GGxJ)Q^U;bgOah&u0SxW((3J&}~RM_#aJQZ2=BP&i#~)E%VTe*~~uM;>d~V(YE5B zWxdsS^rO<)q5+xk6>UNwkwpSokJLXdM`DGNqFs$yJ6 zFe_X@`xT|9wepT;L4@>u)&&R%YLR}(YCq#w)yKSKJDcqr*uGh#l%Ut=r`wW#hpOz& zn78PHwao3n8@dzE-lUS^{FtCo|+nKhUjKzY&Q*?4hu4No$ zsJeny*mR>7@(2RAA%y+*GtSc5HqZDQ1{hE+1Z>_mVF@BJ{IYH*k)7_p$X_Qt99Vw$ z4}2>SKoWQ|iuzj4>9s;BhHOY!OnScQDOa0*tLc5-=A6I=%dhhEx_5h_A^bUR&eQCF zFGeJBHCqct%^3dx=FL5<|3yr8Nkcr?>*qAe1h3rH4W^}jkeSjhjP!#J;6~YfA=Nm-vzN4`HTJ} zoa>Wlbe|Y|sh`?Eno=Cbs^<+s%pHBndzc_2K9Q8k6`Qe!YdLT^yPsAgjrE|};ix!3 z;GC4c=2Wtja(^~Lv%deNu|!&#>izH zC?pM3b-74RRa@)syjxKipQKr5xA0Lg?@K3qH@d1f%R&Y3!>=wo-;_xi*u&jausW~5 z*v9sL6&?E8{izI*4VW0_)+wRTbfRT40nwLEa<#Z`IJUK z?Go$@Td`LV-R<3C_&x=>s<=Sf!O5@wK5Ykv!l2U_8o_s;i3%wn3z~eQSOKIlz?Zd} zdq4-N1sDAow>S`D0e`<9FjjmFT^)5Zy%2lh-)3WjbmC`YhqtC9H?aM1ii2?1MY}p~&}2ahxQiWAiXC`v(QSjA#eKP>dxQ2AAF71X`zt932)Jc{5fNmKtK z_cQx{+sOrh(YV0G!~Jbh_LVl)Pf8eKdn#L4<>VT~=$YBC3MKBf9nz35Ervi4K8+8y z{KnC^-)c2AjHOvH9W{RC``G)Z=~0n)_M4noRhxDd{JRkI&QPf~L`1Tklo>W^kwf?p zkK`1-t@SVY$3cBk0$4dtCaj__l_qJG0raorv*6qK&HC=Ti4Lr(MsB;UZT<>>tfkbH z2o`i6Y}J_exH{Ss_XX?2v;ixozQ&qBwG}3=RCs?z9{zyqTKnvphXU@n`A4o`XVOe{| zb<-YDc5DV>~*S*@bL zj_kuLyt2QT;3`N6N4*pa8JX>x#o0r=iC)Oxv&KHZLUsQSbR=0w5D*;TMq2WPi88 zUly9FHvS5nK*dZph-B0Mawd6OLO{j@(+Ncn0P+b+BlNLHSOjRrAY4D*T}p(SL*2)z zfF6ZGNH&`$5%}I6*oglW_{yseu0JkJ2CoDS$wKg%H>dcjBoN<~GXM|MAmVLvP)-m4 zZbz1FNWp1RXuB`8kv9Fe<1F@NAV*+LhK6F%dgr4sS0gU#l;F` zjjU)+tGfL7JqyIQ%OkwBTV{|VE?PFO*Rvh5NZ=@JOnAc(zhrEDY@n1pHv)7t7eS+M zlk<1QRvog%C4%vU&WWBca{D_=w2WtoELof2@3fE~*o6<_eB8ZLH^1F!=IRs}O*G?G zE*E{vCxtczi;*3gRdt+EGF-q)$hM=_Aii!_npef=3o%w5ziK2tFr-p`<8RhBtSeb9 zXM$OQo?CS}I4#<5z4A;~TAdPhFF1{YYl4)?V2=*JpY)LFgrum>Ya>HV;P2e2k1^aWCLK2E&G&?E2UdjsDpdDLoon{K^+=n-vA*o zXM!l&$4_iM8)=mld7wT9frA2YgC!VM|TsR z&Uy1=9C@67WT(7gJk{5kq{6izmElR8udv5w+3!iV{vtrO@7K*wlrWLX@B^*uxkoC6 zY+nMVC$*()xrsQ7t&yO;HV!##0n6lb}YESKMAuWtp(QM}&=p4P1lpoZJY zwVahxm&;4-k~Zeg1%_}^0+fA3EI2Rdwsfh2yiC(rTb(0RY$oWL@6xKxG z9y~Vrj{c*r5e@dEs71*;?(u2Lf$8LetV!c8efs__?+WT2@l_$#i<+Vl!LbnTndGyI z5f?(@bOHyUZQK7Spy8F`{DDW+8NYToQ2TG&zDjV5^ZjVprBq?2K#$*2W7B7Oz@9< zUPZ6OKAk_q0CeR2(5uU!$N0s-+-Ih`!vI*l*)$bi3z>0xlxyEH06P!^$R}_?XJfFBIqi#xhQh=798f6{PX!%jn2xz{4G0F{k z7f1nn8|6c+I3%m#BS@c~O1_SL%GC{;&jY+_(RllObf?$&@6qDBR@9JCd(i*>RdIwnEI0VI)5$*gHH$vLX&2~N>P8|wwxE?kS(b*Af6e-t7+6+P^y>7D4xM>K% z76gXA#QDD%H+1Uk?&ZbFK74&rGTHb{C!Mr+ULlNsm4GHu5_Hl5b?Ufg!Padst!9v7 zz(OCh052mKg8UPdI4Bd-NI00O1DmE+(BXSYF7iXCjbcLOTY3!A4oNPc9b_keY&4o` zIUE}Omq}3p@*h97`s)*sufmsZC+rTR7pDs`7N@;;PWd67X=nPM5+moe`whm5XKPVj zBG&i-t3FeI`|=acT}N@@{>*3xS&Q2YoZyCZ%CZbH__s3B*-MGV2&mi8%^cS3LbB3?y13L# zQ{nFl$tbyVMblG^3M2v5SiB7??(1#`_=0Mp64}D5u`^)PI>*YC|NFmwz-oN;g3B6Y zHJ#pDOEWbKtA&W3rh2_~|4a{Ik-qe@TC#H*Ob`nB;4Y{hhLnw_XT5AU?P@3S`2V#9 zVzGg$D|5sN@H#x4>smU!>33%+cT`SwMiQW}nkg%n#)(mB9(G&=k$2*D+havqEr znvY-2V`z+pVzvtMTfnaC?-B&EU8+gWtLqw`+B@}oQ2}q_jIc>i*l*u&@r@4}5w+Ua z5j#^X1zq1f-&v6~nKH@Rby^YJLPoMU_>&GYbxzpoh}NGya%8W7?r%zbl(VYdBnxH~ z@Uk`4uysi7_|2f~#5WX&G*WWi=%+Ycna*_5Z6J>EZa@=3W6 zomn<#?EXE*8g811fmW1AiJQMN4xTQ56~1`rPAeT`5_(k?tCW5CF*eeRl8os2Bljgt zUc=O!PtKqgbQYKuml3bjMv|`wsidr4oZcWFhlqq&l?;Jq;18ZR8(?3ASi{=*<}!G` z!5$&}i$x2FLVwzFw@2PmK*7@=K=iIvag~S*(zzVn9e(H3alyNOYjtYn2#=Lgad;KfW13T1_N6`nyZuVk)Z>P@S4B?Bh617JPd__(ITitQ&X=1Gnniu(5M4 z1^U5r8h%-AB!*YpN8dkNM$+wZjpt9jT06A)EfCRo)I`x0@@10vo0!1+pG>G66h&HZ zK$~y-lJ!=Oto*rkA=<;ZVDncD#*Bayu5`rv#*lEHean!o9RB?h-Y0P@fb4?wiP zw1x7p3-bDJwFM~+FdN?>V|)U0_H+1;{r4h}mu|~FH0FIlH2U=>=x7_VkfYIFbG_BY zU|B)U8n3TaNRFKVXuR@4ORvahqENz|&7|`cn;DzXY8D$F=thP=n#GxP%l&50pvnJq zvknt(W@gzlo!m3>Yy^#Ld&$CNYQpPT21v;HID@tnWXUV{)bsBTC4{Qc^Zc!BU<~y& z*!yBB!p4l^wS4adUP}ovzGMDsL;QNSXQo@e)!SFE{6R)5JHU&o3UHWoHZqxZw+bt# zGo`rWsuKVmg*NJ%#$4bokAAHVng?)?w$ujlMqd#^P!Yvy^L0XV5X?}RmW zPN;P5tfV(bLZpZB2TUUGGHRRx-<-;q zT2;P^zAgkGqLB)Q^Exb*d^$luA)t5{L&8X>oW)@IGXoc^;$Jx;NTbfSJ8f7_gUT8O z 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 literal 6627715 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

fik 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

PLxoA$h;zxT@Z8z!u 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 From 5478e50af79d880c9fbe98c2b07bb0f2f18602fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 16 Oct 2012 23:32:55 +0200 Subject: [PATCH 023/227] Updated readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4284503..0e73d55 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Raspberry# IO ============= -See the [Raspberry\# IO Wiki](raspberry-sharp-io/wiki) for full documentation and samples. +See the **[Raspberry\# IO Wiki](raspberry-sharp-io/wiki)** for full documentation and samples. Introduction ------------ From 51420ba7887f019d72e0d99bcfa738dc0f3bf0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 00:28:42 +0200 Subject: [PATCH 024/227] Updated GpioTest Fritzing model --- GpioTest/Properties/GPIO-Chaser.fzz | Bin 28061 -> 28089 bytes GpioTest/Properties/GPIO-Chaser.png | Bin 120645 -> 91736 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/GpioTest/Properties/GPIO-Chaser.fzz b/GpioTest/Properties/GPIO-Chaser.fzz index 82609b130d49abd0b008bc6bcdc04fd39a15384a..24acee91d2b2f50bbb71edcbbfb8b23692710883 100644 GIT binary patch delta 11261 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 Hf(iK_2~V0a literal 120645 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≷gY;OjTg?1JP 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

cT}# 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 z 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 From f1609354643b3bf7ddee1d61121c85cd8572877d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 19:25:36 +0200 Subject: [PATCH 025/227] Added icon file --- Icon.png | Bin 0 -> 2863 bytes Raspberry.IO.GeneralPurpose.nuspec | 1 - RaspberrySharp.IO.sln | 1 + 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Icon.png diff --git a/Icon.png b/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..49e65ef9c95d409f01fcea39849943a48d619691 GIT binary patch literal 2863 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.0.0 Raspberry.IO.GeneralPurpose Raspberry-Sharp - http://opensource.org/licenses/GPL-2.0 https://github.com/raspberry-sharp/raspberry-sharp-io true diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index e9104b6..59a4612 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -7,6 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GpioTest", "GpioTest\GpioTe EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" ProjectSection(SolutionItems) = preProject + Icon.png = Icon.png Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec README.md = README.md EndProjectSection From 8827d21cbc49e03a0e0a031326fb58a567f3e0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 19:27:01 +0200 Subject: [PATCH 026/227] Updated Raspberry.IO.GeneralPurpose.nuspec file --- Raspberry.IO.GeneralPurpose.nuspec | 43 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index 1b027b4..6ce197a 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -1,27 +1,28 @@ - - Raspberry.IO.GeneralPurpose - 0.0.0 - Raspberry.IO.GeneralPurpose - Raspberry-Sharp - http://opensource.org/licenses/GPL-2.0 - https://github.com/raspberry-sharp/raspberry-sharp-io - true - - Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. + + Raspberry.IO.GeneralPurpose + 0.0.0 + Raspberry.IO.GeneralPurpose + Raspberry-Sharp + http://opensource.org/licenses/GPL-2.0 + https://github.com/raspberry-sharp/raspberry-sharp-io + https://raw.github.com/raspberry-sharp/raspberry-sharp-io/master/Icon.png + true + + Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. - It is an initiative of the Raspberry# Community, aimed at providing tools and information concerning use of Raspberry Pi boards with Mono/.NET framework. - Parts of this work are based on BCM2835 C library (http://www.open.com.au/mikem/bcm2835/) - -

Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. - en-US - Raspberry Pi Mono GPIO - - - - - + It is an initiative of the Raspberry# Community, aimed at providing tools and information concerning use of Raspberry Pi boards with Mono/.NET framework. + Parts of this work are based on BCM2835 C library (http://www.open.com.au/mikem/bcm2835/) + + Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. + en-US + Raspberry Pi Mono GPIO + + + + + From 22cdd43bea0f9cb74dc521aba7c13340802146ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 19:33:46 +0200 Subject: [PATCH 027/227] Enlarged icon --- Icon.png | Bin 2863 -> 31034 bytes Thumbs.db | Bin 0 -> 35328 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Thumbs.db diff --git a/Icon.png b/Icon.png index 49e65ef9c95d409f01fcea39849943a48d619691..5db037551f81de42e2bfa87e3f1b116f361e169b 100644 GIT binary patch literal 31034 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 XqpbDJV01kt00000NkvXXu0mjfmxe0# diff --git a/Thumbs.db b/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..8b582877dfcdeb5bd49029264a51297e2097e296 GIT binary patch literal 35328 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 literal 0 HcmV?d00001 From 3275d613ec8886b329ec90bb2daf2dcd9dc560cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 23:27:58 +0200 Subject: [PATCH 028/227] Renamed IConnectionDriver to IGpioConnectionDriver Also made Mainboard internal (and renamed). Also enable forcing board revision in app.config file --- GpioTest/Board.cs | 139 ++++++++++++++++++ GpioTest/GpioTest.csproj | 1 + GpioTest/Helpers.cs | 6 +- GpioTest/Program.cs | 133 +++++++++-------- GpioTest/app.config | 4 +- .../GpioConnectionConfigurationSection.cs | 14 ++ ...nDriver.cs => FileGpioConnectionDriver.cs} | 16 +- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 16 +- Raspberry.IO.GeneralPurpose/Host.cs | 121 +++++++++++++++ ...tionDriver.cs => IGpioConnectionDriver.cs} | 2 +- Raspberry.IO.GeneralPurpose/Mainboard.cs | 121 --------------- ...river.cs => MemoryGpioConnectionDriver.cs} | 15 +- Raspberry.IO.GeneralPurpose/PinMapping.cs | 15 +- .../Properties/AssemblyInfo.cs | 4 +- .../Raspberry.IO.GeneralPurpose.csproj | 8 +- 15 files changed, 410 insertions(+), 205 deletions(-) create mode 100644 GpioTest/Board.cs rename Raspberry.IO.GeneralPurpose/{FileConnectionDriver.cs => FileGpioConnectionDriver.cs} (84%) create mode 100644 Raspberry.IO.GeneralPurpose/Host.cs rename Raspberry.IO.GeneralPurpose/{IConnectionDriver.cs => IGpioConnectionDriver.cs} (96%) delete mode 100644 Raspberry.IO.GeneralPurpose/Mainboard.cs rename Raspberry.IO.GeneralPurpose/{MemoryConnectionDriver.cs => MemoryGpioConnectionDriver.cs} (85%) diff --git a/GpioTest/Board.cs b/GpioTest/Board.cs new file mode 100644 index 0000000..cc3d011 --- /dev/null +++ b/GpioTest/Board.cs @@ -0,0 +1,139 @@ +#region References + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +#endregion + +namespace GpioTest +{ + /// + /// Represents the Raspberry Pi mainboard. + /// + internal class Board + { + #region Fields + + private static readonly Lazy board = new Lazy(LoadBoard); + private readonly Dictionary settings; + + private const string raspberryPiProcessor = "BCM2708"; + + #endregion + + #region Instance Management + + private Board(Dictionary settings) + { + this.settings = settings; + } + + #endregion + + #region Properties + + /// + /// Gets the current mainboard configuration. + /// + public static Board Current + { + get { return board.Value; } + } + + /// + /// Gets a value indicating whether this instance is a Raspberry Pi. + /// + /// + /// true if this instance is a Raspberry Pi; otherwise, false. + /// + public bool IsRaspberryPi + { + get { return Processor == raspberryPiProcessor; } + } + + /// + /// Gets the processor. + /// + public string Processor + { + get + { + string hardware; + return settings.TryGetValue("Hardware", out hardware) ? hardware : null; + } + } + + /// + /// Gets the board firmware version. + /// + public int Firmware + { + get + { + string revision; + int firmware; + if (settings.TryGetValue("Revision", out revision) && !string.IsNullOrEmpty(revision) && int.TryParse(revision, out firmware)) + return firmware; + + return 0; + } + } + + /// + /// Gets the board revision. + /// + public int Revision + { + get + { + var firmware = Firmware; + switch (firmware) + { + case 2: + case 3: + return 1; + case 4: + case 5: + case 6: + return 2; + + default: + return 0; + } + } + } + + #endregion + + #region Private Helpers + + private static Board LoadBoard() + { + try + { + const string filePath = "/proc/cpuinfo"; + var settings = File.ReadAllLines(filePath) + .Where(l => !string.IsNullOrEmpty(l)) + .Select(l => + { + var separator = l.IndexOf(':'); + if (separator < 0) + return new KeyValuePair(l, null); + else + return new KeyValuePair(l.Substring(0, separator).Trim(), l.Substring(separator + 1).Trim()); + }) + .ToDictionary(p => p.Key, p => p.Value); + + return new Board(settings); + } + catch + { + return new Board(new Dictionary()); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/GpioTest/GpioTest.csproj b/GpioTest/GpioTest.csproj index cdf300f..b178dcc 100644 --- a/GpioTest/GpioTest.csproj +++ b/GpioTest/GpioTest.csproj @@ -66,6 +66,7 @@ + diff --git a/GpioTest/Helpers.cs b/GpioTest/Helpers.cs index 5ccd1fa..e6c59cf 100644 --- a/GpioTest/Helpers.cs +++ b/GpioTest/Helpers.cs @@ -27,16 +27,16 @@ public static int GetSpeed(this IEnumerable args) return args.SkipWhile(a => a != "-speed").Skip(1).Select(int.Parse).DefaultIfEmpty(250).First(); } - public static IConnectionDriver GetDriver(this IEnumerable args) + public static IGpioConnectionDriver GetDriver(this IEnumerable args) { var driverName = args.SkipWhile(a => a != "-driver").Skip(1).DefaultIfEmpty("").First(); switch (driverName) { case "memory": - return new MemoryConnectionDriver(); + return new MemoryGpioConnectionDriver(); case "file": - return new FileConnectionDriver(); + return new FileGpioConnectionDriver(); case "": return null; diff --git a/GpioTest/Program.cs b/GpioTest/Program.cs index 997eed1..c7bfcbb 100644 --- a/GpioTest/Program.cs +++ b/GpioTest/Program.cs @@ -13,78 +13,91 @@ class Program { static void Main(string[] args) { - var driver = args.GetDriver(); - var mainboard = Mainboard.Current; - - if (!mainboard.IsRaspberryPi) + try { - Console.WriteLine("{0} is not a valid processor for a Raspberry Pi."); - return; - } + var driver = args.GetDriver(); + var mainboard = Board.Current; + + if (!mainboard.IsRaspberryPi) + { + Console.WriteLine("'{0}' is not a valid processor for a Raspberry Pi.", mainboard.Processor); + return; + } - // Declare outputs (leds) - var leds = new PinConfiguration[] - { - ConnectorPin.P1Pin26.Output().Name("Led1").Enable(), - ConnectorPin.P1Pin24.Output().Name("Led2"), - ConnectorPin.P1Pin22.Output().Name("Led3").Enable(), - ConnectorPin.P1Pin15.Output().Name("Led4"), - ConnectorPin.P1Pin13.Output().Name("Led5").Enable(), - ConnectorPin.P1Pin11.Output().Name("Led6") - }; - - // Assign a behavior to the leds - var behavior = new ChaserBehavior(leds) + // Declare outputs (leds) + var leds = new PinConfiguration[] { - Loop = args.GetLoop(), - RoundTrip = args.GetRoundTrip(), - Width = args.GetWidth(), - Interval = args.GetSpeed() + ConnectorPin.P1Pin26.Output().Name("Led1").Enable(), + ConnectorPin.P1Pin24.Output().Name("Led2"), + ConnectorPin.P1Pin22.Output().Name("Led3").Enable(), + ConnectorPin.P1Pin15.Output().Name("Led4"), + ConnectorPin.P1Pin13.Output().Name("Led5").Enable(), + ConnectorPin.P1Pin11.Output().Name("Led6") }; - // Alternate behaviors... - /* - var random = new Random(); - var behavior = new PatternBehavior(leds, Enumerable.Range(0, 5).Select(i => random.Next(511))) - { - Loop = Helpers.GetLoop(args), - RoundTrip = Helpers.GetRoundTrip(args), - Interval = Helpers.GetSpeed(args) - };*/ + // Assign a behavior to the leds + var behavior = new ChaserBehavior(leds) + { + Loop = args.GetLoop(), + RoundTrip = args.GetRoundTrip(), + Width = args.GetWidth(), + Interval = args.GetSpeed() + }; - /* - var behavior = new BlinkBehavior(leds) - { - Count = args.GetWidth(), - Interval = args.GetSpeed() - };*/ + // Alternate behaviors... + /* + var random = new Random(); + var behavior = new PatternBehavior(leds, Enumerable.Range(0, 5).Select(i => random.Next(511))) + { + Loop = Helpers.GetLoop(args), + RoundTrip = Helpers.GetRoundTrip(args), + Interval = Helpers.GetSpeed(args) + };*/ - // Declare input (switchButton) interacting with the leds behavior - var switchButton = ConnectorPin.P1Pin03.Input() - .Name("Switch") - .Revert() - .Switch() - .Enable() - .OnStatusChanged(b => - { - behavior.RoundTrip = !behavior.RoundTrip; - Console.WriteLine("Button switched {0}", b ? "on" : "off"); - }); + /* + var behavior = new BlinkBehavior(leds) + { + Count = args.GetWidth(), + Interval = args.GetSpeed() + };*/ - // Create connection - using (var connection = new GpioConnection(driver, leds)) - { - Console.WriteLine("Running on Raspberry firmware rev{0}, board rev{1}, processor {2}", mainboard.FirmwareRevision, mainboard.BoardRevision, mainboard.Processor); - Console.WriteLine("Using {0}, frequency {1:0.##}hz", connection.Driver.GetType().Name, 1000.0 / args.GetSpeed()); + // Declare input (switchButton) interacting with the leds behavior + var switchButton = ConnectorPin.P1Pin03.Input() + .Name("Switch") + .Revert() + .Switch() + .Enable() + .OnStatusChanged(b => + { + behavior.RoundTrip = !behavior.RoundTrip; + Console.WriteLine("Button switched {0}", b ? "on" : "off"); + }); + + // Create connection + Console.WriteLine("Running on Raspberry firmware rev{0}, board rev{1}, processor {2}", mainboard.Firmware, mainboard.Revision, mainboard.Processor); + + using (var connection = new GpioConnection(driver, leds)) + { + Console.WriteLine("Using {0}, frequency {1:0.##}hz", connection.Driver.GetType().Name, 1000.0/args.GetSpeed()); - Thread.Sleep(1000); + Thread.Sleep(1000); - connection.Add(switchButton); - connection.Start(behavior); // Starting the behavior automatically registers the pins to the connection, if needed. + connection.Add(switchButton); + connection.Start(behavior); // Starting the behavior automatically registers the pins to the connection, if needed. - Console.ReadKey(true); + Console.ReadKey(true); - connection.Stop(behavior); + connection.Stop(behavior); + } + } + catch(Exception ex) + { + var currentException = ex; + while (currentException != null) + { + Console.WriteLine("{0}: {1}", currentException.GetType().Name, currentException.Message); + currentException = currentException.InnerException; + } } } } diff --git a/GpioTest/app.config b/GpioTest/app.config index 98787ab..913e3b6 100644 --- a/GpioTest/app.config +++ b/GpioTest/app.config @@ -4,7 +4,9 @@
- + diff --git a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs index e315d44..04ff6ea 100644 --- a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs +++ b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs @@ -1,6 +1,7 @@ #region References using System.Configuration; +using System.Runtime.Remoting.Messaging; #endregion @@ -26,6 +27,19 @@ public string DriverTypeName set { this["driver"] = value; } } + /// + /// Gets or sets the board revision. + /// + /// + /// The board revision. + /// + [ConfigurationProperty("boardRevision")] + public string BoardRevision + { + get { return (string) this["boardRevision"]; } + set { this["boardRevision"] = value; } + } + #endregion } } diff --git a/Raspberry.IO.GeneralPurpose/FileConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs similarity index 84% rename from Raspberry.IO.GeneralPurpose/FileConnectionDriver.cs rename to Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 9fabc8c..e10868f 100644 --- a/Raspberry.IO.GeneralPurpose/FileConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -1,5 +1,6 @@ #region References +using System; using System.IO; #endregion @@ -9,7 +10,7 @@ namespace Raspberry.IO.GeneralPurpose /// /// Represents a connection driver using files. /// - public class FileConnectionDriver : IConnectionDriver + public class FileGpioConnectionDriver : IGpioConnectionDriver { #region Fields @@ -17,6 +18,19 @@ public class FileConnectionDriver : IConnectionDriver #endregion + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + public FileGpioConnectionDriver() + { + if (!Host.Current.IsRaspberryPi) + throw new NotSupportedException("FileGpioConnectionDriver is only supported on Raspberry Pi"); + } + + #endregion + #region Methods /// diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index e0208ea..08146fa 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -52,14 +52,14 @@ public GpioConnection(IEnumerable pins) : this(true, null, pin /// /// The driver. /// The pins. - public GpioConnection(IConnectionDriver driver, params PinConfiguration[] pins) : this(true, driver, (IEnumerable) pins){} + public GpioConnection(IGpioConnectionDriver driver, params PinConfiguration[] pins) : this(true, driver, (IEnumerable) pins){} /// /// Initializes a new instance of the class. /// /// The driver. /// The pins. - public GpioConnection(IConnectionDriver driver, IEnumerable pins) : this(true, driver, pins){} + public GpioConnection(IGpioConnectionDriver driver, IEnumerable pins) : this(true, driver, pins){} /// /// Initializes a new instance of the class. @@ -74,7 +74,7 @@ public GpioConnection(bool open, params PinConfiguration[] pins) : this(open, nu /// if set to true, connection is opened on creation. /// The driver. /// The pins. - public GpioConnection(bool open, IConnectionDriver driver, params PinConfiguration[] pins) : this(open, driver, (IEnumerable) pins){} + public GpioConnection(bool open, IGpioConnectionDriver driver, params PinConfiguration[] pins) : this(open, driver, (IEnumerable) pins){} /// /// Initializes a new instance of the class. @@ -89,7 +89,7 @@ public GpioConnection(bool open, IEnumerable pins) : this(open /// if set to true, connection is opened on creation. /// The driver. /// The pins. - public GpioConnection(bool open, IConnectionDriver driver, IEnumerable pins) + public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable pins) { Driver = driver ?? GetDefaultDriver(); Pins = new ConnectedPins(this); @@ -124,7 +124,7 @@ void IDisposable.Dispose() /// /// Gets the driver. /// - public IConnectionDriver Driver { get; private set; } + public IGpioConnectionDriver Driver { get; private set; } /// /// Gets or sets the status of the pin having the specified name. @@ -492,13 +492,13 @@ internal IEnumerable Configurations #region Private Helpers - private static IConnectionDriver GetDefaultDriver() + private static IGpioConnectionDriver GetDefaultDriver() { var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; if (configurationSection != null && !string.IsNullOrEmpty(configurationSection.DriverTypeName)) - return (IConnectionDriver) Activator.CreateInstance(Type.GetType(configurationSection.DriverTypeName, true)); + return (IGpioConnectionDriver) Activator.CreateInstance(Type.GetType(configurationSection.DriverTypeName, true)); else - return new MemoryConnectionDriver(); + return new MemoryGpioConnectionDriver(); } private void Allocate(PinConfiguration configuration) diff --git a/Raspberry.IO.GeneralPurpose/Host.cs b/Raspberry.IO.GeneralPurpose/Host.cs new file mode 100644 index 0000000..a70961b --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Host.cs @@ -0,0 +1,121 @@ +#region References + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +#endregion + +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents the host. + /// + internal class Host + { + #region Fields + + private static readonly Lazy board = new Lazy(LoadBoard); + private readonly Dictionary settings; + + private const string raspberryPiProcessor = "BCM2708"; + + #endregion + + #region Instance Management + + private Host(Dictionary settings) + { + this.settings = settings; + } + + #endregion + + #region Properties + + /// + /// Gets the current mainboard configuration. + /// + public static Host Current + { + get { return board.Value; } + } + + /// + /// Gets a value indicating whether this instance is a Raspberry Pi. + /// + /// + /// true if this instance is a Raspberry Pi; otherwise, false. + /// + public bool IsRaspberryPi + { + get + { + string hardware; + return settings.TryGetValue("Hardware", out hardware) && string.Equals(hardware, raspberryPiProcessor, StringComparison.InvariantCultureIgnoreCase); + } + } + + /// + /// Gets the board revision. + /// + public int BoardRevision + { + get + { + if (!IsRaspberryPi) + throw new NotSupportedException("Host is not a Raspberry Pi"); + + string revision; + int firmware; + if (settings.TryGetValue("Revision", out revision) && !string.IsNullOrEmpty(revision) && int.TryParse(revision, out firmware)) + { + switch(firmware) + { + case 2: + case 3: + return 1; + case 4: + case 5: + case 6: + return 2; + } + } + + throw new NotSupportedException(string.Format("Raspberry Pi revision '{0}' not supported", revision)); + } + } + + #endregion + + #region Private Helpers + + private static Host LoadBoard() + { + try + { + const string filePath = "/proc/cpuinfo"; + var settings = File.ReadAllLines(filePath) + .Where(l => !string.IsNullOrEmpty(l)) + .Select(l => + { + var separator = l.IndexOf(':'); + if (separator < 0) + return new KeyValuePair(l, null); + else + return new KeyValuePair(l.Substring(0, separator).Trim(), l.Substring(separator + 1).Trim()); + }) + .ToDictionary(p => p.Key, p => p.Value); + + return new Host(settings); + } + catch + { + return new Host(new Dictionary()); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/IConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs similarity index 96% rename from Raspberry.IO.GeneralPurpose/IConnectionDriver.cs rename to Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs index 60cfc60..02a9885 100644 --- a/Raspberry.IO.GeneralPurpose/IConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs @@ -3,7 +3,7 @@ namespace Raspberry.IO.GeneralPurpose /// /// Provides an interface for connection drivers. /// - public interface IConnectionDriver + public interface IGpioConnectionDriver { #region Methods diff --git a/Raspberry.IO.GeneralPurpose/Mainboard.cs b/Raspberry.IO.GeneralPurpose/Mainboard.cs deleted file mode 100644 index 8a9c7c0..0000000 --- a/Raspberry.IO.GeneralPurpose/Mainboard.cs +++ /dev/null @@ -1,121 +0,0 @@ -#region References - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -#endregion - -namespace Raspberry.IO.GeneralPurpose -{ - /// - /// Represents the Raspberry Pi mainboard. - /// - public class Mainboard - { - #region Fields - - private static readonly Lazy board = new Lazy(LoadBoard); - private readonly Dictionary settings; - - private const string raspberryPiProcessor = "BCM2708"; - - #endregion - - #region Instance Management - - private Mainboard(Dictionary settings) - { - this.settings = settings; - } - - #endregion - - #region Properties - - /// - /// Gets the current mainboard configuration. - /// - public static Mainboard Current - { - get { return board.Value; } - } - - /// - /// Gets a value indicating whether this instance is a Raspberry Pi. - /// - /// - /// true if this instance is a Raspberry Pi; otherwise, false. - /// - public bool IsRaspberryPi - { - get { return Processor == raspberryPiProcessor; } - } - - /// - /// Gets the processor. - /// - public string Processor - { - get { return settings["Hardware"]; } - } - - /// - /// Gets the serial number. - /// - public string SerialNumber - { - get { return settings["Serial"]; } - } - - /// - /// Gets the firmware revision. - /// - public int FirmwareRevision - { - get { return int.Parse(settings["Revision"]); } - } - - /// - /// Gets the board revision. - /// - public int BoardRevision - { - get - { - var firmware = FirmwareRevision; - if (firmware <= 3) - return 1; - else if (firmware <= 6) - return 2; - else - throw new NotSupportedException("Raspberry board not supported"); - } - } - - #endregion - - #region Private Helpers - - private static Mainboard LoadBoard() - { - const string filePath = "/proc/cpuinfo"; - var settings = File.ReadAllLines(filePath) - .Where(l => !string.IsNullOrEmpty(l)) - .Select(l => - { - var separator = l.IndexOf(':'); - if (separator < 0) - return new KeyValuePair(l, null); - else - return new KeyValuePair(l.Substring(0, separator).Trim(), l.Substring(separator + 1).Trim()); - }) - .ToDictionary(p => p.Key, p => p.Value); - - return new Mainboard(settings); - } - - #endregion - } -} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/MemoryConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs similarity index 85% rename from Raspberry.IO.GeneralPurpose/MemoryConnectionDriver.cs rename to Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 8af4008..3cb165c 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -11,7 +11,7 @@ namespace Raspberry.IO.GeneralPurpose /// Represents a connection driver that uses memory. /// /// Based on bmc2835_gpio library. - public class MemoryConnectionDriver : IConnectionDriver + public class MemoryGpioConnectionDriver : IGpioConnectionDriver { #region Fields @@ -19,6 +19,19 @@ public class MemoryConnectionDriver : IConnectionDriver #endregion + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + public MemoryGpioConnectionDriver() + { + if (!Host.Current.IsRaspberryPi) + throw new NotSupportedException("MemoryGpioConnectionDriver is only supported on Raspberry Pi"); + } + + #endregion + #region Methods /// diff --git a/Raspberry.IO.GeneralPurpose/PinMapping.cs b/Raspberry.IO.GeneralPurpose/PinMapping.cs index 8ac86be..196ce6d 100644 --- a/Raspberry.IO.GeneralPurpose/PinMapping.cs +++ b/Raspberry.IO.GeneralPurpose/PinMapping.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; +using System.Configuration; using System.Globalization; using System.Linq; +using Raspberry.IO.GeneralPurpose.Configuration; #endregion @@ -25,7 +27,14 @@ public static class PinMapping static PinMapping() { - var boardRevision = Mainboard.Current.BoardRevision; + var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; + + int boardRevision; + if (configurationSection == null || string.Equals(configurationSection.BoardRevision ?? "auto", "auto", StringComparison.InvariantCultureIgnoreCase)) + boardRevision = Host.Current.BoardRevision; + else + boardRevision = int.Parse(configurationSection.BoardRevision); + var mapping = boardRevision == 1 ? new[] { @@ -92,7 +101,7 @@ public static ProcessorPin ToProcessor(this ConnectorPin pin) if (processorMappings.TryGetValue(pin, out processorPin)) return processorPin; else - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Connector pin {0} is not mapped to processor on board revision {1}", pin.ToString().Replace("Pin", "-"), Mainboard.Current.BoardRevision)); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Connector pin {0} is not mapped to processor on board revision {1}", pin.ToString().Replace("Pin", "-"), Host.Current.BoardRevision)); } /// @@ -106,7 +115,7 @@ public static ConnectorPin ToConnector(this ProcessorPin pin) if (connectorMappings.TryGetValue(pin, out connectorPin)) return connectorPin; else - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Processor pin {0} is not mapped to connector on board revision {1}", (int) pin, Mainboard.Current.BoardRevision)); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Processor pin {0} is not mapped to connector on board revision {1}", (int) pin, Host.Current.BoardRevision)); } #endregion diff --git a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs index 6e6b0e6..25e1bc3 100644 --- a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs +++ b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 9c9ae29..533bc7c 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -46,12 +46,12 @@ - - + + - + - + From 81bbb163baac755d2dd775f3fb200d3ef79442fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 23:40:24 +0200 Subject: [PATCH 029/227] Added ability to customize poll interval Set a higher value reduces CPU load, but some input changes may be missed --- GpioTest/app.config | 1 + .../GpioConnectionConfigurationSection.cs | 15 ++++++++++++++- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 5 ++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/GpioTest/app.config b/GpioTest/app.config index 913e3b6..ca9e1c1 100644 --- a/GpioTest/app.config +++ b/GpioTest/app.config @@ -6,6 +6,7 @@ diff --git a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs index 04ff6ea..d5a22c0 100644 --- a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs +++ b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs @@ -1,7 +1,6 @@ #region References using System.Configuration; -using System.Runtime.Remoting.Messaging; #endregion @@ -40,6 +39,20 @@ public string BoardRevision set { this["boardRevision"] = value; } } + /// + /// Gets or sets the poll interval, in milliseconds. + /// + /// + /// The poll interval, in millisecond. + /// + /// Default value is 50ms. + [ConfigurationProperty("pollInterval", DefaultValue = 50)] + public int PollInterval + { + get { return (int)this["pollInterval"]; } + set { this["pollInterval"] = value; } + } + #endregion } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 08146fa..764637e 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -197,7 +197,10 @@ public void Open() foreach (var pin in pinConfigurations.Values) Allocate(pin); - timer.Change(250, 50); + var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; + var pollInterval = configurationSection != null ? configurationSection.PollInterval : 50; + + timer.Change(10, pollInterval); IsOpened = true; } } From 8af20ce0915d6e06000880b82aba2efda54eb295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 17 Oct 2012 23:55:39 +0200 Subject: [PATCH 030/227] Updated .nuspec project url --- Raspberry.IO.GeneralPurpose.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index 6ce197a..6faf114 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -6,7 +6,7 @@ Raspberry.IO.GeneralPurpose Raspberry-Sharp http://opensource.org/licenses/GPL-2.0 - https://github.com/raspberry-sharp/raspberry-sharp-io + https://github.com/raspberry-sharp/raspberry-sharp-io/wiki/Raspberry.IO.GeneralPurpose https://raw.github.com/raspberry-sharp/raspberry-sharp-io/master/Icon.png true From 089507f8dec332ce069bf183d113d85f8dfe76c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 18:36:40 +0200 Subject: [PATCH 031/227] Moved interop to a specific class --- Raspberry.IO.GeneralPurpose/Interop.cs | 29 +++++++++++++++++++ .../MemoryGpioConnectionDriver.cs | 29 ++++--------------- .../Raspberry.IO.GeneralPurpose.csproj | 1 + 3 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 Raspberry.IO.GeneralPurpose/Interop.cs diff --git a/Raspberry.IO.GeneralPurpose/Interop.cs b/Raspberry.IO.GeneralPurpose/Interop.cs new file mode 100644 index 0000000..f0dbc77 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Interop.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; + +namespace Raspberry.IO.GeneralPurpose +{ + internal static class Interop + { + #region Interop Methods + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")] + public static extern int bcm2835_init(); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_fsel")] + public static extern void bcm2835_gpio_fsel(uint pin, uint mode); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write")] + public static extern void bcm2835_gpio_write(uint pin, uint value); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_lev")] + public static extern uint bcm2835_gpio_lev(uint pin); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_set_pud")] + public static extern void bcm2835_gpio_set_pud(uint pin, uint pud); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_delayMicroseconds")] + public static extern void bcm2835_delayMicroseconds(uint microseconds); + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 3cb165c..bad2d51 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -1,7 +1,6 @@ #region References using System; -using System.Runtime.InteropServices; #endregion @@ -15,7 +14,7 @@ public class MemoryGpioConnectionDriver : IGpioConnectionDriver { #region Fields - private static readonly Lazy initialized = new Lazy(() => bcm2835_init() != 0); + private static readonly Lazy initialized = new Lazy(() => Interop.bcm2835_init() != 0); #endregion @@ -41,7 +40,7 @@ public MemoryGpioConnectionDriver() /// The pin status. public void Write(ProcessorPin pin, bool value) { - bcm2835_gpio_write((uint) pin, (uint) (value ? 1 : 0)); + Interop.bcm2835_gpio_write((uint) pin, (uint) (value ? 1 : 0)); } /// @@ -53,7 +52,7 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { - var value = bcm2835_gpio_lev((uint) pin); + var value = Interop.bcm2835_gpio_lev((uint)pin); return value != 0; } @@ -70,14 +69,14 @@ public void Allocate(ProcessorPin pin, PinDirection direction) // Set the direction on the pin and update the exported list // BCM2835_GPIO_FSEL_INPT = 0 // BCM2835_GPIO_FSEL_OUTP = 1 - bcm2835_gpio_fsel((uint) pin, (uint) (direction == PinDirection.Input ? 0 : 1)); + Interop.bcm2835_gpio_fsel((uint)pin, (uint)(direction == PinDirection.Input ? 0 : 1)); if (direction == PinDirection.Input) { // BCM2835_GPIO_PUD_OFF = 0b00 = 0 // BCM2835_GPIO_PUD_DOWN = 0b01 = 1 // BCM2835_GPIO_PUD_UP = 0b10 = 2 - bcm2835_gpio_set_pud((uint) pin, 0); + Interop.bcm2835_gpio_set_pud((uint)pin, 0); } } @@ -88,23 +87,5 @@ public void Release(ProcessorPin pin) #endregion - #region Interop Methods - - [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")] - static extern int bcm2835_init(); - - [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_fsel")] - static extern void bcm2835_gpio_fsel(uint pin, uint mode); - - [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write")] - static extern void bcm2835_gpio_write(uint pin, uint value); - - [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_lev")] - static extern uint bcm2835_gpio_lev(uint pin); - - [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_set_pud")] - static extern void bcm2835_gpio_set_pud(uint pin, uint pud); - - #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 533bc7c..165aaa3 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -47,6 +47,7 @@ + From 2714669810cb25310b550afad827277aa5201623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 19:21:58 +0200 Subject: [PATCH 032/227] Introduced ITimer This will support high-resolution timers --- .../Behaviors/PinsBehavior.cs | 20 ++++--- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 19 +++--- .../Raspberry.IO.GeneralPurpose.csproj | 2 + Raspberry.IO.GeneralPurpose/Time/ITimer.cs | 28 +++++++++ .../Time/StandardTimer.cs | 59 +++++++++++++++++++ 5 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 Raspberry.IO.GeneralPurpose/Time/ITimer.cs create mode 100644 Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs diff --git a/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs b/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs index 9eb7cee..11f2ae8 100644 --- a/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs +++ b/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs @@ -1,8 +1,10 @@ #region References +using System; using System.Collections.Generic; using System.Linq; using System.Threading; +using Raspberry.IO.GeneralPurpose.Time; #endregion @@ -15,7 +17,7 @@ public abstract class PinsBehavior { #region Fields - private readonly Timer timer; + private readonly ITimer timer; private int currentStep; #endregion @@ -29,9 +31,9 @@ public abstract class PinsBehavior protected PinsBehavior(IEnumerable configurations) { Configurations = configurations.ToArray(); - Interval = 250; - timer = new Timer(OnTimer, null, Timeout.Infinite, Timeout.Infinite); + timer = new StandardTimer { Interval = 250 }; + timer.Elapsed += OnTimer; } #endregion @@ -49,7 +51,11 @@ protected PinsBehavior(IEnumerable configurations) /// /// The interval. /// - public int Interval { get; set; } + public int Interval + { + get { return (int)timer.Interval; } + set { timer.Interval = value; } + } #endregion @@ -90,12 +96,12 @@ internal void Start(GpioConnection connection) connection[pinConfiguration] = false; currentStep = GetFirstStep(); - timer.Change(0, Interval); + timer.Start(0); } internal void Stop() { - timer.Change(Timeout.Infinite, Timeout.Infinite); + timer.Stop(); foreach (var pinConfiguration in Configurations) Connection[pinConfiguration] = false; @@ -105,7 +111,7 @@ internal void Stop() #region Private Helpers - private void OnTimer(object state) + private void OnTimer(object state, EventArgs eventArgs) { ProcessStep(currentStep); if (!TryGetNextStep(ref currentStep)) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 764637e..502763b 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using Raspberry.IO.GeneralPurpose.Configuration; +using Raspberry.IO.GeneralPurpose.Time; #endregion @@ -21,7 +22,7 @@ public class GpioConnection : IDisposable private readonly Dictionary pinConfigurations; private readonly Dictionary namedPins; - private readonly Timer timer; + private readonly ITimer timer; private readonly Dictionary pinValues = new Dictionary(); private readonly Dictionary> pinEvents = new Dictionary>(); private readonly Dictionary pinRawValues = new Dictionary(); @@ -98,8 +99,13 @@ public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable p.Pin); namedPins = pinList.Where(p => !string.IsNullOrEmpty(p.Name)).ToDictionary(p => p.Name); + + var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; + var pollInterval = configurationSection != null ? configurationSection.PollInterval : 50; + + timer = new StandardTimer {Interval = pollInterval}; + timer.Elapsed += CheckInputPins; - timer = new Timer(CheckInputPins, null, Timeout.Infinite, Timeout.Infinite); if (open) Open(); } @@ -197,10 +203,7 @@ public void Open() foreach (var pin in pinConfigurations.Values) Allocate(pin); - var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; - var pollInterval = configurationSection != null ? configurationSection.PollInterval : 50; - - timer.Change(10, pollInterval); + timer.Start(10); IsOpened = true; } } @@ -215,7 +218,7 @@ public void Close() if (!IsOpened) return; - timer.Dispose(); + timer.Stop(); foreach (var pin in pinConfigurations.Values) Release(pin); @@ -558,7 +561,7 @@ private void Release(PinConfiguration configuration) } } - private void CheckInputPins(object state) + private void CheckInputPins(object state, EventArgs eventArgs) { Dictionary newPinValues; diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 165aaa3..1c34ca3 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -48,6 +48,7 @@ + @@ -63,6 +64,7 @@ + diff --git a/Raspberry.IO.GeneralPurpose/Time/ITimer.cs b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs new file mode 100644 index 0000000..f9a8e38 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs @@ -0,0 +1,28 @@ +using System; + +namespace Raspberry.IO.GeneralPurpose.Time +{ + internal interface ITimer + { + /// + /// Gets or sets the interval, in milliseconds. + /// + /// + /// The interval, in milliseconds. + /// + decimal Interval { get; set; } + + /// + /// Starts this instance. + /// + /// The delay before the first occurence, in milliseconds. + void Start(decimal delay); + + /// + /// Stops this instance. + /// + void Stop(); + + event EventHandler Elapsed; + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs new file mode 100644 index 0000000..e8f7820 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading; + +namespace Raspberry.IO.GeneralPurpose.Time +{ + internal class StandardTimer : ITimer + { + private decimal interval; + + private bool isStarted; + private Timer timer; + + public decimal Interval + { + get { return interval; } + set + { + interval = value; + if (isStarted) + Start(0); + } + } + + public void Start(decimal delay) + { + lock (this) + { + if (!isStarted && interval >= 1.0m) + { + isStarted = true; + timer = new Timer(OnElapsed, null, (int) delay, (int) interval); + } + else + Stop(); + } + } + + public void Stop() + { + lock (this) + { + if (isStarted) + { + isStarted = false; + timer.Dispose(); + timer = null; + } + } + } + + public event EventHandler Elapsed; + + private void OnElapsed(object state) + { + var elapsed = Elapsed; + elapsed(this, new EventArgs()); + } + } +} \ No newline at end of file From d7a2f1705924becb7a66577ed5144c611efe880b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 19:50:03 +0200 Subject: [PATCH 033/227] Introduced HighResolutionTimer Updated libbcm2835.so to add support for microseconds delay --- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 13 ++-- .../Raspberry.IO.GeneralPurpose.csproj | 2 + .../Time/HighResolutionTimer.cs | 65 ++++++++++++++++++ .../Time/StandardTimer.cs | 7 +- Raspberry.IO.GeneralPurpose/Time/Timer.cs | 22 ++++++ Raspberry.IO.GeneralPurpose/libbcm2835.so | Bin 30233 -> 29819 bytes 6 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs create mode 100644 Raspberry.IO.GeneralPurpose/Time/Timer.cs diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 502763b..7ff1f9f 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Configuration; using System.Linq; -using System.Threading; using Raspberry.IO.GeneralPurpose.Configuration; using Raspberry.IO.GeneralPurpose.Time; @@ -103,7 +102,9 @@ public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable + @@ -65,6 +66,7 @@ + diff --git a/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs new file mode 100644 index 0000000..d042923 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs @@ -0,0 +1,65 @@ +using System; +using System.Threading; + +namespace Raspberry.IO.GeneralPurpose.Time +{ + internal class HighResolutionTimer : ITimer + { + private decimal interval; + private Thread thread; + + public HighResolutionTimer() + { + if (!Host.Current.IsRaspberryPi) + throw new NotSupportedException("Cannot use HighResolutionTimer on a platform different than Raspberry Pi"); + } + + public decimal Interval + { + get { return interval; } + set + { + if (value > uint.MaxValue / 1000) + throw new ArgumentOutOfRangeException("Interval", interval, "Interval must be lower than or equal to uint.MaxValue / 1000"); + + interval = value; + } + } + + public void Start(decimal delay) + { + thread = new Thread(ThreadProcess); + + Sleep(delay); + thread.Start(); + } + + public void Stop() + { + thread.Abort(); + thread = null; + } + + public event EventHandler Elapsed; + + private void ThreadProcess() + { + var currentThread = thread; + while (thread == currentThread) + { + Interop.bcm2835_delayMicroseconds((uint) interval*1000); + + var elapsed = Elapsed; + elapsed(this, EventArgs.Empty); + } + } + + public static void Sleep(decimal delay) + { + if (delay > uint.MaxValue / 1000) + throw new ArgumentOutOfRangeException("delay", delay, "Delay must be lower than or equal to uint.MaxValue / 1000"); + + Interop.bcm2835_delayMicroseconds((uint)(delay * 1000)); + } + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs index e8f7820..4b345f3 100644 --- a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs @@ -1,5 +1,4 @@ using System; -using System.Threading; namespace Raspberry.IO.GeneralPurpose.Time { @@ -8,7 +7,7 @@ internal class StandardTimer : ITimer private decimal interval; private bool isStarted; - private Timer timer; + private System.Threading.Timer timer; public decimal Interval { @@ -28,7 +27,7 @@ public void Start(decimal delay) if (!isStarted && interval >= 1.0m) { isStarted = true; - timer = new Timer(OnElapsed, null, (int) delay, (int) interval); + timer = new System.Threading.Timer(OnElapsed, null, (int)delay, (int)interval); } else Stop(); @@ -53,7 +52,7 @@ public void Stop() private void OnElapsed(object state) { var elapsed = Elapsed; - elapsed(this, new EventArgs()); + elapsed(this, EventArgs.Empty); } } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/Timer.cs b/Raspberry.IO.GeneralPurpose/Time/Timer.cs new file mode 100644 index 0000000..8dbbf23 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/Time/Timer.cs @@ -0,0 +1,22 @@ +using System.Threading; + +namespace Raspberry.IO.GeneralPurpose.Time +{ + internal static class Timer + { + public static ITimer Create() + { + return Host.Current.IsRaspberryPi + ? (ITimer)new HighResolutionTimer() + : new StandardTimer(); + } + + public static void Sleep(decimal delay) + { + if (Host.Current.IsRaspberryPi) + HighResolutionTimer.Sleep(delay); + else + Thread.Sleep((int)delay); + } + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/libbcm2835.so b/Raspberry.IO.GeneralPurpose/libbcm2835.so index 14ae6883b6346d66c22d3858022b3f890c24e698..567d0d0bf14fe6f14ba1938ffb136d833d5a81bb 100644 GIT binary patch literal 29819 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 From 71647923897d463a6b8a5fd3798c76ead744f2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 20:02:04 +0200 Subject: [PATCH 034/227] Added support for sub-millisecond poll interval --- .../GpioConnectionConfigurationSection.cs | 20 +++++++++++++++---- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs index d5a22c0..f91b0be 100644 --- a/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs +++ b/Raspberry.IO.GeneralPurpose/Configuration/GpioConnectionConfigurationSection.cs @@ -11,6 +11,15 @@ namespace Raspberry.IO.GeneralPurpose.Configuration /// public class GpioConnectionConfigurationSection : ConfigurationSection { + #region Constants + + /// + /// The default poll interval, in milliseconds. + /// + public const decimal DefaultPollInterval = 50.0m; + + #endregion + #region Properties /// @@ -45,11 +54,14 @@ public string BoardRevision /// /// The poll interval, in millisecond. /// - /// Default value is 50ms. - [ConfigurationProperty("pollInterval", DefaultValue = 50)] - public int PollInterval + /// + /// Default value is 50ms. + /// Values lower than 1ms may be specified on Raspberry Pi using decimal notation. + /// + [ConfigurationProperty("pollInterval", DefaultValue = "50")] + public decimal PollInterval { - get { return (int)this["pollInterval"]; } + get { return (decimal)this["pollInterval"]; } set { this["pollInterval"] = value; } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 7ff1f9f..9a56e50 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -100,7 +100,7 @@ public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable !string.IsNullOrEmpty(p.Name)).ToDictionary(p => p.Name); var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; - var pollInterval = configurationSection != null ? configurationSection.PollInterval : 50; + var pollInterval = configurationSection != null ? configurationSection.PollInterval : GpioConnectionConfigurationSection.DefaultPollInterval; timer = Timer.Create(); From b0ab4fca218891e88b6a3e67ed4059cba44fc892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 21:39:45 +0200 Subject: [PATCH 035/227] Read all input pins at once Dramatically improved performances --- .../FileGpioConnectionDriver.cs | 17 ++++++ Raspberry.IO.GeneralPurpose/GpioConnection.cs | 49 ++++++++++-------- .../IGpioConnectionDriver.cs | 7 +++ Raspberry.IO.GeneralPurpose/Interop.cs | 6 +++ .../MemoryGpioConnectionDriver.cs | 20 +++++++ .../ProcessorPinExtensionMethods.cs | 25 +++++++++ Raspberry.IO.GeneralPurpose/ProcessorPins.cs | 43 +++++++++++++++ .../Raspberry.IO.GeneralPurpose.csproj | 2 + Raspberry.IO.GeneralPurpose/libbcm2835.so | Bin 29819 -> 30169 bytes 9 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs create mode 100644 Raspberry.IO.GeneralPurpose/ProcessorPins.cs diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index e10868f..38ea83e 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Linq; #endregion @@ -65,6 +66,22 @@ public bool Read(ProcessorPin pin) } } + /// + /// Reads the status of the specified pins. + /// + /// The pins. + /// + /// The pins status. + /// + public ProcessorPins Read(ProcessorPins pins) + { + return pins.Enumerate() + .Select(p => Read(p) ? (ProcessorPins) ((uint) 1 << (int) p) : ProcessorPins.None) + .Aggregate( + ProcessorPins.None, + (a, p) => a | p); + } + /// /// Allocates the specified pin. /// diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 9a56e50..eaf347d 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -24,7 +24,9 @@ public class GpioConnection : IDisposable private readonly ITimer timer; private readonly Dictionary pinValues = new Dictionary(); private readonly Dictionary> pinEvents = new Dictionary>(); - private readonly Dictionary pinRawValues = new Dictionary(); + + private ProcessorPins inputPins = ProcessorPins.None; + private ProcessorPins pinRawValues = ProcessorPins.None; /// /// Gets the default blink duration, in milliseconds. @@ -239,8 +241,10 @@ public void Clear() pinConfigurations.Clear(); namedPins.Clear(); - pinRawValues.Clear(); pinValues.Clear(); + + pinRawValues = ProcessorPins.None; + inputPins = ProcessorPins.None; } } @@ -362,9 +366,11 @@ public void Remove(PinConfiguration configuration) pinConfigurations.Remove(configuration.Pin); if (!string.IsNullOrEmpty(configuration.Name)) namedPins.Remove(configuration.Name); - - pinRawValues.Remove(configuration.Pin); pinValues.Remove(configuration.Pin); + + var pin = (ProcessorPins)((uint)1 << (int)configuration.Pin); + inputPins = inputPins & ~pin; + pinRawValues = pinRawValues & ~pin; } } @@ -528,7 +534,10 @@ private void Allocate(PinConfiguration configuration) else { var pinValue = Driver.Read(configuration.Pin); - pinRawValues[configuration.Pin] = pinValue; + + var pin = (ProcessorPins)((uint)1 << (int)configuration.Pin); + inputPins = inputPins | pin; + pinRawValues = Driver.Read(inputPins); var switchConfiguration = configuration as SwitchInputPinConfiguration; if (switchConfiguration != null) @@ -564,44 +573,42 @@ private void Release(PinConfiguration configuration) private void CheckInputPins(object state, EventArgs eventArgs) { - Dictionary newPinValues; - - lock (pinConfigurations) - { - newPinValues = pinConfigurations.Values - .Where(p => p.Direction == PinDirection.Input) - .Select(p => new {p.Pin, Value = Driver.Read(p.Pin)}) - .ToDictionary(p => p.Pin, p => p.Value); - } + var newPinValues = Driver.Read(inputPins); + + var changes = newPinValues ^ pinRawValues; + if (changes == ProcessorPins.None) + return; var notifiedConfigurations = new List(); - foreach (var np in newPinValues) + foreach (var np in changes.Enumerate()) { - var oldPinValue = pinRawValues[np.Key]; - var newPinValue = np.Value; + var processorPin = (ProcessorPins) ((uint) 1 << (int) np); + var oldPinValue = (pinRawValues & processorPin) != ProcessorPins.None; + var newPinValue = (newPinValues & processorPin) != ProcessorPins.None; - pinRawValues[np.Key] = newPinValue; if (oldPinValue != newPinValue) { - var pin = (InputPinConfiguration) pinConfigurations[np.Key]; + var pin = (InputPinConfiguration) pinConfigurations[np]; var switchPin = pin as SwitchInputPinConfiguration; if (switchPin != null) { if (pin.GetEffective(newPinValue)) { - pinValues[np.Key] = !pinValues[np.Key]; + pinValues[np] = !pinValues[np]; notifiedConfigurations.Add(pin); } } else { - pinValues[np.Key] = pin.GetEffective(newPinValue); + pinValues[np] = pin.GetEffective(newPinValue); notifiedConfigurations.Add(pin); } } } + pinRawValues = newPinValues; + // Only fires events once all states have been modified. foreach (var pin in notifiedConfigurations) OnPinStatusChanged(new PinStatusEventArgs {Configuration = pin, Enabled = pinValues[pin.Pin]}); diff --git a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs index 02a9885..cd47c00 100644 --- a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs @@ -21,6 +21,13 @@ public interface IGpioConnectionDriver /// The pin status. bool Read(ProcessorPin pin); + /// + /// Reads the status of the specified pins. + /// + /// The pins. + /// The pins status. + ProcessorPins Read(ProcessorPins pins); + /// /// Allocates the specified pin. /// diff --git a/Raspberry.IO.GeneralPurpose/Interop.cs b/Raspberry.IO.GeneralPurpose/Interop.cs index f0dbc77..5596ad2 100644 --- a/Raspberry.IO.GeneralPurpose/Interop.cs +++ b/Raspberry.IO.GeneralPurpose/Interop.cs @@ -9,6 +9,12 @@ internal static class Interop [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")] public static extern int bcm2835_init(); + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_close")] + public static extern int bcm2835_close(); + + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpioperi_read")] + public static extern uint bcm2835_gpioperi_read(uint group); + [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_fsel")] public static extern void bcm2835_gpio_fsel(uint pin, uint mode); diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index bad2d51..bcb4bb2 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -52,8 +52,28 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { + var shift = (byte)((int)pin % 32); + var value = Interop.bcm2835_gpioperi_read((uint)pin / 32); + + return (value & (1 << shift)) != 0; + + /* var value = Interop.bcm2835_gpio_lev((uint)pin); return value != 0; + */ + } + + /// + /// Reads the status of the specified pins. + /// + /// The pins. + /// + /// The pins status. + /// + public ProcessorPins Read(ProcessorPins pins) + { + var value = Interop.bcm2835_gpioperi_read(0); + return (ProcessorPins)((uint)pins & value); } /// diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs new file mode 100644 index 0000000..da28767 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Provides extension methods for and objects. + /// + public static class ProcessorPinExtensionMethods + { + /// + /// Enumerates the specified pins. + /// + /// The pins. + /// The pins. + public static IEnumerable Enumerate(this ProcessorPins pins) + { + return (Enum.GetValues(typeof (ProcessorPin)) as ProcessorPin[]) + .Distinct() + .Where(p => (pins & (ProcessorPins) ((uint) 1 << (int) p)) != ProcessorPins.None) + .ToArray(); + } + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPins.cs b/Raspberry.IO.GeneralPurpose/ProcessorPins.cs new file mode 100644 index 0000000..cef0fe2 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/ProcessorPins.cs @@ -0,0 +1,43 @@ +using System; + +namespace Raspberry.IO.GeneralPurpose +{ + [Flags] + public enum ProcessorPins : uint + { + None = 0, + + Pin0 = 1 << 0, + Pin00 = Pin0, + Pin1 = 1 << 1, + Pin01 = Pin1, + Pin2 = 1 << 2, + Pin02 = Pin2, + Pin3 = 1 << 3, + Pin03 = Pin3, + Pin4 = 1 << 4, + Pin04 = Pin4, + Pin7 = 1 << 7, + Pin07 = Pin7, + Pin8 = 1 << 8, + Pin08 = Pin8, + Pin9 = 1 << 9, + Pin09 = Pin9, + Pin10 = 1 << 10, + Pin11 = 1 << 11, + Pin14 = 1 << 14, + Pin15 = 1 << 15, + Pin17 = 1 << 17, + Pin18 = 1 << 18, + Pin21 = 1 << 21, + Pin22 = 1 << 22, + Pin23 = 1 << 23, + Pin24 = 1 << 24, + Pin25 = 1 << 25, + Pin27 = 1 << 27, + Pin28 = 1 << 28, + Pin29 = 1 << 29, + Pin30 = 1 << 30, + Pin31 = (uint)1 << 31 + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 6819c5e..ebfeebc 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -48,6 +48,8 @@ + + diff --git a/Raspberry.IO.GeneralPurpose/libbcm2835.so b/Raspberry.IO.GeneralPurpose/libbcm2835.so index 567d0d0bf14fe6f14ba1938ffb136d833d5a81bb..3b62da41cf7363864afb2aa1078feca3ee3eadd4 100644 GIT binary patch literal 30169 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 literal 29819 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 Date: Tue, 23 Oct 2012 22:10:12 +0200 Subject: [PATCH 036/227] Improved performances for poll interval < 1ms --- .../Behaviors/PinsBehavior.cs | 11 ++-- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 4 +- .../Time/HighResolutionTimer.cs | 61 ++++++++++++++----- Raspberry.IO.GeneralPurpose/Time/ITimer.cs | 10 ++- .../Time/StandardTimer.cs | 18 +++++- 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs b/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs index 11f2ae8..8d7e624 100644 --- a/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs +++ b/Raspberry.IO.GeneralPurpose/Behaviors/PinsBehavior.cs @@ -1,9 +1,7 @@ #region References -using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using Raspberry.IO.GeneralPurpose.Time; #endregion @@ -32,8 +30,9 @@ protected PinsBehavior(IEnumerable configurations) { Configurations = configurations.ToArray(); - timer = new StandardTimer { Interval = 250 }; - timer.Elapsed += OnTimer; + timer = Timer.Create(); + timer.Interval = 250; + timer.Action = OnTimer; } #endregion @@ -111,12 +110,12 @@ internal void Stop() #region Private Helpers - private void OnTimer(object state, EventArgs eventArgs) + private void OnTimer() { ProcessStep(currentStep); if (!TryGetNextStep(ref currentStep)) { - Thread.Sleep(Interval); + Timer.Sleep(Interval); Stop(); } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index eaf347d..4e457f4 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -107,7 +107,7 @@ public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable + /// Starts this instance. + /// + /// The delay before the first occurence, in milliseconds. public void Start(decimal delay) { - thread = new Thread(ThreadProcess); + if (delay > uint.MaxValue / 1000) + throw new ArgumentOutOfRangeException("delay", delay, "Delay must be lower than or equal to uint.MaxValue / 1000"); - Sleep(delay); - thread.Start(); + lock (this) + { + if (thread == null) + { + this.delay = delay; + thread = new Thread(ThreadProcess); + thread.Start(); + } + } } public void Stop() { - thread.Abort(); - thread = null; + lock (this) + { + if (thread != null) + { + thread.Abort(); + thread = null; + } + } } - public event EventHandler Elapsed; - private void ThreadProcess() { - var currentThread = thread; - while (thread == currentThread) - { - Interop.bcm2835_delayMicroseconds((uint) interval*1000); + var thisThread = thread; - var elapsed = Elapsed; - elapsed(this, EventArgs.Empty); + Sleep(delay); + while (thread == thisThread) + { + (Action ?? NoOp)(); + Sleep(interval); } } + private void NoOp(){} + public static void Sleep(decimal delay) { - if (delay > uint.MaxValue / 1000) - throw new ArgumentOutOfRangeException("delay", delay, "Delay must be lower than or equal to uint.MaxValue / 1000"); - Interop.bcm2835_delayMicroseconds((uint)(delay * 1000)); } } diff --git a/Raspberry.IO.GeneralPurpose/Time/ITimer.cs b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs index f9a8e38..4747e84 100644 --- a/Raspberry.IO.GeneralPurpose/Time/ITimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs @@ -12,6 +12,14 @@ internal interface ITimer /// decimal Interval { get; set; } + /// + /// Gets or sets the action. + /// + /// + /// The action. + /// + Action Action { get; set; } + /// /// Starts this instance. /// @@ -22,7 +30,5 @@ internal interface ITimer /// Stops this instance. /// void Stop(); - - event EventHandler Elapsed; } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs index 4b345f3..e5572ca 100644 --- a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs @@ -5,6 +5,7 @@ namespace Raspberry.IO.GeneralPurpose.Time internal class StandardTimer : ITimer { private decimal interval; + private Action action; private bool isStarted; private System.Threading.Timer timer; @@ -19,6 +20,18 @@ public decimal Interval Start(0); } } + + public Action Action + { + get { return action; } + set + { + if (value == null) + Stop(); + + action = value; + } + } public void Start(decimal delay) { @@ -47,12 +60,11 @@ public void Stop() } } - public event EventHandler Elapsed; + private void NoOp(){} private void OnElapsed(object state) { - var elapsed = Elapsed; - elapsed(this, EventArgs.Empty); + (Action ?? NoOp)(); } } } \ No newline at end of file From 5b26ec67a5ecab4cc4c86e5311c911355c9d97d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 22:13:40 +0200 Subject: [PATCH 037/227] Updated readme.md and version --- README.md | 5 +++-- Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0e73d55..13f2b0d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Raspberry# IO is a .NET/Mono IO Library for Raspberry Pi. This project is an ini Current release is an early public release. Some features may not have been extensively tested. Raspberry# IO currently supports GPIO input/output. -Support for extended IO (such as support for I2C peripherals) is planned for future releases. +Support for extended IO (such as support for PWM or I2C peripherals) is planned for future releases. Programs using Raspberry# IO must be run with elevated privileges, for example the GpioTest console included in project: @@ -27,8 +27,9 @@ It currently support the following features: + Access to GPIO pins through memory (using [BCM2835 C Library](http://www.open.com.au/mikem/bcm2835/)) or file (native) drivers + Addressing through **processor pin number or connector pin number** + Giving custom name to pins for more readable code -+ Various Rapsberry Pi revisions, for now **Raspberry B rev1 and rev2**, including rev2 P5 connector ++ Various Raspberry Pi revisions, for now **Raspberry B rev1 and rev2**, including rev2 P5 connector + Easy-of-use, declarative configuration of pins. Ability to revert the meaning (1/0) of pins; ability to **use an input pin as a switch button** + Firing of **events when pin status change** (input as well as output) + **High-level behaviors** for output pins, including *blink*, *pattern* and *chaser* + Controlled use of resources using a IDisposable component ++ Support sub-millisecond polling of input pins diff --git a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs index 25e1bc3..62b7dbb 100644 --- a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs +++ b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] From d0191423ffe1656c87b0080515676a4e534c9afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 23 Oct 2012 22:21:31 +0200 Subject: [PATCH 038/227] Added description of bcm2835 customizations --- .../Raspberry.IO.GeneralPurpose.csproj | 1 + Raspberry.IO.GeneralPurpose/bcm2835-customizations.txt | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 Raspberry.IO.GeneralPurpose/bcm2835-customizations.txt diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index ebfeebc..d4f18b5 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -71,6 +71,7 @@ + Always diff --git a/Raspberry.IO.GeneralPurpose/bcm2835-customizations.txt b/Raspberry.IO.GeneralPurpose/bcm2835-customizations.txt new file mode 100644 index 0000000..3d1d195 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/bcm2835-customizations.txt @@ -0,0 +1,8 @@ +// bcm2835.h +extern uint32_t bcm2835_gpioperi_read(uint32_t group); + +// bcm2835.c +uint32_t bcm2835_gpioperi_read(uint32_t group){ + volatile uint32_t* paddr = gpio + BCM2835_GPLEV0/4 + group; + return bcm2835_peri_read(paddr); +} From bf3e8cbe1e067ac0b087a582989df0f2d687c468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 24 Oct 2012 00:33:01 +0200 Subject: [PATCH 039/227] Fixed an issue with empty pin list When creating GpioConnection with no pins in initializer --- Raspberry.IO.GeneralPurpose/Interop.cs | 25 +++++++++++++++++-- .../MemoryGpioConnectionDriver.cs | 20 ++++++++------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/Interop.cs b/Raspberry.IO.GeneralPurpose/Interop.cs index 5596ad2..bf87d51 100644 --- a/Raspberry.IO.GeneralPurpose/Interop.cs +++ b/Raspberry.IO.GeneralPurpose/Interop.cs @@ -4,13 +4,34 @@ namespace Raspberry.IO.GeneralPurpose { internal static class Interop { + private static readonly object lockObject = new object(); + private static int referenceCount; + + public static void Reference() + { + lock (lockObject) + { + if (referenceCount++ == 0) + bcm2835_init(); + } + } + + public static void Release() + { + lock (lockObject) + { + if (--referenceCount == 0) + bcm2835_close(); + } + } + #region Interop Methods [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")] - public static extern int bcm2835_init(); + private static extern int bcm2835_init(); [DllImport("libbcm2835.so", EntryPoint = "bcm2835_close")] - public static extern int bcm2835_close(); + private static extern int bcm2835_close(); [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpioperi_read")] public static extern uint bcm2835_gpioperi_read(uint group); diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index bcb4bb2..8a352d3 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -12,12 +12,6 @@ namespace Raspberry.IO.GeneralPurpose /// Based on bmc2835_gpio library. public class MemoryGpioConnectionDriver : IGpioConnectionDriver { - #region Fields - - private static readonly Lazy initialized = new Lazy(() => Interop.bcm2835_init() != 0); - - #endregion - #region Instance Management /// @@ -27,8 +21,19 @@ public MemoryGpioConnectionDriver() { if (!Host.Current.IsRaspberryPi) throw new NotSupportedException("MemoryGpioConnectionDriver is only supported on Raspberry Pi"); + + Interop.Reference(); } + /// + /// Releases unmanaged resources and performs other cleanup operations before the + /// is reclaimed by garbage collection. + /// + ~MemoryGpioConnectionDriver() + { + Interop.Release(); + } + #endregion #region Methods @@ -83,9 +88,6 @@ public ProcessorPins Read(ProcessorPins pins) /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - if (!initialized.Value) - throw new InvalidOperationException("Unabled to initialize driver"); - // Set the direction on the pin and update the exported list // BCM2835_GPIO_FSEL_INPT = 0 // BCM2835_GPIO_FSEL_OUTP = 1 From 2331613d036a4754f8c6fd0b68aa8a85b3e6861e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 24 Oct 2012 20:17:04 +0200 Subject: [PATCH 040/227] Fixed deadlock in PinsBehavior --- Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs index 55666e3..ed2e203 100644 --- a/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs @@ -66,7 +66,8 @@ public void Stop() { if (thread != null) { - thread.Abort(); + if (thread != Thread.CurrentThread) + thread.Abort(); thread = null; } } From a79aa0ff78d445054f0fdde0b6839e1285cd8ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 24 Oct 2012 20:36:10 +0200 Subject: [PATCH 041/227] Added comments and regions --- .../Time/HighResolutionTimer.cs | 52 ++++++++++++++++--- Raspberry.IO.GeneralPurpose/Time/ITimer.cs | 12 +++++ .../Time/StandardTimer.cs | 43 ++++++++++++++- Raspberry.IO.GeneralPurpose/Time/Timer.cs | 27 ++++++++-- 4 files changed, 122 insertions(+), 12 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs index ed2e203..ada0ac7 100644 --- a/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs @@ -1,33 +1,60 @@ +#region References + using System; using System.Threading; +#endregion + namespace Raspberry.IO.GeneralPurpose.Time { internal class HighResolutionTimer : ITimer { + #region Fields + private decimal delay; private decimal interval; + private Action action; + private Thread thread; + #endregion + + #region Instance Management + public HighResolutionTimer() { if (!Host.Current.IsRaspberryPi) throw new NotSupportedException("Cannot use HighResolutionTimer on a platform different than Raspberry Pi"); } + #endregion + + #region Properties + + /// + /// Gets or sets the interval, in milliseconds. + /// + /// + /// The interval, in milliseconds. + /// public decimal Interval { get { return interval; } set { - if (value > uint.MaxValue / 1000) + if (value > uint.MaxValue/1000) throw new ArgumentOutOfRangeException("Interval", interval, "Interval must be lower than or equal to uint.MaxValue / 1000"); interval = value; } } - private Action action; + /// + /// Gets or sets the action. + /// + /// + /// The action. + /// public Action Action { get { return action; } @@ -35,18 +62,22 @@ public Action Action { if (value == null) Stop(); - + action = value; } } + #endregion + + #region Methods + /// /// Starts this instance. /// /// The delay before the first occurence, in milliseconds. public void Start(decimal delay) { - if (delay > uint.MaxValue / 1000) + if (delay > uint.MaxValue/1000) throw new ArgumentOutOfRangeException("delay", delay, "Delay must be lower than or equal to uint.MaxValue / 1000"); lock (this) @@ -59,7 +90,10 @@ public void Start(decimal delay) } } } - + + /// + /// Stops this instance. + /// public void Stop() { lock (this) @@ -73,6 +107,10 @@ public void Stop() } } + #endregion + + #region Private Helpers + private void ThreadProcess() { var thisThread = thread; @@ -89,7 +127,9 @@ private void NoOp(){} public static void Sleep(decimal delay) { - Interop.bcm2835_delayMicroseconds((uint)(delay * 1000)); + Interop.bcm2835_delayMicroseconds((uint) (delay*1000)); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/ITimer.cs b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs index 4747e84..8acc571 100644 --- a/Raspberry.IO.GeneralPurpose/Time/ITimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/ITimer.cs @@ -1,9 +1,15 @@ +#region References + using System; +#endregion + namespace Raspberry.IO.GeneralPurpose.Time { internal interface ITimer { + #region Properties + /// /// Gets or sets the interval, in milliseconds. /// @@ -20,6 +26,10 @@ internal interface ITimer /// Action Action { get; set; } + #endregion + + #region Methods + /// /// Starts this instance. /// @@ -30,5 +40,7 @@ internal interface ITimer /// Stops this instance. /// void Stop(); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs index e5572ca..8ebefa9 100644 --- a/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs @@ -1,15 +1,31 @@ +#region References + using System; +#endregion + namespace Raspberry.IO.GeneralPurpose.Time { internal class StandardTimer : ITimer { + #region Fields + private decimal interval; private Action action; private bool isStarted; private System.Threading.Timer timer; + #endregion + + #region Properties + + /// + /// Gets or sets the interval, in milliseconds. + /// + /// + /// The interval, in milliseconds. + /// public decimal Interval { get { return interval; } @@ -20,7 +36,13 @@ public decimal Interval Start(0); } } - + + /// + /// Gets or sets the action. + /// + /// + /// The action. + /// public Action Action { get { return action; } @@ -33,6 +55,14 @@ public Action Action } } + #endregion + + #region Methods + + /// + /// Starts this instance. + /// + /// The delay before the first occurence, in milliseconds. public void Start(decimal delay) { lock (this) @@ -40,13 +70,16 @@ public void Start(decimal delay) if (!isStarted && interval >= 1.0m) { isStarted = true; - timer = new System.Threading.Timer(OnElapsed, null, (int)delay, (int)interval); + timer = new System.Threading.Timer(OnElapsed, null, (int) delay, (int) interval); } else Stop(); } } + /// + /// Stops this instance. + /// public void Stop() { lock (this) @@ -60,11 +93,17 @@ public void Stop() } } + #endregion + + #region Private Helpers + private void NoOp(){} private void OnElapsed(object state) { (Action ?? NoOp)(); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Time/Timer.cs b/Raspberry.IO.GeneralPurpose/Time/Timer.cs index 8dbbf23..8191a10 100644 --- a/Raspberry.IO.GeneralPurpose/Time/Timer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/Timer.cs @@ -1,22 +1,41 @@ +#region References + using System.Threading; +#endregion + namespace Raspberry.IO.GeneralPurpose.Time { internal static class Timer { + #region Methods + + /// + /// Creates a timer. + /// + /// The timer. + /// + /// The created timer is the most suitable for the current platform. + /// public static ITimer Create() { return Host.Current.IsRaspberryPi - ? (ITimer)new HighResolutionTimer() + ? (ITimer) new HighResolutionTimer() : new StandardTimer(); } - public static void Sleep(decimal delay) + /// + /// Sleeps during the specified time. + /// + /// The time, in milliseconds. + public static void Sleep(decimal time) { if (Host.Current.IsRaspberryPi) - HighResolutionTimer.Sleep(delay); + HighResolutionTimer.Sleep(time); else - Thread.Sleep((int)delay); + Thread.Sleep((int) time); } + + #endregion } } \ No newline at end of file From f4ed52278e44c1cc12400666d1eb7516b34fd040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 24 Oct 2012 23:01:09 +0200 Subject: [PATCH 042/227] Introduced SPI Sample Based on MCP3008 ic Renamed GpioTest to Gpio.Test.Chaser --- {GpioTest => Gpio.Test.Chaser}/Board.cs | 2 +- .../Gpio.Test.Chaser.csproj | 4 +- {GpioTest => Gpio.Test.Chaser}/Helpers.cs | 2 +- {GpioTest => Gpio.Test.Chaser}/Program.cs | 3 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/GPIO-Chaser.fzz | Bin .../Properties/GPIO-Chaser.png | Bin {GpioTest => Gpio.Test.Chaser}/app.config | 0 Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 62 ++++++++++++ Gpio.Test.MCP3008/Program.cs | 94 ++++++++++++++++++ Gpio.Test.MCP3008/Properties/AssemblyInfo.cs | 36 +++++++ Gpio.Test.MCP3008/app.config | 15 +++ RaspberrySharp.IO.sln | 26 ++++- 13 files changed, 238 insertions(+), 10 deletions(-) rename {GpioTest => Gpio.Test.Chaser}/Board.cs (99%) rename GpioTest/GpioTest.csproj => Gpio.Test.Chaser/Gpio.Test.Chaser.csproj (97%) rename {GpioTest => Gpio.Test.Chaser}/Helpers.cs (98%) rename {GpioTest => Gpio.Test.Chaser}/Program.cs (99%) rename {GpioTest => Gpio.Test.Chaser}/Properties/AssemblyInfo.cs (93%) rename {GpioTest => Gpio.Test.Chaser}/Properties/GPIO-Chaser.fzz (100%) rename {GpioTest => Gpio.Test.Chaser}/Properties/GPIO-Chaser.png (100%) rename {GpioTest => Gpio.Test.Chaser}/app.config (100%) create mode 100644 Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj create mode 100644 Gpio.Test.MCP3008/Program.cs create mode 100644 Gpio.Test.MCP3008/Properties/AssemblyInfo.cs create mode 100644 Gpio.Test.MCP3008/app.config diff --git a/GpioTest/Board.cs b/Gpio.Test.Chaser/Board.cs similarity index 99% rename from GpioTest/Board.cs rename to Gpio.Test.Chaser/Board.cs index cc3d011..13d4ad7 100644 --- a/GpioTest/Board.cs +++ b/Gpio.Test.Chaser/Board.cs @@ -7,7 +7,7 @@ #endregion -namespace GpioTest +namespace Gpio.Test.Chaser { /// /// Represents the Raspberry Pi mainboard. diff --git a/GpioTest/GpioTest.csproj b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj similarity index 97% rename from GpioTest/GpioTest.csproj rename to Gpio.Test.Chaser/Gpio.Test.Chaser.csproj index b178dcc..c6addff 100644 --- a/GpioTest/GpioTest.csproj +++ b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj @@ -8,8 +8,8 @@ {5D9D1834-4C4B-4E03-B635-5F205205B6F8} Exe Properties - GpioTest - GpioTest + Gpio.Test.Chaser + Gpio.Test.Chaser v4.0 diff --git a/GpioTest/Helpers.cs b/Gpio.Test.Chaser/Helpers.cs similarity index 98% rename from GpioTest/Helpers.cs rename to Gpio.Test.Chaser/Helpers.cs index e6c59cf..85d9528 100644 --- a/GpioTest/Helpers.cs +++ b/Gpio.Test.Chaser/Helpers.cs @@ -3,7 +3,7 @@ using System.Linq; using Raspberry.IO.GeneralPurpose; -namespace GpioTest +namespace Gpio.Test.Chaser { internal static class Helpers { diff --git a/GpioTest/Program.cs b/Gpio.Test.Chaser/Program.cs similarity index 99% rename from GpioTest/Program.cs rename to Gpio.Test.Chaser/Program.cs index c7bfcbb..3a1b230 100644 --- a/GpioTest/Program.cs +++ b/Gpio.Test.Chaser/Program.cs @@ -1,10 +1,9 @@ using System; -using System.Linq; using System.Threading; using Raspberry.IO.GeneralPurpose; using Raspberry.IO.GeneralPurpose.Behaviors; -namespace GpioTest +namespace Gpio.Test.Chaser { /// /// This is a sample program. Must be modified to match your GPIO project. diff --git a/GpioTest/Properties/AssemblyInfo.cs b/Gpio.Test.Chaser/Properties/AssemblyInfo.cs similarity index 93% rename from GpioTest/Properties/AssemblyInfo.cs rename to Gpio.Test.Chaser/Properties/AssemblyInfo.cs index b4912b8..a4d1f83 100644 --- a/GpioTest/Properties/AssemblyInfo.cs +++ b/Gpio.Test.Chaser/Properties/AssemblyInfo.cs @@ -4,11 +4,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("GpioTest")] +[assembly: AssemblyTitle("Gpio.Test.Chaser")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GpioTest")] +[assembly: AssemblyProduct("Gpio.Test.Chaser")] [assembly: AssemblyCopyright("Copyright © 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/GpioTest/Properties/GPIO-Chaser.fzz b/Gpio.Test.Chaser/Properties/GPIO-Chaser.fzz similarity index 100% rename from GpioTest/Properties/GPIO-Chaser.fzz rename to Gpio.Test.Chaser/Properties/GPIO-Chaser.fzz diff --git a/GpioTest/Properties/GPIO-Chaser.png b/Gpio.Test.Chaser/Properties/GPIO-Chaser.png similarity index 100% rename from GpioTest/Properties/GPIO-Chaser.png rename to Gpio.Test.Chaser/Properties/GPIO-Chaser.png diff --git a/GpioTest/app.config b/Gpio.Test.Chaser/app.config similarity index 100% rename from GpioTest/app.config rename to Gpio.Test.Chaser/app.config diff --git a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj new file mode 100644 index 0000000..675a165 --- /dev/null +++ b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj @@ -0,0 +1,62 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {B28253A7-BB93-40F7-B41C-B4AE369174ED} + Exe + Properties + Gpio.Test.MCP3008 + Gpio.Test.MCP3008 + v4.0 + + + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + + + + + + \ No newline at end of file diff --git a/Gpio.Test.MCP3008/Program.cs b/Gpio.Test.MCP3008/Program.cs new file mode 100644 index 0000000..ae1ec80 --- /dev/null +++ b/Gpio.Test.MCP3008/Program.cs @@ -0,0 +1,94 @@ +using System; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +namespace Gpio.Test.MCP3008 +{ + /// + /// Freely adapted from http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/overview + /// + class Program + { + static void Main(string[] args) + { + const ProcessorPin spiClock = ProcessorPin.Pin18; + const ProcessorPin spiMiso = ProcessorPin.Pin23; + const ProcessorPin spiMosi = ProcessorPin.Pin24; + const ProcessorPin spiCs = ProcessorPin.Pin25; + + var pins = new PinConfiguration[] + { + spiClock.Output().Name("Clock"), + spiCs.Output().Name("Cs").Enable(), + spiMosi.Output().Name("Mosi"), + spiMiso.Input().Name("Miso") + }; + + Console.CursorVisible = false; + Console.WriteLine(); + Console.WriteLine(); + + using (var connection = new GpioConnection(pins)) + { + while (!Console.KeyAvailable) + { + var volts = ReadSpiData(connection, 0, 3.3m); + var temperature = 100*volts - 50; + + volts = ReadSpiData(connection, 1, 3.3m); + // See http://learn.adafruit.com/photocells/using-a-photocell + var photo = volts != 0 + ? 10000*(3.3m - volts)/volts + : 0; + + Console.CursorTop--; + Console.WriteLine("Tc = {0,5:0.0} Celsius\t\tLr = {1,7:0} Ohms", temperature, photo); + Thread.Sleep(150); + } + } + + Console.CursorVisible = true; + } + + private static decimal ReadSpiData(GpioConnection connection, int channel, decimal tension) + { + connection["Cs"] = false; + try + { + var command = channel; + command |= 0x18; // start bit + single-ended bit + command = command << 3; // we only need to send 5 bits here + + for (var i = 0; i < 5; i++) + { + connection["Mosi"] = (command & 0x80) != 0; + + connection.Blink("Clock", 1); + command = command << 1; + } + + var data = 0; + // read in one empty bit, one null bit and 10 ADC bits + for (var i = 0; i < 12; i++) + { + connection.Blink("Clock", 1); + + Thread.Sleep(25); + + data = data << 1; + if (connection["Miso"]) + data |= 0x1; + } + + // first bit is 'null', drop it + data = data >> 1; + + return data * tension / 1023m; + } + finally + { + connection["Cs"] = true; + } + } + } +} diff --git a/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs b/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c6e8c68 --- /dev/null +++ b/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Gpio.Test.MCP3008")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Gpio.Test.MCP3008")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("72ce3a1e-982d-4a8f-bb3c-422d7c00b816")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Gpio.Test.MCP3008/app.config b/Gpio.Test.MCP3008/app.config new file mode 100644 index 0000000..d3e73c6 --- /dev/null +++ b/Gpio.Test.MCP3008/app.config @@ -0,0 +1,15 @@ + + + +
+ + + + + + + + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 59a4612..3949477 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GpioTest", "GpioTest\GpioTest.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" ProjectSection(SolutionItems) = preProject Icon.png = Icon.png @@ -12,26 +10,50 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP3008", "Gpio.Test.MCP3008\Gpio.Test.MCP3008.csproj", "{B28253A7-BB93-40F7-B41C-B4AE369174ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.Chaser", "Gpio.Test.Chaser\Gpio.Test.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|x86.ActiveCfg = Debug|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Mixed Platforms.Build.0 = Release|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|x86.ActiveCfg = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|x86.ActiveCfg = Debug|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|x86.Build.0 = Debug|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Mixed Platforms.Build.0 = Release|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|x86.ActiveCfg = Release|x86 + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|x86.Build.0 = Release|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|x86.ActiveCfg = Debug|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|x86.Build.0 = Debug|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.ActiveCfg = Release|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.Build.0 = Release|x86 EndGlobalSection From a1e85a21906e0ba1e8e1172076594fab692c7bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 00:04:27 +0200 Subject: [PATCH 043/227] Introducing GpioConnectionSettings --- Gpio.Test.Chaser/Program.cs | 8 +- Gpio.Test.MCP3008/Convert.cs | 19 +++ Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 3 + Gpio.Test.MCP3008/Program.cs | 88 +++--------- Gpio.Test.MCP3008/SpiChannel.cs | 14 ++ Gpio.Test.MCP3008/SpiConnection.cs | 95 +++++++++++++ Raspberry.IO.GeneralPurpose.nuspec | 4 +- Raspberry.IO.GeneralPurpose/ConnectedPin.cs | 2 +- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 94 ++++--------- .../GpioConnectionSettings.cs | 125 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 4 +- .../Raspberry.IO.GeneralPurpose.csproj | 1 + Raspberry.IO.GeneralPurpose/Time/Timer.cs | 5 +- 13 files changed, 319 insertions(+), 143 deletions(-) create mode 100644 Gpio.Test.MCP3008/Convert.cs create mode 100644 Gpio.Test.MCP3008/SpiChannel.cs create mode 100644 Gpio.Test.MCP3008/SpiConnection.cs create mode 100644 Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs diff --git a/Gpio.Test.Chaser/Program.cs b/Gpio.Test.Chaser/Program.cs index 3a1b230..37553e1 100644 --- a/Gpio.Test.Chaser/Program.cs +++ b/Gpio.Test.Chaser/Program.cs @@ -74,10 +74,12 @@ static void Main(string[] args) // Create connection Console.WriteLine("Running on Raspberry firmware rev{0}, board rev{1}, processor {2}", mainboard.Firmware, mainboard.Revision, mainboard.Processor); - - using (var connection = new GpioConnection(driver, leds)) + + var settings = new GpioConnectionSettings {Driver = driver}; + + using (var connection = new GpioConnection(settings, leds)) { - Console.WriteLine("Using {0}, frequency {1:0.##}hz", connection.Driver.GetType().Name, 1000.0/args.GetSpeed()); + Console.WriteLine("Using {0}, frequency {1:0.##}hz", settings.Driver.GetType().Name, 1000.0/args.GetSpeed()); Thread.Sleep(1000); diff --git a/Gpio.Test.MCP3008/Convert.cs b/Gpio.Test.MCP3008/Convert.cs new file mode 100644 index 0000000..bce4324 --- /dev/null +++ b/Gpio.Test.MCP3008/Convert.cs @@ -0,0 +1,19 @@ +namespace Gpio.Test.MCP3008 +{ + internal static class Convert + { + public static decimal ToCelsius(this decimal volts) + { + // See http://learn.adafruit.com/send-raspberry-pi-data-to-cosm + return 100 * volts - 50; + } + + public static decimal ToOhms(this decimal volts) + { + // See http://learn.adafruit.com/photocells/using-a-photocell + return volts != 0 + ? 10000 * (3.3m - volts) / volts + : 0; + } + } +} \ No newline at end of file diff --git a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj index 675a165..a034bdd 100644 --- a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj +++ b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj @@ -39,8 +39,11 @@ + + + diff --git a/Gpio.Test.MCP3008/Program.cs b/Gpio.Test.MCP3008/Program.cs index ae1ec80..1e0fe0a 100644 --- a/Gpio.Test.MCP3008/Program.cs +++ b/Gpio.Test.MCP3008/Program.cs @@ -1,94 +1,48 @@ -using System; +#region References + +using System; using System.Threading; using Raspberry.IO.GeneralPurpose; +#endregion + namespace Gpio.Test.MCP3008 { /// /// Freely adapted from http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/overview + /// Connected pins are the same as in the original sample. /// class Program { static void Main(string[] args) { - const ProcessorPin spiClock = ProcessorPin.Pin18; - const ProcessorPin spiMiso = ProcessorPin.Pin23; - const ProcessorPin spiMosi = ProcessorPin.Pin24; - const ProcessorPin spiCs = ProcessorPin.Pin25; - - var pins = new PinConfiguration[] - { - spiClock.Output().Name("Clock"), - spiCs.Output().Name("Cs").Enable(), - spiMosi.Output().Name("Mosi"), - spiMiso.Input().Name("Miso") - }; + var clock = ConnectorPin.P1Pin12.ToProcessor(); + var miso = ConnectorPin.P1Pin16.ToProcessor(); + var mosi = ConnectorPin.P1Pin18.ToProcessor(); + var cs = ConnectorPin.P1Pin22.ToProcessor(); - Console.CursorVisible = false; - Console.WriteLine(); - Console.WriteLine(); + const decimal voltage = 3.3m; - using (var connection = new GpioConnection(pins)) + using (var connection = new SpiConnection(clock, cs, miso, mosi, voltage)) { + Console.CursorVisible = false; + Console.WriteLine("MCP3008 Sample: Reading temperature on Channel 0 and light resistor on Channel 1"); + Console.WriteLine(); + while (!Console.KeyAvailable) { - var volts = ReadSpiData(connection, 0, 3.3m); - var temperature = 100*volts - 50; - - volts = ReadSpiData(connection, 1, 3.3m); - // See http://learn.adafruit.com/photocells/using-a-photocell - var photo = volts != 0 - ? 10000*(3.3m - volts)/volts - : 0; + var temperature = connection.Read(SpiChannel.Channel0).ToCelsius(); + var lightResistor = connection.Read(SpiChannel.Channel1).ToOhms(); + Console.WriteLine("Tc = {0,5:0.0} Celsius\t\tLr = {1,7:0} Ohms", temperature, lightResistor); Console.CursorTop--; - Console.WriteLine("Tc = {0,5:0.0} Celsius\t\tLr = {1,7:0} Ohms", temperature, photo); + Thread.Sleep(150); } } + Console.CursorTop++; Console.CursorVisible = true; } - - private static decimal ReadSpiData(GpioConnection connection, int channel, decimal tension) - { - connection["Cs"] = false; - try - { - var command = channel; - command |= 0x18; // start bit + single-ended bit - command = command << 3; // we only need to send 5 bits here - - for (var i = 0; i < 5; i++) - { - connection["Mosi"] = (command & 0x80) != 0; - - connection.Blink("Clock", 1); - command = command << 1; - } - - var data = 0; - // read in one empty bit, one null bit and 10 ADC bits - for (var i = 0; i < 12; i++) - { - connection.Blink("Clock", 1); - - Thread.Sleep(25); - - data = data << 1; - if (connection["Miso"]) - data |= 0x1; - } - - // first bit is 'null', drop it - data = data >> 1; - - return data * tension / 1023m; - } - finally - { - connection["Cs"] = true; - } - } } } diff --git a/Gpio.Test.MCP3008/SpiChannel.cs b/Gpio.Test.MCP3008/SpiChannel.cs new file mode 100644 index 0000000..4ccea06 --- /dev/null +++ b/Gpio.Test.MCP3008/SpiChannel.cs @@ -0,0 +1,14 @@ +namespace Gpio.Test.MCP3008 +{ + public enum SpiChannel + { + Channel0 = 0, + Channel1 = 1, + Channel2 = 2, + Channel3 = 3, + Channel4 = 4, + Channel5 = 5, + Channel6 = 6, + Channel7 = 7 + } +} \ No newline at end of file diff --git a/Gpio.Test.MCP3008/SpiConnection.cs b/Gpio.Test.MCP3008/SpiConnection.cs new file mode 100644 index 0000000..a00fc09 --- /dev/null +++ b/Gpio.Test.MCP3008/SpiConnection.cs @@ -0,0 +1,95 @@ +#region References + +using System; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +#endregion + +namespace Gpio.Test.MCP3008 +{ + public class SpiConnection : IDisposable + { + #region Fields + + private readonly GpioConnection connection; + private readonly decimal referenceVoltage; + + #endregion + + #region Instance Management + + public SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin miso, ProcessorPin mosi, decimal referenceVoltage) + { + this.referenceVoltage = referenceVoltage; + + var settings = new GpioConnectionSettings {PollInterval = 10, BlinkDuration = 0}; + var pins = new PinConfiguration[] + { + clock.Output().Name("Clock"), + cs.Output().Name("Cs").Enable(), + mosi.Output().Name("Mosi"), + miso.Input().Name("Miso") + }; + + connection = new GpioConnection(settings, pins); + } + + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + public decimal Read(SpiChannel channel) + { + connection["Cs"] = false; + try + { + var command = (int) channel; + command |= 0x18; // start bit + single-ended bit + command = command << 3; // we only need to send 5 bits here + + for (var i = 0; i < 5; i++) + { + connection["Mosi"] = (command & 0x80) != 0; + + connection.Blink("Clock"); + command = command << 1; + } + + var data = 0; + // read in one empty bit, one null bit and 10 ADC bits + for (var i = 0; i < 12; i++) + { + connection.Blink("Clock"); + + Thread.Sleep(25); + + data = data << 1; + if (connection["Miso"]) + data |= 0x1; + } + + // first bit is 'null', drop it + data = data >> 1; + + return data*referenceVoltage/1023m; + } + finally + { + connection["Cs"] = true; + } + } + + public void Close() + { + connection.Close(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index 6faf114..94432f0 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -13,7 +13,9 @@ Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. It is an initiative of the Raspberry# Community, aimed at providing tools and information concerning use of Raspberry Pi boards with Mono/.NET framework. - Parts of this work are based on BCM2835 C library (http://www.open.com.au/mikem/bcm2835/) + Parts of this work are based on [BCM2835 C library](http://www.open.com.au/mikem/bcm2835/). + + Visit project [Github site](https://github.com/raspberry-sharp/raspberry-sharp-io/) for documentation and samples. Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. en-US diff --git a/Raspberry.IO.GeneralPurpose/ConnectedPin.cs b/Raspberry.IO.GeneralPurpose/ConnectedPin.cs index 309775c..4256157 100644 --- a/Raspberry.IO.GeneralPurpose/ConnectedPin.cs +++ b/Raspberry.IO.GeneralPurpose/ConnectedPin.cs @@ -64,7 +64,7 @@ public void Toggle() /// Blinks the pin. ///
/// The blink duration, in millisecond. - public void Blink(int duration = GpioConnection.DefaultBlinkDuration) + public void Blink(decimal duration = -1) { connection.Blink(Configuration, duration); } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 4e457f4..10c3fe6 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -2,9 +2,7 @@ using System; using System.Collections.Generic; -using System.Configuration; using System.Linq; -using Raspberry.IO.GeneralPurpose.Configuration; using Raspberry.IO.GeneralPurpose.Time; #endregion @@ -18,6 +16,8 @@ public class GpioConnection : IDisposable { #region Fields + private readonly GpioConnectionSettings settings; + private readonly Dictionary pinConfigurations; private readonly Dictionary namedPins; @@ -28,11 +28,6 @@ public class GpioConnection : IDisposable private ProcessorPins inputPins = ProcessorPins.None; private ProcessorPins pinRawValues = ProcessorPins.None; - /// - /// Gets the default blink duration, in milliseconds. - /// - public const int DefaultBlinkDuration = 250; - #endregion #region Instance Management @@ -41,59 +36,29 @@ public class GpioConnection : IDisposable /// Initializes a new instance of the class. ///
/// The pins. - public GpioConnection(params PinConfiguration[] pins) : this(true, null, (IEnumerable) pins){} - - /// - /// Initializes a new instance of the class. - /// - /// The pins. - public GpioConnection(IEnumerable pins) : this(true, null, pins){} - - /// - /// Initializes a new instance of the class. - /// - /// The driver. - /// The pins. - public GpioConnection(IGpioConnectionDriver driver, params PinConfiguration[] pins) : this(true, driver, (IEnumerable) pins){} - - /// - /// Initializes a new instance of the class. - /// - /// The driver. - /// The pins. - public GpioConnection(IGpioConnectionDriver driver, IEnumerable pins) : this(true, driver, pins){} - - /// - /// Initializes a new instance of the class. - /// - /// if set to true, connection is opened on creation. - /// The pins. - public GpioConnection(bool open, params PinConfiguration[] pins) : this(open, null, (IEnumerable) pins){} + public GpioConnection(params PinConfiguration[] pins) : this(null, (IEnumerable) pins){} /// /// Initializes a new instance of the class. /// - /// if set to true, connection is opened on creation. - /// The driver. /// The pins. - public GpioConnection(bool open, IGpioConnectionDriver driver, params PinConfiguration[] pins) : this(open, driver, (IEnumerable) pins){} + public GpioConnection(IEnumerable pins) : this(null, pins){} /// /// Initializes a new instance of the class. /// - /// if set to true, connection is opened on creation. + /// The settings. /// The pins. - public GpioConnection(bool open, IEnumerable pins) : this(open, null, pins){} + public GpioConnection(GpioConnectionSettings settings, params PinConfiguration[] pins) : this(settings, (IEnumerable) pins){} /// /// Initializes a new instance of the class. /// - /// if set to true, connection is opened on creation. - /// The driver. + /// The settings. /// The pins. - public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable pins) + public GpioConnection(GpioConnectionSettings settings, IEnumerable pins) { - Driver = driver ?? GetDefaultDriver(); + this.settings = settings ?? new GpioConnectionSettings(); Pins = new ConnectedPins(this); var pinList = pins.ToList(); @@ -101,15 +66,12 @@ public GpioConnection(bool open, IGpioConnectionDriver driver, IEnumerable !string.IsNullOrEmpty(p.Name)).ToDictionary(p => p.Name); - var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; - var pollInterval = configurationSection != null ? configurationSection.PollInterval : GpioConnectionConfigurationSection.DefaultPollInterval; - timer = Timer.Create(); - timer.Interval = pollInterval; + timer.Interval = this.settings.PollInterval; timer.Action = CheckInputPins; - if (open) + if (this.settings.Opened) Open(); } @@ -130,11 +92,6 @@ void IDisposable.Dispose() /// public bool IsOpened { get; private set; } - /// - /// Gets the driver. - /// - public IGpioConnectionDriver Driver { get; private set; } - /// /// Gets or sets the status of the pin having the specified name. /// @@ -415,10 +372,10 @@ public void Toggle(PinConfiguration configuration) ///
/// Name of the pin. /// The duration, in millisecond. - public void Blink(string pinName, int duration = DefaultBlinkDuration) + public void Blink(string pinName, decimal duration = -1) { Toggle(pinName); - Timer.Sleep(duration); + Sleep(duration); Toggle(pinName); } @@ -427,10 +384,10 @@ public void Blink(string pinName, int duration = DefaultBlinkDuration) ///
/// The pin. /// The duration, in millisecond. - public void Blink(ProcessorPin pin, int duration = DefaultBlinkDuration) + public void Blink(ProcessorPin pin, decimal duration = -1) { Toggle(pin); - Timer.Sleep(duration); + Sleep(duration); Toggle(pin); } @@ -439,10 +396,10 @@ public void Blink(ProcessorPin pin, int duration = DefaultBlinkDuration) ///
/// The pin. /// The duration, in millisecond. - public void Blink(ConnectorPin pin, int duration = DefaultBlinkDuration) + public void Blink(ConnectorPin pin, decimal duration = -1) { Toggle(pin); - Timer.Sleep(duration); + Sleep(duration); Toggle(pin); } @@ -451,10 +408,10 @@ public void Blink(ConnectorPin pin, int duration = DefaultBlinkDuration) ///
/// The pin configuration. /// The duration, in millisecond. - public void Blink(PinConfiguration configuration, int duration = DefaultBlinkDuration) + public void Blink(PinConfiguration configuration, decimal duration = -1) { Toggle(configuration); - Timer.Sleep(duration); + Sleep(duration); Toggle(configuration); } @@ -505,13 +462,14 @@ internal IEnumerable Configurations #region Private Helpers - private static IGpioConnectionDriver GetDefaultDriver() + private IGpioConnectionDriver Driver { - var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; - if (configurationSection != null && !string.IsNullOrEmpty(configurationSection.DriverTypeName)) - return (IGpioConnectionDriver) Activator.CreateInstance(Type.GetType(configurationSection.DriverTypeName, true)); - else - return new MemoryGpioConnectionDriver(); + get { return settings.Driver; } + } + + private void Sleep(decimal duration) + { + Timer.Sleep(duration < 0 ? settings.BlinkDuration : duration); } private void Allocate(PinConfiguration configuration) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs new file mode 100644 index 0000000..6481b15 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs @@ -0,0 +1,125 @@ +#region References + +using System; +using System.Configuration; +using Raspberry.IO.GeneralPurpose.Configuration; + +#endregion + +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents settings for . + /// + public class GpioConnectionSettings + { + #region Fields + + private decimal blinkDuration; + private IGpioConnectionDriver driver; + private decimal pollInterval; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + public GpioConnectionSettings() + { + Driver = DefaultDriver; + BlinkDuration = DefaultBlinkDuration; + PollInterval = DefaultPollInterval; + Opened = true; + } + + #endregion + + #region Constants + + /// + /// Gets the default blink duration, in milliseconds. + /// + public const int DefaultBlinkDuration = 250; + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether this is opened on initialization. + /// + /// + /// true if opened on initialization; otherwise, false. + /// + public bool Opened { get; set; } + + /// + /// Gets or sets the duration of the blink. + /// + /// + /// The duration of the blink, in milliseconds. + /// + public decimal BlinkDuration + { + get { return blinkDuration; } + set { blinkDuration = value >= 0 ? value : DefaultBlinkDuration; } + } + + /// + /// Gets or sets the driver. + /// + /// + /// The driver. + /// + public IGpioConnectionDriver Driver + { + get { return driver; } + set { driver = value ?? DefaultDriver; } + } + + /// + /// Gets or sets the poll interval. + /// + /// + /// The poll interval, in milliseconds. + /// + public decimal PollInterval + { + get { return pollInterval; } + set { pollInterval = value >= 0 ? value : DefaultPollInterval; } + } + + /// + /// Gets the default poll interval, in milliseconds. + /// + public static decimal DefaultPollInterval + { + get + { + var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; + return configurationSection != null + ? configurationSection.PollInterval + : GpioConnectionConfigurationSection.DefaultPollInterval; + + } + } + + /// + /// Gets the default driver. + /// + public static IGpioConnectionDriver DefaultDriver + { + get + { + var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; + return configurationSection != null && !String.IsNullOrEmpty(configurationSection.DriverTypeName) + ? (IGpioConnectionDriver) Activator.CreateInstance(Type.GetType(configurationSection.DriverTypeName, true)) + : new MemoryGpioConnectionDriver(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs index 62b7dbb..bc6213f 100644 --- a/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs +++ b/Raspberry.IO.GeneralPurpose/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.3.0.0")] -[assembly: AssemblyFileVersion("1.3.0.0")] +[assembly: AssemblyVersion("1.4.0.0")] +[assembly: AssemblyFileVersion("1.4.0.0")] diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index d4f18b5..2324f87 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -47,6 +47,7 @@ + diff --git a/Raspberry.IO.GeneralPurpose/Time/Timer.cs b/Raspberry.IO.GeneralPurpose/Time/Timer.cs index 8191a10..3da72cd 100644 --- a/Raspberry.IO.GeneralPurpose/Time/Timer.cs +++ b/Raspberry.IO.GeneralPurpose/Time/Timer.cs @@ -30,10 +30,13 @@ public static ITimer Create() /// The time, in milliseconds. public static void Sleep(decimal time) { + if (time < 0) + return; + if (Host.Current.IsRaspberryPi) HighResolutionTimer.Sleep(time); else - Thread.Sleep((int) time); + Thread.Sleep((int)time); } #endregion From 72931f2ff66c891613df8f9c1de5970d6f3b9a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 00:42:48 +0200 Subject: [PATCH 044/227] Fixed DefaultBlinkDuration type --- Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs index 6481b15..de7b08c 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs @@ -41,7 +41,7 @@ public GpioConnectionSettings() /// /// Gets the default blink duration, in milliseconds. /// - public const int DefaultBlinkDuration = 250; + public const decimal DefaultBlinkDuration = 250; #endregion From 76112b154e2ce4b4718c37a2fae6ef54e5379d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 00:43:03 +0200 Subject: [PATCH 045/227] Updated readme.md file --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 13f2b0d..35b0009 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,13 @@ Introduction Raspberry# IO is a .NET/Mono IO Library for Raspberry Pi. This project is an initiative of the [Raspberry#](http://www.raspberry-sharp.org) Community. Current release is an early public release. Some features may not have been extensively tested. -Raspberry# IO currently supports GPIO input/output. +Raspberry# IO currently supports GPIO input/output, and an SPI sample for MCP3008 ADC is provided. Support for extended IO (such as support for PWM or I2C peripherals) is planned for future releases. -Programs using Raspberry# IO must be run with elevated privileges, for example the GpioTest console included in project: +Programs using Raspberry# IO must be run with elevated privileges, for example the Gpio.Test.Chaser program included in solution: - sudo mono GpioTest.exe -loop + sudo mono Gpio.Test.Chaser.exe -loop Features -------- @@ -33,3 +33,4 @@ It currently support the following features: + **High-level behaviors** for output pins, including *blink*, *pattern* and *chaser* + Controlled use of resources using a IDisposable component + Support sub-millisecond polling of input pins ++ Includes a SPI samples for MCP3008 ADC From c8e45a4c80d41179fa8d9b0e5e16d6de9cc1ee8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 01:54:55 +0200 Subject: [PATCH 046/227] Use MemoryGpioConnectionDriver in MCP3008 Sample --- Gpio.Test.MCP3008/Program.cs | 2 +- Gpio.Test.MCP3008/SpiConnection.cs | 53 ++++++++++++++++++------------ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Gpio.Test.MCP3008/Program.cs b/Gpio.Test.MCP3008/Program.cs index 1e0fe0a..7e414c5 100644 --- a/Gpio.Test.MCP3008/Program.cs +++ b/Gpio.Test.MCP3008/Program.cs @@ -37,7 +37,7 @@ static void Main(string[] args) Console.WriteLine("Tc = {0,5:0.0} Celsius\t\tLr = {1,7:0} Ohms", temperature, lightResistor); Console.CursorTop--; - Thread.Sleep(150); + Thread.Sleep(250); } } diff --git a/Gpio.Test.MCP3008/SpiConnection.cs b/Gpio.Test.MCP3008/SpiConnection.cs index a00fc09..73549b8 100644 --- a/Gpio.Test.MCP3008/SpiConnection.cs +++ b/Gpio.Test.MCP3008/SpiConnection.cs @@ -1,7 +1,6 @@ #region References using System; -using System.Threading; using Raspberry.IO.GeneralPurpose; #endregion @@ -12,7 +11,11 @@ public class SpiConnection : IDisposable { #region Fields - private readonly GpioConnection connection; + private readonly MemoryGpioConnectionDriver driver; + private readonly ProcessorPin clock; + private readonly ProcessorPin cs; + private readonly ProcessorPin miso; + private readonly ProcessorPin mosi; private readonly decimal referenceVoltage; #endregion @@ -21,18 +24,22 @@ public class SpiConnection : IDisposable public SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin miso, ProcessorPin mosi, decimal referenceVoltage) { + this.clock = clock; + this.cs = cs; + this.miso = miso; + this.mosi = mosi; this.referenceVoltage = referenceVoltage; - var settings = new GpioConnectionSettings {PollInterval = 10, BlinkDuration = 0}; - var pins = new PinConfiguration[] - { - clock.Output().Name("Clock"), - cs.Output().Name("Cs").Enable(), - mosi.Output().Name("Mosi"), - miso.Input().Name("Miso") - }; + driver = new MemoryGpioConnectionDriver(); - connection = new GpioConnection(settings, pins); + driver.Allocate(clock, PinDirection.Output); + driver.Allocate(cs, PinDirection.Output); + driver.Allocate(mosi, PinDirection.Output); + driver.Allocate(miso, PinDirection.Input); + + driver.Write(clock, false); + driver.Write(cs, true); + driver.Write(mosi, false); } void IDisposable.Dispose() @@ -46,7 +53,7 @@ void IDisposable.Dispose() public decimal Read(SpiChannel channel) { - connection["Cs"] = false; + driver.Write(cs, false); try { var command = (int) channel; @@ -55,9 +62,11 @@ public decimal Read(SpiChannel channel) for (var i = 0; i < 5; i++) { - connection["Mosi"] = (command & 0x80) != 0; + driver.Write(mosi, (command & 0x80) != 0); + + driver.Write(clock, true); + driver.Write(clock, false); - connection.Blink("Clock"); command = command << 1; } @@ -65,29 +74,31 @@ public decimal Read(SpiChannel channel) // read in one empty bit, one null bit and 10 ADC bits for (var i = 0; i < 12; i++) { - connection.Blink("Clock"); - - Thread.Sleep(25); + driver.Write(clock, true); + driver.Write(clock, false); data = data << 1; - if (connection["Miso"]) + if (driver.Read(miso)) data |= 0x1; } // first bit is 'null', drop it data = data >> 1; - return data*referenceVoltage/1023m; + return data*referenceVoltage/1024m; } finally { - connection["Cs"] = true; + driver.Write(cs, true); } } public void Close() { - connection.Close(); + driver.Release(clock); + driver.Release(cs); + driver.Release(mosi); + driver.Release(miso); } #endregion From 51cdb5a627848b00290a21a3092dcea3caf51a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 21:00:35 +0200 Subject: [PATCH 047/227] Updated Fritzing files --- Gpio.Test.Chaser/Gpio.Test.Chaser.csproj | 4 ++-- .../{GPIO-Chaser.fzz => Gpio.Test.Chaser.fzz} | Bin .../{GPIO-Chaser.png => Gpio.Test.Chaser.png} | Bin Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 4 ++++ .../Properties/Gpio.Test.MCP3008.fzz | Bin 0 -> 37058 bytes .../Properties/Gpio.Test.MCP3008.png | Bin 0 -> 113041 bytes 6 files changed, 6 insertions(+), 2 deletions(-) rename Gpio.Test.Chaser/Properties/{GPIO-Chaser.fzz => Gpio.Test.Chaser.fzz} (100%) rename Gpio.Test.Chaser/Properties/{GPIO-Chaser.png => Gpio.Test.Chaser.png} (100%) create mode 100644 Gpio.Test.MCP3008/Properties/Gpio.Test.MCP3008.fzz create mode 100644 Gpio.Test.MCP3008/Properties/Gpio.Test.MCP3008.png diff --git a/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj index c6addff..6be2881 100644 --- a/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj +++ b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj @@ -72,7 +72,7 @@ - + @@ -84,7 +84,7 @@ - + + \ No newline at end of file diff --git a/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs b/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs new file mode 100644 index 0000000..e5b015c --- /dev/null +++ b/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs @@ -0,0 +1,75 @@ +using System; +using Raspberry.IO.GeneralPurpose; + +namespace Gpio.Test.MCP4802 +{ + public class Mcp4802SpiConnection : IDisposable + { + #region Fields + + private readonly MemoryGpioConnectionDriver driver; + private readonly ProcessorPin clock; + private readonly ProcessorPin cs; + private readonly ProcessorPin mosi; + private readonly decimal scale; + + #endregion + + public Mcp4802SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin mosi, decimal scale) + { + this.clock = clock; + this.cs = cs; + this.mosi = mosi; + this.scale = scale; + + driver = new MemoryGpioConnectionDriver(); + + driver.Allocate(clock, PinDirection.Output); + driver.Allocate(cs, PinDirection.Output); + driver.Allocate(mosi, PinDirection.Output); + + driver.Write(clock, false); + driver.Write(cs, true); + driver.Write(mosi, false); + } + + void IDisposable.Dispose() + { + Close(); + } + + private void Close() + { + driver.Release(clock); + driver.Release(cs); + driver.Release(mosi); + } + + public void WriteData(SpiChannel channel, decimal data) + { + driver.Write(cs, false); + try + { + var value = (int) (data*4096m/scale); + if (value > 0xFFF) + value = 0xFFF; + + var command = ((int) channel << 15) | 0x3000 | value; + + for (var i = 0; i < 16; i++) + { + driver.Write(mosi, (command & 0x8000) != 0); + + driver.Write(clock, true); + driver.Write(clock, false); + + command = command << 1; + } + } + finally + { + driver.Write(cs, true); + } + } + } +} \ No newline at end of file diff --git a/Gpio.Test.MCP4802/Program.cs b/Gpio.Test.MCP4802/Program.cs new file mode 100644 index 0000000..e15ba90 --- /dev/null +++ b/Gpio.Test.MCP4802/Program.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +namespace Gpio.Test.MCP4802 +{ + class Program + { + static void Main(string[] args) + { + var dacClock = ConnectorPin.P1Pin11.ToProcessor(); + var dacCs = ConnectorPin.P1Pin13.ToProcessor(); + var dacMosi = ConnectorPin.P1Pin15.ToProcessor(); + + using (var dacConnection = new Mcp4802SpiConnection(dacClock, dacCs, dacMosi, 1)) + { + Console.CursorVisible = false; + Console.WriteLine("MC4802 Sample: Write a changing value on Channel 1"); + Console.WriteLine(); + + const decimal minimum = 0.0001m; + var ticks = minimum; + var up = true; + + while (!Console.KeyAvailable) + { + dacConnection.WriteData(SpiChannel.Channel0, ticks); + + if (up) + { + ticks *= 2; + if (ticks >= 1) + up = false; + } + else + { + ticks /= 2; + if (ticks <= minimum) + up = true; + } + + Thread.Sleep(100); + } + } + + Console.CursorTop++; + Console.CursorVisible = true; + } + } +} diff --git a/Gpio.Test.MCP4802/Properties/AssemblyInfo.cs b/Gpio.Test.MCP4802/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c961fa8 --- /dev/null +++ b/Gpio.Test.MCP4802/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Gpio.Test.MCP4802")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Gpio.Test.MCP4802")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("81a0aa1c-37b4-429d-9e95-d049372ef9df")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Gpio.Test.MCP4802/SpiChannel.cs b/Gpio.Test.MCP4802/SpiChannel.cs new file mode 100644 index 0000000..5ac5045 --- /dev/null +++ b/Gpio.Test.MCP4802/SpiChannel.cs @@ -0,0 +1,14 @@ +namespace Gpio.Test.MCP4802 +{ + public enum SpiChannel + { + Channel0 = 0, + Channel1 = 1, + Channel2 = 2, + Channel3 = 3, + Channel4 = 4, + Channel5 = 5, + Channel6 = 6, + Channel7 = 7 + } +} \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 3949477..b96ebf4 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP3008", "Gpio.T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.Chaser", "Gpio.Test.Chaser\Gpio.Test.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP4802", "Gpio.Test.MCP4802\Gpio.Test.MCP4802.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -56,6 +58,16 @@ Global {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.ActiveCfg = Release|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.Build.0 = Release|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|x86.ActiveCfg = Debug|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|x86.Build.0 = Debug|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Mixed Platforms.Build.0 = Release|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|x86.ActiveCfg = Release|x86 + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 622fc10b980afa88870ccfd7b210a0a8414bc6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 25 Oct 2012 23:44:25 +0200 Subject: [PATCH 051/227] Added references for MCP4802 sample --- Gpio.Test.MCP4802/Program.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gpio.Test.MCP4802/Program.cs b/Gpio.Test.MCP4802/Program.cs index e15ba90..ea9458d 100644 --- a/Gpio.Test.MCP4802/Program.cs +++ b/Gpio.Test.MCP4802/Program.cs @@ -4,6 +4,10 @@ namespace Gpio.Test.MCP4802 { + /// + /// Freely adapted from http://www.skpang.co.uk/blog/archives/689 + /// Connected pins are custom. + /// class Program { static void Main(string[] args) From 85149174274a8fc4e7e0005b4cb7cc11c486c1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Fri, 26 Oct 2012 00:18:16 +0200 Subject: [PATCH 052/227] Fixed issue when exiting MCP4802 sample --- Gpio.Test.MCP4802/Program.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Gpio.Test.MCP4802/Program.cs b/Gpio.Test.MCP4802/Program.cs index ea9458d..845dd49 100644 --- a/Gpio.Test.MCP4802/Program.cs +++ b/Gpio.Test.MCP4802/Program.cs @@ -18,9 +18,7 @@ static void Main(string[] args) using (var dacConnection = new Mcp4802SpiConnection(dacClock, dacCs, dacMosi, 1)) { - Console.CursorVisible = false; Console.WriteLine("MC4802 Sample: Write a changing value on Channel 1"); - Console.WriteLine(); const decimal minimum = 0.0001m; var ticks = minimum; @@ -46,9 +44,6 @@ static void Main(string[] args) Thread.Sleep(100); } } - - Console.CursorTop++; - Console.CursorVisible = true; } } } From 15b4226ab087dbd26f308384adb1d497d2d4e358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Sun, 28 Oct 2012 21:11:12 +0100 Subject: [PATCH 053/227] Updates MCP3008 and MCP4802 samples --- Gpio.Test.MCP3008/Endianness.cs | 8 + Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 4 +- .../{SpiChannel.cs => Mcp3008Channel.cs} | 2 +- Gpio.Test.MCP3008/Mcp3008SpiConnection.cs | 83 +++------ Gpio.Test.MCP3008/Program.cs | 8 +- Gpio.Test.MCP3008/SpiConnection.cs | 164 ++++++++++++++++++ Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj | 2 +- .../{SpiChannel.cs => Mcp4802Channel.cs} | 2 +- Gpio.Test.MCP4802/Mcp4802SpiConnection.cs | 2 +- Gpio.Test.MCP4802/Program.cs | 2 +- 10 files changed, 211 insertions(+), 66 deletions(-) create mode 100644 Gpio.Test.MCP3008/Endianness.cs rename Gpio.Test.MCP3008/{SpiChannel.cs => Mcp3008Channel.cs} (87%) create mode 100644 Gpio.Test.MCP3008/SpiConnection.cs rename Gpio.Test.MCP4802/{SpiChannel.cs => Mcp4802Channel.cs} (87%) diff --git a/Gpio.Test.MCP3008/Endianness.cs b/Gpio.Test.MCP3008/Endianness.cs new file mode 100644 index 0000000..3f1cc61 --- /dev/null +++ b/Gpio.Test.MCP3008/Endianness.cs @@ -0,0 +1,8 @@ +namespace Gpio.Test.MCP3008 +{ + public enum Endianness + { + LittleEndian, + BigEndian + } +} \ No newline at end of file diff --git a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj index 1a45928..715b2a7 100644 --- a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj +++ b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj @@ -40,10 +40,12 @@ + - + + diff --git a/Gpio.Test.MCP3008/SpiChannel.cs b/Gpio.Test.MCP3008/Mcp3008Channel.cs similarity index 87% rename from Gpio.Test.MCP3008/SpiChannel.cs rename to Gpio.Test.MCP3008/Mcp3008Channel.cs index 4ccea06..8accc48 100644 --- a/Gpio.Test.MCP3008/SpiChannel.cs +++ b/Gpio.Test.MCP3008/Mcp3008Channel.cs @@ -1,6 +1,6 @@ namespace Gpio.Test.MCP3008 { - public enum SpiChannel + public enum Mcp3008Channel { Channel0 = 0, Channel1 = 1, diff --git a/Gpio.Test.MCP3008/Mcp3008SpiConnection.cs b/Gpio.Test.MCP3008/Mcp3008SpiConnection.cs index 9153111..20835e5 100644 --- a/Gpio.Test.MCP3008/Mcp3008SpiConnection.cs +++ b/Gpio.Test.MCP3008/Mcp3008SpiConnection.cs @@ -7,15 +7,17 @@ namespace Gpio.Test.MCP3008 { + /// + /// Represents a connection to MCP3004/3008 ADC converter. + /// + /// + /// See specification at http://www.adafruit.com/datasheets/MCP3008.pdf + /// public class Mcp3008SpiConnection : IDisposable { #region Fields - private readonly MemoryGpioConnectionDriver driver; - private readonly ProcessorPin clock; - private readonly ProcessorPin cs; - private readonly ProcessorPin miso; - private readonly ProcessorPin mosi; + private readonly SpiConnection spiConnection; private readonly decimal scale; #endregion @@ -24,22 +26,8 @@ public class Mcp3008SpiConnection : IDisposable public Mcp3008SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin miso, ProcessorPin mosi, decimal scale) { - this.clock = clock; - this.cs = cs; - this.miso = miso; - this.mosi = mosi; this.scale = scale; - - driver = new MemoryGpioConnectionDriver(); - - driver.Allocate(clock, PinDirection.Output); - driver.Allocate(cs, PinDirection.Output); - driver.Allocate(mosi, PinDirection.Output); - driver.Allocate(miso, PinDirection.Input); - - driver.Write(clock, false); - driver.Write(cs, true); - driver.Write(mosi, false); + spiConnection = new SpiConnection(clock, cs, miso, mosi, Endianness.LittleEndian); } void IDisposable.Dispose() @@ -51,54 +39,37 @@ void IDisposable.Dispose() #region Methods - public decimal Read(SpiChannel channel) + public decimal Read(Mcp3008Channel channel) { - driver.Write(cs, false); + spiConnection.SelectSlave(); try { - var command = (int) channel; - command |= 0x18; // start bit + single-ended bit - command = command << 3; // we only need to send 5 bits here - - for (var i = 0; i < 5; i++) - { - driver.Write(mosi, (command & 0x80) != 0); - - driver.Write(clock, true); - driver.Write(clock, false); - - command = command << 1; - } - - var data = 0; - // read in one empty bit, one null bit and 10 ADC bits - for (var i = 0; i < 12; i++) - { - driver.Write(clock, true); - driver.Write(clock, false); - - data = data << 1; - if (driver.Read(miso)) - data |= 0x1; - } - - // first bit is 'null', drop it - data = data >> 1; - + // Start bit + spiConnection.Write(true); + + // Channel is single-ended + spiConnection.Write(true); + + // Channel Id + spiConnection.Write((byte)channel, 3); + + // Let one clock to sample + spiConnection.Synchronize(); + + // Read 10 bits + var data = spiConnection.Read(10); + return data*scale/1024m; } finally { - driver.Write(cs, true); + spiConnection.DeselectSlave(); } } public void Close() { - driver.Release(clock); - driver.Release(cs); - driver.Release(mosi); - driver.Release(miso); + spiConnection.Close(); } #endregion diff --git a/Gpio.Test.MCP3008/Program.cs b/Gpio.Test.MCP3008/Program.cs index f3aeaf1..aca0137 100644 --- a/Gpio.Test.MCP3008/Program.cs +++ b/Gpio.Test.MCP3008/Program.cs @@ -26,15 +26,15 @@ static void Main(string[] args) using (var adcConnection = new Mcp3008SpiConnection(adcClock, adcCs, adcMiso, adcMosi, voltage)) { Console.CursorVisible = false; - Console.WriteLine("MCP3008 Sample: Reading temperature on Channel 0 and light resistor on Channel 1"); + Console.WriteLine("MCP3008 Sample: Reading temperature on Channel 0 and luminosity on Channel 1"); Console.WriteLine(); while (!Console.KeyAvailable) { - var temperature = adcConnection.Read(SpiChannel.Channel0).ToCelsius(); - var lux = adcConnection.Read(SpiChannel.Channel1).ToLux(voltage); + var temperature = adcConnection.Read(Mcp3008Channel.Channel0).ToCelsius(); + var lux = adcConnection.Read(Mcp3008Channel.Channel1).ToLux(voltage); - Console.WriteLine("Tc = {0,5:0.0} Celsius\t\tLr = {1,5:0.0} Lux", temperature, lux); + Console.WriteLine("Temperature = {0,5:0.0} Celsius\t\tLuminosity = {1,5:0.0} Lux", temperature, lux); Console.CursorTop--; Thread.Sleep(100); diff --git a/Gpio.Test.MCP3008/SpiConnection.cs b/Gpio.Test.MCP3008/SpiConnection.cs new file mode 100644 index 0000000..a837d9e --- /dev/null +++ b/Gpio.Test.MCP3008/SpiConnection.cs @@ -0,0 +1,164 @@ +#region References + +using System; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +#endregion + +namespace Gpio.Test.MCP3008 +{ + public class SpiConnection : IDisposable + { + #region Fields + + private readonly MemoryGpioConnectionDriver driver; + private readonly ProcessorPin clock; + private readonly ProcessorPin ss; + private readonly ProcessorPin miso; + private readonly ProcessorPin mosi; + + private readonly Endianness endianness = Endianness.LittleEndian; + + #endregion + + #region Instance Management + + public SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin miso, ProcessorPin mosi, Endianness endianness) + { + this.clock = clock; + this.ss = ss; + this.miso = miso; + this.mosi = mosi; + this.endianness = endianness; + + driver = new MemoryGpioConnectionDriver(); + + driver.Allocate(clock, PinDirection.Output); + driver.Allocate(ss, PinDirection.Output); + driver.Allocate(mosi, PinDirection.Output); + driver.Allocate(miso, PinDirection.Input); + + driver.Write(clock, false); + driver.Write(ss, true); + driver.Write(mosi, false); + } + + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + public void Close() + { + driver.Release(clock); + driver.Release(ss); + driver.Release(mosi); + driver.Release(miso); + } + + public void SelectSlave() + { + driver.Write(ss, false); + } + + public void DeselectSlave() + { + driver.Write(ss, true); + } + + public void Synchronize() + { + driver.Write(clock, true); + Thread.Sleep(1); + driver.Write(clock, false); + } + + public void Write(bool data) + { + driver.Write(mosi, data); + Synchronize(); + } + + public void Write(byte data, int bitCount) + { + if (bitCount > 8) + throw new ArgumentOutOfRangeException("bitCount", bitCount, "byte data cannot contain more than 8 bits"); + + SafeWrite(data, bitCount); + } + + public void Write(ushort data, int bitCount) + { + if (bitCount > 16) + throw new ArgumentOutOfRangeException("bitCount", bitCount, "ushort data cannot contain more than 16 bits"); + + SafeWrite(data, bitCount); + } + + public void Write(uint data, int bitCount) + { + if (bitCount > 32) + throw new ArgumentOutOfRangeException("bitCount", bitCount, "uint data cannot contain more than 32 bits"); + + SafeWrite(data, bitCount); + } + + public void Write(ulong data, int bitCount) + { + if (bitCount > 64) + throw new ArgumentOutOfRangeException("bitCount", bitCount, "ulong data cannot contain more than 64 bits"); + + SafeWrite(data, bitCount); + } + + public bool Read() + { + Synchronize(); + return driver.Read(miso); + } + + public ulong Read(int bitCount) + { + if (bitCount > 64) + throw new ArgumentOutOfRangeException("bitCount", bitCount, "ulong data cannot contain more than 64 bits"); + + ulong data = 0; + for (var i = 0; i < bitCount; i++) + { + var index = endianness == Endianness.BigEndian + ? i + : bitCount - 1 - i; + + var bit = Read(); + if (bit) + data |= ((ulong)1 << index); + } + + return data; + } + + #endregion + + #region Private Helpers + + private void SafeWrite(ulong data, int bitCount) + { + for (var i = 0; i < bitCount; i++) + { + var index = endianness == Endianness.BigEndian + ? i + : bitCount - 1 - i; + + var bit = data & ((ulong) 1 << index); + Write(bit != 0); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj b/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj index d920ede..778ca34 100644 --- a/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj +++ b/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj @@ -47,7 +47,7 @@ - + diff --git a/Gpio.Test.MCP4802/SpiChannel.cs b/Gpio.Test.MCP4802/Mcp4802Channel.cs similarity index 87% rename from Gpio.Test.MCP4802/SpiChannel.cs rename to Gpio.Test.MCP4802/Mcp4802Channel.cs index 5ac5045..fb6f1f5 100644 --- a/Gpio.Test.MCP4802/SpiChannel.cs +++ b/Gpio.Test.MCP4802/Mcp4802Channel.cs @@ -1,6 +1,6 @@ namespace Gpio.Test.MCP4802 { - public enum SpiChannel + public enum Mcp4802Channel { Channel0 = 0, Channel1 = 1, diff --git a/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs b/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs index e5b015c..b197975 100644 --- a/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs +++ b/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs @@ -45,7 +45,7 @@ private void Close() driver.Release(mosi); } - public void WriteData(SpiChannel channel, decimal data) + public void WriteData(Mcp4802Channel channel, decimal data) { driver.Write(cs, false); try diff --git a/Gpio.Test.MCP4802/Program.cs b/Gpio.Test.MCP4802/Program.cs index 845dd49..0135dc8 100644 --- a/Gpio.Test.MCP4802/Program.cs +++ b/Gpio.Test.MCP4802/Program.cs @@ -26,7 +26,7 @@ static void Main(string[] args) while (!Console.KeyAvailable) { - dacConnection.WriteData(SpiChannel.Channel0, ticks); + dacConnection.WriteData(Mcp4802Channel.Channel0, ticks); if (up) { From 498d4aa090c70dee9283cbd4ff0be666c3f6a0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Sun, 28 Oct 2012 22:00:40 +0100 Subject: [PATCH 054/227] Introduced Raspberry.IO.SerialPeripheralInterface Updated samples to reflect changes --- Gpio.Test.Chaser/Properties/AssemblyInfo.cs | 2 +- Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 8 +- Gpio.Test.MCP3008/Program.cs | 1 + Gpio.Test.MCP3008/Properties/AssemblyInfo.cs | 3 +- Gpio.Test.MCP4802/Mcp4802Channel.cs | 14 ---- Gpio.Test.MCP4802/Mcp4802SpiConnection.cs | 75 ------------------- .../Gpio.Test.MCP4822.csproj | 10 ++- .../Program.cs | 9 ++- .../Properties/AssemblyInfo.cs | 7 +- .../Components}/Mcp3008Channel.cs | 2 +- .../Components}/Mcp3008SpiConnection.cs | 2 +- .../Components/Mcp4822Channel.cs | 8 ++ .../Components/Mcp4822SpiConnection.cs | 65 ++++++++++++++++ .../Endianness.cs | 2 +- .../Properties/AssemblyInfo.cs | 35 +++++++++ ...pberry.IO.SerialPeripheralInterface.csproj | 66 ++++++++++++++++ .../SpiConnection.cs | 40 ++++++---- RaspberrySharp.IO.sln | 14 +++- 18 files changed, 238 insertions(+), 125 deletions(-) delete mode 100644 Gpio.Test.MCP4802/Mcp4802Channel.cs delete mode 100644 Gpio.Test.MCP4802/Mcp4802SpiConnection.cs rename Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj => Gpio.Test.MCP4822/Gpio.Test.MCP4822.csproj (87%) rename {Gpio.Test.MCP4802 => Gpio.Test.MCP4822}/Program.cs (79%) rename {Gpio.Test.MCP4802 => Gpio.Test.MCP4822}/Properties/AssemblyInfo.cs (86%) rename {Gpio.Test.MCP3008 => Raspberry.IO.SerialPeripheralInterface/Components}/Mcp3008Channel.cs (78%) rename {Gpio.Test.MCP3008 => Raspberry.IO.SerialPeripheralInterface/Components}/Mcp3008SpiConnection.cs (96%) create mode 100644 Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822Channel.cs create mode 100644 Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs rename {Gpio.Test.MCP3008 => Raspberry.IO.SerialPeripheralInterface}/Endianness.cs (62%) create mode 100644 Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs create mode 100644 Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj rename {Gpio.Test.MCP3008 => Raspberry.IO.SerialPeripheralInterface}/SpiConnection.cs (80%) diff --git a/Gpio.Test.Chaser/Properties/AssemblyInfo.cs b/Gpio.Test.Chaser/Properties/AssemblyInfo.cs index a4d1f83..55ad3c6 100644 --- a/Gpio.Test.Chaser/Properties/AssemblyInfo.cs +++ b/Gpio.Test.Chaser/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Gpio.Test.Chaser")] -[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyCopyright("www.raspberry-sharp.org, 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj index 715b2a7..1e08aa0 100644 --- a/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj +++ b/Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj @@ -40,18 +40,18 @@ - - - - {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {326342E5-0411-40E8-9F2D-563D6B192568} + Raspberry.IO.SerialPeripheralInterface + diff --git a/Gpio.Test.MCP3008/Program.cs b/Gpio.Test.MCP3008/Program.cs index aca0137..f95f777 100644 --- a/Gpio.Test.MCP3008/Program.cs +++ b/Gpio.Test.MCP3008/Program.cs @@ -3,6 +3,7 @@ using System; using System.Threading; using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.SerialPeripheralInterface.Components; #endregion diff --git a/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs b/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs index c6e8c68..35cbe99 100644 --- a/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs +++ b/Gpio.Test.MCP3008/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -10,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Gpio.Test.MCP3008")] -[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyCopyright("www.raspberry-sharp.org, 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Gpio.Test.MCP4802/Mcp4802Channel.cs b/Gpio.Test.MCP4802/Mcp4802Channel.cs deleted file mode 100644 index fb6f1f5..0000000 --- a/Gpio.Test.MCP4802/Mcp4802Channel.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Gpio.Test.MCP4802 -{ - public enum Mcp4802Channel - { - Channel0 = 0, - Channel1 = 1, - Channel2 = 2, - Channel3 = 3, - Channel4 = 4, - Channel5 = 5, - Channel6 = 6, - Channel7 = 7 - } -} \ No newline at end of file diff --git a/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs b/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs deleted file mode 100644 index b197975..0000000 --- a/Gpio.Test.MCP4802/Mcp4802SpiConnection.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using Raspberry.IO.GeneralPurpose; - -namespace Gpio.Test.MCP4802 -{ - public class Mcp4802SpiConnection : IDisposable - { - #region Fields - - private readonly MemoryGpioConnectionDriver driver; - private readonly ProcessorPin clock; - private readonly ProcessorPin cs; - private readonly ProcessorPin mosi; - private readonly decimal scale; - - #endregion - - public Mcp4802SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin mosi, decimal scale) - { - this.clock = clock; - this.cs = cs; - this.mosi = mosi; - this.scale = scale; - - driver = new MemoryGpioConnectionDriver(); - - driver.Allocate(clock, PinDirection.Output); - driver.Allocate(cs, PinDirection.Output); - driver.Allocate(mosi, PinDirection.Output); - - driver.Write(clock, false); - driver.Write(cs, true); - driver.Write(mosi, false); - } - - void IDisposable.Dispose() - { - Close(); - } - - private void Close() - { - driver.Release(clock); - driver.Release(cs); - driver.Release(mosi); - } - - public void WriteData(Mcp4802Channel channel, decimal data) - { - driver.Write(cs, false); - try - { - var value = (int) (data*4096m/scale); - if (value > 0xFFF) - value = 0xFFF; - - var command = ((int) channel << 15) | 0x3000 | value; - - for (var i = 0; i < 16; i++) - { - driver.Write(mosi, (command & 0x8000) != 0); - - driver.Write(clock, true); - driver.Write(clock, false); - - command = command << 1; - } - } - finally - { - driver.Write(cs, true); - } - } - } -} \ No newline at end of file diff --git a/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj b/Gpio.Test.MCP4822/Gpio.Test.MCP4822.csproj similarity index 87% rename from Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj rename to Gpio.Test.MCP4822/Gpio.Test.MCP4822.csproj index 778ca34..96b99c1 100644 --- a/Gpio.Test.MCP4802/Gpio.Test.MCP4802.csproj +++ b/Gpio.Test.MCP4822/Gpio.Test.MCP4822.csproj @@ -8,8 +8,8 @@ {54075457-7C1D-4C8F-BE7D-CFCA34F11228} Exe Properties - Gpio.Test.MCP4802 - Gpio.Test.MCP4802 + Gpio.Test.MCP4822 + Gpio.Test.MCP4822 v4.0 @@ -44,16 +44,18 @@ - - {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {326342E5-0411-40E8-9F2D-563D6B192568} + Raspberry.IO.SerialPeripheralInterface + + \ No newline at end of file diff --git a/Gpio.Test.MCP3008/SpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs similarity index 80% rename from Gpio.Test.MCP3008/SpiConnection.cs rename to Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs index a837d9e..4c4a50b 100644 --- a/Gpio.Test.MCP3008/SpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs @@ -6,7 +6,7 @@ #endregion -namespace Gpio.Test.MCP3008 +namespace Raspberry.IO.SerialPeripheralInterface { public class SpiConnection : IDisposable { @@ -15,8 +15,8 @@ public class SpiConnection : IDisposable private readonly MemoryGpioConnectionDriver driver; private readonly ProcessorPin clock; private readonly ProcessorPin ss; - private readonly ProcessorPin miso; - private readonly ProcessorPin mosi; + private readonly ProcessorPin? miso; + private readonly ProcessorPin? mosi; private readonly Endianness endianness = Endianness.LittleEndian; @@ -24,7 +24,7 @@ public class SpiConnection : IDisposable #region Instance Management - public SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin miso, ProcessorPin mosi, Endianness endianness) + public SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin? miso, ProcessorPin? mosi, Endianness endianness) { this.clock = clock; this.ss = ss; @@ -35,13 +35,19 @@ public SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin miso, Pro driver = new MemoryGpioConnectionDriver(); driver.Allocate(clock, PinDirection.Output); - driver.Allocate(ss, PinDirection.Output); - driver.Allocate(mosi, PinDirection.Output); - driver.Allocate(miso, PinDirection.Input); - driver.Write(clock, false); + + driver.Allocate(ss, PinDirection.Output); driver.Write(ss, true); - driver.Write(mosi, false); + + if (mosi.HasValue) + { + driver.Allocate(mosi.Value, PinDirection.Output); + driver.Write(mosi.Value, false); + } + + if (miso.HasValue) + driver.Allocate(miso.Value, PinDirection.Input); } void IDisposable.Dispose() @@ -57,8 +63,10 @@ public void Close() { driver.Release(clock); driver.Release(ss); - driver.Release(mosi); - driver.Release(miso); + if (mosi.HasValue) + driver.Release(mosi.Value); + if (miso.HasValue) + driver.Release(miso.Value); } public void SelectSlave() @@ -80,7 +88,10 @@ public void Synchronize() public void Write(bool data) { - driver.Write(mosi, data); + if (!mosi.HasValue) + throw new NotSupportedException("No MOSI pin has been provided"); + + driver.Write(mosi.Value, data); Synchronize(); } @@ -118,8 +129,11 @@ public void Write(ulong data, int bitCount) public bool Read() { + if (!miso.HasValue) + throw new NotSupportedException("No MISO pin has been provided"); + Synchronize(); - return driver.Read(miso); + return driver.Read(miso.Value); } public ulong Read(int bitCount) diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index b96ebf4..ba2df1e 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -14,7 +14,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP3008", "Gpio.T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.Chaser", "Gpio.Test.Chaser\Gpio.Test.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP4802", "Gpio.Test.MCP4802\Gpio.Test.MCP4802.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripheralInterface", "Raspberry.IO.SerialPeripheralInterface\Raspberry.IO.SerialPeripheralInterface.csproj", "{326342E5-0411-40E8-9F2D-563D6B192568}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP4822", "Gpio.Test.MCP4822\Gpio.Test.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -58,6 +60,16 @@ Global {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.ActiveCfg = Release|x86 {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|x86.Build.0 = Release|x86 + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|x86.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|x86.ActiveCfg = Release|Any CPU {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|x86 {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Mixed Platforms.Build.0 = Debug|x86 From 8e59497199a16f1bd620e182684e8e610da77017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 30 Oct 2012 00:46:00 +0100 Subject: [PATCH 055/227] Introduced support for HDD44780 LCD Display --- Gpio.Test.HDD44780/Command.cs | 14 + Gpio.Test.HDD44780/CursorShiftFlags.cs | 16 ++ Gpio.Test.HDD44780/DisplayFlags.cs | 18 ++ Gpio.Test.HDD44780/EntryModeFlags.cs | 16 ++ Gpio.Test.HDD44780/Functions.cs | 18 ++ Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj | 72 +++++ Gpio.Test.HDD44780/Hdd44780LcdConnection.cs | 271 ++++++++++++++++++ Gpio.Test.HDD44780/Program.cs | 73 +++++ Gpio.Test.HDD44780/Properties/AssemblyInfo.cs | 36 +++ Gpio.Test.MCP3008/Convert.cs | 8 +- Gpio.Test.MCP4822/Program.cs | 6 +- .../Components/Mcp3008SpiConnection.cs | 7 +- .../Components/Mcp4822SpiConnection.cs | 23 +- ...pberry.IO.SerialPeripheralInterface.csproj | 1 + .../SpiConnection.cs | 7 +- .../SpiSlaveSelection.cs | 31 ++ RaspberrySharp.IO.sln | 12 + 17 files changed, 609 insertions(+), 20 deletions(-) create mode 100644 Gpio.Test.HDD44780/Command.cs create mode 100644 Gpio.Test.HDD44780/CursorShiftFlags.cs create mode 100644 Gpio.Test.HDD44780/DisplayFlags.cs create mode 100644 Gpio.Test.HDD44780/EntryModeFlags.cs create mode 100644 Gpio.Test.HDD44780/Functions.cs create mode 100644 Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj create mode 100644 Gpio.Test.HDD44780/Hdd44780LcdConnection.cs create mode 100644 Gpio.Test.HDD44780/Program.cs create mode 100644 Gpio.Test.HDD44780/Properties/AssemblyInfo.cs create mode 100644 Raspberry.IO.SerialPeripheralInterface/SpiSlaveSelection.cs diff --git a/Gpio.Test.HDD44780/Command.cs b/Gpio.Test.HDD44780/Command.cs new file mode 100644 index 0000000..6125ea5 --- /dev/null +++ b/Gpio.Test.HDD44780/Command.cs @@ -0,0 +1,14 @@ +namespace Gpio.Test.HDD44780 +{ + internal enum Command + { + ClearDisplay = 0x01, + ReturnHome = 0x02, + SetEntryModeFlags = 0x04, + SetDisplayFlags = 0x08, + MoveCursor = 0x10, + SetFunctions = 0x20, + //SetCGRamAddr = 0x40, + //SetDDRamAddr = 0x80 + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/CursorShiftFlags.cs b/Gpio.Test.HDD44780/CursorShiftFlags.cs new file mode 100644 index 0000000..27a3a8d --- /dev/null +++ b/Gpio.Test.HDD44780/CursorShiftFlags.cs @@ -0,0 +1,16 @@ +using System; + +namespace Gpio.Test.HDD44780 +{ + [Flags] + internal enum CursorShiftFlags + { + None = 0, + + CursorMove = 0, + MoveLeft = 0, + + MoveRight = 0x04, + DisplayMove = 0x08 + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/DisplayFlags.cs b/Gpio.Test.HDD44780/DisplayFlags.cs new file mode 100644 index 0000000..872bebc --- /dev/null +++ b/Gpio.Test.HDD44780/DisplayFlags.cs @@ -0,0 +1,18 @@ +using System; + +namespace Gpio.Test.HDD44780 +{ + [Flags] + internal enum DisplayFlags + { + None = 0, + + BlinkOff = 0, + CursorOff = 0, + DisplayOff = 0, + + BlinkOn = 0x01, + CursorOn = 0x02, + DisplayOn = 0x04 + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/EntryModeFlags.cs b/Gpio.Test.HDD44780/EntryModeFlags.cs new file mode 100644 index 0000000..6381ce2 --- /dev/null +++ b/Gpio.Test.HDD44780/EntryModeFlags.cs @@ -0,0 +1,16 @@ +using System; + +namespace Gpio.Test.HDD44780 +{ + [Flags] + internal enum EntryModeFlags + { + None = 0, + + EntryRight = 0, + EntryShiftDecrement = 0, + + EntryShiftIncrement = 0x01, + EntryLeft = 0x02 + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/Functions.cs b/Gpio.Test.HDD44780/Functions.cs new file mode 100644 index 0000000..9cf9f39 --- /dev/null +++ b/Gpio.Test.HDD44780/Functions.cs @@ -0,0 +1,18 @@ +using System; + +namespace Gpio.Test.HDD44780 +{ + [Flags] + internal enum Functions + { + None = 0, + + Matrix5x7 = 0, + OneLine = 0, + + Matrix5x10 = 0x04, + TwoLines = 0x08, + + //LCD_8BITMODE = 0x10, + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj b/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj new file mode 100644 index 0000000..d8cd8f9 --- /dev/null +++ b/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj @@ -0,0 +1,72 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} + Exe + Properties + Gpio.Test.HDD44780 + Gpio.Test.HDD44780 + v4.0 + + + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + + + \ No newline at end of file diff --git a/Gpio.Test.HDD44780/Hdd44780LcdConnection.cs b/Gpio.Test.HDD44780/Hdd44780LcdConnection.cs new file mode 100644 index 0000000..c1b7bc7 --- /dev/null +++ b/Gpio.Test.HDD44780/Hdd44780LcdConnection.cs @@ -0,0 +1,271 @@ +#region References + +using System; +using System.Text; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +#endregion + +namespace Gpio.Test.HDD44780 +{ + /// + /// Based on https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_CharLCD/Adafruit_CharLCD.py + /// + public class Hdd44780LcdConnection : IDisposable + { + #region Fields + + private readonly IGpioConnectionDriver connectionDriver; + + private readonly ProcessorPin registerSelect; + private readonly ProcessorPin clock; + private readonly ProcessorPin data1; + private readonly ProcessorPin data2; + private readonly ProcessorPin data3; + private readonly ProcessorPin data4; + private readonly int width; + private readonly int height; + + private readonly Functions functions; + + private DisplayFlags displayFlags = DisplayFlags.DisplayOn | DisplayFlags.BlinkOff | DisplayFlags.CursorOff; + private EntryModeFlags entryModeFlags = EntryModeFlags.EntryLeft | EntryModeFlags.EntryShiftDecrement; + + private int currentRow; + private int currentColumn; + + #endregion + + #region Instance Management + + public Hdd44780LcdConnection( + ProcessorPin registerSelect, ProcessorPin clock, + ProcessorPin data1, ProcessorPin data2, ProcessorPin data3, ProcessorPin data4, + int width, int height) + { + this.registerSelect = registerSelect; + this.clock = clock; + this.data1 = data1; + this.data2 = data2; + this.data3 = data3; + this.data4 = data4; + + this.width = width; + this.height = height; + functions = Functions.Matrix5x7 | (height == 1 ? Functions.OneLine : Functions.TwoLines); + + connectionDriver = new MemoryGpioConnectionDriver(); + + connectionDriver.Allocate(registerSelect, PinDirection.Output); + connectionDriver.Allocate(clock, PinDirection.Output); + connectionDriver.Allocate(data1, PinDirection.Output); + connectionDriver.Allocate(data2, PinDirection.Output); + connectionDriver.Allocate(data3, PinDirection.Output); + connectionDriver.Allocate(data4, PinDirection.Output); + + connectionDriver.Write(registerSelect, false); + connectionDriver.Write(clock, false); + connectionDriver.Write(data1, false); + connectionDriver.Write(data2, false); + connectionDriver.Write(data3, false); + connectionDriver.Write(data4, false); + + Write4Bits(0x33, false); // Initialize + Write4Bits(0x32, false); + + WriteCommand(Command.SetFunctions, (int) functions); + WriteCommand(Command.SetDisplayFlags, (int) displayFlags); + WriteCommand(Command.SetEntryModeFlags, (int) entryModeFlags); + + Clear(); + } + + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Properties + + public bool DisplayEnabled + { + get { return (displayFlags & DisplayFlags.DisplayOn) == DisplayFlags.DisplayOn; } + set + { + if (value) + displayFlags |= DisplayFlags.DisplayOn; + else + displayFlags &= ~DisplayFlags.DisplayOn; + + WriteCommand(Command.SetDisplayFlags, (int) displayFlags); + } + } + + public bool CursorEnabled + { + get { return (displayFlags & DisplayFlags.CursorOn) == DisplayFlags.CursorOn; } + set + { + if (value) + displayFlags |= DisplayFlags.CursorOn; + else + displayFlags &= ~DisplayFlags.CursorOn; + + WriteCommand(Command.SetDisplayFlags, (int) displayFlags); + } + } + + public bool BlinkEnabled + { + get { return (displayFlags & DisplayFlags.BlinkOn) == DisplayFlags.BlinkOn; } + set + { + if (value) + displayFlags |= DisplayFlags.BlinkOn; + else + displayFlags &= ~DisplayFlags.BlinkOn; + + WriteCommand(Command.SetDisplayFlags, (int) displayFlags); + } + } + + #endregion + + #region Methods + + public void Close() + { + Clear(); + + connectionDriver.Release(registerSelect); + connectionDriver.Release(clock); + connectionDriver.Release(data1); + connectionDriver.Release(data2); + connectionDriver.Release(data3); + connectionDriver.Release(data4); + } + + public void Home() + { + WriteCommand(Command.ReturnHome); + currentRow = 0; + currentColumn = 0; + + Sleep(3.0m); + } + + public void Clear() + { + WriteCommand(Command.ClearDisplay); + currentRow = 0; + currentColumn = 0; + + Sleep(3.0m); // Clearing the display takes a long time + } + + public void WriteLine(object value) + { + WriteLine("{0}", value); + } + + public void WriteLine(string text) + { + Write(text + Environment.NewLine); + } + + public void WriteLine(string format, params object[] values) + { + WriteLine(string.Format(format, values)); + } + + public void Write(string text) + { + var lines = text.Split(new[] {Environment.NewLine}, StringSplitOptions.None); + + foreach (var line in lines) + { + if (string.IsNullOrEmpty(line)) + continue; + + var bytes = Encoding.ASCII.GetBytes(line); + foreach (var b in bytes) + { + if (currentColumn < width) + Write4Bits(b, true); + + currentColumn++; + } + + if (currentRow == 0 && height > 1) + { + Write4Bits(0xC0, false); + currentColumn = 0; + currentRow++; + } + else + break; + } + } + + public void Write(object value) + { + Write("{0}", value); + } + + public void Write(string format, params object[] values) + { + Write(string.Format(format, values)); + } + + #endregion + + #region Private Helpers + + private void Sleep(decimal delay) + { + Thread.Sleep(delay < 1 ? 1 : (int)delay); + } + + private void WriteCommand(Command command, int parameter = 0) + { + var bits = (int) command | parameter; + Write4Bits(bits, false); + } + + private void Write4Bits(int bits, bool charMode) + { + connectionDriver.Write(registerSelect, charMode); + + connectionDriver.Write(data1, (bits & 0x10) != 0); + connectionDriver.Write(data2, (bits & 0x20) != 0); + connectionDriver.Write(data3, (bits & 0x40) != 0); + connectionDriver.Write(data4, (bits & 0x80) != 0); + + Synchronize(); + + connectionDriver.Write(data1, (bits & 0x01) != 0); + connectionDriver.Write(data2, (bits & 0x02) != 0); + connectionDriver.Write(data3, (bits & 0x04) != 0); + connectionDriver.Write(data4, (bits & 0x08) != 0); + + Synchronize(); + + } + + private void Synchronize() + { + Sleep(0.001m); // 1 microsecond pause - enable pulse must be > 450ns + + connectionDriver.Write(clock, true); + Sleep(0.001m); // 1 microsecond pause - enable pulse must be > 450ns + + connectionDriver.Write(clock, false); + Sleep(0.001m); // commands need > 37us to settle + } + + #endregion + } +} \ No newline at end of file diff --git a/Gpio.Test.HDD44780/Program.cs b/Gpio.Test.HDD44780/Program.cs new file mode 100644 index 0000000..731e710 --- /dev/null +++ b/Gpio.Test.HDD44780/Program.cs @@ -0,0 +1,73 @@ +#region References + +using System; +using System.Linq; +using System.Net.NetworkInformation; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +#endregion + +namespace Gpio.Test.HDD44780 +{ + class Program + { + static void Main(string[] args) + { + var registerSelect = ConnectorPin.P1Pin22.ToProcessor(); + var clock = ConnectorPin.P1Pin18.ToProcessor(); + var data1 = ConnectorPin.P1Pin16.ToProcessor(); + var data2 = ConnectorPin.P1Pin15.ToProcessor(); + var data3 = ConnectorPin.P1Pin13.ToProcessor(); + var data4 = ConnectorPin.P1Pin11.ToProcessor(); + + using (var connection = new Hdd44780LcdConnection( + registerSelect, + clock, + data1, data2, data3, data4, + 20, 2)) + { + + connection.WriteLine("R# IP Config"); + connection.WriteLine(Environment.OSVersion); + Thread.Sleep(2000); + + const char download = (char) 126; + const char upload = (char) 127; + + while (true) + { + foreach (var i in NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)) + { + connection.Clear(); + connection.WriteLine("{0}: {1}", i.Name, i.OperationalStatus); + connection.Write(i.GetIPProperties().UnicastAddresses.Select(a => a.Address.ToString()).FirstOrDefault() ?? "(unassigned)"); + + Thread.Sleep(2000); + + connection.Clear(); + connection.WriteLine(i.GetPhysicalAddress()); + connection.Write("{0}{1} {2}{3}", download, FormatByteCount(i.GetIPv4Statistics().BytesReceived), upload, FormatByteCount(i.GetIPv4Statistics().BytesSent)); + + Thread.Sleep(2000); + + if (Console.KeyAvailable) + return; + } + } + } + } + + private static string FormatByteCount(long byteCount) + { + if (byteCount < 1024) + return string.Format("{0}B", byteCount); + if (byteCount < 1024 * 1024) + return string.Format("{0:0.0}KB", byteCount/1024.0m); + if (byteCount < 1024 * 1024 * 1024) + return string.Format("{0:0.0}MB", byteCount / (1024 * 1024.0m)); + + return string.Format("{0:0.0}GB", byteCount / (1024 * 1024 * 1024.0m)); + } + } +} diff --git a/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs b/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e3e3175 --- /dev/null +++ b/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Gpio.Test.HDD44780")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Gpio.Test.HDD44780")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2d1441fe-8142-4dc1-ae55-b17531eb9acd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Gpio.Test.MCP3008/Convert.cs b/Gpio.Test.MCP3008/Convert.cs index 8d76f07..aedfb0f 100644 --- a/Gpio.Test.MCP3008/Convert.cs +++ b/Gpio.Test.MCP3008/Convert.cs @@ -2,10 +2,12 @@ namespace Gpio.Test.MCP3008 { internal static class Convert { + #region Methods + public static decimal ToCelsius(this decimal volts) { // See http://learn.adafruit.com/send-raspberry-pi-data-to-cosm - return 100 * volts - 50; + return 100*volts - 50; } public static decimal ToLux(this decimal volts, decimal referenceVoltage) @@ -17,8 +19,10 @@ public static decimal ToLux(this decimal volts, decimal referenceVoltage) const decimal luxRatio = 500000; return volts != 0 - ? luxRatio * volts / (resistor * (referenceVoltage - volts)) + ? luxRatio*volts/(resistor*(referenceVoltage - volts)) : 0; } + + #endregion } } \ No newline at end of file diff --git a/Gpio.Test.MCP4822/Program.cs b/Gpio.Test.MCP4822/Program.cs index eeaa226..cf5f9d0 100644 --- a/Gpio.Test.MCP4822/Program.cs +++ b/Gpio.Test.MCP4822/Program.cs @@ -1,8 +1,12 @@ -using System; +#region Fields + +using System; using System.Threading; using Raspberry.IO.GeneralPurpose; using Raspberry.IO.SerialPeripheralInterface.Components; +#endregion + namespace Gpio.Test.MCP4822 { /// public interface ITlc59711Device : IPwmDevice, ITlc59711Settings { + #region Methods + /// /// Initializes the device with default values. /// void Reset(); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Settings.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Settings.cs index 8cc94b4..ce63d7e 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Settings.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Settings.cs @@ -3,12 +3,16 @@ /// /// TLC59711 settings /// - public interface ITlc59711Settings { + public interface ITlc59711Settings + { + + #region Properties + /// /// BLANK: If set to true all outputs are forced off. Default value is true. /// bool Blank { get; set; } - + /// /// DSPRPT: Auto display repeat mode. If false the auto repeat function is disabled. /// @@ -50,7 +54,7 @@ public interface ITlc59711Settings { /// If false, OUTXn are turned on or off at the falling edge of the selected clock. /// bool ReferenceClockEdge { get; set; } - + /// /// BCR: Global brightness control for OUTR0-3. Default value is 127. /// @@ -60,7 +64,7 @@ public interface ITlc59711Settings { /// maximum output current. /// byte BrightnessControlR { get; set; } - + /// /// BCG: Global brightness control for OUTG0-3. Default value is 127. /// @@ -70,7 +74,7 @@ public interface ITlc59711Settings { /// maximum output current. /// byte BrightnessControlG { get; set; } - + /// /// BCB: Global brightness control for OUTB0-3. Default value is 127. /// @@ -80,5 +84,7 @@ public interface ITlc59711Settings { /// maximum output current. /// byte BrightnessControlB { get; set; } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Channels.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Channels.cs index 6c019e7..b6934ca 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Channels.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Channels.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.Components.Controllers.Tlc59711 { /// @@ -81,6 +85,7 @@ public void Set(int index, UInt16 value) { #endregion #region Private Helpers + private static void ThrowOnInvalidChannelIndex(int index) { if (index >= 0 && index < NUMBER_OF_CHANNELS) { return; @@ -89,6 +94,7 @@ private static void ThrowOnInvalidChannelIndex(int index) { var message = string.Format("The index must be greater or equal than 0 and lower than {0}.", NUMBER_OF_CHANNELS); throw new ArgumentOutOfRangeException("index", index, message); } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs index c7588c6..82edf60 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs @@ -1,9 +1,13 @@ -using System; +#region References + +using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.Components.Controllers.Tlc59711 { /// @@ -22,6 +26,7 @@ public class Tlc59711Cluster : ITlc59711Cluster #endregion #region Instance Management + /// /// Creates a new instance of the class. /// @@ -51,6 +56,7 @@ public Tlc59711Cluster(IEnumerable devices) { this.devices = devices.ToArray(); channels = new Tlc59711ClusterChannels(this.devices); } + #endregion #region Properties diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs index 6a2d9de..cda95d3 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using System.Collections.Generic; +#endregion + namespace Raspberry.IO.Components.Controllers.Tlc59711 { /// @@ -32,15 +36,19 @@ public int ChannelIndex { private readonly List deviceMap = new List(); #endregion + #region Instance Management + /// /// Creates a new instance of the class. /// /// TLC59711 devices - public Tlc59711ClusterChannels(IEnumerable devices) { + public Tlc59711ClusterChannels(IEnumerable devices) + { if (devices == null) throw new ArgumentNullException("devices"); - foreach (var device in devices) { + foreach (var device in devices) + { if (ReferenceEquals(device, null)) continue; @@ -49,6 +57,8 @@ public Tlc59711ClusterChannels(IEnumerable devices) { } } + #endregion + #region Properties /// /// Indexer, which will allow client code to use [] notation on the class instance itself to modify PWM channel values. diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs index 66923b7..6e90609 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using Raspberry.IO.SerialPeripheralInterface; +#endregion + namespace Raspberry.IO.Components.Controllers.Tlc59711 { /// @@ -22,6 +26,7 @@ public class Tlc59711Connection : ITlc59711Connection #endregion #region Instance Management + /// /// Creates a new instance of the class and initializes it. /// @@ -69,6 +74,7 @@ protected virtual void Dispose(bool disposing) { connection.Dispose(); } } + #endregion #region Properties diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs index 682578f..20ac6e9 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.Components.Controllers.Tlc59711 { /// diff --git a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008AnalogPinExtensionMethods.cs b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008AnalogPinExtensionMethods.cs index ad19bcf..796bf93 100644 --- a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008AnalogPinExtensionMethods.cs +++ b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008AnalogPinExtensionMethods.cs @@ -2,9 +2,20 @@ namespace Raspberry.IO.Components.Converters.Mcp3008 { public static class Mcp3008AnalogPinExtensionMethods { + #region Methods + + /// + /// Creates an analog input pin. + /// + /// The connection. + /// The channel. + /// The scale. + /// The pin. public static Mcp3008InputAnalogPin In(this Mcp3008SpiConnection connection, Mcp3008Channel channel, decimal scale = 1.0m) { return new Mcp3008InputAnalogPin(connection, channel, scale); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008InputAnalogPin.cs b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008InputAnalogPin.cs index 8488b30..3d98ae6 100644 --- a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008InputAnalogPin.cs +++ b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008InputAnalogPin.cs @@ -2,10 +2,22 @@ namespace Raspberry.IO.Components.Converters.Mcp3008 { public class Mcp3008InputAnalogPin : IInputAnalogPin { + #region Fields + private readonly Mcp3008SpiConnection connection; private readonly Mcp3008Channel channel; private readonly decimal scale; + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The channel. + /// The scale. public Mcp3008InputAnalogPin(Mcp3008SpiConnection connection, Mcp3008Channel channel, decimal scale = 1.0m) { this.connection = connection; @@ -13,11 +25,26 @@ public Mcp3008InputAnalogPin(Mcp3008SpiConnection connection, Mcp3008Channel cha this.scale = scale; } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// public void Dispose(){} + #endregion + + #region Methods + + /// + /// Reads the value of the pin. + /// + /// + /// The value. + /// public decimal Read() { return connection.Read(channel)*scale; } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs index 14462e7..6b9ef87 100644 --- a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs +++ b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs @@ -47,6 +47,11 @@ void IDisposable.Dispose() #region Methods + /// + /// Reads the specified channel. + /// + /// The channel. + /// The value public decimal Read(Mcp3008Channel channel) { using(spiConnection.SelectSlave()) @@ -70,6 +75,9 @@ public decimal Read(Mcp3008Channel channel) } } + /// + /// Closes this instance. + /// public void Close() { spiConnection.Close(); diff --git a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822AnalogPinExtensionMethods.cs b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822AnalogPinExtensionMethods.cs index 17f4092..e6342ae 100644 --- a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822AnalogPinExtensionMethods.cs +++ b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822AnalogPinExtensionMethods.cs @@ -2,9 +2,20 @@ namespace Raspberry.IO.Components.Converters.Mcp4822 { public static class Mcp4822AnalogPinExtensionMethods { + #region Methods + + /// + /// Creates an output analog pin. + /// + /// The connection. + /// The channel. + /// The scale. + /// The pin. public static Mcp4822OutputAnalogPin Out(this Mcp4822SpiConnection connection, Mcp4822Channel channel, decimal scale = 1.0m) { return new Mcp4822OutputAnalogPin(connection, channel, scale); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822OutputAnalogPin.cs b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822OutputAnalogPin.cs index ec49d11..2cc26a9 100644 --- a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822OutputAnalogPin.cs +++ b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822OutputAnalogPin.cs @@ -2,10 +2,22 @@ namespace Raspberry.IO.Components.Converters.Mcp4822 { public class Mcp4822OutputAnalogPin : IOutputAnalogPin { + #region Fields + private readonly Mcp4822SpiConnection connection; private readonly Mcp4822Channel channel; private readonly decimal scale; + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The channel. + /// The scale. public Mcp4822OutputAnalogPin(Mcp4822SpiConnection connection, Mcp4822Channel channel, decimal scale = 1.0m) { this.connection = connection; @@ -13,11 +25,26 @@ public Mcp4822OutputAnalogPin(Mcp4822SpiConnection connection, Mcp4822Channel ch this.scale = scale; } - public void Dispose() { } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + } + + #endregion + #region Methods + + /// + /// Writes the specified value to the pin. + /// + /// The value. public void Write(decimal value) { - connection.Write(channel, value / scale); + connection.Write(channel, value/scale); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs index 49e6461..45c7c0a 100644 --- a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs +++ b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs @@ -13,7 +13,6 @@ namespace Raspberry.IO.Components.Converters.Mcp4822 /// See http://ww1.microchip.com/downloads/en/DeviceDoc/22249A.pdf for specifications. public class Mcp4822SpiConnection : IDisposable { - #region Fields private readonly SpiConnection spiConnection; @@ -45,11 +44,19 @@ void IDisposable.Dispose() #region Methods + /// + /// Closes this instance. + /// public void Close() { spiConnection.Close(); } + /// + /// Writes the specified data. + /// + /// The channel. + /// The data. public void Write(Mcp4822Channel channel, decimal data) { using (spiConnection.SelectSlave()) diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780A00Encoding.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780A00Encoding.cs index f07f141..2d70bc5 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780A00Encoding.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780A00Encoding.cs @@ -40,11 +40,31 @@ public static IEnumerable SupportedCharacters #region Methods + /// + /// When overridden in a derived class, calculates the number of bytes produced by encoding a set of characters from the specified character array. + /// + /// The character array containing the set of characters to encode. + /// The index of the first character to encode. + /// The number of characters to encode. + /// + /// The number of bytes produced by encoding the specified characters. + /// public override int GetByteCount(char[] chars, int index, int count) { return count; } + /// + /// When overridden in a derived class, encodes a set of characters from the specified character array into the specified byte array. + /// + /// The character array containing the set of characters to encode. + /// The index of the first character to encode. + /// The number of characters to encode. + /// The byte array to contain the resulting sequence of bytes. + /// The index at which to start writing the resulting sequence of bytes. + /// + /// The actual number of bytes written into . + /// public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { Array.Copy( @@ -65,11 +85,31 @@ public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] return charCount; } + /// + /// When overridden in a derived class, calculates the number of characters produced by decoding a sequence of bytes from the specified byte array. + /// + /// The byte array containing the sequence of bytes to decode. + /// The index of the first byte to decode. + /// The number of bytes to decode. + /// + /// The number of characters produced by decoding the specified sequence of bytes. + /// public override int GetCharCount(byte[] bytes, int index, int count) { return count; } + /// + /// When overridden in a derived class, decodes a sequence of bytes from the specified byte array into the specified character array. + /// + /// The byte array containing the sequence of bytes to decode. + /// The index of the first byte to decode. + /// The number of bytes to decode. + /// The character array to contain the resulting set of characters. + /// The index at which to start writing the resulting set of characters. + /// + /// The actual number of characters written into . + /// public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { Array.Copy( @@ -90,11 +130,25 @@ public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] return byteCount; } + /// + /// When overridden in a derived class, calculates the maximum number of bytes produced by encoding the specified number of characters. + /// + /// The number of characters to encode. + /// + /// The maximum number of bytes produced by encoding the specified number of characters. + /// public override int GetMaxByteCount(int charCount) { return charCount; } + /// + /// When overridden in a derived class, calculates the maximum number of characters produced by decoding the specified number of bytes. + /// + /// The number of bytes to decode. + /// + /// The maximum number of characters produced by decoding the specified number of bytes. + /// public override int GetMaxCharCount(int byteCount) { return byteCount; diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs index 6eeb491..32dd245 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs @@ -130,6 +130,12 @@ void IDisposable.Dispose() #region Properties + /// + /// Gets or sets a value indicating whether display is enabled. + /// + /// + /// true if display is enabled; otherwise, false. + /// public bool DisplayEnabled { get { return (displayFlags & DisplayFlags.DisplayOn) == DisplayFlags.DisplayOn; } @@ -144,6 +150,12 @@ public bool DisplayEnabled } } + /// + /// Gets or sets a value indicating whether cursor is enabled. + /// + /// + /// true if cursor is enabled; otherwise, false. + /// public bool CursorEnabled { get { return (displayFlags & DisplayFlags.CursorOn) == DisplayFlags.CursorOn; } @@ -158,6 +170,12 @@ public bool CursorEnabled } } + /// + /// Gets or sets a value indicating whether cursor is blinking. + /// + /// + /// true if cursor is blinking; otherwise, false. + /// public bool CursorBlinking { get { return (displayFlags & DisplayFlags.BlinkOn) == DisplayFlags.BlinkOn; } @@ -176,6 +194,9 @@ public bool CursorBlinking #region Methods + /// + /// Closes this instance. + /// public void Close() { Clear(); @@ -186,6 +207,9 @@ public void Close() dataPin.Dispose(); } + /// + /// Set cursor to top left corner. + /// public void Home() { WriteCommand(Command.ReturnHome); @@ -195,6 +219,9 @@ public void Home() Sleep(3); } + /// + /// Clears the display. + /// public void Clear() { WriteCommand(Command.ClearDisplay); @@ -204,6 +231,10 @@ public void Clear() Sleep(3); // Clearing the display takes a long time } + /// + /// Moves the cursor of the specified offset. + /// + /// The offset. public void Move(int offset) { var count = offset > 0 ? offset : -offset; @@ -211,6 +242,11 @@ public void Move(int offset) WriteCommand(Command.MoveCursor, (int)(CursorShiftFlags.DisplayMove | (offset < 0 ? CursorShiftFlags.MoveLeft : CursorShiftFlags.MoveRight))); } + /// + /// Sets the custom character. + /// + /// The character. + /// The pattern. public void SetCustomCharacter(byte character, byte[] pattern) { if ((functions & Functions.Matrix5x8) == Functions.Matrix5x8) @@ -219,41 +255,83 @@ public void SetCustomCharacter(byte character, byte[] pattern) Set5x10CustomCharacter(character, pattern); } + /// + /// Writes the line. + /// + /// The value. + /// The animation delay. public void WriteLine(object value, decimal animationDelay = 0m) { WriteLine("{0}", value, animationDelay); } + /// + /// Writes the line. + /// + /// The text. + /// The animation delay. public void WriteLine(string text, decimal animationDelay = 0m) { Write(text + Environment.NewLine, animationDelay); } + /// + /// Writes the specified value. + /// + /// The value. + /// The animation delay. public void Write(object value, decimal animationDelay = 0m) { Write("{0}", value, animationDelay); } + /// + /// Writes the line. + /// + /// The format. + /// The values. public void WriteLine(string format, params object[] values) { WriteLine(string.Format(format, values)); } + /// + /// Writes the specified format. + /// + /// The format. + /// The values. public void Write(string format, params object[] values) { Write(string.Format(format, values)); } + /// + /// Writes the line. + /// + /// The format. + /// The animation delay. + /// The values. public void WriteLine(string format, decimal animationDelay, params object[] values) { WriteLine(string.Format(format, values), animationDelay); } + /// + /// Writes the specified format. + /// + /// The format. + /// The animation delay. + /// The values. public void Write(string format, decimal animationDelay, params object[] values) { Write(string.Format(format, values), animationDelay); } + /// + /// Writes the specified text. + /// + /// The text. + /// The animation delay. public void Write(string text, decimal animationDelay = 0m) { var lines = text.Split(new[] {Environment.NewLine}, StringSplitOptions.None); diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnectionSettings.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnectionSettings.cs index 6bd50cb..90fde16 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnectionSettings.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnectionSettings.cs @@ -4,6 +4,11 @@ namespace Raspberry.IO.Components.Displays.Hd44780 { public class Hd44780LcdConnectionSettings { + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// public Hd44780LcdConnectionSettings() { ScreenWidth = 20; @@ -15,13 +20,52 @@ public Hd44780LcdConnectionSettings() //RightToLeft = false; } + #endregion + + #region Properties + + /// + /// Gets or sets the width of the screen. + /// + /// + /// The width of the screen. + /// public int ScreenWidth { get; set; } + + /// + /// Gets or sets the height of the screen. + /// + /// + /// The height of the screen. + /// public int ScreenHeight { get; set; } + /// + /// Gets or sets the width of the pattern. + /// + /// + /// The width of the pattern. + /// public int PatternWidth { get; set; } + + /// + /// Gets or sets the height of the pattern. + /// + /// + /// The height of the pattern. + /// public int PatternHeight { get; set; } + /// + /// Gets or sets the encoding. + /// + /// + /// The encoding. + /// public Encoding Encoding { get; set; } + //public bool RightToLeft { get; set; } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs index b81dbda..0c1c6b1 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs @@ -1,13 +1,35 @@ +#region References + using System; +#endregion + namespace Raspberry.IO.Components.Expanders.Mcp23017 { + /// + /// Represents a binary intput pin on a MCP23017 I/O expander. + /// public class Mcp23017InputBinaryPin : IInputBinaryPin { + #region Fields + private readonly Mcp23017I2cConnection connection; private readonly Mcp23017Pin pin; - public Mcp23017InputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + public Mcp23017InputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, + Mcp23017PinResistor resistor = Mcp23017PinResistor.None, + Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { this.connection = connection; this.pin = pin; @@ -17,13 +39,32 @@ public Mcp23017InputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, connection.SetPolarity(pin, polarity); } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// public void Dispose(){} + #endregion + + #region Methods + + /// + /// Reads the state of the pin. + /// + /// + /// true if the pin is in high state; otherwise, false. + /// public bool Read() { return connection.GetPinStatus(pin); } + /// + /// Waits for the specified pin to be in the specified state. + /// + /// if set to true waits for the pin to be up. + /// The timeout, in milliseconds. + /// A timeout occurred while waiting for pin status to change public void Wait(bool waitForUp = true, decimal timeout = 0) { var startWait = DateTime.Now; @@ -32,9 +73,11 @@ public void Wait(bool waitForUp = true, decimal timeout = 0) while (Read() != waitForUp) { - if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) + if (DateTime.Now.Ticks - startWait.Ticks >= 10000*timeout) throw new TimeoutException("A timeout occurred while waiting for pin status to change"); } } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputBinaryPin.cs index 645480d..3580735 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputBinaryPin.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputBinaryPin.cs @@ -1,11 +1,29 @@ namespace Raspberry.IO.Components.Expanders.Mcp23017 { + /// + /// Represents a binary output pin on a MCP23017 I/O expander. + /// public class Mcp23017OutputBinaryPin : IOutputBinaryPin { + #region Properties + private readonly Mcp23017I2cConnection connection; private readonly Mcp23017Pin pin; - public Mcp23017OutputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + public Mcp23017OutputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, + Mcp23017PinResistor resistor = Mcp23017PinResistor.None, + Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { this.connection = connection; this.pin = pin; @@ -15,11 +33,26 @@ public Mcp23017OutputBinaryPin(Mcp23017I2cConnection connection, Mcp23017Pin pin connection.SetPolarity(pin, polarity); } - public void Dispose(){} + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + } + + #endregion + #region Methods + + /// + /// Writes the value of the pin. + /// + /// if set to true, pin is set to high state. public void Write(bool state) { connection.SetPinStatus(pin, state); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs index 6e0a60c..3a023b2 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs @@ -1,15 +1,38 @@ namespace Raspberry.IO.Components.Expanders.Mcp23017 { + /// + /// Provides extension methods for MCP23017 pins. + /// public static class Mcp23017PinExtensionMethods { + #region Methods + + /// + /// Creates an output binary pin. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + /// The pin. public static Mcp23017OutputBinaryPin Out(this Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { return new Mcp23017OutputBinaryPin(connection, pin, resistor, polarity); - } - + } + + /// + /// Creates an input binary pin. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + /// The pin. public static Mcp23017InputBinaryPin In(this Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { return new Mcp23017InputBinaryPin(connection, pin, resistor, polarity); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs b/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs index 4dc320c..622fbaf 100644 --- a/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs +++ b/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs @@ -87,7 +87,7 @@ public decimal GetDistance() triggerPin.Write(false); var upTime = echoPin.Time(true, echoUpTimeout, Timeout); - return Units.Velocity.Sound.ToDistance(upTime); + return Units.Velocity.Sound.ToDistance(upTime) / 2; } /// diff --git a/Raspberry.IO.Components/Sensors/HcSr04/Units.cs b/Raspberry.IO.Components/Sensors/HcSr04/Units.cs index 9a8b64a..29df6d0 100644 --- a/Raspberry.IO.Components/Sensors/HcSr04/Units.cs +++ b/Raspberry.IO.Components/Sensors/HcSr04/Units.cs @@ -2,17 +2,32 @@ namespace Raspberry.IO.Components.Sensors.HcSr04 { internal static class Units { + /// + /// Velocity related conversions + /// public static class Velocity { + /// + /// Sound velocity related conversions + /// public static class Sound { + #region Methods + + /// + /// Converts a time to a distance. + /// + /// The time, in milliseconds. + /// The distance travelled by sound in one second, in meters. public static decimal ToDistance(decimal time) { if (time == decimal.MinValue) return decimal.MinValue; - return (time * 340) / (2 * 1000m); + return (time*340)/1000m; } + + #endregion } } } diff --git a/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs index c1eacf1..4583b40 100644 --- a/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs +++ b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs @@ -12,10 +12,12 @@ public enum SpiTransferMode /// Write data to the chip. /// Write = 1, + /// /// Read data from the chip. /// Read = 2, + /// /// Write and read data simultaneously. /// diff --git a/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs index 5ec17ce..7dcef5e 100644 --- a/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs @@ -1,4 +1,8 @@ -using System; +#region References + +using System; + +#endregion namespace Raspberry.IO.SerialPeripheralInterface { @@ -7,23 +11,32 @@ namespace Raspberry.IO.SerialPeripheralInterface /// public interface INativeSpiConnection : IDisposable { + #region Properties + /// /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. /// UInt16 Delay { get; } + /// /// Maximum clock speed in Hz. /// UInt32 MaxSpeed { get; } + /// /// SPI mode /// SpiMode Mode { get; } + /// /// The device's wordsize /// byte BitsPerWord { get; } + #endregion + + #region Methods + /// /// Sets the . /// @@ -63,7 +76,8 @@ public interface INativeSpiConnection : IDisposable /// Message size in bytes. /// The transfer mode. /// The requested transfer buffer collection. - ISpiTransferBufferCollection CreateTransferBufferCollection(int numberOfMessages, int messageSizeInBytes, SpiTransferMode transferMode); + ISpiTransferBufferCollection CreateTransferBufferCollection(int numberOfMessages, int messageSizeInBytes, + SpiTransferMode transferMode); /// /// Starts the SPI data transfer. @@ -78,5 +92,7 @@ public interface INativeSpiConnection : IDisposable /// The transfer buffers that contain data to be send and/or the received data. /// An that contains the result of the transfer operation. int Transfer(ISpiTransferBufferCollection transferBuffers); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs index 3dc8e1e..7bd7e04 100644 --- a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs +++ b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -8,46 +12,89 @@ namespace Raspberry.IO.SerialPeripheralInterface /// public interface ISpiTransferBuffer : IDisposable { + #region Properties + /// /// Temporary override of the device's wordsize /// + /// + /// The bits per word. + /// byte BitsPerWord { get; set; } + /// /// Temporary override of the device's bitrate (in Hz) /// + /// + /// The speed. + /// UInt32 Speed { get; set; } + /// /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. /// + /// + /// The delay. + /// UInt16 Delay { get; set; } + /// /// Set to true to deselect device before starting the next transfer. /// + /// + /// true if device is delected before starting next transfer; otherwise, false. + /// bool ChipSelectChange { get; set; } + /// - /// Pad + /// Pad. /// + /// + /// The pad. + /// UInt32 Pad { get; set; } + /// - /// Specifies if the transfer shall read and/or write. + /// Specifies if the transfer shall read and/or write. /// + /// + /// The transfer mode. + /// SpiTransferMode TransferMode { get; } + /// - /// Length of and buffers, in bytes + /// Length of and buffers, in bytes /// + /// + /// The length. + /// int Length { get; } + /// /// Holds pointer to userspace buffer with transmit data, or null. If no data is provided, zeroes are shifted out /// + /// + /// The tx. + /// IMemory Tx { get; } + /// /// Holds pointer to userspace buffer for receive data, or null /// + /// + /// The rx. + /// IMemory Rx { get; } /// /// The IOCTL structure that contains control information for a single SPI transfer /// + /// + /// The control structure. + /// SpiTransferControlStructure ControlStructure { get; } + + #endregion + } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs index 6041e95..a47aab1 100644 --- a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using System.Collections.Generic; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -8,6 +12,8 @@ namespace Raspberry.IO.SerialPeripheralInterface /// public interface ISpiTransferBufferCollection : IDisposable, IEnumerable { + #region Properties + /// /// Number of structures. /// @@ -19,12 +25,18 @@ public interface ISpiTransferBufferCollection : IDisposable, IEnumerableIndex /// The requested ISpiTransferBuffer this[int index] { get; } - + + #endregion + + #region Methods + /// /// A method that returns a specific from the collection. /// /// Index /// The requested ISpiTransferBuffer Get(int index); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs b/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs index 98d7e05..c3759d2 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs +++ b/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using System.Runtime.InteropServices; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -9,11 +13,13 @@ namespace Raspberry.IO.SerialPeripheralInterface [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct SpiTransferControlStructure { + #region Properties + /// /// Holds pointer to userspace buffer with transmit data, or 0. If no data is provided, zeroes are shifted out /// public UInt64 Tx; - + /// /// Holds pointer to userspace buffer for receive data, or 0 /// @@ -23,7 +29,7 @@ public struct SpiTransferControlStructure /// Length of and buffers, in bytes /// public UInt32 Length; - + /// /// Temporary override of the device's bitrate (in Hz) /// @@ -48,5 +54,7 @@ public struct SpiTransferControlStructure /// Pad /// public UInt32 Pad; + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs index 65cb4b2..7c99310 100644 --- a/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs @@ -1,7 +1,11 @@ -using System; +#region References + +using System; using System.Linq; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -117,6 +121,7 @@ public byte BitsPerWord { #endregion #region Methods + /// /// Sets the . /// diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs index c844188..2a52447 100644 --- a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using Raspberry.IO.Interop; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -101,6 +105,7 @@ public SpiTransferControlStructure ControlStructure { #endregion #region Instance Management + /// /// Initializes a new instance of the class. /// @@ -170,6 +175,7 @@ protected virtual void Dispose(bool disposing) { rxBuf.Dispose(); } } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs index 4ef0b46..dd40abd 100644 --- a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs @@ -1,9 +1,13 @@ -using System; +#region References + +using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface { /// @@ -16,6 +20,7 @@ public class SpiTransferBufferCollection : ISpiTransferBufferCollection #endregion #region Instance Management + /// /// Initializes a new instance of the class. /// @@ -60,9 +65,11 @@ protected virtual void Dispose(bool disposing) { transferBuffers = new ISpiTransferBuffer[0]; } } + #endregion #region Properties + /// /// Number of structures. /// @@ -78,9 +85,11 @@ public int Length { public ISpiTransferBuffer this[int index] { get { return transferBuffers[index]; } } + #endregion #region Methods + /// /// A method that returns a specific from the collection. /// @@ -105,6 +114,7 @@ public IEnumerator GetEnumerator() { IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO/ByteExtensionMethods.cs b/Raspberry.IO/ByteExtensionMethods.cs index f8d1434..c67226d 100644 --- a/Raspberry.IO/ByteExtensionMethods.cs +++ b/Raspberry.IO/ByteExtensionMethods.cs @@ -1,8 +1,12 @@ -using System; +#region References + +using System; using System.Collections.Generic; using System.Linq; using System.Text; +#endregion + namespace Raspberry.IO { /// @@ -10,20 +14,27 @@ namespace Raspberry.IO /// public static class ByteExtensionMethods { + #region Methods + /// /// Converts a byte array/enumerable to a bit string. /// /// bytes to be converted. /// A bit string - public static string ToBitString(this IEnumerable bytes) { + public static string ToBitString(this IEnumerable bytes) + { var sb = new StringBuilder(255); - foreach (var value in bytes.Select(@byte => Convert.ToString(@byte, 2))) { - if (value.Length < 8) { + foreach (var value in bytes.Select(@byte => Convert.ToString(@byte, 2))) + { + if (value.Length < 8) + { sb.Append(new string('0', 8 - value.Length)); } sb.Append(value); } return sb.ToString(); } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO/StringExtensionMethods.cs b/Raspberry.IO/StringExtensionMethods.cs index 7467d70..9cd8e82 100644 --- a/Raspberry.IO/StringExtensionMethods.cs +++ b/Raspberry.IO/StringExtensionMethods.cs @@ -1,6 +1,10 @@ -using System; +#region References + +using System; using System.Linq; +#endregion + namespace Raspberry.IO { /// @@ -8,22 +12,27 @@ namespace Raspberry.IO /// public static class StringExtensionMethods { + #region Methods + /// /// Converts a bit string in MSBF order (most significant bit first) to a byte array. /// /// A bit string (e.g. "00101111"). /// If true the bit string will be prefixed with '0' if it is not divisible by 8. /// An array starting with the most significant byte. - public static byte[] BitStringToArray(this string bitString, bool prefixWithZero) { - var requiredPrefixBits = bitString.Length % 8; + public static byte[] BitStringToArray(this string bitString, bool prefixWithZero) + { + var requiredPrefixBits = bitString.Length%8; var @string = (requiredPrefixBits > 0 && prefixWithZero) ? new string('0', requiredPrefixBits) + bitString : bitString; return Enumerable - .Range(0, @string.Length / 8) - .Select(pos => Convert.ToByte(@string.Substring(pos * 8, 8), 2)) + .Range(0, @string.Length/8) + .Select(pos => Convert.ToByte(@string.Substring(pos*8, 8), 2)) .ToArray(); } + + #endregion } } \ No newline at end of file From c33941f30f2abfd0149237675546b27649672280 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Tue, 8 Jul 2014 00:28:16 +0200 Subject: [PATCH 148/227] Bugfix: Using FileGpioConnectionDriver as non-root user The system needs some time in order to set the file permissions in /sys/class/gpio. --- .../FileGpioConnectionDriver.cs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 44e559c..34f9aeb 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -3,6 +3,8 @@ using System; using System.IO; using System.Linq; +using System.Security; +using System.Threading; #endregion @@ -49,10 +51,15 @@ public void Allocate(ProcessorPin pin, PinDirection direction) streamWriter.Write((int)pin); var filePath = Path.Combine(gpioId, "direction"); - using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) - streamWriter.Write(direction == PinDirection.Input ? "in" : "out"); + try { + SetPinDirection(filePath, direction); + } catch (UnauthorizedAccessException) { + // program hasn't been started as root, give it a second to correct file permissions + Thread.Sleep(TimeSpan.FromSeconds(1)); + SetPinDirection(filePath, direction); + } } - + /// /// Sets the pin resistor. /// @@ -156,5 +163,17 @@ public ProcessorPins Read(ProcessorPins pins) } #endregion + + #region Private Helpers + + private static void SetPinDirection(string filePath, PinDirection direction) { + using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) { + streamWriter.Write(direction == PinDirection.Input + ? "in" + : "out"); + } + } + + #endregion } } \ No newline at end of file From 7b784fe07ed96115e12e46557954bef53161e1ba Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Tue, 8 Jul 2014 21:54:15 +0200 Subject: [PATCH 149/227] Bugfix: Using FileGpioConnectionDriver as non-root user "SetPinDirection": use full file path to GPIO pin value. --- Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index ffd8b92..5f83da4 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -50,7 +50,7 @@ public void Allocate(ProcessorPin pin, PinDirection direction) using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, "export"), false)) streamWriter.Write((int)pin); - var filePath = Path.Combine(gpioId, "direction"); + var filePath = Path.Combine(gpioPath, gpioId, "direction"); try { SetPinDirection(filePath, direction); } catch (UnauthorizedAccessException) { @@ -166,8 +166,8 @@ public ProcessorPins Read(ProcessorPins pins) #region Private Helpers - private static void SetPinDirection(string filePath, PinDirection direction) { - using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) { + private static void SetPinDirection(string fullFilePath, PinDirection direction) { + using (var streamWriter = new StreamWriter(fullFilePath, false)) { streamWriter.Write(direction == PinDirection.Input ? "in" : "out"); From a8eec1c95deea0b755a3f37f54cbc621dbcc2f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 10 Jul 2014 01:09:47 +0200 Subject: [PATCH 150/227] HD44780 - Added I2C device address parameter --- Tests/Test.Gpio.HD44780/Program.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tests/Test.Gpio.HD44780/Program.cs b/Tests/Test.Gpio.HD44780/Program.cs index 7194dee..7cca9c9 100644 --- a/Tests/Test.Gpio.HD44780/Program.cs +++ b/Tests/Test.Gpio.HD44780/Program.cs @@ -1,6 +1,8 @@ #region References using System; +using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Net.NetworkInformation; using System.Threading; @@ -27,7 +29,7 @@ static void Main(string[] args) var useI2c = args.Contains("i2c", StringComparer.InvariantCultureIgnoreCase); - using (var configuration = useI2c ? LoadI2cConfiguration() : LoadGpioConfiguration()) + using (var configuration = useI2c ? LoadI2cConfiguration(args) : LoadGpioConfiguration()) using (var connection = new Hd44780LcdConnection( settings, configuration.RegisterSelect, @@ -116,8 +118,13 @@ static void Main(string[] args) #region Private Helpers - private static Hd44780Configuration LoadI2cConfiguration() + private static Hd44780Configuration LoadI2cConfiguration(IEnumerable args) { + var addressText = args.SkipWhile(s => !string.Equals(s, "i2c", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); + var address = addressText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) + ? int.Parse(addressText.Substring(2), NumberStyles.HexNumber) + : int.Parse(addressText); + const Mcp23017Pin registerSelectPin = Mcp23017Pin.B7; const Mcp23017Pin clockPin = Mcp23017Pin.B5; var dataPins = new[] @@ -142,7 +149,7 @@ private static Hd44780Configuration LoadI2cConfiguration() const ConnectorPin sclPin = ConnectorPin.P1Pin05; var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) {ClockDivider = 512}; - var connection = new Mcp23017I2cConnection(driver.Connect(0x20)); + var connection = new Mcp23017I2cConnection(driver.Connect(address)); return new Hd44780Configuration(driver) { From 0ec52e1de25fc15c39534d9e63be5661702a4697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 15 Jul 2014 20:01:21 +0200 Subject: [PATCH 151/227] Added support for PCF8574 I2C Expander Also fixed issues on HD44780 connection and updated sample --- .../Displays/Hd44780/Hd44780LcdConnection.cs | 118 +++++++----- .../Displays/Hd44780/Hd44780Pins.cs | 104 +++++++++++ .../Mcp23017/Mcp23017I2cConnection.cs | 8 +- .../Expanders/Pcf8574/Pcf8574I2cConnection.cs | 123 +++++++++++++ .../Pcf8574/Pcf8574InputBinaryPin.cs | 77 ++++++++ .../Pcf8574/Pcf8574OutputBinaryPin.cs | 52 ++++++ .../Expanders/Pcf8574/Pcf8574Pin.cs | 14 ++ .../Pcf8574/Pcf8574PinExtensionMethods.cs | 34 ++++ .../Raspberry.IO.Components.csproj | 6 + .../Test.Gpio.HD44780/ConfigurationLoader.cs | 168 ++++++++++++++++++ .../Test.Gpio.HD44780/Hd44780Configuration.cs | 5 +- Tests/Test.Gpio.HD44780/Program.cs | 87 +-------- .../Test.Gpio.HD44780.csproj | 1 + 13 files changed, 658 insertions(+), 139 deletions(-) create mode 100644 Raspberry.IO.Components/Displays/Hd44780/Hd44780Pins.cs create mode 100644 Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574I2cConnection.cs create mode 100644 Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574InputBinaryPin.cs create mode 100644 Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574OutputBinaryPin.cs create mode 100644 Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574Pin.cs create mode 100644 Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574PinExtensionMethods.cs create mode 100644 Tests/Test.Gpio.HD44780/ConfigurationLoader.cs diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs index 32dd245..ed330bf 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using Raspberry.Timers; @@ -20,9 +19,7 @@ public class Hd44780LcdConnection : IDisposable { #region Fields - private readonly IOutputBinaryPin registerSelectPin; - private readonly IOutputBinaryPin clockPin; - private readonly IOutputBinaryPin[] dataPins; + private readonly Hd44780Pins pins; private readonly int width; private readonly int height; @@ -35,52 +32,54 @@ public class Hd44780LcdConnection : IDisposable private int currentRow; private int currentColumn; + private bool backlightEnabled; + #endregion #region Instance Management /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The register select pin. /// The clock pin. /// The data pins. - public Hd44780LcdConnection(IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, params IOutputBinaryPin[] dataPins) : this(null, registerSelectPin, clockPin, (IEnumerable)dataPins) { } + public Hd44780LcdConnection(IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, params IOutputBinaryPin[] dataPins) : this(null, new Hd44780Pins(registerSelectPin, clockPin, dataPins)) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The register select pin. /// The clock pin. /// The data pins. - public Hd44780LcdConnection(IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, IEnumerable dataPins) : this(null, registerSelectPin, clockPin, dataPins) { } + public Hd44780LcdConnection(IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, IEnumerable dataPins) : this(null, new Hd44780Pins(registerSelectPin, clockPin, dataPins)) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The settings. - /// The register select pin. - /// The clock pin. - /// The data pins. - public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, params IOutputBinaryPin[] dataPins) : this(settings, registerSelectPin, clockPin, (IEnumerable)dataPins) { } - - /// - /// Initializes a new instance of the class. - /// - /// The settings. - /// The register select pin. - /// The clock pin. - /// The data pins. - public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinaryPin registerSelectPin, IOutputBinaryPin clockPin, IEnumerable dataPins) + /// The pins. + /// + /// dataPins;There must be either 4 or 8 data pins + /// or + /// settings;ScreenHeight must be either 1 or 2 rows + /// or + /// settings;PatternWidth must be 5 pixels + /// or + /// settings;PatternWidth must be either 7 or 10 pixels height + /// + /// + /// At most 80 characters are allowed + /// or + /// 10 pixels height pattern cannot be used with 2 rows + /// + public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, Hd44780Pins pins) { settings = settings ?? new Hd44780LcdConnectionSettings(); + this.pins = pins; - this.registerSelectPin = registerSelectPin; - this.clockPin = clockPin; - this.dataPins = dataPins.ToArray(); - - if (this.dataPins.Length != 4 && this.dataPins.Length != 8) - throw new ArgumentOutOfRangeException("dataPins", this.dataPins.Length, "There must be either 4 or 8 data pins"); + if (pins.Data.Length != 4 && pins.Data.Length != 8) + throw new ArgumentOutOfRangeException("pins", pins.Data.Length, "There must be either 4 or 8 data pins"); width = settings.ScreenWidth; height = settings.ScreenHeight; @@ -98,7 +97,7 @@ public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinary functions = (settings.PatternHeight == 8 ? Functions.Matrix5x8 : Functions.Matrix5x10) | (height == 1 ? Functions.OneLine : Functions.TwoLines) - | (this.dataPins.Length == 4 ? Functions.Data4bits : Functions.Data8bits); + | (pins.Data.Length == 4 ? Functions.Data4bits : Functions.Data8bits); entryModeFlags = /*settings.RightToLeft ? EntryModeFlags.EntryRight | EntryModeFlags.EntryShiftDecrement @@ -106,9 +105,14 @@ public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinary encoding = settings.Encoding; - registerSelectPin.Write(false); - clockPin.Write(false); - foreach (var dataPin in this.dataPins) + BacklightEnabled = false; + + if (pins.ReadWrite != null) + pins.ReadWrite.Write(false); + + pins.RegisterSelect.Write(false); + pins.Clock.Write(false); + foreach (var dataPin in pins.Data) dataPin.Write(false); WriteByte(0x33, false); // Initialize @@ -119,6 +123,7 @@ public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinary WriteCommand(Command.SetEntryModeFlags, (int) entryModeFlags); Clear(); + BacklightEnabled = true; } void IDisposable.Dispose() @@ -150,6 +155,25 @@ public bool DisplayEnabled } } + /// + /// Gets or sets a value indicating whether backlight is enabled. + /// + /// + /// true if backlight is enabled; otherwise, false. + /// + public bool BacklightEnabled + { + get { return backlightEnabled; } + set + { + if (pins.Backlight == null) + return; + + pins.Backlight.Write(value); + backlightEnabled = value; + } + } + /// /// Gets or sets a value indicating whether cursor is enabled. /// @@ -200,11 +224,7 @@ public bool CursorBlinking public void Close() { Clear(); - - registerSelectPin.Dispose(); - clockPin.Dispose(); - foreach (var dataPin in dataPins) - dataPin.Dispose(); + pins.Close(); } /// @@ -408,7 +428,7 @@ private void Set5x8CustomCharacter(byte character, byte[] pattern) private void WriteByte(int bits, bool charMode) { - if (dataPins.Length == 4) + if (pins.Data.Length == 4) WriteByte4Pins(bits, charMode); else throw new NotImplementedException("8 bits mode is currently not implemented"); @@ -416,29 +436,29 @@ private void WriteByte(int bits, bool charMode) private void WriteByte4Pins(int bits, bool charMode) { - registerSelectPin.Write(charMode); + pins.RegisterSelect.Write(charMode); - dataPins[0].Write((bits & 0x10) != 0); - dataPins[1].Write((bits & 0x20) != 0); - dataPins[2].Write((bits & 0x40) != 0); - dataPins[3].Write((bits & 0x80) != 0); + pins.Data[0].Write((bits & 0x10) != 0); + pins.Data[1].Write((bits & 0x20) != 0); + pins.Data[2].Write((bits & 0x40) != 0); + pins.Data[3].Write((bits & 0x80) != 0); Synchronize(); - dataPins[0].Write((bits & 0x01) != 0); - dataPins[1].Write((bits & 0x02) != 0); - dataPins[2].Write((bits & 0x04) != 0); - dataPins[3].Write((bits & 0x08) != 0); + pins.Data[0].Write((bits & 0x01) != 0); + pins.Data[1].Write((bits & 0x02) != 0); + pins.Data[2].Write((bits & 0x04) != 0); + pins.Data[3].Write((bits & 0x08) != 0); Synchronize(); } private void Synchronize() { - clockPin.Write(true); + pins.Clock.Write(true); Sleep(0.001m); // 1 microsecond pause - enable pulse must be > 450ns - clockPin.Write(false); + pins.Clock.Write(false); Sleep(0.001m); // commands need > 37us to settle } diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780Pins.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780Pins.cs new file mode 100644 index 0000000..fdc9716 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780Pins.cs @@ -0,0 +1,104 @@ +#region References + +using System; +using System.Collections.Generic; +using System.Linq; + +#endregion + +namespace Raspberry.IO.Components.Displays.Hd44780 +{ + /// + /// Represents the pins of a HD44780 LCD display. + /// + public class Hd44780Pins : IDisposable + { + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The register select. + /// The clock. + /// The data. + public Hd44780Pins(IOutputBinaryPin registerSelect, IOutputBinaryPin clock, IEnumerable data) + : this(registerSelect, clock, data.ToArray()) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The register select. + /// The clock. + /// The data. + public Hd44780Pins(IOutputBinaryPin registerSelect, IOutputBinaryPin clock, params IOutputBinaryPin[] data) + { + RegisterSelect = registerSelect; + Clock = clock; + Data = data; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Properties + + /// + /// The register select (RS) pin. + /// + public IOutputBinaryPin RegisterSelect { get; private set; } + + /// + /// The clock (EN) pin. + /// + public IOutputBinaryPin Clock { get; private set; } + + /// + /// The backlight pin. + /// + public IOutputBinaryPin Backlight; + + /// + /// The read write (RW) pin. + /// + public IOutputBinaryPin ReadWrite; + + /// + /// The data pins. + /// + public IOutputBinaryPin[] Data { get; private set; } + + #endregion + + #region Methods + + /// + /// Closes this instance. + /// + public void Close() + { + + RegisterSelect.Dispose(); + Clock.Dispose(); + + if (Backlight != null) + Backlight.Dispose(); + if (ReadWrite != null) + ReadWrite.Dispose(); + + foreach (var dataPin in Data) + dataPin.Dispose(); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017I2cConnection.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017I2cConnection.cs index 01650b9..e108aea 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017I2cConnection.cs @@ -1,5 +1,9 @@ +#region References + using Raspberry.IO.InterIntegratedCircuit; +#endregion + namespace Raspberry.IO.Components.Expanders.Mcp23017 { /// @@ -93,7 +97,7 @@ public void SetResistor(Mcp23017Pin pin, Mcp23017PinResistor resistor) /// Sets the pin status. /// /// The pin. - /// if set to true [enabled]. + /// if set to true, pin is enabled. public void SetPinStatus(Mcp23017Pin pin, bool enabled) { var register = ((int) pin & 0x0100) == 0x0000 ? Register.GPIOA : Register.GPIOB; @@ -113,7 +117,7 @@ public void SetPinStatus(Mcp23017Pin pin, bool enabled) /// Gets the pin status. /// /// The pin. - /// + /// The pin status. public bool GetPinStatus(Mcp23017Pin pin) { var register = ((int) pin & 0x0100) == 0x0000 ? Register.GPIOA : Register.GPIOB; diff --git a/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574I2cConnection.cs new file mode 100644 index 0000000..a33eb20 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574I2cConnection.cs @@ -0,0 +1,123 @@ +#region References + +using System; +using System.Globalization; +using Raspberry.IO.InterIntegratedCircuit; + +#endregion + +namespace Raspberry.IO.Components.Expanders.Pcf8574 +{ + /// + /// Represents a I2C connection to a PCF8574 I/O Expander. + /// + /// See for more information. + public class Pcf8574I2cConnection + { + #region Fields + + private readonly I2cDeviceConnection connection; + + private byte inputPins; + private byte currentStatus; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + public Pcf8574I2cConnection(I2cDeviceConnection connection) + { + this.connection = connection; + connection.WriteByte(0); + } + + #endregion + + #region Methods + + /// + /// Sets the pin status. + /// + /// The pin. + /// if set to true, specified pin is enabled. + public void SetPinStatus(Pcf8574Pin pin, bool enabled) + { + var bit = GetPinBit(pin); + if ((inputPins & bit) != 0x00) + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot set value of input pin {0}", pin)); + + var status = currentStatus; + var newStatus = (byte)(enabled + ? status | bit + : status & ~bit); + + connection.Write(newStatus); + currentStatus = newStatus; + } + + /// + /// Gets the pin status. + /// + /// The pin. + /// + public bool GetPinStatus(Pcf8574Pin pin) + { + var bit = GetPinBit(pin); + if ((inputPins & bit) == 0x00) + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot get value of input pin {0}", pin)); + + var status = connection.ReadByte(); + return (status & bit) != 0x00; + } + + /// + /// Toogles the specified pin. + /// + /// The pin. + public void Toogle(Pcf8574Pin pin) + { + var bit = GetPinBit(pin); + if ((inputPins & bit) != 0x00) + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot set value of input pin {0}", pin)); + + var status = currentStatus; + + var bitEnabled = (status & bit) != 0x00; + var newBitEnabled = !bitEnabled; + + var newStatus = (byte)(newBitEnabled + ? status | bit + : status & ~bit); + + connection.Write(newStatus); + currentStatus = newStatus; + } + + #endregion + + #region Internal Helpers + + internal void SetInputPin(Pcf8574Pin pin, bool isInput) + { + var bit = GetPinBit(pin); + inputPins = (byte) (isInput + ? inputPins | bit + : inputPins & ~bit); + } + + #endregion + + #region Private Helpers + + private static byte GetPinBit(Pcf8574Pin pin) + { + return (byte) (int) pin; + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574InputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574InputBinaryPin.cs new file mode 100644 index 0000000..7e3c465 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574InputBinaryPin.cs @@ -0,0 +1,77 @@ +#region References + +using System; + +#endregion + +namespace Raspberry.IO.Components.Expanders.Pcf8574 +{ + /// + /// Represents a binary intput pin on a PCF8574 I/O expander. + /// + public class Pcf8574InputBinaryPin : IInputBinaryPin + { + #region Fields + + private readonly Pcf8574I2cConnection connection; + private readonly Pcf8574Pin pin; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + public Pcf8574InputBinaryPin(Pcf8574I2cConnection connection, Pcf8574Pin pin) + { + this.connection = connection; + this.pin = pin; + + connection.SetInputPin(pin, true); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose(){} + + #endregion + + #region Methods + + /// + /// Reads the state of the pin. + /// + /// + /// true if the pin is in high state; otherwise, false. + /// + public bool Read() + { + return connection.GetPinStatus(pin); + } + + /// + /// Waits for the specified pin to be in the specified state. + /// + /// if set to true waits for the pin to be up. + /// The timeout, in milliseconds. + /// A timeout occurred while waiting for pin status to change + public void Wait(bool waitForUp = true, decimal timeout = 0) + { + var startWait = DateTime.Now; + if (timeout == 0) + timeout = 5000; + + while (Read() != waitForUp) + { + if (DateTime.Now.Ticks - startWait.Ticks >= 10000*timeout) + throw new TimeoutException("A timeout occurred while waiting for pin status to change"); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574OutputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574OutputBinaryPin.cs new file mode 100644 index 0000000..5bf808f --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574OutputBinaryPin.cs @@ -0,0 +1,52 @@ +namespace Raspberry.IO.Components.Expanders.Pcf8574 +{ + /// + /// Represents a binary output pin on a MCP23017 I/O expander. + /// + public class Pcf8574OutputBinaryPin : IOutputBinaryPin + { + #region Properties + + private readonly Pcf8574I2cConnection connection; + private readonly Pcf8574Pin pin; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + public Pcf8574OutputBinaryPin(Pcf8574I2cConnection connection, Pcf8574Pin pin) + { + this.connection = connection; + this.pin = pin; + + connection.SetInputPin(pin, false); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + } + + #endregion + + #region Methods + + /// + /// Writes the value of the pin. + /// + /// if set to true, pin is set to high state. + public void Write(bool state) + { + connection.SetPinStatus(pin, state); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574Pin.cs b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574Pin.cs new file mode 100644 index 0000000..5cd6e2f --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574Pin.cs @@ -0,0 +1,14 @@ +namespace Raspberry.IO.Components.Expanders.Pcf8574 +{ + public enum Pcf8574Pin + { + P0 = 0x01, + P1 = 0x02, + P2 = 0x04, + P3 = 0x08, + P4 = 0x10, + P5 = 0x20, + P6 = 0x40, + P7 = 0x80 + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574PinExtensionMethods.cs b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574PinExtensionMethods.cs new file mode 100644 index 0000000..2485f1f --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Pcf8574/Pcf8574PinExtensionMethods.cs @@ -0,0 +1,34 @@ +namespace Raspberry.IO.Components.Expanders.Pcf8574 +{ + /// + /// Provides extension methods for PCF8574 pins. + /// + public static class Pcf8574PinExtensionMethods + { + #region Methods + + /// + /// Creates an output binary pin. + /// + /// The connection. + /// The pin. + /// The pin. + public static Pcf8574OutputBinaryPin Out(this Pcf8574I2cConnection connection, Pcf8574Pin pin) + { + return new Pcf8574OutputBinaryPin(connection, pin); + } + + /// + /// Creates an input binary pin. + /// + /// The connection. + /// The pin. + /// The pin. + public static Pcf8574InputBinaryPin In(this Pcf8574I2cConnection connection, Pcf8574Pin pin) + { + return new Pcf8574InputBinaryPin(connection, pin); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index a0f0b21..25f5069 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -84,6 +84,7 @@ + @@ -93,6 +94,11 @@ + + + + + diff --git a/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs new file mode 100644 index 0000000..ed028b2 --- /dev/null +++ b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs @@ -0,0 +1,168 @@ +#region References + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Raspberry.IO; +using Raspberry.IO.Components.Displays.Hd44780; +using Raspberry.IO.Components.Expanders.Mcp23017; +using Raspberry.IO.Components.Expanders.Pcf8574; +using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.InterIntegratedCircuit; + +#endregion + +namespace Test.Gpio.HD44780 +{ + internal static class ConfigurationLoader + { + #region Methods + + public static Hd44780Configuration FromArguments(string[] args) + { + if (args.Contains("mcp23017", StringComparer.InvariantCultureIgnoreCase)) + return LoadMcp23017Configuration(args); + + if (args.Contains("pcf8574", StringComparer.InvariantCultureIgnoreCase)) + return LoadPcf8574Configuration(args); + + return LoadGpioConfiguration(); + } + + #endregion + + #region Private Helpers + + private static Hd44780Configuration LoadMcp23017Configuration(IEnumerable args) + { + var addressText = args.SkipWhile(s => !String.Equals(s, "mcp23017", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); + var address = addressText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) + ? Int32.Parse(addressText.Substring(2), NumberStyles.HexNumber) + : Int32.Parse(addressText); + + const Mcp23017Pin registerSelectPin = Mcp23017Pin.B7; + const Mcp23017Pin clockPin = Mcp23017Pin.B5; + var dataPins = new[] + { + Mcp23017Pin.B1, + Mcp23017Pin.B2, + Mcp23017Pin.B3, + Mcp23017Pin.B4 + }; + + Console.WriteLine(); + Console.WriteLine("Using I2C connection over MCP23017 Expander"); + Console.WriteLine("\tRegister Select: {0}", registerSelectPin); + Console.WriteLine("\tClock: {0}", clockPin); + Console.WriteLine("\tData 1: {0}", dataPins[0]); + Console.WriteLine("\tData 2: {0}", dataPins[1]); + Console.WriteLine("\tData 3: {0}", dataPins[2]); + Console.WriteLine("\tData 4: {0}", dataPins[3]); + Console.WriteLine("\tBacklight: VCC"); + Console.WriteLine("\tRead/write: GND"); + Console.WriteLine(); + + const ConnectorPin sdaPin = ConnectorPin.P1Pin03; + const ConnectorPin sclPin = ConnectorPin.P1Pin05; + + var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) { ClockDivider = 512 }; + var connection = new Mcp23017I2cConnection(driver.Connect(address)); + + return new Hd44780Configuration(driver) + { + Pins = new Hd44780Pins( + connection.Out(registerSelectPin), + connection.Out(clockPin), + dataPins.Select(pin => (IOutputBinaryPin)connection.Out(pin))) + }; + } + + private static Hd44780Configuration LoadPcf8574Configuration(IEnumerable args) + { + var addressText = args.SkipWhile(s => !String.Equals(s, "pcf8574", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); + var address = addressText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) + ? Int32.Parse(addressText.Substring(2), NumberStyles.HexNumber) + : Int32.Parse(addressText); + + const Pcf8574Pin clockPin = Pcf8574Pin.P2; + const Pcf8574Pin readWritePin = Pcf8574Pin.P1; + const Pcf8574Pin registerSelectPin = Pcf8574Pin.P0; + const Pcf8574Pin backlightPin = Pcf8574Pin.P3; + var dataPins = new[] + { + Pcf8574Pin.P4, + Pcf8574Pin.P5, + Pcf8574Pin.P6, + Pcf8574Pin.P7 + }; + + Console.WriteLine(); + Console.WriteLine("Using I2C connection over PCF8574 expander"); + Console.WriteLine("\tRegister Select: {0}", registerSelectPin); + Console.WriteLine("\tClock: {0}", clockPin); + Console.WriteLine("\tData 1: {0}", dataPins[0]); + Console.WriteLine("\tData 2: {0}", dataPins[1]); + Console.WriteLine("\tData 3: {0}", dataPins[2]); + Console.WriteLine("\tData 4: {0}", dataPins[3]); + Console.WriteLine("\tBacklight: {0}", backlightPin); + Console.WriteLine("\tRead/write: {0}", readWritePin); + Console.WriteLine(); + + const ConnectorPin sdaPin = ConnectorPin.P1Pin03; + const ConnectorPin sclPin = ConnectorPin.P1Pin05; + + var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) { ClockDivider = 512 }; + var connection = new Pcf8574I2cConnection(driver.Connect(address)); + + return new Hd44780Configuration(driver) + { + Pins = new Hd44780Pins( + connection.Out(registerSelectPin), + connection.Out(clockPin), + dataPins.Select(p => (IOutputBinaryPin)connection.Out(p))) + { + Backlight = connection.Out(backlightPin), + ReadWrite = connection.Out(readWritePin), + } + }; + } + + private static Hd44780Configuration LoadGpioConfiguration() + { + const ConnectorPin registerSelectPin = ConnectorPin.P1Pin22; + const ConnectorPin clockPin = ConnectorPin.P1Pin18; + var dataPins = new[] + { + ConnectorPin.P1Pin16, + ConnectorPin.P1Pin15, + ConnectorPin.P1Pin13, + ConnectorPin.P1Pin11 + }; + + Console.WriteLine(); + Console.WriteLine("Using GPIO connection"); + Console.WriteLine("\tRegister Select: {0}", registerSelectPin); + Console.WriteLine("\tClock: {0}", clockPin); + Console.WriteLine("\tData 1: {0}", dataPins[0]); + Console.WriteLine("\tData 2: {0}", dataPins[1]); + Console.WriteLine("\tData 3: {0}", dataPins[2]); + Console.WriteLine("\tData 4: {0}", dataPins[3]); + Console.WriteLine("\tBacklight: VCC"); + Console.WriteLine("\tRead/write: GND"); + Console.WriteLine(); + + var driver = GpioConnectionSettings.DefaultDriver; + return new Hd44780Configuration + { + Pins = new Hd44780Pins( + driver.Out(registerSelectPin), + driver.Out(clockPin), + dataPins.Select(p => (IOutputBinaryPin)driver.Out(p)) + ) + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/Tests/Test.Gpio.HD44780/Hd44780Configuration.cs b/Tests/Test.Gpio.HD44780/Hd44780Configuration.cs index f6509de..24c539b 100644 --- a/Tests/Test.Gpio.HD44780/Hd44780Configuration.cs +++ b/Tests/Test.Gpio.HD44780/Hd44780Configuration.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Raspberry.IO; +using Raspberry.IO.Components.Displays.Hd44780; namespace Test.Gpio.HD44780 { @@ -19,8 +20,6 @@ public void Dispose() driver.Dispose(); } - public IOutputBinaryPin RegisterSelect; - public IOutputBinaryPin Clock; - public IEnumerable Data; + public Hd44780Pins Pins; } } \ No newline at end of file diff --git a/Tests/Test.Gpio.HD44780/Program.cs b/Tests/Test.Gpio.HD44780/Program.cs index 7cca9c9..14ebd99 100644 --- a/Tests/Test.Gpio.HD44780/Program.cs +++ b/Tests/Test.Gpio.HD44780/Program.cs @@ -1,15 +1,10 @@ #region References using System; -using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Net.NetworkInformation; using System.Threading; using Raspberry.IO.Components.Displays.Hd44780; -using Raspberry.IO.Components.Expanders.Mcp23017; -using Raspberry.IO.GeneralPurpose; -using Raspberry.IO.InterIntegratedCircuit; #endregion @@ -27,14 +22,8 @@ static void Main(string[] args) ScreenHeight = 2, }; - var useI2c = args.Contains("i2c", StringComparer.InvariantCultureIgnoreCase); - - using (var configuration = useI2c ? LoadI2cConfiguration(args) : LoadGpioConfiguration()) - using (var connection = new Hd44780LcdConnection( - settings, - configuration.RegisterSelect, - configuration.Clock, - configuration.Data)) + using (var configuration = ConfigurationLoader.FromArguments(args)) + using (var connection = new Hd44780LcdConnection(settings, configuration.Pins)) { connection.SetCustomCharacter(1, new byte[] {0x0, 0x0, 0x04, 0xe, 0x1f, 0x0, 0x0}); connection.SetCustomCharacter(2, new byte[] {0x0, 0x0, 0x1f, 0xe, 0x04, 0x0, 0x0}); @@ -118,78 +107,6 @@ static void Main(string[] args) #region Private Helpers - private static Hd44780Configuration LoadI2cConfiguration(IEnumerable args) - { - var addressText = args.SkipWhile(s => !string.Equals(s, "i2c", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); - var address = addressText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) - ? int.Parse(addressText.Substring(2), NumberStyles.HexNumber) - : int.Parse(addressText); - - const Mcp23017Pin registerSelectPin = Mcp23017Pin.B7; - const Mcp23017Pin clockPin = Mcp23017Pin.B5; - var dataPins = new[] - { - Mcp23017Pin.B1, - Mcp23017Pin.B2, - Mcp23017Pin.B3, - Mcp23017Pin.B4 - }; - - Console.WriteLine(); - Console.WriteLine("Using I2C connection"); - Console.WriteLine("\tRegister Select: {0}", registerSelectPin); - Console.WriteLine("\tClock: {0}", clockPin); - Console.WriteLine("\tData 1: {0}", dataPins[0]); - Console.WriteLine("\tData 2: {0}", dataPins[1]); - Console.WriteLine("\tData 3: {0}", dataPins[2]); - Console.WriteLine("\tData 4: {0}", dataPins[3]); - Console.WriteLine(); - - const ConnectorPin sdaPin = ConnectorPin.P1Pin03; - const ConnectorPin sclPin = ConnectorPin.P1Pin05; - - var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) {ClockDivider = 512}; - var connection = new Mcp23017I2cConnection(driver.Connect(address)); - - return new Hd44780Configuration(driver) - { - RegisterSelect = connection.Out(registerSelectPin), - Clock = connection.Out(clockPin), - Data = dataPins.Select(pin=>connection.Out(pin)) - }; - } - - private static Hd44780Configuration LoadGpioConfiguration() - { - const ConnectorPin registerSelectPin = ConnectorPin.P1Pin22; - const ConnectorPin clockPin = ConnectorPin.P1Pin18; - var dataPins = new[] - { - ConnectorPin.P1Pin16, - ConnectorPin.P1Pin15, - ConnectorPin.P1Pin13, - ConnectorPin.P1Pin11 - }; - - Console.WriteLine(); - Console.WriteLine("Using GPIO connection"); - Console.WriteLine("\tRegister Select: {0}", registerSelectPin); - Console.WriteLine("\tClock: {0}", clockPin); - Console.WriteLine("\tData 1: {0}", dataPins[0]); - Console.WriteLine("\tData 2: {0}", dataPins[1]); - Console.WriteLine("\tData 3: {0}", dataPins[2]); - Console.WriteLine("\tData 4: {0}", dataPins[3]); - Console.WriteLine(); - - var driver = GpioConnectionSettings.DefaultDriver; - return new Hd44780Configuration - { - RegisterSelect = driver.Out(registerSelectPin), - Clock = driver.Out(clockPin), - Data = dataPins.Select(driver.Out) - }; - } - private static void DisplayCharMap(Hd44780LcdConnection connection) { var idx = 0; diff --git a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index 46e962a..7cc39a3 100644 --- a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -60,6 +60,7 @@ Properties\SharedAssemblyInfo.cs + From 1a911026a9d3f34005e75f199b010a0fa6713c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 15 Jul 2014 22:02:12 +0200 Subject: [PATCH 152/227] Added support for Raspberry Pi Model B+ --- .../Raspberry.IO.Components.csproj | 2 +- Raspberry.IO.Components/packages.config | 2 +- Raspberry.IO.GeneralPurpose/ConnectorPin.cs | 60 ++++++ .../GpioConnectionSettings.cs | 3 + Raspberry.IO.GeneralPurpose/PinMapping.cs | 136 ++++++++------ Raspberry.IO.GeneralPurpose/ProcessorPin.cs | 50 +++++ .../Raspberry.IO.GeneralPurpose.csproj | 9 +- Raspberry.IO.GeneralPurpose/packages.config | 2 +- ...Raspberry.IO.InterIntegratedCircuit.csproj | 2 +- .../packages.config | 2 +- ...pberry.IO.SerialPeripheralInterface.csproj | 3 +- .../packages.config | 2 +- .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 5 +- Tests/Test.Gpio.HCSR04/packages.config | 2 +- .../Raspberry.System.1.2.0.nupkg | Bin 9703 -> 0 bytes .../lib/net40/Raspberry.System.dll | Bin 11264 -> 0 bytes .../lib/net40/Raspberry.System.xml | 171 ------------------ 17 files changed, 215 insertions(+), 236 deletions(-) delete mode 100644 packages/Raspberry.System.1.2.0/Raspberry.System.1.2.0.nupkg delete mode 100644 packages/Raspberry.System.1.2.0/lib/net40/Raspberry.System.dll delete mode 100644 packages/Raspberry.System.1.2.0/lib/net40/Raspberry.System.xml diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 25f5069..232524f 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -43,7 +43,7 @@ False - ..\packages\Raspberry.System.1.2.0\lib\net40\Raspberry.System.dll + ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index c09f9c2..7553870 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs index 11d84f7..bc91ef7 100644 --- a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs @@ -111,6 +111,66 @@ public enum ConnectorPin P1Pin26, + // Pins 27+ exist starting from Model B+ + + /// + /// Connector P1, pin 27. + /// + P1Pin27, + + /// + /// Connector P1, pin 28. + /// + P1Pin28, + + /// + /// Connector P1, pin 29. + /// + P1Pin29, + + /// + /// Connector P1, pin 31. + /// + P1Pin31, + + /// + /// Connector P1, pin 32. + /// + P1Pin32, + + /// + /// Connector P1, pin 33. + /// + P1Pin33, + + /// + /// Connector P1, pin 35. + /// + P1Pin35, + + /// + /// Connector P1, pin 36. + /// + P1Pin36, + + /// + /// Connector P1, pin 37. + /// + P1Pin37, + + /// + /// Connector P1, pin 38. + /// + P1Pin38, + + /// + /// Connector P1, pin 40. + /// + P1Pin40, + + + // P5 Connector exist on Rev2 boards (no longer on B+) + /// /// Connector P5, pin 3. /// diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs index dcd9bcd..bf9573e 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs @@ -124,6 +124,9 @@ public static int BoardConnectorRevision if (board.Model == 'B' && board.Revision == 1) return 1; + if (board.Model == 'B' && board.Revision == 3) + return 3; + return 2; } } diff --git a/Raspberry.IO.GeneralPurpose/PinMapping.cs b/Raspberry.IO.GeneralPurpose/PinMapping.cs index 88c4b3f..5a767b8 100644 --- a/Raspberry.IO.GeneralPurpose/PinMapping.cs +++ b/Raspberry.IO.GeneralPurpose/PinMapping.cs @@ -25,52 +25,86 @@ public static class PinMapping static PinMapping() { - var mapping = GpioConnectionSettings.BoardConnectorRevision == 1 - ? new[] - { - new {Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin3}, - new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.P1Pin5}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, - new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin13}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22} - } - : new[] - { - new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, - new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, - new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, + var mapping = /* Value is not used but required for anonymous type */ new[]{ new { Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin03 }}; - new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.P5Pin3}, - new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.P5Pin4}, - new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.P5Pin5}, - new {Processor = ProcessorPin.Pin31, Connector = ConnectorPin.P5Pin6} - }; + if (GpioConnectionSettings.BoardConnectorRevision == 1) + mapping = new[] + { + new {Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin13}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22} + }; + + else if (GpioConnectionSettings.BoardConnectorRevision == 2) + mapping = new[] + { + new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, + new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.P5Pin3}, + new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.P5Pin4}, + new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.P5Pin5}, + new {Processor = ProcessorPin.Pin31, Connector = ConnectorPin.P5Pin6} + }; + + else //if (GpioConnectionSettings.BoardConnectorRevision == 3) + mapping = new[] + { + new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.P1Pin29}, + new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.P1Pin31}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.P1Pin32}, + new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.P1Pin33}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.P1Pin36}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.P1Pin35}, + new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.P1Pin38}, + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin40}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, + new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.P1Pin37}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, + }; processorMappings = mapping.ToDictionary(p => p.Connector, p => p.Processor); connectorMappings = mapping.ToDictionary(p => p.Processor, p => p.Connector); @@ -88,10 +122,10 @@ static PinMapping() public static ProcessorPin ToProcessor(this ConnectorPin pin) { ProcessorPin processorPin; - if (processorMappings.TryGetValue(pin, out processorPin)) - return processorPin; - else + if (!processorMappings.TryGetValue(pin, out processorPin)) throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Connector pin {0} is not mapped to processor with pin layout revision {1}", pin.ToString().Replace("Pin", "-"), GpioConnectionSettings.BoardConnectorRevision)); + + return processorPin; } /// @@ -102,10 +136,10 @@ public static ProcessorPin ToProcessor(this ConnectorPin pin) public static ConnectorPin ToConnector(this ProcessorPin pin) { ConnectorPin connectorPin; - if (connectorMappings.TryGetValue(pin, out connectorPin)) - return connectorPin; - else + if (!connectorMappings.TryGetValue(pin, out connectorPin)) throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Processor pin {0} is not mapped to processor with pin layout revision {1}", (int) pin, GpioConnectionSettings.BoardConnectorRevision)); + + return connectorPin; } #endregion diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs index 4dfa8f0..626e709 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs @@ -55,6 +55,26 @@ public enum ProcessorPin /// Pin04 = Pin4, + /// + /// Pin 5. + /// + Pin5 = 5, + + /// + /// Pin 5. + /// + Pin05 = Pin5, + + /// + /// Pin 6. + /// + Pin6 = 6, + + /// + /// Pin 6. + /// + Pin06 = Pin6, + /// /// Pin 7. /// @@ -95,6 +115,16 @@ public enum ProcessorPin /// Pin11 = 11, + /// + /// Pin 12. + /// + Pin12 = 12, + + /// + /// Pin 13. + /// + Pin13 = 13, + /// /// Pin 14. /// @@ -105,6 +135,11 @@ public enum ProcessorPin /// Pin15 = 15, + /// + /// Pin 16. + /// + Pin16 = 16, + /// /// Pin 17. /// @@ -115,6 +150,16 @@ public enum ProcessorPin /// Pin18 = 18, + /// + /// Pin 19. + /// + Pin19 = 19, + + /// + /// Pin 20. + /// + Pin20 = 20, + /// /// Pin 21. /// @@ -140,6 +185,11 @@ public enum ProcessorPin /// Pin25 = 25, + /// + /// Pin 26. + /// + Pin26 = 26, + /// /// Pin 27. /// diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 9abf834..7f3a28c 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -37,7 +37,8 @@ False - ..\packages\Raspberry.System.1.2.0\lib\net40\Raspberry.System.dll + ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + True @@ -82,9 +83,6 @@ - - - {689cb6c4-3d23-45da-8e00-87c28aea32d0} @@ -96,6 +94,9 @@ Raspberry.IO + + + + + + + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 5f83da4..8c0511a 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -28,8 +28,8 @@ public class FileGpioConnectionDriver : IGpioConnectionDriver /// public FileGpioConnectionDriver() { - if (!Board.Current.IsRaspberryPi) - throw new NotSupportedException("FileGpioConnectionDriver is only supported on Raspberry Pi"); + if (System.Environment.OSVersion.Platform != PlatformID.Unix) + throw new NotSupportedException("FileGpioConnectionDriver is only supported in Unix"); } #endregion diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs index bf9573e..30a0fb3 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs @@ -141,7 +141,7 @@ public static IGpioConnectionDriver DefaultDriver var configurationSection = ConfigurationManager.GetSection("gpioConnection") as GpioConnectionConfigurationSection; return configurationSection != null && !String.IsNullOrEmpty(configurationSection.DriverTypeName) ? (IGpioConnectionDriver) Activator.CreateInstance(Type.GetType(configurationSection.DriverTypeName, true)) - : new GpioConnectionDriver(); + : (Raspberry.Board.Current.IsRaspberryPi ? (IGpioConnectionDriver)new GpioConnectionDriver() : (IGpioConnectionDriver)new FileGpioConnectionDriver()); } } diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs index 69aea5c..fec7fea 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs @@ -224,7 +224,7 @@ public void Should_the_control_structure_have_the_requested_wordsize() { [Test] public void Should_the_control_structure_have_the_requested_chip_select_change_value() { // ReSharper disable once UnreachableCode - buffer.ControlStructure.ChipSelectChange.Should().Be(REQUESTED_CHIP_SELECT_CHANGE ? 1 : 0); + buffer.ControlStructure.ChipSelectChange.Should().Be(REQUESTED_CHIP_SELECT_CHANGE ? (byte)1 : (byte)0); } [Test] From 9e2a8495743de38e876e7a8f7a971711b0f3423e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 1 Oct 2014 22:27:22 +0200 Subject: [PATCH 165/227] Fixed case on BMP085 connection file name --- Raspberry.IO.Components/Raspberry.IO.Components.csproj | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index f3c39d8..2fc8d05 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -97,7 +97,7 @@ - + @@ -143,8 +143,5 @@ --> - - - - + \ No newline at end of file From b5af40ea0d1030fbe57b5b71b2b682f54d45d489 Mon Sep 17 00:00:00 2001 From: Gene Date: Mon, 5 Jan 2015 21:40:32 +0100 Subject: [PATCH 166/227] Disabled driver check in SetPinResistor to avoid errors on non Raspberry Pi systems --- Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 8c0511a..49cf2de 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -67,7 +67,7 @@ public void Allocate(ProcessorPin pin, PinDirection direction) /// The resistor. public void SetPinResistor(ProcessorPin pin, PinResistor resistor) { - throw new NotSupportedException("Resistor are not supported by file GPIO connection driver"); + //throw new NotSupportedException("Resistor are not supported by file GPIO connection driver"); } /// @@ -81,7 +81,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - throw new NotSupportedException("Edge detection is not supported by file GPIO connection driver"); + //throw new NotSupportedException("Edge detection is not supported by file GPIO connection driver"); } /// From 9f0d6969f6e2a83f552ab5ff6fa23bcf188546cf Mon Sep 17 00:00:00 2001 From: Gene Date: Tue, 6 Jan 2015 21:17:55 +0100 Subject: [PATCH 167/227] - Added Ssd1306 oled display support - Little refactoring in GroveRgbConnection - Added IsRaspberryPi check before using SetPinResistor/SetPinDetectedEdges in GpioConnectionDriver constructor (this makes it compatible with systems using FileGpioConnectionDriver - Fixed ToolVersion errors that were preventing some projects to load in MonoDevelop - Fixed repositories.config to work with MonoDevelop as well --- .../Displays/Ssd1306/Command.cs | 65 +++ .../Displays/Ssd1306/Fonts/Fixed1L.cs | 112 ++++ .../Displays/Ssd1306/Fonts/IFont.cs | 10 + .../Displays/Ssd1306/Fonts/Proportional2L.cs | 112 ++++ .../Displays/Ssd1306/Fonts/Proportional3L.cs | 110 ++++ .../Displays/Ssd1306/Ssd1306Connection.cs | 258 ++++++++++ .../Leds/GroveRgb/GroveRgbConnection.cs | 480 +++++++++--------- .../Raspberry.IO.Components.csproj | 10 + .../FileGpioConnectionDriver.cs | 4 +- .../GpioConnectionDriver.cs | 9 +- .../Raspberry.IO.GeneralPurpose.csproj | 10 +- ...Raspberry.IO.InterIntegratedCircuit.csproj | 7 +- .../Raspberry.IO.Interop.csproj | 6 +- ...pberry.IO.SerialPeripheralInterface.csproj | 10 +- Raspberry.IO/Raspberry.IO.csproj | 6 +- RaspberrySharp.IO.sln | 361 +++++++------ .../Test.Gpio.Chaser/Test.Gpio.Chaser.csproj | 3 + .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 10 +- .../Test.Gpio.HD44780.csproj | 3 + .../Test.Gpio.MCP23017.csproj | 3 + .../Test.Gpio.MCP3008.csproj | 5 +- .../Test.Gpio.MCP4822.csproj | 3 + .../Test.Gpio.Pca9685.csproj | 14 +- .../Test.Gpio.WatchPin.csproj | 2 + .../Test.Spi.TLC59711.csproj | 14 +- packages/repositories.config | 36 +- 26 files changed, 1202 insertions(+), 461 deletions(-) create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Command.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Fonts/IFont.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional2L.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional3L.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/Ssd1306Connection.cs diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Command.cs b/Raspberry.IO.Components/Displays/Ssd1306/Command.cs new file mode 100644 index 0000000..59ef677 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Command.cs @@ -0,0 +1,65 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306 +{ + public class Command + { + public const byte SetContrast = 0x81; + // + public const byte DisplayAllOnResume = 0xA4; + public const byte DisplayAllOn = 0xA5; + public const byte DisplayNormal = 0xA6; + public const byte DisplayInvert = 0xA7; + public const byte DisplayOff = 0xAE; + public const byte DisplayOn = 0xAF; + // + public const byte SetDisplayOffset = 0xD3; + public const byte SetComPins = 0xDA; + public const byte SetVComDetect = 0xDB; + public const byte SetDisplayClockDivider = 0xD5; + public const byte SetPreCharge = 0xD9; + public const byte SetMultiplex = 0xA8; + public const byte SetLowColumn = 0x00; + public const byte SetHighColumn = 0x10; + public const byte SetStartLine = 0x40; + public const byte MemoryMode = 0x20; + public const byte ColumnAddress = 0x21; + public const byte PageAddress = 0x22; + // + public const byte ActivateScroll = 0x2F; + public const byte DeactivateScroll = 0x2E; + public const byte SetVerticalScrollArea = 0xA3; + public const byte SetScrollDirection = 0x25; + // + public const byte ComScanIncrement = 0xC0; + public const byte ComScanDecrement = 0xC8; + public const byte SegRemap = 0xA0; + public const byte ChargePump = 0x8D; + public const byte ExternalVcc = 0x1; + public const byte SwitchCapVcc = 0x2; + } + + [Flags] + public enum ScrollSpeed : byte + { + F2 = 0x7, + F3 = 0x4, + F4 = 0x5, + F5 = 0x0, + F25 = 0x6, + F64 = 0x1, + F128 = 0x2, + F256 = 0x3 + } + + [Flags] + public enum ScrollDirection : byte + { + HorizontalRight = 0x01, + HorizontalLeft = 0x02, + VerticalAndHorizontalRight = 0x04, + VerticalAndHorizontalLeft = 0x05 + } + +} + diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs new file mode 100644 index 0000000..9836f96 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs @@ -0,0 +1,112 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306.Fonts +{ + public class Fixed1L : IFont + { + private static byte[][] fontData = new byte[][] { + new byte[] { (byte)' ', 8, 8, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'!', 8, 8, 0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'"', 8, 8, 0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00 }, + new byte[] { (byte)'#', 8, 8, 0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00 }, + new byte[] { (byte)'$', 8, 8, 0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00 }, + new byte[] { (byte)'%', 8, 8, 0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00 }, + new byte[] { (byte)'&', 8, 8, 0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00 }, + new byte[] { (byte)'\'', 8, 8, 0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'(', 8, 8, 0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)')', 8, 8, 0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'*', 8, 8, 0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00 }, + new byte[] { (byte)'+', 8, 8, 0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00 }, + new byte[] { (byte)',', 8, 8, 0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'-', 8, 8, 0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00 }, + new byte[] { (byte)'.', 8, 8, 0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'/', 8, 8, 0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00 }, + new byte[] { (byte)'0', 8, 8, 0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00 }, + new byte[] { (byte)'1', 8, 8, 0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00 }, + new byte[] { (byte)'2', 8, 8, 0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00 }, + new byte[] { (byte)'3', 8, 8, 0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00 }, + new byte[] { (byte)'4', 8, 8, 0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00 }, + new byte[] { (byte)'5', 8, 8, 0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00 }, + new byte[] { (byte)'6', 8, 8, 0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00 }, + new byte[] { (byte)'7', 8, 8, 0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00 }, + new byte[] { (byte)'8', 8, 8, 0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00 }, + new byte[] { (byte)'9', 8, 8, 0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00 }, + new byte[] { (byte)':', 8, 8, 0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)';', 8, 8, 0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'<', 8, 8, 0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00 }, + new byte[] { (byte)'=', 8, 8, 0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00 }, + new byte[] { (byte)'>', 8, 8, 0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00 }, + new byte[] { (byte)'?', 8, 8, 0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00 }, + new byte[] { (byte)'@', 8, 8, 0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00 }, + new byte[] { (byte)'A', 8, 8, 0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00 }, + new byte[] { (byte)'B', 8, 8, 0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00 }, + new byte[] { (byte)'C', 8, 8, 0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00 }, + new byte[] { (byte)'D', 8, 8, 0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00 }, + new byte[] { (byte)'E', 8, 8, 0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00 }, + new byte[] { (byte)'F', 8, 8, 0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00 }, + new byte[] { (byte)'G', 8, 8, 0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00 }, + new byte[] { (byte)'H', 8, 8, 0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00 }, + new byte[] { (byte)'I', 8, 8, 0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'J', 8, 8, 0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00 }, + new byte[] { (byte)'K', 8, 8, 0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00 }, + new byte[] { (byte)'L', 8, 8, 0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00 }, + new byte[] { (byte)'M', 8, 8, 0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00 }, + new byte[] { (byte)'N', 8, 8, 0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00 }, + new byte[] { (byte)'O', 8, 8, 0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00 }, + new byte[] { (byte)'P', 8, 8, 0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00 }, + new byte[] { (byte)'Q', 8, 8, 0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00 }, + new byte[] { (byte)'R', 8, 8, 0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00 }, + new byte[] { (byte)'S', 8, 8, 0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00 }, + new byte[] { (byte)'T', 8, 8, 0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00 }, + new byte[] { (byte)'U', 8, 8, 0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00 }, + new byte[] { (byte)'V', 8, 8, 0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00 }, + new byte[] { (byte)'W', 8, 8, 0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00 }, + new byte[] { (byte)'X', 8, 8, 0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00 }, + new byte[] { (byte)'Y', 8, 8, 0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00 }, + new byte[] { (byte)'Z', 8, 8, 0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00 }, + new byte[] { (byte)'[', 8, 8, 0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'\\', 8, 8, 0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00 }, + new byte[] { (byte)']', 8, 8, 0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'^', 8, 8, 0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00 }, + new byte[] { (byte)'_', 8, 8, 0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00 }, + new byte[] { (byte)'`', 8, 8, 0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'a', 8, 8, 0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00 }, + new byte[] { (byte)'b', 8, 8, 0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00 }, + new byte[] { (byte)'c', 8, 8, 0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00 }, + new byte[] { (byte)'d', 8, 8, 0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00 }, + new byte[] { (byte)'e', 8, 8, 0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00 }, + new byte[] { (byte)'f', 8, 8, 0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00 }, + new byte[] { (byte)'g', 8, 8, 0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00 }, + new byte[] { (byte)'h', 8, 8, 0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00 }, + new byte[] { (byte)'i', 8, 8, 0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'j', 8, 8, 0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'k', 8, 8, 0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00 }, + new byte[] { (byte)'l', 8, 8, 0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'m', 8, 8, 0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00 }, + new byte[] { (byte)'n', 8, 8, 0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00 }, + new byte[] { (byte)'o', 8, 8, 0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00 }, + new byte[] { (byte)'p', 8, 8, 0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00 }, + new byte[] { (byte)'q', 8, 8, 0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00 }, + new byte[] { (byte)'r', 8, 8, 0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00 }, + new byte[] { (byte)'s', 8, 8, 0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00 }, + new byte[] { (byte)'t', 8, 8, 0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'u', 8, 8, 0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00 }, + new byte[] { (byte)'v', 8, 8, 0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00 }, + new byte[] { (byte)'w', 8, 8, 0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00 }, + new byte[] { (byte)'x', 8, 8, 0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00 }, + new byte[] { (byte)'y', 8, 8, 0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00 }, + new byte[] { (byte)'z', 8, 8, 0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00 }, + new byte[] { (byte)'{', 8, 8, 0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'|', 8, 8, 0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'}', 8, 8, 0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00 }, + new byte[] { (byte)'~', 8, 8, 0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00 }, + new byte[] { (byte)0x7F, 8, 8, 0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00 } + }; + + public byte[][] GetData() + { + return Fixed1L.fontData; + } + } +} + diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/IFont.cs b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/IFont.cs new file mode 100644 index 0000000..e90ee02 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/IFont.cs @@ -0,0 +1,10 @@ +using System; + +namespace Raspberry.IO.Components +{ + public interface IFont + { + byte[][] GetData(); + } +} + diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional2L.cs b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional2L.cs new file mode 100644 index 0000000..b885d5f --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional2L.cs @@ -0,0 +1,112 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306.Fonts +{ + public class Proportional2L : IFont + { + private static byte[][] fontData = { + new byte[] { (byte)' ', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'!', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'"', 8, 16, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + //new byte[] { (byte)'#', 8, 16, 0x00, 0x20, 0xe0, 0x3c, 0x20, 0xe0, 0x3c, 0x20, 0x08, 0x78, 0x0f, 0x08, 0x78, 0x0f, 0x08, 0x00 }, + new byte[] { (byte)'$', 8, 16, 0x00, 0x38, 0x44, 0x84, 0xfe, 0x04, 0x04, 0x18, 0x00, 0x18, 0x20, 0x20, 0x7f, 0x21, 0x22, 0x1c }, + new byte[] { (byte)'%', 8, 16, 0x00, 0x38, 0x44, 0x44, 0xb8, 0x60, 0x10, 0x0c, 0x00, 0x18, 0x04, 0x03, 0x1c, 0x22, 0x22, 0x1c }, + new byte[] { (byte)'&', 8, 16, 0x00, 0x00, 0x38, 0xc4, 0xc4, 0x38, 0x00, 0x80, 0x00, 0x1e, 0x21, 0x20, 0x20, 0x13, 0x0c, 0x33 }, + new byte[] { (byte)'\'', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'(', 8, 16, 0x00, 0x00, 0xe0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, 0x00 }, + new byte[] { (byte)')', 8, 16, 0x00, 0x00, 0x02, 0x04, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00 }, + new byte[] { (byte)'*', 8, 16, 0x00, 0x40, 0x80, 0xe0, 0x80, 0x40, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00 }, + new byte[] { (byte)'+', 8, 16, 0x00, 0x80, 0x80, 0x80, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00 }, + new byte[] { (byte)',', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'-', 8, 16, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'.', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'/', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'0', 8, 16, 0x00, 0xf0, 0x08, 0x04, 0x04, 0x04, 0x08, 0xf0, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0f }, + new byte[] { (byte)'1', 8, 16, 0x00, 0x00, 0x08, 0x08, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'2', 8, 16, 0x00, 0x18, 0x04, 0x04, 0x04, 0x84, 0x78, 0x00, 0x00, 0x38, 0x24, 0x22, 0x21, 0x20, 0x20, 0x00 }, + new byte[] { (byte)'3', 8, 16, 0x00, 0x18, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00 }, + new byte[] { (byte)'4', 8, 16, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0xfc, 0x00, 0x00, 0x04, 0x07, 0x04, 0x04, 0x04, 0x3f, 0x04 }, + new byte[] { (byte)'5', 8, 16, 0x00, 0xfc, 0x44, 0x44, 0x44, 0x44, 0x84, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00 }, + new byte[] { (byte)'6', 8, 16, 0x00, 0xf8, 0x84, 0x84, 0x84, 0x84, 0x18, 0x00, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00 }, + new byte[] { (byte)'7', 8, 16, 0x00, 0x04, 0x04, 0x04, 0xc4, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'8', 8, 16, 0x00, 0x78, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00 }, + new byte[] { (byte)'9', 8, 16, 0x00, 0xf8, 0x04, 0x04, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x18, 0x21, 0x21, 0x21, 0x21, 0x1f, 0x00 }, + new byte[] { (byte)':', 8, 16, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)';', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'<', 8, 16, 0x80, 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x08, 0x00 }, + new byte[] { (byte)'=', 8, 16, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }, + new byte[] { (byte)'>', 8, 16, 0x00, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x80, 0x00, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00 }, + //new byte[] { (byte)'|' /* ☂ */, 16, 32, 0x00, 0xe0, 0x30, 0x78, 0xf8, 0x3c, 0x3c, 0xfe, 0x7c, 0x3c, 0x3c, 0xf8, 0x78, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'@', 8, 16, 0x00, 0xf0, 0x08, 0xc4, 0x24, 0xe4, 0x08, 0xf0, 0x00, 0x0f, 0x10, 0x23, 0x24, 0x23, 0x24, 0x17 }, + new byte[] { (byte)'A', 8, 16, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x38, 0x07, 0x04, 0x04, 0x04, 0x07, 0x38 }, + new byte[] { (byte)'B', 8, 16, 0x00, 0xfc, 0x84, 0x84, 0x84, 0x84, 0x48, 0x30, 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x11, 0x0e }, + new byte[] { (byte)'C', 8, 16, 0x00, 0xf0, 0x08, 0x04, 0x04, 0x04, 0x08, 0x30, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0c }, + new byte[] { (byte)'D', 8, 16, 0x00, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x18, 0xe0, 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x18, 0x07 }, + new byte[] { (byte)'E', 8, 16, 0x00, 0xfc, 0x84, 0x84, 0x84, 0x84, 0x84, 0x04, 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, + new byte[] { (byte)'F', 8, 16, 0x00, 0xfc, 0x84, 0x84, 0x84, 0x84, 0x84, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'G', 8, 16, 0x00, 0xf0, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x21, 0x11, 0x3f }, + new byte[] { (byte)'H', 8, 16, 0x00, 0xfc, 0x80, 0x80, 0x80, 0x80, 0x80, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f }, + new byte[] { (byte)'I', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'J', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00 }, + new byte[] { (byte)'K', 8, 16, 0x00, 0xfc, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x3f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20 }, + new byte[] { (byte)'L', 8, 16, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 }, + new byte[] { (byte)'M', 8, 16, 0x00, 0xfc, 0x30, 0xc0, 0x00, 0xc0, 0x30, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x3f }, + new byte[] { (byte)'N', 8, 16, 0x00, 0xfc, 0x18, 0x60, 0x80, 0x00, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x01, 0x06, 0x18, 0x3f }, + new byte[] { (byte)'O', 8, 16, 0x00, 0xf0, 0x08, 0x04, 0x04, 0x04, 0x08, 0xf0, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0f }, + new byte[] { (byte)'P', 8, 16, 0x00, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x88, 0x70, 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 }, + new byte[] { (byte)'Q', 8, 16, 0x00, 0xf0, 0x08, 0x04, 0x04, 0x04, 0x08, 0xf0, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x28, 0x10, 0x2f }, + new byte[] { (byte)'R', 8, 16, 0x00, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x88, 0x70, 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3c }, + new byte[] { (byte)'S', 8, 16, 0x00, 0x38, 0x44, 0x84, 0x84, 0x04, 0x04, 0x18, 0x00, 0x18, 0x20, 0x20, 0x20, 0x21, 0x22, 0x1c }, + new byte[] { (byte)'T', 8, 16, 0x00, 0x04, 0x04, 0x04, 0xfc, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'U', 8, 16, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1f }, + new byte[] { (byte)'V', 8, 16, 0x00, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x00, 0x00, 0x00, 0x07, 0x38, 0x07, 0x00, 0x00 }, + new byte[] { (byte)'W', 8, 16, 0x00, 0xfc, 0x00, 0x80, 0x7c, 0x80, 0x00, 0xfc, 0x00, 0x03, 0x3c, 0x03, 0x00, 0x03, 0x3c, 0x03 }, + new byte[] { (byte)'X', 8, 16, 0x00, 0x0c, 0x30, 0x40, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x30, 0x0c, 0x03, 0x00, 0x03, 0x0c, 0x30 }, + new byte[] { (byte)'Y', 8, 16, 0x00, 0x0c, 0x30, 0xc0, 0x00, 0xc0, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'Z', 8, 16, 0x00, 0x04, 0x04, 0x04, 0xc4, 0x34, 0x0c, 0x00, 0x00, 0x30, 0x2c, 0x23, 0x20, 0x20, 0x20, 0x00 }, + new byte[] { (byte)'[', 8, 16, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x40, 0x40, 0x00 }, + new byte[] { (byte)']', 8, 16, 0x00, 0x02, 0x02, 0x02, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7f, 0x00, 0x00, 0x00 }, + //new byte[] { (byte)'^', 8, 16, 0x00, 0x00, 0x08, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'_', 8, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }, + new byte[] { (byte)'`', 8, 16, 0x00, 0x00, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'a', 8, 16, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x1f, 0x20 }, + new byte[] { (byte)'b', 8, 16, 0x00, 0xfc, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x3f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0f }, + new byte[] { (byte)'c', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10 }, + new byte[] { (byte)'d', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0xfc, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x3f }, + new byte[] { (byte)'e', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x0f, 0x12, 0x22, 0x22, 0x22, 0x22, 0x13 }, + new byte[] { (byte)'f', 8, 16, 0x00, 0x40, 0x40, 0xf8, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'g', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0xc0, 0x00, 0x00, 0x27, 0x48, 0x50, 0x50, 0x48, 0x3f, 0x00 }, + new byte[] { (byte)'h', 8, 16, 0x00, 0xfc, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00 }, + new byte[] { (byte)'i', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'j', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'k', 8, 16, 0x00, 0xfc, 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x3f, 0x02, 0x05, 0x08, 0x10, 0x20, 0x00 }, + new byte[] { (byte)'l', 8, 16, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'m', 8, 16, 0x00, 0xc0, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3f }, + new byte[] { (byte)'n', 8, 16, 0x00, 0xc0, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00 }, + new byte[] { (byte)'o', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0f }, + new byte[] { (byte)'p', 8, 16, 0x00, 0xc0, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x7f, 0x08, 0x10, 0x10, 0x10, 0x08, 0x07 }, + new byte[] { (byte)'q', 8, 16, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0xc0, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x08, 0x7f }, + new byte[] { (byte)'r', 8, 16, 0x00, 0x00, 0xc0, 0x80, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'s', 8, 16, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x11, 0x22, 0x22, 0x24, 0x24, 0x18, 0x00 }, + new byte[] { (byte)'t', 8, 16, 0x00, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x00 }, + new byte[] { (byte)'u', 8, 16, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x3f, 0x00 }, + new byte[] { (byte)'v', 8, 16, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00 }, + new byte[] { (byte)'w', 8, 16, 0x00, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x07, 0x38, 0x0c, 0x03, 0x0c, 0x38, 0x07 }, + new byte[] { (byte)'x', 8, 16, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x20, 0x10, 0x09, 0x06, 0x09, 0x10, 0x20 }, + new byte[] { (byte)'y', 8, 16, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x43, 0x4c, 0x30, 0x0c, 0x03, 0x00 }, + new byte[] { (byte)'z', 8, 16, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x20, 0x00 }, + new byte[] { (byte)'©', 8, 16, 0xe0, 0x18, 0xe4, 0x14, 0x14, 0x24, 0x18, 0xe0, 0x07, 0x18, 0x27, 0x28, 0x28, 0x24, 0x18, 0x07 }, + new byte[] { (byte)'®', 16, 32, 0x00, 0x00, 0xc0, 0x30, 0x08, 0xe8, 0x14, 0x14, 0x14, 0x14, 0xe8, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x10, 0x1f, 0x21, 0x21, 0x21, 0x21, 0x1e, 0x10, 0x0c, 0x03, 0x00, 0x00 }, + new byte[] { (byte)'\\' /* ° */, 16, 32, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'#' /* bulb */, 11, 22, 0x00, 0x78, 0xe4, 0xfa, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x01, 0x17, 0x77, 0x77, 0x77, 0x17, 0x01, 0x00, 0x00 }, + new byte[] { (byte)'|' /* plug */, 12, 24, 0x00, 0x60, 0xe0, 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x0f, 0x7f, 0x7f, 0x0f, 0x0f, 0x07, 0x00, 0x00 }, + new byte[] { (byte)'^' /* lightning */, 9, 18, 0x00, 0xe0, 0xfe, 0xfe, 0x5e, 0xc6, 0xe0, 0xe0, 0x00, 0x00, 0x01, 0x60, 0x38, 0x0e, 0x07, 0x01, 0x00, 0x00 } + }; + + public byte[][] GetData() + { + return Proportional2L.fontData; + } + } +} + diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional3L.cs b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional3L.cs new file mode 100644 index 0000000..5e554e1 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Proportional3L.cs @@ -0,0 +1,110 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306.Fonts +{ + public class Proportional3L + { + private static byte[][] fontData = { + new byte[] { (byte)' ', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'!', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'"', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'#', 12, 36, 0x00, 0x00, 0x80, 0x80, 0x80, 0xfc, 0xfc, 0x80, 0x80, 0xfc, 0xfc, 0x80, 0x00, 0x40, 0x40, 0xc0, 0xff, 0x7f, 0x40, 0xc0, 0xff, 0x7f, 0x40, 0x40, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'$', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0xff, 0xff, 0x04, 0x0c, 0x38, 0x30, 0x00, 0x00, 0x81, 0x83, 0x06, 0x04, 0xff, 0xff, 0x08, 0x18, 0xf0, 0xe0, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x3f, 0x3f, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'%', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0xfc, 0xf8, 0xc0, 0xf0, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x01, 0xe1, 0xf9, 0xde, 0xe7, 0x21, 0x20, 0xe0, 0xc0, 0x00, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x0f, 0x07 }, + new byte[] { (byte)'&', 12, 36, 0x00, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x39, 0x0f, 0x0e, 0x3b, 0xf1, 0xc0, 0x80, 0xf0, 0x70, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x07, 0x0d, 0x08 }, + new byte[] { (byte)'\'', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'(', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x78, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1e, 0x38, 0x60, 0x40, 0x00, 0x00 }, + new byte[] { (byte)')', 12, 36, 0x00, 0x00, 0x02, 0x06, 0x1c, 0x78, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x38, 0x1e, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'*', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x64, 0x3c, 0x1f, 0x1f, 0x3c, 0x64, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'+', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0xff, 0xff, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)',', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x2c, 0x1c, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'-', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'.', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'/', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7c, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf8, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'0', 12, 36, 0x00, 0xc0, 0xf0, 0x38, 0x0c, 0x04, 0x04, 0x04, 0x0c, 0x38, 0xf0, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'1', 12, 36, 0x00, 0x00, 0x00, 0x10, 0x10, 0x18, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'2', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0e, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x0f, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, + new byte[] { (byte)'3', 12, 36, 0x00, 0x70, 0x78, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0x80, 0x80, 0x00, 0x04, 0x04, 0x04, 0x04, 0x0e, 0xfb, 0xf1, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'4', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x1c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x9c, 0x87, 0x81, 0x80, 0x80, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00 }, + new byte[] { (byte)'5', 12, 36, 0x00, 0x00, 0xfc, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x80, 0x87, 0x07, 0x02, 0x02, 0x02, 0x02, 0x06, 0xfc, 0xf8, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'6', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x38, 0x30, 0x00, 0x00, 0xff, 0xff, 0x04, 0x02, 0x02, 0x02, 0x02, 0x06, 0xfc, 0xf8, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'7', 12, 36, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xe4, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf8, 0x7f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'8', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0xf1, 0xfb, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x0e, 0xfb, 0xf1, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'9', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0x07, 0x0f, 0x18, 0x10, 0x10, 0x10, 0x10, 0x08, 0xff, 0xff, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)':', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)';', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x07, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'<', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x60, 0x60, 0x30, 0x00, 0x00, 0x1c, 0x3e, 0x36, 0x63, 0xc1, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x06, 0x00 }, + new byte[] { (byte)'=', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'>', 12, 36, 0x00, 0x30, 0x60, 0x60, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0xc1, 0x63, 0x36, 0x3e, 0x1c, 0x00, 0x00, 0x06, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + //new byte[] { (byte)'☂', 24, 72, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x01, 0x01, 0x03, 0x0f, 0x03, 0x01, 0x01, 0x01, 0xff, 0x07, 0x01, 0x01, 0x01, 0x03, 0x0f, 0x03, 0x01, 0x01, 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x40, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'@', 12, 36, 0x00, 0x80, 0xe0, 0x70, 0x18, 0x08, 0x88, 0x08, 0x98, 0x30, 0xe0, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x7e, 0xff, 0x81, 0xff, 0x7f, 0x80, 0xff, 0x7f, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x06, 0x02 }, + new byte[] { (byte)'A', 12, 36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf8, 0x3c, 0xf8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfe, 0x4f, 0x41, 0x40, 0x41, 0x4f, 0xfe, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f }, + new byte[] { (byte)'B', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, 0xfb, 0xf1, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'C', 12, 36, 0x00, 0xc0, 0xf0, 0x38, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x38, 0x30, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03 }, + new byte[] { (byte)'D', 12, 36, 0x00, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x38, 0xf0, 0xc0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'E', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, + new byte[] { (byte)'F', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'G', 12, 36, 0x00, 0xc0, 0xf0, 0x38, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x78, 0x70, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0xfc, 0xfc, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x06, 0x0f, 0x0f }, + new byte[] { (byte)'H', 12, 36, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'I', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'J', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00, 0x00 }, + new byte[] { (byte)'K', 12, 36, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x06, 0x03, 0x0f, 0x3c, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x0c, 0x00 }, + new byte[] { (byte)'L', 12, 36, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, + new byte[] { (byte)'M', 12, 36, 0x00, 0xfc, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc, 0xfc, 0x00, 0xff, 0xff, 0x03, 0x1f, 0xf8, 0xc0, 0xf8, 0x1f, 0x03, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x0f }, + new byte[] { (byte)'N', 12, 36, 0x00, 0xfc, 0xfc, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x07, 0x1c, 0x70, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'O', 12, 36, 0x00, 0xc0, 0xf0, 0x38, 0x0c, 0x04, 0x04, 0x04, 0x0c, 0x38, 0xf0, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'P', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'Q', 12, 36, 0x00, 0xc0, 0xf0, 0x38, 0x0c, 0x04, 0x04, 0x04, 0x0c, 0x38, 0xf0, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x09, 0x0b, 0x0e, 0x0f, 0x1b, 0x10 }, + new byte[] { (byte)'R', 12, 36, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0xf8, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, 0xfb, 0xf1, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'S', 12, 36, 0x00, 0xf0, 0xf8, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x38, 0x30, 0x00, 0x00, 0x80, 0x81, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x18, 0xf0, 0xe0, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'T', 12, 36, 0x00, 0x04, 0x04, 0x04, 0x04, 0xfc, 0xfc, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'U', 12, 36, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'V', 12, 36, 0x00, 0x3c, 0xfc, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0x3c, 0x00, 0x00, 0x00, 0x03, 0x3f, 0xfc, 0xc0, 0xc0, 0xfc, 0x3f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'W', 12, 36, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xc0, 0xfc, 0xc0, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x01, 0x7f, 0xfe, 0xe0, 0x7f, 0x01, 0x7f, 0xe0, 0xfe, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00 }, + new byte[] { (byte)'X', 12, 36, 0x00, 0x0c, 0x3c, 0xf0, 0xc0, 0x00, 0x00, 0xc0, 0xf0, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf3, 0x3f, 0x3f, 0xf3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x0c, 0x00 }, + new byte[] { (byte)'Y', 12, 36, 0x00, 0x1c, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0xfc, 0xfc, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'Z', 12, 36, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xc4, 0xf4, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0f, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, + new byte[] { (byte)'[', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x00, 0x00 }, + new byte[] { (byte)']', 12, 36, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'^', 12, 36, 0x00, 0x00, 0x10, 0x18, 0x0c, 0x06, 0x06, 0x0c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'_', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }, + new byte[] { (byte)'`', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x18, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'a', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xc6, 0x63, 0x21, 0x21, 0x21, 0x23, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x0f, 0x08 }, + new byte[] { (byte)'b', 12, 36, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x04, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'c', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x06, 0x02, 0x00 }, + new byte[] { (byte)'d', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x04, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'e', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x23, 0x21, 0x21, 0x21, 0x23, 0x3e, 0x3c, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x06, 0x02, 0x00 }, + new byte[] { (byte)'f', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xff, 0xff, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'g', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x11, 0x33, 0x66, 0x44, 0x44, 0x44, 0x62, 0x3f, 0x1f, 0x00 }, + new byte[] { (byte)'h', 12, 36, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'i', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'j', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x60, 0x3f, 0x1f, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'k', 12, 36, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x60, 0x70, 0xd8, 0x8c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x08 }, + new byte[] { (byte)'l', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'m', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x01, 0x01, 0xff, 0xfe, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f }, + new byte[] { (byte)'n', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x01, 0x01, 0x03, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00 }, + new byte[] { (byte)'o', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'p', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x04, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'q', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x04, 0x7f, 0x7f, 0x00 }, + new byte[] { (byte)'r', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'s', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x33, 0x21, 0x21, 0x61, 0x43, 0xce, 0x8c, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x03, 0x00 }, + new byte[] { (byte)'t', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xff, 0xff, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00 }, + new byte[] { (byte)'u', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x04, 0x0f, 0x0f, 0x00 }, + new byte[] { (byte)'v', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3f, 0xf8, 0xc0, 0x00, 0xc0, 0xf8, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0e, 0x07, 0x01, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'w', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0xf0, 0x3e, 0xf0, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x01, 0x00, 0x01, 0x0f, 0x0f, 0x00, 0x00 }, + new byte[] { (byte)'x', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x9c, 0xf0, 0x60, 0xf0, 0x9c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x0c, 0x00 }, + new byte[] { (byte)'y', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3f, 0xf8, 0xc0, 0x00, 0x00, 0xc0, 0xf8, 0x3f, 0x07, 0x00, 0x00, 0x40, 0x40, 0x60, 0x33, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'z', 12, 36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xc1, 0xe1, 0x39, 0x1d, 0x07, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x0b, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, + new byte[] { (byte)'©', 12, 36, 0x00, 0x80, 0x60, 0x10, 0x88, 0x88, 0x88, 0x88, 0x88, 0x10, 0x60, 0x80, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x00, 0xff, 0x00, 0x01, 0x06, 0x08, 0x11, 0x11, 0x11, 0x11, 0x11, 0x08, 0x06, 0x01 }, + new byte[] { (byte)'®', 24, 72, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0x10, 0x10, 0x30, 0xf0, 0xdf, 0x0e, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x09, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x09, 0x09, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'\\' /* ° */, 10, 30, 0x00, 0x00, 0x1c, 0x36, 0x22, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'|' /* temp symbol */, 16, 48, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x81, 0x81, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0xff, 0xff, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x20, 0x4e, 0x5f, 0x5f, 0x4e, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00 } + }; + + public byte[][] GetData() + { + return Proportional3L.fontData; + } + } +} + diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Ssd1306Connection.cs b/Raspberry.IO.Components/Displays/Ssd1306/Ssd1306Connection.cs new file mode 100644 index 0000000..fae0d70 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/Ssd1306Connection.cs @@ -0,0 +1,258 @@ +#region References + +using System; +using Raspberry.IO.InterIntegratedCircuit; + +#endregion + +namespace Raspberry.IO.Components.Displays.Ssd1306 +{ + /// + /// Represents a connection with an Ssd1306 I2C OLED display. + /// + public class Ssd1306Connection + { + #region Fields + + private readonly I2cDeviceConnection connection; + private int displayWidth = 128, displayHeight = 64; + private int cursorX = 0, cursorY = 0; + private object syncObject = new object(); + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class at default width=128 and height=64. + /// + /// The connection. + public Ssd1306Connection (I2cDeviceConnection connection) : this(connection, 128, 64) { } + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The display width. + /// The display height. + public Ssd1306Connection(I2cDeviceConnection connection, int width, int height) + { + this.connection = connection; + this.displayWidth = width; + this.displayHeight = height; + Initialize(); + } + + #endregion + + #region Methods + + /// + /// Clears the screen. + /// + public void ClearScreen() + { + lock (syncObject) + for (int y = 0; y < displayWidth * displayHeight / 8; y++) + { + connection.Write(new byte[] { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + } + } + + /// + /// Inverts the display. + /// + public void InvertDisplay() + { + SendCommand(new byte[] { + Command.DisplayInvert + }); + } + + /// + /// Sets the display to normal mode. + /// + public void NormalDisplay() + { + SendCommand(new byte[] { + Command.DisplayNormal + }); + } + + /// + /// Turns the display on. + /// + public void On() + { + SendCommand(new byte[] { + Command.DisplayOn + }); + } + + /// + /// Turns the display off. + /// + public void Off() + { + SendCommand(new byte[] { + Command.DisplayOff + }); + } + + /// + /// Sets the current cursor position to , . + /// + /// Column. + /// Row. + public void GotoXY(int column, int row) + { + SendCommand(new byte[] { + (byte)(0xB0 + row), //set page address + (byte)(0x00 + (8 * column & 0x0F)), //set column lower address + (byte)(0x10 + ((8 * column >> 4) & 0x0F)) //set column higher address + }); + this.cursorX = column; + this.cursorY = row; + } + + /// + /// Draws the text. + /// + /// Font. + /// Text. + public void DrawText(IFont font, string text) + { + var charset = font.GetData(); + for (int c = 0; c < text.Length; c++) + { + int charIndex = -1; + for(int i = 0; i < charset.Length; i++) + { + if (charset[i][0] == text[c]) + { + charIndex = i; + break; + } + } + if (charIndex == -1) continue; + // + byte[] fontData = charset[charIndex]; + int fontWidth = fontData[1]; + int fontLength = fontData[2]; + for (int y = 0; y < (fontLength / fontWidth); y++) + { + SendCommand(new byte[]{ + (byte)(0xB0 + this.cursorY + y), //set page address + (byte)(0x00 + (cursorX & 0x0F)), //set column lower address + (byte)(0x10 + ((cursorX>>4)&0x0F)) //set column higher address + }); + var data = new byte[fontWidth + 1]; + data[0] = 0x40; + Array.Copy(fontData, (y * fontWidth) + 3, data, 1, fontWidth); + DrawStride(data); + } + this.cursorX += fontWidth; + } + } + + /// + /// Draws the image. + /// + /// Image. + public void DrawImage(byte[] image) + { + var data = new byte[image.Length + 1]; + data [0] = 0x40; + Array.Copy(image, 0, data, 1, image.Length); + DrawStride(data); + } + + /// + /// Activates the scroll. + /// + public void ActivateScroll() + { + SendCommand(new byte[] { + Command.ActivateScroll + }); + } + + /// + /// Deactivates the scroll. + /// + public void DeactivateScroll() + { + SendCommand(new byte[] { + Command.DeactivateScroll + }); + } + + /// + /// Sets the scroll properties. + /// + /// Direction. + /// Scroll speed. + /// Start line. + /// End line. + public void SetScrollProperties(ScrollDirection direction, ScrollSpeed scrollSpeed, int startLine, int endLine) + { + SendCommand(new byte[] { + (byte)(Command.SetScrollDirection | (byte)direction), + 0x00, + (byte)startLine, + (byte)scrollSpeed, + (byte)endLine, + 0x00, + 0xFF + }); + } + + #endregion + + #region Private Helpers + + private void SendCommand(byte[] commands) + { + lock (syncObject) + for (int c = 0; c < commands.Length; c++) + { + connection.Write(new byte[] { 0x00, commands[c] }); + } + } + + private void Initialize() + { + SendCommand(new byte[] { + Command.DisplayOff, + Command.SetDisplayClockDivider, 0x80, + Command.SetMultiplex, 0x3F, + Command.SetDisplayOffset, 0x00, + Command.SetStartLine | 0x0, + Command.ChargePump, 0x14, + Command.MemoryMode, 0x00, + Command.SegRemap | 0x1, + Command.ComScanDecrement, + Command.SetComPins, 0x12, + Command.SetContrast, 0x9F, + Command.SetPreCharge, 0x22, + Command.SetVComDetect, 0x40, + Command.DisplayAllOnResume, + Command.DisplayNormal + }); + SendCommand(new byte[] { + Command.ColumnAddress, 0, (byte)(displayWidth - 1), + Command.PageAddress, 0, (byte)((displayHeight / 8) - 1) + }); + ClearScreen(); + } + + private void DrawStride(byte[] data) + { + lock(syncObject) + connection.Write(data); + } + + #endregion + } +} + diff --git a/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs b/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs index 4b31433..cc8de58 100644 --- a/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs +++ b/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs @@ -10,244 +10,246 @@ namespace Raspberry.IO.Components.Leds.GroveRgb { - /// - /// Represents a connection with Grove Chainable RGB Led modules. - /// @see http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED - /// - public class GroveRgbConnection - { - #region Fields - - IGpioConnectionDriver driver; - ProcessorPin dataPin; - ProcessorPin clockPin; - List ledColors; - - #endregion - - #region Instance Management - - public GroveRgbConnection(ConnectorPin dataPin, ConnectorPin clockPin, int ledCount) - { - ledColors = new List(); - for(int i = 0; i < ledCount; i++) - { - // Initialize all leds with white color - ledColors.Add(new RgbColor()); - } - this.dataPin = dataPin.ToProcessor(); - this.clockPin = clockPin.ToProcessor(); - if (Raspberry.Board.Current.IsRaspberryPi) - { - driver = new GpioConnectionDriver(); - } - else - { - driver = new FileGpioConnectionDriver(); - } - driver.Allocate(this.dataPin, PinDirection.Output); - driver.Allocate(this.clockPin, PinDirection.Output); - } - - #endregion - - - #region Methods - - /// - /// Sets the color of a led. - /// - /// Led number (zero based index). - /// Red. - /// Green. - /// Blue. - public void SetColorRgb(int ledNumber, byte red, byte green, byte blue) - { - // Send data frame prefix (32x "0") - SendByte(0x00); - SendByte(0x00); - SendByte(0x00); - SendByte(0x00); - - // Send color data for each one of the leds - for (int i = 0; i < ledColors.Count; i++) - { - if (i == ledNumber) - { - ledColors[i].Red = red; - ledColors[i].Green = green; - ledColors[i].Blue = blue; - } - - // Start by sending a byte with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" - byte prefix = Convert.ToByte ("11000000", 2); - if ((blue & 0x80) == 0) - prefix |= Convert.ToByte ("00100000", 2); - if ((blue & 0x40) == 0) - prefix |= Convert.ToByte ("00010000", 2); - if ((green & 0x80) == 0) - prefix |= Convert.ToByte ("00001000", 2); - if ((green & 0x40) == 0) - prefix |= Convert.ToByte ("00000100", 2); - if ((red & 0x80) == 0) - prefix |= Convert.ToByte ("00000010", 2); - if ((red & 0x40) == 0) - prefix |= Convert.ToByte ("00000001", 2); - - SendByte(prefix); - - // Now must send the 3 colors - SendByte(ledColors[i].Blue); - SendByte(ledColors[i].Green); - SendByte(ledColors[i].Red); - } - - // Terminate data frame (32x "0") - SendByte(0x00); - SendByte(0x00); - SendByte(0x00); - SendByte(0x00); - } - - /// - /// Sets the color of a led. - /// - /// Led number (zero based index). - /// Hue. - /// Saturation. - /// Value. - public void SetColorHsv(int ledNumber, double h, double s, double v) - { - RgbColor color = HsvToRgb(h, s, v); - SetColorRgb(ledNumber, color.Red, color.Green, color.Blue); - } - - #endregion - - #region Private Helpers - - private void SendByte(byte data) - { - // Send one bit at a time, starting with the MSB - for (byte i = 0; i < 8; i++) - { - // If MSB is 1, write one and clock it, else write 0 and clock - if ((data & 0x80) != 0) - driver.Write(dataPin, true); - else - driver.Write(dataPin, false); - - // clk(): - driver.Write(clockPin, false); - HighResolutionTimer.Sleep(0.02m); - driver.Write(clockPin, true); - HighResolutionTimer.Sleep(0.02m); - - // Advance to the next bit to send - data <<= 1; - } - } - - private int Clamp(int i) - { - if (i < 0) i = 0; - if (i > 255) i = 255; - return i; - } - - private RgbColor HsvToRgb(double hue, double sat, double val) - { - byte r = 0, g = 0, b = 0; - double H = hue * 360D; - while (H < 0) { H += 360; }; - while (H >= 360) { H -= 360; }; - double R, G, B; - if (val <= 0) - { - R = G = B = 0; - } - else if (sat <= 0) - { - R = G = B = val; - } - else - { - double hf = H / 60.0; - int i = (int)Math.Floor(hf); - double f = hf - i; - double pv = val * (1 - sat); - double qv = val * (1 - sat * f); - double tv = val * (1 - sat * (1 - f)); - switch (i) - { - // Red is the dominant color - case 0: - R = val; - G = tv; - B = pv; - break; - // Green is the dominant color - case 1: - R = qv; - G = val; - B = pv; - break; - case 2: - R = pv; - G = val; - B = tv; - break; - // Blue is the dominant color - case 3: - R = pv; - G = qv; - B = val; - break; - case 4: - R = tv; - G = pv; - B = val; - break; - // Red is the dominant color - case 5: - R = val; - G = pv; - B = qv; - break; - // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. - case 6: - R = val; - G = tv; - B = pv; - break; - case -1: - R = val; - G = pv; - B = qv; - break; - // The color is not defined, we should throw an error. - default: - R = G = B = val; // Just pretend its black/white - break; - } - } - r = (byte)Clamp((int)(R * 255.0)); - g = (byte)Clamp((int)(G * 255.0)); - b = (byte)Clamp((int)(B * 255.0)); - - return new RgbColor(){ Red = r, Green = g, Blue = b }; - } - - #endregion - - } - - public class RgbColor - { - public byte Red; - public byte Green; - public byte Blue; - } - + /// + /// Represents a connection with Grove Chainable RGB Led modules. + /// @see http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED + /// + public class GroveRgbConnection: IDisposable + { + #region Fields + + IOutputBinaryPin dataPin; + IOutputBinaryPin clockPin; + List ledColors; + + #endregion + + #region Instance Management + + public GroveRgbConnection(IOutputBinaryPin dataPin, IOutputBinaryPin clockPin, int ledCount) + { + ledColors = new List(); + for (int i = 0; i < ledCount; i++) + { + // Initialize all leds with white color + ledColors.Add(new RgbColor()); + } + this.dataPin = dataPin; + this.clockPin = clockPin; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + /// + /// Sets the color of a led. + /// + /// Led number (zero based index). + /// Red. + /// Green. + /// Blue. + public void SetColor (int ledNumber, RgbColor color) + { + // Send data frame prefix (32x "0") + SendByte(0x00); + SendByte(0x00); + SendByte(0x00); + SendByte(0x00); + + // Send color data for each one of the leds + for (int i = 0; i < ledColors.Count; i++) + { + if (i == ledNumber) + { + ledColors [i].Red = color.Red; + ledColors [i].Green = color.Green; + ledColors [i].Blue = color.Blue; + } + + // Start by sending a byte with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" + byte prefix = Convert.ToByte("11000000", 2); + if ((color.Blue & 0x80) == 0) + prefix |= Convert.ToByte("00100000", 2); + if ((color.Blue & 0x40) == 0) + prefix |= Convert.ToByte("00010000", 2); + if ((color.Green & 0x80) == 0) + prefix |= Convert.ToByte("00001000", 2); + if ((color.Green & 0x40) == 0) + prefix |= Convert.ToByte("00000100", 2); + if ((color.Red & 0x80) == 0) + prefix |= Convert.ToByte("00000010", 2); + if ((color.Red & 0x40) == 0) + prefix |= Convert.ToByte("00000001", 2); + + SendByte(prefix); + + // Now must send the 3 colors + SendByte(ledColors [i].Blue); + SendByte(ledColors [i].Green); + SendByte(ledColors [i].Red); + } + + // Terminate data frame (32x "0") + SendByte(0x00); + SendByte(0x00); + SendByte(0x00); + SendByte(0x00); + } + + /// + /// Closes the connection. + /// + public void Close() + { + dataPin.Dispose(); + clockPin.Dispose(); + } + + #endregion + + #region Private Helpers + + private void SendByte(byte data) + { + // Send one bit at a time, starting with the MSB + for (byte i = 0; i < 8; i++) + { + // If MSB is 1, write one and clock it, else write 0 and clock + if ((data & 0x80) != 0) + dataPin.Write(true); + else + dataPin.Write(false); + + // clk(): + clockPin.Write(false); + HighResolutionTimer.Sleep(0.02m); + clockPin.Write(true); + HighResolutionTimer.Sleep(0.02m); + + // Advance to the next bit to send + data <<= 1; + } + } + + #endregion + } + + public class RgbColor + { + public byte Red; + public byte Green; + public byte Blue; + + /// + /// Gets RgbColor instance from Hsv color space. + /// + /// Hue. + /// Saturation. + /// Value. + public static RgbColor FromHsv(double hue, double sat, double val) + { + byte r = 0, g = 0, b = 0; + double H = hue * 360D; + while (H < 0) + { + H += 360; + } + while (H >= 360) + { + H -= 360; + } + double R, G, B; + if (val <= 0) + { + R = G = B = 0; + } + else if (sat <= 0) + { + R = G = B = val; + } + else + { + double hf = H / 60.0; + int i = (int)Math.Floor(hf); + double f = hf - i; + double pv = val * (1 - sat); + double qv = val * (1 - sat * f); + double tv = val * (1 - sat * (1 - f)); + switch(i) + { + // Red is the dominant color + case 0: + R = val; + G = tv; + B = pv; + break; + // Green is the dominant color + case 1: + R = qv; + G = val; + B = pv; + break; + case 2: + R = pv; + G = val; + B = tv; + break; + // Blue is the dominant color + case 3: + R = pv; + G = qv; + B = val; + break; + case 4: + R = tv; + G = pv; + B = val; + break; + // Red is the dominant color + case 5: + R = val; + G = pv; + B = qv; + break; + // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. + case 6: + R = val; + G = tv; + B = pv; + break; + case -1: + R = val; + G = pv; + B = qv; + break; + // The color is not defined, we should throw an error. + default: + R = G = B = val; // Just pretend its black/white + break; + } + } + r = (byte)Clamp((int)(R * 255.0)); + g = (byte)Clamp((int)(G * 255.0)); + b = (byte)Clamp((int)(B * 255.0)); + + return new RgbColor() { Red = r, Green = g, Blue = b }; + } + + private static int Clamp(int i) + { + if (i < 0) i = 0; + if (i > 255) i = 255; + return i; + } + } } diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index f3c39d8..3feff9e 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -12,6 +12,8 @@ 512 ..\ true + 12.0.0 + 2.0 true @@ -106,6 +108,12 @@ + + + + + + @@ -146,5 +154,7 @@ + + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 49cf2de..8c0511a 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -67,7 +67,7 @@ public void Allocate(ProcessorPin pin, PinDirection direction) /// The resistor. public void SetPinResistor(ProcessorPin pin, PinResistor resistor) { - //throw new NotSupportedException("Resistor are not supported by file GPIO connection driver"); + throw new NotSupportedException("Resistor are not supported by file GPIO connection driver"); } /// @@ -81,7 +81,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - //throw new NotSupportedException("Edge detection is not supported by file GPIO connection driver"); + throw new NotSupportedException("Edge detection is not supported by file GPIO connection driver"); } /// diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index 17519d6..7ee2f63 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -85,10 +85,13 @@ public void Allocate(ProcessorPin pin, PinDirection direction) using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) streamWriter.Write(direction == PinDirection.Input ? "in" : "out"); - if (direction == PinDirection.Input) + if (direction == PinDirection.Input) { - SetPinResistor(pin, PinResistor.None); - SetPinDetectedEdges(pin, PinDetectedEdges.Both); + if (Raspberry.Board.Current.IsRaspberryPi) + { + SetPinResistor (pin, PinResistor.None); + SetPinDetectedEdges (pin, PinDetectedEdges.Both); + } InitializePoll(pin); } } diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 0d0c971..14ed1bb 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -35,14 +35,12 @@ bin\Release\Raspberry.IO.GeneralPurpose.XML - - False - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - True - + + ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + @@ -86,7 +84,7 @@ - {689cb6c4-3d23-45da-8e00-87c28aea32d0} + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} Raspberry.IO.Interop diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index e8eb6f8..2ec8596 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -35,12 +35,11 @@ bin\Release\Raspberry.IO.InterIntegratedCircuit.XML - - False - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - + + ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + diff --git a/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj index a568554..9ba02d6 100644 --- a/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj +++ b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj @@ -1,5 +1,5 @@  - + Debug @@ -12,6 +12,8 @@ v4.0 512 + 12.0.0 + 2.0 true @@ -63,4 +65,4 @@ --> - \ No newline at end of file + diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index cbea414..a64e73e 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -35,13 +35,11 @@ bin\Release\Raspberry.IO.SerialPeripheralInterface.XML - - False - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - True - + + ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + @@ -79,7 +77,7 @@ Raspberry.IO - {ace64f17-87e5-43e7-97a0-bdde19059c61} + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} Raspberry.IO diff --git a/Raspberry.IO/Raspberry.IO.csproj b/Raspberry.IO/Raspberry.IO.csproj index f697055..e32a655 100644 --- a/Raspberry.IO/Raspberry.IO.csproj +++ b/Raspberry.IO/Raspberry.IO.csproj @@ -1,5 +1,5 @@  - + Debug @@ -12,6 +12,8 @@ Raspberry.IO v4.0 512 + 12.0.0 + 2.0 true @@ -59,4 +61,4 @@ --> - \ No newline at end of file + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index f3a48c7..b6dcffa 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -1,167 +1,194 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" - ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore - Icon.png = Icon.png - Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec - README.md = README.md - SharedAssemblyInfo.cs = SharedAssemblyInfo.cs - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripheralInterface", "Raspberry.IO.SerialPeripheralInterface\Raspberry.IO.SerialPeripheralInterface.csproj", "{326342E5-0411-40E8-9F2D-563D6B192568}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Chaser", "Tests\Test.Gpio.Chaser\Test.Gpio.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP3008", "Tests\Test.Gpio.MCP3008\Test.Gpio.MCP3008.csproj", "{B28253A7-BB93-40F7-B41C-B4AE369174ED}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP4822", "Tests\Test.Gpio.MCP4822\Test.Gpio.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HD44780", "Tests\Test.Gpio.HD44780\Test.Gpio.HD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HCSR04", "Tests\Test.Gpio.HCSR04\Test.Gpio.HCSR04.csproj", "{0A18AC47-CA6D-442C-A31C-6864F7DDD97D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{15ECD485-B3FD-4B6F-8491-7489DFFC89BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Tests\Test.Gpio.MCP23017\Test.Gpio.MCP23017.csproj", "{266EDDBC-F741-48F8-83B7-2CD37BACE62B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegratedCircuit", "Raspberry.IO.InterIntegratedCircuit\Raspberry.IO.InterIntegratedCircuit.csproj", "{63B8403E-BC56-43F9-A045-F61ECC3871F3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Components", "Raspberry.IO.Components\Raspberry.IO.Components.csproj", "{8388CFCA-E3DB-43F7-B049-2CB195211CE8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE3E-2730-4A56-9C64-0A58E00A5CEE}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Tests\Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.PCA9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.PCA9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.SerialPeripheralInterface", "UnitTests\Tests.Raspberry.IO.SerialPeripheralInterface\Tests.Raspberry.IO.SerialPeripheralInterface.csproj", "{17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.TLC59711", "Tests\Test.Spi.TLC59711\Test.Spi.TLC59711.csproj", "{AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO", "UnitTests\Tests.Raspberry.IO\Tests.Raspberry.IO.csproj", "{0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Components", "UnitTests\Tests.Raspberry.IO.Components\Tests.Raspberry.IO.Components.csproj", "{99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Interop", "UnitTests\Tests.Raspberry.IO.Interop\Tests.Raspberry.IO.Interop.csproj", "{CAF876A0-0FCB-44F7-96F1-53704CB6015F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.Build.0 = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.Build.0 = Release|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} - {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} - {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {57A001A7-FCF7-45EC-8E25-A390EF044E94} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + Icon.png = Icon.png + Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec + README.md = README.md + SharedAssemblyInfo.cs = SharedAssemblyInfo.cs + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{15ECD485-B3FD-4B6F-8491-7489DFFC89BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP3008", "Tests\Test.Gpio.MCP3008\Test.Gpio.MCP3008.csproj", "{B28253A7-BB93-40F7-B41C-B4AE369174ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP4822", "Tests\Test.Gpio.MCP4822\Test.Gpio.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HD44780", "Tests\Test.Gpio.HD44780\Test.Gpio.HD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HCSR04", "Tests\Test.Gpio.HCSR04\Test.Gpio.HCSR04.csproj", "{0A18AC47-CA6D-442C-A31C-6864F7DDD97D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Chaser", "Tests\Test.Gpio.Chaser\Test.Gpio.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Tests\Test.Gpio.MCP23017\Test.Gpio.MCP23017.csproj", "{266EDDBC-F741-48F8-83B7-2CD37BACE62B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Tests\Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.TLC59711", "Tests\Test.Spi.TLC59711\Test.Spi.TLC59711.csproj", "{AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.SerialPeripheralInterface", "UnitTests\Tests.Raspberry.IO.SerialPeripheralInterface\Tests.Raspberry.IO.SerialPeripheralInterface.csproj", "{17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO", "UnitTests\Tests.Raspberry.IO\Tests.Raspberry.IO.csproj", "{0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Components", "UnitTests\Tests.Raspberry.IO.Components\Tests.Raspberry.IO.Components.csproj", "{99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Interop", "UnitTests\Tests.Raspberry.IO.Interop\Tests.Raspberry.IO.Interop.csproj", "{CAF876A0-0FCB-44F7-96F1-53704CB6015F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripheralInterface", "Raspberry.IO.SerialPeripheralInterface\Raspberry.IO.SerialPeripheralInterface.csproj", "{326342E5-0411-40E8-9F2D-563D6B192568}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegratedCircuit", "Raspberry.IO.InterIntegratedCircuit\Raspberry.IO.InterIntegratedCircuit.csproj", "{63B8403E-BC56-43F9-A045-F61ECC3871F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Components", "Raspberry.IO.Components\Raspberry.IO.Components.csproj", "{8388CFCA-E3DB-43F7-B049-2CB195211CE8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE3E-2730-4A56-9C64-0A58E00A5CEE}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.Build.0 = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.Build.0 = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} + {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} + {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {57A001A7-FCF7-45EC-8E25-A390EF044E94} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj + Policies = $0 + $0.TextStylePolicy = $1 + $1.inheritsSet = null + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.AnonymousMethodBraceStyle = NextLine + $2.PropertyBraceStyle = NextLine + $2.PropertyGetBraceStyle = NextLine + $2.PropertySetBraceStyle = NextLine + $2.EventBraceStyle = NextLine + $2.EventAddBraceStyle = NextLine + $2.EventRemoveBraceStyle = NextLine + $2.StatementBraceStyle = NextLine + $2.ElseIfNewLinePlacement = SameLine + $2.AfterDelegateDeclarationParameterComma = True + $2.inheritsSet = Mono + $2.inheritsScope = text/x-csharp + $2.scope = text/x-csharp + $0.TextStylePolicy = $3 + $3.FileWidth = 120 + $3.inheritsSet = VisualStudio + $3.inheritsScope = text/plain + $3.scope = text/plain + $0.DotNetNamingPolicy = $4 + $4.DirectoryNamespaceAssociation = None + $4.ResourceNamePolicy = FileFormatDefault + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj b/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj index 6b513c6..fbe2831 100644 --- a/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj +++ b/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj @@ -48,6 +48,8 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + 4 + false bin\Release\ @@ -63,6 +65,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets true ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + 4 diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 1f61a85..0b50a03 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -44,6 +44,8 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 + false bin\Release\ @@ -53,14 +55,14 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 - - False - ..\..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - + + ..\..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + diff --git a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index 7cc39a3..5b0e788 100644 --- a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -42,6 +42,8 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 + false bin\Release\ @@ -51,6 +53,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 diff --git a/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj b/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj index d7e68ac..bddb86d 100644 --- a/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj +++ b/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj @@ -41,6 +41,8 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 + false bin\Release\ @@ -50,6 +52,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 diff --git a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj index 0aa3b74..0114dd1 100644 --- a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj +++ b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj @@ -42,6 +42,8 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 + false bin\Release\ @@ -51,6 +53,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 @@ -74,7 +77,7 @@ Raspberry.IO.GeneralPurpose - {ace64f17-87e5-43e7-97a0-bdde19059c61} + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} Raspberry.IO diff --git a/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj b/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj index 109fa6f..9c756f3 100644 --- a/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj +++ b/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj @@ -42,6 +42,8 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 + false bin\Release\ @@ -51,6 +53,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + 4 diff --git a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index f073781..e722fc3 100644 --- a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -1,5 +1,5 @@  - + Debug @@ -13,6 +13,8 @@ 512 ..\ true + 12.0.0 + 2.0 AnyCPU @@ -50,21 +52,21 @@ Properties\SharedAssemblyInfo.cs - + - {8388cfca-e3db-43f7-b049-2cb195211ce8} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Raspberry.IO.Components - {281c71ed-c36d-408e-8baa-75c381dc17e7} + {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose - {63b8403e-bc56-43f9-a045-f61ecc3871f3} + {63B8403E-BC56-43F9-A045-F61ECC3871F3} Raspberry.IO.InterIntegratedCircuit @@ -83,4 +85,4 @@ --> - \ No newline at end of file + diff --git a/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj b/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj index 6f3740b..0c215c9 100644 --- a/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj +++ b/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj @@ -11,6 +11,8 @@ Test.Gpio.WatchPin v4.5 512 + 12.0.0 + 2.0 AnyCPU diff --git a/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj b/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj index 0e0f767..c15cb64 100644 --- a/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj +++ b/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj @@ -1,5 +1,5 @@  - + Debug @@ -12,6 +12,8 @@ v4.0 512 + 12.0.0 + 2.0 AnyCPU @@ -50,19 +52,19 @@ - {8388cfca-e3db-43f7-b049-2cb195211ce8} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Raspberry.IO.Components - {281c71ed-c36d-408e-8baa-75c381dc17e7} + {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose - {689cb6c4-3d23-45da-8e00-87c28aea32d0} + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} Raspberry.IO.Interop - {326342e5-0411-40e8-9f2d-563d6b192568} + {326342E5-0411-40E8-9F2D-563D6B192568} Raspberry.IO.SerialPeripheralInterface @@ -74,4 +76,4 @@ --> - \ No newline at end of file + diff --git a/packages/repositories.config b/packages/repositories.config index 94e3276..afaac42 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,13 +1,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 51986b92f7807d50ef3e6aea3dcae071ba3f075f Mon Sep 17 00:00:00 2001 From: Gene Date: Thu, 8 Jan 2015 17:00:16 +0100 Subject: [PATCH 168/227] - Added GpioConnectionDriverCapabilities enum and IGpioConnectionDriver.GetCapabilities() - Added check against gpio connection driver capabilites for using SetPinResistor and SetPinDetectedEdges - Fixed UnitTests projects to work under Monodevelop - Added ToGpioName extension method and GpioName Attribute to ProcessorPin --- .../FileGpioConnectionDriver.cs | 15 ++++-- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 2 +- .../GpioConnectionDriver.cs | 22 +++++--- .../GpioInputBinaryPin.cs | 6 ++- .../GpioInputOutputBinaryPin.cs | 2 +- .../GpioOutputBinaryPin.cs | 3 +- .../IGpioConnectionDriver.cs | 15 ++++++ .../MemoryGpioConnectionDriver.cs | 9 ++++ Raspberry.IO.GeneralPurpose/ProcessorPin.cs | 51 ++++++++++++++++++- .../ProcessorPinExtensionMethods.cs | 17 +++++++ .../Tests.Raspberry.IO.Components.csproj | 4 +- .../Tests.Raspberry.IO.Interop.csproj | 4 +- ...pberry.IO.SerialPeripheralInterface.csproj | 4 +- .../Tests.Raspberry.IO.csproj | 4 +- 14 files changed, 133 insertions(+), 25 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 8c0511a..4ce9792 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -36,6 +36,15 @@ public FileGpioConnectionDriver() #region Methods + /// + /// Gets driver capabilities. + /// + /// The capabilites. + public GpioConnectionDriverCapabilities GetCapabilities() + { + return GpioConnectionDriverCapabilities.None; + } + /// /// Allocates the specified pin. /// @@ -43,7 +52,7 @@ public FileGpioConnectionDriver() /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - var gpioId = string.Format("gpio{0}", (int)pin); + var gpioId = pin.ToGpioName(); if (Directory.Exists(Path.Combine(gpioPath, gpioId))) Release(pin); @@ -121,7 +130,7 @@ public void Release(ProcessorPin pin) /// The pin status. public void Write(ProcessorPin pin, bool value) { - var gpioId = string.Format("gpio{0}", (int) pin); + var gpioId = pin.ToGpioName();// string.Format("gpio{0}", (int) pin); var filePath = Path.Combine(gpioId, "value"); using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) streamWriter.Write(value ? "1" : "0"); @@ -136,7 +145,7 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { - var gpioId = string.Format("gpio{0}", (int) pin); + var gpioId = pin.ToGpioName();// string.Format("gpio{0}", (int) pin); var filePath = Path.Combine(gpioId, "value"); using (var streamReader = new StreamReader(new FileStream(Path.Combine(gpioPath, filePath), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index 6d3b6da..23eebe6 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -498,7 +498,7 @@ private void Allocate(PinConfiguration configuration) inputPins = inputPins | pin; pinRawValues = Driver.Read(inputPins); - if (inputConfiguration.Resistor != PinResistor.None) + if (inputConfiguration.Resistor != PinResistor.None && (Driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) > 0) Driver.SetPinResistor(inputConfiguration.Pin, inputConfiguration.Resistor); var switchConfiguration = inputConfiguration as SwitchInputPinConfiguration; diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index 7ee2f63..647bedc 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -58,6 +58,15 @@ public GpioConnectionDriver() { #region Methods + /// + /// Gets driver capabilities. + /// + /// The capabilites. + public GpioConnectionDriverCapabilities GetCapabilities() + { + return GpioConnectionDriverCapabilities.CanSetPinResistor | GpioConnectionDriverCapabilities.CanSetPinDetectedEdges; + } + /// /// Allocates the specified pin. /// @@ -65,7 +74,7 @@ public GpioConnectionDriver() { /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - var gpioId = string.Format("gpio{0}", (int)pin); + var gpioId = pin.ToGpioName(); // string.Format("gpio{0}", (int)pin); if (Directory.Exists(Path.Combine(gpioPath, gpioId))) { // Reinitialize pin virtual file @@ -87,11 +96,8 @@ public void Allocate(ProcessorPin pin, PinDirection direction) if (direction == PinDirection.Input) { - if (Raspberry.Board.Current.IsRaspberryPi) - { - SetPinResistor (pin, PinResistor.None); - SetPinDetectedEdges (pin, PinDetectedEdges.Both); - } + SetPinResistor(pin, PinResistor.None); + SetPinDetectedEdges(pin, PinDetectedEdges.Both); InitializePoll(pin); } } @@ -154,7 +160,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// By default, both edges may be detected on input pins. public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - var edgePath = Path.Combine(gpioPath, string.Format("gpio{0}/edge", (int)pin)); + var edgePath = Path.Combine(gpioPath, string.Format("{0}/edge", pin.ToGpioName()));//Path.Combine(gpioPath, string.Format("gpio{0}/edge", (int)pin)); using (var streamWriter = new StreamWriter(edgePath, false)) streamWriter.Write(ToString(edges)); } @@ -280,7 +286,7 @@ private void InitializePoll(ProcessorPin pin) if (pinPoll.PollDescriptor < 0) throw new IOException("Call to epoll_create(1) API failed with the following return value: " + pinPoll.PollDescriptor); - var valuePath = Path.Combine(gpioPath, string.Format("gpio{0}/value", (int)pin)); + var valuePath = Path.Combine(gpioPath, string.Format("{0}/value", pin.ToGpioName())); //Path.Combine(gpioPath, string.Format("gpio{0}/value", (int)pin)); pinPoll.FileDescriptor = UnixFile.OpenFileDescriptor(valuePath, UnixFileMode.ReadOnly | UnixFileMode.NonBlocking); diff --git a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs index 7de9aa2..8913084 100644 --- a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs @@ -26,8 +26,10 @@ public GpioInputBinaryPin(IGpioConnectionDriver driver, ProcessorPin pin, PinRes this.pin = pin; driver.Allocate(pin, PinDirection.Input); - driver.SetPinResistor(pin, resistor); - driver.SetPinDetectedEdges(pin, PinDetectedEdges.Both); + if ((driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) > 0) + driver.SetPinResistor(pin, resistor); + if ((driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinDetectedEdges) > 0) + driver.SetPinDetectedEdges(pin, PinDetectedEdges.Both); } /// diff --git a/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs index f68f370..a7858e8 100644 --- a/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs @@ -72,7 +72,7 @@ private void SetDirection(PinDirection newDirection) driver.Release(pin); driver.Allocate(pin, newDirection); - if (newDirection == PinDirection.Input && resistor != PinResistor.None) + if (newDirection == PinDirection.Input && resistor != PinResistor.None && (driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) > 0) driver.SetPinResistor(pin, resistor); direction = newDirection; diff --git a/Raspberry.IO.GeneralPurpose/GpioOutputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioOutputBinaryPin.cs index f60ce73..19e4f29 100644 --- a/Raspberry.IO.GeneralPurpose/GpioOutputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioOutputBinaryPin.cs @@ -26,7 +26,8 @@ public GpioOutputBinaryPin(IGpioConnectionDriver driver, ProcessorPin pin, PinRe this.pin = pin; driver.Allocate(pin, PinDirection.Output); - driver.SetPinResistor(pin, resistor); + if ((driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) > 0) + driver.SetPinResistor(pin, resistor); } #endregion diff --git a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs index f63d466..91b6d4f 100644 --- a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs @@ -1,5 +1,15 @@ +using System; + namespace Raspberry.IO.GeneralPurpose { + [Flags] + public enum GpioConnectionDriverCapabilities + { + None = 0, + CanSetPinResistor = 1, + CanSetPinDetectedEdges = 2 + } + /// /// Provides an interface for connection drivers. /// @@ -7,6 +17,11 @@ public interface IGpioConnectionDriver { #region Methods + /// + /// Gets driver capabilities. + /// + GpioConnectionDriverCapabilities GetCapabilities(); + /// /// Allocates the specified pin. /// diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 94f39ea..8c1c74a 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -51,6 +51,15 @@ public MemoryGpioConnectionDriver() { #endregion #region Methods + + /// + /// Gets driver capabilities. + /// + /// The capabilites. + public GpioConnectionDriverCapabilities GetCapabilities() + { + return GpioConnectionDriverCapabilities.CanSetPinResistor | GpioConnectionDriverCapabilities.CanSetPinDetectedEdges; + } /// /// Allocates the specified pin. diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs index 626e709..e79e557 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs @@ -1,3 +1,5 @@ +using System; + namespace Raspberry.IO.GeneralPurpose { /// @@ -8,6 +10,7 @@ public enum ProcessorPin /// /// Pin 0. /// + [GpioName("gpio0")] Pin0 = 0, /// @@ -18,6 +21,7 @@ public enum ProcessorPin /// /// Pin 1. /// + [GpioName("gpio1")] Pin1 = 1, /// @@ -28,6 +32,7 @@ public enum ProcessorPin /// /// Pin 2. /// + [GpioName("gpio2")] Pin2 = 2, /// @@ -38,6 +43,7 @@ public enum ProcessorPin /// /// Pin 3. /// + [GpioName("gpio3")] Pin3 = 3, /// @@ -48,6 +54,7 @@ public enum ProcessorPin /// /// Pin 4. /// + [GpioName("gpio4")] Pin4 = 4, /// @@ -58,6 +65,7 @@ public enum ProcessorPin /// /// Pin 5. /// + [GpioName("gpio5")] Pin5 = 5, /// @@ -68,6 +76,7 @@ public enum ProcessorPin /// /// Pin 6. /// + [GpioName("gpio6")] Pin6 = 6, /// @@ -78,6 +87,7 @@ public enum ProcessorPin /// /// Pin 7. /// + [GpioName("gpio7")] Pin7 = 7, /// @@ -88,6 +98,7 @@ public enum ProcessorPin /// /// Pin 8. /// + [GpioName("gpio8")] Pin8 = 8, /// @@ -95,9 +106,10 @@ public enum ProcessorPin /// Pin08 = Pin8, - /// + // /// Pin 9. /// + [GpioName("gpio9")] Pin9 = 9, /// @@ -108,111 +120,148 @@ public enum ProcessorPin /// /// Pin 10. /// + [GpioName("gpio10")] Pin10 = 10, /// /// Pin 11. /// + [GpioName("gpio11")] Pin11 = 11, /// /// Pin 12. /// + [GpioName("gpio12")] Pin12 = 12, /// /// Pin 13. /// + [GpioName("gpio13")] Pin13 = 13, /// /// Pin 14. /// + [GpioName("gpio14")] Pin14 = 14, /// /// Pin 15. /// + [GpioName("gpio15")] Pin15 = 15, /// /// Pin 16. /// + [GpioName("gpio16")] Pin16 = 16, /// /// Pin 17. /// + [GpioName("gpio17")] Pin17 = 17, /// /// Pin 18. /// + [GpioName("gpio18")] Pin18 = 18, /// /// Pin 19. /// + [GpioName("gpio19")] Pin19 = 19, /// /// Pin 20. /// + [GpioName("gpio20")] Pin20 = 20, /// /// Pin 21. /// + [GpioName("gpio21")] Pin21 = 21, /// /// Pin 22. /// + [GpioName("gpio22")] Pin22 = 22, /// /// Pin 23. /// + [GpioName("gpio23")] Pin23 = 23, /// /// Pin 24. /// + [GpioName("gpio24")] Pin24 = 24, /// /// Pin 25. /// + [GpioName("gpio25")] Pin25 = 25, /// /// Pin 26. /// + [GpioName("gpio26")] Pin26 = 26, /// /// Pin 27. /// + [GpioName("gpio27")] Pin27 = 27, /// /// Pin 28. /// + [GpioName("gpio28")] Pin28 = 28, /// /// Pin 29. /// + [GpioName("gpio29")] Pin29 = 29, /// /// Pin 30. /// + [GpioName("gpio30")] Pin30 = 30, /// /// Pin 31. /// + [GpioName("gpio31")] Pin31 = 31 } + + #region Custom Attribute classes + + class GpioName : Attribute + { + public string Name; + + public GpioName(string name) + { + Name = name; + } + } + + #endregion + } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs index b3d5f53..7f22a83 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; #endregion @@ -28,6 +29,22 @@ public static IEnumerable Enumerate(this ProcessorPins pins) .ToArray(); } + public static string ToGpioName(this Enum en) + { + Type type = en.GetType(); + MemberInfo[] memInfo = type.GetMember(en.ToString()); + if (memInfo != null && memInfo.Length > 0) + { + object[] attrs = memInfo[0].GetCustomAttributes( + typeof(GpioName), + false); + + if (attrs != null && attrs.Length > 0) + return ((GpioName)attrs[0]).Name; + } + return en.ToString(); + } + #endregion } } \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index cc3c267..4fa5e4b 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -1,5 +1,5 @@  - + Debug @@ -88,4 +88,4 @@ --> - \ No newline at end of file + diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index 6b0183d..d114492 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -1,5 +1,5 @@  - + Debug @@ -80,4 +80,4 @@ --> - \ No newline at end of file + diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index 99a037c..42f0702 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -1,5 +1,5 @@  - + Debug @@ -86,4 +86,4 @@ --> - \ No newline at end of file + diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index 56a90f9..510b7b0 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -1,5 +1,5 @@  - + Debug @@ -67,4 +67,4 @@ --> - \ No newline at end of file + From 4649bd82c93b9d7b2d0c753be814c78ae7c79eae Mon Sep 17 00:00:00 2001 From: Gene Date: Thu, 8 Jan 2015 21:20:18 +0100 Subject: [PATCH 169/227] - removed useless ToGpioName extension method added in previous commit - removed CanSetPinDetectedEdges from MemoryGpioConnectionDriver capabilities --- .../FileGpioConnectionDriver.cs | 6 +-- .../GpioConnectionDriver.cs | 6 +-- .../MemoryGpioConnectionDriver.cs | 2 +- Raspberry.IO.GeneralPurpose/ProcessorPin.cs | 51 +------------------ .../ProcessorPinExtensionMethods.cs | 17 ------- 5 files changed, 8 insertions(+), 74 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 4ce9792..3a2603a 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -52,7 +52,7 @@ public GpioConnectionDriverCapabilities GetCapabilities() /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - var gpioId = pin.ToGpioName(); + var gpioId = string.Format("gpio{0}", (int)pin); if (Directory.Exists(Path.Combine(gpioPath, gpioId))) Release(pin); @@ -130,7 +130,7 @@ public void Release(ProcessorPin pin) /// The pin status. public void Write(ProcessorPin pin, bool value) { - var gpioId = pin.ToGpioName();// string.Format("gpio{0}", (int) pin); + var gpioId = string.Format("gpio{0}", (int) pin); var filePath = Path.Combine(gpioId, "value"); using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) streamWriter.Write(value ? "1" : "0"); @@ -145,7 +145,7 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { - var gpioId = pin.ToGpioName();// string.Format("gpio{0}", (int) pin); + var gpioId = string.Format("gpio{0}", (int) pin); var filePath = Path.Combine(gpioId, "value"); using (var streamReader = new StreamReader(new FileStream(Path.Combine(gpioPath, filePath), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index 647bedc..46fceca 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -74,7 +74,7 @@ public GpioConnectionDriverCapabilities GetCapabilities() /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - var gpioId = pin.ToGpioName(); // string.Format("gpio{0}", (int)pin); + var gpioId = string.Format("gpio{0}", (int)pin); if (Directory.Exists(Path.Combine(gpioPath, gpioId))) { // Reinitialize pin virtual file @@ -160,7 +160,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// By default, both edges may be detected on input pins. public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - var edgePath = Path.Combine(gpioPath, string.Format("{0}/edge", pin.ToGpioName()));//Path.Combine(gpioPath, string.Format("gpio{0}/edge", (int)pin)); + var edgePath = Path.Combine(gpioPath, string.Format("gpio{0}/edge", (int)pin)); using (var streamWriter = new StreamWriter(edgePath, false)) streamWriter.Write(ToString(edges)); } @@ -286,7 +286,7 @@ private void InitializePoll(ProcessorPin pin) if (pinPoll.PollDescriptor < 0) throw new IOException("Call to epoll_create(1) API failed with the following return value: " + pinPoll.PollDescriptor); - var valuePath = Path.Combine(gpioPath, string.Format("{0}/value", pin.ToGpioName())); //Path.Combine(gpioPath, string.Format("gpio{0}/value", (int)pin)); + var valuePath = Path.Combine(gpioPath, string.Format("gpio{0}/value", (int)pin)); pinPoll.FileDescriptor = UnixFile.OpenFileDescriptor(valuePath, UnixFileMode.ReadOnly | UnixFileMode.NonBlocking); diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 8c1c74a..4dff5b8 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -58,7 +58,7 @@ public MemoryGpioConnectionDriver() { /// The capabilites. public GpioConnectionDriverCapabilities GetCapabilities() { - return GpioConnectionDriverCapabilities.CanSetPinResistor | GpioConnectionDriverCapabilities.CanSetPinDetectedEdges; + return GpioConnectionDriverCapabilities.CanSetPinResistor; } /// diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs index e79e557..626e709 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs @@ -1,5 +1,3 @@ -using System; - namespace Raspberry.IO.GeneralPurpose { /// @@ -10,7 +8,6 @@ public enum ProcessorPin /// /// Pin 0. /// - [GpioName("gpio0")] Pin0 = 0, /// @@ -21,7 +18,6 @@ public enum ProcessorPin /// /// Pin 1. /// - [GpioName("gpio1")] Pin1 = 1, /// @@ -32,7 +28,6 @@ public enum ProcessorPin /// /// Pin 2. /// - [GpioName("gpio2")] Pin2 = 2, /// @@ -43,7 +38,6 @@ public enum ProcessorPin /// /// Pin 3. /// - [GpioName("gpio3")] Pin3 = 3, /// @@ -54,7 +48,6 @@ public enum ProcessorPin /// /// Pin 4. /// - [GpioName("gpio4")] Pin4 = 4, /// @@ -65,7 +58,6 @@ public enum ProcessorPin /// /// Pin 5. /// - [GpioName("gpio5")] Pin5 = 5, /// @@ -76,7 +68,6 @@ public enum ProcessorPin /// /// Pin 6. /// - [GpioName("gpio6")] Pin6 = 6, /// @@ -87,7 +78,6 @@ public enum ProcessorPin /// /// Pin 7. /// - [GpioName("gpio7")] Pin7 = 7, /// @@ -98,7 +88,6 @@ public enum ProcessorPin /// /// Pin 8. /// - [GpioName("gpio8")] Pin8 = 8, /// @@ -106,10 +95,9 @@ public enum ProcessorPin /// Pin08 = Pin8, - // + /// /// Pin 9. /// - [GpioName("gpio9")] Pin9 = 9, /// @@ -120,148 +108,111 @@ public enum ProcessorPin /// /// Pin 10. /// - [GpioName("gpio10")] Pin10 = 10, /// /// Pin 11. /// - [GpioName("gpio11")] Pin11 = 11, /// /// Pin 12. /// - [GpioName("gpio12")] Pin12 = 12, /// /// Pin 13. /// - [GpioName("gpio13")] Pin13 = 13, /// /// Pin 14. /// - [GpioName("gpio14")] Pin14 = 14, /// /// Pin 15. /// - [GpioName("gpio15")] Pin15 = 15, /// /// Pin 16. /// - [GpioName("gpio16")] Pin16 = 16, /// /// Pin 17. /// - [GpioName("gpio17")] Pin17 = 17, /// /// Pin 18. /// - [GpioName("gpio18")] Pin18 = 18, /// /// Pin 19. /// - [GpioName("gpio19")] Pin19 = 19, /// /// Pin 20. /// - [GpioName("gpio20")] Pin20 = 20, /// /// Pin 21. /// - [GpioName("gpio21")] Pin21 = 21, /// /// Pin 22. /// - [GpioName("gpio22")] Pin22 = 22, /// /// Pin 23. /// - [GpioName("gpio23")] Pin23 = 23, /// /// Pin 24. /// - [GpioName("gpio24")] Pin24 = 24, /// /// Pin 25. /// - [GpioName("gpio25")] Pin25 = 25, /// /// Pin 26. /// - [GpioName("gpio26")] Pin26 = 26, /// /// Pin 27. /// - [GpioName("gpio27")] Pin27 = 27, /// /// Pin 28. /// - [GpioName("gpio28")] Pin28 = 28, /// /// Pin 29. /// - [GpioName("gpio29")] Pin29 = 29, /// /// Pin 30. /// - [GpioName("gpio30")] Pin30 = 30, /// /// Pin 31. /// - [GpioName("gpio31")] Pin31 = 31 } - - #region Custom Attribute classes - - class GpioName : Attribute - { - public string Name; - - public GpioName(string name) - { - Name = name; - } - } - - #endregion - } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs index 7f22a83..b3d5f53 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPinExtensionMethods.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; #endregion @@ -29,22 +28,6 @@ public static IEnumerable Enumerate(this ProcessorPins pins) .ToArray(); } - public static string ToGpioName(this Enum en) - { - Type type = en.GetType(); - MemberInfo[] memInfo = type.GetMember(en.ToString()); - if (memInfo != null && memInfo.Length > 0) - { - object[] attrs = memInfo[0].GetCustomAttributes( - typeof(GpioName), - false); - - if (attrs != null && attrs.Length > 0) - return ((GpioName)attrs[0]).Name; - } - return en.ToString(); - } - #endregion } } \ No newline at end of file From 28f535c5fdbe4b42f3cf9fcfea9c732ee1e5687e Mon Sep 17 00:00:00 2001 From: Gene Date: Thu, 15 Jan 2015 14:58:10 +0100 Subject: [PATCH 170/227] - Added Grove Led Bar component - Minor changes to Grove Rgb component - Added CubieTruck/CubieBoard3 auto detect and connector mappings (CN8/CN9) - Modified FileGpioConnectionDriver to work with sunxi /sys/class/gpio --- .../Leds/GroveBar/GroveBarConnection.cs | 182 ++++++++++++++ .../Leds/GroveRgb/GroveRgbConnection.cs | 109 --------- .../Leds/GroveRgb/RgbColor.cs | 144 +++++++++++ .../Raspberry.IO.Components.csproj | 3 + Raspberry.IO.GeneralPurpose/ConnectorPin.cs | 223 +++++++++++++++++- .../FileGpioConnectionDriver.cs | 32 ++- .../GpioConnectionDriver.cs | 6 +- Raspberry.IO.GeneralPurpose/PinMapping.cs | 214 +++++++++++------ RaspberrySharp.IO.sln | 7 + .../Tests.Raspberry.IO.Components.csproj | 12 +- .../Tests.Raspberry.IO.Interop.csproj | 8 +- ...pberry.IO.SerialPeripheralInterface.csproj | 22 +- .../Tests.Raspberry.IO.csproj | 2 + 13 files changed, 748 insertions(+), 216 deletions(-) create mode 100644 Raspberry.IO.Components/Leds/GroveBar/GroveBarConnection.cs create mode 100644 Raspberry.IO.Components/Leds/GroveRgb/RgbColor.cs diff --git a/Raspberry.IO.Components/Leds/GroveBar/GroveBarConnection.cs b/Raspberry.IO.Components/Leds/GroveBar/GroveBarConnection.cs new file mode 100644 index 0000000..d84346d --- /dev/null +++ b/Raspberry.IO.Components/Leds/GroveBar/GroveBarConnection.cs @@ -0,0 +1,182 @@ +#region References + +using System; +using Raspberry.IO; +using Raspberry.Timers; +using Raspberry.IO.GeneralPurpose; +using System.Text; + +#endregion + +namespace Raspberry.IO.Components.Leds.GroveBar +{ + /// + /// Represents a connection with Grove Led Bar module. + /// @see http://www.seeedstudio.com/wiki/Grove_-_LED_Bar + /// + public class GroveBarConnection : IDisposable + { + #region Fields + + private IOutputBinaryPin dataPin; + private IInputOutputBinaryPin clockPin; + private const uint CommandMode = 0x0000; + private string currentLedsStatus = "0000000000"; + + #endregion + + #region Instance Management + + public GroveBarConnection(IOutputBinaryPin dataPin, IInputOutputBinaryPin clockPin) + { + this.dataPin = dataPin; + this.clockPin = clockPin; + Initialize(); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + /// + /// Sets status of leds from a binary string eg: "0010101011", where "0" is off and "1" is on + /// + /// Leds string. + public void SetFromString(string ledsString) + { + currentLedsStatus = ledsString; + SendData(CommandMode); + uint indexBits = (uint)Convert.ToInt32(ledsString, 2); + for (int i = 0; i < 12; i++) + { + uint state = (uint)((indexBits & 0x0001) > 0 ? 0x00FF : 0x0000); + SendData(state); + indexBits = indexBits >> 1; + } + LatchData(); + } + + /// + /// Sets the level of the leds bar. + /// + /// Level. + public void SetLevel(int level) + { + var status = new StringBuilder(new string('0', 10)); + for (int i = 0; i < level; i++) + { + status[i] = '1'; + } + currentLedsStatus = status.ToString(); + SendData(CommandMode); + for (int i = 0; i < 12; i++) + { + uint state = (uint)((i < level) ? 0x00FF : 0x0000); + SendData(state); + } + LatchData(); + } + + /// + /// Turn on a single led at a given position (0-9) + /// + /// Position. + public void On(int position) + { + var status = new StringBuilder(currentLedsStatus); + status[position] = '1'; + currentLedsStatus = status.ToString(); + SetFromString(currentLedsStatus); + } + + /// + /// Turn off a single led at a given position (0-9) + /// + /// Position. + public void Off(int position) + { + var status = new StringBuilder(currentLedsStatus); + status[position] = '0'; + currentLedsStatus = status.ToString(); + SetFromString(currentLedsStatus); + } + + /// + /// Turn all leds on. + /// + public void AllOn() + { + currentLedsStatus = new string('1', 10); + SetFromString(currentLedsStatus); + } + + /// + /// Turn all leds off. + /// + public void AllOff() + { + currentLedsStatus = new string('0', 10); + SetFromString(currentLedsStatus); + } + + /// + /// Closes the connection. + /// + public void Close() + { + dataPin.Dispose(); + clockPin.Dispose(); + } + + #endregion + + #region Private Helpers + + private void Initialize() + { + dataPin.Write(false); + Raspberry.Timers.HighResolutionTimer.Sleep(0.000001m); + for(int i = 0; i < 4; i++) + { + dataPin.Write(true); + dataPin.Write(false); + } + + } + + private void SendData(uint data) + { + // Send 16 bit data + for(int i = 0; i < 16; i++) + { + bool state = ((data & 0x8000) > 0 ? true : false); + dataPin.Write(state); + state = clockPin.Read() ? false : true; + clockPin.Write(state); + data <<= 1; + } + } + + private void LatchData() + { + dataPin.Write(false); + Raspberry.Timers.HighResolutionTimer.Sleep(0.000001m); + for(int i = 0; i < 4; i++) + { + dataPin.Write(true); + dataPin.Write(false); + } + } + + #endregion + } +} + diff --git a/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs b/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs index cc8de58..2b42707 100644 --- a/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs +++ b/Raspberry.IO.Components/Leds/GroveRgb/GroveRgbConnection.cs @@ -142,114 +142,5 @@ private void SendByte(byte data) #endregion } - - public class RgbColor - { - public byte Red; - public byte Green; - public byte Blue; - - /// - /// Gets RgbColor instance from Hsv color space. - /// - /// Hue. - /// Saturation. - /// Value. - public static RgbColor FromHsv(double hue, double sat, double val) - { - byte r = 0, g = 0, b = 0; - double H = hue * 360D; - while (H < 0) - { - H += 360; - } - while (H >= 360) - { - H -= 360; - } - double R, G, B; - if (val <= 0) - { - R = G = B = 0; - } - else if (sat <= 0) - { - R = G = B = val; - } - else - { - double hf = H / 60.0; - int i = (int)Math.Floor(hf); - double f = hf - i; - double pv = val * (1 - sat); - double qv = val * (1 - sat * f); - double tv = val * (1 - sat * (1 - f)); - switch(i) - { - // Red is the dominant color - case 0: - R = val; - G = tv; - B = pv; - break; - // Green is the dominant color - case 1: - R = qv; - G = val; - B = pv; - break; - case 2: - R = pv; - G = val; - B = tv; - break; - // Blue is the dominant color - case 3: - R = pv; - G = qv; - B = val; - break; - case 4: - R = tv; - G = pv; - B = val; - break; - // Red is the dominant color - case 5: - R = val; - G = pv; - B = qv; - break; - // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. - case 6: - R = val; - G = tv; - B = pv; - break; - case -1: - R = val; - G = pv; - B = qv; - break; - // The color is not defined, we should throw an error. - default: - R = G = B = val; // Just pretend its black/white - break; - } - } - r = (byte)Clamp((int)(R * 255.0)); - g = (byte)Clamp((int)(G * 255.0)); - b = (byte)Clamp((int)(B * 255.0)); - - return new RgbColor() { Red = r, Green = g, Blue = b }; - } - - private static int Clamp(int i) - { - if (i < 0) i = 0; - if (i > 255) i = 255; - return i; - } - } } diff --git a/Raspberry.IO.Components/Leds/GroveRgb/RgbColor.cs b/Raspberry.IO.Components/Leds/GroveRgb/RgbColor.cs new file mode 100644 index 0000000..e0bfba4 --- /dev/null +++ b/Raspberry.IO.Components/Leds/GroveRgb/RgbColor.cs @@ -0,0 +1,144 @@ +using System; + +namespace Raspberry.IO.Components.Leds.GroveRgb +{ + public class RgbColor + { + #region Instance Management + + public RgbColor() + { + Red = 0; + Green = 0; + Blue = 0; + } + + public RgbColor(byte r, byte g, byte b) + { + Red = r; + Green = g; + Blue = b; + } + + #endregion + + #region Properties + + public byte Red { get; set; } + public byte Green { get; set; } + public byte Blue { get; set; } + + #endregion + + #region Methods + + /// + /// Gets RgbColor instance from Hsv color space. + /// + /// Hue. + /// Saturation. + /// Value. + public static RgbColor FromHsv(double hue, double sat, double val) + { + byte r = 0, g = 0, b = 0; + double H = hue * 360D; + while (H < 0) + { + H += 360; + } + while (H >= 360) + { + H -= 360; + } + double R, G, B; + if (val <= 0) + { + R = G = B = 0; + } + else if (sat <= 0) + { + R = G = B = val; + } + else + { + double hf = H / 60.0; + int i = (int)Math.Floor(hf); + double f = hf - i; + double pv = val * (1 - sat); + double qv = val * (1 - sat * f); + double tv = val * (1 - sat * (1 - f)); + switch(i) + { + // Red is the dominant color + case 0: + R = val; + G = tv; + B = pv; + break; + // Green is the dominant color + case 1: + R = qv; + G = val; + B = pv; + break; + case 2: + R = pv; + G = val; + B = tv; + break; + // Blue is the dominant color + case 3: + R = pv; + G = qv; + B = val; + break; + case 4: + R = tv; + G = pv; + B = val; + break; + // Red is the dominant color + case 5: + R = val; + G = pv; + B = qv; + break; + // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. + case 6: + R = val; + G = tv; + B = pv; + break; + case -1: + R = val; + G = pv; + B = qv; + break; + // The color is not defined, we should throw an error. + default: + R = G = B = val; // Just pretend its black/white + break; + } + } + r = (byte)Clamp((int)(R * 255.0)); + g = (byte)Clamp((int)(G * 255.0)); + b = (byte)Clamp((int)(B * 255.0)); + + return new RgbColor() { Red = r, Green = g, Blue = b }; + } + + #endregion + + #region Private Helpers + + private static int Clamp(int i) + { + if (i < 0) i = 0; + if (i > 255) i = 255; + return i; + } + + #endregion + } +} + diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 3feff9e..899a247 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -114,6 +114,8 @@ + + @@ -156,5 +158,6 @@ + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs index bc91ef7..22a53b8 100644 --- a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs @@ -5,6 +5,8 @@ namespace Raspberry.IO.GeneralPurpose /// public enum ConnectorPin { + #region Raspberry Pi connectors + /// /// Connector P1, pin 3. /// @@ -135,7 +137,7 @@ public enum ConnectorPin /// /// Connector P1, pin 32. - /// + /// enum P1Pin32, /// @@ -211,5 +213,224 @@ public enum ConnectorPin /// P5Pin06 = P5Pin6, + #endregion + + #region CubieTruck/CubieBoard3 connectors + + // CubieTruck/CubieBoard3 Connector CN8 + + /// + /// Connector CN8, Pin 5 (PC19) + /// + CB3_CN8Pin5, + + /// + /// Connector CN8, Pin 5 (PC19) + /// + CB3_CN8Pin05 = CB3_CN8Pin5, + + /// + /// Connector CN8, Pin 6 (PC21) + /// + CB3_CN8Pin6, + + /// + /// Connector CN8, Pin 6 (PC21) + /// + CB3_CN8Pin06 = CB3_CN8Pin6, + + /// + /// Connector CN8, Pin 7 (PC20) + /// + CB3_CN8Pin7, + + /// + /// Connector CN8, Pin 7 (PC20) + /// + CB3_CN8Pin07 = CB3_CN8Pin7, + + /// + /// Connector CN8, Pin 8 (PC22) + /// + CB3_CN8Pin8, + + /// + /// Connector CN8, Pin 8 (PC22) + /// + CB3_CN8Pin08 = CB3_CN8Pin8, + + /// + /// Connector CN8, Pin 9 (PB14) + /// + CB3_CN8Pin9, + + /// + /// Connector CN8, Pin 9 (PB14) + /// + CB3_CN8Pin09 = CB3_CN8Pin9, + + /// + /// Connector CN8, Pin 10 (PB16) + /// + CB3_CN8Pin10, + + /// + /// Connector CN8, Pin 11 (PB15) + /// + CB3_CN8Pin11, + + /// + /// Connector CN8, Pin 12 (PB17) + /// + CB3_CN8Pin12, + + /// + /// Connector CN8, Pin 15 (PI20) + /// + CB3_CN8Pin15, + + /// + /// Connector CN8, Pin 16 (PI14) + /// + CB3_CN8Pin16, + + /// + /// Connector CN8, Pin 17 (PI21) + /// + CB3_CN8Pin17, + + /// + /// Connector CN8, Pin 18 (PI15) + /// + CB3_CN8Pin18, + + /// + /// Connector CN8, Pin 19 (PI3) + /// + CB3_CN8Pin19, + + /// + /// Connector CN8, Pin 20 (PB3) + /// + CB3_CN8Pin20, + + /// + /// Connector CN8, Pin 21 (PB2) + /// + CB3_CN8Pin21, + + /// + /// Connector CN8, Pin 22 (PB4) + /// + CB3_CN8Pin22, + + /// + /// Connector CN8, Pin 23 (PB18) + /// + CB3_CN8Pin23, + + /// + /// Connector CN8, Pin 25 (PB19) + /// + CB3_CN8Pin25, + + // CubieTruck/CubieBoard3 Connector CN9 + + /// + /// Connector CN9, Pin 3 (PG0) + /// + CB3_CN9Pin3, + + /// + /// Connector CN9, Pin 3 (PG0) + /// + CB3_CN9Pin03 = CB3_CN9Pin3, + + /// + /// Connector CN9, Pin 4 (PG3) + /// + CB3_CN9Pin4, + + /// + /// Connector CN9, Pin 4 (PG3) + /// + CB3_CN9Pin04 = CB3_CN9Pin4, + + /// + /// Connector CN9, Pin 5 (PG2) + /// + CB3_CN9Pin5, + + /// + /// Connector CN9, Pin 5 (PG2) + /// + CB3_CN9Pin05 = CB3_CN9Pin5, + + /// + /// Connector CN9, Pin 6 (PG1) + /// + CB3_CN9Pin6, + + /// + /// Connector CN9, Pin 6 (PG1) + /// + CB3_CN9Pin06 = CB3_CN9Pin6, + + /// + /// Connector CN9, Pin 7 (PG4) + /// + CB3_CN9Pin7, + + /// + /// Connector CN9, Pin 7 (PG4) + /// + CB3_CN9Pin07 = CB3_CN9Pin7, + + /// + /// Connector CN9, Pin 8 (PG5) + /// + CB3_CN9Pin8, + + /// + /// Connector CN9, Pin 8 (PG5) + /// + CB3_CN9Pin08 = CB3_CN9Pin8, + + /// + /// Connector CN9, Pin 9 (PG6) + /// + CB3_CN9Pin9, + + /// + /// Connector CN9, Pin 9 (PG6) + /// + CB3_CN9Pin09 = CB3_CN9Pin9, + + /// + /// Connector CN9, Pin 10 (PG7) + /// + CB3_CN9Pin10, + + /// + /// Connector CN9, Pin 11 (PG8) + /// + CB3_CN9Pin11, + + /// + /// Connector CN9, Pin 12 (PG9) + /// + CB3_CN9Pin12, + + /// + /// Connector CN9, Pin 13 (PG10) + /// + CB3_CN9Pin13, + + /// + /// Connector CN9, Pin 14 (PG11) + /// + CB3_CN9Pin14 + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 3a2603a..fc08811 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -52,14 +52,13 @@ public GpioConnectionDriverCapabilities GetCapabilities() /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - var gpioId = string.Format("gpio{0}", (int)pin); - if (Directory.Exists(Path.Combine(gpioPath, gpioId))) + if (Directory.Exists(GuessGpioPath(pin))) Release(pin); using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, "export"), false)) streamWriter.Write((int)pin); - var filePath = Path.Combine(gpioPath, gpioId, "direction"); + var filePath = Path.Combine(GuessGpioPath(pin), "direction"); try { SetPinDirection(filePath, direction); } catch (UnauthorizedAccessException) { @@ -130,8 +129,7 @@ public void Release(ProcessorPin pin) /// The pin status. public void Write(ProcessorPin pin, bool value) { - var gpioId = string.Format("gpio{0}", (int) pin); - var filePath = Path.Combine(gpioId, "value"); + var filePath = Path.Combine(GuessGpioPath(pin), "value"); using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) streamWriter.Write(value ? "1" : "0"); } @@ -145,8 +143,7 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { - var gpioId = string.Format("gpio{0}", (int) pin); - var filePath = Path.Combine(gpioId, "value"); + var filePath = Path.Combine(GuessGpioPath(pin), "value"); using (var streamReader = new StreamReader(new FileStream(Path.Combine(gpioPath, filePath), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { @@ -183,6 +180,27 @@ private static void SetPinDirection(string fullFilePath, PinDirection direction) } } + private static string GuessGpioPath(ProcessorPin pin) + { + string gpioId = string.Format("gpio{0}", (int)pin); + // by default use Raspberry Pi pin path format + string pinPath = Path.Combine(gpioPath, gpioId); + if (!Directory.Exists(pinPath)) + { + // check for sunxi gpio path name format (eg. "gpio11_pe10", "gpio2_pi21", ...) + string[] dirs = Directory.GetDirectories(gpioPath); + foreach(string d in dirs) + { + if (d.StartsWith(Path.Combine(pinPath, gpioId) + "_")) + { + pinPath = d; + break; + } + } + } + return pinPath; + } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index 46fceca..fb1a350 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -94,10 +94,10 @@ public void Allocate(ProcessorPin pin, PinDirection direction) using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) streamWriter.Write(direction == PinDirection.Input ? "in" : "out"); - if (direction == PinDirection.Input) + if (direction == PinDirection.Input) { - SetPinResistor(pin, PinResistor.None); - SetPinDetectedEdges(pin, PinDetectedEdges.Both); + SetPinResistor(pin, PinResistor.None); + SetPinDetectedEdges(pin, PinDetectedEdges.Both); InitializePoll(pin); } } diff --git a/Raspberry.IO.GeneralPurpose/PinMapping.cs b/Raspberry.IO.GeneralPurpose/PinMapping.cs index 5a767b8..8787098 100644 --- a/Raspberry.IO.GeneralPurpose/PinMapping.cs +++ b/Raspberry.IO.GeneralPurpose/PinMapping.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Diagnostics; #endregion @@ -27,87 +28,146 @@ static PinMapping() { var mapping = /* Value is not used but required for anonymous type */ new[]{ new { Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin03 }}; - if (GpioConnectionSettings.BoardConnectorRevision == 1) - mapping = new[] - { - new {Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin3}, - new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.P1Pin5}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, - new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin13}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22} - }; - - else if (GpioConnectionSettings.BoardConnectorRevision == 2) - mapping = new[] - { - new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, - new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, - new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, - new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.P5Pin3}, - new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.P5Pin4}, - new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.P5Pin5}, - new {Processor = ProcessorPin.Pin31, Connector = ConnectorPin.P5Pin6} - }; - - else //if (GpioConnectionSettings.BoardConnectorRevision == 3) - mapping = new[] - { - new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, - new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, - new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.P1Pin29}, - new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.P1Pin31}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, - new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.P1Pin32}, - new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.P1Pin33}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, - new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.P1Pin36}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, - new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.P1Pin35}, - new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.P1Pin38}, - new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin40}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, - new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.P1Pin37}, - new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, + var uname = GetUname(); + if (uname.ToLower().Contains("cubieboard")) + { + mapping = new[] { + new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.CB3_CN8Pin5}, + new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.CB3_CN8Pin6}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.CB3_CN8Pin7}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.CB3_CN8Pin8}, + new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.CB3_CN8Pin9}, + new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.CB3_CN8Pin10}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.CB3_CN8Pin11}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.CB3_CN8Pin12}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.CB3_CN8Pin15}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.CB3_CN8Pin16}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.CB3_CN8Pin17}, + new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.CB3_CN8Pin18}, + new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.CB3_CN8Pin19}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.CB3_CN8Pin20}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.CB3_CN8Pin21}, + new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.CB3_CN8Pin22}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.CB3_CN8Pin23}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.CB3_CN8Pin25}, + // + new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.CB3_CN9Pin3}, + new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.CB3_CN9Pin4}, + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.CB3_CN9Pin5}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.CB3_CN9Pin6}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.CB3_CN9Pin7}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.CB3_CN9Pin8}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.CB3_CN9Pin9}, + new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.CB3_CN9Pin10}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.CB3_CN9Pin11}, + new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.CB3_CN9Pin12}, + new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.CB3_CN9Pin13}, + new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.CB3_CN9Pin14} }; + } + else + { + if (GpioConnectionSettings.BoardConnectorRevision == 1) + mapping = new[] { + new {Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin13}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22} + }; + else if (GpioConnectionSettings.BoardConnectorRevision == 2) + mapping = new[] { + new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, + new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.P5Pin3}, + new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.P5Pin4}, + new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.P5Pin5}, + new {Processor = ProcessorPin.Pin31, Connector = ConnectorPin.P5Pin6} + }; + else //if (GpioConnectionSettings.BoardConnectorRevision == 3) + mapping = new[] { + new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.P1Pin3}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.P1Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.P1Pin7}, + new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.P1Pin29}, + new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.P1Pin31}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.P1Pin26}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.P1Pin24}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.P1Pin21}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.P1Pin19}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.P1Pin23}, + new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.P1Pin32}, + new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.P1Pin33}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.P1Pin8}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.P1Pin10}, + new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.P1Pin36}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.P1Pin11}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.P1Pin12}, + new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.P1Pin35}, + new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.P1Pin38}, + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.P1Pin40}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.P1Pin15}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.P1Pin16}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.P1Pin18}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.P1Pin22}, + new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.P1Pin37}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.P1Pin13} + }; + } processorMappings = mapping.ToDictionary(p => p.Connector, p => p.Processor); connectorMappings = mapping.ToDictionary(p => p.Processor, p => p.Connector); + + } + + static string GetUname() + { + string output = ""; + // Start the child process. + using (var p = new Process()) + { + // Redirect the output stream of the child process. + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.FileName = "uname"; + p.StartInfo.Arguments = "-a"; + p.Start(); + // Do not wait for the child process to exit before + // reading to the end of its redirected stream. + // p.WaitForExit(); + // Read the output stream first and then wait. + output = p.StandardOutput.ReadToEnd(); + p.WaitForExit(); + } + //Console.WriteLine("[DEBUG] 'uname -a' => " + output); + return output; } #endregion diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index b6dcffa..acba72a 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -175,7 +175,14 @@ Global $2.EventRemoveBraceStyle = NextLine $2.StatementBraceStyle = NextLine $2.ElseIfNewLinePlacement = SameLine + $2.BeforeMethodDeclarationParentheses = False + $2.BeforeMethodCallParentheses = False + $2.BeforeConstructorDeclarationParentheses = False + $2.BeforeIndexerDeclarationBracket = False + $2.BeforeDelegateDeclarationParentheses = False $2.AfterDelegateDeclarationParameterComma = True + $2.NewParentheses = False + $2.SpacesBeforeBrackets = False $2.inheritsSet = Mono $2.inheritsScope = text/x-csharp $2.scope = text/x-csharp diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index 4fa5e4b..f84ffe8 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -14,6 +14,8 @@ ..\..\ true + 12.0.0 + 2.0 true @@ -56,23 +58,23 @@ - {8388cfca-e3db-43f7-b049-2cb195211ce8} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Raspberry.IO.Components - {689cb6c4-3d23-45da-8e00-87c28aea32d0} + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} Raspberry.IO.Interop - {326342e5-0411-40e8-9f2d-563d6b192568} + {326342E5-0411-40E8-9F2D-563D6B192568} Raspberry.IO.SerialPeripheralInterface - {ace64f17-87e5-43e7-97a0-bdde19059c61} + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} Raspberry.IO - {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} Tests.Raspberry.IO diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index d114492..6f4689f 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -14,6 +14,8 @@ ..\..\ true + 12.0.0 + 2.0 true @@ -56,15 +58,15 @@ - {689cb6c4-3d23-45da-8e00-87c28aea32d0} + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} Raspberry.IO.Interop - {ace64f17-87e5-43e7-97a0-bdde19059c61} + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} Raspberry.IO - {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} Tests.Raspberry.IO diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index 42f0702..38c40dc 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -14,6 +14,8 @@ ..\..\ true + 12.0.0 + 2.0 true @@ -35,17 +37,9 @@ false - - False - ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll - ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll - - False - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll - @@ -53,6 +47,12 @@ + + ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + @@ -62,15 +62,15 @@ - {689cb6c4-3d23-45da-8e00-87c28aea32d0} + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} Raspberry.IO.Interop - {326342e5-0411-40e8-9f2d-563d6b192568} + {326342E5-0411-40E8-9F2D-563D6B192568} Raspberry.IO.SerialPeripheralInterface - {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} Tests.Raspberry.IO diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index 510b7b0..f2bd35d 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -14,6 +14,8 @@ ..\..\ true + 12.0.0 + 2.0 true From 99d0797fcfb63db4de5a022300875d3fdd8820e2 Mon Sep 17 00:00:00 2001 From: Gene Date: Sat, 17 Jan 2015 07:26:08 +0100 Subject: [PATCH 171/227] Fixed bug in GPIO mapping for CubieTruck/CubieBoard3 --- .../FileGpioConnectionDriver.cs | 2 +- Raspberry.IO.GeneralPurpose/PinMapping.cs | 62 +++++++++---------- Raspberry.IO.GeneralPurpose/ProcessorPin.cs | 7 ++- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index fc08811..e2258f1 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -191,7 +191,7 @@ private static string GuessGpioPath(ProcessorPin pin) string[] dirs = Directory.GetDirectories(gpioPath); foreach(string d in dirs) { - if (d.StartsWith(Path.Combine(pinPath, gpioId) + "_")) + if (d.StartsWith(pinPath + "_")) { pinPath = d; break; diff --git a/Raspberry.IO.GeneralPurpose/PinMapping.cs b/Raspberry.IO.GeneralPurpose/PinMapping.cs index 8787098..da970a1 100644 --- a/Raspberry.IO.GeneralPurpose/PinMapping.cs +++ b/Raspberry.IO.GeneralPurpose/PinMapping.cs @@ -29,40 +29,40 @@ static PinMapping() var mapping = /* Value is not used but required for anonymous type */ new[]{ new { Processor = ProcessorPin.Pin0, Connector = ConnectorPin.P1Pin03 }}; var uname = GetUname(); - if (uname.ToLower().Contains("cubieboard")) + if (uname.ToLower().Contains("cubie")) { mapping = new[] { - new {Processor = ProcessorPin.Pin1, Connector = ConnectorPin.CB3_CN8Pin5}, - new {Processor = ProcessorPin.Pin2, Connector = ConnectorPin.CB3_CN8Pin6}, - new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.CB3_CN8Pin7}, - new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.CB3_CN8Pin8}, - new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.CB3_CN8Pin9}, - new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.CB3_CN8Pin10}, - new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.CB3_CN8Pin11}, - new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.CB3_CN8Pin12}, - new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.CB3_CN8Pin15}, - new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.CB3_CN8Pin16}, - new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.CB3_CN8Pin17}, - new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.CB3_CN8Pin18}, - new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.CB3_CN8Pin19}, - new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.CB3_CN8Pin20}, - new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.CB3_CN8Pin21}, - new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.CB3_CN8Pin22}, - new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.CB3_CN8Pin23}, - new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.CB3_CN8Pin25}, + new {Processor = ProcessorPin.Pin3, Connector = ConnectorPin.CB3_CN8Pin5}, + new {Processor = ProcessorPin.Pin4, Connector = ConnectorPin.CB3_CN8Pin6}, + new {Processor = ProcessorPin.Pin5, Connector = ConnectorPin.CB3_CN8Pin7}, + new {Processor = ProcessorPin.Pin6, Connector = ConnectorPin.CB3_CN8Pin8}, + new {Processor = ProcessorPin.Pin7, Connector = ConnectorPin.CB3_CN8Pin9}, + new {Processor = ProcessorPin.Pin8, Connector = ConnectorPin.CB3_CN8Pin10}, + new {Processor = ProcessorPin.Pin9, Connector = ConnectorPin.CB3_CN8Pin11}, + new {Processor = ProcessorPin.Pin10, Connector = ConnectorPin.CB3_CN8Pin12}, + new {Processor = ProcessorPin.Pin11, Connector = ConnectorPin.CB3_CN8Pin15}, + new {Processor = ProcessorPin.Pin12, Connector = ConnectorPin.CB3_CN8Pin16}, + new {Processor = ProcessorPin.Pin13, Connector = ConnectorPin.CB3_CN8Pin17}, + new {Processor = ProcessorPin.Pin14, Connector = ConnectorPin.CB3_CN8Pin18}, + new {Processor = ProcessorPin.Pin15, Connector = ConnectorPin.CB3_CN8Pin19}, + new {Processor = ProcessorPin.Pin16, Connector = ConnectorPin.CB3_CN8Pin20}, + new {Processor = ProcessorPin.Pin17, Connector = ConnectorPin.CB3_CN8Pin21}, + new {Processor = ProcessorPin.Pin18, Connector = ConnectorPin.CB3_CN8Pin22}, + new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.CB3_CN8Pin23}, + new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.CB3_CN8Pin25}, // - new {Processor = ProcessorPin.Pin19, Connector = ConnectorPin.CB3_CN9Pin3}, - new {Processor = ProcessorPin.Pin20, Connector = ConnectorPin.CB3_CN9Pin4}, - new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.CB3_CN9Pin5}, - new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.CB3_CN9Pin6}, - new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.CB3_CN9Pin7}, - new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.CB3_CN9Pin8}, - new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.CB3_CN9Pin9}, - new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.CB3_CN9Pin10}, - new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.CB3_CN9Pin11}, - new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.CB3_CN9Pin12}, - new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.CB3_CN9Pin13}, - new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.CB3_CN9Pin14} + new {Processor = ProcessorPin.Pin21, Connector = ConnectorPin.CB3_CN9Pin3}, + new {Processor = ProcessorPin.Pin22, Connector = ConnectorPin.CB3_CN9Pin4}, + new {Processor = ProcessorPin.Pin23, Connector = ConnectorPin.CB3_CN9Pin5}, + new {Processor = ProcessorPin.Pin24, Connector = ConnectorPin.CB3_CN9Pin6}, + new {Processor = ProcessorPin.Pin25, Connector = ConnectorPin.CB3_CN9Pin7}, + new {Processor = ProcessorPin.Pin26, Connector = ConnectorPin.CB3_CN9Pin8}, + new {Processor = ProcessorPin.Pin27, Connector = ConnectorPin.CB3_CN9Pin9}, + new {Processor = ProcessorPin.Pin28, Connector = ConnectorPin.CB3_CN9Pin10}, + new {Processor = ProcessorPin.Pin29, Connector = ConnectorPin.CB3_CN9Pin11}, + new {Processor = ProcessorPin.Pin30, Connector = ConnectorPin.CB3_CN9Pin12}, + new {Processor = ProcessorPin.Pin31, Connector = ConnectorPin.CB3_CN9Pin13}, + new {Processor = ProcessorPin.Pin32, Connector = ConnectorPin.CB3_CN9Pin14} }; } else diff --git a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs index 626e709..b57c691 100644 --- a/Raspberry.IO.GeneralPurpose/ProcessorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ProcessorPin.cs @@ -213,6 +213,11 @@ public enum ProcessorPin /// /// Pin 31. /// - Pin31 = 31 + Pin31 = 31, + + /// + /// Pin 32. (added for CubieTruck/CubieBoard3 compatibility + /// + Pin32 = 32 } } \ No newline at end of file From 3adf8e7bef635b443d8fda4e0996faeae6cb5be2 Mon Sep 17 00:00:00 2001 From: Gene Date: Sun, 18 Jan 2015 22:45:05 +0100 Subject: [PATCH 172/227] Optimized FileGpioConnectionDriver, now faaaster I/O with persistent R/W FileStream --- .../FileGpioConnectionDriver.cs | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index e2258f1..ffbf195 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -5,11 +5,18 @@ using System.Linq; using System.Security; using System.Threading; +using System.Collections.Generic; #endregion namespace Raspberry.IO.GeneralPurpose { + public class FileGpioHandle + { + public string GpioPath { get; set; } + public Stream GpioStream { get; set; } + } + /// /// Represents a connection driver using files. /// @@ -18,6 +25,7 @@ public class FileGpioConnectionDriver : IGpioConnectionDriver #region Fields private const string gpioPath = "/sys/class/gpio"; + private static Dictionary gpioPathList = new Dictionary(); #endregion @@ -28,12 +36,12 @@ public class FileGpioConnectionDriver : IGpioConnectionDriver /// public FileGpioConnectionDriver() { - if (System.Environment.OSVersion.Platform != PlatformID.Unix) + if (System.Environment.OSVersion.Platform != PlatformID.Unix) throw new NotSupportedException("FileGpioConnectionDriver is only supported in Unix"); } #endregion - + #region Methods /// @@ -52,13 +60,18 @@ public GpioConnectionDriverCapabilities GetCapabilities() /// The direction. public void Allocate(ProcessorPin pin, PinDirection direction) { - if (Directory.Exists(GuessGpioPath(pin))) - Release(pin); + Release(pin); using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, "export"), false)) streamWriter.Write((int)pin); - var filePath = Path.Combine(GuessGpioPath(pin), "direction"); + if (!gpioPathList.ContainsKey(pin)) + { + FileGpioHandle gpio = new FileGpioHandle() { GpioPath = GuessGpioPath(pin) }; + gpioPathList.Add(pin, gpio); + } + + var filePath = Path.Combine(gpioPathList[pin].GpioPath, "direction"); try { SetPinDirection(filePath, direction); } catch (UnauthorizedAccessException) { @@ -66,8 +79,10 @@ public void Allocate(ProcessorPin pin, PinDirection direction) Thread.Sleep(TimeSpan.FromSeconds(1)); SetPinDirection(filePath, direction); } + + gpioPathList[pin].GpioStream = new FileStream(Path.Combine(GuessGpioPath(pin), "value"), FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); } - + /// /// Sets the pin resistor. /// @@ -118,8 +133,14 @@ public void Wait(ProcessorPin pin, bool waitForUp = true, decimal timeout = 0) /// The pin. public void Release(ProcessorPin pin) { - using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, "unexport"), false)) - streamWriter.Write((int)pin); + if (gpioPathList.ContainsKey(pin) && gpioPathList[pin].GpioStream != null) + { + gpioPathList[pin].GpioStream.Close(); + gpioPathList[pin].GpioStream = null; + } + if (Directory.Exists(GuessGpioPath(pin))) + using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, "unexport"), false)) + streamWriter.Write((int)pin); } /// @@ -129,9 +150,9 @@ public void Release(ProcessorPin pin) /// The pin status. public void Write(ProcessorPin pin, bool value) { - var filePath = Path.Combine(GuessGpioPath(pin), "value"); - using (var streamWriter = new StreamWriter(Path.Combine(gpioPath, filePath), false)) - streamWriter.Write(value ? "1" : "0"); + gpioPathList[pin].GpioStream.Seek(0, SeekOrigin.Begin); + gpioPathList[pin].GpioStream.WriteByte(value ? (byte)'1' : (byte)'0'); + gpioPathList[pin].GpioStream.Flush(); } /// @@ -143,13 +164,10 @@ public void Write(ProcessorPin pin, bool value) /// public bool Read(ProcessorPin pin) { - var filePath = Path.Combine(GuessGpioPath(pin), "value"); - - using (var streamReader = new StreamReader(new FileStream(Path.Combine(gpioPath, filePath), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) - { - var rawValue = streamReader.ReadToEnd(); - return !string.IsNullOrEmpty(rawValue) && rawValue[0] == '1'; - } + gpioPathList[pin].GpioStream.Seek(0, SeekOrigin.Begin); + var rawValue = (char)gpioPathList[pin].GpioStream.ReadByte(); + gpioPathList[pin].GpioStream.Flush(); + return rawValue == '1'; } /// @@ -163,9 +181,9 @@ public ProcessorPins Read(ProcessorPins pins) { return pins.Enumerate() .Select(p => Read(p) ? (ProcessorPins) ((uint) 1 << (int) p) : ProcessorPins.None) - .Aggregate( - ProcessorPins.None, - (a, p) => a | p); + .Aggregate( + ProcessorPins.None, + (a, p) => a | p); } #endregion @@ -175,21 +193,22 @@ public ProcessorPins Read(ProcessorPins pins) private static void SetPinDirection(string fullFilePath, PinDirection direction) { using (var streamWriter = new StreamWriter(fullFilePath, false)) { streamWriter.Write(direction == PinDirection.Input - ? "in" - : "out"); + ? "in" + : "out"); } } private static string GuessGpioPath(ProcessorPin pin) { - string gpioId = string.Format("gpio{0}", (int)pin); // by default use Raspberry Pi pin path format + string gpioId = string.Format("gpio{0}", (int)pin); string pinPath = Path.Combine(gpioPath, gpioId); + // verify/lookup pin path if (!Directory.Exists(pinPath)) { // check for sunxi gpio path name format (eg. "gpio11_pe10", "gpio2_pi21", ...) string[] dirs = Directory.GetDirectories(gpioPath); - foreach(string d in dirs) + foreach (string d in dirs) { if (d.StartsWith(pinPath + "_")) { From 8b4f8efb8c5407c6ffba7440f56d086eae1ecd2c Mon Sep 17 00:00:00 2001 From: "John M. Wright" Date: Thu, 5 Feb 2015 20:16:36 -0600 Subject: [PATCH 173/227] adding support for DS18B20 1-wire temperature sensor based on logic from https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing --- .../Raspberry.IO.Components.csproj | 1 + .../Temperature/Ds18b20/Ds18b20Connection.cs | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 2fc8d05..4f127d0 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -102,6 +102,7 @@ + diff --git a/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs b/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs new file mode 100644 index 0000000..8713111 --- /dev/null +++ b/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs @@ -0,0 +1,135 @@ +#region References + +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; + +#endregion + +namespace Raspberry.IO.Components.Sensors.Temperature.Ds18b20 +{ + /// + /// Represents a connection to a DS18B20 temperature sensor. + /// + /// See . + public class Ds18b20Connection : IDisposable + { + #region Fields + + private readonly string _deviceFolder; + private string DeviceFile { get {return _deviceFolder + @"/w1_slave";} } + private const string BaseDir = @"/sys/bus/w1/devices/"; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + public Ds18b20Connection(string deviceId) + { + _deviceFolder = BaseDir + deviceId; + if (!Directory.Exists(_deviceFolder)) + { + throw new ArgumentException(string.Format("Sensor with Id {0} not found. {1}", deviceId, ModprobeExceptionMessage), deviceId); + } + + } + + private string ModprobeExceptionMessage + { + get + { + var sb = new StringBuilder(); + sb.AppendLine("Make sure you have loaded the required kernel models."); + sb.AppendFormat("\tmodprobe w1-gpio{0}", Environment.NewLine); + sb.AppendFormat("\tmodprobe w1-therm{0}", Environment.NewLine); + return sb.ToString(); + } + } + + + /// + /// Initializes a new instance of the class. + /// + public Ds18b20Connection(int deviceIndex) + { + var deviceFolders = Directory.GetDirectories(BaseDir, "28*").ToList(); + var deviceCount = deviceFolders.Count(); + if (deviceCount == 0) + { + throw new InvalidOperationException(string.Format("No sensors were found in {0}. {1}", BaseDir, ModprobeExceptionMessage)); + } + + if (deviceCount <= deviceIndex) + { + throw new IndexOutOfRangeException(string.Format("There were only {0} devices found, so index {1} is invalid", deviceCount, deviceIndex )); + } + + _deviceFolder = deviceFolders[deviceIndex]; + + } + + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + /// + /// Gets the temperature, in Celsius. + /// + /// The temperature, in Celsius. + public double GetTemperatureCelsius() + { + var lines = File.ReadAllLines(DeviceFile); + while (!lines[0].Trim().EndsWith("YES")) + { + Thread.Sleep(2); + lines = File.ReadAllLines(DeviceFile); + } + + var equalsPos = lines[1].IndexOf("t="); + if (equalsPos == -1) + { + throw new Exception("invalid temp reading"); + } + + var temperatureString = lines[1].Substring(equalsPos + 2); + var tempC = Double.Parse(temperatureString) / 1000.0; + return tempC; + + } + + /// + /// Gets the temperature, in Fahrenheit. + /// + /// The temperature, in Fahrenheit. + public double GetTemperatureFahrenheit() + { + var tempC = GetTemperatureCelsius(); + var tempF = tempC * 9.0 / 5.0 + 32.0; + return tempF; + } + + + /// + /// Closes this instance. + /// + public void Close() + { + } + + #endregion + } +} From 89b796a774658db89df2f598442f25ba38c99a90 Mon Sep 17 00:00:00 2001 From: Gene Date: Sat, 21 Feb 2015 14:52:47 +0100 Subject: [PATCH 174/227] trying to add support for Raspberry Pi 2 --- Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs | 2 +- Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs | 2 +- Raspberry.IO.GeneralPurpose/Interop.cs | 5 +++++ Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index fb1a350..432c644 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -40,7 +40,7 @@ public GpioConnectionDriver() { MemoryProtection.ReadWrite, MemoryFlags.Shared, memoryFile.Descriptor, - Interop.BCM2835_GPIO_BASE + Board.Current.Model == '2' ? Interop.BCM2836_GPIO_BASE : Interop.BCM2835_GPIO_BASE ); } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs index 30a0fb3..af455f3 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionSettings.cs @@ -124,7 +124,7 @@ public static int BoardConnectorRevision if (board.Model == 'B' && board.Revision == 1) return 1; - if (board.Model == 'B' && board.Revision == 3) + if ((board.Model == 'B' && board.Revision == 3) || board.Model == '2') return 3; return 2; diff --git a/Raspberry.IO.GeneralPurpose/Interop.cs b/Raspberry.IO.GeneralPurpose/Interop.cs index 8417ea0..6abed9b 100644 --- a/Raspberry.IO.GeneralPurpose/Interop.cs +++ b/Raspberry.IO.GeneralPurpose/Interop.cs @@ -17,6 +17,11 @@ internal static class Interop public const uint BCM2835_GPIO_BASE = (BCM2835_PERI_BASE + 0x200000); public const uint BCM2835_BSC0_BASE = (BCM2835_PERI_BASE + 0x205000); public const uint BCM2835_BSC1_BASE = (BCM2835_PERI_BASE + 0x804000); + + public const uint BCM2836_PERI_BASE = 0x3F000000; + public const uint BCM2836_GPIO_BASE = (BCM2836_PERI_BASE + 0x200000); + public const uint BCM2836_BSC0_BASE = (BCM2836_PERI_BASE + 0x205000); + public const uint BCM2836_BSC1_BASE = (BCM2836_PERI_BASE + 0x804000); public const uint BCM2835_BLOCK_SIZE = (4 * 1024); diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 4dff5b8..1a7c91a 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -35,7 +35,7 @@ public MemoryGpioConnectionDriver() { MemoryProtection.ReadWrite, MemoryFlags.Shared, memoryFile.Descriptor, - Interop.BCM2835_GPIO_BASE); + Board.Current.Model == '2' ? Interop.BCM2836_GPIO_BASE : Interop.BCM2835_GPIO_BASE); } } From 1d5dce1dadd3f1bb3e5539909669a7495c816ad3 Mon Sep 17 00:00:00 2001 From: Gene Date: Sun, 22 Feb 2015 16:25:29 +0100 Subject: [PATCH 175/227] fixed wrong i2c base address being used for rpi2 --- Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs | 8 ++++---- Raspberry.IO.InterIntegratedCircuit/Interop.cs | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs index 0d58abd..7c45935 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs @@ -47,7 +47,7 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin) var memoryFile = Interop.open("/dev/mem", Interop.O_RDWR + Interop.O_SYNC); try { - gpioAddress = Interop.mmap(IntPtr.Zero, Interop.BCM2835_BLOCK_SIZE, Interop.PROT_READ | Interop.PROT_WRITE, Interop.MAP_SHARED, memoryFile, Interop.BCM2835_GPIO_BASE); + gpioAddress = Interop.mmap(IntPtr.Zero, Interop.BCM2835_BLOCK_SIZE, Interop.PROT_READ | Interop.PROT_WRITE, Interop.MAP_SHARED, memoryFile, Board.Current.Model == '2' ? Interop.BCM2836_GPIO_BASE : Interop.BCM2835_GPIO_BASE); bscAddress = Interop.mmap(IntPtr.Zero, Interop.BCM2835_BLOCK_SIZE, Interop.PROT_READ | Interop.PROT_WRITE, Interop.MAP_SHARED, memoryFile, bscBase); } finally @@ -286,14 +286,14 @@ private static uint GetBscBase(ProcessorPin sdaPin, ProcessorPin sclPin) { case 1: if (sdaPin == ProcessorPin.Pin0 && sclPin == ProcessorPin.Pin1) - return Interop.BCM2835_BSC0_BASE; + return Board.Current.Model == '2' ? Interop.BCM2836_BSC0_BASE : Interop.BCM2835_BSC0_BASE; throw new InvalidOperationException("No I2C device exist on the specified pins"); case 2: if (sdaPin == ProcessorPin.Pin28 && sclPin == ProcessorPin.Pin29) - return Interop.BCM2835_BSC0_BASE; + return Board.Current.Model == '2' ? Interop.BCM2836_BSC0_BASE : Interop.BCM2835_BSC0_BASE; if (sdaPin == ProcessorPin.Pin2 && sclPin == ProcessorPin.Pin3) - return Interop.BCM2835_BSC1_BASE; + return Board.Current.Model == '2' ? Interop.BCM2836_BSC1_BASE : Interop.BCM2835_BSC1_BASE; throw new InvalidOperationException("No I2C device exist on the specified pins"); case 3: diff --git a/Raspberry.IO.InterIntegratedCircuit/Interop.cs b/Raspberry.IO.InterIntegratedCircuit/Interop.cs index 9208a47..29268bc 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Interop.cs +++ b/Raspberry.IO.InterIntegratedCircuit/Interop.cs @@ -17,6 +17,11 @@ internal static class Interop public const uint BCM2835_GPIO_BASE = (BCM2835_PERI_BASE + 0x200000); public const uint BCM2835_BSC0_BASE = (BCM2835_PERI_BASE + 0x205000); public const uint BCM2835_BSC1_BASE = (BCM2835_PERI_BASE + 0x804000); + + public const uint BCM2836_PERI_BASE = 0x3F000000; + public const uint BCM2836_GPIO_BASE = (BCM2836_PERI_BASE + 0x200000); + public const uint BCM2836_BSC0_BASE = (BCM2836_PERI_BASE + 0x205000); + public const uint BCM2836_BSC1_BASE = (BCM2836_PERI_BASE + 0x804000); public const uint BCM2835_BLOCK_SIZE = (4*1024); From 5f0c86d4aa2edcdca850cc980995fa2b39ef1a77 Mon Sep 17 00:00:00 2001 From: Gene Date: Tue, 24 Feb 2015 22:45:57 +0100 Subject: [PATCH 176/227] fixed I2C driver, now working on Raspberry Pi 2 as well --- Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs index 7c45935..7bc01ec 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs @@ -286,19 +286,19 @@ private static uint GetBscBase(ProcessorPin sdaPin, ProcessorPin sclPin) { case 1: if (sdaPin == ProcessorPin.Pin0 && sclPin == ProcessorPin.Pin1) - return Board.Current.Model == '2' ? Interop.BCM2836_BSC0_BASE : Interop.BCM2835_BSC0_BASE; + return Interop.BCM2835_BSC0_BASE; throw new InvalidOperationException("No I2C device exist on the specified pins"); case 2: if (sdaPin == ProcessorPin.Pin28 && sclPin == ProcessorPin.Pin29) - return Board.Current.Model == '2' ? Interop.BCM2836_BSC0_BASE : Interop.BCM2835_BSC0_BASE; + return Interop.BCM2835_BSC0_BASE; if (sdaPin == ProcessorPin.Pin2 && sclPin == ProcessorPin.Pin3) - return Board.Current.Model == '2' ? Interop.BCM2836_BSC1_BASE : Interop.BCM2835_BSC1_BASE; + return Interop.BCM2835_BSC1_BASE; throw new InvalidOperationException("No I2C device exist on the specified pins"); case 3: if (sdaPin == ProcessorPin.Pin2 && sclPin == ProcessorPin.Pin3) - return Interop.BCM2835_BSC1_BASE; + return Board.Current.Model == '2' ? Interop.BCM2836_BSC1_BASE : Interop.BCM2835_BSC1_BASE; throw new InvalidOperationException("No I2C device exist on the specified pins"); default: From 4acf29b53b46914599565f98d2f2fba67a2cd25b Mon Sep 17 00:00:00 2001 From: Generoso Martello Date: Tue, 24 Feb 2015 23:20:54 +0100 Subject: [PATCH 177/227] synched with upstream/master From 2a6a7d411e67e15646ee19a5e3ad0878881232f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 25 Feb 2015 20:19:21 +0100 Subject: [PATCH 178/227] Updated nugets --- .../Displays/Ssd1306/Command.cs | 25 ----------- .../Displays/Ssd1306/ScrollDirection.cs | 13 ++++++ .../Displays/Ssd1306/ScrollSpeed.cs | 17 +++++++ .../Raspberry.IO.Components.csproj | 29 ++++++------ Raspberry.IO.Components/packages.config | 6 +-- Raspberry.IO.GeneralPurpose/ConnectorPin.cs | 2 +- .../GpioConnectionDriverCapabilities.cs | 26 +++++++++++ .../IGpioConnectionDriver.cs | 10 ----- .../Raspberry.IO.GeneralPurpose.csproj | 8 ++-- Raspberry.IO.GeneralPurpose/packages.config | 2 +- ...Raspberry.IO.InterIntegratedCircuit.csproj | 7 +-- .../packages.config | 2 +- Raspberry.IO.Interop/ControlDevice.cs | 4 ++ ...pberry.IO.SerialPeripheralInterface.csproj | 7 +-- .../packages.config | 2 +- SharedAssemblyInfo.cs | 8 ++-- .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 7 +-- Tests/Test.Gpio.HCSR04/packages.config | 2 +- .../Test.Gpio.Pca9685.csproj | 9 ++-- Tests/Test.Gpio.Pca9685/app.config | 6 ++- Tests/Test.Gpio.Pca9685/packages.config | 4 +- Tests/Test.Spi.TLC59711/App.config | 17 +++++-- .../Tests.Raspberry.IO.Components.csproj | 11 +++-- .../packages.config | 6 +-- .../Tests.Raspberry.IO.Interop.csproj | 15 +++++-- .../packages.config | 6 +-- ...pberry.IO.SerialPeripheralInterface.csproj | 22 ++++++---- .../packages.config | 6 +-- .../Tests.Raspberry.IO.csproj | 14 +++--- UnitTests/Tests.Raspberry.IO/packages.config | 6 +-- packages/repositories.config | 44 +++++++++---------- 31 files changed, 203 insertions(+), 140 deletions(-) create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/ScrollDirection.cs create mode 100644 Raspberry.IO.Components/Displays/Ssd1306/ScrollSpeed.cs create mode 100644 Raspberry.IO.GeneralPurpose/GpioConnectionDriverCapabilities.cs diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Command.cs b/Raspberry.IO.Components/Displays/Ssd1306/Command.cs index 59ef677..b344d3d 100644 --- a/Raspberry.IO.Components/Displays/Ssd1306/Command.cs +++ b/Raspberry.IO.Components/Displays/Ssd1306/Command.cs @@ -1,5 +1,3 @@ -using System; - namespace Raspberry.IO.Components.Displays.Ssd1306 { public class Command @@ -38,28 +36,5 @@ public class Command public const byte ExternalVcc = 0x1; public const byte SwitchCapVcc = 0x2; } - - [Flags] - public enum ScrollSpeed : byte - { - F2 = 0x7, - F3 = 0x4, - F4 = 0x5, - F5 = 0x0, - F25 = 0x6, - F64 = 0x1, - F128 = 0x2, - F256 = 0x3 - } - - [Flags] - public enum ScrollDirection : byte - { - HorizontalRight = 0x01, - HorizontalLeft = 0x02, - VerticalAndHorizontalRight = 0x04, - VerticalAndHorizontalLeft = 0x05 - } - } diff --git a/Raspberry.IO.Components/Displays/Ssd1306/ScrollDirection.cs b/Raspberry.IO.Components/Displays/Ssd1306/ScrollDirection.cs new file mode 100644 index 0000000..020db0e --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/ScrollDirection.cs @@ -0,0 +1,13 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306 +{ + [Flags] + public enum ScrollDirection : byte + { + HorizontalRight = 0x01, + HorizontalLeft = 0x02, + VerticalAndHorizontalRight = 0x04, + VerticalAndHorizontalLeft = 0x05 + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Displays/Ssd1306/ScrollSpeed.cs b/Raspberry.IO.Components/Displays/Ssd1306/ScrollSpeed.cs new file mode 100644 index 0000000..62310f8 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Ssd1306/ScrollSpeed.cs @@ -0,0 +1,17 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Ssd1306 +{ + [Flags] + public enum ScrollSpeed : byte + { + F2 = 0x7, + F3 = 0x4, + F4 = 0x5, + F5 = 0x0, + F25 = 0x6, + F64 = 0x1, + F128 = 0x2, + F256 = 0x3 + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index c0a0ba0..eed52df 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -33,17 +33,20 @@ 4 - - - - ..\packages\Common.Logging.2.2.0\lib\net40\Common.Logging.dll + + False + ..\packages\Common.Logging.3.0.0\lib\net40\Common.Logging.dll - - ..\packages\Common.Logging.Core.2.2.0\lib\net40\Common.Logging.Core.dll + + False + ..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll - - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll + + False + ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + + @@ -81,6 +84,8 @@ + + @@ -154,12 +159,6 @@ --> - - - - - - - + \ No newline at end of file diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index 7553870..b127615 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs index 22a53b8..01f3fc4 100644 --- a/Raspberry.IO.GeneralPurpose/ConnectorPin.cs +++ b/Raspberry.IO.GeneralPurpose/ConnectorPin.cs @@ -137,7 +137,7 @@ public enum ConnectorPin /// /// Connector P1, pin 32. - /// enum + /// P1Pin32, /// diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriverCapabilities.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriverCapabilities.cs new file mode 100644 index 0000000..6bf80b9 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriverCapabilities.cs @@ -0,0 +1,26 @@ +using System; + +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents capabilities of a driver. + /// + [Flags] + public enum GpioConnectionDriverCapabilities + { + /// + /// No advanced capability. + /// + None = 0, + + /// + /// The driver can set pin resistor + /// + CanSetPinResistor = 1, + + /// + /// The driver can set pin detected edges + /// + CanSetPinDetectedEdges = 2 + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs index 91b6d4f..edc5f07 100644 --- a/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/IGpioConnectionDriver.cs @@ -1,15 +1,5 @@ -using System; - namespace Raspberry.IO.GeneralPurpose { - [Flags] - public enum GpioConnectionDriverCapabilities - { - None = 0, - CanSetPinResistor = 1, - CanSetPinDetectedEdges = 2 - } - /// /// Provides an interface for connection drivers. /// diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 14ed1bb..00b44fb 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -35,12 +35,13 @@ bin\Release\Raspberry.IO.GeneralPurpose.XML + + False + ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + - - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - @@ -57,6 +58,7 @@ + diff --git a/Raspberry.IO.GeneralPurpose/packages.config b/Raspberry.IO.GeneralPurpose/packages.config index 052cd50..78864cb 100644 --- a/Raspberry.IO.GeneralPurpose/packages.config +++ b/Raspberry.IO.GeneralPurpose/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index 2ec8596..9bd89c9 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -35,11 +35,12 @@ bin\Release\Raspberry.IO.InterIntegratedCircuit.XML + + False + ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + - - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - diff --git a/Raspberry.IO.InterIntegratedCircuit/packages.config b/Raspberry.IO.InterIntegratedCircuit/packages.config index 052cd50..78864cb 100644 --- a/Raspberry.IO.InterIntegratedCircuit/packages.config +++ b/Raspberry.IO.InterIntegratedCircuit/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Raspberry.IO.Interop/ControlDevice.cs b/Raspberry.IO.Interop/ControlDevice.cs index 4f947e7..0bfe3bb 100644 --- a/Raspberry.IO.Interop/ControlDevice.cs +++ b/Raspberry.IO.Interop/ControlDevice.cs @@ -9,13 +9,17 @@ namespace Raspberry.IO.Interop public class ControlDevice : IControlDevice { #region Classes + private static class GenericIoControl { + #region Libc imports + [DllImport("libc", EntryPoint = "ioctl", SetLastError = true)] public static extern int ioctl(int descriptor, UInt32 request, ref T data); [DllImport("libc", EntryPoint = "ioctl", SetLastError = true)] public static extern int ioctl(int descriptor, UInt32 request, T data); + #endregion } #endregion diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index a64e73e..43f9f0c 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -35,11 +35,12 @@ bin\Release\Raspberry.IO.SerialPeripheralInterface.XML + + False + ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + - - ..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - diff --git a/Raspberry.IO.SerialPeripheralInterface/packages.config b/Raspberry.IO.SerialPeripheralInterface/packages.config index 052cd50..78864cb 100644 --- a/Raspberry.IO.SerialPeripheralInterface/packages.config +++ b/Raspberry.IO.SerialPeripheralInterface/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index dba3ed9..6221bbb 100644 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -4,9 +4,9 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyCompany("Raspberry-Sharp")] +[assembly: AssemblyCompany("Raspberry#")] [assembly: AssemblyProduct("Raspberry.IO")] -[assembly: AssemblyCopyright("www.raspberry-sharp.org, 2012-2013")] +[assembly: AssemblyCopyright("www.raspberry-sharp.org, 2012-2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -25,5 +25,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.1.0")] -[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 0b50a03..852b0db 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -58,11 +58,12 @@ 4 + + False + ..\..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + - - ..\..\packages\Raspberry.System.1.3.0\lib\net40\Raspberry.System.dll - diff --git a/Tests/Test.Gpio.HCSR04/packages.config b/Tests/Test.Gpio.HCSR04/packages.config index 052cd50..78864cb 100644 --- a/Tests/Test.Gpio.HCSR04/packages.config +++ b/Tests/Test.Gpio.HCSR04/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index e722fc3..5e11036 100644 --- a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -37,10 +37,11 @@ - ..\..\packages\Common.Logging.2.2.0\lib\net40\Common.Logging.dll + ..\..\packages\Common.Logging.3.0.0\lib\net40\Common.Logging.dll - - ..\..\packages\Common.Logging.Core.2.2.0\lib\net40\Common.Logging.Core.dll + + False + ..\..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll ..\..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll @@ -85,4 +86,4 @@ --> - + \ No newline at end of file diff --git a/Tests/Test.Gpio.Pca9685/app.config b/Tests/Test.Gpio.Pca9685/app.config index 2401161..09d5127 100644 --- a/Tests/Test.Gpio.Pca9685/app.config +++ b/Tests/Test.Gpio.Pca9685/app.config @@ -22,7 +22,11 @@ - + + + + + diff --git a/Tests/Test.Gpio.Pca9685/packages.config b/Tests/Test.Gpio.Pca9685/packages.config index a2f5d8c..5148318 100644 --- a/Tests/Test.Gpio.Pca9685/packages.config +++ b/Tests/Test.Gpio.Pca9685/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/Tests/Test.Spi.TLC59711/App.config b/Tests/Test.Spi.TLC59711/App.config index 74ade9d..88f04af 100644 --- a/Tests/Test.Spi.TLC59711/App.config +++ b/Tests/Test.Spi.TLC59711/App.config @@ -1,6 +1,15 @@ - + - - - + + + + + + + + + + + + diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index f84ffe8..2aaebdb 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -36,13 +36,16 @@ - ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll - ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + + + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll @@ -90,4 +93,4 @@ --> - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/packages.config b/UnitTests/Tests.Raspberry.IO.Components/packages.config index 277a3fb..1191330 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/packages.config +++ b/UnitTests/Tests.Raspberry.IO.Components/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index 6f4689f..eaaa384 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -36,13 +36,20 @@ - ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll + True - ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + True + + + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + True - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + True @@ -82,4 +89,4 @@ --> - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/packages.config b/UnitTests/Tests.Raspberry.IO.Interop/packages.config index 277a3fb..1191330 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/packages.config +++ b/UnitTests/Tests.Raspberry.IO.Interop/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index 38c40dc..020e944 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -37,8 +37,20 @@ false + + False + ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll + - ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + + + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + True + + + False + ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll @@ -47,12 +59,6 @@ - - ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll - - - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll - @@ -86,4 +92,4 @@ --> - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config index 277a3fb..1191330 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index f2bd35d..ddc9754 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -36,13 +36,17 @@ - ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll - ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll - - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + + + False + ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll @@ -69,4 +73,4 @@ --> - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/packages.config b/UnitTests/Tests.Raspberry.IO/packages.config index 277a3fb..1191330 100644 --- a/UnitTests/Tests.Raspberry.IO/packages.config +++ b/UnitTests/Tests.Raspberry.IO/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/packages/repositories.config b/packages/repositories.config index afaac42..a7cbf91 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ebf3133b9b2b924ecbc686311163ffb21e43503b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 25 Feb 2015 20:32:40 +0100 Subject: [PATCH 179/227] Updated .nuspec --- Raspberry.IO.GeneralPurpose.nuspec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index e564e48..4a7ae57 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -19,15 +19,16 @@ en-US Raspberry Pi Mono GPIO - - + + + From 5060b20fa147d794d820934500c98141220b6e32 Mon Sep 17 00:00:00 2001 From: Generoso Martello Date: Wed, 25 Feb 2015 20:36:36 +0100 Subject: [PATCH 180/227] synched with upstream From 1b5bdd61bf0f3d451dee919317f1d291be26f817 Mon Sep 17 00:00:00 2001 From: shibayan Date: Sun, 1 Mar 2015 00:32:24 +0900 Subject: [PATCH 181/227] add support for MCP3002 converter --- .../Mcp3002AnalogPinExtensionMethods.cs | 20 +++++ .../Converters/Mcp3002/Mcp3002Channel.cs | 8 ++ .../Mcp3002/Mcp3002InputAnalogPin.cs | 47 ++++++++++ .../Mcp3002/Mcp3002SpiConnection.cs | 85 +++++++++++++++++++ .../Raspberry.IO.Components.csproj | 4 + 5 files changed, 164 insertions(+) create mode 100644 Raspberry.IO.Components/Converters/Mcp3002/Mcp3002AnalogPinExtensionMethods.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3002/Mcp3002Channel.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3002/Mcp3002InputAnalogPin.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3002/Mcp3002SpiConnection.cs diff --git a/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002AnalogPinExtensionMethods.cs b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002AnalogPinExtensionMethods.cs new file mode 100644 index 0000000..a42fc51 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002AnalogPinExtensionMethods.cs @@ -0,0 +1,20 @@ +namespace Raspberry.IO.Components.Converters.Mcp3002 +{ + public static class Mcp3002AnalogPinExtensionMethods + { + #region Methods + + /// + /// Creates an analog input pin. + /// + /// The connection. + /// The channel. + /// The pin. + public static Mcp3002InputAnalogPin In(this Mcp3002SpiConnection connection, Mcp3002Channel channel) + { + return new Mcp3002InputAnalogPin(connection, channel); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002Channel.cs b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002Channel.cs new file mode 100644 index 0000000..8c06ae2 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002Channel.cs @@ -0,0 +1,8 @@ +namespace Raspberry.IO.Components.Converters.Mcp3002 +{ + public enum Mcp3002Channel + { + Channel0 = 0, + Channel1 = 1 + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002InputAnalogPin.cs b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002InputAnalogPin.cs new file mode 100644 index 0000000..71e01ca --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002InputAnalogPin.cs @@ -0,0 +1,47 @@ +namespace Raspberry.IO.Components.Converters.Mcp3002 +{ + public class Mcp3002InputAnalogPin : IInputAnalogPin + { + #region Fields + + private readonly Mcp3002SpiConnection connection; + private readonly Mcp3002Channel channel; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The channel. + public Mcp3002InputAnalogPin(Mcp3002SpiConnection connection, Mcp3002Channel channel) + { + this.connection = connection; + this.channel = channel; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose(){} + + #endregion + + #region Methods + + /// + /// Reads the value of the pin. + /// + /// + /// The value. + /// + public AnalogValue Read() + { + return connection.Read(channel); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002SpiConnection.cs new file mode 100644 index 0000000..c46f2b8 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3002/Mcp3002SpiConnection.cs @@ -0,0 +1,85 @@ +#region References + +using System; +using Raspberry.IO.SerialPeripheralInterface; + +#endregion + +namespace Raspberry.IO.Components.Converters.Mcp3002 +{ + /// + /// Represents a connection to MCP3002 ADC converter. + /// + public class Mcp3002SpiConnection : IDisposable + { + #region Fields + + private readonly SpiConnection spiConnection; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The clock pin. + /// The slave select pin. + /// The miso pin. + /// The mosi pin. + public Mcp3002SpiConnection(IOutputBinaryPin clockPin, IOutputBinaryPin slaveSelectPin, IInputBinaryPin misoPin, IOutputBinaryPin mosiPin) + { + spiConnection = new SpiConnection(clockPin, slaveSelectPin, misoPin, mosiPin, Endianness.LittleEndian); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + /// + /// Reads the specified channel. + /// + /// The channel. + /// The value + public AnalogValue Read(Mcp3002Channel channel) + { + using(spiConnection.SelectSlave()) + { + // Start bit + spiConnection.Write(true); + + // Channel is single-ended + spiConnection.Write(true); + + // Channel Id + spiConnection.Write((byte)channel, 1); + + // Let one clock to sample + spiConnection.Synchronize(); + + // Read 10 bits + var data = (int)spiConnection.Read(10); + + return new AnalogValue(data, 0x3FF); + } + } + + /// + /// Closes this instance. + /// + public void Close() + { + spiConnection.Close(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index eed52df..2b926d6 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -65,6 +65,10 @@ + + + + From ae40bffd82bb57dfa33a4626bef80e93166781a5 Mon Sep 17 00:00:00 2001 From: nickpbd Date: Sat, 28 Feb 2015 12:46:31 -0800 Subject: [PATCH 182/227] Addition of PiFaceDigital device --- .../PiFaceDigital/InputPinChangedArgs.cs | 12 + .../PiFaceDigital/InputPinChangedHandler.cs | 15 + .../PiFaceDigital/PiFaceDigitalDevice.cs | 249 +++++++++++ .../Devices/PiFaceDigital/PiFaceInputPin.cs | 81 ++++ .../Devices/PiFaceDigital/PiFaceOutputPin.cs | 40 ++ .../Devices/PiFaceDigital/PiFacePin.cs | 90 ++++ .../Raspberry.IO.Components.csproj | 6 + RaspberrySharp.IO.sln | 410 +++++++++--------- .../Test.Components.PiFaceDigital/App.config | 6 + .../Test.Components.PiFaceDigital/Program.cs | 78 ++++ .../Properties/AssemblyInfo.cs | 36 ++ .../Test.Components.PiFaceDigital.csproj | 64 +++ 12 files changed, 886 insertions(+), 201 deletions(-) create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedArgs.cs create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedHandler.cs create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceDigitalDevice.cs create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceInputPin.cs create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceOutputPin.cs create mode 100644 Raspberry.IO.Components/Devices/PiFaceDigital/PiFacePin.cs create mode 100644 Tests/Test.Components.PiFaceDigital/App.config create mode 100644 Tests/Test.Components.PiFaceDigital/Program.cs create mode 100644 Tests/Test.Components.PiFaceDigital/Properties/AssemblyInfo.cs create mode 100644 Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedArgs.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedArgs.cs new file mode 100644 index 0000000..78dec43 --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedArgs.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + public class InputPinChangedArgs : EventArgs + { + public PiFaceInputPin pin; + } +} diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedHandler.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedHandler.cs new file mode 100644 index 0000000..977b2a1 --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/InputPinChangedHandler.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + /// + /// delgate for pin state changed events. The pin that changed is in the args + /// + /// + /// + public delegate void InputPinChangedHandler (object sender, InputPinChangedArgs e); + +} diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceDigitalDevice.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceDigitalDevice.cs new file mode 100644 index 0000000..a07e84d --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceDigitalDevice.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Raspberry.IO.SerialPeripheralInterface; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + /// + /// Controls a PiFace Digital device on a Raspberry Pi. + /// Pins on the board have software counterparts to control or read state of the physical pins. + /// Polling is required for the input pin values as the PiFace Digital has no interrupt support. + /// + /// This driver uses a NativeSpiConnection which requires the native SPI driver be enabled + /// + public class PiFaceDigitalDevice : IDisposable + { + + #region Constants + + private const byte IOCON_SEQOP = 0x00; + private const byte All_Pins_Input = 0xFF; + private const byte All_Pins_Output = 0x00; + private const byte CMD_WRITE = 0x40; + private const byte CMD_READ = 0x41; + + #endregion + + #region Enums + + /// + /// Registers on the MCP23S17 chip + /// + internal enum mcp23s17Register + { + IODIRA = 0x00, + IODIRB = 0x01, + IOCON = 0x0A, + GPPUB = 0x0D, + GPIOA = 0x12, + GPIOB = 0x13 + }; + + #endregion + + #region Fields + + private string driverName; + + private INativeSpiConnection spiConnection = null; + + /// + /// Re-usable buffer for reading input pins state to reduce the polling overhead + /// + private ISpiTransferBuffer inputPollBuffer; + + /// + /// Last known state of the inputs, used to optimize detecting changes + /// + private byte CachedInputState; + + bool disposed = false; + + #endregion + + #region Instance Management + + /// + /// Create the device with a custom driver name + /// + /// name of the device driver e.g. /dev/... + public PiFaceDigitalDevice(string driverName = "/dev/spidev0.0") + { + this.driverName = driverName; + InitPiFace(); + } + + /// + /// Create the device injecting an SPI connection + /// + /// connection to the SPI driver. + public PiFaceDigitalDevice(INativeSpiConnection nativeSpiConnection) + { + spiConnection = nativeSpiConnection; + InitPiFace(); + } + + + public void Dispose() + { + // Dispose of unmanaged resources. + Dispose(true); + // Suppress finalization. + GC.SuppressFinalize(this); + } + + + // Protected implementation of Dispose pattern. + protected void Dispose(bool disposing) + { + if (disposed) + { + return; + } + + if (disposing) + { + spiConnection.Dispose(); + inputPollBuffer.Dispose(); + } + + disposed = true; + } + + #endregion + + #region Properties + + /// + /// Software proxy for the input pins of the PiFace Digital Board + /// + public PiFaceInputPin[] InputPins { get; private set; } + + /// + /// Software proxy for the output pins of the PiFace Digital Board + /// + public PiFaceOutputPin[] OutputPins { get; private set; } + + #endregion + + #region Methods + + /// + /// Set up the MCP23S17 for the PiFace Digital board + /// + private void InitPiFace() + { + InputPins = new PiFaceInputPin[8]; + for (int pinNo = 0; pinNo < 8; pinNo++) + { + InputPins[pinNo] = new PiFaceInputPin(pinNo); + } + + OutputPins = new PiFaceOutputPin[8]; + for (int pinNo = 0; pinNo < 8; pinNo++) + { + OutputPins[pinNo] = new PiFaceOutputPin(pinNo); + } + + if (spiConnection == null) + { + SpiConnectionSettings spiSettings = new SpiConnectionSettings { BitsPerWord = 8, Delay = 1, MaxSpeed = 5000000, Mode = SpiMode.Mode0 }; + spiConnection = new NativeSpiConnection(driverName, spiSettings); + } + + Write(mcp23s17Register.IOCON, IOCON_SEQOP); + SetAllOutputPins(0); + + // initialize output and input pins + Write(mcp23s17Register.IODIRA, All_Pins_Output); + Write(mcp23s17Register.IODIRB, All_Pins_Input); + + // set resistor on all input pins to pull up + Write(mcp23s17Register.GPPUB, 0xFF); + + // set outputs + UpdatePiFaceOutputPins(); + + // Create re-usable buffer for polling input pins + CreateReusableBufferForInputPolling(); + + // Get the initial software input pin state and compare to actual inputs + CachedInputState = PiFaceInputPin.AllPinState(InputPins); + PollInputPins(); + } + + /// + /// Sets up the transfer buffer for reading input pins; + /// + private void CreateReusableBufferForInputPolling() + { + inputPollBuffer = spiConnection.CreateTransferBuffer(3, SpiTransferMode.ReadWrite); + inputPollBuffer.Tx[0] = CMD_READ; + inputPollBuffer.Tx[1] = (byte)mcp23s17Register.GPIOB; + inputPollBuffer.Tx[2] = 0; + } + + private int Write(mcp23s17Register port, byte data) + { + ISpiTransferBuffer transferBuffer = spiConnection.CreateTransferBuffer(3, SpiTransferMode.Write); + transferBuffer.Tx[0] = CMD_WRITE; + transferBuffer.Tx[1] = (byte)port; + transferBuffer.Tx[2] = data; + var result = spiConnection.Transfer(transferBuffer); + return result; + } + + internal byte Read(mcp23s17Register port) + { + ISpiTransferBuffer transferBuffer = spiConnection.CreateTransferBuffer(3, SpiTransferMode.ReadWrite); + transferBuffer.Tx[0] = CMD_READ; + transferBuffer.Tx[1] = (byte)port; + transferBuffer.Tx[2] = 0; + var result = spiConnection.Transfer(transferBuffer); + return transferBuffer.Rx[2]; + } + + #endregion + + #region Public Methods + + /// + /// Configure the output pins with a byte that has one bit per pin and set the pins on the PiFaceDigital + /// + /// + public void SetAllOutputPins(byte allPinsState) + { + foreach (var oPin in OutputPins) + { + oPin.Update(allPinsState); + } + Write(mcp23s17Register.GPIOA, allPinsState); + } + + /// + /// Update PiFace board with the current vales of the software output pins + /// + public void UpdatePiFaceOutputPins() + { + Write(mcp23s17Register.GPIOA, PiFaceOutputPin.AllPinState(OutputPins)); + } + + /// + /// Read the state of the input pins. Will trigger any Onchanged events registered + /// + public void PollInputPins() + { + var result = spiConnection.Transfer(inputPollBuffer); + var state = inputPollBuffer.Rx[2]; + if (state != CachedInputState) + { + CachedInputState = state; + PiFaceInputPin.SetAllPinStates(InputPins, state); + } + } + + #endregion + } +} diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceInputPin.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceInputPin.cs new file mode 100644 index 0000000..8faa3d5 --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceInputPin.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + public class PiFaceInputPin : PiFacePin + { + + #region events + /// + /// Event fired when the state of a pin changes + /// + public event InputPinChangedHandler OnStateChanged; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// Number of the pin in the range 0 to 7 + internal PiFaceInputPin(int pinNumber) + : base(pinNumber) + { + } + + #endregion + + #region Properties + + /// + /// Indicates that sensor grounding the input pin is closed + /// + public bool IsGrounded { get { return !state; } } + + /// + /// Gets the state of the pin, note true indicates the pin is high i.e. open. + /// if this throws off your logic use the IsGrounded property instead. + /// + public bool State + { + get { return state; } + } + + #endregion + + #region Methods + + /// + /// Update the state of this pin based on a byte that contains the state of every pin + /// + /// byte with all pin values + internal override void Update(byte allPinState) + { + var oldState = state; + state = (allPinState & mask) > 0; + if (oldState != state && OnStateChanged != null) + { + OnStateChanged(this, new InputPinChangedArgs { pin = this }); + } + } + + /// + /// helper to set the state of every pin in a collection + /// + /// + /// + internal static void SetAllPinStates(IEnumerable inputPins, byte allPinState) + { + foreach (var inputPin in inputPins) + { + inputPin.Update(allPinState); + } + } + + #endregion + } +} diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceOutputPin.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceOutputPin.cs new file mode 100644 index 0000000..1540f9b --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFaceOutputPin.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + /// + /// Derivative of PiFacePin that allows setting of the internal state + /// + public class PiFaceOutputPin : PiFacePin + { + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// Number of the pin in the range 0 to 7 + internal PiFaceOutputPin(int pinNumber) + : base(pinNumber) + { + } + + #endregion + + #region Properties + + /// + /// Gets/Sets the state of the pin in software but does not update the PiFaceDigital device + /// Allows individual pins to be modified then everything updated with a call to UpdatePiFaceOutputPins + /// + public bool State + { + get { return state; } + set { state = value; } + } + + #endregion + } +} diff --git a/Raspberry.IO.Components/Devices/PiFaceDigital/PiFacePin.cs b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFacePin.cs new file mode 100644 index 0000000..8e6c41e --- /dev/null +++ b/Raspberry.IO.Components/Devices/PiFaceDigital/PiFacePin.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Devices.PiFaceDigital +{ + /// + /// Represents the pins on a PiFace Digital board + /// + public abstract class PiFacePin + { + + + #region Fields + + /// + /// bit mask that allows this pin to get / set it's value from a byte + /// + protected byte mask; + + /// + /// state of this pin + /// + protected bool state; + + #endregion + + + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// Number of the pin in the range 0 to 7 + internal PiFacePin(int pinNumber) + { + if (pinNumber < 0 || pinNumber > 7) + { + throw new ArgumentOutOfRangeException("pin numbers must be in the range 0 to 7"); + } + mask = (byte)(1 << pinNumber); + Id = pinNumber; + } + + #endregion + + #region Properties + + /// + /// Number of the pin 0..7 + /// + public int Id { get; private set; } + + #endregion + + #region Methods + + /// + /// Update this pin based on a byte that contains the data for every pin + /// + /// byte with all pin values + internal virtual void Update(byte allPinState) + { + state = (allPinState & mask) > 0; + } + + /// + /// Returns a byte representing the state of all pins + /// + /// collection of pins to aggregate over + /// byte of all pin state + internal static byte AllPinState(IEnumerable pins) + { + byte allPinState = 0; + foreach (var pin in pins) + { + if (pin.state) + { + allPinState = (byte)(allPinState | pin.mask); + } + } + return allPinState; + } + + + #endregion + } +} diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index eed52df..a44821d 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -75,6 +75,12 @@ + + + + + + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index acba72a..4882677 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -1,201 +1,209 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" - ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore - Icon.png = Icon.png - Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec - README.md = README.md - SharedAssemblyInfo.cs = SharedAssemblyInfo.cs - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{15ECD485-B3FD-4B6F-8491-7489DFFC89BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP3008", "Tests\Test.Gpio.MCP3008\Test.Gpio.MCP3008.csproj", "{B28253A7-BB93-40F7-B41C-B4AE369174ED}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP4822", "Tests\Test.Gpio.MCP4822\Test.Gpio.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HD44780", "Tests\Test.Gpio.HD44780\Test.Gpio.HD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HCSR04", "Tests\Test.Gpio.HCSR04\Test.Gpio.HCSR04.csproj", "{0A18AC47-CA6D-442C-A31C-6864F7DDD97D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Chaser", "Tests\Test.Gpio.Chaser\Test.Gpio.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Tests\Test.Gpio.MCP23017\Test.Gpio.MCP23017.csproj", "{266EDDBC-F741-48F8-83B7-2CD37BACE62B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Tests\Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.TLC59711", "Tests\Test.Spi.TLC59711\Test.Spi.TLC59711.csproj", "{AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.SerialPeripheralInterface", "UnitTests\Tests.Raspberry.IO.SerialPeripheralInterface\Tests.Raspberry.IO.SerialPeripheralInterface.csproj", "{17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO", "UnitTests\Tests.Raspberry.IO\Tests.Raspberry.IO.csproj", "{0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Components", "UnitTests\Tests.Raspberry.IO.Components\Tests.Raspberry.IO.Components.csproj", "{99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Interop", "UnitTests\Tests.Raspberry.IO.Interop\Tests.Raspberry.IO.Interop.csproj", "{CAF876A0-0FCB-44F7-96F1-53704CB6015F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripheralInterface", "Raspberry.IO.SerialPeripheralInterface\Raspberry.IO.SerialPeripheralInterface.csproj", "{326342E5-0411-40E8-9F2D-563D6B192568}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegratedCircuit", "Raspberry.IO.InterIntegratedCircuit\Raspberry.IO.InterIntegratedCircuit.csproj", "{63B8403E-BC56-43F9-A045-F61ECC3871F3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Components", "Raspberry.IO.Components\Raspberry.IO.Components.csproj", "{8388CFCA-E3DB-43F7-B049-2CB195211CE8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE3E-2730-4A56-9C64-0A58E00A5CEE}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.Build.0 = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.Build.0 = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} - {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} - {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {60B59A9C-69F6-4CEA-8385-C8542AE2BB98} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {57A001A7-FCF7-45EC-8E25-A390EF044E94} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj - Policies = $0 - $0.TextStylePolicy = $1 - $1.inheritsSet = null - $1.scope = text/x-csharp - $0.CSharpFormattingPolicy = $2 - $2.AnonymousMethodBraceStyle = NextLine - $2.PropertyBraceStyle = NextLine - $2.PropertyGetBraceStyle = NextLine - $2.PropertySetBraceStyle = NextLine - $2.EventBraceStyle = NextLine - $2.EventAddBraceStyle = NextLine - $2.EventRemoveBraceStyle = NextLine - $2.StatementBraceStyle = NextLine - $2.ElseIfNewLinePlacement = SameLine - $2.BeforeMethodDeclarationParentheses = False - $2.BeforeMethodCallParentheses = False - $2.BeforeConstructorDeclarationParentheses = False - $2.BeforeIndexerDeclarationBracket = False - $2.BeforeDelegateDeclarationParentheses = False - $2.AfterDelegateDeclarationParameterComma = True - $2.NewParentheses = False - $2.SpacesBeforeBrackets = False - $2.inheritsSet = Mono - $2.inheritsScope = text/x-csharp - $2.scope = text/x-csharp - $0.TextStylePolicy = $3 - $3.FileWidth = 120 - $3.inheritsSet = VisualStudio - $3.inheritsScope = text/plain - $3.scope = text/plain - $0.DotNetNamingPolicy = $4 - $4.DirectoryNamespaceAssociation = None - $4.ResourceNamePolicy = FileFormatDefault - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E87796-2109-444A-8852-7174C93E6F45}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + Icon.png = Icon.png + Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec + README.md = README.md + SharedAssemblyInfo.cs = SharedAssemblyInfo.cs + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{15ECD485-B3FD-4B6F-8491-7489DFFC89BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP3008", "Tests\Test.Gpio.MCP3008\Test.Gpio.MCP3008.csproj", "{B28253A7-BB93-40F7-B41C-B4AE369174ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP4822", "Tests\Test.Gpio.MCP4822\Test.Gpio.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HD44780", "Tests\Test.Gpio.HD44780\Test.Gpio.HD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HCSR04", "Tests\Test.Gpio.HCSR04\Test.Gpio.HCSR04.csproj", "{0A18AC47-CA6D-442C-A31C-6864F7DDD97D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Chaser", "Tests\Test.Gpio.Chaser\Test.Gpio.Chaser.csproj", "{5D9D1834-4C4B-4E03-B635-5F205205B6F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Tests\Test.Gpio.MCP23017\Test.Gpio.MCP23017.csproj", "{266EDDBC-F741-48F8-83B7-2CD37BACE62B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Tests\Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.TLC59711", "Tests\Test.Spi.TLC59711\Test.Spi.TLC59711.csproj", "{AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.SerialPeripheralInterface", "UnitTests\Tests.Raspberry.IO.SerialPeripheralInterface\Tests.Raspberry.IO.SerialPeripheralInterface.csproj", "{17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO", "UnitTests\Tests.Raspberry.IO\Tests.Raspberry.IO.csproj", "{0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Components", "UnitTests\Tests.Raspberry.IO.Components\Tests.Raspberry.IO.Components.csproj", "{99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.Interop", "UnitTests\Tests.Raspberry.IO.Interop\Tests.Raspberry.IO.Interop.csproj", "{CAF876A0-0FCB-44F7-96F1-53704CB6015F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripheralInterface", "Raspberry.IO.SerialPeripheralInterface\Raspberry.IO.SerialPeripheralInterface.csproj", "{326342E5-0411-40E8-9F2D-563D6B192568}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegratedCircuit", "Raspberry.IO.InterIntegratedCircuit\Raspberry.IO.InterIntegratedCircuit.csproj", "{63B8403E-BC56-43F9-A045-F61ECC3871F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Components", "Raspberry.IO.Components\Raspberry.IO.Components.csproj", "{8388CFCA-E3DB-43F7-B049-2CB195211CE8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE3E-2730-4A56-9C64-0A58E00A5CEE}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Components.PiFaceDigital", "Tests\Test.Components.PiFaceDigital\Test.Components.PiFaceDigital.csproj", "{475CEB21-BA5F-4338-80E2-C6B29766A04A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.Build.0 = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.Build.0 = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} + {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {60B59A9C-69F6-4CEA-8385-C8542AE2BB98} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {57A001A7-FCF7-45EC-8E25-A390EF044E94} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {475CEB21-BA5F-4338-80E2-C6B29766A04A} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj + Policies = $0 + $0.TextStylePolicy = $3 + $1.inheritsSet = null + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.AnonymousMethodBraceStyle = NextLine + $2.PropertyBraceStyle = NextLine + $2.PropertyGetBraceStyle = NextLine + $2.PropertySetBraceStyle = NextLine + $2.EventBraceStyle = NextLine + $2.EventAddBraceStyle = NextLine + $2.EventRemoveBraceStyle = NextLine + $2.StatementBraceStyle = NextLine + $2.ElseIfNewLinePlacement = SameLine + $2.BeforeMethodDeclarationParentheses = False + $2.BeforeMethodCallParentheses = False + $2.BeforeConstructorDeclarationParentheses = False + $2.BeforeIndexerDeclarationBracket = False + $2.BeforeDelegateDeclarationParentheses = False + $2.AfterDelegateDeclarationParameterComma = True + $2.NewParentheses = False + $2.SpacesBeforeBrackets = False + $2.inheritsSet = Mono + $2.inheritsScope = text/x-csharp + $2.scope = text/x-csharp + $3.FileWidth = 120 + $3.inheritsSet = VisualStudio + $3.inheritsScope = text/plain + $3.scope = text/plain + $0.DotNetNamingPolicy = $4 + $4.DirectoryNamespaceAssociation = None + $4.ResourceNamePolicy = FileFormatDefault + EndGlobalSection +EndGlobal diff --git a/Tests/Test.Components.PiFaceDigital/App.config b/Tests/Test.Components.PiFaceDigital/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/Tests/Test.Components.PiFaceDigital/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Tests/Test.Components.PiFaceDigital/Program.cs b/Tests/Test.Components.PiFaceDigital/Program.cs new file mode 100644 index 0000000..4e082cd --- /dev/null +++ b/Tests/Test.Components.PiFaceDigital/Program.cs @@ -0,0 +1,78 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Raspberry.IO.Components.Devices.PiFaceDigital; + + +namespace Test.Components.PiFaceDigital +{ + class Program + { + private static PiFaceDigitalDevice piFace; + private static bool polling = true; + private static Task t; + + /// + /// Demo App + /// + /// Loops through each output pin 10 times pulsing them on for 1/2 second + /// Inputs are polled and any change reported on the console + /// + static void Main() + { + + piFace = new PiFaceDigitalDevice(); + + + // setup events + foreach (var ip in piFace.InputPins) + { + ip.OnStateChanged += ip_OnStateChanged; + } + + t = Task.Factory.StartNew(() => PollInputs()); + + for (int i = 0; i < 10; i++) + { + for (int pin = 0; pin < 8; pin++) + { + piFace.OutputPins[pin].State = true; + piFace.UpdatePiFaceOutputPins(); + Thread.Sleep(500); + piFace.OutputPins[pin].State = false; + piFace.UpdatePiFaceOutputPins(); + Thread.Sleep(500); + } + } + + //stop polling loop + polling = false; + t.Wait(); + } + + + + + /// + /// Loop polling the inputs at 200ms intervals + /// + private static void PollInputs() + { + while (polling) + { + piFace.PollInputPins(); + Thread.Sleep(200); + } + } + + /// + /// Log any input pin changes + /// + /// + /// + private static void ip_OnStateChanged(object sender, InputPinChangedArgs e) + { + Console.WriteLine("Pin {0} became {1}", e.pin.Id, e.pin.State); + } + } +} diff --git a/Tests/Test.Components.PiFaceDigital/Properties/AssemblyInfo.cs b/Tests/Test.Components.PiFaceDigital/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..848b273 --- /dev/null +++ b/Tests/Test.Components.PiFaceDigital/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test.Components.PiFaceDigital")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test.Components.PiFaceDigital")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9e706a1c-5a89-45a4-8dd4-826b2ee03eca")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj new file mode 100644 index 0000000..19eac27 --- /dev/null +++ b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj @@ -0,0 +1,64 @@ + + + + + Debug + AnyCPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A} + Exe + Properties + Test.Components.PiFaceDigital + Test.Components.PiFaceDigital + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + {8388cfca-e3db-43f7-b049-2cb195211ce8} + Raspberry.IO.Components + + + + + \ No newline at end of file From d10fe78127d86c59884baca810e6f999ee3025a4 Mon Sep 17 00:00:00 2001 From: Generoso Martello Date: Sat, 28 Feb 2015 23:19:53 +0100 Subject: [PATCH 183/227] changed toolversion of PiFaceDigital test project to make it work with monodevelp too --- .../Test.Components.PiFaceDigital.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj index 19eac27..44c9755 100644 --- a/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj +++ b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj @@ -1,5 +1,5 @@  - + Debug From b3bf75399d56b6a95912481f896d2b900bec0d01 Mon Sep 17 00:00:00 2001 From: gamondue Date: Sun, 1 Mar 2015 18:42:39 +0100 Subject: [PATCH 184/227] Mcp classes as made by WildGenie + test program over all 8 channels. --- .../Mcp3208AnalogPinExtensionMethods.cs | 20 ++++ .../Converters/Mcp3208/Mcp3208Channel.cs | 14 +++ .../Mcp3208/Mcp3208InputAnalogPin.cs | 47 +++++++++ .../Mcp3208/Mcp3208SpiConnection.cs | 98 +++++++++++++++++++ .../Raspberry.IO.Components.csproj | 4 + RaspberrySharp.IO.sln | 9 +- Tests/Test.Spi.MCP3208/Program.cs | 76 ++++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++++ .../Test.Spi.MCP3208/Test.Spi.MCP3208.csproj | 64 ++++++++++++ 9 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 Raspberry.IO.Components/Converters/Mcp3208/Mcp3208AnalogPinExtensionMethods.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3208/Mcp3208Channel.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3208/Mcp3208InputAnalogPin.cs create mode 100644 Raspberry.IO.Components/Converters/Mcp3208/Mcp3208SpiConnection.cs create mode 100644 Tests/Test.Spi.MCP3208/Program.cs create mode 100644 Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs create mode 100644 Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj diff --git a/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208AnalogPinExtensionMethods.cs b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208AnalogPinExtensionMethods.cs new file mode 100644 index 0000000..9a125d3 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208AnalogPinExtensionMethods.cs @@ -0,0 +1,20 @@ +namespace Raspberry.IO.Components.Converters.Mcp3208 +{ + public static class Mcp3208AnalogPinExtensionMethods + { + #region Methods + + /// + /// Creates an analog input pin. + /// + /// The connection. + /// The channel. + /// The pin. + public static Mcp3208InputAnalogPin In(this Mcp3208SpiConnection connection, Mcp3208Channel channel) + { + return new Mcp3208InputAnalogPin(connection, channel); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208Channel.cs b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208Channel.cs new file mode 100644 index 0000000..b757889 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208Channel.cs @@ -0,0 +1,14 @@ +namespace Raspberry.IO.Components.Converters.Mcp3208 +{ + public enum Mcp3208Channel + { + Channel0 = 0, + Channel1 = 1, + Channel2 = 2, + Channel3 = 3, + Channel4 = 4, + Channel5 = 5, + Channel6 = 6, + Channel7 = 7 + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208InputAnalogPin.cs b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208InputAnalogPin.cs new file mode 100644 index 0000000..1062325 --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208InputAnalogPin.cs @@ -0,0 +1,47 @@ +namespace Raspberry.IO.Components.Converters.Mcp3208 +{ + public class Mcp3208InputAnalogPin : IInputAnalogPin + { + #region Fields + + private readonly Mcp3208SpiConnection connection; + private readonly Mcp3208Channel channel; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The channel. + public Mcp3208InputAnalogPin(Mcp3208SpiConnection connection, Mcp3208Channel channel) + { + this.connection = connection; + this.channel = channel; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose(){} + + #endregion + + #region Methods + + /// + /// Reads the value of the pin. + /// + /// + /// The value. + /// + public AnalogValue Read() + { + return connection.Read(channel); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208SpiConnection.cs new file mode 100644 index 0000000..c0e2aaa --- /dev/null +++ b/Raspberry.IO.Components/Converters/Mcp3208/Mcp3208SpiConnection.cs @@ -0,0 +1,98 @@ +#region References + +using System; +using Raspberry.IO.SerialPeripheralInterface; + +#endregion + +namespace Raspberry.IO.Components.Converters.Mcp3208 +{ + /// + /// Represents a connection to MCP3204/3208 ADC converter. + /// + /// + /// See specification at http://www.adafruit.com/datasheets/MCP3208.pdf + /// + public class Mcp3208SpiConnection : IDisposable + { + #region Fields + IOutputBinaryPin clockPin; + IOutputBinaryPin slaveSelectPin; + IInputBinaryPin misoPin; + IOutputBinaryPin mosiPin; + + private readonly SpiConnection spiConnection; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The clock pin. + /// The slave select pin. + /// The miso pin. + /// The mosi pin. + public Mcp3208SpiConnection(IOutputBinaryPin clockPin, IOutputBinaryPin slaveSelectPin, + IInputBinaryPin misoPin, IOutputBinaryPin mosiPin) + { + this.clockPin = clockPin; + this.slaveSelectPin = slaveSelectPin; + this.misoPin = misoPin; + this.mosiPin = mosiPin; + + spiConnection = new SpiConnection(clockPin, slaveSelectPin, misoPin, mosiPin, Endianness.LittleEndian); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Close(); + } + + #endregion + + #region Methods + + /// + /// Reads the specified channel. + /// + /// The channel. + /// The value + public AnalogValue Read(Mcp3208Channel channel) + { + using (spiConnection.SelectSlave()) + { + // Start bit + spiConnection.Write(true); + + // Channel is single-ended + spiConnection.Write(true); + + spiConnection.Write((byte)channel, 3); + + // Let one clock to sample + spiConnection.Synchronize(); + + // Read 12 bits + var data = (int)spiConnection.Read(12); + //Console.WriteLine(((byte)channel).ToString() + " " + channel.ToString() + + //" " + data.ToString()); + + return new AnalogValue(data, 0xFFF); + } + } + + /// + /// Closes this instance. + /// + public void Close() + { + spiConnection.Close(); + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 7e30c3f..622e4cd 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -75,6 +75,10 @@ + + + + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 4882677..f591fb6 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +VisualStudioVersion = 12.0.30501.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" EndProject @@ -63,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Ras EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Components.PiFaceDigital", "Tests\Test.Components.PiFaceDigital\Test.Components.PiFaceDigital.csproj", "{475CEB21-BA5F-4338-80E2-C6B29766A04A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.MCP3208", "Tests\Test.Spi.MCP3208\Test.Spi.MCP3208.csproj", "{D4B87926-598E-4EAB-BA75-CD9FB253D450}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -149,6 +151,10 @@ Global {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.Build.0 = Debug|Any CPU {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.ActiveCfg = Release|Any CPU {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.Build.0 = Release|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -170,6 +176,7 @@ Global {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {475CEB21-BA5F-4338-80E2-C6B29766A04A} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {D4B87926-598E-4EAB-BA75-CD9FB253D450} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj diff --git a/Tests/Test.Spi.MCP3208/Program.cs b/Tests/Test.Spi.MCP3208/Program.cs new file mode 100644 index 0000000..46fc7b4 --- /dev/null +++ b/Tests/Test.Spi.MCP3208/Program.cs @@ -0,0 +1,76 @@ +#region References + +using System; +using System.Threading; +using Raspberry.IO.Components.Converters.Mcp3208; +using Raspberry.IO.Components.Sensors; +using Raspberry.IO.Components.Sensors.Temperature.Dht; +using Raspberry.IO.Components.Sensors.Temperature.Tmp36; +using Raspberry.IO.GeneralPurpose; +using Raspberry.IO; + +using System.IO; + +#endregion + +namespace Test.Spi.MCP3208 +{ + /// + /// Modified from Test.Gpio.MCP3208 + /// Connected with standars SPI pins in Raspberry + /// + class Program + { + static void Main() + { + const ConnectorPin adcClock = ConnectorPin.P1Pin23; + const ConnectorPin adcMiso = ConnectorPin.P1Pin21; + const ConnectorPin adcMosi = ConnectorPin.P1Pin19; + const ConnectorPin adcCs = ConnectorPin.P1Pin24; + + Console.Clear(); + + Console.WriteLine("MCP-3208 Sample: Reading ADC points in all channels"); + Console.WriteLine(); + Console.WriteLine("\tClock: {0}", adcClock); + Console.WriteLine("\tCS: {0}", adcCs); + Console.WriteLine("\tMOSI: {0}", adcMosi); + Console.WriteLine("\tMISO: {0}", adcMiso); + Console.WriteLine(); + + var driver = new GpioConnectionDriver(); + + { + Console.CursorVisible = false; + var adcConnection = new Mcp3208SpiConnection( + driver.Out(adcClock), + driver.Out(adcCs), + driver.In(adcMiso), + driver.Out(adcMosi)); + + while (!Console.KeyAvailable) + { + Console.CursorTop = 0; + Console.Clear(); + + Mcp3208Channel chan = Mcp3208Channel.Channel0; + + for (int i = 0; i < 8; i++) + { + AnalogValue p = adcConnection.Read(chan); + decimal points = p.Value; + Console.WriteLine(i.ToString() + " ADC points " + points.ToString()); + using (StreamWriter sw = File.AppendText(".\\prova.txt")) + { + sw.WriteLine(chan.ToString() + " ADC points " + points.ToString()); + } + chan++; // enum increase sends to the next channel + } + Thread.Sleep(500); + } + } + Console.CursorTop++; + Console.CursorVisible = true; + } + } +} \ No newline at end of file diff --git a/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs b/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6b7c192 --- /dev/null +++ b/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Le informazioni generali relative a un assembly sono controllate dal seguente +// set di attributi. Per modificare le informazioni associate a un assembly +// occorre quindi modificare i valori di questi attributi. +[assembly: AssemblyTitle("Test.Spi.MCP3208")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test.Spi.MCP3208")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// COM, impostare su true l'attributo ComVisible per tale tipo. +[assembly: ComVisible(false)] + +// Se il progetto viene esposto a COM, il GUID che segue verrà utilizzato per creare l'ID della libreria dei tipi +[assembly: Guid("2e0267cc-028e-4e7a-8ca6-d9cab73f13ed")] + +// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: +// +// Numero di versione principale +// Numero di versione secondario +// Numero build +// Revisione +// +// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build +// utilizzando l'asterisco (*) come descritto di seguito: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj b/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj new file mode 100644 index 0000000..327a3c1 --- /dev/null +++ b/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj @@ -0,0 +1,64 @@ + + + + + Debug + AnyCPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450} + Exe + Properties + Test.Spi.MCP3208 + Test.Spi.MCP3208 + v4.0 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + {8388cfca-e3db-43f7-b049-2cb195211ce8} + Raspberry.IO.Components + + + {281c71ed-c36d-408e-8baa-75c381dc17e7} + Raspberry.IO.GeneralPurpose + + + {ace64f17-87e5-43e7-97a0-bdde19059c61} + Raspberry.IO + + + + + \ No newline at end of file From fc39bcf41c5e01091150511e0c43ad68b19c4b40 Mon Sep 17 00:00:00 2001 From: gamondue Date: Sun, 1 Mar 2015 22:19:28 +0100 Subject: [PATCH 185/227] Change of Assemvly.cs in Test program,like other testbprograms. --- .../Properties/AssemblyInfo.cs | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs b/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs index 6b7c192..8b07c69 100644 --- a/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs +++ b/Tests/Test.Spi.MCP3208/Properties/AssemblyInfo.cs @@ -1,36 +1,13 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// Le informazioni generali relative a un assembly sono controllate dal seguente -// set di attributi. Per modificare le informazioni associate a un assembly -// occorre quindi modificare i valori di questi attributi. +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. [assembly: AssemblyTitle("Test.Spi.MCP3208")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyDescription("Raspberry Pi MCP3208 Component Sample")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Test.Spi.MCP3208")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili -// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da -// COM, impostare su true l'attributo ComVisible per tale tipo. -[assembly: ComVisible(false)] - -// Se il progetto viene esposto a COM, il GUID che segue verrà utilizzato per creare l'ID della libreria dei tipi +// The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("2e0267cc-028e-4e7a-8ca6-d9cab73f13ed")] -// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: -// -// Numero di versione principale -// Numero di versione secondario -// Numero build -// Revisione -// -// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build -// utilizzando l'asterisco (*) come descritto di seguito: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] From a584fe4a50b750c4d4ef2fbe2451dfb9ebf4f385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Mon, 2 Mar 2015 01:49:48 +0100 Subject: [PATCH 186/227] Added support for DHT-11/DHT-22 sensor These sensors require high-precision timings --- .../Sensors/Temperature/Dht/DhtConnection.cs | 158 +++++++++++++----- .../GpioInputOutputBinaryPin.cs | 35 +++- Raspberry.IO/IInputOutputBinaryPin.cs | 13 +- Tests/Test.Gpio.DHT11/Program.cs | 41 +++++ .../Properties/AssemblyInfo.cs | 36 ++++ Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 85 ++++++++++ Tests/Test.Gpio.DHT11/packages.config | 4 + packages/repositories.config | 1 + 8 files changed, 328 insertions(+), 45 deletions(-) create mode 100644 Tests/Test.Gpio.DHT11/Program.cs create mode 100644 Tests/Test.Gpio.DHT11/Properties/AssemblyInfo.cs create mode 100644 Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj create mode 100644 Tests/Test.Gpio.DHT11/packages.config diff --git a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs index c70f33c..d21f9ad 100644 --- a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs +++ b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs @@ -1,86 +1,158 @@ -using System; +#region References + +using System; +using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; +#endregion + namespace Raspberry.IO.Components.Sensors.Temperature.Dht { /// /// Represents a connection to a DHT-11 or DHT-22 humidity / temperature sensor. /// - /// This is preliminary work and is not working. + /// + /// Requires a fast IO connection (such as ). + /// Based on . + /// public class DhtConnection : IDisposable { + #region References + private readonly IInputOutputBinaryPin pin; + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The pin. public DhtConnection(IInputOutputBinaryPin pin) { this.pin = pin; - - pin.Write(true); - Timer.Sleep(100); + pin.AsOutput(); } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// public void Dispose() { Close(); } + #endregion + + #region Method + + /// + /// Gets the data. + /// + /// The DHT data. public DhtData GetData() { - // pull pin down for 18ms - pin.Write(false); - Timer.Sleep(18m); + DhtData data = null; + var retryCount = 10; + while (data == null && retryCount-- > 0) + { + try + { + data = TryGetData(); + } + catch + { + data = null; + } + } - // pull pin up for 40µs - pin.Write(true); - Timer.Sleep(40m / 1000m); - - pin.Wait(true, 40m / 1000m); + return data; + } + + /// + /// Closes this instance. + /// + public void Close() + { + pin.Dispose(); + } - // Wait for pin to be down (at most 80µs) - pin.Wait(false, 80m / 1000m); + #endregion - // Wait for pin to be up (at most 80µs) - pin.Wait(true, 80m / 1000m); + #region Private Helpers - var data = new byte[]{0,0,0,0,0}; + private DhtData TryGetData() + { + // Prepare bugger + var data = new byte[5]; for (var i = 0; i < 5; i++) - for (var j = 0; j < 8; j++) - { - pin.Wait(false, 50m / 1000m); + data[i] = 0; - var start = DateTime.UtcNow; - pin.Wait(true, 100m / 1000m); + pin.Write(true); + HighResolutionTimer.Sleep(100m); - // bit "0" has 26-28us high-voltage length, bit "1" has 70us high-voltage length - var value = (DateTime.UtcNow - start).TotalMilliseconds > 40.0/1000 ? 1 : 0; + // Measure required by host : 18ms down then put to up + pin.Write(false); + HighResolutionTimer.Sleep(18m); + pin.Write(true); - data[i] = (byte) (data[i] << 1 + value); + // Prepare for reading + pin.AsInput(); + try + { + // Read acknowledgement from DHT + pin.Wait(true, 100m); + pin.Wait(false, 100m); + + // Read 40 bits output, or time-out + var cnt = 7; + var idx = 0; + for (var i = 0; i < 40; i++) + { + pin.Wait(true, 100m); + var start = DateTime.UtcNow.Ticks; + pin.Wait(false, 100m); + var ticks = (DateTime.UtcNow.Ticks - start); + if (ticks > 400) + data[idx] |= (byte) (1 << cnt); + + if (cnt == 0) + { + idx++; // next byte + cnt = 7; // restart at MSB + } + else + cnt--; + } + } + finally + { + // Prepare for next reading + pin.Write(true); } - - Console.WriteLine( - "{0:X2} {1:X2} {2:X2} {3:X2} {4:X2}", - data[0], - data[1], - data[2], - data[3], - data[4]); var checkSum = data[0] + data[1] + data[2] + data[3]; if ((checkSum & 0xff) != data[4]) - throw new InvalidOperationException("Checksum is not valid"); + return null; - pin.Write(true); + var humidity = ((data[0] << 8) + data[1])/256m; + + var sign = 1; + if ((data[2] & 0x80) != 0) // negative temperature + { + data[2] = (byte) (data[2] & 0x7F); + sign = -1; + } + var temperature = sign*((data[2] << 8) + data[3])/256m; return new DhtData { - Humidity = (data[0] << 8 + data[1])/10.0m, - Temperature = ((data[2] & 0x80) == 0 ? 1 : -1)*((data[2] & 0x7F) << 8 + data[3])/10.0m + Humidity = humidity, + Temperature = temperature }; } - public void Close() - { - pin.Dispose(); - } + #endregion } -} +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs index a7858e8..549202e 100644 --- a/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioInputOutputBinaryPin.cs @@ -5,11 +5,17 @@ namespace Raspberry.IO.GeneralPurpose /// public class GpioInputOutputBinaryPin : IInputOutputBinaryPin { + #region Fields + private readonly IGpioConnectionDriver driver; private readonly ProcessorPin pin; private readonly PinResistor resistor; private PinDirection? direction; + #endregion + + #region Instance Management + /// /// Initializes a new instance of the class. /// @@ -23,6 +29,10 @@ public GpioInputOutputBinaryPin(IGpioConnectionDriver driver, ProcessorPin pin, this.resistor = resistor; } + #endregion + + #region Methods + /// /// Releases unmanaged and - optionally - managed resources. /// @@ -42,6 +52,22 @@ public bool Read() return driver.Read(pin); } + /// + /// Prepares the pin to act as an input. + /// + public void AsInput() + { + SetDirection(PinDirection.Input); + } + + /// + /// Prepares the pin to act as an output. + /// + public void AsOutput() + { + SetDirection(PinDirection.Output); + } + /// /// Waits the specified wait for up. /// @@ -63,6 +89,10 @@ public void Write(bool state) driver.Write(pin, state); } + #endregion + + #region Private Helpers + private void SetDirection(PinDirection newDirection) { if (direction == newDirection) @@ -72,11 +102,14 @@ private void SetDirection(PinDirection newDirection) driver.Release(pin); driver.Allocate(pin, newDirection); - if (newDirection == PinDirection.Input && resistor != PinResistor.None && (driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) > 0) + if (newDirection == PinDirection.Input + && resistor != PinResistor.None + && (driver.GetCapabilities() & GpioConnectionDriverCapabilities.CanSetPinResistor) != GpioConnectionDriverCapabilities.None) driver.SetPinResistor(pin, resistor); direction = newDirection; } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO/IInputOutputBinaryPin.cs b/Raspberry.IO/IInputOutputBinaryPin.cs index 3bd2a18..6ac3688 100644 --- a/Raspberry.IO/IInputOutputBinaryPin.cs +++ b/Raspberry.IO/IInputOutputBinaryPin.cs @@ -3,5 +3,16 @@ namespace Raspberry.IO /// /// Provides an interface for bidirectional binary pins. /// - public interface IInputOutputBinaryPin : IInputBinaryPin, IOutputBinaryPin {} + public interface IInputOutputBinaryPin : IInputBinaryPin, IOutputBinaryPin + { + /// + /// Prepares the pin to act as an input. + /// + void AsInput(); + + /// + /// Prepares the pin to act as an output. + /// + void AsOutput(); + } } \ No newline at end of file diff --git a/Tests/Test.Gpio.DHT11/Program.cs b/Tests/Test.Gpio.DHT11/Program.cs new file mode 100644 index 0000000..a5351ce --- /dev/null +++ b/Tests/Test.Gpio.DHT11/Program.cs @@ -0,0 +1,41 @@ +#region References + +using System; +using Raspberry.IO.Components.Sensors.Temperature.Dht; +using Raspberry.IO.GeneralPurpose; +using Raspberry.Timers; + +#endregion + +namespace Test.Gpio.DHT11 +{ + internal class Program + { + private static void Main() + { + const ConnectorPin measurePin = ConnectorPin.P1Pin7; + + Console.WriteLine("DHT-11/DHT-22 Sample: measure humidity and temperature"); + Console.WriteLine(); + Console.WriteLine("\tMeasure: {0}", measurePin); + Console.WriteLine(); + + var driver = new MemoryGpioConnectionDriver(); + + using (var pin = driver.InOut(measurePin)) + using (var DhtConnection = new DhtConnection(pin)) + { + while (!Console.KeyAvailable) + { + var data = DhtConnection.GetData(); + if (data != null) + Console.WriteLine("{0:0.00}% humidity, {1:0.0}°C", data.Humidity, data.Temperature); + else + Console.WriteLine("Unable to read data"); + + Timer.Sleep(1000); + } + } + } + } +} diff --git a/Tests/Test.Gpio.DHT11/Properties/AssemblyInfo.cs b/Tests/Test.Gpio.DHT11/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6144e46 --- /dev/null +++ b/Tests/Test.Gpio.DHT11/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test.Gpio.DHT11")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test.Gpio.DHT11")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("70e3e7a3-cba8-4665-a925-a968a0ec8946")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj new file mode 100644 index 0000000..6e605d9 --- /dev/null +++ b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj @@ -0,0 +1,85 @@ + + + + + Debug + AnyCPU + {63356B6E-47A0-44E8-8B98-456E8579DCD2} + Exe + Properties + Test.Gpio.DHT11 + Test.Gpio.DHT11 + v4.0 + 512 + ..\..\ + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + + + + + + + + + + + + + + + + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} + Raspberry.IO.Components + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} + Raspberry.IO + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Tests/Test.Gpio.DHT11/packages.config b/Tests/Test.Gpio.DHT11/packages.config new file mode 100644 index 0000000..78864cb --- /dev/null +++ b/Tests/Test.Gpio.DHT11/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/repositories.config b/packages/repositories.config index a7cbf91..5043e92 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -14,6 +14,7 @@ + From 3e36d2b95e793f7306a14e08e905033a9005fbb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Mon, 2 Mar 2015 01:51:04 +0100 Subject: [PATCH 187/227] Renamed Pca9685 to PCA9685 --- RaspberrySharp.IO.sln | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 4882677..c86e321 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -30,7 +30,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Tests EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Tests\Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.PCA9685", "Tests\Test.Gpio.Pca9685\Test.Gpio.PCA9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.TLC59711", "Tests\Test.Spi.TLC59711\Test.Spi.TLC59711.csproj", "{AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}" EndProject @@ -63,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Ras EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Components.PiFaceDigital", "Tests\Test.Components.PiFaceDigital\Test.Components.PiFaceDigital.csproj", "{475CEB21-BA5F-4338-80E2-C6B29766A04A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.DHT11", "Tests\Test.Gpio.DHT11\Test.Gpio.DHT11.csproj", "{63356B6E-47A0-44E8-8B98-456E8579DCD2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -149,6 +151,10 @@ Global {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.Build.0 = Debug|Any CPU {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.ActiveCfg = Release|Any CPU {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.Build.0 = Release|Any CPU + {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -170,6 +176,7 @@ Global {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {475CEB21-BA5F-4338-80E2-C6B29766A04A} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {63356B6E-47A0-44E8-8B98-456E8579DCD2} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj From 43947583d7350a9ac6a6a599233c1c415e140703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 11 Mar 2015 20:38:41 +0100 Subject: [PATCH 188/227] Renamed AnalogValue.Maximum into Range --- Raspberry.IO/AnalogValue.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Raspberry.IO/AnalogValue.cs b/Raspberry.IO/AnalogValue.cs index 36c984c..c5e1694 100644 --- a/Raspberry.IO/AnalogValue.cs +++ b/Raspberry.IO/AnalogValue.cs @@ -6,16 +6,16 @@ namespace Raspberry.IO public class AnalogValue { private decimal value; - private decimal maximum; + private decimal range; /// /// Initializes a new instance of the class. /// - /// The maximum. + /// The total range (ie. maximum value). /// The value. - public AnalogValue(decimal value, decimal maximum = 1) + public AnalogValue(decimal value, decimal range = 1) { - this.maximum = maximum; + this.range = range; this.value = value; } @@ -32,15 +32,15 @@ public decimal Value } /// - /// Gets or sets the maximum. + /// Gets or sets the total range. /// /// - /// The maximum. + /// The total range, ie. the maximum value. /// - public decimal Maximum + public decimal Range { - get { return maximum; } - set { maximum = value; } + get { return range; } + set { range = value; } } /// @@ -51,7 +51,7 @@ public decimal Maximum /// public decimal Relative { - get { return value / maximum; } + get { return value / range; } } } } \ No newline at end of file From cecc007268d20807a48f9c4dc4cee608e8d632ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 11 Mar 2015 22:43:43 +0100 Subject: [PATCH 189/227] Use Units.Net for physical units handling --- .../Raspberry.IO.Components.csproj | 3 + .../Distance/HcSr04/HcSr04Connection.cs | 7 +- .../Sensors/Distance/HcSr04/Units.cs | 8 +- .../Sensors/Pressure/Bmp085/Bmp085Data.cs | 4 +- .../Pressure/Bmp085/Bmp085I2CConnection.cs | 34 +++---- .../Bmp085I2cConnectionExtensionMethods.cs | 17 ++-- .../Sensors/ResistiveDivider.cs | 17 ++-- .../Sensors/Temperature/Dht/DhtConnection.cs | 5 +- .../Sensors/Temperature/Dht/DhtData.cs | 4 +- .../Temperature/Ds18b20/Ds18b20Connection.cs | 89 ++++++++----------- .../Temperature/Tmp36/Tmp36Connection.cs | 15 ++-- .../VariableResistiveDividerConnection.cs | 11 +-- Raspberry.IO.Components/packages.config | 1 + .../FileGpioConnectionDriver.cs | 13 +-- Raspberry.IO.GeneralPurpose/FileGpioHandle.cs | 26 ++++++ .../Raspberry.IO.GeneralPurpose.csproj | 1 + Tests/Test.Gpio.DHT11/Program.cs | 2 +- Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 3 + Tests/Test.Gpio.DHT11/packages.config | 1 + Tests/Test.Gpio.HCSR04/Program.cs | 4 +- .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 4 + Tests/Test.Gpio.HCSR04/packages.config | 1 + Tests/Test.Gpio.MCP3008/Convert.cs | 6 +- Tests/Test.Gpio.MCP3008/Program.cs | 9 +- .../Test.Gpio.MCP3008.csproj | 14 +++ Tests/Test.Gpio.MCP3008/packages.config | 4 + packages/repositories.config | 1 + 27 files changed, 174 insertions(+), 130 deletions(-) create mode 100644 Raspberry.IO.GeneralPurpose/FileGpioHandle.cs create mode 100644 Tests/Test.Gpio.MCP3008/packages.config diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 7e30c3f..d0308f9 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -47,6 +47,9 @@ + + ..\packages\UnitsNet.3.4.0\lib\net35\UnitsNet.dll + diff --git a/Raspberry.IO.Components/Sensors/Distance/HcSr04/HcSr04Connection.cs b/Raspberry.IO.Components/Sensors/Distance/HcSr04/HcSr04Connection.cs index 0997755..f38a945 100644 --- a/Raspberry.IO.Components/Sensors/Distance/HcSr04/HcSr04Connection.cs +++ b/Raspberry.IO.Components/Sensors/Distance/HcSr04/HcSr04Connection.cs @@ -2,6 +2,7 @@ using System; using Raspberry.Timers; +using UnitsNet; #endregion @@ -77,10 +78,10 @@ void IDisposable.Dispose() #region Methods /// - /// Gets the distance, in meters. + /// Gets the distance. /// - /// The distance, in meters. - public decimal GetDistance() + /// The distance. + public Length GetDistance() { triggerPin.Write(true); Timer.Sleep(triggerTime); diff --git a/Raspberry.IO.Components/Sensors/Distance/HcSr04/Units.cs b/Raspberry.IO.Components/Sensors/Distance/HcSr04/Units.cs index 9592749..7fc43c4 100644 --- a/Raspberry.IO.Components/Sensors/Distance/HcSr04/Units.cs +++ b/Raspberry.IO.Components/Sensors/Distance/HcSr04/Units.cs @@ -1,3 +1,5 @@ +using UnitsNet; + namespace Raspberry.IO.Components.Sensors.Distance.HcSr04 { internal static class Units @@ -19,12 +21,12 @@ public static class Sound /// /// The time, in milliseconds. /// The distance travelled by sound in one second, in meters. - public static decimal ToDistance(decimal time) + public static Length ToDistance(decimal time) { if (time == decimal.MinValue) - return decimal.MinValue; + return Length.FromMeters(double.MinValue); - return (time*340)/1000m; + return Length.FromMeters((double)(time * 340) / 1000); } #endregion diff --git a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085Data.cs b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085Data.cs index c9cfe0d..f02a310 100644 --- a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085Data.cs +++ b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085Data.cs @@ -5,7 +5,7 @@ /// public struct Bmp085Data { - public decimal Temperature; - public decimal Pressure; + public UnitsNet.Temperature Temperature; + public UnitsNet.Pressure Pressure; } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2CConnection.cs b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2CConnection.cs index 151c6d2..17a3e63 100644 --- a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2CConnection.cs +++ b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2CConnection.cs @@ -58,14 +58,27 @@ public Bmp085Precision Precision #region Methods /// - /// Gets the pressure, in pascal. + /// Gets the pressure. /// /// The pressure. - public decimal GetPressure() + public UnitsNet.Pressure GetPressure() { return GetData().Pressure; } + /// + /// Gets the temperature. + /// + /// The temperature. + public UnitsNet.Temperature GetTemperature() + { + // Do not use GetData here since it would imply useless I/O and computation. + var rawTemperature = GetRawTemperature(); + var b5 = ComputeB5(rawTemperature); + + return UnitsNet.Temperature.FromDegreesCelsius((double)((b5 + 8) >> 4) / 10); + } + /// /// Gets the data. /// @@ -104,24 +117,11 @@ public Bmp085Data GetData() return new Bmp085Data { - Pressure = p + ((x1 + x2 + 3791) >> 4), - Temperature = ((b5 + 8) >> 4)/10m + Pressure = UnitsNet.Pressure.FromPascals(p + ((x1 + x2 + 3791) >> 4)), + Temperature = UnitsNet.Temperature.FromDegreesCelsius((double)((b5 + 8) >> 4) / 10) }; } - /// - /// Gets the temperature, in °C. - /// - /// The temperature. - public decimal GetTemperature() - { - // Do not use GetData here since it would imply useless I/O and computation. - var rawTemperature = GetRawTemperature(); - var b5 = ComputeB5(rawTemperature); - - return ((b5 + 8) >> 4)/10m; - } - #endregion #region Private Helpers diff --git a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2cConnectionExtensionMethods.cs b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2cConnectionExtensionMethods.cs index 0ad038d..867275a 100644 --- a/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2cConnectionExtensionMethods.cs +++ b/Raspberry.IO.Components/Sensors/Pressure/Bmp085/Bmp085I2cConnectionExtensionMethods.cs @@ -1,6 +1,7 @@ #region References using System; +using UnitsNet; #endregion @@ -17,24 +18,24 @@ public static class Bmp085I2cConnectionExtensionMethods /// Gets the sea-level pressure. /// /// The BMP085 connection. - /// The current altitude, in meters. - /// The pressure, in hPa. - public static decimal GetSealevelPressure(this Bmp085I2cConnection connection, decimal currentAltitude) + /// The current altitude. + /// The pressure. + public static UnitsNet.Pressure GetSealevelPressure(this Bmp085I2cConnection connection, Length currentAltitude) { var pressure = connection.GetPressure(); - return (decimal) ((double) pressure/Math.Pow(1.0 - (double) currentAltitude/44330, 5.255)); + return UnitsNet.Pressure.FromPascals(pressure.Pascals / Math.Pow(1.0 - currentAltitude.Meters/44330, 5.255)); } /// /// Gets the altitude. /// /// The BMP085 connection. - /// The sealevel pressure, in hPa. - /// The altitude, in meters - public static decimal GetAltitude(this Bmp085I2cConnection connection, decimal sealevelPressure) + /// The sealevel pressure. + /// The altitude + public static Length GetAltitude(this Bmp085I2cConnection connection, UnitsNet.Pressure sealevelPressure) { var pressure = connection.GetPressure(); - return (decimal) (44330*(1.0 - Math.Pow((double) (pressure/sealevelPressure), 0.1903))); + return Length.FromMeters(44330 * (1.0 - Math.Pow(pressure.Pascals / sealevelPressure.Pascals, 1 / 5.255))); } #endregion diff --git a/Raspberry.IO.Components/Sensors/ResistiveDivider.cs b/Raspberry.IO.Components/Sensors/ResistiveDivider.cs index ba93fdf..b4aad9d 100644 --- a/Raspberry.IO.Components/Sensors/ResistiveDivider.cs +++ b/Raspberry.IO.Components/Sensors/ResistiveDivider.cs @@ -1,4 +1,5 @@ using System; +using UnitsNet; namespace Raspberry.IO.Components.Sensors { @@ -11,11 +12,11 @@ public static class ResistiveDivider /// /// The function. /// - public static Func ForUpperResistor(decimal lowerResistorValue) + public static Func ForUpperResistor(ElectricResistance lowerResistorValue) { - return v => v.Relative != 0 - ? lowerResistorValue * (1 - v.Relative) / v.Relative - : decimal.MaxValue; + return v => v.Relative != 0 + ? lowerResistorValue * (double)((1 - v.Relative) / v.Relative) + : ElectricResistance.FromOhms(double.MaxValue); } /// @@ -25,11 +26,11 @@ public static Func ForUpperResistor(decimal lowerResistorV /// /// The function. /// - public static Func ForLowerResistor(decimal upperResistorValue) + public static Func ForLowerResistor(ElectricResistance upperResistorValue) { - return v => v.Relative != 1 - ? upperResistorValue * v.Relative / (1 - v.Relative) - : decimal.MaxValue; + return v => v.Relative != 1 + ? upperResistorValue * (double)(v.Relative / (1 - v.Relative)) + : ElectricResistance.FromOhms(double.MaxValue); } } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs index d21f9ad..55e82a2 100644 --- a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs +++ b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtConnection.cs @@ -3,6 +3,7 @@ using System; using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; +using UnitsNet; #endregion @@ -148,8 +149,8 @@ private DhtData TryGetData() return new DhtData { - Humidity = humidity, - Temperature = temperature + RelativeHumidity = Ratio.FromPercent((double)humidity), + Temperature = UnitsNet.Temperature.FromDegreesCelsius((double)temperature) }; } diff --git a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtData.cs b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtData.cs index a2811f9..be25da4 100644 --- a/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtData.cs +++ b/Raspberry.IO.Components/Sensors/Temperature/Dht/DhtData.cs @@ -2,7 +2,7 @@ namespace Raspberry.IO.Components.Sensors.Temperature.Dht { public class DhtData { - public decimal Temperature; - public decimal Humidity; + public UnitsNet.Temperature Temperature; + public UnitsNet.Ratio RelativeHumidity; } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs b/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs index 8713111..8d7ebeb 100644 --- a/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs +++ b/Raspberry.IO.Components/Sensors/Temperature/Ds18b20/Ds18b20Connection.cs @@ -1,6 +1,7 @@ #region References using System; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -18,9 +19,10 @@ public class Ds18b20Connection : IDisposable { #region Fields - private readonly string _deviceFolder; - private string DeviceFile { get {return _deviceFolder + @"/w1_slave";} } - private const string BaseDir = @"/sys/bus/w1/devices/"; + private const string baseDir = @"/sys/bus/w1/devices/"; + + private readonly string deviceFolder; + private string deviceFile { get {return deviceFolder + @"/w1_slave";} } #endregion @@ -31,49 +33,27 @@ public class Ds18b20Connection : IDisposable /// public Ds18b20Connection(string deviceId) { - _deviceFolder = BaseDir + deviceId; - if (!Directory.Exists(_deviceFolder)) - { + deviceFolder = baseDir + deviceId; + if (!Directory.Exists(deviceFolder)) throw new ArgumentException(string.Format("Sensor with Id {0} not found. {1}", deviceId, ModprobeExceptionMessage), deviceId); - } - - } - - private string ModprobeExceptionMessage - { - get - { - var sb = new StringBuilder(); - sb.AppendLine("Make sure you have loaded the required kernel models."); - sb.AppendFormat("\tmodprobe w1-gpio{0}", Environment.NewLine); - sb.AppendFormat("\tmodprobe w1-therm{0}", Environment.NewLine); - return sb.ToString(); - } } - /// /// Initializes a new instance of the class. /// public Ds18b20Connection(int deviceIndex) { - var deviceFolders = Directory.GetDirectories(BaseDir, "28*").ToList(); + var deviceFolders = Directory.GetDirectories(baseDir, "28*").ToList(); var deviceCount = deviceFolders.Count(); if (deviceCount == 0) - { - throw new InvalidOperationException(string.Format("No sensors were found in {0}. {1}", BaseDir, ModprobeExceptionMessage)); - } + throw new InvalidOperationException(string.Format("No sensors were found in {0}. {1}", baseDir, ModprobeExceptionMessage)); if (deviceCount <= deviceIndex) - { - throw new IndexOutOfRangeException(string.Format("There were only {0} devices found, so index {1} is invalid", deviceCount, deviceIndex )); - } - - _deviceFolder = deviceFolders[deviceIndex]; + throw new IndexOutOfRangeException(string.Format("There were only {0} devices found, so index {1} is invalid", deviceCount, deviceIndex)); + deviceFolder = deviceFolders[deviceIndex]; } - - + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -87,47 +67,48 @@ void IDisposable.Dispose() #region Methods /// - /// Gets the temperature, in Celsius. + /// Gets the temperature. /// - /// The temperature, in Celsius. - public double GetTemperatureCelsius() + /// The temperature. + public UnitsNet.Temperature GetTemperature() { - var lines = File.ReadAllLines(DeviceFile); + var lines = File.ReadAllLines(deviceFile); while (!lines[0].Trim().EndsWith("YES")) { Thread.Sleep(2); - lines = File.ReadAllLines(DeviceFile); + lines = File.ReadAllLines(deviceFile); } - var equalsPos = lines[1].IndexOf("t="); + var equalsPos = lines[1].IndexOf("t=", StringComparison.InvariantCultureIgnoreCase); if (equalsPos == -1) - { - throw new Exception("invalid temp reading"); - } + throw new InvalidOperationException("Unable to read temperature"); var temperatureString = lines[1].Substring(equalsPos + 2); - var tempC = Double.Parse(temperatureString) / 1000.0; - return tempC; - + + return UnitsNet.Temperature.FromDegreesCelsius(double.Parse(temperatureString, CultureInfo.InvariantCulture) / 1000.0); } /// - /// Gets the temperature, in Fahrenheit. + /// Closes this instance. /// - /// The temperature, in Fahrenheit. - public double GetTemperatureFahrenheit() + public void Close() { - var tempC = GetTemperatureCelsius(); - var tempF = tempC * 9.0 / 5.0 + 32.0; - return tempF; } + #endregion - /// - /// Closes this instance. - /// - public void Close() + #region Private Helpers + + private string ModprobeExceptionMessage { + get + { + var sb = new StringBuilder(); + sb.AppendLine("Make sure you have loaded the required kernel models."); + sb.AppendFormat("\tmodprobe w1-gpio{0}", Environment.NewLine); + sb.AppendFormat("\tmodprobe w1-therm{0}", Environment.NewLine); + return sb.ToString(); + } } #endregion diff --git a/Raspberry.IO.Components/Sensors/Temperature/Tmp36/Tmp36Connection.cs b/Raspberry.IO.Components/Sensors/Temperature/Tmp36/Tmp36Connection.cs index d5a0b97..b2ebdd2 100644 --- a/Raspberry.IO.Components/Sensors/Temperature/Tmp36/Tmp36Connection.cs +++ b/Raspberry.IO.Components/Sensors/Temperature/Tmp36/Tmp36Connection.cs @@ -1,6 +1,7 @@ #region References using System; +using UnitsNet; #endregion @@ -15,7 +16,7 @@ public class Tmp36Connection : IDisposable #region Fields private readonly IInputAnalogPin inputPin; - private readonly decimal referenceVoltage; + private readonly ElectricPotential referenceVoltage; #endregion @@ -26,7 +27,7 @@ public class Tmp36Connection : IDisposable /// /// The input pin. /// The reference voltage. - public Tmp36Connection(IInputAnalogPin inputPin, decimal referenceVoltage) + public Tmp36Connection(IInputAnalogPin inputPin, ElectricPotential referenceVoltage) { this.inputPin = inputPin; this.referenceVoltage = referenceVoltage; @@ -45,13 +46,13 @@ void IDisposable.Dispose() #region Methods /// - /// Gets the temperature, in Celsius. + /// Gets the temperature. /// - /// The temperature, in Celsius. - public decimal GetTemperature() + /// The temperature. + public UnitsNet.Temperature GetTemperature() { - var voltage = inputPin.Read().Relative * referenceVoltage; - return voltage*100 - 50; + var voltage = referenceVoltage * (double)inputPin.Read().Relative; + return UnitsNet.Temperature.FromDegreesCelsius(voltage.Volts * 100 - 50); } /// diff --git a/Raspberry.IO.Components/Sensors/VariableResistiveDividerConnection.cs b/Raspberry.IO.Components/Sensors/VariableResistiveDividerConnection.cs index 2f9465b..76cd899 100644 --- a/Raspberry.IO.Components/Sensors/VariableResistiveDividerConnection.cs +++ b/Raspberry.IO.Components/Sensors/VariableResistiveDividerConnection.cs @@ -1,6 +1,7 @@ #region References using System; +using UnitsNet; #endregion @@ -14,7 +15,7 @@ public class VariableResistiveDividerConnection : IDisposable #region Fields private readonly IInputAnalogPin analogPin; - private readonly Func resistorEvalFunc; + private readonly Func resistorEvalFunc; #endregion @@ -26,7 +27,7 @@ public class VariableResistiveDividerConnection : IDisposable /// The analog pin. /// The resistor eval function. /// Methods from should be used. - public VariableResistiveDividerConnection(IInputAnalogPin analogPin, Func resistorEvalFunc) + public VariableResistiveDividerConnection(IInputAnalogPin analogPin, Func resistorEvalFunc) { this.analogPin = analogPin; this.resistorEvalFunc = resistorEvalFunc; @@ -45,10 +46,10 @@ void IDisposable.Dispose() #region Methods /// - /// Gets the resistor, in Ohms. + /// Gets the electric resistance. /// - /// The resistor value. - public decimal GetResistor() + /// The resistance value. + public ElectricResistance GetResistance() { var value = analogPin.Read(); return resistorEvalFunc(value); diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index b127615..3cd21b2 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -3,4 +3,5 @@ + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index ffbf195..b6cf26d 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -3,7 +3,6 @@ using System; using System.IO; using System.Linq; -using System.Security; using System.Threading; using System.Collections.Generic; @@ -11,12 +10,6 @@ namespace Raspberry.IO.GeneralPurpose { - public class FileGpioHandle - { - public string GpioPath { get; set; } - public Stream GpioStream { get; set; } - } - /// /// Represents a connection driver using files. /// @@ -25,7 +18,7 @@ public class FileGpioConnectionDriver : IGpioConnectionDriver #region Fields private const string gpioPath = "/sys/class/gpio"; - private static Dictionary gpioPathList = new Dictionary(); + private static readonly Dictionary gpioPathList = new Dictionary(); #endregion @@ -36,7 +29,7 @@ public class FileGpioConnectionDriver : IGpioConnectionDriver /// public FileGpioConnectionDriver() { - if (System.Environment.OSVersion.Platform != PlatformID.Unix) + if (Environment.OSVersion.Platform != PlatformID.Unix) throw new NotSupportedException("FileGpioConnectionDriver is only supported in Unix"); } @@ -67,7 +60,7 @@ public void Allocate(ProcessorPin pin, PinDirection direction) if (!gpioPathList.ContainsKey(pin)) { - FileGpioHandle gpio = new FileGpioHandle() { GpioPath = GuessGpioPath(pin) }; + var gpio = new FileGpioHandle { GpioPath = GuessGpioPath(pin) }; gpioPathList.Add(pin, gpio); } diff --git a/Raspberry.IO.GeneralPurpose/FileGpioHandle.cs b/Raspberry.IO.GeneralPurpose/FileGpioHandle.cs new file mode 100644 index 0000000..73f32d2 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/FileGpioHandle.cs @@ -0,0 +1,26 @@ +using System.IO; + +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents a handle on a GPIO file + /// + public class FileGpioHandle + { + /// + /// Gets or sets the gpio path. + /// + /// + /// The gpio path. + /// + public string GpioPath { get; set; } + + /// + /// Gets or sets the gpio stream. + /// + /// + /// The gpio stream. + /// + public Stream GpioStream { get; set; } + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 00b44fb..a8f8d6f 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -56,6 +56,7 @@ + diff --git a/Tests/Test.Gpio.DHT11/Program.cs b/Tests/Test.Gpio.DHT11/Program.cs index a5351ce..1ffaa6f 100644 --- a/Tests/Test.Gpio.DHT11/Program.cs +++ b/Tests/Test.Gpio.DHT11/Program.cs @@ -29,7 +29,7 @@ private static void Main() { var data = DhtConnection.GetData(); if (data != null) - Console.WriteLine("{0:0.00}% humidity, {1:0.0}°C", data.Humidity, data.Temperature); + Console.WriteLine("{0:0.00}% humidity, {1:0.0}°C", data.RelativeHumidity.Percent, data.Temperature.DegreesCelsius); else Console.WriteLine("Unable to read data"); diff --git a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj index 6e605d9..555374a 100644 --- a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj +++ b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj @@ -45,6 +45,9 @@ + + ..\..\packages\UnitsNet.3.4.0\lib\net35\UnitsNet.dll + diff --git a/Tests/Test.Gpio.DHT11/packages.config b/Tests/Test.Gpio.DHT11/packages.config index 78864cb..4840151 100644 --- a/Tests/Test.Gpio.DHT11/packages.config +++ b/Tests/Test.Gpio.DHT11/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/Tests/Test.Gpio.HCSR04/Program.cs b/Tests/Test.Gpio.HCSR04/Program.cs index 0860c18..f5c5729 100644 --- a/Tests/Test.Gpio.HCSR04/Program.cs +++ b/Tests/Test.Gpio.HCSR04/Program.cs @@ -38,8 +38,8 @@ private static void Main(string[] args) { try { - var distance = connection.GetDistance(); - Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:0.0}cm", distance * 100).PadRight(16)); + var distance = connection.GetDistance().Centimeters; + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:0.0}cm", distance).PadRight(16)); Console.CursorTop--; } catch (TimeoutException e) diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 852b0db..96b922d 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -64,6 +64,10 @@ + + ..\..\packages\UnitsNet.3.4.0\lib\net35\UnitsNet.dll + True + diff --git a/Tests/Test.Gpio.HCSR04/packages.config b/Tests/Test.Gpio.HCSR04/packages.config index 78864cb..4840151 100644 --- a/Tests/Test.Gpio.HCSR04/packages.config +++ b/Tests/Test.Gpio.HCSR04/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/Tests/Test.Gpio.MCP3008/Convert.cs b/Tests/Test.Gpio.MCP3008/Convert.cs index bb8124e..00d662e 100644 --- a/Tests/Test.Gpio.MCP3008/Convert.cs +++ b/Tests/Test.Gpio.MCP3008/Convert.cs @@ -1,16 +1,18 @@ +using UnitsNet; + namespace Test.Gpio.MCP3008 { internal static class Convert { #region Methods - public static decimal ToLux(this decimal variableResistor) + public static decimal ToLux(this ElectricResistance variableResistor) { // See http://learn.adafruit.com/photocells/using-a-photocell // and http://www.emant.com/316002.page const decimal luxRatio = 500000; - return luxRatio / variableResistor; + return luxRatio / (decimal)variableResistor.Ohms; } #endregion diff --git a/Tests/Test.Gpio.MCP3008/Program.cs b/Tests/Test.Gpio.MCP3008/Program.cs index d079132..cf50362 100644 --- a/Tests/Test.Gpio.MCP3008/Program.cs +++ b/Tests/Test.Gpio.MCP3008/Program.cs @@ -7,6 +7,7 @@ using Raspberry.IO.Components.Sensors.Temperature.Dht; using Raspberry.IO.Components.Sensors.Temperature.Tmp36; using Raspberry.IO.GeneralPurpose; +using UnitsNet; #endregion @@ -33,7 +34,7 @@ static void Main() Console.WriteLine("\tMISO: {0}", adcMiso); Console.WriteLine(); - const decimal voltage = 3.3m; + ElectricPotential voltage = ElectricPotential.FromVolts(3.3); var driver = new MemoryGpioConnectionDriver(); //GpioConnectionSettings.DefaultDriver; @@ -47,17 +48,17 @@ static void Main() voltage)) using (var lightConnection = new VariableResistiveDividerConnection( adcConnection.In(Mcp3008Channel.Channel1), - ResistiveDivider.ForLowerResistor(10000))) + ResistiveDivider.ForLowerResistor(ElectricResistance.FromKiloohms(10)))) { Console.CursorVisible = false; while (!Console.KeyAvailable) { var temperature = temperatureConnection.GetTemperature(); - decimal resistor = lightConnection.GetResistor(); + var resistor = lightConnection.GetResistance(); var lux = resistor.ToLux(); - Console.WriteLine("Temperature = {0,5:0.0} °C\tLight = {1,5:0.0} Lux ({2} ohms)", temperature, lux, (int) resistor); + Console.WriteLine("Temperature = {0,5:0.0} °C\tLight = {1,5:0.0} Lux ({2} ohms)", temperature, lux, (int)resistor.Ohms); Console.CursorTop--; diff --git a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj index 0114dd1..d3390c2 100644 --- a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj +++ b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj @@ -14,6 +14,8 @@ 512 + ..\..\ + true x86 @@ -58,6 +60,10 @@ + + ..\..\packages\UnitsNet.3.4.0\lib\net35\UnitsNet.dll + True + @@ -82,12 +88,20 @@ + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + - + \ No newline at end of file From e5cc3c9ef3067b9cd7a7180face98be7daaffc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 7 Apr 2015 20:39:50 +0200 Subject: [PATCH 207/227] Updated nupkg for v2.3.0 Fixing issue with multiple heads in Nugets --- Raspberry.IO.GeneralPurpose.nuspec | 6 +-- Raspberry.IO.nuspec | 59 ------------------------------ 2 files changed, 2 insertions(+), 63 deletions(-) delete mode 100644 Raspberry.IO.nuspec diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index 3116c10..69486f1 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -11,11 +11,9 @@ https://raw.github.com/raspberry-sharp/raspberry-sharp-io/master/Icon.png true - Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. - - Raspberry.IO.GeneralPurpose is no longer maintained and superseded by Raspberry.IO. + Raspberry.IO is a set of Mono/.NET assembly providing access to Raspberry Pi I/O features. - Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. + Raspberry.IO is a set of Mono/.NET assembly providing access to Raspberry Pi I/O features. en-US Raspberry Pi Mono GPIO diff --git a/Raspberry.IO.nuspec b/Raspberry.IO.nuspec deleted file mode 100644 index cef409b..0000000 --- a/Raspberry.IO.nuspec +++ /dev/null @@ -1,59 +0,0 @@ - - - - Raspberry.IO - 0.0.0 - Raspberry.IO - Eric Bézine - Raspberry-Sharp - http://opensource.org/licenses/GPL-2.0 - https://github.com/raspberry-sharp/raspberry-sharp-io/wiki/Raspberry.IO - https://raw.github.com/raspberry-sharp/raspberry-sharp-io/master/Icon.png - true - - Raspberry.IO is a Mono/.NET assembly providing access to Raspberry Pi I/O features. - - It is an initiative of the Raspberry# Community, aimed at providing tools and information concerning use of Raspberry Pi boards with Mono/.NET framework. - Parts of Raspberry# IO are inspired by BCM2835 C Library (http://www.airspayce.com/mikem/bcm2835/) and Gordon Henderson's WiringPi (http://wiringpi.com/). - - Visit the project Github site (https://github.com/raspberry-sharp/raspberry-sharp-io/) for documentation and samples. - Raspberry.IO supersedes and extends Raspberry.IO.GeneralPurpose with support for SPI and I2C. - - Raspberry.IO is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. - en-US - Raspberry Pi IO Mono GPIO SPI I2C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From e4142020ecc1cb00c5134db7be4dd155a094eafa Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 20 Apr 2015 19:49:45 +0200 Subject: [PATCH 208/227] Added support for repeated start conditions. --- .../I2cAction.cs | 19 ++ .../I2cDeviceConnection.cs | 25 ++- .../I2cDriver.cs | 190 ++++++++++-------- .../I2cReadAction.cs | 17 ++ .../I2cTransaction.cs | 29 +++ .../I2cWriteAction.cs | 17 ++ ...Raspberry.IO.InterIntegratedCircuit.csproj | 4 + 7 files changed, 213 insertions(+), 88 deletions(-) create mode 100644 Raspberry.IO.InterIntegratedCircuit/I2cAction.cs create mode 100644 Raspberry.IO.InterIntegratedCircuit/I2cReadAction.cs create mode 100644 Raspberry.IO.InterIntegratedCircuit/I2cTransaction.cs create mode 100644 Raspberry.IO.InterIntegratedCircuit/I2cWriteAction.cs diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cAction.cs b/Raspberry.IO.InterIntegratedCircuit/I2cAction.cs new file mode 100644 index 0000000..51feb65 --- /dev/null +++ b/Raspberry.IO.InterIntegratedCircuit/I2cAction.cs @@ -0,0 +1,19 @@ +namespace Raspberry.IO.InterIntegratedCircuit +{ + using System; + + public abstract class I2cAction + { + protected I2cAction(byte[] buffer) + { + if (buffer == null) + { + throw new ArgumentNullException("buffer"); + } + + Buffer = buffer; + } + + public byte[] Buffer { get; private set; } + } +} diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDeviceConnection.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDeviceConnection.cs index 18829e7..6c84178 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDeviceConnection.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDeviceConnection.cs @@ -1,5 +1,7 @@ namespace Raspberry.IO.InterIntegratedCircuit { + using System; + /// /// Represents a connection to the I2C device. /// @@ -39,6 +41,20 @@ public int DeviceAddress #endregion #region Methods + + /// + /// Executes the specified transaction. + /// + /// The transaction. + public void Execute(I2cTransaction transaction) + { + if (transaction == null) + { + throw new ArgumentNullException("transaction"); + } + + driver.Execute(deviceAddress, transaction); + } /// /// Writes the specified buffer. @@ -46,7 +62,7 @@ public int DeviceAddress /// The buffer. public void Write(params byte[] buffer) { - driver.Write(deviceAddress, buffer); + Execute(new I2cTransaction(new I2cWriteAction(buffer))); } /// @@ -55,7 +71,7 @@ public void Write(params byte[] buffer) /// The value. public void WriteByte(byte value) { - Write(value); + Execute(new I2cTransaction(new I2cWriteAction(value))); } /// @@ -65,7 +81,10 @@ public void WriteByte(byte value) /// The buffer. public byte[] Read(int byteCount) { - return driver.Read(deviceAddress, byteCount); + var readAction = new I2cReadAction(new byte[byteCount]); + Execute(new I2cTransaction(readAction)); + + return readAction.Buffer; } /// diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs index 737a897..44fd7cf 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs @@ -142,129 +142,149 @@ public I2cDeviceConnection Connect(int deviceAddress) #region Internal Methods - internal void Write(int deviceAddress, byte[] buffer) + /// + /// Executes the specified transaction. + /// + /// The address of the device. + /// The transaction. + internal void Execute(int deviceAddress, I2cTransaction transaction) { lock (driverLock) { - EnsureDeviceAddress(deviceAddress); + var control = bscAddress + (int)Interop.BCM2835_BSC_C; + + foreach (I2cAction action in transaction.Actions) + { + if (action is I2cWriteAction) + { + Write(deviceAddress, action.Buffer); + } + else if (action is I2cReadAction) + { + Read(deviceAddress, action.Buffer); + } + else + { + throw new InvalidOperationException("Only read and write transactions are allowed."); + } + } + + WriteUInt32Mask(control, Interop.BCM2835_BSC_S_DONE, Interop.BCM2835_BSC_S_DONE); + } + } + + #endregion - var len = (uint) buffer.Length; + #region Private Helpers + + private void Write(int deviceAddress, byte[] buffer) + { + this.EnsureDeviceAddress(deviceAddress); - var dlen = bscAddress + (int) Interop.BCM2835_BSC_DLEN; - var fifo = bscAddress + (int) Interop.BCM2835_BSC_FIFO; - var status = bscAddress + (int) Interop.BCM2835_BSC_S; - var control = bscAddress + (int) Interop.BCM2835_BSC_C; + var len = (uint)buffer.Length; - var remaining = len; - var i = 0; + var dlen = this.bscAddress + (int)Interop.BCM2835_BSC_DLEN; + var fifo = this.bscAddress + (int)Interop.BCM2835_BSC_FIFO; + var status = this.bscAddress + (int)Interop.BCM2835_BSC_S; + var control = this.bscAddress + (int)Interop.BCM2835_BSC_C; - // Clear FIFO - WriteUInt32Mask(control, Interop.BCM2835_BSC_C_CLEAR_1, Interop.BCM2835_BSC_C_CLEAR_1); + var remaining = len; + var i = 0; - // Clear Status - WriteUInt32(status, Interop.BCM2835_BSC_S_CLKT | Interop.BCM2835_BSC_S_ERR | Interop.BCM2835_BSC_S_DONE); + // Clear FIFO + WriteUInt32Mask(control, Interop.BCM2835_BSC_C_CLEAR_1, Interop.BCM2835_BSC_C_CLEAR_1); - // Set Data Length - WriteUInt32(dlen, len); + // Clear Status + WriteUInt32(status, Interop.BCM2835_BSC_S_CLKT | Interop.BCM2835_BSC_S_ERR | Interop.BCM2835_BSC_S_DONE); - while (remaining != 0 && i < Interop.BCM2835_BSC_FIFO_SIZE) + // Set Data Length + WriteUInt32(dlen, len); + + while (remaining != 0 && i < Interop.BCM2835_BSC_FIFO_SIZE) + { + WriteUInt32(fifo, buffer[i]); + i++; + remaining--; + } + + // Enable device and start transfer + WriteUInt32(control, Interop.BCM2835_BSC_C_I2CEN | Interop.BCM2835_BSC_C_ST); + + while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_DONE) == 0) + { + while (remaining != 0 && (ReadUInt32(status) & Interop.BCM2835_BSC_S_TXD) != 0) { + // Write to FIFO, no barrier WriteUInt32(fifo, buffer[i]); i++; remaining--; } - // Enable device and start transfer - WriteUInt32(control, Interop.BCM2835_BSC_C_I2CEN | Interop.BCM2835_BSC_C_ST); - - while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_DONE) == 0) - { - while (remaining != 0 && (ReadUInt32(status) & Interop.BCM2835_BSC_S_TXD) != 0) - { - // Write to FIFO, no barrier - WriteUInt32(fifo, buffer[i]); - i++; - remaining--; - } + this.Wait(remaining); + } - Wait(remaining); - } + if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); + if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); + if (remaining != 0) // Not all data is sent + throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); - if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK - throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); - if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout - throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); - if (remaining != 0) // Not all data is sent - throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); - - WriteUInt32Mask(control, Interop.BCM2835_BSC_S_DONE, Interop.BCM2835_BSC_S_DONE); - } } - internal byte[] Read(int deviceAddress, int byteCount) + private void Read(int deviceAddress, byte[] buffer) { - lock (driverLock) - { - EnsureDeviceAddress(deviceAddress); + this.EnsureDeviceAddress(deviceAddress); - var dlen = bscAddress + (int) Interop.BCM2835_BSC_DLEN; - var fifo = bscAddress + (int) Interop.BCM2835_BSC_FIFO; - var status = bscAddress + (int) Interop.BCM2835_BSC_S; - var control = bscAddress + (int) Interop.BCM2835_BSC_C; + var dlen = this.bscAddress + (int)Interop.BCM2835_BSC_DLEN; + var fifo = this.bscAddress + (int)Interop.BCM2835_BSC_FIFO; + var status = this.bscAddress + (int)Interop.BCM2835_BSC_S; + var control = this.bscAddress + (int)Interop.BCM2835_BSC_C; - var remaining = (uint) byteCount; - uint i = 0; + var remaining = (uint)buffer.Length; + uint i = 0; - // Clear FIFO - WriteUInt32Mask(control, Interop.BCM2835_BSC_C_CLEAR_1, Interop.BCM2835_BSC_C_CLEAR_1); + // Clear FIFO + WriteUInt32Mask(control, Interop.BCM2835_BSC_C_CLEAR_1, Interop.BCM2835_BSC_C_CLEAR_1); - // Clear Status - WriteUInt32(status, Interop.BCM2835_BSC_S_CLKT | Interop.BCM2835_BSC_S_ERR | Interop.BCM2835_BSC_S_DONE); + // Clear Status + WriteUInt32(status, Interop.BCM2835_BSC_S_CLKT | Interop.BCM2835_BSC_S_ERR | Interop.BCM2835_BSC_S_DONE); - // Set Data Length - WriteUInt32(dlen, (uint) byteCount); + // Set Data Length + WriteUInt32(dlen, (uint)buffer.Length); - // Start read - WriteUInt32(control, Interop.BCM2835_BSC_C_I2CEN | Interop.BCM2835_BSC_C_ST | Interop.BCM2835_BSC_C_READ); + // Start read + WriteUInt32(control, Interop.BCM2835_BSC_C_I2CEN | Interop.BCM2835_BSC_C_ST | Interop.BCM2835_BSC_C_READ); - var buffer = new byte[byteCount]; - while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_DONE) == 0) + while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_DONE) == 0) + { + while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_RXD) != 0) { - while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_RXD) != 0) - { - // Read from FIFO, no barrier - buffer[i] = (byte) ReadUInt32(fifo); + // Read from FIFO, no barrier + buffer[i] = (byte)ReadUInt32(fifo); - i++; - remaining--; - } - - Wait(remaining); - } - - while (remaining != 0 && (ReadUInt32(status) & Interop.BCM2835_BSC_S_RXD) != 0) - { - buffer[i] = (byte) ReadUInt32(fifo); i++; remaining--; } - if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK - throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); - if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout - throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); - if (remaining != 0) // Not all data is received - throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); - - WriteUInt32Mask(control, Interop.BCM2835_BSC_S_DONE, Interop.BCM2835_BSC_S_DONE); + this.Wait(remaining); + } - return buffer; + while (remaining != 0 && (ReadUInt32(status) & Interop.BCM2835_BSC_S_RXD) != 0) + { + buffer[i] = (byte)ReadUInt32(fifo); + i++; + remaining--; } - } - #endregion + if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); + if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); + if (remaining != 0) // Not all data is received + throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); - #region Private Helpers + } private static uint GetProcessorBscAddress(Processor processor) { diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cReadAction.cs b/Raspberry.IO.InterIntegratedCircuit/I2cReadAction.cs new file mode 100644 index 0000000..aea7b2f --- /dev/null +++ b/Raspberry.IO.InterIntegratedCircuit/I2cReadAction.cs @@ -0,0 +1,17 @@ +namespace Raspberry.IO.InterIntegratedCircuit +{ + /// + /// Defines an I2C read action. + /// + public class I2cReadAction : I2cAction + { + /// + /// Initializes a new instance of the class. + /// + /// The buffer which should be used to store the received data. + public I2cReadAction(params byte[] buffer) + : base(buffer) + { + } + } +} diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cTransaction.cs b/Raspberry.IO.InterIntegratedCircuit/I2cTransaction.cs new file mode 100644 index 0000000..58d46a9 --- /dev/null +++ b/Raspberry.IO.InterIntegratedCircuit/I2cTransaction.cs @@ -0,0 +1,29 @@ +namespace Raspberry.IO.InterIntegratedCircuit +{ + using System; + + /// + /// Defines an I2C data transaction. + /// + public class I2cTransaction + { + /// + /// Initializes a new instance of the class. + /// + /// The actions which should be performed within the transaction. + public I2cTransaction(params I2cAction[] actions) + { + if (actions == null) + { + throw new ArgumentNullException("actions"); + } + + Actions = actions; + } + + /// + /// Gets the actions. + /// + public I2cAction[] Actions { get; private set; } + } +} diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cWriteAction.cs b/Raspberry.IO.InterIntegratedCircuit/I2cWriteAction.cs new file mode 100644 index 0000000..c273a40 --- /dev/null +++ b/Raspberry.IO.InterIntegratedCircuit/I2cWriteAction.cs @@ -0,0 +1,17 @@ +namespace Raspberry.IO.InterIntegratedCircuit +{ + /// + /// Defines an I2C write action. + /// + public class I2cWriteAction : I2cAction + { + /// + /// Initializes a new instance of the class. + /// + /// The buffer with data which should be written. + public I2cWriteAction(params byte[] buffer) + : base(buffer) + { + } + } +} diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index 9976c6b..5981014 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -50,8 +50,12 @@ Properties\SharedAssemblyInfo.cs + + + + From 1e3d350ebcfdb37aeb6f7b4299cb424e1a43af63 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sun, 17 May 2015 16:49:11 +0200 Subject: [PATCH 209/227] Add support for Sda5708 displays. --- .../Displays/Sda5708/Sda5708Brightness.cs | 17 + .../Displays/Sda5708/Sda5708Connection.cs | 120 +++ .../Displays/Sda5708/Sda5708Font.cs | 825 ++++++++++++++++++ .../Raspberry.IO.Components.csproj | 3 + 4 files changed, 965 insertions(+) create mode 100644 Raspberry.IO.Components/Displays/Sda5708/Sda5708Brightness.cs create mode 100644 Raspberry.IO.Components/Displays/Sda5708/Sda5708Connection.cs create mode 100644 Raspberry.IO.Components/Displays/Sda5708/Sda5708Font.cs diff --git a/Raspberry.IO.Components/Displays/Sda5708/Sda5708Brightness.cs b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Brightness.cs new file mode 100644 index 0000000..8dbc18c --- /dev/null +++ b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Brightness.cs @@ -0,0 +1,17 @@ +using System; + +namespace Raspberry.IO.Components.Displays.Sda5708 +{ + public enum Sda5708Brightness + { + Level100 = 0, + Level53 = 1, + Level40 = 2, + Level27 = 3, + Level20 = 4, + Level13 = 5, + Level6_6 = 6, + Level0 = 7 + } +} + diff --git a/Raspberry.IO.Components/Displays/Sda5708/Sda5708Connection.cs b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Connection.cs new file mode 100644 index 0000000..d8cc142 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Connection.cs @@ -0,0 +1,120 @@ +/* Sda5708Connection + * Parts of this code are ported from https://github.com/pimium/sda5708 + * which in turn used the information from http://www.sbprojects.com/knowledge/footprints/sda5708.php. + * The font is taken from http://sunge.awardspace.com/glcd-sd/node4.html + * with additional german characters added. */ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Threading; +using Raspberry.IO; +using Raspberry.IO.GeneralPurpose; +using System.Collections.Generic; + +namespace Raspberry.IO.Components.Displays.Sda5708 +{ + public sealed class Sda5708Connection : IDisposable + { + private Sda5708Brightness _brightness = Sda5708Brightness.Level100; + + private readonly ProcessorPin _load; + private readonly ProcessorPin _data; + private readonly ProcessorPin _sdclk; + private readonly ProcessorPin _reset; + private readonly GpioConnection _baseConnection; + + public Sda5708Connection () : this( + ProcessorPin.Pin7, + ProcessorPin.Pin8, + ProcessorPin.Pin18, + ProcessorPin.Pin23) + { + } + + public Sda5708Connection (ProcessorPin load, ProcessorPin data, ProcessorPin sdclk, ProcessorPin reset) + { + this._load = load; + this._data = data; + this._sdclk = sdclk; + this._reset = reset; + + this._baseConnection = new GpioConnection ( + load.Output (), + data.Output (), + sdclk.Output (), + reset.Output ()); + + this._baseConnection [reset] = false; + this._baseConnection [reset] = false; + Thread.Sleep (50); + this._baseConnection [reset] = true; + + this.Clear(); + } + + public void SetBrightness(Sda5708Brightness brightness) + { + this._brightness = brightness; + this.Write(0xe0 | (int)brightness); + } + + public void Clear() + { + this.Write(0xc0 | (int)this._brightness); + } + + public void WriteString(string str) + { + var chars = str + .PadRight (8, ' ') + .Substring (0, 8); + + for(var i = 0; i < chars.Length; i++) + { + this.WriteChar (i, chars [i]); + } + } + + private void WriteChar(int position, char value) + { + this.Write(0xa0 + position); + + string[] pattern; + if (!Sda5708Font.Patterns.TryGetValue(value, out pattern)) + pattern = Sda5708Font.Patterns['?']; + + for(var i = 0; i < 7; i++) + { + this.Write (Convert.ToInt32 (pattern[i].Replace (' ', '0'), 2)); + } + } + + private void Write(int value) + { + this._baseConnection [this._sdclk] = false; + this._baseConnection [this._load] = false; + + for(var i = 8; i > 0; i--) + { + this._baseConnection[this._data] = (value & 0x1) == 0x1; + + this._baseConnection [this._sdclk] = true; + this._baseConnection [this._sdclk] = false; + + value = value >> 1; + } + + this._baseConnection [this._sdclk] = false; + this._baseConnection [this._load] = true; + } + + #region IDisposable implementation + public void Dispose () + { + this._baseConnection [this._reset] = false; + ((IDisposable)this._baseConnection).Dispose (); + } + #endregion + } +} diff --git a/Raspberry.IO.Components/Displays/Sda5708/Sda5708Font.cs b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Font.cs new file mode 100644 index 0000000..67444c5 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Sda5708/Sda5708Font.cs @@ -0,0 +1,825 @@ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Threading; +using Raspberry.IO; +using Raspberry.IO.GeneralPurpose; +using System.Collections.Generic; + +namespace Raspberry.IO.Components.Displays.Sda5708 +{ + public sealed class Sda5708Font + { + public static readonly Dictionary Patterns = new Dictionary + { + { ' ', new[]{ " ", + " ", + " ", + " ", + " ", + " ", + " " }}, + + { '!', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " ", + " 1 " }}, + + { '"', new[]{ " 1 1 ", + " 1 1 ", + " 1 1 ", + " ", + " ", + " ", + " " }}, + + { '#', new[]{ " 1 1 ", + " 1 1 ", + "11111", + " 1 1 ", + "11111", + " 1 1 ", + " 1 1 " }}, + + { '$', new[]{ " 1 ", + " 1111", + "1 1 ", + " 111 ", + " 1 1", + "1111 ", + " 1 " }}, + + { '%', new[]{ "11 ", + "11 1", + " 1 ", + " 1 ", + " 1 ", + "1 11", + " 11" }}, + + { '&', new[]{ " 11 ", + "1 1 ", + "1 1 ", + " 1 ", + "1 1 1", + "1 1 ", + " 11 1" }}, + + { '\'', new[]{ " 11 ", + " 1 ", + " 1 ", + " ", + " ", + " ", + " " }}, + + { '(', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { ')', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { '*', new[]{ " ", + " 1 1 ", + " 1 ", + "11111", + " 1 ", + " 1 1 ", + " " }}, + + { '+', new[]{ " ", + " 1 ", + " 1 ", + "11111", + " 1 ", + " 1 ", + " " }}, + + { ',', new[]{ " ", + " ", + " ", + " ", + " 11 ", + " 1 ", + " 1 " }}, + + { '-', new[]{ " ", + " ", + " ", + "11111", + " ", + " ", + " " }}, + + { '.', new[]{ " ", + " ", + " ", + " ", + " ", + " 11 ", + " 11 " }}, + + { '/', new[]{ " ", + " 1", + " 1 ", + " 1 ", + " 1 ", + "1 ", + " " }}, + + { '0', new[]{ " 111 ", + "1 1", + "1 11", + "1 1 1", + "11 1", + "1 1", + " 111 " }}, + + { '1', new[]{ " 1 ", + " 11 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 111 " }}, + + { '2', new[]{ " 111 ", + "1 1", + " 1", + " 1 ", + " 1 ", + " 1 ", + "11111" }}, + + { '3', new[]{ "11111", + " 1 ", + " 1 ", + " 1 ", + " 1", + "1 1", + " 111 " }}, + + { '4', new[]{ " 1 ", + " 11 ", + " 1 1 ", + "1 1 ", + "11111", + " 1 ", + " 1 " }}, + + { '5', new[]{ "11111", + "1 ", + "1111 ", + " 1", + " 1", + "1 1", + " 111 " }}, + + { '6', new[]{ " 11 ", + " 1 ", + "1 ", + "1111 ", + "1 1", + "1 1", + " 111 " }}, + + { '7', new[]{ "11111", + " 1", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { '8', new[]{ " 111 ", + "1 1", + "1 1", + " 111 ", + "1 1", + "1 1", + " 111 " }}, + + { '9', new[]{ " 111 ", + "1 1", + "1 1", + " 1111", + " 1", + " 1 ", + " 11 " }}, + + { ':', new[]{ " ", + " 11 ", + " 11 ", + " ", + " 11 ", + " 11 ", + " " }}, + + { ';', new[]{ " ", + " 11 ", + " 11 ", + " ", + " 11 ", + " 1 ", + " 1 " }}, + + { '<', new[]{ " 1", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1" }}, + + { '=', new[]{ " ", + " ", + "11111", + " ", + "11111", + " ", + " " }}, + + { '>', new[]{ "1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + "1 " }}, + + { '?', new[]{ " 111 ", + "1 1", + " 1", + " 1 ", + " 1 ", + " ", + " 1 " }}, + + { '@', new[]{ " 111 ", + "1 1", + " 1", + " 11 1", + "1 1 1", + "1 1 1", + " 111 " }}, + + { 'A', new[]{ " 111 ", + "1 1", + "1 1", + "1 1", + "11111", + "1 1", + "1 1" }}, + + { 'Ä', new[]{ "1 1", + " ", + " 111 ", + "1 1", + "11111", + "1 1", + "1 1" }}, + + { 'B', new[]{ "1111 ", + "1 1", + "1 1", + "1111 ", + "1 1", + "1 1", + "1111 " }}, + + { 'C', new[]{ " 111 ", + "1 1", + "1 ", + "1 ", + "1 ", + "1 1", + " 111 " }}, + + { 'D', new[]{ "111 ", + "1 1 ", + "1 1", + "1 1", + "1 1", + "1 1 ", + "111 " }}, + + { 'E', new[]{ "11111", + "1 ", + "1 ", + "1111 ", + "1 ", + "1 ", + "11111" }}, + + { 'F', new[]{ "11111", + "1 ", + "1 ", + "111 ", + "1 ", + "1 ", + "1 " }}, + + { 'G', new[]{ " 111 ", + "1 1", + "1 ", + "1 ", + "1 11", + "1 1", + " 111 " }}, + + { 'H', new[]{ "1 1", + "1 1", + "1 1", + "11111", + "1 1", + "1 1", + "1 1" }}, + + { 'I', new[]{ " 111 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 111 " }}, + + { 'J', new[]{ " 111", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + "1 1 ", + " 11 " }}, + + { 'K', new[]{ "1 1", + "1 1 ", + "1 1 ", + "11 ", + "1 1 ", + "1 1 ", + "1 1" }}, + + { 'L', new[]{ "1 ", + "1 ", + "1 ", + "1 ", + "1 ", + "1 ", + "11111" }}, + + { 'M', new[]{ "1 1", + "11 11", + "1 1 1", + "1 1", + "1 1", + "1 1", + "1 1" }}, + + { 'N', new[]{ "1 1", + "1 1", + "11 1", + "1 1 1", + "1 11", + "1 1", + "1 1" }}, + + { 'O', new[]{ " 111 ", + "1 1", + "1 1", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'Ö', new[]{ "1 1", + " ", + " 111 ", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'P', new[]{ "1111 ", + "1 1", + "1 1", + "1111 ", + "1 ", + "1 ", + "1 " }}, + + { 'Q', new[]{ " 111 ", + "1 1", + "1 1", + "1 1", + "1 1 1", + "1 1 ", + " 11 1" }}, + + { 'R', new[]{ "1111 ", + "1 1", + "1 1", + "1111 ", + "1 1 ", + "1 1 ", + "1 1" }}, + + { 'S', new[]{ " 1111", + "1 ", + "1 ", + " 111 ", + " 1", + " 1", + "1111 " }}, + + { 'T', new[]{ "11111", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { 'U', new[]{ "1 1", + "1 1", + "1 1", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'Ü', new[]{ "1 1", + " ", + "1 1", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'V', new[]{ "1 1", + "1 1", + "1 1", + "1 1", + "1 1", + " 1 1 ", + " 1 " }}, + + { 'W', new[]{ "1 1", + "1 1", + "1 1", + "1 1 1", + "1 1 1", + "11 11", + "1 1" }}, + + { 'X', new[]{ "1 1", + "1 1", + " 1 1 ", + " 1 ", + " 1 1 ", + "1 1", + "1 1" }}, + + { 'Y', new[]{ "1 1", + "1 1", + " 1 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { 'Z', new[]{ "11111", + " 1", + " 1 ", + " 1 ", + " 1 ", + "1 ", + "11111" }}, + + { '[', new[]{ " 111", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 111" }}, + + { '\\', new[]{ " ", + "1 ", + " 1 ", + " 1 ", + " 1 ", + " 1", + " " }}, + + { ']', new[]{ "111 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + "111 " }}, + + { '^', new[]{ " 1 ", + " 1 1 ", + "1 1", + " ", + " ", + " ", + " " }}, + + { '_', new[]{ " ", + " ", + " ", + " ", + " ", + " ", + "11111" }}, + + { '`', new[]{ " 1 ", + " 1 ", + " 1 ", + " ", + " ", + " ", + " " }}, + + { 'a', new[]{ " ", + " ", + " 111 ", + " 1", + " 1111", + "1 1", + " 1111" }}, + + { 'ä', new[]{ " 1 1 ", + " ", + " 111 ", + " 1", + " 1111", + "1 1", + " 1111" }}, + + { 'b', new[]{ "1 ", + "1 ", + "1 11 ", + "11 1", + "1 1", + "1 1", + "1111 " }}, + + { 'c', new[]{ " ", + " ", + " 111 ", + "1 ", + "1 ", + "1 1", + " 111 " }}, + + { 'd', new[]{ " 1", + " 1", + " 11 1", + "1 11", + "1 1", + "1 1", + " 1111" }}, + + { 'e', new[]{ " ", + " ", + " 111 ", + "1 1", + "11111", + "1 ", + " 111 " }}, + + { 'f', new[]{ " 11 ", + " 1 1", + " 1 ", + "111 ", + " 1 ", + " 1 ", + " 1 " }}, + + { 'g', new[]{ " ", + " ", + " 1111", + "1 1", + " 1111", + " 1", + " 11 " }}, + + { 'h', new[]{ "1 ", + "1 ", + "1 11 ", + "11 1", + "1 1", + "1 1", + "1 1" }}, + + { 'i', new[]{ " 1 ", + " ", + " 11 ", + " 1 ", + " 1 ", + " 1 ", + " 111 " }}, + + { 'j', new[]{ " 1 ", + " ", + " 11 ", + " 1 ", + " 1 ", + "1 1 ", + " 11 " }}, + + { 'k', new[]{ " 1 ", + " 1 ", + " 1 1", + " 1 1 ", + " 11 ", + " 1 1 ", + " 1 1" }}, + + { 'l', new[]{ " 11 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 111 " }}, + + { 'm', new[]{ " ", + " ", + "11 1 ", + "1 1 1", + "1 1 1", + "1 1", + "1 1" }}, + + { 'n', new[]{ " ", + " ", + "1 11 ", + "11 1", + "1 1", + "1 1", + "1 1" }}, + + { 'o', new[]{ " ", + " ", + " 111 ", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'ö', new[]{ " 1 1 ", + " ", + " 111 ", + "1 1", + "1 1", + "1 1", + " 111 " }}, + + { 'p', new[]{ " ", + " ", + "1111 ", + "1 1", + "1111 ", + "1 ", + "1 " }}, + + { 'q', new[]{ " ", + " ", + " 11 1", + "1 11", + " 1111", + " 1", + " 1" }}, + + { 'r', new[]{ " ", + " ", + "1 11 ", + "11 1", + "1 ", + "1 ", + "1 " }}, + + { 's', new[]{ " ", + " ", + " 111 ", + "1 ", + " 111 ", + " 1", + "1111 " }}, + + { 't', new[]{ " 1 ", + " 1 ", + "111 ", + " 1 ", + " 1 ", + " 1 1", + " 11 " }}, + + { 'u', new[]{ " ", + " ", + "1 1", + "1 1", + "1 1", + "1 11", + " 11 1" }}, + + { 'ü', new[]{ " 1 1 ", + " ", + "1 1", + "1 1", + "1 1", + "1 11", + " 11 1" }}, + + { 'v', new[]{ " ", + " ", + "1 1", + "1 1", + "1 1", + " 1 1 ", + " 1 " }}, + + { 'w', new[]{ " ", + " ", + "1 1", + "1 1", + "1 1 1", + "1 1 1", + " 1 1 " }}, + + { 'x', new[]{ " ", + " ", + "1 1", + " 1 1 ", + " 1 ", + " 1 1 ", + "1 1" }}, + + { 'y', new[]{ " ", + " ", + "1 1", + "1 1", + " 1111", + " 1", + " 111 " }}, + + { 'z', new[]{ " ", + " ", + "11111", + " 1 ", + " 1 ", + " 1 ", + "11111" }}, + + { 'ß', new[]{ " 11 ", + "1 1 ", + "111 ", + "1 1 ", + "1 1 ", + "111 ", + "1 " }}, + + { '{', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { '|', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + + { '}', new[]{ " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 ", + " 1 " }}, + }; + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 7ca78e4..b831c74 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -150,6 +150,9 @@ + + + From 973d331d0931b5af0d5cd804a18aabbb3c2fb019 Mon Sep 17 00:00:00 2001 From: jyksnw Date: Tue, 2 Jun 2015 10:43:43 -0400 Subject: [PATCH 210/227] Added support for 4 row Hd44780 displays. --- .../Displays/Hd44780/Hd44780LcdConnection.cs | 85 +++++++++++++++++-- 1 file changed, 76 insertions(+), 9 deletions(-) diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs index f05145d..9cc67a5 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs @@ -14,11 +14,16 @@ namespace Raspberry.IO.Components.Displays.Hd44780 /// and http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf /// and http://www.quinapalus.com/hd44780udg.html /// and http://robo.fe.uni-lj.si/~kamnikr/sola/urac/vaja3_display/How%20to%20control%20HD44780%20display.pdf + /// and http://web.stanford.edu/class/ee281/handouts/lcd_tutorial.pdf + /// and http://www.systronix.com/access/Systronix_20x4_lcd_brief_data.pdf /// public class Hd44780LcdConnection : IDisposable { #region Fields + private const int MAX_HEIGHT = 4; // Allow for larger displays + private const int MAX_CHAR = 80; // This allows for setups such as 40x2 or a 20x4 + private readonly Hd44780Pins pins; private readonly int width; @@ -64,7 +69,7 @@ public class Hd44780LcdConnection : IDisposable /// /// dataPins;There must be either 4 or 8 data pins /// or - /// settings;ScreenHeight must be either 1 or 2 rows + /// settings;ScreenHeight must be between 1 and 4 rows /// or /// settings;PatternWidth must be 5 pixels /// or @@ -85,17 +90,17 @@ public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, Hd44780Pins p width = settings.ScreenWidth; height = settings.ScreenHeight; - if (height < 1 || height > 2) - throw new ArgumentOutOfRangeException("settings", height, "ScreenHeight must be either 1 or 2 rows"); - if (width * height > 80) + if (height < 1 || height > MAX_HEIGHT) + throw new ArgumentOutOfRangeException("settings", height, "ScreenHeight must be between 1 and 4 rows"); + if (width * height > MAX_CHAR) throw new ArgumentException("At most 80 characters are allowed"); if (settings.PatternWidth != 5) throw new ArgumentOutOfRangeException("settings", settings.PatternWidth, "PatternWidth must be 5 pixels"); if (settings.PatternHeight != 8 && settings.PatternHeight != 10) throw new ArgumentOutOfRangeException("settings", settings.PatternWidth, "PatternWidth must be either 7 or 10 pixels height"); - if (settings.PatternHeight == 10 && height == 2) - throw new ArgumentException("10 pixels height pattern cannot be used with 2 rows"); + if (settings.PatternHeight == 10 && (height % 2) == 0) + throw new ArgumentException("10 pixels height pattern cannot be used with an even number of rows"); functions = (settings.PatternHeight == 8 ? Functions.Matrix5x8 : Functions.Matrix5x10) | (height == 1 ? Functions.OneLine : Functions.TwoLines) @@ -264,6 +269,43 @@ public void Move(int offset) WriteCommand(Command.MoveCursor, (int)(CursorShiftFlags.DisplayMove | (offset < 0 ? CursorShiftFlags.MoveLeft : CursorShiftFlags.MoveRight))); } + /// + /// Moves the cursor to the designated row + /// + /// Zero based row position + public void MoveToRow(int row) + { + if (row < 0 || height <= row) + row = height - 1; + + var rowAddress = GetLcdAddressLocation(row); + + currentRow = row; + currentColumn = 0; + WriteByte(rowAddress, false); + } + + /// + /// Moves the cursor to the specified row and column + /// + /// Zero based row position + /// Zero based column position + public void GotoXY(int row, int column) + { + if (row < 0 || height <= row) + row = height - 1; + + if (column < 0 || width <= column) + column = width - 1; + + var address = column + GetLcdAddressLocation(row); + + WriteByte(address, false); + + currentRow = row; + currentColumn = column; + } + /// /// Sets the custom character. /// @@ -356,7 +398,7 @@ public void Write(string format, TimeSpan animationDelay, params object[] values /// The animation delay. public void Write(string text, TimeSpan animationDelay = new TimeSpan()) { - var lines = text.Split(new[] {Environment.NewLine}, StringSplitOptions.None); + var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (var line in lines) { @@ -376,14 +418,19 @@ public void Write(string format, TimeSpan animationDelay, params object[] values currentColumn++; } - if (currentRow == 0 && height > 1) + if ((currentRow == 0 || (currentRow + 1) % height != 0) && height > 1) { - WriteByte(0xC0, false); + int addressLocation = GetLcdAddressLocation(currentRow + 1); + + WriteByte(addressLocation, false); currentColumn = 0; currentRow++; } else + { + Home(); // This was added to return home when the maximum number of row's has been achieved. break; + } } } @@ -450,6 +497,26 @@ private void WriteByte4Pins(int bits, bool charMode) Synchronize(); } + /// + /// Returns the Lcd Address for the given row + /// + /// A zero based row position + /// The Lcd Address as an int + /// http://www.mikroe.com/forum/viewtopic.php?t=5149 + private int GetLcdAddressLocation(int row) + { + int baseAddress = 128; + + switch (row) + { + case 0: return baseAddress; + case 1: return (baseAddress + 64); + case 2: return (baseAddress + width); + case 3: return (baseAddress + 64 + width); + default: return baseAddress; + } + } + private void Synchronize() { pins.Clock.Write(true); From b17d0f23b927c81532c5a39bdf2264e4137d0ca7 Mon Sep 17 00:00:00 2001 From: dgt0011 Date: Thu, 2 Jul 2015 11:40:48 +1000 Subject: [PATCH 211/227] Add support for the MCP23008 I/O extender used by the Adafruit I2C/SPI serial backpack for driving HD44780 LCD --- .../Mcp23008/Mcp23008I2cConnection.cs | 177 ++++++++++++++++++ .../Mcp23008/Mcp23008InputBinaryPin.cs | 89 +++++++++ .../Mcp23008/Mcp23008OutputBinaryPin.cs | 58 ++++++ .../Expanders/Mcp23008/Mcp23008Pin.cs | 14 ++ .../Mcp23008/Mcp23008PinDirection.cs | 8 + .../Mcp23008/Mcp23008PinExtensionMethods.cs | 38 ++++ .../Expanders/Mcp23008/Mcp23008PinPolarity.cs | 8 + .../Expanders/Mcp23008/Mcp23008PinResistor.cs | 8 + .../Raspberry.IO.Components.csproj | 8 + RaspberrySharp.IO.sln | 7 + .../Test.Gpio.HD44780/ConfigurationLoader.cs | 49 +++++ Tests/Test.Gpio.MCP23008/Program.cs | 40 ++++ .../Properties/AssemblyInfo.cs | 36 ++++ .../Test.Gpio.MCP23008.csproj | 79 ++++++++ 14 files changed, 619 insertions(+) create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008I2cConnection.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008InputBinaryPin.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008OutputBinaryPin.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008Pin.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinDirection.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinExtensionMethods.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinPolarity.cs create mode 100644 Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinResistor.cs create mode 100644 Tests/Test.Gpio.MCP23008/Program.cs create mode 100644 Tests/Test.Gpio.MCP23008/Properties/AssemblyInfo.cs create mode 100644 Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008I2cConnection.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008I2cConnection.cs new file mode 100644 index 0000000..4146d54 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008I2cConnection.cs @@ -0,0 +1,177 @@ +#region References + +using Raspberry.IO.InterIntegratedCircuit; + +#endregion + +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + /// + /// Represents a I2C connection to a MCP23008 I/O Expander. + /// + /// See for more information. + public class Mcp23008I2cConnection + { + #region Fields + + private readonly I2cDeviceConnection connection; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + public Mcp23008I2cConnection(I2cDeviceConnection connection) + { + this.connection = connection; + } + + #endregion + + #region Methods + + /// + /// Sets the direction. + /// + /// The pin. + /// The direction. + public void SetDirection(Mcp23008Pin pin, Mcp23008PinDirection direction) + { + var register = Register.IODIR; + + connection.WriteByte((byte)register); + var directions = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + var newDirections = (direction == Mcp23008PinDirection.Input) + ? directions | bit + : directions & ~bit; + + connection.Write(new[] { (byte)register, (byte)newDirections }); + } + + /// + /// Sets the polarity. + /// + /// The pin. + /// The polarity. + public void SetPolarity(Mcp23008Pin pin, Mcp23008PinPolarity polarity) + { + var register = Register.IPOL; + + connection.WriteByte((byte)register); + var polarities = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + var newPolarities = (polarity == Mcp23008PinPolarity.Inverted) + ? polarities | bit + : polarities & ~bit; + + connection.Write(new[] { (byte)register, (byte)newPolarities }); + } + + /// + /// Sets the resistor. + /// + /// The pin. + /// The resistor. + public void SetResistor(Mcp23008Pin pin, Mcp23008PinResistor resistor) + { + var register = Register.GPPU; + + connection.WriteByte((byte)register); + var resistors = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + var newResistors = (resistor == Mcp23008PinResistor.PullUp) + ? resistors | bit + : resistors & ~bit; + + connection.Write(new[] { (byte)register, (byte)newResistors }); + } + + /// + /// Sets the pin status. + /// + /// The pin. + /// if set to true, pin is enabled. + public void SetPinStatus(Mcp23008Pin pin, bool enabled) + { + var register = Register.GPIO; + + connection.WriteByte((byte)register); + var status = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + var newStatus = enabled + ? status | bit + : status & ~bit; + + connection.Write((byte)register, (byte)newStatus); + } + + + /// + /// Gets the pin status. + /// + /// The pin. + /// The pin status. + public bool GetPinStatus(Mcp23008Pin pin) + { + var register = Register.GPIO; + + connection.WriteByte((byte)register); + var status = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + return (status & bit) != 0x00; + } + + /// + /// Toogles the specified pin. + /// + /// The pin. + public void Toogle(Mcp23008Pin pin) + { + var register = Register.GPIO; + + connection.WriteByte((byte)register); + var status = connection.ReadByte(); + + var bit = (byte)((int)pin & 0xFF); + var bitEnabled = (status & bit) != 0x00; + var newBitEnabled = !bitEnabled; + + var newStatus = newBitEnabled + ? status | bit + : status & ~bit; + + connection.Write((byte)register, (byte)newStatus); + } + + #endregion + + #region Private Helpers + + private enum Register + { + IODIR = 0x00, + IPOL = 0x01, + GPINTEN = 0x02, + DEFVAL = 0x03, + INTCON = 0x04, + IOCON = 0x05, + GPPU = 0x06, + INTF = 0x07, + INTCAP = 0x08, + GPIO = 0x09, + OLAT = 0x0A + } + + #endregion + + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008InputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008InputBinaryPin.cs new file mode 100644 index 0000000..a8a13b9 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008InputBinaryPin.cs @@ -0,0 +1,89 @@ +#region References + +using System; + +#endregion + +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + /// + /// Represents a binary intput pin on a MCP23017 I/O expander. + /// + public class Mcp23008InputBinaryPin : IInputBinaryPin + { + #region Fields + + private readonly Mcp23008I2cConnection connection; + private readonly Mcp23008Pin pin; + + /// + /// The default timeout (5 seconds). + /// + public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(5); + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + public Mcp23008InputBinaryPin(Mcp23008I2cConnection connection, Mcp23008Pin pin, + Mcp23008PinResistor resistor = Mcp23008PinResistor.None, + Mcp23008PinPolarity polarity = Mcp23008PinPolarity.Normal) + { + this.connection = connection; + this.pin = pin; + + connection.SetDirection(pin, Mcp23008PinDirection.Input); + connection.SetResistor(pin, resistor); + connection.SetPolarity(pin, polarity); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose(){} + + #endregion + + #region Methods + + /// + /// Reads the state of the pin. + /// + /// + /// true if the pin is in high state; otherwise, false. + /// + public bool Read() + { + return connection.GetPinStatus(pin); + } + + /// + /// Waits for the specified pin to be in the specified state. + /// + /// if set to true waits for the pin to be up. Default value is true. + /// The timeout. Default value is . + /// If timeout is set to , a default timeout is used instead. + public void Wait(bool waitForUp = true, TimeSpan timeout = new TimeSpan()) + { + var startWait = DateTime.UtcNow; + if (timeout == TimeSpan.Zero) + timeout = DefaultTimeout; + + while (Read() != waitForUp) + { + if (DateTime.UtcNow - startWait >= timeout) + throw new TimeoutException("A timeout occurred while waiting for pin status to change"); + } + } + + #endregion + + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008OutputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008OutputBinaryPin.cs new file mode 100644 index 0000000..cfc3ae9 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008OutputBinaryPin.cs @@ -0,0 +1,58 @@ +using System; + +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + /// + /// Represents a binary output pin on a MCP23008 I/O expander. + /// + public class Mcp23008OutputBinaryPin : IOutputBinaryPin + { + #region Properties + + private readonly Mcp23008I2cConnection connection; + private readonly Mcp23008Pin pin; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + public Mcp23008OutputBinaryPin(Mcp23008I2cConnection connection, Mcp23008Pin pin, + Mcp23008PinResistor resistor = Mcp23008PinResistor.None, + Mcp23008PinPolarity polarity = Mcp23008PinPolarity.Normal) + { + this.connection = connection; + this.pin = pin; + + connection.SetDirection(pin, Mcp23008PinDirection.Output); + connection.SetResistor(pin, resistor); + connection.SetPolarity(pin, polarity); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose(){} + + #endregion + + #region Methods + + /// + /// Writes the value of the pin. + /// + /// if set to true, pin is set to high state. + public void Write(bool state) + { + connection.SetPinStatus(pin, state); + } + + #endregion + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008Pin.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008Pin.cs new file mode 100644 index 0000000..c262007 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008Pin.cs @@ -0,0 +1,14 @@ +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + public enum Mcp23008Pin + { + Pin0 = 0x0001, + Pin1 = 0x0002, + Pin2 = 0x0004, + Pin3 = 0x0008, + Pin4 = 0x0010, + Pin5 = 0x0020, + Pin6 = 0x0040, + Pin7 = 0x0080 + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinDirection.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinDirection.cs new file mode 100644 index 0000000..4ead024 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinDirection.cs @@ -0,0 +1,8 @@ +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + public enum Mcp23008PinDirection + { + Input, + Output + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinExtensionMethods.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinExtensionMethods.cs new file mode 100644 index 0000000..9d7e556 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinExtensionMethods.cs @@ -0,0 +1,38 @@ +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + /// + /// Provides extension methods for MCP23008 pins. + /// + public static class Mcp23008PinExtensionMethods + { + #region Methods + + /// + /// Creates an output binary pin. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + /// The pin. + public static Mcp23008OutputBinaryPin Out(this Mcp23008I2cConnection connection, Mcp23008Pin pin, Mcp23008PinResistor resistor = Mcp23008PinResistor.None, Mcp23008PinPolarity polarity = Mcp23008PinPolarity.Normal) + { + return new Mcp23008OutputBinaryPin(connection, pin, resistor, polarity); + } + + /// + /// Creates an input binary pin. + /// + /// The connection. + /// The pin. + /// The resistor. + /// The polarity. + /// The pin. + public static Mcp23008InputBinaryPin In(this Mcp23008I2cConnection connection, Mcp23008Pin pin, Mcp23008PinResistor resistor = Mcp23008PinResistor.None, Mcp23008PinPolarity polarity = Mcp23008PinPolarity.Normal) + { + return new Mcp23008InputBinaryPin(connection, pin, resistor, polarity); + } + + #endregion + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinPolarity.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinPolarity.cs new file mode 100644 index 0000000..b6e37b0 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinPolarity.cs @@ -0,0 +1,8 @@ +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + public enum Mcp23008PinPolarity + { + Normal, + Inverted + } +} diff --git a/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinResistor.cs b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinResistor.cs new file mode 100644 index 0000000..f43243a --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23008/Mcp23008PinResistor.cs @@ -0,0 +1,8 @@ +namespace Raspberry.IO.Components.Expanders.Mcp23008 +{ + public enum Mcp23008PinResistor + { + None, + PullUp + } +} diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index b831c74..9f61b90 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -111,6 +111,14 @@ + + + + + + + + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 3061028..e8521e6 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -69,6 +69,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.I EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23008", "Tests\Test.Gpio.MCP23008\Test.Gpio.MCP23008.csproj", "{E401FE2A-7F73-41E7-9347-B51FEDAE71B9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -167,6 +169,10 @@ Global {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -191,6 +197,7 @@ Global {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj diff --git a/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs index 2ccd78d..47a0503 100644 --- a/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs +++ b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs @@ -6,6 +6,7 @@ using System.Linq; using Raspberry.IO; using Raspberry.IO.Components.Displays.Hd44780; +using Raspberry.IO.Components.Expanders.Mcp23008; using Raspberry.IO.Components.Expanders.Mcp23017; using Raspberry.IO.Components.Expanders.Pcf8574; using Raspberry.IO.GeneralPurpose; @@ -21,6 +22,9 @@ internal static class ConfigurationLoader public static Hd44780Configuration FromArguments(string[] args) { + if (args.Contains("mcp23008", StringComparer.InvariantCultureIgnoreCase)) + return LoadMcp23008Configuration(args); + if (args.Contains("mcp23017", StringComparer.InvariantCultureIgnoreCase)) return LoadMcp23017Configuration(args); @@ -34,6 +38,51 @@ public static Hd44780Configuration FromArguments(string[] args) #region Private Helpers + private static Hd44780Configuration LoadMcp23008Configuration(IEnumerable args) + { + var addressText = args.SkipWhile(s => !String.Equals(s, "mcp23008", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); + var address = addressText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) + ? Int32.Parse(addressText.Substring(2), NumberStyles.HexNumber) + : Int32.Parse(addressText); + + const Mcp23008Pin registerSelectPin = Mcp23008Pin.Pin1; + const Mcp23008Pin clockPin = Mcp23008Pin.Pin2; + + var dataPins = new[] + { + Mcp23008Pin.Pin3, + Mcp23008Pin.Pin4, + Mcp23008Pin.Pin5, + Mcp23008Pin.Pin6 + }; + + Console.WriteLine(); + Console.WriteLine("Using I2C connection over MCP23008 Expander"); + Console.WriteLine("\tRegister Select: {0}", registerSelectPin); + Console.WriteLine("\tClock: {0}", clockPin); + Console.WriteLine("\tData 1: {0}", dataPins[0]); + Console.WriteLine("\tData 2: {0}", dataPins[1]); + Console.WriteLine("\tData 3: {0}", dataPins[2]); + Console.WriteLine("\tData 4: {0}", dataPins[3]); + Console.WriteLine("\tBacklight: VCC"); + Console.WriteLine("\tRead/write: GND"); + Console.WriteLine(); + + const ConnectorPin sdaPin = ConnectorPin.P1Pin03; + const ConnectorPin sclPin = ConnectorPin.P1Pin05; + + var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) { ClockDivider = 512 }; + var connection = new Mcp23008I2cConnection(driver.Connect(address)); + + return new Hd44780Configuration(driver) + { + Pins = new Hd44780Pins( + connection.Out(registerSelectPin), + connection.Out(clockPin), + dataPins.Select(pin => (IOutputBinaryPin)connection.Out(pin))) + }; + } + private static Hd44780Configuration LoadMcp23017Configuration(IEnumerable args) { var addressText = args.SkipWhile(s => !String.Equals(s, "mcp23017", StringComparison.InvariantCultureIgnoreCase)).Skip(1).DefaultIfEmpty("0x20").First(); diff --git a/Tests/Test.Gpio.MCP23008/Program.cs b/Tests/Test.Gpio.MCP23008/Program.cs new file mode 100644 index 0000000..106bd6c --- /dev/null +++ b/Tests/Test.Gpio.MCP23008/Program.cs @@ -0,0 +1,40 @@ +#region References + +using System; +using System.Threading; +using Raspberry.IO.Components.Expanders.Mcp23008; +using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.InterIntegratedCircuit; + +#endregion + +namespace Test.Gpio.MCP23008 +{ + class Program + { + static void Main() + { + const ConnectorPin sdaPin = ConnectorPin.P1Pin03; + const ConnectorPin sclPin = ConnectorPin.P1Pin05; + + Console.WriteLine("MCP-23008 Sample: Switch LED on Pin0 pin"); + Console.WriteLine(); + Console.WriteLine("\tSDA: {0}", sdaPin); + Console.WriteLine("\tSCL: {0}", sclPin); + Console.WriteLine(); + + using (var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor())) + { + var deviceConnection = new Mcp23008I2cConnection(driver.Connect(0x20)); + deviceConnection.SetDirection(Mcp23008Pin.Pin0, Mcp23008PinDirection.Output); + + while (!Console.KeyAvailable) + { + deviceConnection.Toogle(Mcp23008Pin.Pin0); + Thread.Sleep(1000); + } + } + + } + } +} diff --git a/Tests/Test.Gpio.MCP23008/Properties/AssemblyInfo.cs b/Tests/Test.Gpio.MCP23008/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d490767 --- /dev/null +++ b/Tests/Test.Gpio.MCP23008/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test.Gpio.MCP23008")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test.Gpio.MCP23008")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9951e52d-ee54-4579-8eea-64a2e2e5a638")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj new file mode 100644 index 0000000..38ddeba --- /dev/null +++ b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj @@ -0,0 +1,79 @@ + + + + + Debug + AnyCPU + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9} + Exe + Properties + Test.Gpio.MCP23008 + Test.Gpio.MCP23008 + v4.0 + 512 + ..\..\ + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + {8388cfca-e3db-43f7-b049-2cb195211ce8} + Raspberry.IO.Components + + + {281c71ed-c36d-408e-8baa-75c381dc17e7} + Raspberry.IO.GeneralPurpose + + + {63b8403e-bc56-43f9-a045-f61ecc3871f3} + Raspberry.IO.InterIntegratedCircuit + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file From 84419efce3e038ba5ae2cf6c4b0e02cf05794dd0 Mon Sep 17 00:00:00 2001 From: dgt0011 Date: Thu, 2 Jul 2015 13:32:51 +1000 Subject: [PATCH 212/227] Merge in fixes for Backlight enable/disable pin --- Tests/Test.Gpio.HD44780/ConfigurationLoader.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs index 47a0503..705dd28 100644 --- a/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs +++ b/Tests/Test.Gpio.HD44780/ConfigurationLoader.cs @@ -47,6 +47,7 @@ private static Hd44780Configuration LoadMcp23008Configuration(IEnumerable (IOutputBinaryPin)connection.Out(pin))) }; + + retVal.Pins.Backlight = connection.Out(backlightPin); + + return retVal; } private static Hd44780Configuration LoadMcp23017Configuration(IEnumerable args) From 72d19e545061b1b7fc9af158b6b81f81f90c1937 Mon Sep 17 00:00:00 2001 From: Stuart Date: Fri, 5 Feb 2016 15:40:34 +0000 Subject: [PATCH 213/227] HT16K33 Display Driver used by adafruit --- .../Controllers/HT16K33/HT16K33Connection.cs | 157 ++++++++++++++++++ .../BiColor24Bargraph/BiColor24Bargraph.cs | 74 +++++++++ .../Program.cs | 35 ++++ 3 files changed, 266 insertions(+) create mode 100644 Raspberry.IO.Components/Controllers/HT16K33/HT16K33Connection.cs create mode 100644 Raspberry.IO.Components/Leds/BiColor24Bargraph/BiColor24Bargraph.cs create mode 100644 Tests/Test.Components.BiColor24Bargraph/Program.cs diff --git a/Raspberry.IO.Components/Controllers/HT16K33/HT16K33Connection.cs b/Raspberry.IO.Components/Controllers/HT16K33/HT16K33Connection.cs new file mode 100644 index 0000000..8c18d81 --- /dev/null +++ b/Raspberry.IO.Components/Controllers/HT16K33/HT16K33Connection.cs @@ -0,0 +1,157 @@ +//Copyright (c) 2016 Logic Ethos Ltd +// +//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +//The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +using System; +using Common.Logging; +using Raspberry.IO.InterIntegratedCircuit; +using Raspberry.Timers; +using UnitsNet; +using System.IO; + +namespace Raspberry.IO.Components.Controllers.HT16K33 +{ + + /// + /// Driver for Holtek HT16K33 LED Matrix driver + /// As used by Adafruit devices + /// + public class HT16K33Connection //: IPwmDevice + { + + + public enum Flash : byte + { + Off = 0x00, + On = 0x01, + TwoHZ = 0x02, + OneHZ = 0x04, + HalfHZ = 0x06, + } + + public enum Command : byte + { + DisplayDataAddress = 0x00, + System_Setup = 0x20, + KeyDataAddressPointer = 0x40, + INTFlagAddressPointer = 0x60, + Flash = 0x80, + RowIntSet = 0xA0, + DimmingSet = 0xE0, + TestMode = 0xD9, + } + + const byte DEFAULT_ADDRESS = 0x70; + const byte HT16K33_Oscillator = 0x01; + const byte HT16K33_DisplayOn = 0x01; + + private readonly I2cDeviceConnection connection; + private static readonly ILog log = LogManager.GetLogger(); + + public byte[] LEDBuffer {get; private set;} //Max 16 rows, 8 bits (leds) + + + /// + /// Initializes a new instance of the + /// class. + /// + /// I2c connection. + /// Rows in use (1 to 16) + public HT16K33Connection(I2cDeviceConnection connection, int RowCount) + { + LEDBuffer = new byte[RowCount]; + this.connection = connection; + + log.Info(m => m("Resetting HT16K33")); + + connection.Write((byte)Command.System_Setup | (byte)HT16K33_Oscillator); //Turn on the oscillator. + connection.Write((byte)Command.Flash | (byte)HT16K33_DisplayOn | (byte)Flash.Off); + connection.Write((byte)Command.DimmingSet | (byte)15); + + // connection.Write(SetupSequence); + } + + + /// + /// Flash display at specified frequency. + /// + /// . + public void SetFlash(Flash frequency) + { + connection.WriteByte((byte)((byte)Command.Flash | HT16K33_DisplayOn | (byte)frequency)); + } + + /// + /// Set brightness of entire display to specified value (0 to 15). + /// + /// . + public void SetBrightness(uint brightness) + { + if (brightness > 15) brightness = 15; + connection.WriteByte((byte)((byte)Command.DimmingSet | (byte)brightness)); + } + + /// + /// Sets specified LED (0-[row-count] rows, 0 to 7 leds) + /// + /// . + public void SetLed(uint row, uint led, bool OutputOn) + { + if (row >= LEDBuffer.Length) throw new Exception("Row out of range"); + if (led > 7) throw new Exception("LED out of range 0 to 7"); + + if (OutputOn) + { + LEDBuffer[row] |= (byte)(1 << (int)led); //Turn on the speciried LED (set bit to one). + } + else + { + LEDBuffer[row] &= (byte)~(1 << (int)led); //Turn off the specified LED (set bit to zero). + } + connection.Write(new byte[] {(byte)row, LEDBuffer[row]}); + } + + + /// + /// Write display buffer to display hardware. + /// + /// . + public void WriteDisplayBuffer() + { + for (int i = 0; i < LEDBuffer.Length;i++) + { + connection.Write((byte)i,LEDBuffer[i]); + } + } + + /// + /// Clear contents of display buffer. + /// + /// . + public void Clear() + { + for (int i = 0; i < LEDBuffer.Length;i++) + { + LEDBuffer[i] = 0; + } + WriteDisplayBuffer(); + } + + /// + /// Set all LEDs On. + /// + /// . + public void SetAllOn() + { + for (int i = 0; i < LEDBuffer.Length;i++) + { + LEDBuffer[i] = 1; + } + WriteDisplayBuffer(); + } + + } +} diff --git a/Raspberry.IO.Components/Leds/BiColor24Bargraph/BiColor24Bargraph.cs b/Raspberry.IO.Components/Leds/BiColor24Bargraph/BiColor24Bargraph.cs new file mode 100644 index 0000000..58819e7 --- /dev/null +++ b/Raspberry.IO.Components/Leds/BiColor24Bargraph/BiColor24Bargraph.cs @@ -0,0 +1,74 @@ +//Copyright (c) 2016 Logic Ethos Ltd +// +//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +//The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using Raspberry.Timers; +using Raspberry.IO.Components.Controllers.HT16K33; +using Raspberry.IO.InterIntegratedCircuit; + + +namespace Raspberry.IO.Components.Leds.BiColor24Bargraph +{ + public class BiColor24Bargraph : HT16K33Connection + { + public enum LEDState + { + Off, + Red, + Green, + Yellow + } + /// + /// Initializes a new instance of the class. + /// + /// I2c Connection. + public BiColor24Bargraph (I2cDeviceConnection connection) : base (connection,6) + { + } + + /// + /// Sets the led (0 to 23) + /// + /// Led no. + /// State. + public void SetLed(uint ledNo, LEDState state) + { + + if (ledNo > 23) throw new Exception("led must be between 0 and 23"); + + long r,c; + r = Math.DivRem(ledNo,4,out c) * 2; + if (ledNo >= 12) c += 4; + + if (r > 4) r -= 6; + + switch (state) + { + case LEDState.Off: + base.SetLed((uint)r,(uint)c, false); + base.SetLed((uint)r + 1,(uint)c, false); + break; + case LEDState.Red: + base.SetLed((uint)r,(uint)c, true); + base.SetLed((uint)r + 1,(uint)c, false); + break; + case LEDState.Yellow: + base.SetLed((uint)r,(uint)c, true); + base.SetLed((uint)r + 1,(uint)c, true); + break; + case LEDState.Green: + base.SetLed((uint)r,(uint)c, false); + base.SetLed((uint)r + 1,(uint)c, true); + break; + } + + } + } +} + + + + diff --git a/Tests/Test.Components.BiColor24Bargraph/Program.cs b/Tests/Test.Components.BiColor24Bargraph/Program.cs new file mode 100644 index 0000000..5330631 --- /dev/null +++ b/Tests/Test.Components.BiColor24Bargraph/Program.cs @@ -0,0 +1,35 @@ +using System; +using Raspberry.IO.Components.Leds.BiColor24Bargraph; +using Raspberry.IO.InterIntegratedCircuit; +using System.Threading; +using Raspberry.IO.GeneralPurpose; + +namespace Test.Components.BiColor24Bargraph +{ + class MainClass + { + public static void Main (string[] args) + { + using (var i2cDriver = new I2cDriver(ProcessorPin.Pin2, ProcessorPin.Pin3)) + { + I2cDeviceConnection i2c = i2cDriver.Connect(0x70); + + var bargraph = new BiColor24Bargraph(i2c); + + bargraph.Clear(); + + while (true) + { + foreach (BiColor24Bargraph.LEDState state in Enum.GetValues(typeof(BiColor24Bargraph.LEDState))) + { + for (int i=0; i<24;i++) + { + bargraph.SetLed((uint)i, state); + Thread.Sleep(50); + } + } + } + } + } + } +} From 380c49c1ee053cc6d016fa0ab8c001230b22ec36 Mon Sep 17 00:00:00 2001 From: Stuart Date: Fri, 5 Feb 2016 15:41:40 +0000 Subject: [PATCH 214/227] Added HT16K33 driver to project --- .../Raspberry.IO.Components.csproj | 43 +++--- Raspberry.IO.Components/packages.config | 6 +- .../GpioInputBinaryPin.cs | 3 +- .../Raspberry.IO.GeneralPurpose.csproj | 25 +-- ...Raspberry.IO.InterIntegratedCircuit.csproj | 8 +- .../Raspberry.IO.Interop.csproj | 2 - ...pberry.IO.SerialPeripheralInterface.csproj | 8 +- Raspberry.IO/Raspberry.IO.csproj | 2 - RaspberrySharp.IO.sln | 145 +++++++++--------- .../Test.Components.PiFaceDigital.csproj | 2 - .../Test.Components.Ssd1306.csproj | 2 - .../Test.Gpio.Chaser/Test.Gpio.Chaser.csproj | 2 - Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 11 +- .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 9 +- .../Test.Gpio.HD44780.csproj | 2 - .../Test.Gpio.MCP23008.csproj | 8 +- .../Test.Gpio.MCP23017.csproj | 2 - .../Test.Gpio.MCP3008.csproj | 6 +- .../Test.Gpio.MCP4822.csproj | 2 - .../Test.Gpio.Pca9685.csproj | 13 +- .../Test.Gpio.WatchPin.csproj | 2 - .../Test.Spi.MCP3208/Test.Spi.MCP3208.csproj | 8 +- .../Test.Spi.TLC59711.csproj | 2 - .../Tests.Raspberry.IO.Components.csproj | 2 - .../Tests.Raspberry.IO.Interop.csproj | 2 - ...pberry.IO.SerialPeripheralInterface.csproj | 2 - .../Tests.Raspberry.IO.csproj | 2 - packages/repositories.config | 14 +- 28 files changed, 128 insertions(+), 207 deletions(-) diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 9f61b90..fc2759f 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -12,8 +12,6 @@ 512 ..\ true - 12.0.0 - 2.0 true @@ -33,30 +31,20 @@ 4 - - False - ..\packages\Common.Logging.3.1.0\lib\net40\Common.Logging.dll - - - False - ..\packages\Common.Logging.Core.3.1.0\lib\net40\Common.Logging.Core.dll - - - False + + ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - True - - - - ..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll + ..\packages\UnitsNet.3.24.0\lib\net35\UnitsNet.dll - - ..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll - True + + ..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll + + + ..\packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll @@ -161,6 +149,8 @@ + + @@ -175,15 +165,14 @@ {326342E5-0411-40E8-9F2D-563D6B192568} Raspberry.IO.SerialPeripheralInterface - - {ACE64F17-87E5-43E7-97A0-BDDE19059C61} - {D2E41147-5BF6-4109-A497-C76284F3C020} - Raspberry.IO - {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} + Raspberry.IO + @@ -201,4 +190,8 @@ --> + + + + \ No newline at end of file diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index 3828cf1..77e8a1b 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -1,7 +1,7 @@  - - + + - + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs index 43d8df1..bbec7c3 100644 --- a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs @@ -1,11 +1,12 @@ using System; +using Raspberry.IO; namespace Raspberry.IO.GeneralPurpose { /// /// Represents a GPIO input binary pin. /// - public class GpioInputBinaryPin : IInputBinaryPin + public class GpioInputBinaryPin : Raspberry.IO.IInputBinaryPin { #region Fields diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index bd9ad03..a211025 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 8.0.30703 - 2.0 {281C71ED-C36D-408E-8BAA-75C381DC17E7} Library Properties @@ -35,15 +33,17 @@ bin\Release\Raspberry.IO.GeneralPurpose.XML - - False - ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll + + + ..\Raspberry.IO\bin\Debug\Raspberry.IO.dll + + + ..\Raspberry.IO.Interop\bin\Debug\Raspberry.IO.Interop.dll @@ -88,17 +88,6 @@ - - - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} - Raspberry.IO.Interop - - - {ACE64F17-87E5-43E7-97A0-BDDE19059C61} - {D2E41147-5BF6-4109-A497-C76284F3C020} - Raspberry.IO - - diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index 5981014..a9219da 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 8.0.30703 - 2.0 {63B8403E-BC56-43F9-A045-F61ECC3871F3} Library Properties @@ -35,15 +33,11 @@ bin\Release\Raspberry.IO.InterIntegratedCircuit.XML - - False - ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll diff --git a/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj index 9ba02d6..034c6fc 100644 --- a/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj +++ b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj @@ -12,8 +12,6 @@ v4.0 512 - 12.0.0 - 2.0 true diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index b0ebc17..0914c7d 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 8.0.30703 - 2.0 {326342E5-0411-40E8-9F2D-563D6B192568} Library Properties @@ -35,15 +33,15 @@ bin\Release\Raspberry.IO.SerialPeripheralInterface.XML - - ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - ..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + + ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll + diff --git a/Raspberry.IO/Raspberry.IO.csproj b/Raspberry.IO/Raspberry.IO.csproj index e32a655..e58e755 100644 --- a/Raspberry.IO/Raspberry.IO.csproj +++ b/Raspberry.IO/Raspberry.IO.csproj @@ -12,8 +12,6 @@ Raspberry.IO v4.0 512 - 12.0.0 - 2.0 true diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index e8521e6..e46c6b2 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 +# Visual Studio 2012 VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" @@ -42,6 +42,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Spi.MCP3208", "Tests\T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Components.Ssd1306", "Tests\Test.Components.Ssd1306\Test.Components.Ssd1306.csproj", "{CAD5F2DD-AB2D-4145-9850-8101343E2AF5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23008", "Tests\Test.Gpio.MCP23008\Test.Gpio.MCP23008.csproj", "{E401FE2A-7F73-41E7-9347-B51FEDAE71B9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Components.BiColor24Bargraph", "Tests\Test.Components.BiColor24Bargraph\Test.Components.BiColor24Bargraph.csproj", "{CD6D36DA-740B-480F-A8EF-3F94E2117F34}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Raspberry.IO.SerialPeripheralInterface", "UnitTests\Tests.Raspberry.IO.SerialPeripheralInterface\Tests.Raspberry.IO.SerialPeripheralInterface.csproj", "{17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}" @@ -69,116 +73,116 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.I EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23008", "Tests\Test.Gpio.MCP23008\Test.Gpio.MCP23008.csproj", "{E401FE2A-7F73-41E7-9347-B51FEDAE71B9}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Debug|Any CPU.Build.0 = Debug|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.ActiveCfg = Release|Any CPU {281C71ED-C36D-408E-8BAA-75C381DC17E7}.Release|Any CPU.Build.0 = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.Build.0 = Release|Any CPU {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Debug|Any CPU.Build.0 = Debug|Any CPU {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.ActiveCfg = Release|Any CPU {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Any CPU.Build.0 = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Any CPU.Build.0 = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Debug|Any CPU.Build.0 = Debug|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D9D1834-4C4B-4E03-B635-5F205205B6F8}.Release|Any CPU.Build.0 = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.Build.0 = Release|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU - {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU - {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {475CEB21-BA5F-4338-80E2-C6B29766A04A}.Release|Any CPU.Build.0 = Release|Any CPU {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Debug|Any CPU.Build.0 = Debug|Any CPU {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Release|Any CPU.ActiveCfg = Release|Any CPU {63356B6E-47A0-44E8-8B98-456E8579DCD2}.Release|Any CPU.Build.0 = Release|Any CPU - {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.Build.0 = Release|Any CPU - {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Release|Any CPU.Build.0 = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F}.Release|Any CPU.Build.0 = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A}.Release|Any CPU.Build.0 = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Debug|Any CPU.Build.0 = Debug|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.ActiveCfg = Release|Any CPU - {326342E5-0411-40E8-9F2D-563D6B192568}.Release|Any CPU.Build.0 = Release|Any CPU {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.Build.0 = Release|Any CPU {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {8388CFCA-E3DB-43F7-B049-2CB195211CE8}.Release|Any CPU.Build.0 = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B}.Release|Any CPU.Build.0 = Release|Any CPU {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF711872-F931-46A8-AAC0-AFF6FFEF5AE3}.Release|Any CPU.Build.0 = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B28253A7-BB93-40F7-B41C-B4AE369174ED}.Release|Any CPU.Build.0 = Release|Any CPU + {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAD5F2DD-AB2D-4145-9850-8101343E2AF5}.Release|Any CPU.Build.0 = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F}.Release|Any CPU.Build.0 = Release|Any CPU + {CD6D36DA-740B-480F-A8EF-3F94E2117F34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD6D36DA-740B-480F-A8EF-3F94E2117F34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD6D36DA-740B-480F-A8EF-3F94E2117F34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD6D36DA-740B-480F-A8EF-3F94E2117F34}.Release|Any CPU.Build.0 = Release|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4B87926-598E-4EAB-BA75-CD9FB253D450}.Release|Any CPU.Build.0 = Release|Any CPU {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Debug|Any CPU.Build.0 = Debug|Any CPU {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {E401FE2A-7F73-41E7-9347-B51FEDAE71B9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(NestedProjects) = preSolution {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} + {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} @@ -192,20 +196,23 @@ Global {63356B6E-47A0-44E8-8B98-456E8579DCD2} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {D4B87926-598E-4EAB-BA75-CD9FB253D450} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {CAD5F2DD-AB2D-4145-9850-8101343E2AF5} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} = {93E87796-2109-444A-8852-7174C93E6F45} + {E401FE2A-7F73-41E7-9347-B51FEDAE71B9} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {CD6D36DA-740B-480F-A8EF-3F94E2117F34} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} {CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C} - {E401FE2A-7F73-41E7-9347-B51FEDAE71B9} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj Policies = $0 $0.TextStylePolicy = $1 $1.FileWidth = 120 $1.TabsToSpaces = False $1.inheritsSet = VisualStudio $1.inheritsScope = text/plain + StartupItem = Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj index ee907a4..b65d4fe 100644 --- a/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj +++ b/Tests/Test.Components.PiFaceDigital/Test.Components.PiFaceDigital.csproj @@ -11,8 +11,6 @@ Test.Components.PiFaceDigital v4.5 512 - 12.0.0 - 2.0 AnyCPU diff --git a/Tests/Test.Components.Ssd1306/Test.Components.Ssd1306.csproj b/Tests/Test.Components.Ssd1306/Test.Components.Ssd1306.csproj index 526c78d..4f9d9e7 100644 --- a/Tests/Test.Components.Ssd1306/Test.Components.Ssd1306.csproj +++ b/Tests/Test.Components.Ssd1306/Test.Components.Ssd1306.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 12.0.0 - 2.0 {CAD5F2DD-AB2D-4145-9850-8101343E2AF5} Exe Test.Components.Ssd1306 diff --git a/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj b/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj index fbe2831..c7c6b4e 100644 --- a/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj +++ b/Tests/Test.Gpio.Chaser/Test.Gpio.Chaser.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {5D9D1834-4C4B-4E03-B635-5F205205B6F8} Exe Properties diff --git a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj index 858a3a2..77a6fd0 100644 --- a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj +++ b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj @@ -13,8 +13,6 @@ 512 ..\..\ true - 12.0.0 - 2.0 AnyCPU @@ -36,10 +34,6 @@ 4 - - False - ..\..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - @@ -49,10 +43,9 @@ - ..\..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + ..\..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - False + ..\..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 0ba9adc..760b24d 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} Exe Properties @@ -58,18 +56,13 @@ 4 - - False - ..\..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - ..\..\packages\Raspberry.System.1.4.0\lib\net40\Raspberry.System.dll + ..\..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll ..\..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll - True diff --git a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index 5b0e788..9f774c2 100644 --- a/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Tests/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} Exe Properties diff --git a/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj index 38ddeba..ef2675b 100644 --- a/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj +++ b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj @@ -1,5 +1,5 @@  - + Debug @@ -49,15 +49,15 @@ - {8388cfca-e3db-43f7-b049-2cb195211ce8} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Raspberry.IO.Components - {281c71ed-c36d-408e-8baa-75c381dc17e7} + {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose - {63b8403e-bc56-43f9-a045-f61ecc3871f3} + {63B8403E-BC56-43F9-A045-F61ECC3871F3} Raspberry.IO.InterIntegratedCircuit diff --git a/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj b/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj index bddb86d..3347fd2 100644 --- a/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj +++ b/Tests/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {266EDDBC-F741-48F8-83B7-2CD37BACE62B} Exe Properties diff --git a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj index 8948986..634866f 100644 --- a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj +++ b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {B28253A7-BB93-40F7-B41C-B4AE369174ED} Exe Properties @@ -60,10 +58,8 @@ - - False + ..\..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll - True diff --git a/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj b/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj index 9c756f3..e135eb3 100644 --- a/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj +++ b/Tests/Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj @@ -3,8 +3,6 @@ Debug x86 - 8.0.30703 - 2.0 {54075457-7C1D-4C8F-BE7D-CFCA34F11228} Exe Properties diff --git a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index 642a942..945ba8e 100644 --- a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -13,8 +13,6 @@ 512 ..\ true - 12.0.0 - 2.0 AnyCPU @@ -36,21 +34,18 @@ 4 - - False - ..\..\packages\Common.Logging.3.1.0\lib\net40\Common.Logging.dll - ..\..\packages\Common.Logging.Core.3.1.0\lib\net40\Common.Logging.Core.dll - True ..\..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll - - False + + ..\..\packages\Common.Logging.3.1.0\lib\net40\Common.Logging.dll + + ..\..\packages\UnitsNet.3.10.0\lib\net35\UnitsNet.dll diff --git a/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj b/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj index 0c215c9..6f3740b 100644 --- a/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj +++ b/Tests/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj @@ -11,8 +11,6 @@ Test.Gpio.WatchPin v4.5 512 - 12.0.0 - 2.0 AnyCPU diff --git a/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj b/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj index 327a3c1..a2af000 100644 --- a/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj +++ b/Tests/Test.Spi.MCP3208/Test.Spi.MCP3208.csproj @@ -1,5 +1,5 @@  - + Debug @@ -41,15 +41,15 @@ - {8388cfca-e3db-43f7-b049-2cb195211ce8} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Raspberry.IO.Components - {281c71ed-c36d-408e-8baa-75c381dc17e7} + {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose - {ace64f17-87e5-43e7-97a0-bdde19059c61} + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} Raspberry.IO diff --git a/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj b/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj index f2637eb..4e4b7a0 100644 --- a/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj +++ b/Tests/Test.Spi.TLC59711/Test.Spi.TLC59711.csproj @@ -12,8 +12,6 @@ v4.0 512 - 12.0.0 - 2.0 AnyCPU diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index 2aaebdb..dd1bb84 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -14,8 +14,6 @@ ..\..\ true - 12.0.0 - 2.0 true diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index 0642beb..92877f0 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -14,8 +14,6 @@ ..\..\ true - 12.0.0 - 2.0 true diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index 075a675..92b4bc4 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -14,8 +14,6 @@ ..\..\ true - 12.0.0 - 2.0 true diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index b8efbe7..6adcd51 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -14,8 +14,6 @@ ..\..\ true - 12.0.0 - 2.0 true diff --git a/packages/repositories.config b/packages/repositories.config index e198861..331f51a 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -4,22 +4,12 @@ + + - - - - - - - - - - - - \ No newline at end of file From dbe5f7842912a64ad37fbf65b0ee4e4805bb9838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miha=20Marki=C4=8D?= Date: Thu, 5 May 2016 13:52:48 +0200 Subject: [PATCH 215/227] resets I2C pins back to original state, not blindly to input --- .../I2cDriver.cs | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs index 44fd7cf..8da61fb 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs @@ -21,6 +21,8 @@ public class I2cDriver : IDisposable private readonly ProcessorPin sdaPin; private readonly ProcessorPin sclPin; + private readonly bool wasSdaPinSet; + private readonly bool wasSclPinSet; private readonly IntPtr gpioAddress; private readonly IntPtr bscAddress; @@ -72,8 +74,9 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin) throw new InvalidOperationException("Unable to access device memory"); // Set the I2C pins to the Alt 0 function to enable I2C access on them - SetPinMode((uint) (int) sdaPin, Interop.BCM2835_GPIO_FSEL_ALT0); // SDA - SetPinMode((uint) (int) sclPin, Interop.BCM2835_GPIO_FSEL_ALT0); // SCL + // remembers if the values were actually changed to clear them or not upon dispose + wasSdaPinSet = SetPinMode((uint)(int)sdaPin, Interop.BCM2835_GPIO_FSEL_ALT0); // SDA + wasSclPinSet = SetPinMode((uint) (int) sclPin, Interop.BCM2835_GPIO_FSEL_ALT0); // SCL // Read the clock divider register var dividerAddress = bscAddress + (int) Interop.BCM2835_BSC_DIV; @@ -89,9 +92,15 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin) /// public void Dispose() { - // Set all the I2C/BSC1 pins back to input - SetPinMode((uint) (int) sdaPin, Interop.BCM2835_GPIO_FSEL_INPT); // SDA - SetPinMode((uint) (int) sclPin, Interop.BCM2835_GPIO_FSEL_INPT); // SCL + // Set all the I2C/BSC1 pins back to original values if changed + if (wasSdaPinSet) + { + SetPinMode((uint)(int)sdaPin, Interop.BCM2835_GPIO_FSEL_INPT); // SDA + } + if (wasSclPinSet) + { + SetPinMode((uint)(int)sclPin, Interop.BCM2835_GPIO_FSEL_INPT); // SCL + } Interop.munmap(gpioAddress, Interop.BCM2835_BLOCK_SIZE); Interop.munmap(bscAddress, Interop.BCM2835_BLOCK_SIZE); @@ -369,7 +378,13 @@ private static uint GetBscBase(ProcessorPin sdaPin, ProcessorPin sclPin) } } - private void SetPinMode(uint pin, uint mode) + /// + /// + /// + /// + /// + /// True when value was changed, false otherwise. + private bool SetPinMode(uint pin, uint mode) { // Function selects are 10 pins per 32 bit word, 3 bits per pin var paddr = gpioAddress + (int) (Interop.BCM2835_GPFSEL0 + 4*(pin/10)); @@ -377,7 +392,17 @@ private void SetPinMode(uint pin, uint mode) var mask = Interop.BCM2835_GPIO_FSEL_MASK << (int) shift; var value = mode << (int) shift; - WriteUInt32Mask(paddr, value, mask); + var existing = ReadUInt32(paddr) & mask; + if (existing != value) + { + //Console.WriteLine($"existing is {x} masked:{x & mask} vs mask:{mask} value:{value}"); + WriteUInt32Mask(paddr, value, mask); + return true; + } + else + { + return false; + } } private static void WriteUInt32Mask(IntPtr address, uint value, uint mask) From b982449667a78d4431715aa05dece2c05f41bfb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 26 May 2016 00:31:47 +0200 Subject: [PATCH 216/227] HD44780 : Replaced row+column with struct --- .../Displays/Hd44780/Hd44780LcdConnection.cs | 74 +++++++++---------- .../Displays/Hd44780/Hd44780Position.cs | 13 ++++ .../Raspberry.IO.Components.csproj | 1 + 3 files changed, 50 insertions(+), 38 deletions(-) create mode 100644 Raspberry.IO.Components/Displays/Hd44780/Hd44780Position.cs diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs index 9cc67a5..0d9e5ea 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs @@ -34,9 +34,8 @@ public class Hd44780LcdConnection : IDisposable private readonly EntryModeFlags entryModeFlags; private DisplayFlags displayFlags = DisplayFlags.DisplayOn | DisplayFlags.BlinkOff | DisplayFlags.CursorOff; - private int currentRow; - private int currentColumn; - + private Hd44780Position currentPosition; + private bool backlightEnabled; private static readonly TimeSpan syncDelay = TimeSpanUtility.FromMicroseconds(1); @@ -240,9 +239,8 @@ public void Close() public void Home() { WriteCommand(Command.ReturnHome); - currentRow = 0; - currentColumn = 0; - + currentPosition = Hd44780Position.Zero; + Timer.Sleep(TimeSpan.FromMilliseconds(3)); } @@ -252,9 +250,8 @@ public void Home() public void Clear() { WriteCommand(Command.ClearDisplay); - currentRow = 0; - currentColumn = 0; - + currentPosition = Hd44780Position.Zero; + Timer.Sleep(TimeSpan.FromMilliseconds(3)); // Clearing the display takes a long time } @@ -264,46 +261,47 @@ public void Clear() /// The offset. public void Move(int offset) { - var count = offset > 0 ? offset : -offset; - for (var i = 0; i < count; i++) - WriteCommand(Command.MoveCursor, (int)(CursorShiftFlags.DisplayMove | (offset < 0 ? CursorShiftFlags.MoveLeft : CursorShiftFlags.MoveRight))); - } + var column = currentPosition.Column += offset; + var row = currentPosition.Row; - /// - /// Moves the cursor to the designated row - /// - /// Zero based row position - public void MoveToRow(int row) - { - if (row < 0 || height <= row) - row = height - 1; + if (column >= width) + { + column = 0; + row++; + } + else if (column < 0) + { + column = width - 1; + row--; + } - var rowAddress = GetLcdAddressLocation(row); + if (row >= height) + row = 0; + if (row < 0) + row = height - 1; - currentRow = row; - currentColumn = 0; - WriteByte(rowAddress, false); + SetCursorPosition(new Hd44780Position{Row = row, Column = column}); } /// /// Moves the cursor to the specified row and column /// - /// Zero based row position - /// Zero based column position - public void GotoXY(int row, int column) + /// The position. + public void SetCursorPosition(Hd44780Position position) { + var row = position.Row; if (row < 0 || height <= row) row = height - 1; + var column = position.Column; if (column < 0 || width <= column) column = width - 1; var address = column + GetLcdAddressLocation(row); - + WriteByte(address, false); - currentRow = row; - currentColumn = column; + currentPosition = new Hd44780Position { Row = row, Column = column }; } /// @@ -409,22 +407,22 @@ public void Write(string format, TimeSpan animationDelay, params object[] values var bytes = encoding.GetBytes(line); foreach (var b in bytes) { - if (currentColumn < width) + if (currentPosition.Column < width) WriteByte(b, true); if (animationDelay > TimeSpan.Zero) Timer.Sleep(animationDelay); - currentColumn++; + currentPosition.Column++; } - if ((currentRow == 0 || (currentRow + 1) % height != 0) && height > 1) + if ((currentPosition.Row == 0 || (currentPosition.Row + 1) % height != 0) && height > 1) { - int addressLocation = GetLcdAddressLocation(currentRow + 1); + var addressLocation = GetLcdAddressLocation(currentPosition.Row + 1); WriteByte(addressLocation, false); - currentColumn = 0; - currentRow++; + currentPosition.Column = 0; + currentPosition.Row++; } else { @@ -505,7 +503,7 @@ private void WriteByte4Pins(int bits, bool charMode) /// http://www.mikroe.com/forum/viewtopic.php?t=5149 private int GetLcdAddressLocation(int row) { - int baseAddress = 128; + const int baseAddress = 128; switch (row) { diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780Position.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780Position.cs new file mode 100644 index 0000000..0785985 --- /dev/null +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780Position.cs @@ -0,0 +1,13 @@ +namespace Raspberry.IO.Components.Displays.Hd44780 +{ + /// + /// Represents the position of the cursor on a Hd44780 display. + /// + public struct Hd44780Position + { + public int Row; + public int Column; + + public static Hd44780Position Zero = new Hd44780Position {Row = 0, Column = 0}; + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 9f61b90..13cc279 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -109,6 +109,7 @@ + From 74cea6a8ec4b6da3f723df18cfc8173a0226d654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 26 May 2016 01:22:44 +0200 Subject: [PATCH 217/227] Fixed code --- .../Raspberry.IO.Components.csproj | 12 +- Raspberry.IO.Components/packages.config | 2 +- .../GpioInputBinaryPin.cs | 3 +- .../Raspberry.IO.GeneralPurpose.csproj | 16 +- RaspberrySharp.IO.sln | 147 +++++++++--------- Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 5 +- Tests/Test.Gpio.DHT11/packages.config | 2 +- .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 5 +- Tests/Test.Gpio.HCSR04/packages.config | 2 +- .../Test.Gpio.MCP3008.csproj | 5 +- Tests/Test.Gpio.MCP3008/packages.config | 2 +- .../Test.Gpio.Pca9685.csproj | 17 +- Tests/Test.Gpio.Pca9685/packages.config | 6 +- .../Tests.Raspberry.IO.csproj | 22 +-- packages/repositories.config | 12 ++ 15 files changed, 137 insertions(+), 121 deletions(-) diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 60fba6c..2804b05 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -37,15 +37,16 @@ ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - ..\packages\UnitsNet.3.24.0\lib\net35\UnitsNet.dll - ..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll ..\packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll + + ..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + True + @@ -191,8 +192,5 @@ --> - - - - + \ No newline at end of file diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index 77e8a1b..3a6ee6b 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs index bbec7c3..43d8df1 100644 --- a/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs +++ b/Raspberry.IO.GeneralPurpose/GpioInputBinaryPin.cs @@ -1,12 +1,11 @@ using System; -using Raspberry.IO; namespace Raspberry.IO.GeneralPurpose { /// /// Represents a GPIO input binary pin. /// - public class GpioInputBinaryPin : Raspberry.IO.IInputBinaryPin + public class GpioInputBinaryPin : IInputBinaryPin { #region Fields diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index a211025..6d07bed 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -39,12 +39,6 @@ ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - - ..\Raspberry.IO\bin\Debug\Raspberry.IO.dll - - - ..\Raspberry.IO.Interop\bin\Debug\Raspberry.IO.Interop.dll - @@ -91,6 +85,16 @@ + + + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} + Raspberry.IO.Interop + + + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} + Raspberry.IO + + + \ No newline at end of file From 94f1571ab0079c2e174a0429fa01ee5eb1a6e9ee Mon Sep 17 00:00:00 2001 From: Jim Hurst Date: Wed, 10 Aug 2016 12:34:47 +0100 Subject: [PATCH 220/227] Saved the Fixed1L.cs font with Unicode(65001) encoding. --- Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs index fc152fe..5f0b702 100644 --- a/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs +++ b/Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Raspberry.IO.Components.Displays.Ssd1306.Fonts { @@ -100,9 +100,9 @@ public class Fixed1L : IFont new byte[] { (byte)'|', 8, 8, 0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00 }, new byte[] { (byte)'}', 8, 8, 0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00 }, new byte[] { (byte)'~', 8, 8, 0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00 }, - new byte[] { (byte)'', 8, 8, 0x00,0x20,0x55,0x54,0x55,0x78,0x00,0x00 }, - new byte[] { (byte)'', 8, 8, 0x00, 0x39, 0x44, 0x44, 0x39, 0x00, 0x00, 0x00 }, - new byte[] { (byte)'', 8, 8, 0x00, 0x3D, 0x40, 0x40, 0x7D, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'ä', 8, 8, 0x00,0x20,0x55,0x54,0x55,0x78,0x00,0x00 }, + new byte[] { (byte)'ö', 8, 8, 0x00, 0x39, 0x44, 0x44, 0x39, 0x00, 0x00, 0x00 }, + new byte[] { (byte)'ü', 8, 8, 0x00, 0x3D, 0x40, 0x40, 0x7D, 0x00, 0x00, 0x00 }, new byte[] { (byte)0x7F, 8, 8, 0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00 } }; From 35dbe9242aaba0a77c0b607211c33cbf23b3becc Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 29 Aug 2016 13:42:22 +0100 Subject: [PATCH 221/227] Upgraded references to Raspberry.System from 2.0.0 to 2.1.0 --- .../Raspberry.IO.Components.csproj | 7 ++++--- Raspberry.IO.Components/packages.config | 2 +- .../Raspberry.IO.GeneralPurpose.csproj | 13 +++++++------ Raspberry.IO.GeneralPurpose/packages.config | 2 +- .../Raspberry.IO.InterIntegratedCircuit.csproj | 7 ++++--- Raspberry.IO.InterIntegratedCircuit/packages.config | 2 +- .../Raspberry.IO.SerialPeripheralInterface.csproj | 10 ++++------ .../packages.config | 2 +- Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 7 ++++--- Tests/Test.Gpio.DHT11/packages.config | 2 +- Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 7 ++++--- Tests/Test.Gpio.HCSR04/packages.config | 2 +- 12 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 0ab5aae..a99d55c 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -31,12 +31,13 @@ 4 + + ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + True + - - ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - ..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index 3a6ee6b..2025ba4 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 6d07bed..04923c3 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -33,12 +33,13 @@ bin\Release\Raspberry.IO.GeneralPurpose.XML + + ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + True + - - ..\packages\Raspberry.System.2.0.0\lib\net40\Raspberry.System.dll - @@ -82,9 +83,6 @@ - - - {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} @@ -95,6 +93,9 @@ Raspberry.IO + + + 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≥t-TPLq*n)~hsh}^PL%qq1La-of}&m4eCjv57Z6*W7@3bZ^l z8QYyS>x|DWqk3bFB3MmVTap>!`&qf9BT!ZcI?m+4c_l6@k%@8;gaV3gKW7r`>XjztmX=`gmFVDkixh}bsDt*JJOYW5V>RKt=88adv&WdU!n zc6*6YK$}M4045oKnb=5*go5~rcB5!pigusOnrc{fWgnpSU03Ja*MnLK3+d0Mtpn^HohJ70aG_NY5DPmtBE;kN>!2Xtbmx?8m0EsKWPw*`8`(w)g0l z-r)`AVkV>wBd&r?ZWI13nm$D>RJtxX7KElL+GVb+Y^c~yb5}(bO^uVM;O3IHjjphR zM98^uV%mC&4_P;kGAOVG%#Zfk*#tUl;{g93lXx zxCCx1T5F;=eYAG;=-=Xpi*SykRnr@1%sjSwKRv?l@H1^(Skd(I)Y#O+@o&0{Xp4|| z!gZ5G90i_p&{r19346;zW4w5lH3!SaMD^|i@OXVjKU~L~8V+1}=TZVgx(ijQ)5s&iiK{SJT$M~@_zzpOQV+0SeKehnri9=75 zj;B38QrcoGT`F6#8BUrJE-ZsK%%Rt|LuOn39u#Y9+@pVED2UC{}<``q*L{SbrYJ+R$Q9#CUb5 zZ@pMCUDD4E^&sP&K2E0lg+r|<6Sz3Lh_4f<{vE6Nh@-IMya>aiU!KhGEdm*jQwE0c z`^KP0|NqH+&VndYOtN2Y?YyjhFu zbjRCW^hne2`Ftz#3)Q+rC=kJlHNZ&d%ePx9;=cOR0yqyFv|$?TpK)V6K@>$TkN!b&o3lTkbxg2!aWHA}7=D*V!4Jsdd?Dq76**0L!K2XF$Plf_m_uUg8gjg*G41b=-fd5XkGa|yXXiUoK2&*w# zA4|2AGG6=GiD z2Skh!{Qa<^gf&?VGZF@+r5B(??-bUdB>cUlgDvZ>hv(`uPc!g8E6^fs4Ws*@&|qO7 ze1T)B%%mRtqJO>^KmQ-&SI^#Z4(XqFi(&s^nF6;M4^sgA0AJ}S<6#Z}kBri<>ut~K zP>+zZ|KzFNlH&M&2y#gGDE)dHKEt)_-Fy-hA>O0(8+$_w+fzI)NRvJSCFP`#3-Z1` zMYlsv25I|8>DTraQ+RjLPVqMB))LMRK#n7_eZf)st-WdDPME6sqOE3dTv=?&TNkDP zYlI`Ck8W)5UT?eYHhJ^_SH@p<_d0nbPGoxZw%45e7~_BPRBJs)EKAWsjz1oy--Vt@ zoMWw-75yXTTDeAzif7XLfCG>ypx8G`@7){r2rOKlPObh;nqmQQN5b(3AqpSeZt7ou z?@SYG!bA$-gh>`&o}}*{hDmK7puh!EV}p-O9i`ufM@hZ~Ie!9?Kd`4ztE2kJV-*0B z5xiIuV-d_l?Db*a3PG~b60r|hQn#>XbCI{K zZfmhe@7*UF!4aE6c$r`~8h85x`EdNel0d9JZUEH69|buuHiO3PzIC<|lVi+u?U zLE0mt?!@sO>N$92sWL1dEDUJ(rVB!Ie8tqQWXIFq4nXlP3DiT|bTGovN`KT0(IFo* zitQL!j@$}zrg0-+PI+|y(SwKaED+GrP(D3nlcAvkEB%)mXuUsK>_WiXGhXaJ&@M=m zcoGfeI5V(7>}lZSz>9cnu}OP{Ltt$~`HY70<#c!eQg~E@TPilSEZSh;KtS`9HMFVF zym5W=?B#fw(7b$K!qK9Zmk=FOC2GtV-?DgI^SYVBNM2giGI4x@59#&?O7p_eqUdNN zQkGlhE2!C7R}mUZ@h%A2&o%O}v=|$KyWcFr!xck-oc5)7UlO7y?Yi+E{pR>19Bn_s zLVAQ^DZ>x3^)sy5JjUn8LyXqHC|0kBgs&B$_#$NHFczGkK(8 z9g|OD8)yvID?6y!2TU%DU2sv9L$ngqJqU2&m4zo3^$!XM2Yj+O-Rm2Zi|s_={wxX= zM@@M2tn*ObQg}y$riidN5S$EmX)zqMrQR}foO<+ueK7z6-qHwGd~nIajU?FX55f&q z%)uJ8c5eM)P6$^FVIfVPC^7ob0sR^m9D)xBF>g(iHZg~f9$wK{z7;V9BA#Fh5q`qX z*n~Yt56rVUpIDOy$L+^gY_(yS-c36vHm#q+7%9@n7FQjgza+65VT>3lTy5~Wg>rnk zK{}bi_k>siTPM)YeAT8Fnun_rY3Ow#8aWTZ%+J8SJcEw~+ijZBS!ShRkrn(8Q^&KI{P$ zrw9_-N8Ui8VhUmy+6?x~ z(L@S{l@C_%=rj{9cT4qn^v7cp)?=JN=_e|V#>xq?<=e5s#t5OE&}6-HeBMgytddkT zR{d1}qi|R~+Oo77=a5>KBZRKXXqNiJpz}vNck!}&>gwh-_%2oLq*f-swRBn9e(T{6 zV4ra;&MrW?grIS--Df`|`1ge7DaC;nFCBywjDl?-KZfhx^nqjeDn$(q@Asr1A*PlH z+XT?_hF2&hOkfD3Act>TH6j@L6e^iAAd2c=YVGcX4;22-$*HR75L6cHC)!TJ${s6v z(mF?Q{D`*85by^z2DP*ke00 z$_m{lzQ=wHtEi;<1vPtcpeP9SCS3JbrkERKWmx(Nfv({q?7IfZ{6N=wbPrU9aj*Qe zad~yDdPbu4k!o(FtDk6r@I)6kIc`ohIcgW<{_0i~`NGM@2X30$gyWh~yOr?Mr?WWV z^_MN?+ek1ndfPJ;CLf<5!Zii+J!tdzOPdXLxrT zc0lvGNhiuT;mC2zqFu&`1#?@bE^S#-Ee;^UpqMoirwdaIg*!7F3S;?RaGubBYptxb z$ZM1#;Iu60FQVNDd4nGPMtT(3KoLegY~O$|6hKq)WZ(mrY)yO)W#TyuY2Q%5E^r#- zU?~^#y3tJ#Q-{V{!wp5EjD}=;imk6!2O@Kawy%E~!w5D+p6iY$w zWE#RUklfFA6vJLXMDB?nzpWKbFRM*$Dogo zE02q=-ww*M0noHz2Rk2^Iv55Sc36X_SWKYdG;Fq)5(e$?2BerrA2HPH zkNA-k01E~fG;rMKb%|p3u^tIcGKlB0_5gv5DLdWdp1iVv1$Q?M25UbUs0j^)y2geZ zf;{|XWmEx|wGes6$NZkyM13TmMaI*k&7`Uo);fUB7cX@?uaD&EnobTkuVtV4^6|}6 zH_>h)f`v}Z-PJsGpTjx*{=sm*6nX2aL4>lgezW95|Zhhx3n)>*CnC)rRXg{LV8K3u22*MgRIO!eV>a;e?C}cyPXS8Nw zij3i;2`L+$Vo#I;J`&a*ezKhwsBpNAH1OnS0Co-Gx6PN56g*-K4ov!C|wAV`)QPZCV6G$bdmH;5;AMr zQTpi*OFanZW&+Gv*{YU9vd0420QTm&D{~#980VD{C$5G+z7D8J@AeBt1LZSCz zY*>1X{`t_5@=wHuVINOcg7Sr(Z`FhfrE}p(EP@0b@YHc6qaEoe!mabM+z=2rKMiL$ zps8k>I`R^cgll7-k6_9q2^rJO*U0x#3Ycv=d&+o&AJ$3Z{+Y2Ylbcpeu=fgJqr}!$ zG`_T?amhxmhB`2cVv`mk9}J6I?dB63jq@fRJ%IQkN(Xav-(&(6{!xh8Scx@T<1#3p z0)e=N&hq-cq$VFd^t^2HQadEgYVVF0;iTavb2V!9lJyoGpCM`7IEPz$?9c|gr55PY ziLt#qEKj2BgaoOzcEfFSL{C|57spg&!)Gl(9opqc;?Pv4J|9RS{t;lL!fSYFT$I_6|Ne5ex5um&1jl)g4wLGgbS8fKk< zvFr;5Dnct(1gvZ6Q#x7fqP#i@F@iX!Q79bOa5TXTwKD9$j=i5xWO$4RC0X9G=Pmc)u0O@>Ek{sYj-vd8C!bM;ngM4%iL5%JLWSB9LFOugqeenGdOGWcQ zdT>x&m?YCxZq*><96~cFeNg-=Sb&NHGDO38b3FP)t22_KA)^t}bnF`o*K8&?8qQ5v zPazjk-q1Khaj<|Q3KKpzg3wSk`w=JRJq**&)-N2E z2UAaUkGK%*cQ20a_{UJhQEE-JBHpw%nm`xGk79cY=6(9JG9G=J92PR9Q$(-Abq6C7 zMsc?iAedPE4)agg+&B^Zv?y00hNSGID-eL5&&p9AwjHUCHMsNqpu8# zJEVg)i8q;W0tS&cIGSTbkrc)sp_94d(wXF_Np@^oQX9L8Xtpj`lu$A&N;iUip8P=c zNy(BAgq4#|C+2a85|hGr1VIXb!EYDDsbnhKw*mr;DoS1UNs$`iDh%2;dVs zRFW_P_*4u}8(30#gFwS&O|Q5BqVU8F1^=i$W>`X8T3%IN6M~ox<8u)CRjrxHqrcgS z)wRscw5*}xpa{*~hozULiA6rB)$FTIjzX^x-~fCXQyL};**qaj*{0%Npu`Kw1}Ej2N(-AP)o%0b z^E_5BHc%6B#0K|_4XtTuuc}ve;vh%LR@L(Sw3aDw7E}B(?On;mW>RD`(%|e%OnSva ziD|Fwcvs}QvJzl%&+(BK#D-0S*P1rK;H5@<7+u=h8%qEaEr=({vd+U;!gNw+2I4bC zgVSCc9?Dw7>Z(sOB9FfKl=@Y)XDPNQ zX_1E+Z)ZXpGTQB=jRhR!A%6sIM*xPF8at5eY%V+( zA`t!t*K) z_|RWzPYa#JgMCja@md&N+GXah-05 ztA;YN!C)!!;;2~>c8jqkTolFZh2sM_MC`LlWx@8gY zmPbJHIUw3%FZJRy5DYe31lQzUYI$MnvQ`E-BRSzi5=3EpjX;)%l!Hm$qT20s%Y?hi zz7Bj&U9smaB2vh&2KzR^XNGXwd_;zq8Uc7iFFUrj97pqG`}Q=gm}b?oS9rYOqxDJW zSoso)VcEAcUX52(qK-K3(_^F;>E`MVk=aZu8Jyd|1!?n@PJ=^l%5bkbc>-PUG1zJ! z^aCAgLfRD(>Pq6YCyP)lvcPfH+CK*N7P*>l?(2&bda>E&$4PCNi{w(Yu10}ds2z{a zX3rZStY%<;=%&6k8zMNujO||XD@$p<7^LGN*(}T*ShGIh^XONKUKLkn#7rG~H_NBm zBjsC;R;|T$TNBa*SHz~^$ZL{?qTk)Tb5`^6P1eJS$9Pdfx_t|hXKOxaf~m22 z#nRRp>v~`_w*p5e%W&cuM=jyL#i7giy#5|Lrdo%;U14Bt0$5;Tr3W| zVe2)|H-`2fm=;D3LO{Gl9{nLWN084*q}V`}2*Rm3^n*{IVi5+{3#?Si*nzZ20X|kC z=|USL-7x1M00r(6EB+9zD8^oj{s21_;1S@ANbCVYmWamX6WQYtTfL7GsxWSA~s{Met*-{HSARYB=F#ch%MRHv=gWcW2+CvDko5;TmflO z5qRsjqcY>+TevwmqO)n?vSTZ&^$`0D@Su}(;c|9JA7v25E>eI_a~Y8UGUZ}xFei#t zPADhhEfj~k;7dT{rnMy{8I4mL6k`F4g)&A!k~*mjlqrx4VyrN&bh!zsll&1p5v*zo zYgQwH3ax=h`h7UQ1zU;^+0y#TIu~edO$D*;LPgkABlwI*1P=j6CU7CF?Qjiyq0vn& zRlVU7Y+C}xdgkPLL*wW{W0jB0!gRtTzGWp(bs+Hy)~fiXW!GIYE5zbqgNSq+M@tA&O4#TY>9TPkQl!j1Hg_Wis@U${N&zm2fJ;6z zLR(`9a6w*x@@W|PbZjm$vu;r4)Lbst2}rh$Y*5CD8M~UN&!H7Ug1QqsVa@BN;ahBj zt*10n8@5@8O6+~Iaq(|kpSmlyY-J1yPKs-r=$yV2*>byKIZEfz@mz5xFf_IlDr8|^ z8JY9Q?}_DiU4>zm29R`G?wxUFPiz)pLJ=JtCO%F*=HYNn@E@MR~Xaxr#Am zB@Rn|f*6n960i_4GzhrHBWIU4QnLqsIeEN=x)fR;Mi#mY`E>)` zumu;u?pztp`H2}oY}Y|c1&|~iilDbNed2C-oFFZPFCF}$m{;^JY4Lm{x+DHE71`B; z%{n%Rc&Xg9WyP^A^Bb4!KUO_Ews`?(K|i)>6DPd0)wtz;zK%^K7H!n@}=kuD~gY+P>YBSLsiL**Lb zfI5tSQ5ENe;c3B%aby!;gL;;;r7fFoB%KnTviigXI9>M7#2>?uD-TOp;b{<=HZYw0wF}84N8mW#lws3=cDKd&Kqhf9vY_A)K}>u5 z(v=}dMyZQ&vJ4|b#7WBTrpy?kw^PRjglH`IG4t_annn+(hSTjZ4rl4BBb9SxPnUIRBD_U;r zkKFD@;GS5ph?4@ec&o*_N@o2ohL(p0K@4J$TYdGIDCa3e)^KLb-n&n*aXrk??^bQ!Xs2}oo_Lq(XaNqCbd zGM<$Cz+lUVrcD*i5vr%kF7&Pr5Xu_6S_yAtn=w}%mPrA@w{Ew1QDA(#jG0TVh0(;u=T_{MG4zVDYA*b z@gO&JZ~>VjEU7juFWzDD=%xK^*E?C8GD#CMz`*Rq2V^zkMy&NMtW`=5NI5};g3YkC zgS?}1PbURfChv;cCzHwiOw4~pc@*NyZxEL*C?-j|U>C9?#ij{au5!zwW`i(=6Jh8= zxCQKlU|Yi42l41WiwKyzp`YaqbIMWVz#xAC+pI9=G3(QQLcBE|qYp(_(>91-c;}$_ zlTfT|R~~(do??e$lOWB4n|~3avQ-|cbO)WK^Bp?}uyf;E0vYpJwc&CvvyEEei{@qg zOdJeJ$R{P{gOuz8_U}rhaj>UJNtNgsu;aO(*R7M*$Q;EPl`vqfL)F+<7A|Y}ipwPD zgc}-m7N!6YF2UW6AsY8CCpx*2nogR`mOr^vUMilu$)lGf41QXY*x8Q|VMqgC40JJL z&>$kWuEhf^xP)()-L=BBj(c(QF!0%Ln}BHLQ+i3SpN~n!&Xb>%`$vY6Axb>S8No4Q z3C@TV*DPDPiH^xir_Hdyo()A^U^$ zSK1#Xcq$8$vIrrGmhgItqcG)qp8(c0V00MHw1CeG?IOtyZ#$MSl5RBbh#w8g4|ogc z*MZ3S5%$6Mvwt@Tfx$SUPoXY01Y!p*y3)rYAF2G#N>}93gRu$aOHK16XANylF)kYgCMniZ*wSnML&jKDfzOljRA z?Bdgp6cGYa4dTQfj{4b?AY7^92nOm}^nis;DV8|Rb?O~?^zC{-gy`=np!0w1N$H=c z?kU^m2%P4~K?_CR9I?cL-_`obqX7u4;7OCx_rQMxB_I+wg|WoNvYB8hvI5~3VlcxL z7r8vGi(oc|-oSxEqjSo@=nTsTE5I;LTNPkn!N{_wUHwIUFy%Fb-EQ5Zy~rSUFZ(j+ zcat!xtxO!&&n02yh?$0bIT*k=0EamRKhc46B{X)uNEnv@RE(5E;_M-&6xo&5AtcI= znbKUEW2jMdswj2Bq)Ex@J~XLj1GfppNtsOX>q@v%9@0RH%#`tIRq%|$Fhm|Bf|KnP zF$RfKG9X2+%vR0gJ`=y+&a<^pI_pX zN%UzvV^Y`;17A3x(7Cv_SWIF5wuTbLq=*xRmfZmFhDag*bIi-gskDibJ<|Vic4D8A zI#ttwDCCYz-m%BoCvbQMyiD<}`;>b|$`X;etF>?&fdR2Y8)6eG+4E&@@moI)g`IQC zVTqLHTVsbOP>>eoq@0qJ_i3F@*`4MuI5923O(iB>Ym0n=<%d5pf0Ectmy>YnV6w7G zvOhoFo_q7o-7Sk};v32(nedZRC+19Rerdr+d#gB~`uLVbb4a{Zwy7ohNMG4l?8rbT zB~9&^w|Q9N5)ma{$jMnf%O#f-54K~xoc#A8c~@i%Z}(kj{~7e8Nx`0)fZ zPBtl-L@8X5r%Pm;OnGh|eU8mD%=_w3>e&o$S z>=j5Y{9{nAI2z_J@XB0@bT}wZc7_%S8Lg)AmT@|Uf27whC*K%WlDldBNz*vCFq7>A zah{cGz^0GHS)y=Jf|_5g-{tBNqm zc}B-%6KxZj_)A2!Cs-&Xf}hNSbakud5>i$D-qaE3(Vy3A<^`?u@bnaM;7=T73rb6* z*oR(*vVb8%+6|HItl?2D70sxrE+b*`-s2pf+-8NUi~m4Y4vy_&h3%yZ2$|1|mPWCP zF7xR9?$^cve6ukRaOl z!la}7C$Vi{*$D!Sr1J;Uv=7P^)~py!GrB!^F-^;bETT&=rPCQ5U_~;Wr49 zX@zVIl&L{Z${3wk;MzlC#0ZQ>MDJ0k8M&^Ic-cTQScu>!3u%jl$5;e`Bd`+WESEUP zu^SPyr`0p?Vk57>_$*eO7&f$hV zrj3A#&xrbi_R2D89zsT8gj$JTGqo!iJgJB@1Tz*Q3hTtYNti}x@;I>&QCY}Gu%Kn? zX7W=mSdD{YLrcQmv3X_i)FXQ@G;^64*W3x5Oqjxf_*c%Nv|)nZ9)yd!AcS8eq}f8u z5;Z$>eKeC;6+OCFJ`Zwqz%;{gwXna;O5~gHz%4B;9t7pc%%>FEA*5~0!;T7Kds~er z8JpzM7wGlNphC%`NP1YL(Zm`JNp+!d;T#k}Hnb?DJqxI5@)<%E3xy3=qDXMiw(=Fu zMyY&-Uy(eIoSrdBTa)iHN&j!d5x2o2FNu{d78WQd4;N!DcqmkGqV|MC+>aBQD)i;`1MFW2h`ZYiXg{PQp_L3BS+rG{t-9*A>Q{Ajj(vD;2!(8Ih>yA904T zm4R(57LVQ~xhpBbNIJEEz>*X;ODe;f#Wn(rUEVIh_5l6ZD6C$Y79E}U!*r}ql&prmCs>P3-Sc5tqsSO>DQ!T*lr ziDkPr%jNp@`}&a;H4ryI%Ry^ahS`fv1-PJT+O|p1KWSku-Nu$PnjRKJJo>GKCH9g- z2_gI7J3vV*l1Ys&A*Yylsu=8cYrq`@RLRDWwLyoJXeih{i24HYhpC|@LMBDT8k4X{yYjL3WzOwDQ4hzSuojC zY!)_E;^sb`Q`?{??n=?|v;=D7J*EG&Q`UBc2LZY4F2}gxpe<`-3Uk>4IMPyD$-!H| z;2%EkYDHC{X8*pI^F|qMvWW#o)7CXy%L?L>N84;ILqm0TN?VuO+9j!#MpvZGYn(l? zaooDpmbPx=#yOa#WgBOqiN}||1T<>iJ#8LfIc9}Qg^_6|1V)A;YnTdWq#a>~kp(ZO2v@_o zG5LG%B0)mfz)yDh{AqlaI1WUvO3tGYrW*!1czaKr>mpYumQ`?hQYHNE5sRqX00XqRpdnd5BKCsSz0~$&U=vFpqRw@V3#z2&QEdz4`sv)PM*jVHSCmk3|nsA7%^lL_RH}+1Wodda> zQL}-5!cfe5bUz}xO{$fI5L^mq<4F)9esmY;M6BA7-GkCJi65z_a1wbMt5xG+CCI%; zs)x;7{PHw952={NK`%b$CB@Krw7qGy9mm4>6qnTkgbjQ2b(VVM1th0*wx0#<(etxl zf2f!NEoo>iv1tXfh93h>idfasLbDaAk;tBYQyXhc(dFpzR(qj#mOC`wa=y}XHs0^E zI;ERmGv|9AS1x^>FUJlqX((Sn$?uXQ{;-jnuoG%!uEDTRi~($QKO&USJ}QM@1e!&s zvEt{ps8tCLSQ(3hIyhHlM-8SNr%GKrPfK^dNe8U-!@6{_X39_9wPpPB6O~JmQS0(_ zsj7+O6s0(o&Ko9AYkaPW9JDx|lz7ajmEYDr03|~i?E_G@)snb1EFH)C@8s@nt325h z&xr8F0IjZt8#kUan~a&n{apOMfZWI}Lr@Sx5tGs2B99>w$LPELb$FXBC{Uj%yZ8A%-N+*}FN3XM$9@(p$v>T2rk&V^Tc@#HEI)b)> zsTsmejL$$*sp^mbijEr5dKWAs8?G23N>CRFmSc+yzuRUV8%lk6*mkBP0i@?(+mRW< zhhY=;p{Z%uJrOLUUvF={FRlNkQ#~j7caS~2D+Nr#Alwcgh5Y>-;YO}Mba|p9H|f9; zoh{-Zr^F>y!ttRUBKlICFe2A)8>!4GkSZwx3;t)hYt8OtEc9Ti!c8qs2*K^0(t*OI zf}l}yJtwx7{4T;%O$UCgAO0b;Hy%<-KgEL|KM-q1;r^x+koMgind;H^>TJknN{3Ds zEHbXaG^kyMU#pjaTXu@qq%7&i07|8fY%b)cj<0s)KC^wU2M246Qml&YO>`jR2o7b2 z3FC+wN1f6%NDEY~9)$lzddw;L%L9B0#F_;#dWyXXDPQErDP0*)1S2cJ>oXcZU}tnk z$lXnkLw<|43jwxd$r2WlTxE)?x|w-Nl6+R)Oi*U2x_Jr^$Y5C@ zA&>wYNgxSGNl4=DX(#l=M0CtZ5%Xcb%}k?wNF*^cUnY7!Ow9cLYwf+yxsOc1T@@V@ zK~!1fz4x4b_SuiM*Wj@eAkMu7O8qpF9_!k)G@3_&Gkz)SF7Y0iC&)=xU0*Aai z81Gy9#PZdZ4q{>EZ%jGW<_IoO$KQFQmR&6oiTTYBz(2&5Hyo=-`Tngs#`nK+H`nkJ zNv->V^~TgT;Y9;Ds8!R&j^Nqm37AmiP@kaq!eck3p}kt{FoiiBPxI7BcjsXb}sq- zaLr8`$yHig&R!)>=O^F!@XStm>UKl#e+fEpQc))Njpg^II$IBVtM0UGZt}xRLN=1g zr^YNT)Y(Ntdl9Ffx{wVf>Tu{a6~+h^!Wj-#C6Dg4;WA4w=W2r7QF&{)Zn%bx;1r|^ z?s-mVb*+ID*IqfocWSDDaVTf)8gw9U<_fc2VA#&ngkD%XVgw&BE@+&8hOT@JE8~dM7YZ18aPxU%AmB=EJcjHdZr=V zEy@wqMh~3jvpL&vf7XbSVH@L;1KIj;C?h>cKMOQMp#v-v_)FvRk)b+_ElJyif%-hp zDZWs_1*R3}9H%OifDs!@YnQWC%Lo7&k|ELcga!l{mhXtAYR)0dV!(>{AH$Ny3zZX{ z`s?=GG28=MBo`;yb4`#2WpWk>ZJIno_2m&oPaYX*;6qjo1z(TKqN?}a5Dl%%E7cX2 zGa6g0_v3U1vY6y6DO47_wh4aJ(|OT^zyKqDbmvT-d55Bm1^-XD*YZlOUSm!G7T$Lr>Hw2G<%$` zOr3@At)?+P5YG?IT_L@&f|0cjJL@!#YTA z2c%ip4KEC$slbNO@8xmx)KHkMypfnlN|Cf8%X*)z^Zy|ui_mLBcsNhTK#=b>$FBnq zf-1t0Sj0wuGycZ8DotBFEAclvxe8uf;Id@bc)r&yur{8{{2-Y+zaK&>BHJW?aa^Pm zB?Y=?BX0D7SZU54&rRSM$Qr^sq(m_K;vqACf**o`RV5_Q{`<^Nt*Lij5kaK!H_~}O z^it%#q33>?nvRT&H`DoMPRA4ytnWW$9qAR)qrxlLiAx9LTO=~apMIk8c#Q`taD5I% zu^SP^N*TP`;!fkJgVl4{B7NdT&+<*FZGQ3=;$oHpY`Nt*hhvPf%{7hjp?+=sTmO9% zIsU)kk5y8{2pL`ICG3L|g2_ro3uwjVm?vj#RHkiH9kb zXYp5-iIQg%20C}vAA%K+zR;TrlKs7KG|u&|^4k-iOrgO*&sdyoF`2~VMlH|+XXFj| z7@5+7iuS){k0nBRO)%$HU%SOFLeLH$vK9nnq9HY1dST4GNW;&Ml^*)w*Wi9m3SR?1 zBMX1-HxGeCrZ2ES*1t7}W_qaOdCH|n4Z}lVw7`UhdKv7aa`x*)%?J>+z{}XAo)RQnsVFwXgg3K{-qQ!&;JimW7RIfCg;7Po9Im9gxdjE+ zu}hSsZmiHV7YAa_zc|;J-6|1dadiH^c^D6V0`h`bZ%AS?g)xQ7B0L8xVv(I7MKTrl zOd-fQnGSz52FAGtFm)nwFcwD$(Ft_LtA+~^ZB&tUERwfCzW9G+UN=c0%EBSyUbqmt zguGbUa(#+VIs1ak6va*F=3h*Ph}~v@Hm9uNeD1x0VDS`PEAWEW*7t2`1B<0yj z73X?$hb*$DLuqSH&bf&d>lR!~D#hNe5fC>VpEu2;__@W(mzIMlrcEa65PTcy(zP{| z;=`Q*P z5YRXh%`!Ks}wwymUGJBdVljf|y z?6ZsQ=&5s+xDqeMUX*KL3Cr1M2(L`;IY>3=q5}d`UnYIR+bd4PRTE=7lcnE?w4Xma z(jFey!G22As_en|iLAV=9$OF8)3VQN!z?MwMl`oEE8d~=Uw9zeVac4*Do#e3L5A9f zYxr0p|J22{%Hzx0r5-d>SOy;)$?N(bQJzPWuFn#8B|Tr+9LywDi}BtK$^nWF^=4K1BAh<;w7|}P>^~-ewg1lYn>g{@^zoN;$!C93>8P${ zsv{B_SE|;STsHQM@e_UEjz5#bj$=ovr4_8SwrVFShLlwXPt1}`_7oN6$ZA9}Lm04h z+Q!c@gfyE_ZsNvTSVYTWEbE>4$DaWEzPWmBnHe7SP9F>4sEAHi`^@(rmKXOa+k)Bw zaohGFn{=isQjR=qewNxT4~4sM_%N%y0dsa*ecTV6NtW=h0c}a;#Bk zwpxUcpM*9$<9T+4wYA{#7<;#f4#N&ch34ttz=Q!yL@F%kvSYTi;Bq9EK9v@77`F8j z8CpmXE5urAx37n|*^h+V<3on}Klpn1B(>>v#@gnoQL5gh18|gou`&rezK)QZ-}M95 zC7iww2%0}y*(BEZwE&y>y_H3I#%~Xq#I5$N%KmVrpNqLnQBJwA=(08>vAR}ebG>B}OxzGLE}vfMjnqpV@6}ogdi|08UN39x*N9yC z%1WUOq73n{RFWZF*$TMwM=Kiy3D?!cztmUlMy{;NzEub?VVG0yo{T4xB}AG+=_A7* z3A0>e+A<1WdrG-5;KLEk$rRu)LtJR~^qasf8hUvgzF9sojZYRF_*_aW6uf zqA1zjDMTSYNHTNBFLI6=79du9B-Eg+T?$2B>fqN9!>GcheNVxi?{8&1c`>gM!=iLw zUS1ue0!?f!+0B7m&rZhgv~q|W?K?*z=VRpbZ{)XFq!!QKo z2!}bbKy}vM(oy`64TB+bZ_V+tO!FD)b^G7!7S_uy3{Tq(hrezb*~_rju7DHpD>ve|+; zhnbEHt`l7^?Z<4o#z&R2;qR&7WZnVG6~i} zl=4;AB+-??`dk1dZOE1@btP>rm4phbAkcH>v5;cu0bWigd2YJ9So;Z*2>m`+H_O@X z?4guLRa_>V4EXuuk_?RXrrD%rA%aeF9zzn=T#wP3B)?c81yyW-Zam)A^vE(v%o95@TTtrUMdj+7(Hltsmc!EZytoAPFay(-+Q!3!TV_3-5lg>RxXvHA0cl(RDzdQ9@O}bR9A4o?17m z=(^g_@BlITHbUwBL+kKg$^EzVeuIeM1k@Q&8D7oG17;$UE92C-r`k6>1Th&`=>k9$ z0-@Xk!gBoR5UK!$MDf^s?LnkDIq>bFzL4^@E!Rt_y~9+8AB3OTN{CQF0ET(a4LNR> zKX`|`!pR{NHL~>2btKZ8ucxL;_HyG``mqV{IEtm!6}t)tA`na?O6E0H$Y8;PxY3<_ zk$y@cwpp-Az_OC8?$Ip{KE40yW^#2QRD75JGOQC%9Wb)OLm)3BQ53LC*cV}{hrgab zw&Mkg088hPI&gK<&oy5^a3YPFm#EN(R6G1~>Du#qjAPK4p^R(e+VN+_4fW~G4}0d z(C-gyx$UG7cESmN1@_%_)e*dOeU%X}BPK^=9~BzJi0|-0*eU>FR(kt~ft6s`xlN?n zQpRIJMNy{i+w3i-jRF>UPOZRfum{W8{Seh@+iW`rw$9DI56{00IDB&N*hkxTH`si! zApo`368}ciQj@n>jj^??F*gd`2AQ_XLGpO+JwvOpnHK$dI2nii9Rsk>p6IAhJebNr zrSWrv{p+e%wkK19@75VaTw8K@jyCT@kAuAr)U|9h`1`E1wRYg*;hOd%R-r|$`o3M7 z=OZ<5L1~`7q5g=kIIo=D`$KY#Mc!(h673>y>!3M~1zm)1pLjJ6V^V|he0Egk=+u%2 z0e8X-pj+K|RFMfnS2fVku=e_v9zXu;!*evUs9;747vtt5;)(6)Q$N?-FJ+=^v%Vhp zqOvlAxlWS6;Wx1+HC;X?vrPJ*&AfY%eQHpSP}|ay&M_XZy}Kb8kAjrU?E9Ir+T(@| zndS3mS(HriZ}T*n%~z9|>EV4|5FK_he}jeuRToA+j)s z7GJSRT*D-ScdEhnHRlZeU4zXT1%!EWuqx32e)_=ao#$NjjbrAf8;p}od2xpvkcN(=89?&|3%EnG3u+t!cavvB!f{{Z+$ z9ZO4!rtrUh7?4_}R&CLgKfJW?v5@NYmGYO%U&?Oxxa@;}dyFjs?)It(d-e9JXumBh ze*3p_d2SN?_NutODt_zssvu`4j zgDR!pKmdhL?)|SzuiCfm!}ITAvP~Q!Irt5y7?hFsg?Nj3^!*l+n%u!(xcFzf_!~bN zKSE)}4rLcP51)J9ublF3S>n)<(z=|S&s(QhvK%Cp8dfgE30y2+kp1HqEOcJHVls_= zBR|Tr2b!4XY-ljG1ThTW?l3SSamHjTxXt|m)cIRtd~b571j08Ou!btbk4IlMzm6Xl zRGB}ZhSuzaj zt~u$G5V+2mghin#Ckd;^+=uTl&tU4l_V$@TAy%L&z5B`wk%EhOElH{C;oLS?t>NPR z4Mf9jCYZBokuxo00oLS)5(}2UxQ#!S^*RfO8^)Wz2xCMKYrONv@Ba)xi+M>baMy|o ziVH5_Ic;55p6DHT5jPT0++i#n90_fhIz#+{|Ia^AVzSe(jluP=@TcCQrRUw(AtEXC`zmF}9@espr*dw!n?B&Y~*{@m2Xlb)sMH^pzZ z6KvB>O9H{B)B9V0yN8TCvu*sMcm_SG-f_O^qlyK@yg}alfn@^h;sFf=|M(a&;nr4Z zNsRppt}jz*PeB{`lv3)k)%0borX$~GPdQr=$1#%lcT}lmJ$}MsQ3G9!yf!0U9bsr$ z7m;8crwXokUC@GK`(6ruItT+`w2?L1yNa40M8NoKLrh0I&J}QU&eE^e`0OFrJn3Ck z+G7#}!y#IJ8Uke`cxgptj@t*Tm7xK?RmOT9=VCeQX%5C;-TZUo+ul*2-ZxJug^V}7 zdUX?ZjkjA?dbmv0ibK_xI>!CUH_ydjQ=mR*^A@UYPu9j_Y>FO(padi$hfb9of>>fdMXI6!ki@|_hugbH-y0DZN4eG zAw-~@t4|3RkcZ+w2-#4@ZAXMf?qr;4!?;-r(;U9UKV!*iN<+^!P`1;YBOa^AU8+oi z1q$X{X16oO1wMUwPYPf?v4n3V{4dh*bFpN~CA>1{@VV5p=BLY$C=F@o*}b;n$wkz= ztF}>~%ZKc3_{yQ7;X&09QK?`nDgr~k{hKr7TPgv#9OTFntsr(u#luymj0nXp0SOne zJ8nbNiZ6ojW~14XM%?(({awU7EczaWIXg?zIm>(pZQSiy5zO!N&L=U zih7yl>_1gT*ev(h0oZ61%MEwI+@78pmIH0S^dzu1ck z;W2)^ojM@n$HP+a?nT~KZ;fSU$0Z13Qxmw?We|#j_bRLp3V6|}zlot}C#yIVFG^vU zv~(J^i9_eEZhV=dlA>GPu+bmhD8$5;dXV#}uH468AUK2z+H){IEXHXHG6!7Iu9+7v z$m=WZV(j@qgyGLgpd%AauOhxqT-&+*+D=M-Jow1^eyVl^Ig>B0pnw!(%LXDMZk$$E z&v08%LTtosX+5|^)z_fpWYUl*p+SxlA7<2#7L%<>D<~$uKGs$>;7`1N1R3$3Vm^{Y z1tB5#H6u+k1u? ziuI&5_*p0gN8q@C9bD#X(Zx=ZHvw33x@#IWG*}ABZ z8J1PV=xq!YrPL{;zMi$*E>o;#@fB+5sQ?nInL6v3WDC5)E|gLgX>OLNjFz^3q?-~p zquTGW%EXXlu43Petf_b9Y-w@b^=e%h=g&X|N+7WXQ3G6v2KIkiUEmXtwXCivY*pFe zePrO@l=%i`EKLC~j7)M0e?fZ9;a6 zL+CxrC{+WoX2m(0`Y9Li#8|PyLu@=Kif=_>HW(TbSfHD56 z7!ZcNjD@0zCV4w5YamFdjIv7C_II=6yCre8^$`pVX4=;S)fSGQONG`+04*4b>#eE|Q$*fmv5`z+xDhcc6qt%Gbl|gZ8-?xWn5HNzy{1I4D+$Vfv~Ou zL_od;k?5P9;#OpYY~R1EcVPTA#D!IZiNlWAM4MAAvY&CM704>qcEm%oV{BbjjtSYU((88b7tD7cQ3i zP1Fb#1ktGQDcyEh)!X>UIr@Vnm4fx>2%59on@WB=AADZKGgc7Yo6N%R|D-a|-_})S z!*}#w*>rhpyXrh~R&dJ6`4g&oOBO|$k_^K-v2vdV5Y$DOP@`4X5XM5>nomZIa}AKR zYEH=XcU#e5e(3J5$f&?Z${}#OZF-$IRgZbA;hV-CLin% z@6$5UTCA>So2ar})Yqj@;ArB|))^1~8hQ-QIP^683LLzFe#{q@6fm~--J7SjzUpS9*4+I+k@!H7?C7qH25P9Fi;p-E6vYb`Ks22pAk0$B3?7O} zc=>6mWYMmaDEaf{?rH*AZN?wEzfjVS=n>YM?*SDoZd)^cw6C+P6EL=na|75tLU~C^ zVCQT!?MxD>t2%y2e&R=M;1Ml!&g?$f zWF{u$h}NtT`jh>k-Vc$AgqIj~iRlC3Bc4YqEYu6|82_;*w!*yE|3LX>sQx)9v=6l4 zJvryzxLkn4xLFwTE?GQXy4)bE+D^V+VEwA^X40DemN}g`@%%^oe(~Y2(30>g39{EL zlF-(f^s5oXjG;KOdlNI>SR>LQenrRDre~sfdgbcIdcpMY%-ETkBV#fkuNO>4*@82_ z*gEs%(=%J%OxVAao+20#8q~WRginqVD+#EF9$i1$*>ib+M_<=k28ZInh^Y}=)4^5S z%?WEOZM4!uQHj2OApuR9vTxf*FYmW+lKyj_jWr69%_1u!Uk$j4iwk1>H8!SJ#IS!G z)Ll=!=9W2Sgt~QXP2JzJ;(&|-C zH?8llPoKObueSNE5HLl7)!g93n=etU%G_DVDG4L97$um-Hd21dQ%PFg_eQvH(Syb; zivoi+rM@*^%%ETsn$rslur43%-Uq5+ccBhr!!iAf!~2!yHNN`1P+gCUqF+34$--_` zW6-|43}1X(4|JNQx`fVP={1fa1CPFqW7?G)8$r3IzKsvuB2gsMp`65_Zf+o#CfqBZ zIF0u7Q-GcDlL6>rb6UXjtVO%Ag$wSeFWBXP+Go+<8t(ft5Dc?#cCRA&!j8HikgmX0-BE;}2pibS0iv~$_ z7rB>HZb**Dz7BIphQIoI(9tP@3EmK?Ai88?&r%L)s@z#Fm22xbX8+2Kl|VjiE}-Cx zN?SXGpU=Yq@D%XlsZD1mE^L@MdYWwsxS#A=M5zxM- zAByVU;X40Nif1RcPcBfcl@-h{v+-+Pfsv;pMt5-4pu9Fj z)(a6lUq~bMSB%J)GyrDWwJogQE)fY!&o|!=aCXvl2GDb>YvWk_EQ?m0Mndv^c!kmQ(4^4*)U;ep{aySxUxQ*_ zRUfCrJyl_pqb+FOD(xL^LQKXjgo2Rt2rYgQSzAanJlR^Sc@ZX#*O7 zy0KL9-f?yFW{V=eI`Jwo!%JYe>)iaC$Pq>^AGbK<23%O-Ma*VAekWcqBglU47bb;I zMqk3Br=PXV zGlL!!h_cONM*ZQC)6r;(&YyXH`?r1nm$R*G(%dZVg~P9hbv+zCTzFsP&Ftznv(y}0 z`pbtG6*~OVKUf(>Cy_wo=ioGxQQKD;U9ZYvlpgOh4_XbsTd5lebNA(~Y}SFeI)|fC z>kCsxt@+9Lm+cYY4Km~S+FA4B!brdACxodfmZb6{ZB3UqUmB}3ZU|d^{Xx3^Ppu8$ z2u5#C50iEn%XYP9)|L_(U1u?GC50o*L=MKU%wuZE7LFw!S1=inyPxeBZfD7%;i z>17x41Fj~I4=2dlDn!zHZ?feu)mP=bL={ew{x%l7vfNfz*Yt!W>E%*We59B|kxtBt z9^tSfcWwTOo?q0LLv%sa8^{?htWp#8>C4`AZHLTtDr0=I0?7r zV3X)3>`Y;hQG=0~&96tuo5!l+ot0r%eViCBMvTq|B@b!h`8gTsP~{JfAH$QVphW_i zAo{CBU>3G_m9xiE6a?|ly=c|>y9h+X+QoC+Nx()fOFe>D32zc(#U1@jkUb*=M#|a0 zX*e*7(2|KuyF@6^`rknRdNdi*HU}ZZQjJN19X5O^oXj*qEfUcz904)f@t1Ld z1^% z^cS%Q@CkUzp_kc)fJy}s1AitW_Pu%uEbt2g9AHc-<{lNimgTJT{{CJf7!q7E8S)@U z$1oyQo2?IX#((sIQ}}|@2u}b=7t7|o5zqx|pqzE(VPzTmxqDn`*+tXe&%r214c$_@ zZ#5#mjt_%M1w^3bF&G|1D4@BqH_YE&&Q{{;Ob&x^wkMhChJy><6ccIS@^=~x&kvrs z_;bKo>B?+Xkl6*_LU=^%vSVN6t2l7dgDKNHUoKK?OuxR<+g7WzUAQvqiBaklUXc@~ z&fnmMMD7*!$CpbFDjuz>*G}9oeOcMcP+%ZZh(8S@0Ts?kEyHPH5o@_B3c;A*nqc?j zt_hozf^orepOf)IP3n=2HxH$eMZZLws$mBSIWHm>hM$SYbH-kA;!&u8t zGz%yF0%NkMZ;)8{a0RsC6G@^=w=YC{B(5V$ry#j~Ee5wpX@#mXJD-K*evaLtY;=8V zdLBIh)+R?n7t&g8mA_76UUE9VFCvShgO&~36Q771%xlQ@Vbatbks)}Gy`4^hVgopL zcs-PqSF;A!OBk*Oq26FPv<@W|6#gL33*X2DNR^VOc3(orXdRN;I16#bmMr*k{Dt#_ zB7%gTZwg5@3jVp+Ev`SmW#*+fnwzkc)WX>@l0xYrTxEPjb-o`%6NOVDZnc*D7K9lh zyS6AUP?bu`DHj$x2E%Zb;%O#S25;j)Vfmx5AihXUS5CjJel)2-O_84`ac!7K$#_n5 z5H-_Uh{>g{#fq=~u@)ze`;Jr0D^g;%^f)E0-++=SLLLVtCx~vrXE9q%U-L_Y#FSAW z|8!jhj^nA$t>pvYhmk4uoIGX%SV*ldu8yMF(}g_^acnQS^ECoSo#I0qL_XTpb(M6@ z`_=COUmYryHufyx0pWaY?~TZ7Lrd*c-74JC(}mvzU$r>DjD$8%WStcc^#dv6 z?#n*5bK=}?MdzM-SLe;{Q+TO-hsj;F{mF^l@7aU+^P?A@<&ba}X->5E19xr*2iE>g zvK5Tjg0{jT^`_j~G%&sYP@yd+UsH=u9fD(1_QUGs{k86qp_$JYaEQko{%R7t((L)2XPI-00~!Amnf|CCVHt=K zuIQ{P;nBhxu|aPMvD%O=7b~GWQ0X8E7KEOocd~FH$a1jk79}J!XiF~DU(*$GMb#EU znbb)Uw_54fumAe+-M>Ek>+>8*P>ic}GYOK}k*tz(*89DF>b=$QYhhB@f(N;Uhbn(< zL$+$M7hm7{pfVv`s*#|`+z>b35S8_B8xA4P3qPy^v_Y20`Ky~L+<_$`Zjdn96T496 zfI2*72aKWRWuiQJb<-~slU+QStd8WypIdMeLxq^+(-z583Ak)D9Wn`G8X#G46P!9T zbMfG{BZqB)1t%61NZ2KcNyY$V;=GGz5h$+h1R-DAE>aSqTAzB^jF`g*KYsh2!Z}mJ zD^-PBq@wM0p{I*b~NKEihhhD7+a^7ve5>&)iJ!V!#-?fl&CVDuNj>oHuzPI6mm6vmVaG zCIZDl6RH?*1>6I~i=#t$FBwN-@{4xSZhg-;$QwLLH-+%(Ti#&&7{Y4-uAfm9*e)?> z66Q1~lPbDvw~b$rW~;qnTnjzDGKXvw4b345JfQt#ld{2oGG;^1WL=L9}9XLW|PAx1YH~mj74nmR2m^xtr;5( z3SoSn>6~(7nJLweDOF>V4Pq9b87?hnKhGL-mFysMWC(ofL{9+ia%{<A?Y zI`u3ROvgB98@gnNs2{7ymZ{w*!f>S^k&fowPpLm+PxCDA63wPIvwxS>`Ow-%O1&J2 zuxyiHm7>Pcc&m2f7pqm)35Hkl=;u;#eqEOyXLvIvWSWMW9jpC5&S zXo@+lu-;=o_6>o<=^0{`a$Iv@R7=i_NTkyvP849V42F=vS#=J@R7A~`09(1^M=^R# z|0`OddYB%r1APsiUDcZKhr5y(4cKyaC2ctdS6D@kMqGs2A0E>Q=B1oH+JwLqgnbXi z%{b0$#QGpCp(sLW2`n*a<+PED(RljDjmM8_Tj8SIiq(1PDJ8DS#yvSw4B$&4h|i+c zv?Uo#EWH0NBd(9Hk*F@$MdY)&oYn0rIg9v7g6KfK@JU6CG^M_kOAnwS{LQe8TG=YO zIZIL;nJ)A^zKr~l7|W&(BrDk>7loV`XYK*b#RbGV#J(=R9$u8xamIr z9My~~)Y>|Bb<=z1AU&w4S%5JSJFEAU=9w{4Lt@?@YRD$V;2NBzO$mJ7Z^CcKCbq(~ z^ty}82vS#UkGzP9GiT6(f>3IBeuGheY~s|ViC-NI4HWv%b@lz0iS8Lao-h=>xBou# zN)9Cj>d~&IvT1Rs)PvG_`^6Z z>zoTbL?U`UMt*oc(M!J~Je`2SJN0`fq3g8+kO2s%SUIaGO!8Dq2c^U z`8M)YspO5Y4O5pj#nlcf3{LNs;>)GiyPvrE)Xm%l;V$kJS2QQN@&zc|3!9z*zUDe; zQ8mjjxMNig7xl{cQksFml9eUq55nR*f6RmvW%SG#KXMqFufV!{aPk!xVN zw~zVITXI-WX`V)C9)<@HHI6p40Hxs5?8-RurusBMa{@OZ>QDis6LQ4xcMv=^2E%~Q z;j$74bc&V;$4P~~>@Vx}5ji0ephl;Ezo^|T8mb-(VWTqEs2j}aVE-`j01kDh$_U^a zJ;MkKyL#yS!-dY<@omRB73^ywMvdL}d{`53w5rg)pyZY(CP=paPykMVXvF6efq%3J zPA1Oj{D(#Mj7`s6-3(raG_TkFc+Fum3Z7Dg{?-rrtWrcc8x^8aCWfO;aZwO1_#Ofz z#uz$Y+I}l1YxY>ffrkxCCRijyM1;rH>G4qzEudLCJY(MwEfM_!T)eL`2of4E1e5Wj zy2$|ZoWLrYYNJTB_@_;^qVVgg91gaOaG)8SMJgQFbXJfSP&wN^OEy2UStWMx83^NS zJgVgKf3THrRl8l_=;)8u1qDpBkd*?O_@x#gHL!`NjKS85%Yd6V)(QME-tI4KQz@%| z{8cAY=HPXVQZGnfLZLP_A+2Bj zXX&wMsmVo9&KA4 zvU3Z`wz_9Uj7$#qj-Q|&>H)5DY%%dtY znJjYZ`mnS}<|qD0B#gC{EK@3b1Zz*p96wrCaB#8thubJkl{1AzlPnIqL=L@l+sqtf zWhOZd#lxp3cWl7y ziC$LcXf~hfilmt*wfksncrFS6e5MDt%$$8*cST=nO5BKm4yE6819bszw-%J0bmipo zXwK_LP@#Go2gyi4Z<}8=XxF46#x)@uAE*plkf?JWXp4)%Sa@w4vi-thXvkrOg56J$Gt*J$Jb$nkOz z_7C?C_YFrEB@W3yh@?5(+~7?FGR<)=f1m?Ke~8Y(?BfqRCw?F-Bfmt z5>JKqvfqaK?a5xRW>xmJ(0C%EDm_tmfN`;m0j(*+L6Ri!!Om4#{Tr>Va#>x8r_ZmT z1}w>vp)_1nu63pa?{Y*T!kF*m-pSP(IHzJwC)cJW^*`^#-R|Gik#O;(^yTAkPn{lf zrPy_6UHi?%)=f|%lyVBHv7G^}6NKe(T;z3}iIUrR^Yyc>`XJ~^RskV5qMVZaPjUe?hPWGq8!2-<7K=y!5 zd3h%1-)^SXMgT5HoQ^8SO9vtC$o0YX=;9+_6M&*z+0-|J`CpKwt-x{L4DZco1+7nG zZS|QkBVw(P&A{UWQPu z^Tf%`TDxDG7~2+NW-h2FA%HsA7>4+f= zh3hF4@GWQGxv!6B;#bHuf3ZlY9|-nA;y~;|8zw-D>=3|Lpgg?ZqyUDCAAzEvCR~R# z;6Yuj6>SoG8(=OWM54ilE$6u0Ar?H7F@YReCZx9qMC=Xx@dTT~v$?Gu!}-Sz2MT-S z>ZW(hSz$W}|AbPoH(TuDW$hZ~FOUhoZjpiK;rW`{e=cIWqu+n&%$9@K*hSCnsduVh z|JfPUE{9X_ZD0>u4qxB=VxFY)@mss>$E3u6^~WOvWXx#gi9ROGCc8`y?pU3d_g8wQ zM#5)v(K3qFF#3@$#`SN-+QJ0jjEtkL;nK%AA22T3*`hsXBo862IzJZ7FCg!#Jjb^A z*mhFAHp2^ni$Rot{04)UmuZ;KX4Ni!la_E78&*wpG;Cq8OiS#5!RKjvv3>l)h$aok zr)XeG0`U|J{e~11$}kL542kmwf>CzpmdxD(qH!o}%ts%7pj8z>qwp^G4|dW#FjwOJ z!z8CbsX|_=ayGT(S6J{*kpPO9L7mZ~wFGp4IS8IqcjJZ&{P5bDg`j-g-6eX!zHAAM zCMWEp7hl3R8hqQu5`Y|dp0WMmxhGrn$}gSRa6yo_J+Dk`-=ClXsOWk#34`sSH%V-S z-ZbE-8~c$81*#L4M%=m+;mz}2?AS)J!N!hs)zpWm!PG(w=j=l z)40n48+oZs^|!;Q5XVoWP$=Y>?Tvzom&UJTXV;)6fH6nkYec2zV?BPXs&Ve&pkxxz zHyHd1b0l-Fxo=@Fx|kY2MmWQm2e=LQy*s;#;;Nio%IZ(KleQ>0{F=Q}g>UNc>fT_h z!i=xC=%HUXvEe9Wypf#11Lg1&Y_V)u$lwU`k8!}}!@$)sgkK+4e21T<=2d~RZ3SbV3Y>^I|;~CRnnvN zO6m&nc42nc6WwtrWz!gxv(rWC5rjvsO87c%jiAq`5sGLp{8$tr7-CHl#0}l1Ua)c2 zN>g-hbIGbgBt30Bzc~nwJ)dYnkjG+KD37D;31!U|bQp}?(r<*lFSJ)U0su{ldQTA- zLsCZmJ;En3;38XFu*+5zD1C`aadJSWh1j9*LxJ)v;FOCzTMJENSkA_>73fXvcKY67 zY*_(bi6m_X`g<24dxezf5dVC_<9RSY}(z;Ju3Mz_INYLXV!Sv9%md26yW29NLxbo5l$0cpWoKyHC- zK38_)NX%cyU)@-0<44-p+*vL?7O6IpLWFLF56eeJ7p8$>Sk|SCwnyTKqn@(?K`=7x zFw}Qe#%30%Xq^d+H~~s+`la-DjZzI zygA5pI9DGZpq{bo7ql(g4t!2T=0l1|DG2jNn$4-zAVbrH(*S7iNUOn0@fQxa$F8-K^&Jq2!MUjLqnW0ds2I50la5BUq ztp*Y+ByYXl4}C$|isuR<@9K`GdOBbGkH;^~ZaI5o-bW!>1?q7)?GD ztecKr-F*1!re9p$MAgylrTHv9I4oLf1A)@wls!6MqN2PYQNUcR)q?38tz9AeF>OB{ z+am7P>w6E*pE)!wkqwR!f`1PK=!uL zcbU~4*I%iMO%j%Bx%3d%b`0vM-rzDGt)Rh{V3xpYw~VtqbXIx{tclF|9`iKm*zggu zmdWbVL*=sTuJFJ>cT8d#%CObuVdDJnNE^{Xff3aD#mn!5B*8M!Y(Et*3isHa#f7lK z#dUJk=>T}|)WoGN0j%ygfjND7++t6hIK?6Gvh3afGH@rJHTN?x^mftI>0dw(`O(ww zsD1o=FF!|VApC>H!$M8mA7#Eu{S247e|~wz>?I{!Lfp;QaS8yVhvr3ZJKnYlWR#_-7EJPjH z7_pP9kXQ=TkKVkNhG-xmmNUP5ysp8;2x)Phghn!hzK%VQcxPI;Bd#;a?nE&m9D#(m zhsfgP;T2T1qVE=ckCvBJAOEs!E)1u$AfD~ru5Kdf3&(#8LoR!yAeW1v(i$mzOpR}{?U zY`7JZoLFqFXl#*yNA*pRtdYED%pQUy6{Va3QR@V7A$Zm-jmz0XwtsY(*NI5WZ3<$N zkzl>5J`z68up!`#Si@E@sX0oJE$Hp+v1^&B&c4#Tr0hU{#&HY`>QlMh*0?uYc+G+uokr+ben2t#UJ){`S5l9rU)8>KjIq%(jqj z%jCM_@b(FGTf4ZeOWoESVR5;wC(mtC{Fl)#<}Hc_yqrM*dV@K>s(`+}V^Q+#xLYS& z=Dr%Pj7aP|78SiU;i}}U(S;k&d~|s0s%*g`d1P?GM6gx&Fjwae87?h=wC`ACmY)hQ zdz%IS3RmWE?K>9LyGgh@IYzk9VLR2@s_f3jxBk;V{nO~;;6gq*Ad5@qFG{WpMhZs> z1-`V)-1;@O31i9ax| zf78jg$KLmG_@9546&Uos3gehR%R8O91DPyg{~_b%R0k?$~4+#Y~s##CDZN#xIC+ zrku@R+Er5#2=fe)%n3MG(Z)DH!n)hsmb1@JQBRQ)U}xV2%@?jpQ|c3~37j{v@t{g0 zo_#yN%%|69T-SX0CzWo>dR-#UuGuyylAKUHo0QU^?gv zz^9+tuMPF!5>jD|jw+;(UF)oTD`3l|)!G_oo+1R%gO64(q(ve^F2=S1(GTxL8=)`# zUgDw#)glR{@}uUrE6l~+xf?YOn|i78h2`u^8d{OORZ4=l48|4aZo1~N2Jh^RG%hq) ztj>UAdoC=uP0vhiIWqASUQNF&cIUG{aesb(ds*D?ev~{~c74`Tr_b!SuJZymP*t#h!Yo(1B z_W<=uEey{}Sck*ALnKRbB0@V`>1Ime{-AE2;^_ocdWn&V8ii~>KJl{pa&;GLFzp)m z_knNrJ>w{y>61sMPChqz@Z8jepHl@1MhwE^Q*XTCwMo-fg62qjhnrF~{mD4MySKC1kgVhT2{o%r|wgwD&^Jj6t&GYA)`;AJpwYCSsTv zfp(qRAm)H$8s_i68J6UQ7$VY2*d?lYj&x7?kt<0A_uc4W=FY+KUjSkwnBj9lTV!<) z!YxHU>+m3c^iG1%qN|~0Dqj)p?(MQ-qCP=|{j2KXCJD7&f#ZnaLSYe`W4g=V%)2Ju zx~aBQk6q+3dSgXvg6>exh9(bgnArYe2tNoO{if#|5H-GNe<>nidl!7yNn@jfknY*5 zn_sqHRrQlgiBL|eiu_o^hQ)>OwJe~k8ln^!82mI#F@E8U1X z1o8UXs7l=ABqtn4s^(5T>LfG5kb~j#5ofsTRs|=e76SkS=N;+Q!ePvHK$f$gk>TAe zM(PMbi4W_b46@?f2T!Zmr(=vRpeXHvB!l`@!gV8N^u5Xn6v|!w%6=5d2UYtBdYBZl zVxUMLE45Q6e+bb)dC^6UE_x|Vs$1k5DsV+QH%D1F%c)yZ1nz$V7CoSW3=7mf%u<7J zv?mn@Xf2mMU61`q`b=Q2$UfB&u}$<8k`bTuAA>F*c_;MCr(!_W$Ro&wElPt=I`D-9 za=BiKjYg>#L0Obg5TUWYYpl|Wrl_cjm9u#%Drv|OuY|&7xk6UXl%cJ9j2+p@)OYuf!O|NKt^W2pKudClA1lSPrkjroPE0RmeSm0;1pNk z!WN)9JC&dVP@t?~f&77uVjrpI~#zk9?na&pJ?FSn*c=EJi)p#>M6>n}G<9(vh1NmR^i&#uWW zyIq@07i(cGntbgS`Gujq7kvfM61PtNbo+izzXs6CbDTJB_WmsGcH8Ellh2Z!_dIYZAXfE>M^Qlr z<$P`Ter56P6W6K`%-8pm)kh`m=Vx}F(DC~GQ3^1v7#OUq?+^NlXMwRj08#nQB28l1RJCHYJgNw@bZVtpJsrjz|awi4(M7xT4De z%?1(`s`CtDW(^2wC?Ztnlmd|mzv7S?xv>O1VjeXDQg($>$DF z?%giwc$c@7+VF}FZZ7+mE>!`>qWXoK9*ZY+sPjXr(lulafpf16NfrQtB_mFz zc4O&m3~WK8@;kFiLbon=z63@!*3dTC>OJDU{;~O8%W*SzOssL zf|fTon=0r~Q3MwNu^TqB0L}Ff;jDi%^W?MFetB$W>&+BXNSD?L=ja}L-UzM(HDmBp z1oG?Wo}78=oohR{U)zZQ?n^3KET{m5_4=;MTU8vKgpnd|V!>r0g(#?UhJ!8MWQBZ; zKapk7-v%`ztqmJDBQA=HCcPsg;;W0)(?7b%8geq;9X zP1H=VoQ&-_Lxe@$Es!eT0KA&rA)=&H>>YThuxsQH38<|4mP#B0I8ppCKum+$Qa-AP zu|m~yg#QIjhzkhm@onSpjw&U*RV@Tys0@Vv?kq7TwUNI?!QIz2*o}nfOmz}u_w+EP z*anM@+uF(;MDMJd>6WEHDr!0V%=9Z8-3$g!n)FjVCVb4R7W{GXDi@vZAMvUL61ksU z;dKSf=YbH6IwXH~Yjac72FFRZV3|y`2b5@wY#Ky=)FETpi$Za_#B;X?R?xynkv`&B zH?tsT_GO(UZ?rFfn(}h*jP0@*oQK;k4325|?!BywytMOlsf36*9Ar|uv%%PEF`Xf+ z&AuG`1I8HFWFh5_2b_r;reCoN#^q@L7r~A09T2YZnsd>=v^DO$FMBuKkcY;jxTC1e zaC!fLamXX7KugX=p6`Vy896c3hQth%&W35&K#eQm(C<8u`mbB}GZo+xJhN zI6C1K1IM0hR%FP14(4Pkahvuc_d6!M*r@ZjvqzmR&KXO>*rhw!mY%LHtF-C)evk=7 z-uP091w|h6ZRd)DK|B3ecw1Sh_QI}F6(2%oc2U`iulFKmb5OsY+2zDjbv<{<61u%( zn-5rOOTFQKdt`H;jgiG$OU*zC{ex;=T&tj!G5=;tqQ`l)MAPM(gJh~A3iZVC(pn@6 zwni{aIFZB%`s>3<&10GK(bgb$5O5JiJnslrcSRP(R4m zfGXpL9fN)oNlBk*Rpnl+0lL@LKbY*+T3DdvY}+S{#=WRKl1oL!^ERZd>~8XtQ*{>v z2dQ~h?9ujNb5Ic8c#LQC)u787ieG}eqoQ&P3@S->yn;lz>#F<}Oj{h6P>7PVQHD_- z;or9!&k7xO{x{Cf3b#3DvL9q=Kg`UVR z;e;0>>B>PXUn(WpB-bG0NWn0<^XKeHFUP}Rd@NT-rk{qPD7>vIn*ZM!V^Gwx^%^N* z9lk@1Y{K+X5_%jv6Q@_ar(^;SfB)W zLbLg}Cj$cZ6B;%kL#zcIUY)2(psdZ!6XK~=ZW!z*sLIcpabCLlLUuvVkX-Prhz0H; z3M;Smg9)qkiBcd>vTu0Xa`wMC0e+(;Lt1+@TRg4(P$~mAi}CVmD+g1!H|&81g-G$2 zR#p`5C<=O5P3v8v)EB+Y2{A=&;u)u`==H8>7uDt5&(d1Mo78axG`wWfYA~<%5qmXy z)X=XwqBlmYWv8-TpGfAJCFz^DTfF*-0UsvdP%D+h{A8brjz4`emY&^jT;F@l82O*w zLgZ-X@Qc@~dgjFqv15f!r9L;Tp8`3-wN1~@ zJa@XeUO*%6;y-19OkfmoRJpQ=U}G$&#|F-gNGV)c;i=4PvLcxynUDdlQRn&-uRx&* zoY^Yy4cCC5D@3)pTwDUG@m+suFjK&v@s({HJTLB_OqE(w=(Ad5w+) zyV5+wM9QM&g=aVbI12t@vdkBEb9fF_y74V2p5srBT|)P1=sjT*Xt>34ha25gG0rc$ zEIgp-#lRx};>txjLuDv_2X55}H;kIBnOfg5Jf1EAX86^Wi;5;u%bVPk(QOfMSzfuw zO_0{tn;Bu(2izr3NlLrj;+l5j+v=7A{_;yJ7cF-&)#@=`I7zqUK+G@u>zh8<>Yl>; zJJ4#?t&bSJN@~gto)G|=w>&AlMmpwNKEg>K_3jb5$t?vj4@0gdA8xr;Lo5)mG!JX5cS>ME#xAeSsUg3Fl+;63Lae^~r*#|bb;$txIMM2{4@zMUbW#^xJ z-J7+C74Ogf?V~Effu){9pEXD_DX`EjbaMl~w-UD>p}^@8zuGv4RQflT`e<@*~ zSc2HfjBF~ksse{}^Rner_4|G2pEr@1TRC?BF zT9*`1RkNZrRU7KBa~G(W zu!tFJL9e}1N}nL;ATS`OB$1ucy=c3-P2(B0)4ZOz7H_&S-=+xo&^D6UngaiTQu?_S z>1Y;=0pX=1SB*$`a28vHyPW-rzVbtH^56~t1)P0#hp!yxpVLL@FiY3f9h$oC+l!rp zRBzzIXn290aebE$ti5tcN0s9cF6z{yZfJfKX5WMWv~bug@Y6^>Te(i@K=Gss_yMQw z{PF`~jTTM@(c%YrEy@e^A1%h?v4o=L+2|l?)zf%k5bPfMC%{-3K^(;GaB`~|4Ij*r zb`^ff1^O-sKAcqtcUVaLwH9Jh19YdZjw0y!H?EC6d+lX0Hi-dQeVNGvY(AFOL55P& zfSU4x5Y4gc*H^Aw=tGrSV6T;LSr9V3WZaeN1Miv!V-;5ywo$_-0u~fFJTM>?KW3{2 z;Hyd`hqB2;>43~S1ix%JV>ixd@hZL>}-^l+7zwVyuqvdy>ejpDB0 zZ>Y#I%k*f?>SOM{qtT#JhDOtlDYk2kreA0)?V?0g9^37RxSo8Qh}S3-c0-dSbVHd^ zw66vYQfj4-MF<0348fT~LlB>Kj|@Q~{&)3UN8%+48X1em^o`=q6ZerRfN}g?6%;vA z*e?~l;o7n-Zf;N*nWl2qzKq8?$k!B*29?ZpHBq4l4UUPI83{d5f#k^iP`S!C{~$jRN&BM9Rgj_$4C$zA4Q#qXUycY+85BCW(S5lZO!5p}XGY^D*_EJvz)b!?ycXHn|(dS%98(K9J)S|=oFmW2~-w^+FwaF{ZM+K{(1hE(9Cz|$_ zgmu|aK+;b9!bz(3IQDGUPmVvx92#>k{ zW}$uuZgW;|KBs(^>(GEY0bKc(e1PWFwETpE1_R)Z%AV*OnELG$JSY54l-0oB5_Bh?#I=nqjx5sI23a#7n>E=lDZjaOLaVnm{|9p`&4Db43`#SSD(_=1!IL@^Dx!#E=rb#JvhdqT6U-Y z%Menk|1!k#yoYGYG#cYVpQeY+>>d781%ZBVQIV;`zK@Zf&n&8Qe(_tYNX{SHuq4He ztLkDlk1coG*Hc`a^1$q8P&%Y6By2SSK}g;}KdC&hqfS4&cwhi%TII8UVeU@M^!Vc%^KghdmMS>WXemMSar;2zH z0KvhE^XM^%TE{OCTId8XQI8J)k(Jo$izsnJ7Gf6Ty|FUu_><<%_2j&+ItDVcnL-&d zUMs{3akE@Oc$z1jmD_yuZRZQ`oHMy9P! z@(!_5d9a1T^;KLqH44=!W`QrSHfQrxUS3X=!ti-C6gtg~g7kqH1Rkbr3T!J7WwsnC z!#k>w1_L!`zaN|HS0WCtM=Li#zzmxO?JrsP5&TXPy)9_tWhZk`;e@Pnu67OU^pX+- zL;ie($5RILd?AlJWZi@Zs_SL)vW_qGbglRLBBLsU zzLm^E{i1=tyfq}v3u|xn(=8{3udRZ5EM(HM+oiaH|N498qc<}+t|IwY1!!OnM9tm; zp>L&&$v+gWHBg?GkBCorCVT%`!A(@vObPPu8FxBm)iHbF>iA%nyzY?*m|PS8N~Mg2 z?l*`^OFTdRc_IW{QeX2}SdCR|Lsozs}-y1=`U{fnjSIBQ9cG?yji?4Lc@-`mC}6~zPzp)lN(v;T(gG=c1@_%wZG z7xA5OQk1iQSzPu!l`L&N^`pzo7zF$N?ySmjf@NB z?DyY)-nsUh*bmCt@8Dx_f&*ymVNoe(-(6m*)z&LxnLXWxr$xo&EV~lS7f~a~mb^d- zHw@#jMGW|n6klr5^sio;{OQY7gao|*(S{eMf3yQWWV^n->>%DQx) zQ%_DE-l!K{_|b-6PQCZS^tQKk_wnbZPwWUM%l=I%hX~~()I$CKy;V355`rG~iBjA6 zMO@0B3@)U&fJGO{I3Fr1yoDkn)ZqLR>&T9J$|JBK%whRp3pf6UrS(e}X>#`?ZTtuUC;8zGLsK`S>0W_!dO!d?m@D+r;lBjJVWUX>TV>i zl-F4WQ}4duE>WXSL1e!k^PNn}3#)5X@0(9qhWQRHf$x&MJ@d+o0)~dHCUU%Io*Vo4 ztuYDfYkPO4VpNuVIJ5UzD!LZ-#Gl<;p@gfg3S5th*W!bQ#vRAB(V&Q%y}v`XHA+sH zWaZ#ZIFFWwAsK)%NuGL6YoM8NYgKz8mRdm|RYQTx-g2M#+rW@ESqm9{h7i}JO<8YY z${400N>m8wLm~JNb`h#+nInY@(PXaW0aExls+jJ8G}88nKeT*s``#dg#_4We#YAuN z!DjNE@9*mE=^|YZ2khlTgTo;6yk3#QmnJ?hAF7Z@cli*%z@DT$zr=NY!SdO5pKSo7-0nf~#W7reRvF?_Oiq6BAb z6L-nHCB+f}tXF?WauN(W3&ysbmB}g%gn@AUH^}%o2uzaTN6Q2K#i7}cWO{U2pNQp@ zF~hTzNsl}XRC6{;QHr#y1`)zvY*N%c=x`b)OT7>02WraTh!xN+XUqH`fLKc`b0+O4 zo;u7QlP|tJv32A0$ur=)CN>?zY?*rX{Nzzi+np2Vc9Vi8t7O}W$)`_hz1*+xoHNzg z5#Vj;NZEIG;=*oDiiy34^aR6;(b(j(2l>9Z{v@nUn4IZ0eiAH(I;#a~+kn7$$*fiwjgTlG6kBt+-wZo?ES*(eWcxQb+Z=a-@rD;L73R%%N~{ zRpGm3gT28pQQ}HXoH>T4@|>f^5GeF?aG(&k=ryV=CPfQBPC;GfDlAyk-KKC-PTOVa z{P7F}>{m^$i)Xi43H0cQ~vHTzzpE zbOEc=SEGg~(Tfr3W7m?UBMV76FS@jNIzrfytQ*mx^!8RdE2E=evSd+lt1aqL-XD31 zpo!<5t!^U))SHTEh0On9)*eBn8Yl~3&2ceRlR z>=mMeS2w??(~qK6oA+Ja{5qTfb$KFnLS`D?r^6Q}H*cLd{H6>ehgT6I3~+{ea={&0 zI2_3f_P?(02gh*XMigQsX1r0le(?0QT^nXzINn4;Mybd>AHQ|Hq*MB}t!^wiNGrFc zc9U@OVyS38X}ig6!b}neOZ%Gs^@2TNXb)gX@ij+s^$Mw?{Mg4ghO}xS7AY?qhz=`8 zXjU5?VXJvdYtX5#Y$A5H7*0bD=faW(NE25ydU%wdb?cb~w_bKHyMnc&Wo*=lrVFv0 zHRb(KH?8Icv;?IJl(Q@FvzYZH8!Dvamr~r2@FIp3rjW2s3L;`#5%N=R{yR!M5LwwK z&{X=U`~|KE9~uO?QXA^>r1epTn#B|C+*b#%u!Q`G%#1N?Nrdst2U|?}2y|-V3~=DF z^}3urzPzGyzI5dfn;1Jkm`$yC%!~+)OdM#@I4lHW(wS8)vZZxP>wreMtEUqy%nK&g zDp+cLi6PBnmEfP2EqVZ}`H96H9Zx)5?S)wM2|t6L2qcbAJUY;U)9X8>g=S~1)by-M zL7$Z_C_rA{Vly)7UL7km#7VO%`~Gjx%CR>Kt+=(aD*N6oHUw4}v$D{T9XG3Pd2}>J zg;suK`qHhxSDzWMg@*hnxb15GL@vY1Xx%IJ`W#!!JoVyWTcq>=(R%Q3y z>YU4VFSHYdUH@vQ`_V1-$Yj&*LYEp9%2nBtTWqq@QE1K`HmkDlK8gip z+xa*2GJN+p@G_tnPHumXeJ@q=TXQ%XimnN_SEn~@&0Ro`JqpptIz&=WtsBql+TQWw zeSaT5h(1|7^WwpcmqYc#7Ohg)Ixv9%Tj{uih7tlQ+3b!Yo`Medg3E7`PZm zKPvhp;A&^j3VLsj3S)NVti=_7E53=v^ss7v58Pz`MZ6Of4@EP3m;Z)!bKk9cCyWyb zg{j$h*Wtc9IVFa=`|&Jy0~|HD6u#oy?Hc#^q=j~i2O3`m)~4$ zKF>c~jOVPkt;Zs7I6N`@2ccgc!jCQomzar=9mLS!ji1~*hB1oC=@#lo2cDEP`D3wy zoV_6JeBb_}_?UW!YMbxsk}t22ufu55=kiyA2aQk8z968r@v{BUJA<`TPi9n#Jtwzu zSzoQfOUM9g+QtTtlUpRT-4AEaf_Sg_2i>12V^dizn14t$2Eb@3Mb?|1ly5}V3+7cC zrY~LHOx`<2%(h_76xwDubp{TDI7W4`p%zd9M?;Q4}3*h!~^|9m<>20ygyU~~kIk}-$D}U@aPTW1|Sno%}l9yIp z&R)sBPm(G%ml~CtSn?hLpZU`*ZM^Qw4cOZ0rLTZs>&m3cZ*lPw?O|^W1D>gG?Mf%MP0U z)gHD|=pJ4=uB%W>M!JufWulR5{~f^dwcg%O&R%lDFUD7fv2j8yLQFWa#n%mF5I*?;eA)mU{D>InVz zZt$hw8r#2vID^^o|veB^=Xhd@eakNLX#N)I^!HEwo~#4q<8W|?>t{9dwR`NI$W zU_t4zd;H(;+2=daG-{nyMB$piA=q!t6kEb%`*ho?L;Gp$h+(JkQKF#xm8?@%Fb@oH!eKD4GNOPc*`T%S?Pfic7v7A|0{foGOfb9B~$h zy$S555_!SHPG*8)PF8SOaVSK6PA}1C9y!)N)d4inp;KtAxB?~m{+|qKVi5f;4c<6qIEKsR%rl8tOrN~E@#kD()d60z!)^zcH8avU z`+4ArnQNRuMjS%~UETP6BVYQ)S0_#$LKX#9=EJ8a_CQRFH__Od#e4I%JdPU!o+9;H zwCjnWW)}r5km>QNn4ozno7ucQ_xp)g&|lh|eVbpL+45%Y+LLCR2x(52t{1pw0^Q3T zqUhtdDYYX4=L^^O9xOS>J9+?#R;8JpN3ZYOL5AnG>7$(5;{9AP? z8}}tA-@fJfhdY#E+1I~bF+mTr3`^WzIe@=c!ZvZo7}bnilf#3{{t%mM*2?wm@rV0`tZzClLyXR-3TC} zkkdu>i=FFHtdZj$Kxs~|eC_FzGuTAWZj8*XpZy8dEG};yD2h0-Oqe{QW5}1a^sKyM zxDD*#5M||a8m7WKFxzWUK= zCc1t2CoAt;8tvZh;Z@mhtz537bD=K$ot0fsxJo;5V{BFSk9BouTMbk6A=wT3wf?b* z(9oXruecg1J+c}XE4UVJv}zxrnG_7B0_jR3AWD|Mh+mVCDW6nR%5v#l$#81+G4;?7 zdJA;|uv(S4$7$=+b0jc!8x3Wm|=nTiv#P0n&cAjm^!VO zhla*BPXF>n94G?c(27_ktlg&OK0JE}m&Y6}u3L=b0q_JY{CR~StDi!VF?3dOOB}%o zg5Vz-9*_rv;TT1QeWc#m0dfW&3TP+*x1{#gq4!W2Be_s4?V-#om9u|i3kO%$@M_Z& zbQ{K@j%GbU(Em0d9(~FK(CG75Xt{>9i|$au(^~LX6nW90cuw78?1zCKK%rRVz1(^U0A_7794wra(v<-)y|2G{VXS&ty@uySHdnRymb|e z8D;)WYW?A5ccafKHd~bcMD$Y9$bc^EzMP4zZwX&+V};EmGv61 zMQJw|D0jp*C>nN^5iBx_;iWOBC=yxto}Pe-j|@;&0{gCTd-gwPD=-~9s;evPCK1H*Up%Js=?ez>vHfxt+&{O3(Vr2zXMq ztlNHSo@ou&-q+cu%5+><>!wCi_>qW2A6Ro4DXMPGXSVlbw(*${7lc|GyZAAR%t* z=()*LyFWbhS}<^*d~518%VyZ80EW)ff0s?|eb@CH;tEuj(mR=POah(W?AZPgb=bd& z#;1=_kl}@o4)4()JNJgyvM5qv^JKdc2hV}mG!Z24rW2g4M{L#jr=9lbz zdGg?Eo>rxov4BN-6ROZoA9*pnLo&{P@regjAyKuwiAv!58s)D_cRTFi1O45@9noSR z{q^C5eJ!o+;;6PYsB?c^3EXTCK@9{#^onuXtidI1g%Z|Xxx|tcj27ZE!VWAbi;0XZ zK+@^i9Ed4XFpWa7g>b#KQR}8OZWk#V&G-7iluOI4PrDUaiWu24K)lz7%#>c12c#24F0hgxw}NImE5$ zxM<`f7!r-0(PsJ6H84djU1Ec(xnw~i(cSb#T4f=R_rf+o}PgiCeLZSU4YwHTGe)gjmlJ9hJl_OD*ca zs*cCcUp$#0z%X{ArbOIE*qDfZ{;E48geWnncT7d5&r{_Q?fl##p)C8w%VW@)FV|rQ zMZ+`EbwPdHP^#dH3MdQ+UylztSs?v=Kh`%bmE71340cMtht03i`}2LL6)kkfZ^qw$ zYSi3?OUTc-&M%Dg*nKZlxW^s(zgT7^UQ~aOiRRCpHJ%`JwOF$#H(~@H7Vbv*y;|B3 z=KHw5iG@xXrrU7iCD6E9BO+ny{$nhn>Bk6DW5b6>J2Pmrzr2s zDYaVU{^*l)nW((^~{xtiXL7TqSJupJ3YBvW= zwn7vrsbk)Ox4t@ylkV-n=5bf038wO391*sCzy|1WxcZiG1Rnb8P~ZACBuf<*Y$oiz z2RB-e`4x69(&t69H=dxXXR&Jg2b4i*w?_2M?ev_e6rw&Ye;v27 zB&I-M$^=%?cf=-9-e^sL5nCu_>4K~PIfc4#2U_g*N@es>FWsn&cQ{G^j&sCQgLt1CB8wrWY!JxEi!#iekiJajtY z*61eY_Tiun3-p5MX{uhF^+<8cp`we5u3d~TL;I^(FEZxiqQkhRkRTy=`=q#{I-hQH zL8r=cT~(OKhav&f4-`YN>;($0tZ4w9TK>Uqbb2i}X*R$SMOf@~jNj@m!Dv!LB_P<* z*NfZz7-~T~V!a&EL@)z!qQLHmHn?xPz;KP5DMRPujJN$D$9&UZ3@8qp%h1IFr7c6Q&L0G0}VH zN3~g>*Upah%%Sa{ZU4zNXzTOZV@ND(cSA+Ks``(nd0K5&7Qa~4JwUIt7waE5LHGC+ zHEyA7%+o}ZEv@MY&#{JFT2taa96AxuZLMuxqZ5H`k4Ecxcr99)5H;FjnPJ=t#*SJ< zwpTF9Qy3#kmy*X3ZEn@)b+o1nxuEtS8m>f#!it(U>1Li9qP9h@(DBVIKK8O*YPS7} zZ{cZeDK^Sg&sx000@Y>Fq+omsh>NhDkel^}5z3lKcWTHXlz4Bv8rrg5s+;35*OU%( zUCW92KlE%+lkrWfm}tY!>VX*;t)b6Tw-PmWVSNIuN{Pop;}VgU@w;xOzFdA-m?9m3&=b&rz>q4PIPd2sZ(_I&js;soJqq z)Bq;jD$ND+FP+$YV)iM}N%CYf)&O4hAahYw_XwJxgjdl%vuoMoEsJUMQkA!=naA-N zXf?T?8T}*yTdyuerwW>;9vq9OlF8j9WiN{ci&dZ%=fUEo>?alRs;(2(RU^F5MtUF4 z=c9Gm7`Y{EE5gba;x|Dn(V--IlO&$l4CSg%P8&?LyI8URUB>&uvf`w;1F)ouf zbp!;TIEtK*Y(RDV2tt0;u*pHJkRDMv`K^rU@9caq}UEhf{ zAXGJ{ubx`obAkr!$!#x^j zh(wBl`0}>1XM}R#A<=Dv%C0lF>I!PiY{v?W?LtF6^oK4HR<#j&jhJB@X#Jh(U(Hx+ zT0UW0K=sCp`n;vW$3;S-A};I&5>Aq(+dy$WTXgWHNYAT!fH(!GwN@;|&g!akM5nMk ziXl0o$Y`-sXjaAJVU_LbjS%&D7tmpZYE~+@-vqbiMCc(@Rln&RLgjK7(?+iLxfkui z;S;+;-4wrxj;)$`b>(!{k-4`$Lj+Vi-uXX|58VMC1!^Ts2@wsHT1H^Bvy z79mNro*~SJ=xD`tG-F~tQtE+KeN-^>=(&KAXO$mr!wb~D@EgJDHhZ&!QAfc5NKsTQ zM-$8L0>6pW1#=p>Ia0!^)QQkwR?V9&+Bg?8!I2loSF64#mq)CqdQfTQdbgkuRJVRb zaS5dzPMU??u`nK3gNLh*po^L_0)E1&Q|LJni;nGb_YV4)XOrWCG8M<~1?Es_onCcENx~*IqH%I}46=|7x&!v5A;|%!asv@+& zE1ZQTmeJFKFv`!uE$#m0R^RlsiC1(`BoMDQagQac`uxMDdY2>V>IivjW>oi|iFJRW z|Ckjkxw0$718XU9z4sWBraplyYKwM}!#s5ulnhZktQ5la(^Yk*3Ae1r?se196^E>l zuAAnGVZP4Qd)E&YU(tqJI*r;OR{RsrtkLEcTom@gp)6Q+ookpAZ5Q56pVtq=DjpPwH znn5QD7tzTTc;}@FM@Z29tI$?jotdj^SFfv>rbm}m!~hF#y3q$ZQ>y&Yp&HECa;1gf zZoILUDE$jp;qgY^;)(WOVG$d-FkKK!8)a~36gEc-7c=43&%*bi=j>?lkhaaD{l?3y zDq}`^js1509-29cCQ?v^V#9veikDt^`f14USc^E#$ix=-5yp-JjvwM3Gw_?melRZr zS7_}3PgMQ==y&xGQr8wXTyrheHOl|h*&kvZQoSyaXyO5V2q(HuNOiWQjWQM;(u%yS zI>!><*B3GI>CUutN-3HR|6!#MIyN6$DdFM*>I)MIxJ8B3wZCh<#YVTu_t54@7aHLP z{3DQXsJ}4xLS}?nR-AMVrJKKIVM&ju6uMIYth#WZJ#9`*KZ2{;RhPKEk*YJ3gs^9a z)^-!CnM|m$Y!N3B+)5oxW9aVS!sUz9p*#>5EJuj8FZ2-!&9;ZS9~$t4QbujHFhnp? z$FAmjN4P@!Y}j|>hA1#C<+Ktj>(OB=V&fNRISVaFENY=V%&M_EQWnfCZC&83D30lB zTlmQaj&p}>coz(tx;7nFF5V<`2yGMGz*pL0M8~dk!x(7Ysj8B6IT9~n;Xq44^sQ*s z2xEZqGB8?T23>m)ODtht7I%dkJb;A?v#~^OHU?y~-Br-e=kJX;0&IMIJkf80{&dlx zut0aZ{1)AT!rcuE3h_n7F0rv?)QfNo0A?wm7uC@N5uk$-WlXfURfk~9%?gDSH7=o9 z!}2%}leRuwcJ#sGgLFZes_K!r&C1L|Ifhkm9;}Xfn7XO@=Mq|x!f>4@JJ$-wl5zDQ zdXkORL2+j?`l;#kJ5iO0Sv1UWd6=?=+BGivZz87C?$EKnV$Fl2@l|&aKEj?zJa2XM z^T!5H_i{nkZdHi_!@Sk~VD4NzP!HN9KKu-Z4}}5R^$T-|#zk+s;GJ-09hQI!;Ob6v zd>X0@STK(I6;8FQwvs42h|k@_I!B{1T#VMxP?uu$8H}UBFbULH)TifVI8EmUrHy4p zW>$Z}C!<%ZX2=b3^qcd^8xy+y?7A^~-4cI8?3%?sRr!K-CWq1(|a>HmF zTJs6E@b^PCrmC{S)=;KxrPR<02cX5@*eDOZ z-LyVL=eluHj^4E@6Az`+=SA~IVR0WUqy|~#CK985gK==eL2EQ(@rsDIV-SYNd114? z>SsW`Ofb7hMo9H31stpQ$bbcAW7oBe=d=RQsTr_wLrd71nMLZV}-Wgq! z`n&?(e_HA9413jVFU--xU^ncom;HVHCgNTwI-1bql*rv6;vYOcSh5)FkrRaY{qvJ1NHO!fS&XIn6vi>t(_)7{8R zGjNgBX@pa{xY^xebfVQkF-G z+U02_gErm^J5mHp7VDXgd9TR2X~D7dQ11=i`Kg8~r& zT7_+etyVN^#&8$9gQ?i4KQwmG3z*pd&sjD%ppW`Mi!G!8(P5amVU?3x3<@oKYSa@nwNs09Kcdm=aC* zMsa{nIhjV}-dSf^zf3T`(|&dI^9oj%GV7;wePABpM#+faaKfxXk35_=Ms@J0*sj3v)HJ%wY(-lYiCdmFnA}?u8HHkFj>u*_h})R7IST zyNl#+mS|Ej8y_vKONb>8@&-D~xW?wPk@rHEJy?vAV6sY*(>7D$M8Bm)}8=ZvBPWUN4rn+XHP`!JZK5yN>43}n|mZGVzBI7F7=~?~J zskyDatWKADxYkiv{23}sc%qHq=WrSTYvL)%!p zGQST{S>P%n@XP8Q!nMUS7e83TEih|3n%j+{YBLJ41{92nKu-#*T+o_4VFm18OOgN7Au7IhGKM%m{sU7rLV5kZE%`l7$LOeKbmi}= zGN))=aFi2EcWg(ixLEVV0G5DkDLuLaLv?!uRJUrGpuk{1lpx*ds-ZQDk@y7mm@MyA z{Tb-;{ahChD}vEJVraDJ8`LQH>GLLB+JrI=Er6k=;k)ISaZ)%}y}F$NYKLV*#R_h; z`15@u?IC>Ls?Jxg03sY1fQMmY4ulO3bX{lRmI!os0euk+TtsL#^^Y|t$Te5Tf1>Gt z>>QTVbaZv8o>W_P7BkTPFSIjSp#Lw`=)96Dx%fY65l;=OC7niNQDa)hn&yKNq>n#; zCdOX}PN!uoF4a&sprb_A9;K5>xSWX1ZF#)=k4ITc9v_W)5Pp~%LE%7>hwDP0Y}yUK zkGJo8w13azec_K&A|7XF!WU0(f@t0Xnx=exrqOmNOkbe$D!=RG*XJ3V3roec*W5)N zzqkSXfqBVTT>+_7*?NE?K{^pKc z&=*B&&MzWBO&bIJzU_WSAYsQqNA%@sQlo(zJH|?;U|ybfYSd;kJU{rm@Yy`XZ<)W4V$1 zy`DJ6xHi;L*r6lM82G9_0~2RspZkm;ivSGDf)w3mjEPqcBs=#aB<=+YifH zdAU!+8ego&*4J3yfd11{9|$4y_jT!u<-{O%UV7?w{?j0^!(4*L&}DJ@PV3pz(ZtEb zv_~%^V;6(pdUg8#X8vdk^mY;59kbb_@KEDq@CX0dnOoBTo!eS0lq)YkFR&zrNQOhJwZ5)1d1MUktmxaKxzV3m10yxbXeB$)SZGo`yD+ zDGmLld13Fl(`aW!7RT8xWAS*lBLo;-sZni?>H+E#3v>S7t3HJF^yV-j%gjCogMpqw|qV z-XEA3{uM0Gm=_+CIWL@dbY6IR?!55USLcP#c|9-uZP~nVoyvLPjMb3n^f7T<0rsv*{DtLWTQrXkd3;f3 zqO2O{M`?A)k1|oqkNTpYA2q=`KWgW&{HRoLb!2{&>)8CL?oRnp+g$UbPI%=_xk^;n@;Ph5mK&}MTfR3bY5j1F_s)kc*S;OLyw@H0dl``v=rWhVr&y5|J3yvu^v)7NnA zZ$WIIdxF^grGnVdXM)(p;C4v!xKClt} z7B@hnTbvar?b0nSSi4(X;og05p2Ih-ef@U&`gHGs z6I6kBS$V=6#fk*^_7w?h)hZIs7*r(8>{XEvI-nvUW?)5vQZM<$Bs2NMBLn0UW2VX{ z#sW1 z?hY_WTs+4h(ICzsk+;Smu?eu*Y>=3?(;)HKE`!9)8HW-Ne^@9u0wOCH3feUe6$HwM z3ficI3Nq9~1&y>q1^rAz1zJ5r1tz^i1?~EW3SL@;3f^yz7JLQEcSH+fQlkaD^k_kP zMzo;ynP|bB2hoDJPof1nFQNsGU!w&xrIrg~nt)qJ1vj1?72F29pB@#czd0%}EITSN zXm(6cD1S^aq4P0;q5d&}tm!eq0IOqykwcFO{vO_9^R3|IEn|-C+}dYq+Ez1g_V=`{ zgWS`$mV2jdJvKXSYtQ**~XMHfe&|D+Al~| z(27qT|66?ORPdr#eCpdi@u`mH@u{Q7#i!01AD?>D59j#tsS$JIQ*)x@Q!lNIPo2AV zck0^CAJZ&MKBkQ}{g~!B0!;sy=I8M-jm-a;_9^CL+SxT9)6N6ygpX-Cdq1W*WqeGF zo7{NUtqyl~DHQT|`xWzdA9}>!eH5&C%->C3@psG1`0q|{>A$;F(SLXEPX4>qwfuMY z=<2^)LC=5p;dhPFkATRsM(OQH`?Zs@l<(Db)f2S!@9I`9_c4QX|t za9FDYuN_+**b*dv;Pu-<2hA>Y%1oL%I>yu+QwLV$+N9&VU!Itfy!Pif)}k%+Q=xJoZM95q>Pfn$rWF> zpE|hn!RgA32d6)Sf`boEmuEjXZF&5`>9M&FPR}oVaC%G;j&D9V?fmY+Y5$4`r@J?L zczWGql{0-xRnD}2r*h`{2bD9uNc%IoP1>JXE!+M~97t~2{>%W2_GfwxZGT2~RQoe3 zquZakYOHf+vbD~cuQoboKL4(B=B1m?nUP*PXU2lxeRR$w%+Wb>akb8w+c7$48f}4} zojPZXHCLT|FI9GSbL+CR`xMH~=I8>;va?qPmz|w7qU@~BsIs%ag5M{Woz0t7c6NJE z*;$R{WoLaqOBZC?%_*2Lc1}Tiw>brc9&-vt&YDv&7Ifv$DM*aBxn+qGNLk zPG6c+aO3iv0*i}L1$~O53LGCr70i4bRj}ntRDqphbb*CRbip0H=z=HRqYGYuyFH={ zJO)P>3>XnzFuI4_xn=$2&aE|wZi!mzbKp!P*XVHUsvJ$L4AeuR}B=- zk240g3gPNtp^E;q!jXN$uM8X*e&z7c@GD2a zxnbc~UX2UCGTI~jN-zKLE7L>5uk4KoztU+%_!Yy|;a5hcgkO;g>htIFpp}0P4*vY- zvyTI=e*QAxYO5yZSEHMoU(IM~e)W;M`Bfh+^Q#Ko%&$7>m|t}Ut?bONZX9KPRezlM z)yr=JuT856y!Prt;I$230};itRh^D{f`DueiV|x7gP!w>Tv@xA@T9 z+~O_sa*K6CbBnE)>%@%OyKk zUoJTucezA6^>T?|_vI4zBbQ55a&Ya`<&x$FmrLTFUM}hM>~e_~=o{Pj@7uq<{#%E) z;O>B@F?UTi1>756HuL_}_cQOuHl20fyY;O5gH&eSKd(RQzK51n;C#CF#GS7T<~ z&#|9%|0HPPIO~4#BkzaWA$uQL&1+Mt71yTJWKEmWFMqTtosiR}bZ1_h(o}HuOq){I z3vEif-)vL5?RJ~e6ZhMcT0L%4s@#7|X=}Hk&pREke|1wU;ME@IcdbMqFrKIbXj`dqGY>+=B3Tc52!Y1dnygS*}O zd^$Mf>ujS+-rCCyz>Po2|(v{kitt)j9@Q&g4JzXjNQeCP3&vd0+KIux` z=;tQ=yOo>tB3n1<)x+JS%>&$|-^|9jg>KUG7P(2wE^(7?0q$;flP25Uq?e|;N&9yw zly0I?C>^U=DE*sup>%(+3>fPdN@p7uO1B$=Yc_?_e~c-VJ~*yW`ngM?^n2gFjlP2A zetjFo`1ftZo71;ZdPv_!tylMLG-p@eMsL&mHqtrRw~^!NzKv!Uz|Y0Ljjn~?YrJIT z{U#eGILagdok@-|J*POzY;|^&8SCyS(=otNCO+6v=D-|BnZ_#}W!l8x`dUYs3j#-( z=F0Ih!}b)(yvZz*(LPxu)9Xx;OsBI&GCMC6$(*@bBy;0tk&H)4k<8e#A{hbL28Mks zl9_ZTs`-x8wapLpRFrkHQk3-_q9{AS5zJPU)mW)0TNtY-J9(p`Y^gv|_8G`MrYKvI zrzku9l%njqkuI{YgQ8`ZE{K-hxj0((@X}~m?WAZ~!RBaL_dU_FD*JKmaI|dmqtUW) zx1wb`-HDdf0zvPMZ63Ny`xXCM}nZ zYtnK#Xg;G!%aXt*EkkEFY1wPZ>6RCsw~)W{s)c+To}B#iW^(c;6y)S>yUNMG)W>fN zIr*=H=qr`xvF+(7ZhQx6ardCnky+rn=36`ZLVY(Z?3dzySdWG6Xr^OXU&y%TrgMq z`;NKNtGn>?$Xw}Sqa3AFl^mrb9deYmspTkj*UV9})yYu`(9cmS9Fn8d$vQ_#3rrrF zqx8Z)N9m$Zj*|QZDdn>_rIc^pmQsFFA*Gx{q?Mn@ODlg=kXE*CC#_tnDy_VvPQnFa^Y!NW#wX7<&I$2Em`Fa<+93(A7zz$e3DfjN?Ir{ly9ND zQn7{dKIIn58`DF6dHqXMm8BX@Rd#l1s&cqnQx)w2O;rQ~o2s~vY^tJSk82Z~sx+V4 zR3&bHQhX$ws)d#NRDwQfI&F zrSAJx3yt=x?(DN)wZvw>>gy5vRV#j-*+EA?rh}qsOb2Vrm=5EuVmfFKi|KIICZzk68z>H(?KUVri0QBFSVpJFSR3kz0_hZd8x$$%|E@=`d{-> zODpzLoAS4pnp{(FHPvR`YW?NC)lMpVtA#~xSBqP|U2WT%?P^n!wyPcfYrC54t?g

TvmuXb!mT3eTm1$U;mT3$J=grDA!upqK3>sOc@n~$BM)6;Unks`=X?6gmR;x6f z?N(_9j9R5xG-;J)qT?z}zS}CzcHXNr!xpX5j9Y?hQL8jZ#IDjLid#CR2Iy#&E#Ic~ zC~ljUL&7$#DPa1>ZCbbf*rpY`eVdkj);6t*>}^`7j&IYtmbXo-#pP{UWjD5IU7jl2 z<%6eem(p3XT^#&nyL=3k?Xq^UY?o1MWxLn|=MA!5NSbVyf+MnB{yGZ3*JQi&=x5pW zmaAO1S!dOCnii_-=oYE#^!`g-C*_s8j`}-wohLjEo%M}1begu%(1~cJq0_dzhRzlP z4V`45(kff811Ocx)^q+PTQ8t}wq8-^Y`sLCY(2g~wq85aY`rj>Y`wSJlf94biAF>R~I{@KzBQ%2O)Mw??Q1c z+|Fp%3Ol29X8y(lZTyW#+4>u+yZRfa2f+>TH|E9p8~5GpZ(Oj|-}oFDveVyqbH2av z@zegspN{o6=}WX$w*leJHpng+%D_SF2tx2MrI-=5~j!42P@qi_25EWYR4bH_v9 zo@t=urEkxHP5gRxlk@AjNzzvga1f1^Eu{^n=ET|xiR_XYin zp9%W!cq!1fE#+v$#5`pM|SqKZ|$M z`dI|H^|Ofe?q{Lui{DZGESkjjvrvlfXJNawpTz{L^%e`puD4hX---lFNY^%ku_Tw%ivcIWo#Pf7WydWF zKODE1ER|zX+BnDJ8OYVju_)2bv6!xxV=?c~?v}HfSy(o0ZDFa~&cd?yFBX<5-7PHD zjVvsm46v|VZ;5NeEG#32TUfT8VPUz&$HFoh*#3FMO5xJ-AzpVcTd#O{**fvbW$UYz zm#trXxoq9y>t*XO=|byS9SW_9TA{TJur(~S{$g5a?PXSIece!R==jS8HX1hyY@|vG zY!v@4usPoJoQ;O!IUA$4=WMb&oU@5gKW7sS7WO%3(`mptn`Tz$Y&v|sYh!k>mF@nl zR<>$aTG`Hf+RC=&i&nM?FI(9fylrLM6D%yl?_cC?cWKDm9@CV!ePAeW`%yk+_$Lt2 zI%Rm<9x21)jZ=mzk{`Tr|_S$jd?7M@!wd3q} z?i^>|Y0o%&^8@4Twf3L0e|FGr{O7}V<6Gt0jgLNQH$LO6-S|hvcH@0Y?8YlRup966 z&~CglXw_om_>C<`j@MTlIo_?ci9>*biNg_169-FO;B4aH;A-OV*xkh8CFnfI#Nk?q ziNncdCJy(bOdPycnK-lvp6W2^jl08oj{^=m5v?b_7p$CkRw-%XzK%%~pZuCM@x4LP zL=V%XiMm!v6Yma9nt0kiY2x*XNfXabOPV;&KWU<4K+;54p!jRYsT+E9oO;N(S3J6#T?=oSNehJoT?RrjED3&bg+J z@vBT7jT1~AuWdGU)cV8J(KN->aY`oK98*Wjzf2wNZ<#u_dTQ#}$h3`9+n#Nly7q75 zbla+pQ}0D>oFW&uaf$+6m$h*^5ZT6Q@X9t$tv0rC3Kz6-+WJQur}m3HoK(S%Fb}7L zOFW!9M|(J3Tjk-Dl<484wAsVSB-z7hai)h;Y!MTGr+X)a_6TT%AJoVmpf~ATki5ppqFdj z5--=na4%PZz{}NeAKXJ;t_v@ExgII@avfIU?Kk#zZ{OaX8K-$|itf!1ylj}3x z)MI+PpHzP8{=nd=`@0@b-H(|+b?@r_)P17=Q+JP`r|#asb@o&DKj%GlKe_0s`->G% z-SgKzb^WuGVb5!chdoCnANI5dowgnJ?3jJnGxgG8&!dH)^swi-Mp>S>8fSTi zx5@GxA6(?wW%WDH{W0%6$FFlU57 z-?Z-J9YzG++hhdZ8BGP=pMMc}yNncgx3d>`hfNT8ubU+B*8W}K-5qF66L_b(3cQ;v z5O|-pXfea$YPe6ITj4&A&%=FYz6kf((rBrV-7iahEYz3!+%a70^TcGS&kJz3=TaXJ zo25Pj?3enyn?7Kc%I0L>4xn^PvafS$vTwkyWZ$C9WZ%Ri$-ex&WZ!mYl6}MOB>TqQ z#kI%Dz9U{G`>t!fGB6ROD69&$}g>;|XJg3|sr3(CH0 z7UcTIEQrL;4;q^IHQ4Bnufgv7zXk^#{2Kf;`)lyd^IwCfUH%$8r1)#__`6?&hd%il zT=em4@ZX=l20sJ}CKa>CTUX4U3SJDYnElqKVz%R`irJ&5SInN}UNQS-7|t!Om>m&a zF*_%*V)ms?6|=3Mww>ES#ddC>vF+TiJ#FW{?PWXn9SAkEotre(cCMVO?cAdtwsXB# z+s>UEgLCU_=XTj_J9l+Q{dw1o^yl3HGfed7`SsMF_qUn;yep&h=e-`SKX0NB&dt=H z*E~pnp7}EUd3I6y^Q?Fg^Q7A!nKw(jbbe&7()l0ymd@YMzjXd@!%OF{8&f*}&F`i2 z%RnQi()oflIG0#D-*a2({Mjj`^L+-42(cMEB4o0|h>(kuM}$0g84=RXeME@WoDm_u zVIxBFKt5Q$azu#F&JiJ>(?*0m>dz0!AIA^5I-VbrIGrC-xriS!YzaTa1~gg853$dqrWK{ObP^NL^{ zSSHOQ3ttfOWeAU$fFO_sysUU+H+TcK4CaxCpc{^VhuZ=CHHb$J>l1QZjSwkqLd?N2 zumGIuLda5J4GKCF(j4xfu7orJc_0ip^&lkQfRGPBAID3&6Y>g-1ghW>;?9D*0@o*i z&fw8?9`Uv%#1N!_dq8bCAr7GV2ts1vUIgVhUH}GxEb#a&kM!BXBTK+#pqk7h`kQ!U zt$;`FfnXfxgI1e)WCGX1V1;v@R)oA8jCX{))P|7t!wBgFTH|<$4UY^0dBb?55nOY) zp@4v6LwTexm=8W#Lzcj7FyK!f`FMp#GQguk9#IC9!DcWE=k&l?_*o3bT*bElZIK2O zK;#<8FTk=AWH1PfoP_tbPA(RAmLd7w3pGu$B4aIfQc zr6-RVdGN?`V2R@=aFgJ+f^O)}=aGYvJYxNj5Cw4a0U_SN6eNQeICl^%0B0XT9>65f z8E9w`G8ROFdzyqOcOt|Vgo1B1{AeFi-gRYhUd2+@p}ZXEDFMo1y(d7O}@aJL*Kq#sDYZyx-)g2g8x zbLx=uH_)HAu!C?Lf%)J)c!qPkLCHHpeBrvn?FP1h%=ge)pz{It5L^WdDxrTM0mm)j zz5$1T?ngqL!GgwkKX47`fUk{^UT}F$2$7Z{L=WybkOo4*b>QZOZx#!=!?#fK$2aXk zNIOI5JxBm|fTj^4E+7Szf?39}%V0mK0O=(>Vw-{QascPxhQL(@d-oGEcOT>(48`%2 zgSanf59~4txiuU41ky<60U=!#U?cFK%tY8o@CTR$rcZz@fkJS`0eKOK1v+3VFv9um z_?9~^!TtjSkb8kgz5=t0kZX_uf`Q{@9?=4i;3pAoY-hZ4Uml6-!y`9=jv2l^exHUL z3|w*Cs2`8K2AjcXFrYt=>}|y(D)P`JxOZB@K7#DU434O-%OH0a+R`5ia|*5dbTTuTLW)L>J9QBUZ25p2gb$Op&+ef}gQ3Ov0+$T~0t z+`{imSMg0i2>5D&dxXOVFX542K@h+sSdtNjd<5=Y5D#9$Pw%C8UbqfmXEf3oOa@^f zCknP5_yHTx8GMN(q!q3`#<3~fSbW1n!O$DH!@%tz9+`>XU4adbr9m7x90*+i+TbR> z>m9^%Y8&JZ>G=T|4#0DOTcDjebQCNFp7?Eqe5n%0Ilv3Yz1G2ILVl!>ZuSDi7mnuw znIH~~0KT9Zc(?>|4>tn3?*=S^2I#vLdI++T37HK(fn)d``Uiv%EZGKqh1&>j9^652 z9sM9Tz3|+~*9L7t8i72}1V|zL(#^OAqBbG@fh{Ni&2i2em<}N1L4Twfc+-!NO<*97 zyO~25aV;EpTcC^s3UF>VXuA{f=t1US)0eg;qQ_|@~e$J(hP2Ia2|Mq1n?Hu zbHOU0h4j&w1zVJeIF}$zj`2uoQywu+h3p{iMc^pdf!{vh1CAfSRZk=2GFSs9f)=}w zKcH+Rx0Oenf%_jQM{eU0C7^)gESx(I*DnQSC~yMj&%*UQMMy3a3zgL)bV=>+-IqfU%1}*y%x6C zX)=!tKg%Qg&p=1vZUE~}!G4{D{=hXl%_9rId7uJ6Zr~x#cV39JhCcVl^Nfca1++!E zuMNHj-1)Gjw}6=<;scey0oRP%@yJzNe*-rL#K%D=@J&1BLS`ahKOzZn2g$$!zvqEW zFm@U8DCkUkxU0Z9AcOON1fY!Uk93CX0@QIlnGYQSjyT>7?%-Gz+=T9|2gCDuWMUrj zX^@2DSKu>_58)Z6gXTCk#=EaRf$|Et2R64ro+gWY5j4ZG4=@9Lu1rgO z2e>o9q%p8(qmfoX1ILx4cq9y1gPAyI0*>LhCAcyY-vS(jetmd|`{TPVf_oImfgvFN z0c<;XcpveCnLq=-CxH*q(BIXNColu_0*%1MRY(_L0M>)l7?e+e1&{-c-3Ynhig$q< z5BGP_4TM1^v%nkhH?Hjfen5FT{Jub*`y6%xqyvX%&?|7U6gCbF0t9H|+C7|41Wyj* z8qftT4uk@Jl*uHaG?p_8~n$CYZ9HM`XcX(C7e<{Ed4)yoWM2(sdHt zO(6O%(i|w^SQ_pS5d1g34|rLE?*q5l2Ixv5>P$*_9uNXDz?ZhDhqXhw3!K97O5gxm z^r;$2ok-#~ZZ3{I>-nGs9`UBK(*kR7<$aKphU;8Fy8x)k5_D{RmgLNuNi5PAoC8hbP!@;l5BdN#Fdj_C`PpCq=mZqcLwCVC5Pc5!0hd5Aes{cp`X`uy z^7v!8TY)Z)lRcsLU@Y*$v&DeJ;BU|!=bC~ypaA^hg?oYDdO=^n1rX2^`7~(p8}t@D z2jjr*-bi2Y3#bIGuHzk%j?>}h0F@h%aWMZcyd&JsaPQtkc^eercp2QuPa*qHQ1*j6 z1@0=44_4y$>c`0E!Bp@b=;Hhdxc#JIlcZ1|1aHAy9&93k9)nXjR=~L)aP9EBF*uBG z>gbKS0VoAUUa&<#6~_iMc*GwZ1{Zu#KLlTKybP{q0?N9m8=8ZH2p(wy*B-74xU&pp z8{iIB;W{kYZKMgvzlH1IUNK}H?kk+z3i{l^GnByogUdKx0&ZSL zKF}0-4wx!~JRf{&0(k~k8uN%L+#QWjCj|GA4l{914wUSG?b?a9A24A%(gPHO4mdvr zB!T<5wgq%Xe&q^sbYSOop#$J4XrYbzc2^$R4t#K22u!-cj)IS13j8lFLAwab{*F^o zzA{6Zw=e1<{b0}FzUhrJQ6EA!zg#;dd+O-4gkZI^;(K=?$_qQSJgp zo$y{@trp$`Ea{B21D^rE3v3B&Yf?PQzQ04p!E)R`54;EG@H-yx98n$v0^kXnBOkpA z*JC@%ASq~X0^4wWAN&e>;rFL)$Y~zZ>5Y$l&)-xUYAi{sruD zZ6uy~3CIEyenEKvXIUP@p%SPafD zM;&Da@&T|0$5Vke@Wt=#pah(Kf#(8tAR26ahBDuC)C1v82fE+|zR5M5TL&hAL48nu zp9z}`PWa%N;3~mAJ_FekPykupkV%|#hARg$kQaQ>#&Zou9#R0=J4=W$+>>B4jvatJ zcy=0T3$}n$XJGSz39$D<{*etk0`_I`$UCt6F!UJA0M8Dg>;*hP4_xyFuW){JFSL8y zMwt&(0y%K>7W4sx7NZ^m)N%ai4!#|*2By%xu_2HTpt=C>5sI<{+`C}VLbP=NS)4Oo zgz#|V;Z}mr<01FfD6b;D%%zYw@(?d*gX2_!d=|&Q10w+QOK#vCZb3$Y&Y<)r@&T{| zJo*duVYqt5$Zv4G`38@u14rP3-}m5Z!IfTxa^qLjc^%OnFb#GNH<*B9y{XUx;5!9% z8jv{|Wlp#cac&^|2mtRfbiohhMn1j^*n#5|0?dytnjLV7{wJCxy`g|LA@77PKaE<=vM z7;pjnbqVb|;CIjoJiG{biihn5Pr-&YC@TRC9JhsA7>BYB-14=ki-BLkKJX}jMccCf!5%*9%LH? zfm`^!1IWYA``_>_G-10nU=x5AjytQP4A&7d3pWPtP{0ER@!J}H2sj8G+LnrPK_0?i zhkY-?w}iU`e7%OUG`MgTWpKE`xRwidF)+h%2AFyt?eO68IoR9+=pQ%$BJg`4_=IEQ z3n<^g&mUk8j$55W`7r?bJow!o-vUVCcyJ)dI|#JEWUvqCW`k#-$068_ zL9lrs&k}KiM+4FB3xa_KkOhBQpzMZgY9Ip&w<+AO^N~k^RbT>$3`IIF#4-32 zw8rn@pz$K41vri44{%MxQ1*fw0ychxUM@yi02~3KVR&v(44UD$DR2UoOQ7dq7Dxoa zvmjq62MhtZ;43i0xwpW;7cvL;5nL@l$S7QI@C)(>myxLFS;BsSuVBC+TLa4$1Pzi_ka*!u7^KN2Gx>NnP!POxpZv=b1^{p4xh*()O};o|&|1G_KVP zGHII!&uZUG+X(0yAM)n|X`|hZU4HCEBx!%u)+?XLHmOytRLXkQ#w(Mt8MX1sBrK^m zUYUGdsEt=9T|}l9uf=4mdu_Zj$(mUkuS~AeYUh|ok_hzD{VC&<+pSTSEN*Q7E=uMfs=M_4x(5(t0P3~om>L+c-nNHT9V zWORJewpoKc9hLAQ4HX^Jg3yMFj%mt~hKi19lXUY2N;{@;eH$t|rj;`rDmtdQR~sri zrrr9o4U~4&yiX&(4HX@;5<40yI%Y`}TEOVkEce)O_QHisCF3|7g7P3|KSsc-e(k)9 zEW%_-gYb!mWI?EA2TBrzX>WuiL70ZFl_Ut$!c<9uFip#qBnZ={i;@Ik8dEGu5T+GR zBnv_%|C1y^m~_)_=vvDdlVDv0F`!~OgSbLc-M%Ts4?}(zOorn+A2}c`=hL!%PXt1h zSF%7NskW_qU_NoHYhWtrVRZ}4WIm~GftmCd)GaX6gJ*RM%rv4gS_kX!shDo4*DWy9 zlA(1A%=BeeT?13iiLF~;rbFp<3(U0XDgx^;#qfiA&~}(=HStC1(H3X?@Q<~~yn%Pq z+Iu%g(bNeM(46rLg7&LhP>~|?&`?~jDEOpN{i2{s*{nWMFx6~PpD37uwyIAQOikO= zCkm#lO7)3?sjNzUqF{>Kp*~SC^;NH56jX^j)h7z3%CuLc&H~O9S_e@W)?Up-s`YDK zg7HZ&$%9c9vX(R$Q=74p24ku+P10aYJ!VN7jH$#tNrN#pSSD#OCi-!b24mt*yWJ#` z5>~fKl{6R=>qC+TW1@Tt!L$dW<-!FeI2V-TXv>Bp@+d#lRcKEE&6il)hBLVW&nOnw z&a+7B??@hqPo78`h)Voh$pSHX|0G!;Chbkpdn!RfFj;RWSs*6q+L8rga&9D9ASUI5 zB@4u4+)mO!)QCGs7Kq8Wqhx`Ybk9N{lym=0U}@W45CrF+eau1N0snl7s>Y84i=;oX z{*mxWMtvip+HtXdkuYs3uU{lgdyHDwD`A;7O{`xeOuIJJFA}D0bZB-xq%JtGpK%%Fm0V)zet$&?nNYK|E7SWkXy|{%L5fD{=aDOEks~hp9n-+ETz~W z5%EdahKPu2vrYXYVjAsV|A?4YXVgC;rrEda9}&~;&KU1m&(F^^d|>?}Vp<+p|A?5T z?`(*OXkL7_{t+>ae_sEHnAUf0`-2jxJ+$2gS?_R^Olhy%czFKTg4nm7McV8vc_2QS zC21h4rD2iQG+Ssk0|>M?H(?UE(8T=runy==q`^MjwuiW%wPzdP^QmB=IZi z6P!xx)>1p~B1!hFOE5l} zD|s*~(b19yV^Y0Y(qK%oPfHq%Nq32)!I*@XOB#$xdCT?^em5rRJtPgrqAwrC_!Z}GW@|`yMCYZrhniV}_?2&iiX^{FeWTzLi~2=DwPH$rqHsoj=T8>bCkm!9 zJL?k#)1NE#iGpdz@IY9<;bEl#?3r6%={1T(Pe8wu6a+4YNr>1uNQB4OHks(z6$eZ5z| zNSMY-Yu4)%Go4khUnERx?dlf^)7vHWjf84$O8p{Xx|>(ONSO9MLL_4cp#_b0(fVQ> z1FI>`z%M?r;_6cDuQ_T~Uf;~|5Y3bnwJ`f}qx1Nf{^)}`R+~$9ujB4l=_ z{jUx7gscTSy5S;Zw&q>KMaZnobbXBe`H^vOLJ5hsihpZiL?yU0h`{*YB47n7Z?21# zPGRyTv`{q@%?cQN`lCDlD4@s;weS9eNB{2#_}KBF9uZJ86HxaEgl47g5im0%ZBXY| zU}nR%?h!CE5mWaFm|3_`_XwC7(CAU;G+=7)QlAKD!D4&eBVcO%wC)iwH6CJ!g$u>C zkm{Kes$KrvfO9&G&lS)ix~wycwp)r%y7wdIxZ(^oukO6{6HY!HjaX*lAJt!K3YM_^=+9=TJgWWEwf}V|JS!=_RqlhfBbEk)r|aK z-wX4mKc?{7Hq|`>W`!=+JpyKB-q$?>W<|^f)cGqgD>1+B5il!oqV5qeEpK67=T~6O z%R}oP0n<|7x<|mYFc%SMix)ZQfPX$$`lkyw`k}p-wj$9QffsoR&jz*iEYdbv3yA~q ziI${+s8;orED+NqC&>aa?O85aAf_<~B@4u~+8>Vv@d2vOr9_uOU#4JcgFi{ZSsLxeUuT0+7>CNuWI&)sp@S0c+$jwGAkedIigR zMZhP<^@)IL!??Ofz%*k~-6LRHvb*jPFpard_XwEwG#^ywufQ}34I_1x1Ey7ub&r5) zSVVmypxTyQ_XwEgmDW81riJ>0k;e>1HzZqJpAOgZ5gYwgvme72o(*d2S)^?)k_Y0G z5J>}3ty&{lAf`zNBn!l}r%19uOk-Y47KmwyqLoBR&NRbNvOq#@kSq|>faQ_~qEeqO zSs*6q=Oqioq`Mq}^h9+NIslrs>Ucrc=~CDOxdD;%m~JZJf@O5D1pg3ZN|FQ+N%?@f z1;k_4B_Ngd9g+uR68}*0fK2M!TT7fcO!9|I9*{}@GRXrn4LBlsK&Azahf4g8OcMsx zB_P#?Ws(PE8gWwcfJ`ge48x>Mk&v?`aM|uDwDCB$NCt2&P=U+;h#+%`IG1|F?@GscvoepPu-{_P;z)iCy$#PfR{f{n!(e z##SSL_)JXpM*Y|mleFbO_Qd2W_s5=?6zPom;WIIr3HmQjR6=(D*b|e7XFvADzP{;b zY!dcwAJ~uh;IihwUlvKgAGPtuC-?u`8K>CI@c+<&8y68e|bm>s9 zZx$+`*8;dJv_+z3f8qDzzpN46sD_J9BzXZpBU(P$-0;y-$v)N4(K1aaYv^d1=BSTv z;7`UhZFECN%QQ2(p`&G*e7K>bWtz`(XyCLJmbe=}TAJT1Z0Km2CEDN6(K5@`WC9w& zeq?G``F^^v&yJSvYx*`t1eP^V)to8(UlE9`lY7HN#3$<-A|h&mPS!snW^prewfKEfy%U?+hvbHch+2dP^^b_z0JX{Wel@1` z0sj?I%@PWoBuvLS(doFsWDr`q+_{pDAK8hBY<{HuwT(z*1uivggnaUq#%W+f&xT!hS8ENHk0nbp|Ua1k==QP^-1GAp7owZXnJvnE3uGD2!qf*LMD zW?eQmT!hTZoI`};Yi}I>p&nGD)-)Cth^`#KmIHl)$bbJ?k&CR6?(aYSCK!wTvu{GJ zR>IG{3A1Fkf9_3~b<=nJso#WIyv0BFCd>-n`MEb?meFw9PfadnEu((!O_&9}_p@(8 zt*VLBPfadnY1jPRn=tFE>Wn2|Br}k-^@@#XXMLS?p>et$4y(ddH*HQq)Kh*=)FR7k z=kk+p!6&0!f9fr$)ireciML=j*LnI+yaltkyWM}{EttJ6^Z1FkVAi(3*H63!v$Z3= zf8s5er9Cv`C*FeD+5bn}m%ztW9O=&^n}j5U00F|y!yM+Y2W$u-hSZ_5`dOt0`vElom*v6!Z&YfP=Fj%MbE3PqX zhoQwaW}JVyxWdVO0$f-+W*2J0 zGSOA22}{D-uNCNszrX+M1)I=U-(IK*e{21P0$lhDzlSFN?9Vt3=VR0b7?VZ(kgj{m zr0I|O299RhBT*7jmNdPok4{;tzS(y(lAsfP zHDhVHd{!TwvSchlvs=f=I7QEZWOi60;rlt74=%pBlAQl>LT32Roo%}}lB}!jlCh+f z*(GDitF%kTlGtRIj3sl8T{4!`{dUP%a?jW$V@ba7MVsG^bB#W4my9KSyj?Pu`~=7b z@$TtbQm56UK2=1~&prn7JGeX0+-w7ch;M?{I83VtxPsk|vZ~KId zgHOz{J*$j_>+KUV7CvvEkkK&CJ|W{_iW5T8_20Bl$e37epO8^;1cVomkkfTnqwzn= zRsR8gye#)eCEdU3{h{GI+uK8u(!b_^$ddT!xq16!Y18vRWQn>n|3j9V;rSo3WK7Ec zkiUK;|3m)5FZA}1zT(3C5BWn@E6;N^3X+oXZdkA^Epo$xCGJ~pSg>4nx?#c6d+mG|)5$XafEyN! zgw<|XFkXJ>js>CW+yyS?g0VNy4GTtS4OsZc3j0~r>*&iDu?i%2+apnkJnWPd=Y5=! z5(3X%=wQH%yxX0SGU6U{Ldr;c-U%rqY?BjGM%H(okTRnFZjpl-W+V-AMoI{p?1Yq& z^K~brjF@kO^a_fUmceHi_B{d%12>=Hzmr(sg1+D4alhUlD60(_!Hp&IFMTy*>07z94{j`J&%Dw{GnT6Jmi5_;BqRCB#noZ(;!2Y8L@`ZST2>a* zlqKe$i)qSI^YN8MjFly4Y%xt)dcIanQ~O;4z#dKTDfF##PHgyox`Juw$&Li zBkkADh#6(~ZFKa`jIigO5i`0za7N6?dgwJr!)8>ibwU2iTXqx&ud^_3JVs?Zy zQ_V$X82uC^ciSUTNa}V{|2Qbx=(ARSX!{Hd;L2zj40Opa*eR>HGhkUSj> zCwj?Hp>0EH7#qHSECpji>aV?L%s9U8P0#0;Q9jvw#!?4(&zLpDe(xEx{`isij9I&U z<}J@Z9_yZwrC?0^)R^~-S#Q1SJ!95tzXao_+$o_60B{YxJp50I91qmxn|;2D(y><> z@1YN)8^iat(sx7JaC51{ce?rl^&Dx^BqzHBsn9x-U(k;4B$d3}U$x<#@M zb$aL~qAK`9D8GhsX@-JrL51&(t`~VU0SmRP0%k9w-%i)}R;fDADAw=6t+V>{(;3D;0azl-f?z81X_= zQt+K?dS~?INHG6ushBIR*;M*Y4BzomcS0KUqq|BvU93k(m9`Vsrf-(E6V|DJDs3mM zS)bfp(r?20_0`gL!dmvvrR{`u?N|4dbh=pMZZ2&ntatxZ+D=&eR_;aJ+d>L5J6cZ3 zp;6eR5&WCa$7k1c+6;CD&0c%#l!omr1zW>+)jrQhOImci*KApD&i9%vYs!E1nl0)z2%+}>zuvr8L^i6wtGf$ zAM2hGYm&3>8L{s8n|nsAEzUdWS|C|JTXDY%oz2Q zKN|u5RrQT$KsvNIyyucCq}RA*VfbdcV?pR%}; z7{CASh6N+{_ik7)X3st3LOOX@a-|y37M$Bls;BX%{0eL-D(1*_>#YK&Xikw*fRbW&w0jgL=3U!OTWr&(8M?4&% zK&N*M8L^kQcs4>t@m}v3GP0jJ>e&bx?dKo!j3H})wcasgt+4oA&qm0a;>mA$$dI(h zpS)wp8l~y)JsTlwna1}VFr0t|u(!;i!Kpryzw&9DLJXDG*;X3HhHudE5{#I%&|BU! zW^MFntLGzTt@K;(8MAiU`fblg%vvh+9nTrFw)&0tj9F`a@LkVG%-ZYNKa_wmX|eeG zo-<}`_BZbtvsSzDdp_UrLYs>0XI9Sv)&H$Q-c1|;{yEqb43QMaMrp8*e&0iOhVO3g z*paphdc}@))EckYv1WSTD|W1peE;Opr(i8K#4C2Jd#b!*#~Np+SL|5N{K`9aq+PE5 zfk&T$b;=m8*s&&g3G7B^!#w-E)da*9=;UG;=lLmbFN*&r&!gIzW$OJN1gmmySSgKi z+H01EPjB;dl%!e8y=2MSWto>OS;PFRmn>P!TzbO8xnxZ<$xD{3ZC><}C2O3Yc*&Br z&Q<^H;asxU^cgQ%vi5n^OO~vGeh-$n7FHWc=pU*KO7V}+{}AOxif^to$x}|q5YwvqW)P5)@0jMnPk*d=3B zT>LLKXObm<1jug67UhxfdD2JajL*z%mebHQ=U8-aO_jv|vt1IySN3CDy^y4@w?o2G ze%-&?=!GSGvmFwa?z?_sqZgL!lpPY5>Y+ci(F;rTZ|#tof8|r=baK0nwB~vW;DI+jF{2% zV`s#Srr$avW;9*W?&wo7n!ezSn9&q=M$Bk>$tf|dRc|{ZW;7jlM$BmXHHfjz&$rB| zU)fyDhRMfIqMD>?kiDd-U-OYEL|x;C-0%%`PEM$L+9^5Xs?jMqBWtHqa>mwoosu)U zPB|rKe4Uea_}v*{gPf8x#-4OePAGfcDLLb8xl?jR+J2A^p!@BqR$*M+L6Up3g{sk8 zhFx96_X`l*WrskatKAtPDvCQHBt-qjJ|Sc25B3SAwP&A@@$<0`+q25ZInO>JW9GB= z2^lTd*e7J1+~kCi5HiR=EDjF_N5d+yQ;OsN zC`M-ZCgN9m{s72_J119&S>^>B!}oLdYzR#^o^tt8jIEGcHjK2RZrL#IKHcf^r5J?) zw`>@bd)%^NgkE;qkv#)!hUP+3;Wpc;{vf;|bSGCX z?!N;TqusGk2*13`BUXm*tKP68q`&3`D@OZoykNzMf419$xnk76;{_{5{-tL<7!{*` zsu!$S1N_trR;&fS@LwLhAbV#PdBKXcLAw{MSR=$f@cAY)oDH#>hjP53BZOBpif4v6 zaZA-yG5=fAF35KJSt+|< zP5RaUE8$zPhP~={=H@oPhE)+`&U?t*O!hVi?<=G~dm~iZ@q6wV!1v&W0cp06|K9N{ zu->}GIRn;8lbkbPo%40)3|OPQ<(vWQi&p0hSR4G-IRnP}<$rMe8QJ#vl5+-((~xrp zjKcL`@Z~~avR+7%TPR>8terTl9rALJ$AfElJ_HMBI_w{+niTZChYo_J>_DOVqCb8p z9U^rAKqi46Q&^tQXv}Va@cmTQ;nLe&Lo4YnqRJ z+U1vGjpBF9hBZgbEgRMlTimlDP4GjvY#8yMI^X3KGqN89n~B*bNVc(JeU>l5OVtm` z-PMM{xZsx9DPyG#mY22z!}oqEJ0K16f2Heyb<6FaDcLt*trIO>2ds}amaYTVR6i+Q z2du+BaY4zx0c*FXOV^4o`s>Fmw8A7P^aDS(dgtrE!n_|LE56opaHL{z9@ATX4ka ziBfjKT6caayI>95jV^AQfapA(-;P38avcVW)MtA=6TX`+*L?osnko%=zg-f;_qaV0 z(oj)5B&>0k*dbvJvega=YlM^?5=MC14hbXnFLp>6frGEG@hKTmkJ}?5TV=K#5|;Q4 zc1T!)zYmhTCt!U?9U7dW3Hu(w-`L<_XPK!>V0|(HvQF9gL0=lAL!FT-3IEiUE?F49 z&%0wm2zb^F3r55&H!K(-EpAvaVotkZ!3etYDi>db5p}N{7L2gx+^}H8z3GkxA@D!k zuwX=f@@f~;$p{?|7Nh%u*+?LA3XqvZPFOaQ6R0Sn5L*LQ<=(JT2wvkgOT+hlZ&?z; z|K=r2M*OYUcsQ4=0U}q3cTPUN!Z*=irq33YW|o$6lm_CIs7{YkKZ5_7{sX`H!Uu`+!7y<%(aW-y7~&N>))X=QDIe`cSM@p{HSAtUp5_6Zq-AMJ1ZJ2KinZJ&^Fb+r>hLeQ=D2^lMQ+b3jH zJPg8H3kmrstg9JJJc;Imi*K$FQQ?Hl@YUESBQ!j3myEH{XqSwUu*fbM<6xCtGDg8` zcF7n6+wGDu0`}V_WBEU7pNypcAMBE`?EkY}GM4<4AcH@;_l+V&p)+S6tu4Di3V*Z{ zQiX^CH@jqE_?~dbf{-%b4GTuiF*ht2L7%?G#au9&Cb(h2$ZB@Of>HKMH!K)&_ulGa zE*O1_-LW7f{)-zHjLOg5=Hf*dp)Z0(K?6+rfyf7B-R->(!uty0vo}J8&hrMiVqo|l zaKnI*`Az2xBrcsZU{ro~pyN4UOa`1YU_@?n&Vcdw-_98@8b|vb&jDj`gBu2f#Gg86 zz&O12cE_*4C|m>v4;BVf%r_P`qJiv$D(s;sGaP725L ziF?hIw9a8~nX)E2?@mu&pS9CB!4%0(y_@2sP_m!@JxB@~{yj;QrumUmQp1;aMoL=a z4^Bu~H(Ys_gLh>OFw_YtIEt3*81RnN+ z6(jP57pxeer@dgsi2a)vtQf%;-R*%~F{1DEf)yitv^T5>@c}Pbu?Cpo1uNDFyTPhp zaMX(aGH3&mY|;tVdpoCyjIap6^Bu5z%u14*#9@8bH#?;%{#XjOhVSMtcs^RvAYbvC zEo+k%UbAJ*^6y@=Wi4~rJs!_3Yn(^DX3N@VuGef?6aCC$qFCBBkS6eFPq|x3e4Rh9O z|4|y|tle(7wnh?S@XSJ3f8Rm{5Ux zux5>S1gvq)s5p&BPN^ES& zDOj_{`}pt@%r$Gg;iX{B8t;Wtux5?7uN16V<9&QY3FewLURh~alg6tr1#8xLdrHBY zHQq-@YQB5yXgq6P%)KDK-zl-uVh!$@7{0x3nUH4sFLz8>2i-Qx)ts=lX>iAc^~w+2 zF<}kTZ?vn|VO+-Ut<{ zD#y8EVEDGXVL<5mi*p9j+c4hoD=^AVJ7>U13q0z01dO(m&KWS`#y{qG1dO`hIA_4f z`{o44BjB~|1Lq7FffW-SkAP7)U{aq9Y7s4_{LoO|nDOgiFwzRoTp!~klnW}vK%w%7 z-Y_zJfA)eAq4fI6u3wGO`nY>WjM|snGh+09&pjhX@r94Oo+C!{aQBQD)pOl5Vsy89 z!HCw_bDwZMM~wEN?in%aUj!pqvbDf;Wljw*K9SFO55kH~0`=VP0El48+9Oiv{*iNH z!}mWo#Y^jHYoQ#wpxmPa zC4T|P?x5|KI%7T&5gNX2fZ{Z9Sd9}QOeE@~@LzO0LEQHP5Zz;!NTJ|Q&WR1*t@07%!uo5i@G)oDnm24m%|#1a&(jmN@#V zqX}a)Jp6gC5g$k5sXd?uevFDAhTs!(ltB$QqCvtblJRSd4bZLLu$2SF8+Q zyEm)|g`W&~@PdrV0ba0TgjRULit)PG3s#KY_q<@mSnl$I6(jrl3J<;@%Q`3TYAiH4c9ve^mVQ9+2E^k3=Cp>6Fy)z2%IQ z5dA|Zq>SJTf)3tQBGw5hBXp+|Qby$OoscpD%R&y`l@Yhi2`MA&Q&SxDD&uxeNEty} zoscqOZk($5^xni@?ZyIVbaP*g6e?aQzOmtZwb;fa`MZj1%(DJ|agABJe_dQ-mgmn@ z6*U_y!M7LJm}U0i;u^D*PA{%8%jL3S8z!CSm)av@DLrG4h^2KzwXNZ?)Go6}#M1kb zh^?Mjio)i4(tSm=z_9WY z8NM&sB_ip5+#V52w_%TnrF)${B9`v&+9P7={U4uuZ?f z9TP_DZ`?6q^e#%mVOP!sLyaX^NhpCoRTvFS2!hS?ESxDV~7k`F%SCB*CYPCt#WVSbfnSj-~W25M)Vd6kbtUw0L)tk%c!0>(D4gpE&vf>F?N_Q4dz*71T#S^fUri&+FDg9gV1T3Xjel6z<_x>GN zO7AP4fTi>)I|L-9$>IrEN|zQ-z*71i2oT}RBt&MH&m4gYoMf+53lINPSS=JUx3*9C zegPJU@VQ~3B>S&ku`+zuf8CQ&5gH!!f)(SW)(cjQpw(WmVr;$V1uI6~8828d9?yTl zgD=QPy~hhyjNzy^tO(ufykNz+|F##bSR?!atR5}|=Oi>h99n_yN1}-TWAM3U?hvN@ z%m?t)Kz_~h`1eiUKwTm4*eOl%U@6$*h6wN3k_K7oHCxsufA2M0)-2s#vt=!F!8bjY z1lBlrd(D=$&p5ByvL-UTX3JV>yZ3BKL;cKawydqRnI205Yp#J{dspwOCZn0C4dn%n zlz!ExL3p1NLZyw8?id)pC2kmyhI!jL1J)(2&Ka=Q_@#3OtRMd3oB?ZsOBx)1M#lW@ z&KWSe$2w=gI8L}>K!{!HoB?BVw{r%J!ZToiKtylbfm~N-{&4eO!Q?@=OcXk=ZuE>9 zVtrmQBh)_O4KqgYbZ?k3n%8;5jFJ6qZ(jp(3 z?cs~FE_udFmaI{BddZUY$~iB3_~NWxp7N3<>zHF+vSdx;pX1?+v%XpGElbimzxR?Q z>z>JTJ$!N2K;H#R1Ymo&S29oX)p)yP9xjx2POdb~EncuOd_&x`A&v5gTQ;mkVs6>6 z=2+;K4Qq=x-Lhc~am+0n)(Ss%%Z4?80F*KvSDP`flUE_ zKnApY$5_Umcm;$7`~kfaDm3qO$H4IYiyH=n;NLrEz}UTIf#W$~)IRE*0pqpSIRi%O za_0;fqkEk*V08Y^F*2b9_4Y4CHw*5I+o*%ML$kP2y`-Cj(DJO&^`TuR7 zka2MS65Er*s2B^vkr^S+%@yYw2vdL=mBldY1!x0kdhI_}5(YV$-hK$m`ddHB_J9epObI7P}_KqQ=J?$Ms)&gI7#j{st?Qq;n zhNLyFT;|ybS({XP$B?zm|AFBhkNX0!->9-I-Oc}K$SzUtVXLKJ@}OHLN+tb=cgzf5|5rU48L6UYyV`kCep zGgdu^yMEf{o!@?w$>4h23u1us-;)TQ;l-e&?1A>ws(4xcpL#{s-K$Vcbu1 z%Z3rZ(JdRs`gh&4A(a1@TQ-dEi`TmRQjF{|U~`XMXevM&&WR1*R;R=SzMnZGX2@N) z&e1zF(5jsgGrV>?BW6(j(HSvA>HhVO-kAZk+!-;$=I2g{2`qy)I2txXBkse7^xvkF~HbB8Aq^zu}nJ@J)A0Oz7O@jF?gRS7*eG z#;?5T=$#pb>zxrZ`hM<=m{E7hTaJd!Xj|-zm{Imyr^JM=M>abeHlu2uGh#+l7l`l5 zH4+Iu95bxJ`ez7_Q>{3Kq}Ilu@0Klyl{z6*sEWB`VEDGVVL<5WaL#}cHgv1wIbf76 zcFus2_7mp}7;QJd?f4ZKaTU%PFzSBkoB<*h{8%FQ5YU^>rA}cerIjNdB@rCXC@3?wBxoe+(vf z+gpqk?6kuUNe$oK&PWMjVJD;vtgTK+8BV?<4&IeP^q3P;hR!x8qzsr3oRBh1Dq0-8 zD}!UdGg5-YzUI^Vl?8+PlyD@Z_y5`* zFZ9=qm|h#GtPV^K>45}(8}ved?auVB7du{^bMnYLznZxgt$sCg-N~bCPaZr>|2c^M zv*W;#^!(=Z++C+OFGwF=oL)FvyRGBZUFp}>cWhnOv2m_sjt1#n4V|yAJ9*@dbi?XX zjfZ6qH;->!6%GarJrPS*#Ns+S(StF)A`nS!Kfb6ssZR@3$8_|i-8M2{gu;41wCJY? zLpA#NKy}E_1Ca!N8-(Ag!qNKVlvK;qP*l6EY-&6-H4xVW@ye?3^q3q*AcA*%E*UaH zdS$GJex`KjoCwSr3{d0B zs*r)HM03^pf%c~5?Ts7T8#lE#y)7BHH!fvfdV9m>_J$Sh4R5wLz1-f^)ZVzey{V%W@0p1&W>Zf&4C95UqG(i8D1@mj%fWjGcU)An4_GHpUM zV%f8Hf7`OQV{NYb?(h+as4JQO!V zl49V97`#9t~8 zo0DEy9}VH{BcaMrG#ttZx0w2tNO(p_pAm=~vDP(}YUFoV<}$S%qLgPc6RGXfLt! zASV{fml-fT6bZ)@;d;F~R+BW;SjI&N3D9oGH-zGmP+Ybin34WitpS9p_Pq%I>6!CR zZ#?8g_)j++Jl#Co{F3|)3k&~7y@td+mM{tl|Lqpx*T?Zo2vy#z?2oIh45#)+r7Q>3 zEB7M%cSxQ#B!66OJ*HBD#q6LL$sg83^0&4(t!QsN(BAYG3%rN`wU8d{N6xW()q8^9w%Y`H;}%CuTzMTS%Xun5h(4 z@uGjbDf)>}>a9>TRINU3FVa7FcrqLbhNDyU+IVbQs8XUup8|8i2*jtt2$&KN)P!cl z;=~FIv|qcsWBcprwVPq7oLaM^qj^rp#uq!*3nNA>b*GkX=$N|%7{OB$CbSF;Vmj!0 zqT9R*L>+G}V6J-l$l+5*ccgdCHSHQAxo2{nF+H`B763f~twdw27FeLa^~%)tNNjp6 z$(D$LN6C1S7pX6fmu=amnGue|AWOBx^&kwer^2B~=C#0=tewH5tt_a42BX$I4bQPzjn`vcxp>PD3l;99U6_A z+}c=D*h8bunXMG7teoFLBjTX|!v|#e1exx!wmp{&1o7(f<4BUq_QrRGX|spSoTj-t znMF<8=%=RU_NJZU*-kmt?F~B!T}|7`5^8*_y%CRvg_>cL1rPZ;qeecw75HI<=AY({9B zXdz?{LOCKHhHb_3ob|cz!H5>50s3M&pJ__lQef|0tSU#a-k6qF1B|a@z~bSygMcOe zIEH73Pc*9aNXOE2aDO`b9nTLFs!p=>jskLNU|;#_iN`pUiMh|L*)-($-3hO?NgoG-%P(eKhJ+$ zIBER2r^Y>2etdO#Y7svdq>~isMP(x=k9ut4sPYjHl?}m%gN>+NTt+`VG-1N1v7^c- z3gd-3DVsd`p$X&ibn>Y)dye88@{xnI1^Cnr5w_Si#AdhsKnIv$k{+YU-784dci%R1&AJ9%&swmGMl zWowix%_pb!y_RlSetOYM6&kCEyLMJtn`DB!L`7Aqrx>10V``uy7GMnqta@}4G) z7O~{?0BmNzcKL{^u-OhT6os~kO%E6Wzjkwb<91+DQnfcM?0j=Ud&8#oh6U}7^MwJp zroHhMdW##GF}5ZIqV8SCy4TIpyXUUdyH~tufzWkW!*p20^oCe?V|sNYSy^vg#I&nM zR9Qwtix%D~Mz0jah^}i}4S{~?#2h&p1O}Z9GHf{Z5ib1NmGr)PAR4HG@_{8)0r89m zY68LIyZzcHX_{}YyS@AtUDN95|3A{Pa;K)1Y1%aHBUl49EhZn(V}t%ar){66g|bM` z7i>UzdwR*6VD%~S-(_GsM3)Vxi9S9p9!yAWzr8$$cHDhTJhBeO`u8V5B1gzS8=^UP zQK#Rom*1kDC)l>_yS?qG$u)HQgY@_KKq7%Q8YC0_jx141Y6LM4o~RMVj(&)CY3I%Z9gCNoJhtZKk=IWxc`-d_d&i<3L$uFzzP*5d*T)O0&aI0& zx6d1*-S|`>7@CI7BQwK>EL;@{v~GknV+qz%hp`n74bko$9yZWOtfQf*J^>;r_ynRg zp-34*_5lbST)?*Ev9Ey`q0lWPn+D&L$8;jE(IRuPhFDiyyi6LV*re0)-Hgs|b zCJV%z)I&TPrj<0ITX>^!f4n$e7XAk70{na(=3KjCbd0Frq!9e;!9UFJHAMS@S{Jc2 z9>6l$xpz)Sb4y3l>~!;Ptc+}as%3F;djtFj%duA*0`CE>cI&zqti{r{^;CHYDPE^tb|qyV~GpJXM~_(#4HcduA`B{ zj0=#@$efL^buu1+UZq|CJ8cKCHo-&Cgk2PDN3}u1{s|bCyCq)64xeafJ2(*k*bnj9 zBmTK-h<59kREseMpM}40b-0Ec8x`TmRJdT`;b>T|piLDFoFN!|wuD(^i|j^L<=0ze z?2VHL7o0qNIQ{ZUasjZg3Eh9aDR6LIp%J!6Fb&a23Z7`x-xR*QVn-w9E{F9Lzp}n1 zPgsS_ps)y%?Z@p#IS|2kC<0l;s*!3|OYBv7B~fflu>cS5*tXGz2#Tp14DDqx#EKHd ztMiH?EG~Z6UWG6-9e3LiLSZ&B>p@E9DzJ>`fv}+$5mOr6E5*7N{!sDXySWN|V z0n|$}kqpGcP_dWbH>eP}k|N;*$dhrQs?WpEXk|dLK-F0XauGXLFxz_fx_w=5&O+xG zmj~)+1oUKUOPx_2n-L9HlWx9H@Zio;8%1x|!4hhLA;~7_iG}cK90M$2Ly}=hJ`L@{ zN0JfjMvm{UJifaOi!FW{2%`jsY-K#myZsr^5WoQ`d~9=Q?^XppQOPbVzjjT>+O4eE zJGO6P9~^;f=RWxD$jG?vteOx1PtEMVz(6zC7@NLLvDt!u&S{Vgz!_MvML@5E0gHNI!Dp|0X?~sHHYz6@#Tla~Tce-+>7Dsea|&Ol-z5WZ{tJe&NDw`Q2Dk zGP|f7$ONp#x&rHuK0#7!n~cy@d@7lsxnN!=|OfNprv35~<{>JpG z&Ekj7RU1yW9H!ss2W~0pT6by}1j*1BTqKiA=-=TWAOaY|ETs-&3GK7uF~os>741U_ z?Se4+&Kkny!Y2iX>{<#pv^VY-JM1O+r}pVH2Y10()4OM_?brr>r$-K;tcl>?Iw?qA^@Lo4WdSgWE2veNNS%M8H$JyOCX9}a44vKCVgN}dhx3r z@61ilZ9ctfQ`Qe#>4(pb3t|I|y|tm&$CIraLvWvKH_#SnOzItgaC$60H2@GYIs+9` zLlyBD+~wH(TskTet_ep2475toC$;Y1jKs~ho|4cceB8@H2q?}A_-*xdc%!mcHowTmVtlI#-* zpa*gfgtQAsJzp6~!s=6liDB#VIys8PHe3oPq>r3vw28t0j%gQ72t%%PXiG$?AYX8K zX=P;UV^^-vfH?{2!>6a2h5n3V0U+`F+F-;R9*-p>LA?%6CRjvp_z>D*TSk+iVTgq6 zdhz6um#CqB^5Ay<0JKmMUuaG2W3Y|se6!)yk+)7A**;7gp!)1s+mt@GUJ$0|(pRF^ zjhm_Ip_WsJ7p7OdG)%iwwXR4)EMxo?kFNo~>v?P=s-V3H^wn|1N@#C6OdG9;gv%>{ zpiVywuOD`_5%IMR;S|OmS6b+>l=aC{0-)`TM96?OI!wDm@uAHxOF=xfk?Yde{8zF9xHH!A3c#}17hy#1t4bb$;y%s4lpQ)AKj^`+e<8Ni=#GyH%(byZ%!x^AwY^4lXeB1b9b;BsC~v)+$&j@GaDFRyfn zcAH{XSX+={@N3UtLddI2F(q1E9|##`kqAB)g`Gyj%|QFQ#MqF5$i7^I>uN(f0{+pM z{|OPN@*^@sX8IUtApZn-$tk=tJ`jgx<=4JoKICw=sCcIEQ!1?$Muig=?4F(SU$BS7*z?T(R5(Sluk zeW0}w-UKqf=(8mCc&vU#`1tI4*lj&0rH}6G;U%qzgpt5i9nL$URpk_Gp*5DofwEvC z^uaiV4n7qp^4C*h>C+`Cw?Nr`ltIuyj->&hArtJfofSzG{|w&K+CU4CXL?)~;&Krte!XPb*F@XR~#vl)vg!DQEXyKqCiT zXyhK9eE90P2e=3((sHyRHF_akT%F4ZeH5dMbEc;_MO<4*5ySNeTdofsoYQTe3OM9e z0q1mx%|M8Ydj(?wbqtO1H&V1GD0VI*sler@DKHPX1u@WO&LHWq}} zN|>G;!5D?DY@i|(NKV0P2SafRWU!Ng%*_X_nynT-N4P9w(J5g>z}cG$3lh6yI2R}Z z1OL{OQJNwIIbxVSHEq~~j~v5uCsIhvCsXiBdTl6PgY6U&3iL?-aCADnYvgWA1i}fJ zJNPRYi^AI*LOkY+R)Z1dA~NwYX81(a=R)5Ig&Xj`QK|~}V_+Hs+N1bV>7B@TJo8*HGAlv&tx88R=zn$@bg08DF!#;jQ+DMW*dXpK5s5 zp;?qJwh9Rj%MtU~48x68PS^Zph@m5O`3(^~U%jk*&-Sy+^O4lX#11QIh9Zi_Ja-IS5!*B+WsixAF~ zI`Xkp#EdF^;6qXP5`&?~kPsh7x=$!5t@H%E_CbB142^&bK03~cz-J2=a0p3P_aoz~ zV;Le=4e2EdJ662Ip{qg+(@Phc4CxaOksKE9vrjt~zT)GH0tv`&2A_pq#_SoWAS@#e zhBpzOAAF=|M&jest}Gl)z{#MO3E=9}A?N*i=h_d545ERYq<#n#z){5cVMzjL0vgq* zN5<$d#(E%FLjVjV#8;plS)uu=Gso=Lo*V7njYC0M!6Mn584Xmy$%7j^UOfa2phBLj+8dGKhTtep8R&tmdi%-SquYl2AB~C>b!o*+PICTqW2UV0O}r_}aJtQjyM zAOf@{mB;8>SA|3nb-N#@z$m{Vu8)fcqxcuFRF&EkG4vXoMxw=4XxnN7XYfK{G77#p z3c(@T{nv)*-xL9Z_SS1s8%0(ZEC6+;4&p?rbP9T+j0#Ivwc*qu9qR^2R8win1!e969jMzPGQeljTHo+C0d{6X=cYLw z%XiT#-*~jW3FkB3pr=Ta<0Bf@b9l&S#W$k$J}b>Zc(Na%9EY=u_jN5=hV@?WesNjX z>zi>@L+9glA_D^OKC=r^xOMwPy7}U5XP0lLtcO>T0+E$Ce$PaF6)8*gff<;Z0F?Cc zRh7sMkA_=Yn{p$`yyo7T)yXd2s|YCF`pu20)J^E1u7uCj7zzohm*! zOu`9PV0El`jgqVdym|ubgO-IS4{b0T^x&9*-vd_onFLnIF|Uq2OFP!i>&eJO<+v% zDNQMLxK}VkHWkj1ww3*D{Mu*>(4iY7Q-g@q0b27LTYl@o=Sx=nlSyw5&meWS2CC`Jox&V4y?EJdBx?L|wdWT**QibCuPa&*O+y)8XDuxJr! zCuF6`kFh8WTH2M;Ah{teL56{;C|YL?5CWwh^qAo>79}Fqb(&$)BvO3{ZDQ&VKrv)_ z)Pq}9Pwhe*h&(C=NiL>7L9UfmpR^qsKx=!}^Bz5ovnZUZP#nwd)NmecGd)yC$zbBx zx~V#{b&*`u{iEV>sF_%0WfFevpgsf1LzIt5L1fyCWX^FT^ApF-uTO89g}n2e)9=`2 zq~{zyy=)aX>fgC)IW@8#b?;c!cxqJ(PMDouxU+LBAAQvZ(=m6wz7~E473yWpz~Rnd ztaT&O1gc>X*Hs)}!^{Va#sOihq!poX4W*$6;`obFV#qA99EO)e;rF8x?&765a-^1O zaYBO|4xa?XhA;=nBn!c6OeB%HhEyRP$9y3Thyuka14e|0@Lvkgf`dp4#^l^T0Uu+t zj*K_n48&-y22V1P;KhjaMzYRMpbeQB^&U|jFLxB#JP8|8Q-(A>rE`iD+!HVi&u3opQ|ICz3YvYl(*Hj zYi)Pay0foZG7-ebzVGq6gmHX!ZMd~juV`&NK08ReGaOE#l-2r>fy2Zccp;owPJQtp zZW$nDBSJ_`j zI2VgGR&@H~AZW0rGd~J#XU@;-;noeXVZ-rih)5MBhQcbKBU;?}3M?LQ#URyZ0_~!r zQ*j^xJ8ERP;CN7a_xg^RZ*}fChVzX$Gbw&1s}m2l(Syy~aiE)uHk6}1J-A^qi~&O& z`Zd|XLX;=o;mQ(xZ=pTyC>(c>B84w7g}eZ;q{-T&;t7UlEcf8ep#ocaSg!uQT5d*;U=Mc9Y5{9+`8y+O3ZxR!5GU88|C}c%4as zj8Sm}IuB7)Y+9 zkn+RSAj!!57>OLd8F?9$BQLpAKnZ>{&lbt)pTn$I`MD!kesbomrxXp8Qk2t!2?c@- zj&Uf7D$8l-K(4Mf_35;5EwbTip|0;IIL-|GtiWj>;r$j99sXj^_kUyPXoig z%A641&qpSaEiKjzxiaAJt~wie$J0-KMSl|NRDZgR|G=k2?i2pI{3|+qhx*fF#J}aw zNWLWsWDhe%diLhiO`G{YL4cHErr_V{KZj{|=b<>Y`o-Re@QCS#5M3EIFEljzH}rr$ z9sZ5VD&+0(0Fi_x1}GK-^C9w+iT2?D5AxvvtYw_bQ#1$wNh*|y=0W~TESrLh{5!WD^0kTEsOj)r^ZUTFk!pdtEPujK9t_kS-yLT*6V+q+<1p<3 z$`NEtie(k?ia?OgJ5_`#kp)KnLkOsP z3#eg=L=GSbqP)&Acu~1h7t*Vzh2e!XJs=55OVya3q;=l1W3fglMAa@FWycv?V*nyz zIL|`mFSxi@&_YKgzW5AQ!gON7KLl8CR&+pA`~pa^+sNAX0BtbE>4X5Lo{N74$n!z- zE?k>g1oYyM!-~k-_aJyd+suSKoP}x{NjjuO(Gz@c^+6>=ggsJQrXfa&M;R{Q>(|Cv z7nnfaB4V%#E33d8^8miW<6-gIObvstMNVe)tQrQb06!V+pR&u2VF1toJ-nV2^4LIW zZ!;Tm2xxNwW~vIAd02tGAKEiLYmr&pqcD=YcH*27JfUk_x^~XYtx!frG#4rB?WEYa z@nplAiyu5o6d8wUfE`*ehUjS>WDo(>(2M|ls9ey@bd^lQnZ``nGe$%CxU3yne>2Jv zkVVfRIZ{wa!&FkWvuW7T&_^YIiFHFqGE&jD2|GAcI?F0XKt~lUCDC#t8(GEBXxrCB zQB)n82`A7f>rHxK!4u-H-NPuThijh7Z=l<3*G4dWd;@2qv1P(R48-xZ!K0}zg+7RI zDoWpWxa#u-KUPE~ZV- z#?iOl9HyY++BqiG@bR(Zi=b>}(TmhkEEr zVc1)$V1|w$r;h*5I7)IDQ0lF$o+019YyzLHQ1vEaJb7GM2SPv|4y9Idn5m%*nIt?) zR78iQCKL@&_#?+TrH*EZA{?nLigxfsQFlZ3$^~_(*IaVz2b+@n&4XBsvLV35Mj1R1rUjv!T1;b3{1`hFsfGytuV!4vb|J zeZX)JudU+rg`6I80w2Jsd?zkF5=<(>&od%{G=)jXZDCLj0x0ieV2MK!_FzfW_ZEPq z&R$EPQZR=USkOttBb}oYZ%OY>Tpm>TjEZi?bIB|0b!;J&IE@krg`Y7a2y!+BNX2Qr zK2S<*9yULL!3X>pr+~LwtaCpxuq+pT3EG5uxw{y(IDp2Vl@k;S;g&{FmD_<6+)|GP zkxM<5=l0Yma>2G2?21n?CR|xxf$Vez;kt~*rnp1~#kqP6r@&T{0eHEP$R%l^7-hjTQ`=ZYn?0cCX4 zi8sgcd&$`bT1g4mZn`)E1H0 zB?-C4Fh%>sJR$KO8<>Ca(*xRKKHvGGN;AFkX?{oM58Mw+3X1}~qk#mo(7{|rU= z*RO;_rfbPsn6R?KF3MOP?B2MGf(B=M4esmOkc@?@;&iY{5$2f@4x$(m68mC7c!e9q zsSUC)Mde*Ug(f&NTV!C02~KT|qMDGJDA=G>Hi#!Uh6x_epAY-moQOVU@saKMF3K5D zF$4ICMfp+uM+5#if}jE74p;y=F+ddKJ+T0T@CzB6N|hKzIZ_M|<_n#ToKCgfg#S1b z(#N35C#0}~A6|)aOr;@@Tv@RltwLG~3`(v@EFu+Z_bJ~EsT|0w8}cMlV90c& zd{kmfH9*K&gmhQ@PvV5qhp4~-{VZ&GAR7sc6X}pS)rK->6yv7204naLwm=L5NIatH z6HyJht(4v4IZ6sn6b>PHn^bfh+gvP=sN*BQ3Mga9!^E~x(&3R`3lLKPD3b$2`#>Bz zXBQIEWV66To~D@%a$8AttoMpCU~@&HEwX6X!puGoIvib4`b<|Nj{fc=aETP!<_yL} zB?Y-toVBU@&`R12W}Olq_PF#Uk;0*x)ph!ex*F&fQGsiQm>Rh&tkcD=uU>szPJ;Ww zMDZoWhoCJTW*Z{QpP@#O(;g2lXU>_G-wzWz88sK-J<5U$!q)F%t466Yb3~yLE_*FY zSM6arlUq88Ln=i=wQ@vD0FLV=h`J(BqNw#7hrnQ;K#A|P%K`W(;Lip;BCO zDPi~{V3P-C*O(wOk!7wmgp|wF^L30Q7I%7b!*J7wLt=pyPPlS1IDy9p^#DggF9|qE zpipckFC=bIkgy=a;(QS=fn(cnvPiMl-+TMLW_0~t^Ls}`OgdN6DMn*DLwFJpn#q>x zm^L~`YUMaH4v``yS12rVB@k&H1*LQVW(Bfo@m45LMGuigMS<(b(QA`?fnP)k;Ks~s zA=E&%^C&V5mnAnVAXg}R$ZdrDAk9Gd3ry*`AGrgf2nrMsWje^zU+8T*3ZXuMTHh`1 zOKHeJLuUCKg_UB87H=}ijF~sLW9_!|_7y0BbMoMxj2SaXYHne&NatuzDv)3)mzK}{ ztt&&u@ip~`*1#g6LlMYA6@{DN`4^Ur#jt_vQHrgyeozRK5~*Y{U8TjPZ6oIs2_+#^ zk)hN^IX{Vds=E+E1;7Z*A(C#>Izl29#i!}4E>$I>K_$XeoH~<7jcj+}mxlXWO(hO$ zS}Y}A?V*gJgrv#j*PbA@Re{tF3`6mSVWje`aV&yk1;jODNHJTsqa<51xteV%zxL<^ z@wEdyR*|x*QofNIfHfxD!-#ZC_a}1j#U_^gqF79N_#3F` z5Ebwh>6dUFK{(QL;ab?Kj5ZZypJbv<+Fi_4EFU<5u^iq)kxMOBkv+4zn{kkK+d)(_ z!^$FjiPC_}Sw6;(z=>HD4Z_!&hNB6bWgSDzh++`=3^Pk=2d7kL8FK*dvt>dG_{+lm zi(^B`p%wNT$poz;Jw-xF1lx9S7%2Snrz2mlH1ROUOEFD;Iuo4|? zI|yf@nO%)#g}fOEa>yFL1?)T)cu+5C=3kBgbk)zlUI$08srgOtJ-qG{X)# zzFXD-mQ@yEW}r9~9g{`&XBdg>VffUf8R^$P(4erzWg?g!m@@<@G)qv~*`Qyah>y@@k9n=ZR!A&v<+8QBl{Yw5VIbOrIYSbh~m_i zI4nZ(U9+6{lQ8%yv9zL|sM%Xa+wq_(>R`NybQsZp2*;D+F%)FPj(<81tcwx$A0p}?AKP+``4v+9_rk=4yDT}V6$j>dd?BFHF=-fu@R|KC@F?pSUTr7 zo@zXlKJ-q<>oYqxykRP5^nCJYGmT>LPNbHfp1Hd7-8m=-b?T*^>DQXli&vhWvsmxf z>-+W7Gbus+=r#N49qZoUw=l?jIQTPXgkjtR}qbIZi3ovU{67-Q*~-% zJ*=b{a#KaUtARM3f(Nyz{EqW#kZ>b39Vx(A^jVmZ1c)tqHC6+0R|xh7ND8K4V3sIg zCxa*miUxrW3r`Z6J^F-N)L)v8q<=L6c*;e&fQ{90gPWq19vu@9sfB($-`(ihT)iSC-g0o}z7tBcLw1HA_^c#RB9(8px{SXN(4Y?Qe3l`O> zccL^b3P$$wDuE>YU>P<8pwa1uBEbz*lTaRyYDgwbol*#MG-QdkDbOxm?_Y{w08wH^es*>;*T<%CX2#SqK&PnOK5I)DXd*n3n4(!I zjwavGvEqpMERF=A5>*AZzzBeFEfkd+h=40h8l{>seyD2Hzl6oot5~8QxP-P}`_4II zXf@^;Lq;YRPOb9c;5cBMoE}G2XAGetmfAsRR)9u)nPoDO z3t`L~UaFq*Y$+lfZG9yfL}4Ky9_L;IROJ~=)Vd@>M_9$`)uc@(4*}9ersJp7mZ>N- zEfyy^BI_jfcpFG8Oh)=X2?|7I&0BxD(jncO*1Cd|Hyu{EAf`Kn%$Zz#&SPOZ$S3ZT z!0=_HS}gHGIt?hp@mQRtu*M@Xh#x5M!r+E+VG1COFg&G7%$_(kodfhK|cQiFPU3@4T?K?DiJ_-rPvgx#9EmBZ}uEvW{PkO zGj~qJNz6vvH)ZD7iHzJc=VW#ZU3>R;uUR4zzs1c_c@JA=JWhJg_A9#MBO9~ zYp(2S-qf{apZ;|Ar{K$akRl}xgzGr;h24j^?qJ0}x-I1C%$UyXn~4;3JVxu;2XSbe znw@Px)nyzKhl_d5ES6C-Gq8JB^I2r2FE>j$cCB0@TCQ4&dn_>KnN%yNfD}>(Y`jpS zh507kE4JBsb$Nh2>-gH=pEEvQUpE6A9eFxc-W*4|az-7c%2(E7)$r?OFr{Jf%;2Bu zj?W>ZXGUsoyq@hG33Bp?+S2^wYs*LjmTBqlTiHNc*sj#IHsKy^zBTWMTC~`jyZ)3^W zhHszD7}(ch!&py_$0&~NwXTU{0h|#=o~FFvrB?+3TEF(@Ic4UWBM;)5dqB)19FSPl zsq#7#o9{|2^@id(xh=wnE|zG=Dq=Li@_R0+LIS%Sf{WIh_V>{ z2`eEctsTGC@e#U4O2jPaK(NJiiv6$E7fU`>IuJpJC&Y~);-um++`#r0exu_RDDS+- ze8?rG&<3X*;l$mOJzbKK*mEBOIXc>h{-{{*F`@t?+^mCE;74bi`^kGP%sa47EPx>? zYEAB@-MV?t0S<4VK04Yj6W(I-9XE=*4`y22%EZ4P68rI!7y)ni7m9HRuO41%wRl1$ z7{uF&w>UAUz?)*kMb07yF0ZSj2&zn+lwNKs`XC$)R6HB}s20RNx-O_!amR~LDKFHP z5a~?#5Assrx(EE5z95^mehpeh_!h8v56dcA;v6=tD;?G2TQ}gk7MgiNr_6l>Y{WvvK6_vCt=8=NhJ!8z%*((zJc>M zQRmAL1-_BliI}7W1D_d3+$St5;o{~JD#{!se3DlrYviI;pblp(Dq(8&Iy?P!I!+I7 z39k3UK(R$3?#Ssnz9F8(L%#14v3oYKAIuqIugNV z6jDf%DTmO-#o_^+b6BV|URZ9;R7w=Bn&n7sd&iRQ|6x&=v2%&AV)w;hskf`;@m z`3O5ZDx*5YY>W5`bWJ8sc{QHWSuw?n9%sV6k})3Qx&kWgU_L}-ib#j(Vt6>oy)f5P zc&&Jx3D|b8JBY>6av0|t(ICrj2UVoriEjwX3=9KT&Nqs$Qi4U{WK1RtCNtxweG@7xiA#atyQocVr&^)>%6@IGHcDj< zR#U2=N>I+}yB{3IP%biWiRK;$qgCtxH>*;@geV3mHv8Bg zShB=P2h=mcQ9WEMqa$%TtJ`2Xj^85nD(6LzZJQSu6xXJgq#Yq$d|-hFMKma*8qNTb zhhTlV9a=7bQRoThNp}`=Mm#5x(hPIUW8mhe#bpaiS=e)SbvzXmGN%Y6EA=H0b@&$?|iuke#p>B-YYjGz`N&f>RvmGLhRTo@Le!eDIOaHbM(BK znccN$7ntHgL{UlJybbDwa`>^#2ns|=9E8oCR&_=_yId*0819(CMbwDo@%Di3n&FX= zOA6KJ6^{AL6C3)Oq4~Av%Egr+P~=?nBDZ6>`eAXJ=h(A?FpLTuOpA#qe@{S|c!*iM z+#pKcWW`*}4ACC)3hU;GDK;rX?xAma@Yr zmpsb|M!?7XUVd$k_Mkc$kD44k#w56FVpW0f+uZm`Q{z79j{nM5<|8Bwvp9wK+dYJP9Dyfkm&l;MM0pE6t@ z5Otn<1_iPI$u;I7&soAt$I>&5ZhSxm1EHo77NmQA`CjX+?=@;79CMkB1g!r!fh^ec zr--36Z(((3-{(eKP0F$4_DHKS6AC&GFEPVkruA!H^adXjQVh_BwCoU*=;W~%@tf?H z1rZI*o8OoU!prT5_U@--MnXMqx}DZD0YS%ezK&4jV;=ZL&Q_^PNQs~zn9u#(GgmOQcu z#!!JL@l7(zzWP3yif-a#zzNjj(mA@|O47?V+6b_mLdPT2XUC$BT@%oWGdWoa2l{Bb z*$PWNU2DZ8f(gRpf!tgJD)@w4gF}*0?;ckmPd261TA0oG*Wj;YQVwv}4;D~njm43# zVo~_a&N;wg%57b{mUX>>(@%m*EUS60R~$c1r6Yv&*25_GM){%{FIJxP0}+qFEtXhE zGwG!!DT?xx@#n*JCuVg&Y#@1Nv$71t!~&EEDWXJy_~td4oRnl6U)V@HdA^ttmj>fr zE%G;DFHbx9!%|@JA3gF;;jhTP@DZz7ZenUrhNxFJ9QT^w_D0Gp;4xPR>R_;AH1$2T?x1b_otcP_d`EyUf@%A^9TnXO1(| zZ`X_631v@<+jvpFiEobEg6*BSu@}kIny&T_QJpss!ZScc9M!$N*C?|dNX#5sP(dyn z#%7~i8Z&hDE>c#Jk$PFiDwbgtJi^UMG40MA4?lLuJDv+ul%k!f-dba44E?6GH*q<^O`AZy1Xeqx1!QqX)gk7*zv%N*%4bVy1ipi?5FI$2Gc;ARwo zmgI46x|l6Yc0vhJLb+&&J-B5`A7x!lhcODL z*CN3@J32}0?@KtSEFy#Qnn@Ah`+{J}rItlBi!#G4XEUT0qp(|ct;IW0#;HD8O$AUP z+16C>EH#E=%jU5SO{C&_4_p#BxU0t(jN)oAO%vY5QOFXc&XAhHo@u{v;?xOkh&vGC!tqKO;Orr z0@-2Mz?e-*=bC#2RpO#Qk}At;!{~-ikk#O`!Tx&QyuMcu<9_m-{OcP9O zq#)0h7SOGnJ$drob?NOZu}{l>&bgG*_1w?wxS!6K2$O1_rDb=0YTs)JFq~erAGAmq z%-_4&2prOHHd6ZLtUVY2?*Y{q%vLmvw-?A^Sl>T0jOJdP-qpgS6t5gWwIkdZs0>eK zcOFF|U}`&j*Xje|!-<8%l5U9FVQ_Zig6d35YL$#1UxbSJasx_56D&UQ)OH*aqzqX8 zSbnWpQ%0?@X{o<~aA-$TEhwf%H;`KIK-MejagI&Y%@GP9WBKN|#VMH&CB7-UJ`Piu zQh#zdquerG#Vq!>a$8GTd-6_Z%UAVl>od-Byr0~>LR|}QIqeiHBP60UQ}B=@-c}of z>suVrqKG!`)iur5xY$_=-6X_YsnrJcIZn z5r`mTfOhR!&oi6&r1Ib6O?pmWN+YiAjoWEMpIgKLp7Qy)kg&aBHFAm2qezj;YTxH} zD6{`Zc9n$`9(kc)a(wsJNzS@6yRZlUZSfXo8#jqVZh0=nHtV9`Eu^VKg8@aMO`3En zm~#zd^MxIfcnOba`brZXnBe{}-6v{mmM=_koT87J+I+nCb&C@estC z5}Jk#HyRkCv}htLl!;wp>tR$i%-@*KR|t8atf2Y;Zu+Ks%tYHI zqXc6F_(kOjA-oyoI-d=@s#g{ri6`!a>oqw5&0l8 zwS_rxW`-E7CC7yh0-u;IA_#EHaLz>@GBRAP-kY{vNc*6h((^6w>9X}$GA zrpuy%DqK7QuS_PAP=j;^%ACOXq#aTvclz{gEEGvp{*)!>;NCPHH=Np$)mDTU0(C)o zb+5?%unIJ4Y@gpuO3P%qxm;7Gp+>l8P z!+OmQG9N6h^VhdQYqNHSHndmYkr-Mv&ags$;1oq^E#!#z7~4H+1vcGE){+_ha@t!8 z*=Tp-^~E}u?QV+4EcG#R$Z>Oz^g)R#3|L!$dQrCqPU+t2VNfwFUd~L9)d1zO;!8Sk z0$P@{p|EU^KA*_>1zJ2O#+tuaO`p158=k{iXy5!bYPx&#gAFBJ7z?Tr7gk3Ye~Ii$ z7dbuRyu0#|i7Cxk8?Y0w;Psr15%QXAa&sW11esQ5oDsXo9+hbFyVeGe&rSs(7*cY9 zu7D_Zn%OS5tJ#kdn}QFGvlVJ&(qRuTB;}as=^ZPP=3zQTV1H*nVGjsf#ah2{#0w`1 z$nU|S5sR~f9XnTzLx=TY5%&3Z%q#?p>rCl#W5OlmiIyUr}93XT(vyjzSsamz1 zezc)RAd)Rcix2~z3g-pvVELAk1xikchGamHQ>X<2c(|%^(x+9ZK$BB-2I)Ej z*~gDFz36;eAOd?%t!3nvQR%8Yq-(}eP=?aKXwc+7Rqw^m@582W7Su9aUGO5%RV#F| zyr-)?*UP}vSMuw?8CpYmA^(rOcMYsr_dZ0Uku7~`j2 z*c4b2h=*{Qhh0ea^Y}o=k~Hbx*`}RGZX2=j^l3eyqJ7|Mg$; zucrRB9EMhOw~wA>GKn>?;#o%Zd97qGqBBx zu!OrLD{tlqm<`*5KjqE_=sjYXfR_y_W=oUJ4*l*cK|K{ zKT;<*Dm)mWYJ1Ab_wM%)?*n-&L{YT*N~S{A1b7^OT`rgRm+9AV*+&Dl2b;vhUJQdE zX)a3nc}Q7+ow6I4xd_Qor7gmaX-mrP2u-!5;-Xi`RZFsD7~F5>9*WOIbe!JWhw>Hg z{gHW^!RNp2+OQTW?4JH6OAm+>+aB>s=6fq91My^}8mB!y_1rV1`va=od>zFpw6`q* ztzFUl^PdL{2c0@Q3Sv|w#$@xALseH-;e1WMn@teLN(r+VNg>|IXB(SW{Q8mmTVu>{ zeFmS}m8G+?fljI3$s6y!C7`Q2=B)Htz^S65$+6rV+*ZYtAKOAsi@oBrOS>NsnxH*V zf>iJfwK)q>QAMwu{M6TFX*T$O1IF#clDNtW?oC$6>_BmCQ(; zHwC)GC}dxuy}24JKLEL*R`8sR%pp9}?121t5!fWo!1^lR#OUQ+8D9#&(1T- z;lL7WL_=RhdKA(LYyXQF2HfxX3(x24nAny1xFY)l=Wj4s%&t$a(e7?y^leZS3T3lz zq+#qyD~M2W^dj~^WvY%i`xNCYGH9CkCjfpcK0yLprO2oof1g*xjf-lXXUa=Y!L4l+ zwSm4exyFx~$a;tKSXy*hqW5u;T7NXQ04fc=OzzsKY#MER3mdP{Zt>< zJbfeF`^?jm`(GMA^L!YYapTs{B9wENrV+~idN+Bc(l*$itr_hjKF8mcA*ync2yBZv z&apIXQ`Yfb4h9SeaORNIEhzJx+hjm`HYIz}3HWoWJo24&;@?^HUNT!QTg%$+9co1!=6#M@2Z5$KeYcMN4LmH*sRSXA9J+*Z9&KH+M~e}*94eI ziTm3Fj@K^*xC0+z#@OFS2-_9^25g9_s#H$CVV|mgV`Jl@6?wmG1TzHEAxVB=fyTFq zCMvf{1R$s|=B6=C#YlovTL1Uf=WPKi5As%AfPp*M2P9WJIivnpp;k&NRgg8?#Y5eiGn%3*L^6S-@7i_oqdWAk{a>uT0 z)!uxCtJZr+NIe)2oYKV$*vnkHiIfXoG_T{EFT0K*KY2}MNR3+z_o0tQDf!`*tm%^X z7MsId^I;^fDOlZ{d7;{AxM_j?S9a?;RW_uM@v~GyB(Jy0cD>AM|EV>Sb0fch?9d0# z9Lp?Q9riOU{O``V@crXRvck8U+XCOa%oZpd(BwBCXGa)w&MC{_Q#KzVd3U6Su)JHV z?tNsKp?$JtL2TDcC&7SNyi1br-l`OF6WB;7%K+&dmQjuCnCuXAdro1)r0Bjdb@R`k zd2aHJr%1KAaO5O#5^QEC)Yb`1^3As6NORvC)1KBpzOeHc%}|voG+>PVG$4|bokz0< z3QzP~mpLuJD7C<+)F>#5J|%U3L{uNO9z%o%7)v<$1B%5xmQE^?EX&S+odiM!%6Jp0*dhtTY$*7=ZVQ*ZY2CSrig@@`o2vs=*g~{PcAmO zKZWH6vB5O@NrjmqM11k77tX&;-Z~&Cm=X6FFy@c=IF&rl6a~7(Gm12=9nIh43q^S( zQKe}+r|zG6VPmKy^z;)`8w88lI%Uu^C5n?T-b$hv+KjiQI?(oK+Rw9j#=1X3$fl?I z&Z$1iS%GtiWOkPS3~2>CveK9wWaD`txlO)sNt&dgk+;1On6IS3n`+MFYJcFbtK(~C z1~rGC*b&A*W7jvW9P|7Tn^++WRlriL#6l$G`I2C(Tcn;V-16>el=T+njO+OdYw?7f zH{VnBIQaNK(CM*+X~@qc?UYJJEwan3aLDprV@x0zn>Kf1F!p$%7f|3fT)3=PAdkzi*`sk`TH3qM02f=Ojhtvlawef3PSz10@)$& zKwf_2mV`MD%-lh+BwaH~kb`X!B;=qK36W_^cWBx>u0)7XrfO>YBh3{4zKWwPDJbHR zIuMdui)4vn$OZC55f`iKfkteJWjTRzXHKBRBOnMAD`?s*RkEACtJy7SnU8X^Jgwa^ zqjWI{^E4vn3W|S}lLc2IVLT73NXFQe=30s?!XyAncrr2nS&@+Sp<%sZH-vRpFGO$!sK_}7l$Bup0ENAY$qdKpKgXwuo;tE6{ji7RI} zIxFYdjpbzik~m>f1LAzO_04uNu>z&6Xu1?SNN4N*!n8Fb$V~ls1#bRQYeqj7ck7F( z+SK|J0PdnBf2Q~BE-_j(<))+@nPPoFpTH6QR|~6yodY$?PIN^7rzZ~{op|Q4@Q;bd zAD?_%MPA7h_|#HLpbq-qpPkQhD}msNOfLKsnlkUW|Mb_n)~#T#G8z0g%T4sVK0W!$ ztJxdj3<4qKSN>v2`oi#-0a^Xx-%xttZBxXAe@3zLpZ{{+*vrPD(HjyOKC>(k8~F9l z=4lB0r%yY1fdAuPL--4kJIaOs`(I)7uc~&Fwy81r*J>>Hg?||vkDq5Z<3JV{eW?A>z$^>NXPD!}FiM z`1FB`FFfNHK0Utu@r!%5`aeD+X9lpq@Q^-};9~ffU#!L<{42kAUvHX^@|hs%;%o9P ze_DjNyPx&fw6wbj&Y+jsFMjcF0^Z=TrBYQkD*%jyG-KEI{jTFx`LeIRA&BhncR zT0$C~J&i6zXoa9nZ%5BC3KDGgW#yNZR#toZ6>c^crz~Oj3Z#h#b4r+>Sc;_NmXl!x zk&jURV%Nl`C-S}`LR}a38~~Y@dX+%zOl*18@42`$6zJyAlK8{0_7<9bPCB-Z9TBTzhx)p*xvc1Jw3jY};kAvzTN^rcf;rz)r-AB%YV1h3`ySCkD#mgpN zd4;Xzh~SHBcTetnCBAG=lB;hTkr8k!2(Xq`IV~+&4JYT0q3RqU6b7WjAX_=m*B~73 zR=6NU(Q#WYEgstgedpPos@*+yy1Npf{4|=~g~;;6HC|?}JRD_)aDfqrmyi8XkBikd8JeMZi@OSF83hNmV zoEG$J$=GI)Ck54JQ`ffotIaerceO|!Te=HjBjX(m4thH~?lB9);yYGX@gbv6P{kQ` zE_5pS(N%Yl9uvUi-_l)X6GDn!TlLq5xeCRmZ9k&**555jzBFN=MC9w!jZa@|ozRS; zRbtsTjV!I!Z0F-GiK4)$IOwVdvjznTkvmkM(5|P*cU4p0X6TGi!`7SsJ(SQi=NZgX9=1kLXY{nn&GRHK*mLVQ z>qtAYUGHCqMn?3OhD7VgN6D!ZYtpz=rzxzP{D-7C=ulKG*q61uw^L6Yo!YqR(y?tM z)#W@vUY1Rdez0RZN?j9|M`=c1uUJMd9om2C_3b(DFdT_fJJ()%8K%XxnxTxk(5mD# zHJ|J^{3wZbPk(hyA0&T+wX-|skZ4-X+{B1FsDjyxG6ZoxNzSdY zf;qwxHz+LIEi7?Aao$eJEuv`^EP_}uIg7strRR&i1{GnK_=n#);md1dQcy{ml@2D$ zKnXYpwHpy5c>%)Ob|;m|j@)*X{E%7^XSK*I@NkBO_>tA4(d5JGN5C{gXyJETiKr2Q z^M8H}MQP|t6(z@lj@yd~<$XMj>E+~OYD|to)oCuoHJVdUe?D=&Y4^w1o9+|_b}lMU zSIO0(PgsFE@(C+Ysaz{jQv?5$v5tJ=y40~xSeFX>l6{@ihyMSdR{dWeU#*JVDeLyN z=tTct*RTHLN7JvI`Q_4~$1|-dhTHzDDp`j=NhK@Ati#R>c-$1PpgLisd}3`xN0)9D+rqz)UQ-VMT^Ikk3amGT!t9}Fyvq56&_EhLWc=DQVZPXW9nXV zqBSLD89V{?D%1dX^{h#s`Y*4dy^&n8iWWF{FhLzjVd2#OTB@2@S&4|?k-Kj2`hrw2 z^m=IN%E=AmkN@_ZPL~mI)qALI=1d@~bAB0KY~DAjzul^2Xw^LN(YI>wX?8VLNZf1a zZa}gimU;cjG_}!_C+wwIM@9ycxk=)u3;QCh6z)h|j2fnp&80uFVqpJ>iD1!v5C+Xk z&c@bD*VXJvV9z)Pa5!+Yr`&|Q7qyu3VVneC4x%yVtHIc4wo6EBpoQ;X!9OtARU}AfP7gf--$CQ1MY=y{CROf zV&M@SyC+U;_`{pcC7agpLKVvf&np*fV;Bcct!D*X&o)B#qi1eWbU3*oP~kbp*Dxk0 zCJm+C(7rUCN`7=_3{Dp^Rmmk#x_}X#!C~MKaTaNO%FP0Zf<50cwGxs!qQ7%m;qU^n z3Flhylt;9Ct@MSF@6Ofi*g9+mxPBaSWSxWfHq>W5U4oXj)G>CNxRB))fEb?Vly_E_ z&wPtU2mmsVfREGcqOo~z<`(kumXn_>3gl<9;92z%9K?fkz%n73zVJoC%3qEBZYcyj zo>JIFzB@cvAh=@WzZ?e}H=gD9$>G*;7F;4bH$ZdH87q;%P%D49Zd74#!Cb=A*q@dJ zPgE~r_EiQXUQXF*(+O?zU(L*0H$NtL?~cs{?${5uQRw2?sol>(?wb0FfCCwQY_kjJ z=YgEgbb;7RPou;Cou5bwJPcDrz=QhuWd!RVf*kFp{50V0jrg8y_6f{dLQ>?bm?hmu{T)x$%p>#$lA;r~`^ zWmX5@k-bkPOQMBvNf9rV$DS=lEm>AQK7ZG-^a+MZ9v~?RvJ5=+hzwO*&Ate+Zdbil zkX*|msr$wPeZ3|x!mvY&x_KyV>Xvr#uM9zD{E~Kg>=@_3`P0ub5II;}l=;_si_MPF zm$zPea&L2);A@xGdxziI*&}pGV`xo%fRZHYn7oadXAzoOK1+F*@zV`uD0x2i%7f5f z6qj8^|5H7LO{||Y@^GC2Y$kWzX@-DPB9uvlhme}tN{g5D&fuex*vs$nQilvyPhFW` z)&Z%Zv&$4R>PBNyObrgMxRN-s9~965f0oK3hV`YK_8vT8tVakt@cB3Tl#UoE;mb*H zn$_+LO>ZEbhQ)*`Gx_!tlY6!bRrb`O^T)T0Z+_H+VIEy8D9LRK(D@UOrK>millC45 zc&Y_@fBL%Yd-$DW!-HqOpeK(!Jn__y@x4$lzUE4mzss*GgLLzwlj~29?|Liko*IV| zz1jmx)v46*@ajP3d(ih)h7Rt~Mo^<(L%5_Y@c1B_VrN$MyZcYODN9AA7yyT*)ot~{ zIb2HMVBa}|uP#Q(-Z@x?HAqNRy%gMu!C51WE$}-|9|aQuUtnx2QIEp3xcWesLQAXb z10aM&Zi8pDYYubCFJ37QP3<0M_XkS{GMz|2yL)r8Sa}+u5L%<7M%mG9z>9)jwsv?y zK^1a-RdlE_&`(yC+#hKuOSD=Z6hni6#+_3y#}#j(uX3_AjS}&FJZ%~yAEgZy)^l4- z3q(*$jq}hy+%L+ERZA+=MKg*prfa=Id3J7@U44+WyoO?cbf~w+NCX~vqQ?1{m9`d@ z07euuxO@UZJMi!6V*7=h-MK=TtTJ=_sx#v@|I|p z97)o5NR|~d6A+ZP{ie{*fnBU`=aymbDMVCMt_v>;oQZ^z)>^(Vaike)vTybM6bWlC zAI3@^%X*y);heGhS(KQX%JZFNs&?sv$B$lmben11uk5?@WNQg`<5$QBo4m-?)YBQ6 zyyXsV+55p$o0}Dl?Rhsw#wz2YJ67Wja*VAHT&xR5D+mzlRs|l-J=^;v5;of6N^9B* z$n%y}T@6Y-S@a1mKo_dW8h@)|P1Jb`i{Z zgFp`fAHqQVN&2(E({GElP#Hx|64S;k|Lz-BUU<4tk}@Y0>3N$b;C0P{K5|;vp%^1f zdcitDtzPHn{H-E@{qLfjaC4?Yo}=X){UT$WAFic2N#slpcycv`dl1e;DmBa`8DkRACBOjjZ7O?P{Fer8p1RgET6XT*dkCM4^JIc=m?r0_bcZ?ShiL zTQ{b9T0TcZr_wCHE3c~I9LY?q z29%2hG2q#h$mcY(4#jR!ughlx$>)&^=%{YW@Xg^1u2u37*at&}N|I*Sf#wuCgk}(Q z)~uN*7$l(?&x1pzH7749dCn7zKoYhkCEREaBOvk#378h!w@fMO5Q z*yL|?b3BLoy?RkEqo;^!F6J7#I2#+mSD+MoWywYJK$^bi@!B}6meA~6%rGvVK1c6= z4`eN(-GH-9!SYI@XGn8J&~6UBs#e(0nU(Dq;5l{*jEg6qnLMzUFq^AUZYlFmErD-3 z)5XQzPf-03TiXL-jtBA^{TJOUwiuR3th)=O5r)|M2tPSvd`cuA2;^^F1S@`ufnBCd zOCp)5^inxe<$~PdnvS;?OZrZ~t%6$dW3-Bu6)3LJAjeLm%Imj+I zXk{q_Bnc6oCe{IPu(*Wzy4 z&H7JG2rYO^H-Bv3_{JA0*DY^p%AoxD%;J@`OO}a9lv%6S-?owpOvY*Big>RUcMtAS zURWAC1uZ4cIV+R=rDc|L4v_}G$+Ct1AqqKF$HAyS^ zBA+K~H6}-_8Sd{~*#|sE&XmtDQKw|NN+BVAyfL7P%Vb-_OK|ADO}PUZvJ=mVQgK98 z6cn066xx`p|Hg(;)#Gq4QV37UP08PA3}r>?Xy#L8W0lLvSK>+ckX@Lt*~IZ3uYWOK ze>h%eLgU46WJh3_#E?U%cQ7a69pBPFEf271K3S05&@`=d=<~Pvlqy|J&w-1Sb^B8C z<-4Iy*6f9Y&#q!3gv(diu~0OnZN;`{>Xb@RY;-kWSkHr`Kd({Y4IS&0p+~IlpMGWWz3E;B?+}wCQ0Ewa{gq zfU#1Kbvt5YR1Zs2Y9||=_;2R*^dx^izH#5h_50HQ{F!^V9 zW1jI3jG=n+7pb|C{P`s`{og*3{Kb7yf#%jmS3UXjcYi0vF8TAjt$Jc|yV6tGVGzB+ zY-cC5P`~UJN52dW_e({QcRS5cvEN8$xhvfCD+&uyP_dl+V)Bg*oS_#EpB#UFOB#!j zkU0E28Lv6LOj#?f&zJl;37K2vb~y3G#XZl{P`gop; z@-@WMy>vG}t!6A|wKNN>$l^P&B^Y!-ZI!O@F=9*`s`Xo{3(h=v-c|EO1COz+9pMNVUl6#65&wQs1kL< z>l{DcpV&v^qm7+Jy>Dx<3nXWD#IHMWVc!8}Ds;#cR^%|WvFND}og4i_cq0P3wW$(| zV%n^jJ5{{d!~P#Uvt4v=)ZqRrYN=DOcNj7Tbyp!D1{rH{3va z`rwjMfhJoMKaP}+md9lR@&F4m&81l?`7_WWZCveV%_}3$Xks~3FnVMi5&g4Mz1EqD zEjUSWEZ97guhlAqZj=|*wf^xZ9zE|27dB0jOjIbbe1eP5?U-1*&IOf3$In|tkox3y z0guRY^Y~Lde(||yCpKm7rYmC6O+Y!wYxqrZ=& zJ1Hu)&Tjr%orhNv_V2{YWMc3-RrP{9-Z27*koDWE12A^MVS*2y5U!W>!=8Fufgg!BS!8&(u%+;;A^60Ute=}?r9wpV zKtwu%Q@&x!$=})W*DUw&SrM62&FUU6?Hnef(gh(w%N1K`l(<4D=42#RS~>ae7qH_H zbkT5UhZF>j(CrbELkb)@RcNq+$mVH56u{qsMOcEC)q;S73vqyV^5C!_26JQXUHWS| zSv}#|TYC;*r9(?d)M)bUXT~4f72cHEe=Onj?=+l*s7nzFMK1+*Q1Dg>$leQ{y0vNV z#8YnpO}IF^A$zIYm6FhAV5V^>y)H#I6nx|KulsL3B;^$qJY<9lh?`2K8M<-ru|CPm z>8m#rYH`5^Tm*PsUK5abH=L%0Lu`nNqCtK-k@PkbE`*YlMRgy^KLgB`g?ACY(iiP* zPO2+$T<;^a!w#it5Npa!EeKjnShxF$X0;DVD1khyy;rjUx0jRk3BDu=-3Gp+bQO98 zsVLNB7LV3qMfpUQm6e8}!bs&kBL&M4{$DSfom+%ET4Gc9qTG+gs7WfPF{Wt#2kxcN z5xXlFehM8af`bg!Nn30mCfrwcp`dS%qympA>gD$EHSqcVY8!bILVm zW33%+9~sUz(#}o3P@ z6rpez%4?@A5X~$;yEFpjKp|p2#GEXy6`@82Z#Sq>`@4~&lsZ7?#r{dFSyEoPpQx5c zYU;tPu_$^#4}N*_%#(7cKJ_pe%Bpc`;0?Q|bMorRQ^$1qm2K_UO81%tLA(L0fCL!~ z3~Lz!BQ*X^_hIy{sB~a$4k4uEq44u04LF2*zk$}DL)?KT!chrA5eI|-EwRb#(c&Yb zjtD<@Nd>2#tlgv~88Z9J$(M59uEIfTh4U=DZ!VuT{>aWIcpN-i_W34G0^LQp{hF!g zH(uKPVv2r)z$UNU%Eu${69FmC$5pb}>uVGuQIKee|D; zM%MgMTeZj2Kvl4o<+Fj6_bV5ZH9XH{7#0&?^_LqTp(SvVt~6 zqvKDou-3IQXBUhDItI(gcyQ25tej+LO8AlK25mY7#CcP{KU8oSgpz<6TlNRr3$%#j z0VlyO=#eqsAUiVh8(g>bE=nvh$)*TYsA<@w2Z%RwAY&zg{0EM0&0RtBeZjZqR5&o` zWQ!@QY3Yjz16_+Lz)GG@3@kzl@3e=jst`3Ft_ZS|9J%HI+@z>ddIDRh$r$$ETU#`Y z?>(+S6#tuQ0z$_N6>rcKv(itAt{)$dDg)6=V^_ghgSH(H;-*8mHqgy(EEtm<$#zP` zlXDp!PVO>8Si&%#^S&Pl!F=XZcLN^oMY@G z?lb38IT=el;8tu`TfeBlPpLp$s&~tE~PKYw`?5>MXA3c9;%jD_PsX!0N1t2e{ z))HE2?zPK#9G~L{k53+aZeq_v+&=#3_VI^La&Owkg#&voJn_)@j(yxY`N-&n(c@Hf z#I-r`<|bMI8M>xw02Z+Al)Mh_V=+DGfUa^)ROZNwJ-@EhV zo(D=74z9g;@_EP)y*J}q&QKGLCoVSr>-JhSPc>*ckBVj9}qlNafNsGbPo*mQNsY*M#zfaInzDt zYR>4N+1f`n6&5KvZ$*<}2OkQ8BgQoX3oEz{l!QT~n9Fz%&`tv5i|?S=%Gh3^R=YTN z2BEJf#Egcx0&KycKn6zT(lfTV3xvqno6DDTlBdYmg|<7ESE)NX%Y|LFZKlldIChSwi@_J`nJAMY`L8L&n61whtMgU9=`TX z1eZ&t&wOgBk`o{rbrx6W$wg=`^*#~flg8>j|HtT`1um>xh zMg-%6qm=wF=_iKMztzdXck-3Oa)2xtdj+u*N`b3smOFG+_*Dlmf7CiJ3%Wy2zewq3 zSlNx$P})f8=%|k!&;pNZoT2iG9c=wlJ`$~mLZtKohe+Q$Pd2(rzhD6}G!)Oq_hBDt z?=4|);o9k})6bD89WN$#rJfR>$f$*6Gg+GH|B0ujy1EAJ8Gj67+2>d@jN2^lc!_gN zZjTXLF}b*CRL}Q3N1t>*g;_zds%Y%k6!dVqhw*M}fYYqN`OYPr5Ih1P6TI z&fvajMJ{~iQz=0W0-2aY_&kHIv?^YL9*@3sPQ2n)fpa~@Hfit`#U@5Kom=;iViqV? zBF^CtvD-AQTOkKa_qS+j571kh-K)?B&5j;_1iq zZ~6ibk=O`vU;%Cninw;24UF7K_Ex9gq05+lrvLpPmvtab8F1q>pK`+U68Ib+Aw@q@ zcao`$TlP-<{wP^gm!5o9KxU^%g&pV89;$++g*WeS9+6OG$!bjR*jAcazi#UJC(M=f z^id%r?@!-RdjIHJMQ@&e;(^kojmLP4Zu?*zv6QHy)LZ+A zS%0v7e`IESKQRyzv1m}H1C9Pl0gBq=IoA<>N}&QU*R?Bf(eN2lf4y0_h93l z4IE>jwmU~~m(i#C$Z#kcgSn2{QBMBHRK$hNpZTtYstGdO_qU1gde{LSmD+>)N_Td} zy`7Tyn5G=Wx3VT`4;pqmC%n1i4GHgh>*u*hljEar>d6aXX`BbhvXzFSc80>Xv=oY>*mzzN0N8VdYfa@)1 z`zdJ8OauPM9CoMVYRjj`N9~^oSV|&9UD4N@hr%LkykRYx{&8MU&*3WK<>KR~h>k_i z_>t^b`AAB$TFdpkw}pe;UJN*$W{l^kWc|j2$o<>+$#b+uEi$*ZWo!uY8EKK|Do@47 zH}HPpBbAgJiUC|~b^0|M8*=DrEiDP90c1_7UXQ4PaB=84_C&jJjgi?3=?8A%ElF(HOUMLZ8S{cbpvk-a*@HzUj9YLEo zl`_&3Yn=mixFSYQx0taCv4vcU43>al(d2;&RT*wFxBqlWEBFQi z$-cBH8xw<4k`h};g^?wgM0hP#_f+~NCruCxfVxXH}MlH0#RT;u{e~do5CVf+b{8KH7)axctiN7M% zbDG?5?a3kEA<>Hfnfb-qm5^5Nn2*-nI9i$4%U^1voAZ46?RR|W!!_oX>o6o6IG%ns zgg5DfqsIz4>=k9=`;plu*z*A-&p^3(+O5%}I7gQffTO(?idUO(f;79y9n^YH3Kb!@1wk=JM%KO!Z`_apdseXX7Q}_oZs8+U-HMJB zDKT`_*1N^Ak?Hm#0W2Y)$>12VeS=TCf$wZ>Jyd)ELUw8NnW?9bUV0*!NGG?D6={3Wa&q;9^ z$O_h2N?5@f`B|KW);+E@fpRUpXVW3qy2yGy^sYzsRQA92{KKYaS}uhuGrzY{x^6rg z(Q8}Aj1mG%o8OhU$&pM3{Pd&C0PF1S?fahJ0Tz9fz5au^Kt9A?w_ePT4}P@$ZEbw_%J+0OS9caD zksovOE}}Ov!u>He>`fnj!`d+17>DvoHmN=F5C4?A(%xWPS9U0)`hKXL_l0FLj1=Ti zv>d%q{7Qoug2~_bE}Pi=N6Iz0iIo5OvGo_82YR@PAh>>(q8OqLD|;-hO%8ci9wD3H zjxRthqd+~5j+IfZg#UpnpI`JK{&%mG#Up0r3@Y`hbXQg0S~)CJmEMlBPBcTi<8yb_ z;PK)UfF}$ldH3v$#a4T^3V6E%-uPZxX-qPDjw^w6w(i*h(L290M*^C-4{yM05 zC@}zR#B!=6=Jd??!G|vX?!~46mhKcrpT|n$8(!BFy7R)(7bwPZ@zFQj?3QwM&FuyY zwaeO&GJhM2zc9tjgah(#T1by+VD7TcmE>B&n&0Ezh(I`EW`?I%5Rd7v;*3VgATj(7 zMF#i?Yu^2z05B;Xv!X#ZFh?QB2}Xr|-HmoL@g?=t?~RF%)jmq|Dv}`hjhPen#8-4@ zHe!R79@yPzlFr)o@9Fd9=hc0-VorsIv4DLb3-TbptGhoK-RrmFTfGht`t@qjpy|8U zPCfr(TVCYNw}XBlUlGX9!1C%U+~jH{OQ4DQk|Pz0mQ?x(fM5_=C$F2Q3TzA!TSL$I zm&-V|@5v3&P4E8JawhR2oq2B~i%Z$H==UWS;K}zMd+%X;-YvWk0Jk?>uVHXi-y7F! z=Ji!pvIfC#gZ1trXk=NIbFN?=TG;pBe+Mi0#^&`1lX8jQMJ;GODOi_!B3+l^_LQ6q>>Xy&cUU#EL zie03Ey0Wz%!H&2YjQ?DTLsT!P{DU$;4UAMBko?sJWLavHlCY^1sF%qo%I2}L0J;)Yk;uafC9?Mq|##hh@UP}e70BhLJ&93 zlE7a|CO14+X|~dBXNNS*aHqF}ux7{OuH;ue97atCx|B78Atr z0%1xFI=hi@4ew|#lPdWLv=S2rvI2{6g)EB5wYk;aU z91A^g-n_HR@_48MN&o@Yx%u^>m8E-_EG;HG29{D@0v@}rQZHz7kid}{L+lE($KT#~ zanH%|C$>&J{iY-5@yAVUdW(7EsNi(CuzQ^rzumZdQ(zo9{Wf<^uHERHBi#7HDcv~t zZwd6{@1&CX2yopYSRBvPSU6BDbTh82NRY#@t^whICygC4EB1AkAuNDhcyDJx=_w_K zTuW*oJNHP)Gf5Ug%+OWs;F=DGz>$fz*2mgqpM)*J3={Dn>TaA1b$K`4+YhAcFgUnH z?317W{O7h+W;^XB-4t{|^>Xm%C<}_EK_^%v)WZS9HTH@)A0i70I|xm7S=t5Lcf8e5 z#mG!OtC6RYVEjruDB?Hjv^alk5AaqL=9ssja5%F<3Q}`Qp6#HYI3XuN-MDphNK9?t zM!{`!gj%M3%ENhdYC9p{ERy@v#a4`$h>G_ zA`W%$QLs!=w`#Y_q~)kcs^aAk zY*UwPRlNdcT)PJR<*6ERA%gm_53rJUOCxnzyY6r_0pkjmtKr)OXfG&{p|Zk-VlIh z%WHsbrk+7nSh%##BB-XiLOo~%dEhkFnPP5KhNjLvf~hjkC#5$p&}8jusROyIb-~d@ zb;3RZ?f@u>;oBVcW|c&H-}S^H;UlmBi$TiAIrJ?X=?q?B;R;SzF@Su+Q315M;HhN( z{2=-`7=y0hkmbSJNVydAhf)-CAraHhwY^PG%{F%y&Ii;7hfvJ%ZQbE|tepHX-LujT zUOq&c5S*+;VK3}I!Jcl}=t0AN`H;5zO-+yPJM535jfY2@H@zz#dhRE2)4SfymLKfJ zCFXqKKw3w-kO=MDKWgdAq^0NfziCb|p)C)|7(G?453=8jg#g)HE+ZIrJt~c*oZOLV z@vTz8b6XX|g~GMcIrf@L1~yBBpu(im;I^RCXPO5ei4%oPF3AE{OC)X!<$*M!C@+%v zuoCd^R1HKFaP}h#`Ws`fv(!1kv1J-mU(SmJf5hYodcfV95SaE+62(7yFv^G4^vzTn zggY}Wr$`jsmlFknLSSv_(s9bgZN2nc$OPKbEpzf9+z(G+fjqd`O$Q;qgnhtv8x}TA z$(2P?0IR`uAtXt#7MiC}X%eJeSl*e8N8Opd9s9rV|3XDa{YOIU|@> z;Y`-@FiXtgvVI<^rUP~Iz_Q}W)}9Y3WZzF=Jm-%+=6m0QJ>y%CU)=a88~yyrljl!w z&ztDlyx&Y8Q~sUh*N4M?=P^|qGy6Nd;?~82{*Xn78jGb}dgsj89`^SBR-2qO`Fa<1 zOvhg9iWN+?*;hA0JHK8u=w49-rJduMjZUj8s!qxbC|xTCw0akstq9OTqoKD2z#;zD>)WJV188ap0agqk#*Au>uVZ@oS+_8Mn?I7 zyLGN#f~vq@ak7kP9R?EugndJ43giv3AtjGTj1mB3lL-Fa-~|Y8z9Vk(ePl;WK72Ib zb(;YmnG0Y#*i!rsxv$-{fB(oS{yH^v{F&hNZ*>mX={_Bh>DC;OiCXb8YfiAI-#Jz3 zvbgWa3Vu}pSUWi=0)mF7PJ_^)rR~|x87Pc^>dNQ{$c7U;&?X_A_CDlbFhh&~co_gx z>uDeC8?>yxv(`pzx}Vi#)^ z-+o5J$VX$-no6Kr2|j)c&{XSHn2#imqFJg?>CFVlS)l<~h#f5_DBQuBr!Zrzcf z16#M6Ys%R!!-DobgAEyn9+ynqF|HRAxSH4K%xSi^15k*|$>$bxW~Bt5zNV4u$=7pQ z>hw^$S*~=>xYlNAtr=QQKqt^#agjMOC(EjwT)o)VN~!~Ey-6e>^OOG>+3OeL+x51|69^2;h9TM9tP=du0GTIZ%MBD4Zb?1I1b2J zm+9ga-n+!g0S>0`prFw$$<6OR9Xx7Bd{^NlX!WUSyELoU?;fMQ+l6c$5;YEg;Z=hk z_?G0`OT$6uUrA;XzBH+HwoBMz#9+v-Fzzp_+JWm-L%&J&IVRpZIsV9Qq$R4ZoqNnh z>sj~RP~^$ZG^xJ1-Fk00ktlXsC!uVAeA4QIP-jRh%FeRjlGY)qGb+AsMU4co@V=}-$ek0f?#bz; z&`vku5VK?I7M(+!Rf@Y?-H^$*PcwUQxe}#DLEUAepPg6&AGRJ+X05)tjsLV-tI79r zl|;H^kY?n*@;FE5HKL9qsuqurn{Bwwdmp^g2 z#Z0SPx`j>3hf-Rm!IHcviD{OHu~$>3*Rlp+p0P;TQt}Ps=SZ$hNfp3371go0);ilb3?wk8q`-mu0x{utyr!Wdt#{MRTQ4~4@yC8*`!2d&$f<1G zcfb4)`z|CSPP5@|&TqIFLb#&+_WjGBaTbPX*=)-`kpoUu9t?>ieY>3e;L5gIRlyJ0 zRztM`hv8gigAI@dDPY2M>f-pO-4}Q4{a739ySWW^;pLMw_fgbE{8+|3zzOxyb{MDA za_W1cD*o^aHrPKlERYuWNZegNy!_!d*yvX+r4Oqs@(6T&t-A{vl#hI@jcmTR1_CjKPcM;$oy`tlwq!E>l0I|PMK-pN!dsxSq*OAJ9E zvxti1BCD&XiL4F-m@wRWC3>SQ6IRo2R15j|3QK_bRcA%=-Y0^1ErY@!EETP4o%mPQ zw8vm+cWnPExZAzbMf7Fy1I~EM4as6NM#~ddUejv}5FB#%0OZgjq~>c;#5S!bq*{{Z z3#+IaM)=yA!96mvnR@!682RmSUEb7LPkx`oIBvjsuw+Ag_vsgu2e@fJYh6VO)}NMT zF`aYGP;F}`Um_a($7a8pxq%~@3VUK=17MICMxI$ZZ%&G$!wMxG1P)@Jf*cWjtDCNL z>6QI>n+-~xdh4EovNK=gy+o$r)U&%qjuOzP&lSg$R|ez=PB?Skg_6~<)R$IKw38DuWNcmOa9-2~%>T8;7N`Vw>eH6QA$DF3D00|?~Y5lBG} zR$R8utwxMi9?Q+hL43K1*Pg;udCW>^{lU(j#$atVi~LZ_IgyJj3%JLz5UN5!uhHr& z)K6By@ol->d6F9SP2BgM=-BFxC*;-QscegP^JYWFNZAA;n2(@SsyKJ95Xv4Q{yO-BK~cl~ zWqJsqg?_XXD5$U5@#8A($31?k@%V9d_!B>Ug5o^-U-at&hA3b1QI4V5v<@O7rn_5DqD+SeZ1hih z7-etz5a&^9F8q_7M>852ed&3Wvm9diKfsUanS{Rc5znMt!{y{3i%pWYbBX2g5znPG zj&8~qE8;)2oJ)l^Mg&zg9aL?{)PJc%s<4aYq>($Wf_3vxaAdXFP34w&KnVU~IpsZ+ zRJ|63l4XXZfo-cho;Put(pbNdH&#N%sg4v6ihIp+jGpiOrX`9kZ;=vN^Py{;^^o1x zMvU8(C~&Joa=M6hcus}iaYOz%6Vf>(RY=+lCPHVZi`^cxUXV%JT-f?gfBe&Kdiw@G-PQek0r}|93_kxGT7CZB^H}%2-PylzT5UQEsXQGqSRE?Cw>u!)6RhmLNF~pY zZ7QQqTm)?=p;bC;{|ERmOiHG(IVY7A*PojT-_*K=^X>hqSzre`K! zdg#K=r^XMg*A#x!UO)cU;q>0@MnEFxPrk_Q;|Kq!dvD<0lBvAb3o2beNBO7ScwVag zgJctlnW3%}xK(s!?(%Z7z`q}3Ep>&Yg)ao&9$4cbQ&AGnn!9`!Rq=XDW6$C?p^6@^ z6D$+*T&;&Fon9a!{d7yzr}`t=prEtBkXeeIkCxvW92Vu$Ju2{uQ%GO$x;Mk6BwAYT&6QMI>8cuAViO%~0+dB~vGMQsNlAcoX9* z?>{&CJ0Ial6w#a_az|K^QHTYbzsYpJ^yq=9r;biNdFayay_fbMrHcmXGrvGcHaN=Gkt6AxPqwqo>a{x4tz3kSk-~qi#>7y_Vboa~gnDLjDh=~?6%j=sN1{~T0(l1L! zTW_@zeV*B4p(f$n39Hw3{^Vm>rCl#_$h-{Zm^KcgbSnxly)-{Kyz*&RPMNrmXAEI}7Qbk7Jb zCA||0fAXKx*NzAkDjg|ZnB9=CinPmf5Ps$TvL(YMd7f7nZSeLK3Kn&T5D*gA8a^eqWaBkQ*T0q zT~rX|hTI}uGhFW)IJ={R5c$KQe-8N1L^_G{1>~h+7*w&$hYhbR!xjf%!L)1CkdW^^ ztlDBGXc4%IdV3Jf(D-lpqUF@o94h$1C=P^mLe0cRFNk_o4F+?J_mMb^kqQCn%T}o+ z+xYxZz@r=YOM?ke{0bo`q9`R{dvr@=@u)R7rg;2x>9SCXI$hXvK*TwuId9vAj^}(* zTEkhYjrWb;F1&Dp!h6z-&|^;@aFQwA`y*e-eafFPzFRV-R-fJZ&W<4t$r09rlH4%{ zoOa4AIj>70{bZ>NUe|MR=};{)Ce@TFWnv1r6k&o%H|L-}l)teF~x(<^w9tqcH3Hng(B2sTo$ne=>dYSio@ME$gx z3I!xvz?Wa%a^WDP`Y|te-IJ>POF6|CPE5XnqE(b-_kg`B)$gaK$*?Kq3A%)Gc0zkc zt`Hd)CNq{o%;(-N$?esQVK_ZZP(1sqa0{#|4T5o*LoP)aTuNU>{-wc;5`LIO%J%an zoBv>9nBvUIs+niD!?I*~Dog@&9C_9t7mR@(F5KoBJ+UoZi$A~+&OSGWa5T29WaT`p z{G1s6fb^r4z?@>{8GX4(L5#B?5F7)fw__vF8M^@RuB(LGGih`Ybe!cKWhtr!5J4pwzwhV57-sZR?YSKVq@3J<+2c?xUe!` z={g%9UiwA$W3VXLYLV+S^yn*hWF`6Xh4|u2t|Fjmw1rALb@L)#`evTP5PQ{oZYw#c zJ=s@$DKLprSs`C~FLdGyR(cPuKCQPG-|?j-DY2)aD8hGy=dOQuFVg)ubnu9HE7jbl zt;dG0UZ|3K94D(gNyPQ4Q1RNWS0LJl=?4qe`9p9+Fx??QJQx^y5iysQ@+Jqkd<>gL;Rm7<mfV%uMFzkB-^3 z9^9+MO!AB|=u&-I<(qV#m&AtKj}i`~rjul_rd*P=r-jtMghelVq_ljT42@<0K+M{@ zl4GUo3XheRms&*Ls^IEm@re8kr%P|{bjhWC7WgZR4w`VlKz~EjH&Ec{&uK}5|Di~a zOlt-dA3iWg!kbBLFRY~ea^lC{_Vv{G_~+3XNjzE~6xAI(VeLvK@Ky?J+sTaC{*-1+sQ?V57o`zHV{ zw`gJ;?Y*@zld_k5%Wui?-h)J$MpJ{njYF=js6)Q!<7I85bWMxKM4!=AKIVIuS)}MW zDUCg=&2^~c%eKaHO!iHxPx9+*<@D4cp$NuKScGV9JzY2=OLq?p2T@0{krnuJar5dA zSw;g@d=NE=(ubE;$kZGp)vR-6Ia!h}s4Qq@)r`mY9_KK_LK;8x+~mRS!K>TS3Iz;;p`(K)-sZ9@0Jiar?RNDFVGAo)#IkSopx^{!T zvtlNK5gDTaFwWm}!%I=cr>x@?{{i8aIvgP-b19F#)>k?EXzQ25Fd+xnQej-68|&lm zV$%!vGSNOU1LIzvQ>v}(Q%dN{TF-KwW`iZDV=Fx{5#l*(85KyhEh*I8&)xYQ)#xw~ zDtiPhYQOAXWJV9Rb*yD4TwMdUHvOIn!~q^?z_O}ymTGqOzTSo$6V$11n$&Vqk2|ep zPf8u;VB}kAHx+QDMPU7hacip+(yg32iMtevo?Q_m75+MmLA}rD-dbPS8DFTASWA**SOF!tEV_V=G#|3{TIqcGX@CSXfb z=SHE8+k1}UW$USC+vGuy$9R$b*PCJEK6w1-rAOgY0=7JjY-yQ|(iAMs&u)OTq1n6s z^s5==9PY-WIWDHYym0ENgZ?MHyQYHk#&@_>#E=S$Yk&fjM>-m-NHNMVn>>LqXuBC&3B@2%1Fp2mmHE{tB$^-}-hlD|?%&p9^J#(|A2@WAt(rO<3 zaze@5=VTtl6bMz&ca(GZ9@vUFG>Ig@ULU127)iSP!=ZNFA!omQ&vJHI*@`d8?P^Ul~FphiKDbYhq@uT z4V7dVjT_@bts=#&VBX_yA(3K-Cld|pAtO{$9{v`NdKX*?bwQ|?=*_pt3bc;_x^0|p;U%9aB#qr;sK7VrWE$J#w zK8LP4@yugdseUQkf7N0T_G5c`;U46u9(%33G7_7*>Yl!iszOsD`JG=~UR~L9i}y3R zdO^L{4ndAz4#7H%K=t^TuIZv`*>J6|Q59)|eOUIKJvE4697>=2lK0S(KPkOQ1x)^T zbA0kkQ`@&jE-lM&d1d3J-N)nAFEit~?J$a{@LTOvmBd@JnN7af++C_l=lVNG6Gsf^ zEyx4jFwPC6p{PAim8(tK+3FWb;w-GP1E#SF48Z*b$Wuiqla^pYmIaCSyszmB1=x zlaW64)!bxY2t0jmG!(yz&9=^mSNM!quL|>_gQ#;At){yy`QnmrGTVA=j1w#SG98oZ2J%AroOf@by&*EW^E5V8wa zz1=0qNu*!)Hy}8*`(`chei6k%bB%Z|`K2sKX7|XEh;?@$e0-}renVDH_IunJLSjwO zEHtvzx87d%H`m@XOcdY0nr12@e11KKPsO?m_e)hr#raSY`~o;wTr0Pn%vPw)w^{ zszY%`OYiK0yi8TBU{QsSi8#Jz2Z!VN3)$W5!A8H}UDEIXnPpdC_n&xnElG5U94(O< zF6G)|U1+~(m5jYc{h0h35I##6G4?25n!QPmJvLAjBnl~guIXx&8nl=FPP{LQ3Pt;J z?Fo`+J^E{xu<5aFz!Wj7GEtm{?(uT+*IBCpOUb)3t00SFN0S^hU#jG%N>u8XvB^rW zyKYl*CyOq9X}&v3sC6sJ(xUW#!#seN*fW#=Z+2eM&q9Za5QikdpmV1fh&I(e80+3Y z_C#Ktk0gqzM9Ywgu zP!R4IR6N+$b-t-|ISI_OeG@AOb!773i|Ox*Wkn}*w#v1_ejz;C_D#r*f-a^Dk>&!* zecFcpZgJ!pkKR2NZCh6fR0CnF_wupP2iRy{)@=tA{>*zK3pq+jTa#Y3vRukbFSmH9 z`s}WN76e9e=hCq7+Zq#LK%@bH>R-WhXDbd~K7T;xHD_A3gNU~+4LQ|CP4-3d;Zoc< z%{we>)na2@jEf`bpxr61C+vgXkh z5v4*AGWj%GPWsJ;X`woHD<&;4-~MXcYriu$85*n@RY7RkVK%L!F6{y+qhF**S^qUZ zGmIaV(((7&iDRCHE{aR!CcQbp@z-vcK zI?nD~i4~N~C;)t+gDXiCv;7_1X#MdsLaB@}NZ291+d^*XOvJY8>+qJ%?R)^dICpowuKEc#VzS09t z9o62sL?+-IfK)%Zu24H^!`qzUV{`Tg5><8SK{$*5>}ney8LjF3>WDEjYhe>}vquOXn0lr7zvpWO;8@O5{b72$WDXrp zamGz6pvd01HZFuv#L-=cX?xo7Ha1_4OQN~I<{I?DD_j;?L*$X$eVGDnpM?`a4(%-U z$F0%NrVGT?zcQ;SI5KPyQe{=OC1Zh3Ukm92Un-t|^@4}44qB;Av+ru3UNzV>!PcN^ zOn#wtV$&=CHb0wb2RvCv2^57hr(Vpqn=`}k>5Tz*`^d3Cygjw|x4Q8wR&6s|$L!kF z*<@popC4<~ifewka8}$4ORJw_FlM(7KEGdekA-o)9R&^omYMAzx97p*DFWN$tLc&FcHUF~QBw5Tr5MCLWC@mowhyD1adpuO> z-L)kd`l|{@b3B;_hDcmc?8b1Hd`ALf~eht?_&^CR1omgWGyE@zExD^QCW<@ z6)Xx{T0w^#bfyP7Ikhg1g0g&hZ}~33IKbV*WdR zH!GutQG;pBE7UPssd>jnP?J`-JY1;b2YOp37Ub&1r(QV!_NXA)cAyqhqPMsQngaPi zUUwwbmiI=bpOQyu@^0zUDA~M6#ipJb5O&`S8>b$6bZWz4vVxQpbx-hoHutT=73cP9@s1;j&R%FgS(#frh6uYv?Zf`LgeTCwk z!lq?WjJ-mY3|7Sxinj}wdlZ+{=~5a5Z0jY#b-AzKz!#~sIrm$O?+imAH5-JGlV6LP zbX25k&aX3fH^D01BgQmXY~;^Wxki%lEEZ2)mUoXOzh2t1P)+|QLDfwJrGRu)l!Dxg zz~cWzJcFOph-X-3oG_GX=!Q+Sn$gvmWJ|0H6V!RY*5RT%c&s71A`R(PP(H zzNNvHbrNF<*@Fcz)=|79g!z@q=^XaTJ%K#44u2*mTX@p2Ho9HzR{^W^pMk2fOS($K zI=sTzmXk%|GTZs~#G@}D`7YvKIsGK3?D*PK6Pun2M5YJUlT&+P!<*wzJa+NnN9BsO zg>gJ`!8&N)1OxU)X6{4hO?KRKlYM88go(BP5$9IJ$LWo3Z+%gKJKun z*2*p`v015BWPTLLE^3s10c`|M$Iu?#RBouRhBO~1Xk|4&2BBH)#_(S>FjyT@A(>?y zdqP8XQ8sO*xL^2fMYUR6LHvS0@1wanY8P9}*-o=(NEv0^(7JPJEtbh*W+DOzM+r5; z8fX#o?y6dbEodUdOP|WVF^SAWMRQ{r({(aVAV?jcbTI-*2`juZ^;E(|cUQ>K9T7?e zMa0Uz(TWOJ0>9q>j}2y+zVgM+mr5oJcVhStRF$>@G%D|3`P*eWB`k@zsY?uAx?sTK zU=;Q?lvUjWT#J7wZw1Jca$2H)rko5gx8s{0Chk1Gb}yb1@`*_I1p#+%-6j=(AgOWf zx=5aC(4@8NTKp(zIpYsKI)37%bL*cpNEFE}GZw_WXKMF43S3IndH>Mwf|R33-1}#a ziDz|`vQfsk8bn@`aHOm(72`r;3peCYOTYMy=lWV1A;|f=NH^P9!qy(LI2(WWG&)pX z^qmcq$Am#n^)d-FdFBcLCKr(9FZIzXwd=(S=nqG}gXnWRd&W8;l?kC2gqSem|E3^irn;(8p*@NxWE*ylqwe{LHOQMWusO)FA(u_+kNT@Dl?LVlzIpqzZ; zPT#9SJK9F(3=4fgrV}1SP805#y)5oTGY5RLW_OaHsTR zzM3vkk*142?Zek?N?4yoUtMw4jzrOS{~)*r2XI(j#FAN5Fp$3YkdD^oRe3yZ{o1jo z5SQJtt8pC-utahz2UAJsp`RnET}T|zmjX+G<7oWEHhete8{hO*qD65-_Eb1prHR`T z;hFQtwoN>|d2;{j8J+gRU)u3vju%It@meB>>AKky)(uF75?SiVT8t$tJs6p_F=>Cf zkfTGVNIcJlPV)oZ>wxFim>np9utDO+)s`g!tGcKk8m<|*dxSo*_R{ktTYa1(7z(!7 z$6l+1!v*~R9affAhen>+#xQH@mcqfb7FMQC4=Nz1<&Pr~H%oRQsa(GF!PY|x*aI52o1Lmb16MUW;_~hrO})v z?89X%p8})49qeB)NUk;AI2;tMMU(Hk&&58F)yy&$;7y&juxq+SI2Uqzhkw<~ro*x> zt>Rx|_CC8&^bzxy6i*^jC_N&W#ITt-a#dZKnG`%4aR}(DoUGS@&?MQz*ahoa-D|Hw zp4)|p`qtCoy~pRE4VO41bgFH*1 zAW@8ureAs9f^1K}JnofNt(R2Q4EL6kPVe2h(bo)Qe=s*IxK9B{zItvHkrTjqa)nRB zW8;Tyj?ISiR(85hmw)Fk`CxRfpc~n|m!?j>dTICOsf`%vUb$VQwM_&z@koCDRf^kC zX{yjhzyJ20M(0RQ3^kG0kjLgr4jYJ?-W4Ij)|kGE?VidoOM;WKilnNlth*H(U=99a z9(n57lE}DiQOsAl-k zlO|U=opigPn_&Jr$TP`g$1(q$7=gv8M7?`~I9)Ipry#}u$ z=-i%$O2b8{LLhADP*N}{+kLY+;~!L7YH3+_t-l|sC4c(QQnf`gXY0oCC;kY|z#;NT zEA*H1ryo*coKq=9;Whczk;%6oRs%QNr=?FiaGodav6tGPys#bX`!PLvM}XDSfH60W zU|;vqTZ9%Hb5)gK1*}IX?|oJ4IO2){sjp&d;uk`MVd#*CB-j+KJ>Y_$Q?Mk+fj1z{ z#gd8o$TLEY!6#nFw00;$URp7LF|*eMmccg%`#}go`>p1GW}hi(S@EIf^plv9S)3yD zt2p&>T)FV!d?2lQlO&5L?OC|uRKZk0z_*L?W>HrE>^dUh8^!QEo zex#2-$b0cL%8T31E6IZQDkputQlF+b9M(7Gx$NJ*4lc&;~rL&JS~B3 zOWA#EWEl6>Rw?qJ+5WMOwo(UdxW(F_iM3XS>Y6L2N{E6u)izUd;_B&t@TG`!*rEh} zVFz->>`d6?SQ*fD%*J&!r;wG)5wUM`Z5@T#)Bag^hEdBZB+r!yTaz7&|E!ZZV-p(y z)FeYdgwUKgu>#t#wz@i-0l~*q zft&M37uRk^P5}7{t;|xTt?^Uqp=ak9lCy5xasJi~`6g!RjJnxj@@hVIfrk+c6FWw^ z?g5Lom+Q%Ue-&`_AcOo-=`g1D^pR8)18gBqVT^Z_VIRcpK2%>x%q@F5-zo4-ia&&b z$$gTf25O!X5|NzuHZkMj%NrU(BS8^p`$)HLfXf?@Klhm~LU^h%h-o{`Ak*Mr1Mkj? z3d+agJ7(7{2_ZjPQI06WfJ2Sf>{ksB{#-t`AL1Ci=Tx*jI@C6XNbHy>kn5F7@5$9h ze1hyxJmM%WT+R;>X-EJ5+-OtwK)yrRNAY8uDhO|F!dZZR7-ijoV+0TD9~!_dn_UmLy$Rd+kIqRc(ge#tp9cGb8cFhl7d7X zsi4rPIz=zRfFadUSrw@IlowHxO4R&Ov`|i#&P((6a-Tq;sIT6b%W|l9U}h6-^tCX{ zaFPZRQ?bALEVLeiQbC#b1h+;4C6M zy%rOSiw%~UstzRE7(@r~bSblMR@+jWg?-M=m`mi%qaUcOvNGsP$-X22fI1lm5+DdW zA#vgm*KKd0W`@C4gdCL@A9#lt%+e1i>aK!9#Cv>)SZaQQfn*Q{?L1^3z|q5&l}(3q zV-Ip7iY-=eC>ZPHU;-dxh;uFGLoq`!*R|~9ZSf|uTAWdqH2bhuNq9;3?@U8HN9zef z*(_UM9)K{wahZtRi!OU?pAN&S!!vDT&fq?sM6i^{sGMucSFeUvM{L%~%M52p9?fht z-8tc1lMlyNunlG$$sq(3reIOe{!Cg{LRw9(cB`B*1kd6o2486an1i~EDD4>jdkq7R)L{ew)5(SsxzKVhtn$Ih*P zS#O%T9K!z)KP+-`kyZS36Vfb%<7WIWQTT4$bm`c(OE0}z`rwh{0xl>{k?IT(4YYj} zCXLunsZx6Bm5rD$vQgfDef|4KP7xB^ffYnGpJ%K}(CbIvKe9npyhApPnl|pCrr=*G z*_-?(%0Gqj1cnIHW>G(92p$?3<}`xzN^);aW5zv+=|fN;$7nz(X>irq9bx?p!)1Vb zcw_~k2BgUdN()HcUI{=VfjDTeeG5*py-7giX&p+25IWAukcO>vqKJ7Raz)#*K!jlC zYCp>Gk_36dB*+{WAuc~y^mMtspUJr-hY$?0px4o%HkB6Nvux?21#?p@2fC4kCCMOb zVLdoxxk$(4^+BIHG~-}LDx^0<;0c|Jm?vu4X&ybMIH+tn8iGwBRm$Fb3}Y~$J(MCV zO-u>PXlHb##NS5^R04PNEd?K0O3oyUUBG}}8J5L2LZ*3&IfXre@x#m7Ha-M4hnLGC zF5eSq=)e$~!-mL{Ug_(p^bS^fI5SU?+1i`YGej=u8TS<)WKlVk#@>W91Dt{}Ipy@c z5<>IyvN@wXi^3OuF8P9MM0x#X;<1;11WA^BQ}BX1 zQGhVu5&-UyCGm1ifMJ@9s0k>GV@)4w$-3F@8%!RU4roczJ*J2}9l|Yz)Ls2pxE0uT zrxf(bHpAokA-R5D>#B<^mAzuJ&6^3|b$v7SXu_Rvaoro^XI^PvHRBIIG``8a<=^&) zf@vXt<;HcB`wq7&u<(LieAtjcKf9MjW68pJ;V82<@Xi^9Qu^!N!#JC;qGw)gWiP)< zBRQJ}HzTDAWmAf$R``Rv^cNNk9z^F63EN_tC5oL%2*j465-!XIh0AKNwgQc%#~j20 zbP!JoS?8Bo!4(XrU&j_Pz48%SmdPNX10*zXIhMVALNqO#$=Hl9x7Gn6Wi3Z^SsyQf zL07%y|FGPuX2ikd1Rk<&Q&9h>MK=gDsF*E?o-5KOh~$nEae={P^SSl=?T;f(I!VAc zN22pP<*JUy_OvH@y3IJ%kMEP}aA_Ot(nq65GY^?eI*7*)=0WcAD!A9dPGYM1fqoc- z$7Afsnr<8qIP-_tsb@EK0)))(T-b`_r%3m%>=v2^eEZ9JzH>P?-7{&fOCM`y5QqnE za^=8;JbYV3n7;~yh&42W~Eg^#h5gP$`5Xba#!+^f(?5CJ+^!47=_Qh^2J z?+z!?*s1ozDH9XO2po8T*f`(d`x@?TSnyhj6;ogoq;Nk!@^a$b{a!A>YsO3v< zgBl$lG9wifa7=nZA>}pjXPJfp1`SU#!=>OAt`9wTdv$n@SO)MxrD@Q_KIiqeTf^+pE{wwH+4LXi>G}b-=G>Q_O|q*y8p*5 zfs3Jd#0$HP{~`7~ZR-Imqw^n=JRm;BY=&8X=b$3)9#Al$Z;K$i=!xP^M_VHAV^5dL z*mirYp7|)37Od<9**UkTR%(co4~d#xox^Ht48HRsE{e$HlS{D5t)lD^Ri?=MDw>y3 z868+Dd&_LO8{jQ$;ASNL9D#WJrw}evWdIHJ++`Uyz_L_yOnGy@0a*7ds=>K%>)0tO z#kfyI)nk_RSB++!keR%4E$zYeSGe46TRG5jr!lM)&Eo^G12#Cc{&TXdH4{LgvRG=D zJv;WAHax&Fi;ZFShqxVzoiYegGh0C)bWeFM9HyX6bpb`J2E#iTf-(y8X z7;B+ob5Am^M%5v|XOT3(0h7H2t+MbNkp=%b35aj0o-ThFP7m{8r!@c(hG1f)(b?dr z?(6{;p|1DMj!}c?;~;3@P7jV;n?igUxmGQRBDC>9bp?SCLXmt@)*xT>pb?4SmMQ+G z)#UAD_e(XxH;1oQFPZN9PA9oMiI8zo1!o*l`Q@AJjPs#ho4t?;Scx^^1 zIAg?DS#%4oVJFLBF9*6b3q=*J;Jeq19a&Y_iWE(A^b8j-ZHs07PstMLNnpWS#i$YO z#gzK47$dLttrVHBLweZs8d-(ab3)b<2pnfVy+rlRiVM8CtvMw`km!IgBBl|l%@0f~ zcxIK8|ChZtfwMF#>x16{6hzix2Z6R{pqp`~rnhN&hMH!o*D37HuIipa2d=m3-m1QI z)xE`iZ*_OEDvC>72na3&{1Q~6Ac{&{P%$cui5QoNyV0Ogqn{C%2>C)nzW?)_=j_jU z@7u$eU;KUFKzHBwJpXgv^Pd0z?AyB^CPPH;M+27^3(@?U+pRx=t;IJS*}~+#Xe^G%%XVR43cCfcYjcpC0)-jK8>#0xzI zvDJ-PB0-al_LeQQW2LzbINGY=7EWrby9>y6nnrH~mMK4X``9hvns07PqA$pI8(^lG zhqVS~{U(CN^;D)mWZG?J5Fu!cnVZLWWfS@-Jd%a=mwV}>XpA6h_ss4<8wx|p*r<$& z3R+bspSYjBpdCS7e_l9=)S%@Dt5|@532dHy;mK3VY2xV%&3n+jcl9(ceBea}h&>uL z3j{&s7uRQU*#<8p;M(yk-oQapyW63FwdY^F>5doQ^xt21&p&(eH@yDG0DTqy z9K}cdSN!|)`1e)xf%xw@{q^vwx_iDFS8LT)wNdq}VKu2b)zPYpU&Cs|PeNLDX`Qx|EmgcN!gg4;JexKoHjjsMwL z{0h7syMAx^`~OS3fKvL-AnL=2#-~9SGrO@qnC9J;x(5(7o1c<$pCHnanI`@qa| zV=rrT3m5t&Sg^`r<9g2q0OHxlE=$}IDF>H)K@7&QY#jt8A8S9sTeEP^m~ecuq{*>k z0oMsqQeX@ICB!#OIn*Y@TcgDL50CptP}DpN!lM7AsCm?H{q|Qp@uz<1t8Tck@bydtx2 zo2GzSN0D|G8GHh_LDfUPJ%xXlt7DvlS5N>9xZoRb4x*SGXybhm@O2K>c>D%{7>+TGMY*t|COoNG>V%@o|~t6^3nTKzz;4UI#;-G zq_jJMXmz<_xr)ypSC$ z1YX3mrBF*2GS<=f%ymL_j$6n_aGp5Nrb zN9oZh7w!znj`KQI>6B6HLey@7_XBObr&0VKc${tH(MRuhqq65`AP7bjQLf z-i4Pta_}1q$+2q(vET#8(0dxtK`QQj^({LFyzj^OM6Z%2A+UkprBA?X@NyTu%cKUO z*=Qk56hwghQ);Z?yaPiwH&+LUk^N|_`oc;bY7Aqhe-npBP<(OGIQ8^)(D4Wp^!PF3 zIfHHZ3P4vBrR7OGl=fxLzHg6%Ia38sI#cZ8Pl!w-wCq z7;%|zNJ*cJFpX;!K09;kIX-)aM96C|r@(hCU{%uWX1x~|D2xZ2$Q5x+W@lbcQAHnj zSkn@56R68Tp^+rXS!M)fB;t{rhmJ@jJnc=m zYhWpkppBPA$*JV6oS}~Ks#~+WWP;17DWj~95D}XFrWY)3ZESRL`;BXd^TjH+M82ZDoArIhTw#*!|wF?;-yJeyBxpSB!q7n-y7+_t( zD&%J(z=;u*LZ(o%(SsP*QHJa|iWMmEjZ=d-7)nwLp)Z)7xw?et3c;)joxn&+1^Q&< zxg~cya_*v+fVp!x>0-QS#AmiANI}Rz$K0g&2}#CwS%-S5rmzp?cYX1{FUshmQ_3!M z^ic3fg$9ODO-`a0bHPf*zMlVZ0z@?HeC=VdiTuJ!AjZ|K<-q z^_w35h4+2)2cP(@-~5X1zkJILmv4IOxhH@4ZI4`i_B#&#ue;vyo?W;6iywZ|Kl!dZ zpILv;3!X6h?x$V&^t=D*=2ySxu^)NhJ-_k(KmPuQS3BSL?8E=<2QUA{=8ym7M}GFl z@BOvk{_*Gh;Rk=>na{fP!Jm2CJs>AN!g={;H2X;$QvN$3FS#Gr#xTUw_T-|Ic51^dG%xW%r-mb7k=_ z=gvL*@89=dzxq?Z^S~c|>cbEG?tgpCEzkHLdv1LC%-cS-@t8M#VDy-GZl8SIpZ}ZJ zJpL))|C>*K*oXh%$?yNj!Dqbo_S>KN$p859XWjd~4}bRUKYQV(*F53%&wtI$ckbT$ z=u3CM@27tK*5|$VnYX?015eoVxOYCV=eOSeeS1IWYu|d{rr-SK7e4EoKQZ@?n}6)C z%kRJQ@bafW`QjTt{gS&s=i-ka{r1bZAAi{Iz2(GP250X1&R@Cro~3tv>B1xa@@G#y z@O=-Q`PR2>E&Y%BllSe|_>GsIKD7O^5Bx>1d+wM1dU^W|pXq(g&bO{U{`=2vyx`^c zZ@lQxW5)0O!J8*9dhyR)+35e$mCt|lpKSl$cfb8LKYHc1*S%qN{&n3aR@JA_q&<#q z*b~sg`?<%UGymkO`r#*3)!*RvAEW#EnI~1%U%}Qxm*tMfSJjWg&p!p`3!hR|x5Do( zxZe%zYtZuC^|Y$`Quuj4{`@|E|L#)}#-pq1D}nnPg!yXpDK-(t2l4zZH&oRH*xrnA zejI;(6yZDzn3u!fuOqC_U|ja}=T+4zu-^c;cf#L~!0k^VuYZehhWPz8h}SzFTUB3< zIKBx3Krg|cN8?-G2h49H{7)dWTQH1$M#N!5KVuSGgs1@=GVJ-?6mKMCPn!@E8Y>GfuO@5k}y-H6w7fx83lcLMtb@b`My z>Aw?Sz@rmA^r@*oO~Z>cMtYQg(LgW_1yCQ523DxYvdT}?2dDoq7`%r6QCDXTK=Qnxv@xKvT z=C_3DOqAV&_|`nG;|HQHB7$SMnz6S#;q?T)CG~n1w9@!rC?^_LxRw#R0#{OH4?*2> z4Bv5;y^iqiUUiPY%!rwW+!mn;(j!fXd_o zF?ye2ELM13eI7FG4i6@-JlG272tdy-f#MMF1N0UTr758i1W);sK5rS{)0gZ{F zKgs~+Ek;LiG;L`_qfT3h3ylu{E`mK|gQfY)H4e@czp-};d=-Dj_(SyftB0e$b)Vrq zQz{UxR5zwdeg?c8&fiC2+fsJgTW>)S`|==YG>=lE^yU-rc8m2!*�Y=UHx~K%39M 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

ZWV|}J9 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�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

+=la(}wXEbj&*N%wK1@a<#Oa zo|YF_0O+gU4kz#Do(bljQ9T_fB70j1k)x~EqQCC!3T(Fm#-v=KwSwdaZX{$utzdYX zks(}#k7qDH3E9l;&g^P;>soZ*llCu@5=Y|zz;kb#{awu^Yf*aiwjQ2glb}YUQ}=p& z!k;ydB170epU?bNHVCTi5)C_G8fKQ!95b41Cel{WyH4iR(wgWmWCnxP9tj066n~Rf zN7hIbLq|UGRm-|Yv)bxf&ja~28d|$hW=$~nx?}b=%xN@IR#fmaOW@F*=C(UUX+*%~ z!%P!E3MjKV3P;bxI9A5LB!MZ)svN5itT|NPWCFuX31hcN=q^u})fFw9Gm&s>+y zG3Zv7N>Lchqk=h1SNK3CnSpVmWUoQzv$}CU1K#dYmgpVKeU!@~Yp5}r*Inr+JIWNL zc^k{5q*3m^VD1lyIZV}egw456aK>Z4k-t97ALN3O^^&zMV^$PheThFC-IpK~%WD%H zOL|_<+8^{hp0Z)Dya}r!vTVwRUCbv|V=Y6wm1l;kvQg;9Vm^$Q|U1(V5SWI$!^X!>q6 z{HcYkxjUI@LIR=$#cL<765T-|fUj9Fb3Tor3mIPan^){O1`^+_j{7hOB$bZuf!EDo zJpOp!6wMHHw(t0`sYxsgi;b$j>N%^`OrCHjg|Vo1N)ebL zh$wZfPTP2am~fZbE2LlMWM{ZjR`=V^Mz1=OJVG8RK>?$;*$)r9EVXsk^|$FpL@WNo z2kSI&EWnE`-044d$S-npMo)aJgM;cFKN}??L{8;?L zhM4OtG@r|47<^HJjXpkSz=M%Zq?&wlrkCkJ(~TZk&Xzp>jNm-}E2DYtDozZkT$T3m zdFwGtdJLB`(2=US}{TvO78Y z0NE{MnXUo>s#EB+7XuvKZuGa#vyZ=@em8yu(4z0cWusouk6I4NXcv+qM$Z`=9RKxN zIoM50!yU~1!=ucA7?lYjtTw?P{%HZE1$UbtZ}Nny1RJ@ROb)$5S9W01NFej%XKsYz zSM#g0Io21%~u{sw%EM1Ow8`3!6h4-O zPLksp)bKRa|8>yjVY(Z?mrLjhxbVSM6sfWHKtt@>P#d9}`m#3F9owl_|-0Tl7EQxWaF>;#^blqFkT@XIR>=N>^LhREOBoT$@V6| z^7UH&OxrNvx>lM|GkagQPdnTg)Lzw!4LY=Xhx38R`D0M_IVu@2*PRZDqEKZ~(u3Md zh&S1Zoa$AF;;e?_x9s^&p1jVZWG}-;Sv{{0Yx$(zGZ!GqNnsMxdB3^1#w+UZUY+Hk zLm|eJtV(9o-()&csP6*LI;KIIIt7lRD}EBe6{@C}oZAF>R?`8^k9bH3MRhtU^&UiM zAvk`0${6;2A%LSHWY)cj7M8E__=ml1P)MP^+wI^Wi~rh75E;`!8+f0x9ipT*@W&2V zw$=podsuyvUU2hLqf%}nlPSaZA8EjJiO+pPRrR!#5fqHb^%KV3MD;1$Z5%|$_$^8E zl{2d0F>_rw6EL!e46UMNQ*5s#rsl&o9A{*(a(*8yZqa}USI0D!&;lcS65(q79Hn~a z(5i4FU6M>wESGDQm_oiPJ20;L>pgd7yIiexdsQEIF_tmZlzxDb&N;DSzb*-4oPY0e z*3f;rhB=Q!00L}CvK{|}uqe{Ho7vRyPaGLL^ZpUR8WSX~67#Dji(f(;wUf(-2B=Da z&*M)93%TAp5 zkC^hxFDFv`YWqJ$(ph!Q|tbKp7oU$-exoF__`W&N-%$0P<_(l*;bH|koD{MYslRH z$jZ|E9TDWf<32HCG5HCem{Hl>L?4=>@fS2zP(6d;%LE=4qNG+$e5v@doeWwDN3hcM zPa2Lp14N!C;*3MABX>&X*p)#>@UVez-y!TfZXsN@BOf9vYKm!CoQ=734io2UR9<^) zcaMg`?=jJa4Dpoxj&oOc2gLAb#T}h6r?i-bBnfKLm$i8XAewU1m#m2q_5J z!1pYvkE)KU6Q-lR>WL;UAY^_xs4`mM9Ye=(aXCtS9)Bq}lo{vvm$f)QK|2P{v^}*T zqGEZccONiy{JIuBY3}tX~zws*}0thmjl=U(i}H-#V4iP5ildd{ZmEPKK6vuvto zV$~s<#dl{b0cB=a*oLIc|B9eK;aTsbEdR58lf_bPNq|K)31NcrT)=)$uH7S}g`>c8 zZWP=XMuy9ina>%)vAt7%Bs@u4m3EHLfGvsmwpba{7xu4UUZA5^Gqb4u3Uild8zo{N z>973E#7tAXlQOgYnfMYA868nZW2gCFo5W`HF>Hf*=f9EWv8IKcHT>ZkU2ZGoQNCA{PUCnn zEkn)*lrD%mt)^FbX+2>6H!kaPw;FZ!dy$5NLex&nm-}RE$R3myVH)61R8l=@wDP(= z-`IftIRBQBGCw)&Y@L(j@xdpwMpVb`X_i7}o4k4w%F3c#wr8gPbC>8dySyMWGB8Mx z{W|}S<3Y0-=g-)ZDEDCi()@eu<#2k4P4tZxoJgC0ACU$@o)$?#(x;ItE|UQzWm0D| z_-VwQIaW%=e`W`N1~k0RBidZ^X5jK27Gi1h4Mm_5}|eT*UC$zzu7@ zqRGJTPvKE@49@`)e7&+bmVqbyemciQIpVD<;n9Po9e0G`dcpFm3}Fy{6CBjd~%Eb$WD}j;OjEt zElJ9?D}tRlkH@gi<6!{Ogh4*`_N!H*wQ z50~Q^P1DQa@DLlOJt5(UU+`;Pvc}>!@%+Lq!z&Z~AM_#)FC0(_sgPEe_t@A{a^{GO zlhS(ED{E{vE-@2XW6_%z%N#9dYdC@6ozAPjOzdMTOY*9G+edC)pC>|c_W9#w)IJRH9bAf&w{rYG!p`L3pXtt-XhIelQ& z!3u->)i{9o!__zgKk6mJd3aquL%@S$e8-QE3rj7>Hb4dCIBJ?zfQvMw@Rx$P>6Lob zh;LJ_6a5{r@MIr9s=;qD_zM9k1b+xSJ(k9+Ar9V}GRwS<1L`ewBTkCZ4*Y-@?!hNN z45WgD=JKC&#~amr(!_ub@{?Dkvo4GC_xyVz@S73v73b*r`a_bq1CGk_W}cw^FJj<_ zdirymF=WC&#f!(~^2-o#Q7=CVhthH+6$IX>#bYLH*kk5AZ*X44Ide=G$%L<^IWzww zDg58Y`aS<3E%JEanJ|U?$SNZ6IA4k%j=ey5ix+>NK5Wcs`0nyV_+80(tYjQn4F6Y{ z#qbqAbNQ)2WQEt~rEuKxmn`L{{J79x!W1}-_glE*&<(ijg`Kv6sm-8j=1_%27f~w_z1pS5hLo6PLy*xQSNC(-Qn=trD-9y zmoDPtIQIKEQBnN&41A8`gWs4(mm&Ax!T5P6$&ceQ@yWpF8+@L{r#bR3iT@IHXcUtu z!cUfF*ND;ilhZ)W@YPdGqc)%}vUMQ776?r-H^*q6(Grl)ZCKzLQVvP`wk#R|D!?b8NAZ>OD??9%I4+au7lh*OlIcXVqR zT5q%y^eaAPsOa>NDuB+#C!jgE`SzBf7WkfXE<@K^+$~0flmdF9by(+7>dMg+(Bt@I z(QEkX_slyWuJdU65ajpA7SLXN@XK{)gkz%wi2DFP3kRx(Pep2Ibdk};N&&S8af*O$ z0{MRK4;q0_Ku?*QXY?}2@1wUt@8c8DF5Q|%zk+zbWzmrT9F#K)xNZSt0Rp?p^iB8MOiVF?luUCVbAM;rRL>J^?+8 zuSr@#%FukH6-ohB?;N8o_%5LD@zwXsFQ6mhiai?Euar@Fr7Wrns)tV&wN?t~YTX*p zEg&An)#!fEG<>SjyZHL4&@rQ8kA<#+Q7-5*d;+=^UwvN<2l+mj2J%PGJlp!3(F)K< z_?$~S@%5lkxyM7QsT9zKAfC}HQag}8qOMk|P1k~Y;}g&TeDyWJ524G^Q=4Xh=E~M3 z`08u5La8>b1995gw8Q9okWX^HGFE*MMnQJx*6naH4wz(C5uLZ z{Cqkcf@6|SDEW- zbhA=GgFswv78TgmhmGbKy{uG^-U6+|rygxn%Ay0hwIRi4V+7+9(7E{P_eTSzhI9d_ zwQTKWTW>dd5X2)fpvTNDRjNm;KpXL?M^9WH(zoUkb3%8zQb2V;z6NM(IU_)e45cNqoYQrKOJsu zXmpuTH=}+=qm5=7y`q#wAA@)#7N<=hzkcjdN{@%*TWi#DnYXdj4c zT91AK`IYmSQf(^!Qh3aq4&q#HPSgbX(k=k`{o4-2`yBfX!xz8+GTH`z$6KM<>TT zWHIHaDHR}QI?NOJ)WUwdNK(D1rZSyF*NJ)4VrtTj$R(4$Qd1r2`bf+lmZ}cjDKWtv zVa^xObcrdgrZV!~A*QOCTk+e7xX$O9=}YNiTA8_%Dv4=t=3Y8S%){t0ZbfCfkLruL z&SD;-wqkBEGl{MiGsw&WnkeQ0Gq2E7VkW}O$EOy(O)K1NwCr_!$NPfl9a;&vuN? zIX3;|Iz7d7!6A}K^;1l@828VkSNmh93+iEj>W*6k_vQidkNW+x~%?-mzb4rNnHve14;k3UNz+GINmDNUA?m z%x4ng`iE^lM&C+I2{V7wZ}_EgI8tEvUoHBZ4oRxE7USH}LfrFx)eyy9dSR~N5Q~Ys zjKbWCQD!n+$->-+kE!WGgP|~Fz-39Q(Uxk6J6&QPwU{BUoWv}#n4zws#4NX%q3#?p+jTyyMZ?_rVm`K*;qDsA z=S$0Hlz_L+3ZVn(?eif}(?4hma3%JnS5$3-nOqutFC(;~&(A~79O%&lT>H#5-< z7V|)g86swynMv+`F>_N)vWP?JOUz7hqooz=)DTT`4@)byTg)^!5vhoNR?~%MxapGW zxTShT&1rXsqxTW_i1b)_HMQ_8<)i6KHAH`^`8mb(kQg^4 z+=G9*8^x4KF+Ii9PBFd2G*2f&xxHaF^^eHwOFp0 z*UVIponMUi*GkK|Myy#e?u{=krbg@{NwrVS+*oexYDx9GrK%t6E++HdaG%zX^(e+; zqpF%NR6llu&XsKGoUXhp=ET&a#k>s<=OzYSi60=!N?^yfTMlt&>rbq0Mm|&=HY46w#u|LI} zp=NiiPpout-aF^2sYSQNs)}iD=Jwb*VmdYU&s%HJz*rM8S6NI!tYdNRpBvS5q2aM> zit}C`U@@a$c&43}V!9RQwcuGZV`Dc+s-ZbIx%X+^f0O=**2gT$O`F;ikg#k4RpJvL5qzFG~=gklpU=2nZD z6?HxNHMD=)eDyD`PfHN!w=NFp7v5~i=^6YsTRhziupCgY?D+)?(^+> zJ#ArZr}R%nn0olsqD8TNV)9bVcT)P*nre4!aqI^%cUa8wSjp3PY}{{VO|0%|yicc_ z`83w-H17GA)DUfqU4rNNnY2{R8S#y=wvuWU42B5mvnAF=Qf*a(XZf+NQr5wgm}?~; zcYm1b%UDlIm8pj4t5_e2sbDc*#rjK36N}jz8+00vx=Sr)YwR8=tAm-HvEfp~8_n#F zjTUoniWw{BVKaMU<0YTR%zPW0B<49abJKo_y(p=cSXHyz9rOFJ`@_xtQNVGZl04aD!V&!ihH=Df5KVs15)m-cTlL(E*3_HHJR zmhozc?o6v#g7cYUF?Xg_5wpz9fV7%o)~M+n861rad91l9}0Q&q_YE)YOd4O?zF+YGg65q-_v$shZ6AlC-ZR z)s1TA#+IagE#^)&+3{6rE{j`wpT&HbmM&(3nKfxyVxCk}i#Dg_;#UY}(i>)Wq+KCq zt(ouB`it3T=J&MOlFwgej;1XY!&lk<9N_P?cO+Gr2g2TP@fsz$tlDM@$D5Yq`MF7o zX;qS2(bi1ScpFJ|ote|(S4pZnQcP!wNv4=CVjfO0*Olb`HA@ZAY4MvSW?o9n04e&1*UlNaA4=1DUx;$MkbY^GIwrIyjTAG;>wFh?rhxI>t+gxz|jmcv&%%%yf>QA?7(V*Tk!c zdD~34_&H)WnYk`rN6daR-Q(wpNgElq;)eJIV#=B68E-Bo*UU}vOU1M{(>s2-nCs2l z67L{pkeR;mE@B=sb9?-HF>}rIi}w=qrkVcnTg7~8W?=kIG2fXP6u(;xjS5>aI6h2F zSu^*AHKh_`;`7CPZ>h${Un#}M@{eZ5#dk;yjrR4aMdRYT#hhVgV*G%ZW@C$X^si~WIJYKIf*LkqT%!xM=Gg?if#8dGL#mrLEIQ~++TWRi} z7u66gjt`KSRhG}<_+6#B$39cjh2DwJlG4Anm^Cmw=J%>;pV$yzD2AV(bI-R=d=h_E z%pr^UB)(XTyV>^!$GldWDreH)Vb1Q8_#34uCzHyJ@i9FSvka+->fPi`7upzqUrY^+ z=|Y>?pf{SR$xCci(?Lxw+7@3UF}=*}i|;MX`)in){qZ9bGx$v3in@vY@nd2-z2>A{ zY>tbmy~LX_Fb?ls;u_?vC{>!62Q}x3h)I;;J@|+k&L>@B?l|A4nwj`9UPw$L#S{^9 zQym}E05QeHJY#kKF@BnuchxjV{1QK1O!jxah7A&b#jBSYj+Smg4F9V|f5p!&lLm9x z%-?E?j}2pDiQ1AX$4puxS5ieW>1@!hrW!LhRwPkhOiN2uEYawsR3#EE#B{Tml8H;i z++n74qP3XeX38Ymh?!-kT;eJ*FPbTz=qP4|nKKfd#B4HCG0|CSxX;X)iEG59Js7sV zN}`*jI?c>ki5_CkG*c~cqnPu|R8RC0)7s2AiJQfAHB%$e=cJgLiCe|oZZWkJx1AJI zCvk_E0*k4exKsAdR5Q7W0TT13nR;rXey*RmOJdepOoPPTV!knRUSf!ts1;2U1t*yc z6T?q3%@QL|%IBiQ=#$JPi3umAx-v2Iq?r7~BPW@ziKkC8y%O_JGPfrdpJWCm-V*bR zw(E@e{fSj#(#C~*c|>CUNvXypz7UgRG2;{4#pIfqnE3XjRFf0miHY{|^u#Y>q9bKS z;x{qTh?tS>i7< zYZHx6O7(H#qOv?kl^P%JoehcR5>sDIJhnwmvlP=>VxnVbOX5l~(NXYaB413@KVKy} zoRn&7;$LE-{k1J|wV3GW{yNe5q*U7z*NBPA+Lh=gExpWIu_tkz#6+db< z&&(f*`^3Cy=Fdb@%tkYbV2qfkf6{{o#Y8nM6pR=1t)(gwJS^s@nc~4DF{eEg?)S`K zikK>9vVv)1&Novgm?5UEne1Sem>y=z2ak%0)`E(`<6`czm`cHuV#b=O8qAR%d)&;~ z!P62G9fRit^Tb5^y=L&dn5gY_f)~XsuzczT3&p%=ra|zEm@m!b1#gLoW}6nl+hTsQ zm{!4ZF|mik9=jxXSIik^t_jwNiN;2^;N!9h9D}(Qb8WC*%q3=e1YeX*;27*+=Eh*F z6(lAaKaZ;^JR#hJPX-lF%K53_%#(6{HmI6igl9-i zbxz{>pqj))^Yi@R95KkL=H3&q@J=JntrF=NfV6*LzU%_J*=mSUpW_}!qDn5duM4=xrH zwe*AF5;0K?R|S`fiF*FS;Iixlt|lJW(!0=_pzTR9>(oSZ@A}|!iHT;v4Z)RSo<}~b z@Tow{Otjzk1b2&x%Gw(Y5mRVlIC{Sg?hzC1 z_d~&OG0}eiGZ-T#n%Ry74~nU1`5X<#iK%Dic<_*zOU(QoOb`>D(^C2*G1pj3TKW_* zx0y+#PZKlTOwsfw#6%;iRQj`GqPeb2`oG0QH7uXLK=v{}LEwL{r=5}hvcyEQM8))1 z#YBBrDSh!tF_qI_6En@~lav0sm>0~PnZ8WSN;B2d-xu?xnRC)tiiv7?Zu)95Q6JVw z|42+!!9wvV%(%~B;=-lE+#s<>!)wY z#w|rEtuf~$8l-1e6thEej#|+$eW%3q)|g`W6%@O~3{~@8 zJTLusF%#6h6>pVJr^ivBxoT=9E=iA{&Z|Rod|i^BAtvgLOVbOBSsbRK%hHRA`Or+e z^x|T+!T34h^7KqG(NUS7o-O96rRtDgPRwbO!#?bkUO`M1Go8~bii!5uHR+XMh<>@k zr|Lr8($75I5&k|hP2b8-5z8B$V|0O0Dd`;Sf<&?IhRI)=7LJlqoC)6-ZlCTv_xDcewvjjht3DREv`9eB`81H z8{}I)2(%u~(HPK1p}C;VLhpdK3vCAN7CHptx}g8?Bd+^|>VvpejxGcJDAd#32#_yr zHt1K``UdC^p)WzlK>5kPG%kmV;cp(hZJb{=$md)aR9M`lAYbP`pwr-T=>bp~P!3H3 zoi6kgsG_8J0px42)@TpN=bXTMXP)>iHBU{9t^xV9!_<`^?#Z)|bAIv(-I|}AZ?w#4 zwbAEBdyRfKIt}mGa2ff@@yGP)TwRon!l*FcYn+YWkGC>>9b7lKZ`FY92dul>a!-?pwsck9+18V}+T;pkL* z^%;$Gw87Gbd%6Vu2FLr?Q8_&4^kvjDid<`RHy8~CasBGkv+C;8YeuV$J~!HFbkHck zkB~2y8dL)L8e9nSEsu_+PB%hejENGe{0iHutEKqj?~o^IJ+Kh-Vd^E&OQz z0Cg!rUtsHcq2r*mDL(y^h9-J?Ct5J9~)~7$=xaGN2 zI16(G(&kcmqdH1CbP4FhBOsUBt8;WCh`#218O;Ls!1+FnY7or~Q?b?8>P4gI_;}CU zUZX;Ie&6hm}tE={nwxgg)lcR}3pAlMD!wYyVtKZsYbPRZYl z{#0s6F+45cv<<0*Q9Yv;M(vDx8zqfq7(J_0pWam}No$QhH#(@)(Bg8aa9O`PH>8pv z-=b*!tp?}!YS^dfAvj)1a;XPs5c(>$<^AD!Uv^5~ZB(G-h*z9@rFX|@+7cAeRJgIS zbuNgHM!yGnoaWGSxQDQ{1bqaW4$4n{$%LNFr5}|XMQ0g_Y@(+S=O{eiC_$CrxJCZl z=XuGGN1dmC)+MzD&5?EyQshv3&{9eJpHeuw331D$2E#zUcc&V?tdvV@Kr0ZJ+LNEc zaoSGFFO~9>J2XXp@_i2Y(bn?i!nknm%%wVTyO1K6S}LWk zq1`OSK%<9@rWx_v>F4Z!mfTwlHaFR5 z9_U-?jn$w7LO+831o<%;+s?#evZxTBM^q5v8NHei&*Ke+c$I7+RI~!diV)B3eqE>! z*Iis!P+y_ppus{ffW`~)+1GTTjc{{?_)KddD3^}H@o4gE_cGbaXLGBCxGr0TxGp~l z@fluh2dCgOyfQ*um+C@%hSyYx%V;fB^bDeILJdH-gK$;~;&I?;D9HD7G;$`xJ%G3l z$(M9%hveHv>x{lO`pM|HQZ5y*7`Ck%Xq?o5*O}=cM?5C|jNS}eJzZ|p)o8lW3Z-27 z5;WWL^Lvo@D(~N1`VL#4!PXoKkEk5_4et4qoU4R6M{?n{Y#As&Sq#qi#@Qf$2G9Ae z#8yX*;QXB31;i_-qkftqhlYdJNEtIgeD#z=;T1uy%+DKS>r2?WNoWa(ujz8=U63z# zE$B(pWGG5T34wTF1MU%iuih*x`0#}VhL$eErTl?M4S6s=5E&0PZe7`gbieIdl-YNybx z*!qLeFwg;uJL0!u9B_*Kaost8Ta_An*c_hg1!RW5l!*H7=KfXJ&P3WIzc(_l4xF4`JmtF-O5c*Il zhxUN{$l>+FpMxAym!B+smfxD6JWDBu>VXa+7aZN@S}Hj@KThgoru^g;x)t}~ zj2<+aW3<5NEu|a^SB)I{46e{FE_XjDODL_HcYeQBgeyTj1J@AZz2%9|06g&-MI+hD zcWgZI9h(;7DkDGdc(wPAS9|ZcMfp}nS1aRIA>O}!E1ywt3P;gdB+nMZ#I;5lql9{Z z_|6^9@Id3>a%c`{qENWjI$8+#IGjHgo)Y4H&R2{6JcrMq9IdweJ_F51T} z;5sFDV=EJ`k3haIKdDPi!PiG`NDBTvZJvr7l~uw_W5nmX9OtMB9OvxUg?GeV1;=;u zaOV!B^A*+#@A|>Lk2v4TkA-+X{X&S3#+{)2f%rI&&K~@VorSHqF2h!?OAhS?oh2!bg6aqrs*ZgLa(3q7=qxyY*3wbQpAF|B zt_1O!Wg8(r1Gq+r$A;g^XO?}%@foeZ|93xf87A&I&}gCcAit;o0P$Ht4plmbXa=@o z<^nw>)CBaR(B&Xst8iwB?s5C}E|r|QE=>8!Zb-pBiQ^K)ec<=jM-ulS+-D%~z6PCo zO?d@zyJRb$@A~VlO>n+0$CYyEtaHPD=63iqj~a0P-fK9ol^{O9-zPQTbMGTUe5PM+ z5BKhcNKsFy7pR>O-&4I#=pneFLW@C@g|>m_fgB}j;2xt;1<(he)Y0Bpw{}XlR%%FB zfIgBG9YE_rer{*VrLJ(FiR%O6_U2N7QhstGi2F1@`IONzr5suh+AKML1>!4pN4s>Z zqvIey#w*n%+JU$nst(#CDe8dyXy+ODd)e9+&ZoE<^c!4$@;Z>;tG9so?h(ci=(wa9 z2I7^y1o1dc+snjbqnHq%spbgrYSmJR?`U=v;u+4T;A^H~;&^0x$1|%Zo>@oBR-RcO z72=uIZ{?Yl)8;21L|uICxs?mxd`*4JXTb5@tsHs=v`Drt1o2r*>aqVW-0RrtXdTFp zzn!3!aDG<#9F(8j59g2gBcQJ(zsy>GJ;#xZR_>A%yjJ`y#C3MxN?)PQC58CfuZj>K zzx9Q9)cLDf9(5PPx(mevor97l~7L-F*f?flie4oajGeouTrDf#O zeIP#H$e{;8%aOJr%>aESIrCNE7NIBMc7goW#6F>gaKC|k+YW;o68}!h*glSX2b2!- zTbVi}KZ4^iluO${{yb+d$X}KJ6vtC$#HF60gx8mj4kON=<^Bcodn>z6NOg@a2l2S_ z^F8P1d(xlh^wYQ;8Vln5a%eiJ65?{`X;4+E!2*y!n_C0&2*VQHmDX-_!-zg z2g`%=^^4Z-aPCZ<&8|gUJ*4fFDZ;NYFDF&&KGxy(NLp4Mqz1=dLuu7 z{_>zvxc2xS;yd~I$rrGd>x_FIN;$L<i0^aF5#n545aM}_DL+{~HylGPL5txW zaVy`DIIjJBLR{zdLVPB@MTqOXM~GL5UxYa4zl6Ac{!U<5Q0zM%_t&BfJ}y(|jp*sk z&DiS4L3r22(QtF8dfxbiZG8_^6lFO2#N2KWk2U<3E|5RBJ#mEjqvurjRC$E?t^aw1 z9YxN5wkTgOq-LN+xE6QR%iL&?Z(DTL`y^Zmsq-?B@0b5CSJr&T+SmCjY6U{@dam6wYaV3aH=R_es0_F?x zI9)Bo=Px^i_{sc1P=2y#1K$Vv$!bO|jIL60at7tkOKyU5-*e0RgSfA-x?oM_=R%G~ z!UfpsXTnS&u9ZKl=URECM3Dkwks9LVpFf391O-qx-DUZh`zcrWlO)R6XJ z>)FVqAstf6p~Ik>aJU3K55E-@uEXDfs-Lj}Tv> z6@c=SXJRYYIX{_e)JiFb!mAV9w}s=?K9{Zs@!i$v>5acm87DdOJjwT3O5ks+hWB6i z{M65w+>!paqi4o1jG?M{9H| zo(i5FzLCVoa_9lY~?y16ymuv@dKyjD?@)Dn6Gv? zMGj>)^mhmxRR#HL?5GA8!(}6F4&4koM`)1IXplb|PgVOzv9&Q$IEvo4c+FCTcP9M$ z=4;RU+!K!%Pdr|HO`~(_EyzXZ7pyKVrENTN{8caK;)!RK*0PoFqYspIkoP{j{Nygp zC6^9>{M~qd>fzT~Ug`XZ;Nz&Hg;)&Dt zlN5ZN;$4yR!~E)ld|G~cXS^@h+;GrzaWAkF+GunXX3ZS=zXPzw8iLqqhm(J z8vFbjQaPh@j2anTY{b7Yg=^4|ZUynG+mP-CEy6n8kfwtCwM%qUB^?nf#$|o+8O3vHusjfDDG2p`z-Dcb48nmb&1>==4yg`{hFC; zW3HRI;pU>aN6bBEaqG-QaXZW%w77B?hUK0E@_luoxhQS^DO|5pIBt<|#}LbJoW(`` z_xLFs_oPqzhNWF)aa+tCG*_ruSm)9p-M{88G8dH_rR`{O_gdUkb92otGPlZHl;2n8 zqJ93ex%fq4{Yrv-{c4$OqAvCNm)~mIjj`J)c`3FsIl2<$*Q4&B@8I&2w}bpy`2C?bLHDp2B0Rf8XqDkiWONALPqT%L`ZHN=EfTe@MA`pkqRpg4~Z> z=X_8g)D2Wb=uVJd&nFr^3(AzOFM>)7Ee4en`p9T2$k*iukbmp>kZmpA9Cs@u#hDRsAU*e!stw+nnn$cE--4Ru{IyuFSl41l>czRmN(d!@{ zCH3h85ZA9hZB}x$&**oJbCl6499LPO-bm{xY=@&NaJPwT0O~K)!Kg3DkBtY6CWG#l zxH%xd2bb8^RiL4=^>a{x(C;AMlO-<>^SjXKCeXtYH&|UmngHSy4QZOu9HWIs?-^}S z!uzZsJ}OF3>=J(jl%QfpIZ9=y0cZ;1%Fsoir$7O<0WB2jV$>7Fb-~|qQ7S`&K(9;M z0?=xq@#bcz!`~MIasLIh6!eAU{1Iq}&}Sh3G<kE2|Dvn0 z@TpNiKVj={mh)ku-!%pP;*?RTOEFJktD~AApI>8;Kh9ez1;q99xpaZ!JCyqy)}xCTP+fSO9VYmGkD6ajHu zV~N`h;(JvA?FaFjPG~QvnQSfDI;0vPU*~%NpfYqmTuVt2^;*=*kbJLQg*Zp2>b0mY zEs&qD)s>*DC1>u9ZbDI9cdN_opjoK>|E7$gNXvJ{{eJ5q_2d2fe^=A7$mJ%f-&Cs= z*ZEd)Pr~&RVmCx6Y{&nm&QWR4TWO1pxQzRxj1RQj|G&!Ea6%cw|DTk>wI3rnhrRZ{ zsXgcN5OVq7q>Xy_s}tHg`Gi{GFBo7eUwsDj8;ECt62#X+GZ5$RD9sV#>**JS_&t@|Iw@tt@4Z5V4?;<9iy<8l9=%h-rA0xE_S zn}sTY_$|1As(|=s2L2~4+GaKV&n^E(%BYE)zZGf>;yd60g>#}W?Z2Lj!#MnP3#8?> zBB0Abem1+>=qAv9tJVKqes^jvzApZm`l`6)F7r!MC96#r+E66{igSWm_}a`nZ5ff_Pj7RMn_9$nW!pMy-sl0NsI{{TeV( zsGDuQ5yb5cXfTL-@>Fr?7fsi)+&joc&o@APM?IizAb;c?GAevIW+W-CJZS$( zwc@>XSX?b^^(}7#^84*#5Whi^nsZc_PT0yn!4uH+AYbmCMx1t-?6(o1v;!PB1LSj_ zW3)gi^-a5X;rL#p@5!Q)HYzvjm)#sETX}!@xZmN*{Fg4u<)113yZJdv5xXL6M_x%^f`8uDAxKp30avZ!V@dk*BwSZMUV(KklNjmljarf3TCBeo65&&oYOeuldn&aWCDfUXv|6~v`E`W?ix znWGBr!+EVaDC)`Uks_ezNakKU(fv;487XF4 zQ2zr=+#7?0_&(CTAV<$&Yf@-Ah|}iKR*a+#xCC*@uR66QurR{v$Tn*%c)0aUBvnMrJ+%C&@`k7sI^f? zkZ&(vCHNX#59hC9dV=_gHs+yIxc+dDNPfdX+<#?=*W@SR{F?07X0Y!WIRB``(D}8=Z+&^0xjadA>O4Q|RsX;4iN0jy|xLqf0y#bEjCh&c~Pqs!Y z4!4NkKS;g%b_Y`Yh`3J4dz1ni0rLG9oqdHZ_s7wHz7F^m`Q;ElA^$_@A>>EDgtaOy z6!qy7*ji590?=6&*GMR8?;5Ms7NfmJzZyk3M|2EZFO>W;JA}tu)c0W-|J@wX1xK>K zKU4*|c&ZQbR|$=cT7gf6n>`u=T_fWer7$@d>ZAl z6S?@&^aIGBj~@n&My-4>%r;(*#A7vG|2z3c$TZ+QoF4agrK zJoEcEI8W8K0f_Tw3ilX|0`c?TfTn3Kr@lUlwmywGUzdpZUV%T8c@bMZy$*U*TC~F4 zDiA;Q4QM@x-wbxN1vDFRj=ll;ocDvCk+eL6JTF`Sf?FVz_OI|a(3}QZB(5BY)8b7m zJk|31H+o7|6I;D&@*m?`V=Iq8M;$=E+<)eWt1N8gXJ`Qp1idab9!u%+vo5nPS`4uKc zJvHWXm_Nky)0pctpEMe*G52Ub_{-87GhJiiG+xb98WX3PYF>i*3ppofwwgC!+^=lr zt68Zr0WDJVsm27fT+P=o+^%$5t>!2Uw=11KQrwkPpQ;-pkpE8u~W2Da9in3Ha#gsyw zvnemdl!qxt?Y*JuXlV{id0JkT%bG&x!_5#}P8GwFRX zljv5M)-YA*v+A5`5*5JogsD!u)l64&4jokU0!%-|oJ+^lyrrfF#m|v^ve(1hg&16l z$-k9}&tZm~V7`HQ-~{s{%ovzjmg;YqX)v{^f#kf`h56K>rfR}`>QK*fIpJOx=2MsQ zYIqaolS_TYjFO&z6gk(Uq?k!`+BG=S7vqaxS*$Y5GcfhNpq0hWgLyvHBwE67KJ|%z zYKdrsu#sY&A9Y}jA}4E5^ksJ zYR-e z)l`K!3#sm+DvA z8kk{}fh$Ok`4Z+9m?TwIvsX=lJT>DOHg_TB0UCTM5~1`zV1~ntpvS}%P(}}&N5PDw zqL*<@0ab^Y1~ZBdsA&bm^%+gA+xnOeYR1r_cHZ0!^8{kX(y`0gOrpDCUWIv(_$dYF zJRW8x%y{Z4W)eLD^99U9ly{|1wGd_x%mnHvrht~id=E2``f1FkFn_>IqA?ot4Gj1E zWIC+o7Z~pO$yBtxFC7P{%o~$wwwOs&28PR;ObzmVOf{I}FjI){fpVQ2z;Hg(sMJ;7 zG=s@F#HNv&%Ppq6n(JXQC5G<>az3AQ$5@4#PD|DFLrfKz8FZ|pj~N0}6Xp?G`Y&%D zglP!#7#$EZg{H$?2=fGW#C0m?JQwC-nAtQ@%_}hNVCK*NfAO6R$5A(c|I7l!ASg;ZHhyr&;6FH?0j zQ;$vqKrWiH_G#!S=&mtNsCR+6t(^QRlR#PpZb~r2LRIh63 zOK69fNyMw(GstHNRqf_u!nOMinkgn)Vc(z~8WXObZxZh(&Y4&0SCP*$;`NwKTl|;T z_Z4&iYXBQw-&Y~#J?h@wn-5T*&tX2GMQS#|?15QD*_a(T)o(CA!hA?oG5XmQ?}gvH z1G9$OiHXiq)>0|#Z$1jDAcoiOwNz7#A9XxSd`u10T!0wf?;lg1m?)oh)D5L#MAnW)wENeZDSJPSZ*+5g(^wNAb&}=pRHRcnV zr{;c*`Ggj!84tsw?o(Q(=HDch`4dHGc5A;$gAWtCEsuVxcfSJP9?=hRfq z-D~07<7+Ab#RW_U9T7 zrzVKuxn(CU6%*C@8(J==fLb9Y1AFir${xU}3hW;2Zt5szR7MxXa1D1;H#I$AxQ4r_ zx0*g0vxoYr8Kg0LXs9=G43-0DsNho4;VHp{!r1rkbKSs%pXfO5N0yhp7+q8}(DuK+Qp#sOEAQ&iN3{ zR&xss=lna(Q!`p){-C95o`AUsF^6fNm}nLLlMbj^f*9Ukf6`$!@51o@`jg^AxfP=_ z)@jTUDyrsdjX6TuYQpQ~qf}Ww#$#0dJ~q)lJw_Yu zXA_OXW3*dL0Ubd;T_vAmJ|-i)Gw>J1lSqU*hj#}4qD(bK`}pJHIAyCj9ftS&ajL2& z?2W&vrkb!f{-#E1!aEG)^3;TP7|69#Qw=%uy$k0$s;LLV{p?&fHO*kSpPlQirj5qL zTt77(G$!VTstK>i(%c9&;T2h$o2aIn<`Z`_)%4eV;%=^*F&dL_^VK||F$uR+%_5Bn z+;TM=G$wFs)r41(>FzT%;ZyeC1o#4IbKgFx&`l&er<8Yi- zb3?^MBkF9|bfT0_L0_C%pcQAkj+sQ25yR_64cAvp0o8%ohnSk~ zfSL;z~{Be4^E%sjHyo3B>R`*3?xEV_=8Q zWk15Hh7;%980K;}|52Y0udr9abaZ)-v)StwBIbISf4RYG7Qys^>Fkb)iN;13SK$dx zHHlUurXOOuxSDEqz}yXUjcY2#r{ZTWU0rW6d);Bg+=rNMuAiDBx8p9Bn89i)!c2j= z)+N={hvDmj>l~Mjc_z^Y<`KkP@5X3MXnMHAVxl_V=;%pKHHms4)w4)-qbn+AI`Mtu z`7k|QZ;iPRF-u@>a?8|AhFJmA$2FSG`S_gqInk}Ivo{&xGrPX7yPDy++U93=eO+H~ zXg2cUGtb-HQZd8n1(*+!^KGv3Q-pt0XbH?GFn74_V%~QvVZMav=iXQI2@F30@9*MI zbE--7ISk)b8|W&C8I|!Z%r{7Nm#ZqKAmbp+4`S;27&(9DE9gP4=v<$Vy94Ksh#BlU zt0@a}L`+gmF3jIz=Ba6IF&n(Gxp%NTCT3JdH^lH!FxbVP;j#)cZiC@tXRyl@Gb-ag z7@iY`xNMD?0>g8{5Lea5NS*m9)je*gm`OAbFWCTR z#)v7PmM}c4k9CK|L|2;QT>Rf$`gBLArPS5?h5NOeBUL$14;J}^9wJ?!?Y;X5!* z5i`MUexCD*a-JL>xy9~7DqcM!^AHTLo{@P>W2RUtzH;T5$Q0`8pEysonDB{nWR@Wn zkEm%D^9c-(C^L!hx##pSMhx$Z87COt7c%a^M(zopVA`R_ zo-lI&IdeX9PB5I$QzsbC=V>!Xk&0uUIl**7&d;7;IMuupOgF?lZzkhT%!M#7n#qLe z1M`xZY#2V4Ba;Jj#|bg@U8>Wop8)@tRvLrXZs^>O35EUg~!H z7#EI~rS4#g;hulp#pg>aB!>I>4c9HJ_*!aM0O);Eml{=PVcx-&=+P&!8#jW76y4H0Q zGl?!k|BQuM@0MvyxZgLrwJC=8`zAN=C7(|?#x}ddYQizL#bqz>G2s~7;;O3&$JiD( zUd$xwh|;Gc=PzCLg`BE@`oZu~`IT!eCOWtI%1u-gp4)uwdcVx6{5a$}bGsWXrodM7 z9WJRRT+Mg5@nZJ62kyk1oG5*#jqph@T>2h2_?0MU-aC8TR55!CO-BsRNPFE(F$Ecm zVO~T&d);g`D`5C3@Lo6Hr*a>|a6aF!v6WqO;vNXmj0XDAjY3RuS3oU-2sic6)~G&4!QA*eM|3x z;Trzo>Mmh3ogRSUmFTb=s%AXQHl+H~y)PzOiT-rE#Y~~c5VKQaTEFIVeja8Y%n{d5 z%p`gh<`B$Lw_Hp#YyIU`pOoq^m%WtpiDHhs%KtDu#q2HA2kX~g$oaS%C}v8=yC^ID zPc}pUk!pmPs1?WET%U?QN2+3ys?qCQ`fz(T@wdwp6XpE38>8k2q$-0{f4hll{(vbj zW~Q370lp6@wonb<)8$^J*lIPoW_GA)W9G1$8_i_C!8M$c!FO8mW2B zOnWtJ%=A{X%S=+uQ8P2ulpGYcVxgKEW>%|dX=aC-u4WFa8DJ*!E#Hc9W~!@s+Dx9B zH_dcbv(ZdHH9wdcqbBX{u+Fp9oMUFGnhs_*s2OHvpPJ{)(A&PwpP0#3bJR>-HD?VD zOK+{_N;BQn3^6lU&C_Nks`=Q=JT-rqS*|8$NLbcpHEqotP;;Z1jCXu1?l)6e&7)=- zsd>#zdo>%)^j7n;nWUN`_k{JCspf1m3)QqVvs%sdW_GB#*UVuxGt6Wz_pNxF=FV)uqM?5C!-nK5dvG&5TbKe6$1%ThIy%xqBeikW?CHk!eMa{QZ;anMY* zn$knVoa?G-Xr{HAtIc#*GuX^vHM7i2RP(Btd1^i}vs}&3W;UxSHY}{q0W~$uWW4KJ zahaLQYHl{uNXm;c7LF&FoOq#mr$f!^~v9 z=UXwyOm#IMn8{P~ote&RirpWU-cL=gnK5eqWoEXTA!e4UdECqfH7m^QQ?thmz3=N> zC>fTXt)`Zlx@s;l(^}1qX1c3Mni;I-aWfOuykTaZnlH>OS98$JW;G=W!Wte>Q`=0& z2ZVo9GTNG{tfse_MruZyX|LufGriTkV8Iu@Gh@`;ZDzKb$IL8Mv%<^!&5JJjqj zb6Cw^W->qYttdA-tYLLE=bOn>)6q<4HFuinr)GkgF=}2mGh59@GfUMRGP6NV*)d^# z_Ni%XhCcFj?rJ7m%`h`{)jVmYwVD-Xx~th`X0V#X*s%18YR)z@Pt9d!maFMuX0w`M zW)7&CWhP^dZ^dFWmDPM=rjeQ-&9qlj=)tgtz15s$CaI>mnVD*?HM3C75HqXQOf$1X z&C6yEtNGYW=33v1Z_QL!lNcA)Fi%YtGo95mH`7ne^=8JX8D?g-nn%qnRr9);4QjqH zvro+-Gk6UT|E6S=93R#&TTQN+x@xX8(^}1KX1c2xWoEFNr_D@Mv)s%)HQUTAS98S7 zW;JCW3Tt>kO#?F->wGKn%~V!%yO~C6#+hlaW}cbeYCbTNRP&9QnQHzvvrtW?hr=4K zR@2hV4mCHMIjm-!nauUR6${K%SF_Pfo|-?*bXHS-LRfk~H5Zu~qvl34v(=0?vsBFs zW;UoRf+Ep~pehK0B5V4-5D7BF9C@qlf>TK;D5VhuS?hCphXHYVb zYD)Ai(~E~G`H(J3A>;>260+;fwyrYBF_cQkC6q?UeUw(nJCsgH&SIOn2Qr@02RW4z zd)xHldP*Gf3?%{ioRWfUQ*Y}kha5(!fm}#wg4{)EgSvG;PZ9a;U z2f3J10BNEWL;gc4f&56Rfb860>#BuJp|n6Qp>#m*p>#vupkyF@l;|4Mi(PKDb>%}Q zQwkwxQ<9JxN*Ux~N+o19r4jNir4^FfXlw6;>__Q=%%Jo^{z-|wYkJW{i9=qdBp|(% z6lBnCw)S$!SV|3K7NrT&OlgCxqjW*?Z?~D#kkcs6d#24xD0z?%DFu+cJ8Yg}$cdB^ zNIj(j@;0Rw5?f;Pv_Pg(Iv|TE-H;Ya2GU81zHfSwrsPASciOrNA#q9)QcNj>lu;@n zHIzn33#Ap(N$G^7DLs(rQrn(BNSqSuHoYjO#37eZ5|D=|Dad~*<&fB2wyqk;VU#Aw zd`cVSK}r{7EhP=vs>x<{J}_-Ql#&Ozm{I^~p%g@B>`DVNkN{Ylta2HHIN@DO^{*DwuNnw@suve6iOO$ zF2z}E+FVV^gWN|cfOJxdAzx8SAY0yN+fxDAlTr(rPHBN$Lg|3qPEmhjLCuZlDH%u) zCHh|z`jS% zYWNZ*esCux()+GLDjf zOrfM8r&7uxb15~DYbZ^SC6qSE|wRI&R(5MNxkjUA6hYln#jhxUH)jvO6UMnMR5BnmqrYgPcR@g4|3=LtdshY18IDN*-j7Cv9B?kTWU8kXtDwkX4ilNX}C>Pc39$N({@CsAr4<&+l4wUiFX zJ(O<96O;^OB_+DSwC6)gK4c@M5aPDmUL+ygQpzA>D3y?dD2D}Y$lH_z-|B@KC-B0m|{ zGvPZ*9%R@Hwmk)qy(qCq^Q4-qUP#aN(S;BCHjqt zQSSkny)qxNBc%{Bfs%wAMJa=nP%0twDUFatlvc<+lupR=lpe@hN+0A`N-Se~F}%a} zA`aP~l7OTrDaa+1a!3QE2J$4O39^RL2Kk=S1sV3DZBH7qCq;f3F8?i#CMkK4^C$(7 z8cH$beo6^s1*HPAj#3M8Ub5|Jf$T`>fJ~xvLuODikP1rlJJX8>NdFgrdHbsAL+Y4{{bI_PvRjM^V25Q>Ct^Bp?lx z6yyO)IYhnDWA>&R$ZM1)$cL0R$S;&G$c`&)o;2i8inGbIa26#Gavh}r@+hSk@;0Re z@*|}JGW-==doAQ3N(4FUIv~5m9)Y~y;W;#EaHt$POzlv48m_jLloJlE$R8UGFH&QAf z&6HZmvy>LdYDx#Bm(mT{OvymDea-eF+GpB4j*<_VOeut%MoB{EQ_3JWQYs<$QyL*J zP+B4HQ924Ka{Nkb|q&M&6Tw^Q;U?UVw@$CP5ouapwVh*h>d6_5idwUE;&Es!fH9T4?? zis@-L-|B@Ow2;)JHn^4UC$Mjj-eQUEEU6hq1=C6Gmw z3P>xZ7P5xY0_mf4Kt`;y?dgUjC>cm8B^t?b)KRpCk`Gx%DTH)Ul8{Z5GRW4S+S)52 zdr=x8$5UD%^C+E=TPQt{rzm}p_bIWc>4jPuGcz*|*?zs11Y{y51v!OM4p~5{f!s-H zg1kU!gM3Emg2XQ#HkWvd#t4wBm zS|E!l9gr6&-HBYg6e8?P1A>>X<60(X?2Kkjz2^o{Nbu~gxrnEw8 zD4md}DLs&0N*`pKFKp)67N!?PlsM!fN&<2ZB?VDyCT3L2A>UDIAS1rCF-?%kls1T3 z{V;jDAh%P}kQEeXh-vdiN*+Y5W0*VzkV7fOklBy%c=kCaZx$c?tH z9>`QmAEb;D+tT!+ni7XJQxcGuC@Dw}r5v)EQUe+Bjcrd8WFn;vlA?4$=2Oy;dWw9^ zP#=GupyWZiClwwGjvF#~=jHFaR4x-dTW>8un>hGeOIo1KWnbHkWf3?%ZWFW6o zqA}BpUP?a1{nnN$gzQL3LMBqmASY5PA#*8>kj0c%NE@XS@?T01#Qn~;rw_6lCAPKc z#S}^$av>!FX`rMa&r!-D>Y2A0u^LG5y_F`&7)l%DSV|XU9wiN_qsWIY&HSO{LEfPh zKsHf|A=_-S?J0rmOR0dIM5%?SC)1{1Es)zN9gt@!-H?wc8Av}R`WMrS9e%Kx^C1UO z3L)y-{HFFKWC5iNawnw{@&ct1@;^!|L_Xz<%$<;(DLs%wDSeQ$D6w4Ai-nXpqD~o&+0dgPcd{f-It>A&*kzlc#$AbW!pk-%$!6 zxqY^-V#vOf5=e?t0lAb?3t2*GfxJNJfT-uSreEEVUnv>L@Skl=bX(Jl{VDkn^>o(c zDTG`?NkSSZWsoN+m5?=*M#%S+R>-hlY+ap@Jt;kqB&82>0VTGb>BWtdIHZ-5fV@XZ zLHa4>kdeRI_S8U%DNT?$lr~5`r3>;bB@IzeL(QnFkKd|0m$2VT9%L+~05XkI45^@$ zK$cP}ATLpBAzxBjAj5vMwRb=!Qo12$QZkV1DADarFP@;}Lq4PwLfp-^t|Vj(r3^BS zQVF?~(g?YS(h7N<(h2#6(gPXyyRE$sawa7<-1MS>5{JA_NkBGJQjopmshHWO<&asF z8p!RGCdg_^8^o38QYKFqWM4`eavnuKdaUQqQc51=c}f99Jp(hDiy@voPcl*h8BM8x z97(B#%%-$JZlZKRo}hF?-lb$9eU#`3(~G~#lOfZde8@qRLdY4EBxE6_4DvLk60(uf z2-#Jh-3 znQI_NQ<@-GQraM`lrG3RN*a`Pj8?^JGdMq=Hfad5BUBSxYH_Y$;C&Oy&xR zdSYRu7BZL80%@jnK;ENtL!xrmZt`Rx6DiT1OfP0q@*!7J3L)y5fytAEtfrJfHc=`e z!{u(87ymGlq!G}QHmj#P)Z;VQ7Rz+ zrPM;yeX7aa0y&D(0a16HCZ-#*l9GY=avx@5q9aW&4yEKnDk+7K7br_Ap~N9kxnnRf3CJW$3Q|rf zhcr`aAnIPkC6qX%gOY%(r=%cJxwbX6mqW%#6;X-^+y7fNib>BXUxIAkUz0lActf;3XfAx}|iAZsX1knbpMkeFN@m=<#uTreq*bQKI8a zFFvH?LpDdG~_ml{Gl9u{%WV>K|Z4t zK!(ZL&(vNFIhaxcnN6vH+(xN|tfaI+zNd6R^5q<5>gt9ZL&-ocr9}5My?B6<4_QMg zgyhJ1!(>iE#!<>3M^P#v=TRCV*HKy_4^cWHuTy#;UsC!YgXNrH+7sK$^kNJp4mpaF zfSgB3L9U~eLmr~kKwhUbLB6E4LAI2myJ=4sWM4`eavH_i+qAiwk_UN|QUH06QViKl zDS?cZqq3>J0y33S3z<)8fh?tTKvq(^AsZ`}Mu(EhIr{fy}0KK$cLtA*(1ENIxaIpXtR|**{EO`H-2ELdYUY64Fj7 zgKVHwLPp4(HJKYBQz)&F1(Z(6GD;6*Eu{~l=Dx`sD>S`OGu=oWqUN=c1VqhZBPocQ zvqs7xYK9uAfvEXtqzR&CpOH3*nrlY7AZlhANkh~;GUDuS+N@@ckvxc+BSs1!YDO3- zhTKLefxJMefP6}+g{ZA<^0Ywqpmac{QMw_QP%@Aul;}j$ix(;RkX}k5WD6MsQ+pCp zKq-TqK&gaWN@;}LN@<0tEnqTtLO!7MKz^b0LH;VeF{NS$m|jex#383r5|GO&Dac)v za)=sBleq@+38e|*N-IoE8)O$s7o>=ihMYx_Kf0%{f2t{YkOwIRkX4jo$TyS{$S|qF zw5I~H52Y5OdTe4^AeT`(AWJFTkQXT#$a+fjK+}te{68jhK4c7~5ONG937JPJgWN%> zguFy)gnU71g~a4vQ+p?5KS~eeG)f=jYD(-N(~D)4IOH8l0`dzb1=(5tHMN&RiYYaa zvnfrGYDydA0ZJF7lahvfL2(W?Z5}NDn%eUqyHg4vQz*rdzf(#eH&QAfk5OtNU6dBc zx0DXZu!L<-H)Jd&138KkmH(wyj>;(ckZMXHq?wY0yhKsuRh}M7C1f+D5i;Ts+rn1J zL`o+lMNt`5=J}L9NIfMc|4YR@L5V}&q$D62imF4E+WJu2o^r@ulp4tKlqSeLN*m-B zN*ClQN*eM$MgBOZuDy?v2ig8G+nxf*L`pH_6iNwX0i^=cM5%>zQd%GxN(Usb$kyHs zNl-G7GD=j+t1+ylQ^6pj1LqltxG;r4`abQ9V@cSwZQ6tf%xr z{K>ZVn6yll8bygiiYRInR7@!)1zAWbhcr`aAS)5JKDCe1TukA0XdFR3z#97rQYs*lBD!OE~dm}d{ynYQ{s?+QxcH%loZ6B zYHKftjH1*)CR3UqWt29^b(Aj1GD;ec8Z!Ms`hs%9gvNbZpfgdZBGU=iV~G=sq!35$%o9K6hbbhBq6nwGRVV}O2|q| zBjgiGE2N*&3EA#A+vXm~UX(t_k(8Ls3Dt{IN*r}mel7c)*DTj1XY9L=xnjqmc z+rl=;&Xg|5BuW}`62*~uquM-|k_WkgQUGb86hl@~N+6pk6_63f+ZNVBiYP6R*^~}Q zJ*6AcPEm7RwRt@yDzi<=kmb!A!H^c30X)fgDj&|Le@|kA)6_!kg+G&+B+dL zC_RuGN+0AYN=)XT?iVEv8Fr%0oPZ=KDaag3Ib;c?2J$+k3DQStgN#1O*3|`>PDw*9 zqBt@mRht_qd5~u)1(3CrV#x2563EDut-S(rIHeX+MrnauPw9X>O6i8YMae)mQKB+y zRWG(X+18#9nMf&woK8tXYA9up$0?PN4=IfhZ-%X_6*8962|0n%1G${i2YG-Jll?*U zqKguT{7gweMxJ78PeG2RltboGY9LD}O^{AX8)Oru3z9$6)|G}#p*XS^sWw+o@*vHW z0!SC77}8HEfy7U>byYy7Q)(fVlorS`N(ZEy(hd2Al7Zx(X6uT|9;LZBQ%WGK zDHV`)lv>CylorUaGi`f1AY&-qkV7dM$P7wUjzp>#b1C_d>nMegdnifBvlMk?RC(T} zR6@R_G(z07Y@1sl!zrDReJDMU>6AXmMU7*1wzNaK1JDy|fDuWzAsf5g=G(!GK zX@xAMsI!7<&%Y@>kRD1OB&W>Q9+RWFDm9W4ha5&pKuReo$kmi`$o-TW$g7klNSe|H z8G5d5k2>F|_UubZLr$kSa#m0=HIzKaN7cb=`Q1TvOV0XczE3%Q)q0(pSa z0qLTsGns1P&y);gmclpe_Kls-rYB_`)B)#hGG95UqZw)O;MFG>n>Jf$2`L8*bZy+mxJ0$%9-*DS$LliXpF1N+4fSDj-{3U~8|1OrW$tj-zxy=2E&L zizyk%a!ORrh^iOwQt}}`QVJp4mD~0tA%&DO$jOvS$fcA<$Q_hcNIRty@?T01WHY4? zvcrY8Jux{)s$L{0amZPe1f-ghf;>nmhpeL1K)#_gL59t>wYNd`p>#n~lr-criX&%D z)#jy?Jjjcb0?2wwF~qsZ)?Nb1r&K@^lv+p$r3F$+>3}p*x*;8u45Wt=m2<7?g)`5# zCm)heDTE{_Nk|E$3{pv{gfvkaAuA}YkPQ@dHK5v)d$Da#4`dRh4^m2r$yr>LT11IM zmQxatwUiXZpKt3@*AObtSV|3KI;9D+fYJtOrgTA8QPPmFDUMtXsJez-Vr$QX>_;hp z%%l`UswgFp`zaNW|4?cn8A=Oen+jWd2V^3p8*(}&16fFk%2kEx#efNt-=5(( zpUGDh0=HI6owLP1bDXP0Lbn;RBP8Os8OeL|WXHK!zEu%*9l7ptoa(%hBKu0_s2kI= zGJ4-k$N56OrZLFPh3qSNzLQde+&m-B#xln_L`n^E<60V=6C`GemI-oIp;}lba=geE zZV}`Pkr^UG+&nq=tC;IV&JfwsEri^LQd_xGAWuMIZi$vUXNAZ)Qfh0r12ON4sBf|U z#a#nQLvr0skj;>7Twl)g()Z|1GaTn#>DRXI5XfC3A8N^i481(Z`G?4MZa!qV$b6}5 zJ9jMPF)5|K0Fvjb>lKyxIg!6=NoZ+^?k1%wrPTIrF=Ud+LM=%n&T%5wiVSz# zRnCbbH;Me!ohN5RnZ3>#BDaa`;C5+ga4ry0-g=LqnaICIM!7LLzT25_hqQULo2Ny_Szo^f96?a!bz7pA1%Noc}B7fDQ&Ms=N{7^Ehw_^V0Zi4(y86xKZ6*J-r8#4-WAY~Hd zG>SR{sZuqR*^v7w3n6b%mT0MSHi@Xc>2K~bExkDpNt@Hs!ZGd|EoR?QBeuJ{c7VJo z{o38#WF$KIY{z+DWDmC=QlE01wOV{RyEx8DXUobQy~pk0&W3C!@`;Y=fb1ypo9vb2 z+#zySQ2nywJkG6!*l`}`HbU$;k8_(KcAUq%Z4f)oB%+RN`@6oJfmBSf$k$q8TB@UJ>!_HCZXRNq zMO4g0cNAi#ADgD?0i1VU7;nL`7n0_@;o4UMoXz8H!jChmHAD`;clsxY@W&PY%SS5lihlh z`WdB;aJwKoR+-Gj?hx7Y2ln(xH&;tG&ylV=daBxwK&hkLivL&YXt(nJl{(sO`F}A} z+}8gWGsW%JQs?|#GOLk4#?6ys!NB%Rb@R1kx8PJ)&3=i|`@5PyQ{7s~v2p}Z^Jl8N z1kx>M*gYikv2HVDy~y5LS|N6>CfzoOovTTA1;ozPUTYb2mWh5Och%j(VyWcOm9@*OBcsuBgk|z_Y_lHxFXZ4l~_Sh&?-;>b7bz`=Dy` zsqT=gRGvC#U-^G#%V?a&ZLxH=>1kH%%*=|NhgmsP@~FQek(H@`l9NT|{-Lh3|0MJN zBv*;3>&$FsJHxZmBr$61WM$c(wgkE=d*da^)Xnkc{OGe~@3# zb(~xOAR{E^&VdrtUFbOK`}xcqWJD4&!%uf}_13A5s=1;1b%v|Tt9>wqS$BpThm4kg zACo+1x&@H^ss}kUb_`?4}SiSX%m{Y@LhUQpDJ!#C&%)V(fWvzFUD9d)&ChtwhXjl1H`q z5_b_|?2)9xtw+q>h^cU!5Mz%U|8QFnW6zcUaF-*-9)B)%+YwWQJeRtih_Oec%iJ!+ z9EX_8+_jJyBI<8yEO0BU&9;~?(xasYqK-&ki2T#7h1@JL-)mU{QAf7TBA2_(kozP? z{Uwge-B!r+sOt)M`ZcDmZq#*!I}`G~$X}#XrCSOKq@_D(DcADJpzTD|wM~_~2r^Mb zoeQem7RafT6_BeaJ&*@Q)LEv=&971I`DD;4N(p46h&mcqxrNu7m^|r?I$~G3qpmY@ zjEFj_SGlEHvip0LTcf4USs*cS>BW_97etNa-Xd4I6Ry{z!DG}ycaoMm=V6JNBryx! zDUdfr4imZBoeud%ME&iOYPS>;lm49~a*aD1vZqL?NR2xWa)!v?MXq&QAax>_i(Kcn zL0%M5UzWVy?SOnMa<#-Payub=$T;07a)a9iIalOXksDoqk?L2SbDv0y$W3l8x=G|?kz3rn zS|fLhY!qp9d$cq-{}TCCw+iJT;Iw;Q{~lsZ~umdHJB0&=>@B_j8_ zDahp_>hHERy9*$9irgx4pW6v(7ikf>-}M_z=J!M%7kR)P0of>`zJb`{CLp0~x3@$d zbQc-nJ>x^}S}oPl9VJE`MIUn4Lv|BUN4AIDjF#-2f7s2vRn^{`qpl&>N#n_=sC#VtC#1h+77+R}PQ3^B@JPg;Lj}?gGfcBHwGN(UNW9 zV{W&J;U3rO_GoEvrb?;JQmWOBHmY7UII~1N`EKLmZVBWcB2kei+*-(uBI;iFUv9IO zI%f%Dmb(?V>21MLebUWnF@4XGv&@sObGwSEj;gb;dIIy58`V-3RcB!p^OT#brNMbx zGH)fdKkde~)H$z1+T1i`y~wr_^NgFgL)Y$PME)xBtlI(EEHYB0-5s^W#6)GU`kTn} z?i9#hMbtCT7u-t7I1zQU`L|mOnJS`=Q5|lR5%%;&caxSXj`NFdzm|sR94R$k>Uz=j z?^Lz-=Gg1i7u~3q>`Zvs&DCN?Y#%B0vRiCK&kc1S_llc@s4LjRB<2-2rKNX}y#sp1 zT`(ZeR2|bgKxT-%>P}c{wuPEeW%7;VPInT--dlCLMOw0%JKZuZbb;8yyljhJRFVJ+=>CB?kit&7Y-10U-`OQtEG34&GR33xt2QT8mX&H>iUnnL5sN? z{aVgw|8Wy{sa}|IRxxk5#agPPw@azZSf(kk=`VTC&^X4co8a z$_wRKD9v}aExkFm)O&8~ZdH4g^Oe+fwZweL%)g0z zDCeEEe-QQeo<638a=gD)emnMDv0e@pW8h^ zRKI?9*F$W-eswbt+ppi;eu(YY@9u4fb?=?egzarjRi0#)PFZW(O zTR3|Mdn2@D=f+?!J|Lz|j#`7g!U3XY<`!Pj0Qp7wHPq`c5}hMssP4^UUMHkRM9s{Y z*RQ3)xkJR0@7Tt?wauzMbdB*4fodwy087aw#OwtR&BF z-a;+CId*%E@irl5D~UNyV#a!f51P8{798)jLF^XX%Ukr2iLqO7f>-viscV$vIYaX7 z=f#$p7`sg;dL0nEO(%IpkC;;XNU8Ir)Pdewhcl30@;& zx)F1N*Nm8TB5G!y=q*FcCJ}Xqc%moWl>b%+;Z3qSDKq>euT97F=2%I28%!SVJ12Xa zv@CYi@$gM)^U2JJ^u+)YLdvH-{rZD zSE;4JDHhpY|m#lSIzCBsD)dG(NMMfMcA(OU&sEOLNItylQ0*%pt9Octs0QjiXjX(IJr z3FIx2Q$%j@O0`r+KM_&;MT0k6OI7qo5w%}5com4*qRzzJ>Qy3Uq=<^S)mvm@^n4Cw zMm2hAE#{iPRO-6j8}*!OVfLE;4(=)YOP=#3CM#+$xLD*)Z@MmJ&YqWxEcIq;F;@;M zW~tW%v3c(D`m`)|4wTFbCFX7~+OBHP-e26~jnIm3*IJ3QbgU^b$DZ6Rhb){Geq`~m>0cC zkiSD-_NHj5i!Kn^Phwv2+O@23ZW5U+cN4F8X~wA zIZfnkuM;vzo^zZdvc~IyX-|>wWKVgYQuHS|^-pr%pX9Rt zCo6{9RfhMyA*;={P)}kmmiD~wCABPc>P6I9_%HQ)%-m4-upJ_wdD9`=NX)Auz1~bMRnFcbD$nO$ zy_W1;O?%B+RyapV%xZ~Ad&{&mI4RWig%^EW)wMW!mdLvj^QAWmQZDk5mYG`WoPQ$b zE3Xf-L}Z=BeB~{A$F%t=k&Pl>d%0_jye{&i$T!|}EsGr`zlmhL4ey$mPeejD$NARV z1lc5_`u?5gyr*JJzqXV;_j@lkK-3X(lb1h0hDx3vy-Fj|EpIVbj6ZwrkP(#J_jTsz z1QB%&`Lj0xG6gZecncsi5%Y_;L`$7BTSOg^e&u|gE27R;{gkUk)N`b)+$y53V6*bC zKgp|qlD9>MOTV(EdPH^|D8XALjx+ub@{`1<6?vB8+IqjYR`+5d_sV{6y_ViVc9p8% z+kn2?RjPik4>9Wbn0oU6o9A?!F|=Bf5o1@WHhcMqvFppfdvV05 zRjU1^7r%QG5Mx)I9e)yH)GC#Var|P$*fr=JKZzK%x^$?-J) zemP?7I<@ClAV#fZsTj{+h#0$-eZK}`x3cdqg4mTT->*j=yOQPmO^C58S%Kez7`u`c z_{$MvSF%FC9Wiz#EA%@NV^^{weivfwN>;>Qix|5~74_F6rf8u#`bGT=V(co_AiobW zc9m+7?|-1Sa(0z-us=jgc9nCmpNAMb!?*B9Kv2Q;Bx2MWnOY|r>ZcH+*2qqfJVX6b#MssUE&bVuQEOx+ z60@aWff&1gZRIb4*f#{W@|(3(Mb)$X^QF{Qeyf(1Id+eW`Rh%o9J^P>d>KIbZzcCZ zD=UJDl1J^iSvf*P?cFhdgU+*1ueqrA3Sxf#M`~N#;+!Ed>iDy@U#}(m9@;Q}iIzI& zVu`s#@(lBvwV0!*I_v$#FI=nlTzv#kPlR&)B?Dxkl-kxG@?RBWo@d@9vb~?Lr8;`E zWLC$q9sCJe7DkVrAy4A9OwzK_vG2F+;3u`LaBNR^@Jk`Kr#tvvC}qcR2Y=qjs`e^p zsnn&Of$ZRq{hyIXC^Oe7S&`ErqR#J4}YGP>{ZG*f58AzGjp6@GeEYL>%;Nfcg~SKIiB2& z|3L`keZm|T&4DQa~{&7VTbQjrVgT7oiEy-&Ndl*)>IFC{DX-FQl1-;K|TT6cO( z?j5r77-WCe{=CR&scRxdl`0UKM0rc(0Fi?!Ux^$llA!z|a>z1UgD;Oeuzgk+DmA{DGATo_H zJBi#XGTl$a*xEE=r1&N@yM3)7ip=A&X8lBdaj=G8?{^&Es)I1q}0iN z6XXz)C$ucnlKr*C48I*>`#!_(Fv4G3%u zLDY(|8N>CEb(DTc&Jr7w`?cxC4wSKwgDFLj(Iit`p|_X~cXaqRu<>{Y_fTop|8Om6JdH8&!LQvr%G( zh*bEcke?uz`t!8ZIpLi-&NdRWz|YH=Qrn5BJXiP=wA49cMRpdc^vkvM<{T*BxYZctNc=kT2WVWwOo0>`4Y}T51*wPJ;IG$` zy@tHW-=M`D`4dvtP5y-MRC`uB_MPNfzZ7E61$BP2mhAJfI=>S!4@q4|NS-=>E#w)I zq{w1_$oDF9_Nt)4&ovT#MPg=1OoN|rdBG?F<)D>(ux8jasUlIHbkT z{n3<4h}24{hy5ZgRnAP2+e9Aqo3$)wC%DF{EJx_Sj zZ`V@iG>fR`>QDN85cQ1cIVts&J;x2T*Wqmxd$!6-o8(c~KhH2`REgv4DpzP(885Q? zA7m9uJ-?Rn`B(k=4JA7q`#Ym~bsk1F-XA4J7;{XsT}tf4%HQr&+LRq7)vL+!}_k77qY zD|Y0w^5lh%^P}YHVJW*UveJRRXXQi4CoJ_7WF2K#li3!ZQVJmJDN`VyQO<|-QfeTd zTM1f3)EK7!AZj$eqO?m)zsNU#5LN0s$~zLHO8xK$Q6v8|Wc7B< zX37?GZxN+koU9ND~))8JT(d?43Mow{9uX} zb8h;ZNF-RMr8md6XN#cdSF?BjC~Yp5m@R_hej~x%InJ>nLxSnQ8OaryAu=?m-E3qJ z#B3E5{H~-o$M!20^f>A@m^$YuiJ2v(whjt&l=SADjAhxG}30kz&Ij2ggxl$@O zSPq#lvOr{;pc8UEWZPgZqzSTJkbyiYQZ1$Of_}&cknMx0Yg+idh-%^RU<737J*L!O zgE(Y25fw8cm;^ZlF*^h$S{j^FL~f9n9fJh}8aWqoKVgM>Q~si z1sO=0;v(4@AZW3COc3wMS44SuLVQV_cBb zlD$S6ACwFbwZ>5pbQ+1;6_&k%E-h72`#X-kg0)(*@4W3DtVfJmtw>8k4)oKRN9f>BzkqQ8i!JJ$Vz0>p&(;_f&oM9elKm#F*Ypa?OeL_*24 ze=r3x2Z#*OA{EJhD}!kwe-W7&q;yR7uI->;-T?WFoMjFQmKfoiga-%BT2>4yl|1TM z)4@RtX0BRKdx72>g}3M%%Qnr)IB3@~S36fr%&{Uz2K`#(_nsmtk)whUgG>wW6RDHuKSu|(kf%h> zkeDe!BjiPqpJe2Z36?>+MbvxdQ-kGNvUh*S2JKqR>{Z+A*q~F(im2T>$zT=4j$tzB zg4peq4AvNNY~Pc?28fz1s;9>VvB9brD;zr-(}G+r)y_B4!fA5EJ|5$cXYET53C8gBfeOfTZmJ(63_p~6TCEMoH?T8JvS0GujS0GtgAbHe% zQ;97VTrG0H)RmRDO5|-Zkuw={i^L3{kc)!ldQ`LT zc+3mhwU{?&-j+P`f)!eN2ib9+7p#KVah?}+L+m(T9P}8;vEzJkupVN^`I2A*#E$c& z!6t|u=gWdVh#ltzK|jQf^FIS;sG6C*Id+^c4}6Fn=PQEf08!&y6%2vcQN1e2h1gMD z7>t0}QN21C1+k-A9gKz8QN1RZ0I^%JCMeXBy|27BDAJNWpI#f3n^J@97+x1tKBGI`WCRWbEJ%K%Y((=EZ+n2Awaxm)Dcpm2bw{p+@%8)CQnk|4FUDP_m` z&Y(t%Tpvn%)O=nVv_b4R-xZ`$%FcwQpdVsq!reh^n8|Fn={>$&| zYVU3imS|a#bDD_i>3u<~mfjq@P4BmR6Q2@4U?rF%rPfKC9|$(-Qf4cEA<_~||BGr* z?;!hZ`N3e3ksMp0{0iV(DfLj0fh>^BeIgGBeUKYOeivC5__->xsVj`+IFAG= zEoSe|7kNCW)zX`Dx0E_U`WV`2ua6;W^CJRS5vHi(>{W73dcMNZMO z!AMT@0Xb7^@wd@E)pCJITTlWyY=+}hh&&Ul9UxUA&jx8NRZi{$@=GO==YpbbRh}wm zcab_RvmpnH+%3``tcM&S@`T9qL3}$?O10-Dkr#p<$O$5Eh;#(<863%6=ah)75qU8v zfT$LJD)Mqrq(#0#Au->Gyb>%y%q1efio6=gr*d?j8z8R*2`%yrL?jZG862b#^MuH@ zBCCQj#JnytTI7wOSxfdw`|4nsmg=ZI0;~=?Aod8bI#>l+CwbI$=9|G9h~Hw~40$u? zfs7VWFRg4vNCF)^S>1g8LoP2=GbH%(=m_&XY@5ScIXzaXKd zH^;6eeG)8!*fp~C!7`MpmQs~cYJJeDWwCRI$gLuu1sRmGYZJXe$4;irc1`N@Aa`dY zb|q^=FjI@!Pg^9bqbe^gy-|QCG`91!>4`BI<44z96F|d;Ix1=+jc|>@P9B zlIQ0jI@0vi9+7?x3bdH*uGUlfgW>_Aj*$I9=>SpZg5QD#14OM!{T?(9kd0DTPU!EV z>dMY}Kg`uq%{3`M909RwQhpdmDLXTRaIBW>I(`sN(2`y43c`db#hDp~Ga+`(E(~iS zcFisl=8e)V37~Rc? z%Cnuwu&@!LR%XYD`pc$ndaPOPzD8#LN&G5oREdiku~~Q`iUTfaHhrQ7P36eOIE^5O)qo zX=#YQFEMka)X1^0l?u*`^)D>164OpS{7=_UQv$^7ir1vapS{!BRu1e z4;!^)>naGFwU|BbUddb#rj2k-eBUsmr7CLQaN9TRM~q!1-!JsXsa}|0fU5PT{lb`* z>gY)6#lIwTVVDOg6nRF=D2V;7;{M@S+)hlPllDy7spWn!2>%y}Z}jl_xJ z6vR{`=74ZIVwwtNm{C%Ezg#Bs3r5EVQPT9rKJ+`tn@;y+8-7! zgRF!c9SU}hD#)n;=(>B z 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 diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets deleted file mode 100644 index f864982..0000000 --- a/.nuget/NuGet.targets +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - false - - - false - - - true - - - false - - - - - - - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) - - - - - $(SolutionDir).nuget - packages.config - - - - - $(NuGetToolsPath)\NuGet.exe - @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 $(NuGetExePath) - - $(TargetDir.Trim('\\')) - - -RequireConsent - -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - - - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index a99d55c..13f4a5a 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -11,7 +11,6 @@ v4.0 512 ..\ - true true @@ -184,7 +183,6 @@ - - \ No newline at end of file + + diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index a19ea39..b82adfa 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -11,7 +11,6 @@ v4.0 512 ..\ - true true @@ -64,7 +63,6 @@ - - \ No newline at end of file + + diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index 06038b1..ad6b183 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -11,7 +11,6 @@ v4.0 512 ..\ - true true @@ -87,7 +86,6 @@ - - \ No newline at end of file + + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 5f24f8f..def0123 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}" EndProject @@ -60,13 +60,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegrate EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Components", "Raspberry.IO.Components\Raspberry.IO.Components.csproj", "{8388CFCA-E3DB-43F7-B049-2CB195211CE8}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE3E-2730-4A56-9C64-0A58E00A5CEE}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}" diff --git a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj index b3a8d46..5eca5ac 100644 --- a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj +++ b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj @@ -12,7 +12,6 @@ v4.0 512 ..\..\ - true AnyCPU @@ -73,13 +72,6 @@ - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 077a9a8..06b3452 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -13,7 +13,6 @@ 512 ..\ - true x86 @@ -97,7 +96,6 @@ - - \ No newline at end of file + + diff --git a/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj index ef2675b..a242b51 100644 --- a/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj +++ b/Tests/Test.Gpio.MCP23008/Test.Gpio.MCP23008.csproj @@ -12,7 +12,6 @@ v4.0 512 ..\..\ - true AnyCPU @@ -62,13 +61,6 @@ - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj index b1d0c43..55a85e9 100644 --- a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj +++ b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj @@ -13,7 +13,6 @@ 512 ..\..\ - true x86 @@ -93,13 +92,6 @@ - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index e02c8f7..6c4ec85 100644 --- a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -12,7 +12,6 @@ v4.0 512 ..\ - true AnyCPU @@ -81,7 +80,6 @@ - - \ No newline at end of file + + diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index fcbe965..dd1f518 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -13,7 +13,6 @@ 512 ..\..\ - true true @@ -84,7 +83,6 @@ - - \ No newline at end of file + + diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index b79eb0a..51abfdc 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -13,7 +13,6 @@ 512 ..\..\ - true true @@ -76,7 +75,6 @@ - - \ No newline at end of file + + diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index 330dc7a..e6ac4d7 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -12,7 +12,6 @@ v4.0 512 ..\..\ - true @@ -80,7 +79,6 @@ - - \ No newline at end of file + + diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index c1e5e2c..058c7ff 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -13,7 +13,6 @@ 512 ..\..\ - true true @@ -66,7 +65,6 @@ - - \ No newline at end of file + + diff --git a/packages/repositories.config b/packages/repositories.config deleted file mode 100644 index 265b6d7..0000000 --- a/packages/repositories.config +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 68ae10ca1394e4893cff92ebea1c13f8b7933c7b Mon Sep 17 00:00:00 2001 From: neutmute Date: Sun, 23 Oct 2016 21:13:18 +1100 Subject: [PATCH 224/227] command line build scripts --- build.cmd | 2 ++ build.common.ps1 | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ build.ps1 | 43 +++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 build.cmd create mode 100644 build.common.ps1 create mode 100644 build.ps1 diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..76266c2 --- /dev/null +++ b/build.cmd @@ -0,0 +1,2 @@ +powershell -f build.ps1 -configuration release +powershell -f build.ps1 -configuration debug \ No newline at end of file diff --git a/build.common.ps1 b/build.common.ps1 new file mode 100644 index 0000000..fd47175 --- /dev/null +++ b/build.common.ps1 @@ -0,0 +1,90 @@ +$Script:UseWriteHost = $true + +if(!$Global:ColorScheme) { + $Global:ColorScheme = @{ + "Banner"=[ConsoleColor]::Cyan + "RuntimeName"=[ConsoleColor]::Yellow + "Help_Header"=[ConsoleColor]::Yellow + "Help_Switch"=[ConsoleColor]::Green + "Help_Argument"=[ConsoleColor]::Cyan + "Help_Optional"=[ConsoleColor]::Gray + "Help_Command"=[ConsoleColor]::DarkYellow + "Help_Executable"=[ConsoleColor]::DarkYellow + "ParameterName"=[ConsoleColor]::Cyan + "Warning" = [ConsoleColor]::Yellow + } +} + +function _WriteOut { + param( + [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$true)][string]$msg, + [Parameter(Mandatory=$false)][ConsoleColor]$ForegroundColor, + [Parameter(Mandatory=$false)][ConsoleColor]$BackgroundColor, + [Parameter(Mandatory=$false)][switch]$NoNewLine) + + if($__TestWriteTo) { + $cur = Get-Variable -Name $__TestWriteTo -ValueOnly -Scope Global -ErrorAction SilentlyContinue + $val = $cur + "$msg" + if(!$NoNewLine) { + $val += [Environment]::NewLine + } + Set-Variable -Name $__TestWriteTo -Value $val -Scope Global -Force + return + } + + if(!$Script:UseWriteHost) { + if(!$msg) { + $msg = "" + } + if($NoNewLine) { + [Console]::Write($msg) + } else { + [Console]::WriteLine($msg) + } + } + else { + try { + if(!$ForegroundColor) { + $ForegroundColor = $host.UI.RawUI.ForegroundColor + } + if(!$BackgroundColor) { + $BackgroundColor = $host.UI.RawUI.BackgroundColor + } + + Write-Host $msg -ForegroundColor:$ForegroundColor -BackgroundColor:$BackgroundColor -NoNewLine:$NoNewLine + } catch { + $Script:UseWriteHost = $false + _WriteOut $msg + } + } +} + +function _WriteConfig{ +param( + [Parameter(Mandatory=$true,Position=0)]$name, + [Parameter(Mandatory=$true,Position=1)]$value) + + _WriteOut -NoNewline -ForegroundColor $Global:ColorScheme.ParameterName "${name}: " + _WriteOut "$value" + +} + +function _DownloadNuget{ +param( + [Parameter(Mandatory=$true,Position=0)]$rootPath) + +$sourceNugetExe = "http://nuget.org/nuget.exe" +$targetNugetExe = "$rootPath\nuget.exe" + + +if(!(Test-Path $targetNugetExe )){ + _WriteOut "Downloading nuget to $targetNugetExe" + Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe +} +else{ + # _WriteOut "nuget.exe is already present" +} + +Set-Alias nuget $targetNugetExe -Scope Global + +} \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..e9fb1da --- /dev/null +++ b/build.ps1 @@ -0,0 +1,43 @@ +param( + [string]$configuration = "Release" +) + +. ".\build.common.ps1" + +$solutionName = "RaspberrySharp.IO" + +function init { + # Initialization + $global:rootFolder = Split-Path -parent $script:MyInvocation.MyCommand.Path + $global:rootFolder = Join-Path $rootFolder . + $global:packagesFolder = Join-Path $rootFolder packages + $global:outputFolder = Join-Path $rootFolder _artifacts + $global:msbuild = "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" + + _WriteOut -ForegroundColor $ColorScheme.Banner "-= $solutionName Build =-" + _WriteConfig "rootFolder" $rootFolder +} + +function restorePackages{ + _WriteOut -ForegroundColor $ColorScheme.Banner "nuget restore" + + New-Item -Force -ItemType directory -Path $packagesFolder + _DownloadNuget $packagesFolder + nuget restore +} + +function buildSolution{ + + _WriteOut -ForegroundColor $ColorScheme.Banner "Build Solution" + & $msbuild "$rootFolder\$solutionName.sln" /p:Configuration=$configuration + +} + + +init + +restorePackages + +buildSolution + +Write-Host "Build $configuration complete" \ No newline at end of file From 1c040f077aec8e185ae8e0f595c5a577b2efa12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bilgehan=20Zeki=20=C3=96ZAYTA=C3=87?= Date: Mon, 31 Oct 2016 16:26:41 +0300 Subject: [PATCH 225/227] * Update and Fix Nuget References Update reference path to "$(SolutionDir)packages\" Update Nuget packages to working lastest version: - FakeItEasy 1.25.3 - FluentAssertions 4.6.3 - UnitsNet 3.46.1.0 --- .../Raspberry.IO.Components.csproj | 13 +++++------ Raspberry.IO.Components/packages.config | 2 +- .../Raspberry.IO.GeneralPurpose.csproj | 5 ++--- ...Raspberry.IO.InterIntegratedCircuit.csproj | 5 ++--- ...pberry.IO.SerialPeripheralInterface.csproj | 5 ++--- Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj | 9 ++++---- Tests/Test.Gpio.DHT11/packages.config | 2 +- .../Test.Gpio.Ds1307/Test.Gpio.Ds1307.csproj | 1 - .../Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 9 ++++---- Tests/Test.Gpio.HCSR04/packages.config | 2 +- .../Test.Gpio.MCP3008.csproj | 7 +++--- Tests/Test.Gpio.MCP3008/packages.config | 2 +- .../Test.Gpio.Pca9685.csproj | 13 +++++------ Tests/Test.Gpio.Pca9685/packages.config | 2 +- .../Tests.Raspberry.IO.Components.csproj | 20 +++++++++-------- .../packages.config | 4 ++-- .../Tests.Raspberry.IO.Interop.csproj | 20 +++++++++-------- .../packages.config | 4 ++-- ...pberry.IO.SerialPeripheralInterface.csproj | 22 ++++++++++--------- .../packages.config | 4 ++-- .../Tests.Raspberry.IO.csproj | 13 +++++------ UnitTests/Tests.Raspberry.IO/packages.config | 4 ++-- 22 files changed, 82 insertions(+), 86 deletions(-) diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 13f4a5a..e875fb8 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -31,20 +31,20 @@ - ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True - ..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll + $(SolutionDir)packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll - ..\packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll + $(SolutionDir)packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll - - ..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + + $(SolutionDir)packages\UnitsNet.3.46.1\lib\net35\UnitsNet.dll True @@ -193,5 +193,4 @@ - - + \ No newline at end of file diff --git a/Raspberry.IO.Components/packages.config b/Raspberry.IO.Components/packages.config index 2025ba4..5b70f76 100644 --- a/Raspberry.IO.Components/packages.config +++ b/Raspberry.IO.Components/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 3d5ef47..cabdaa4 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -33,7 +33,7 @@ - ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True @@ -103,5 +103,4 @@ --> - - + \ No newline at end of file diff --git a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj index b82adfa..2d629a4 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj +++ b/Raspberry.IO.InterIntegratedCircuit/Raspberry.IO.InterIntegratedCircuit.csproj @@ -33,7 +33,7 @@ - ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True @@ -70,5 +70,4 @@ --> - - + \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index ad6b183..13fa724 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -33,7 +33,7 @@ - ..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True @@ -93,5 +93,4 @@ --> - - + \ No newline at end of file diff --git a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj index 5eca5ac..de43d32 100644 --- a/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj +++ b/Tests/Test.Gpio.DHT11/Test.Gpio.DHT11.csproj @@ -34,7 +34,7 @@ - ..\..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True @@ -45,8 +45,8 @@ - - ..\..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + + $(SolutionDir)packages\UnitsNet.3.46.1\lib\net35\UnitsNet.dll True @@ -79,5 +79,4 @@ --> - - + \ No newline at end of file diff --git a/Tests/Test.Gpio.DHT11/packages.config b/Tests/Test.Gpio.DHT11/packages.config index 03e8cfb..67e0cf0 100644 --- a/Tests/Test.Gpio.DHT11/packages.config +++ b/Tests/Test.Gpio.DHT11/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Tests/Test.Gpio.Ds1307/Test.Gpio.Ds1307.csproj b/Tests/Test.Gpio.Ds1307/Test.Gpio.Ds1307.csproj index 27d2dc1..81f8e63 100644 --- a/Tests/Test.Gpio.Ds1307/Test.Gpio.Ds1307.csproj +++ b/Tests/Test.Gpio.Ds1307/Test.Gpio.Ds1307.csproj @@ -40,7 +40,6 @@ - diff --git a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 06b3452..7709dd7 100644 --- a/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Tests/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -56,13 +56,13 @@ - ..\..\packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll + $(SolutionDir)packages\Raspberry.System.2.1\lib\net40\Raspberry.System.dll True - - ..\..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + + $(SolutionDir)packages\UnitsNet.3.46.1\lib\net35\UnitsNet.dll True @@ -103,5 +103,4 @@ --> - - + \ No newline at end of file diff --git a/Tests/Test.Gpio.HCSR04/packages.config b/Tests/Test.Gpio.HCSR04/packages.config index 03e8cfb..67e0cf0 100644 --- a/Tests/Test.Gpio.HCSR04/packages.config +++ b/Tests/Test.Gpio.HCSR04/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj index 55a85e9..c28ab36 100644 --- a/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj +++ b/Tests/Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj @@ -57,8 +57,8 @@ - - ..\..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + + $(SolutionDir)packages\UnitsNet.3.46.1\lib\net35\UnitsNet.dll True @@ -99,5 +99,4 @@ --> - - + \ No newline at end of file diff --git a/Tests/Test.Gpio.MCP3008/packages.config b/Tests/Test.Gpio.MCP3008/packages.config index e7d26fb..b4e59a6 100644 --- a/Tests/Test.Gpio.MCP3008/packages.config +++ b/Tests/Test.Gpio.MCP3008/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index 6c4ec85..c65a4a2 100644 --- a/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Tests/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -34,20 +34,20 @@ - ..\..\packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll + $(SolutionDir)packages\Common.Logging.3.3.1\lib\net40\Common.Logging.dll True - ..\..\packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll + $(SolutionDir)packages\Common.Logging.Core.3.3.1\lib\net40\Common.Logging.Core.dll True - ..\..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll + $(SolutionDir)packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll - - ..\..\packages\UnitsNet.3.34.0\lib\net35\UnitsNet.dll + + $(SolutionDir)packages\UnitsNet.3.46.1\lib\net35\UnitsNet.dll True @@ -87,5 +87,4 @@ --> - - + \ No newline at end of file diff --git a/Tests/Test.Gpio.Pca9685/packages.config b/Tests/Test.Gpio.Pca9685/packages.config index 407e739..c717648 100644 --- a/Tests/Test.Gpio.Pca9685/packages.config +++ b/Tests/Test.Gpio.Pca9685/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj index dd1f518..418273e 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -32,17 +32,20 @@ 4 - - ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll + + $(SolutionDir)packages\FakeItEasy.1.25.3\lib\net40\FakeItEasy.dll + True - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.dll + True - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.Core.dll + True - ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + $(SolutionDir)packages\NUnit.2.6.4\lib\nunit.framework.dll True @@ -90,5 +93,4 @@ --> - - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/packages.config b/UnitTests/Tests.Raspberry.IO.Components/packages.config index 1191330..3c2106d 100644 --- a/UnitTests/Tests.Raspberry.IO.Components/packages.config +++ b/UnitTests/Tests.Raspberry.IO.Components/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj index 51abfdc..cd88ef2 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -32,17 +32,20 @@ 4 - - ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll + + $(SolutionDir)packages\FakeItEasy.1.25.3\lib\net40\FakeItEasy.dll + True - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.dll + True - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.Core.dll + True - ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + $(SolutionDir)packages\NUnit.2.6.4\lib\nunit.framework.dll True @@ -82,5 +85,4 @@ --> - - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/packages.config b/UnitTests/Tests.Raspberry.IO.Interop/packages.config index 1191330..3c2106d 100644 --- a/UnitTests/Tests.Raspberry.IO.Interop/packages.config +++ b/UnitTests/Tests.Raspberry.IO.Interop/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj index e6ac4d7..12ff3b6 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -34,14 +34,20 @@ false - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.dll + + $(SolutionDir)packages\FakeItEasy.1.25.3\lib\net40\FakeItEasy.dll + True - - ..\..\packages\FluentAssertions.3.3.0\lib\net40\FluentAssertions.Core.dll + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.dll + True + + + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.Core.dll + True - ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + $(SolutionDir)packages\NUnit.2.6.4\lib\nunit.framework.dll True @@ -51,9 +57,6 @@ - - ..\..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll - @@ -86,5 +89,4 @@ --> - - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config index 1191330..3c2106d 100644 --- a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj index 058c7ff..e213af9 100644 --- a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -32,20 +32,20 @@ 4 - - ..\..\packages\FakeItEasy.2.0.0\lib\net40\FakeItEasy.dll + + $(SolutionDir)packages\FakeItEasy.1.25.3\lib\net40\FakeItEasy.dll True - ..\..\packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.dll + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.dll True - ..\..\packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.Core.dll + $(SolutionDir)packages\FluentAssertions.4.6.3\lib\net40\FluentAssertions.Core.dll True - ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + $(SolutionDir)packages\NUnit.2.6.4\lib\nunit.framework.dll True @@ -72,5 +72,4 @@ --> - - + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/packages.config b/UnitTests/Tests.Raspberry.IO/packages.config index 1191330..3c2106d 100644 --- a/UnitTests/Tests.Raspberry.IO/packages.config +++ b/UnitTests/Tests.Raspberry.IO/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file From ff2debfae4f46ba97c6b6de8d6698fc9554fc491 Mon Sep 17 00:00:00 2001 From: Tanson Date: Sat, 24 Dec 2016 02:32:23 +0800 Subject: [PATCH 226/227] add BH1750 Sensor --- .../Sensors/Light/BH1750Connection.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Raspberry.IO.Components/Sensors/Light/BH1750Connection.cs diff --git a/Raspberry.IO.Components/Sensors/Light/BH1750Connection.cs b/Raspberry.IO.Components/Sensors/Light/BH1750Connection.cs new file mode 100644 index 0000000..d840259 --- /dev/null +++ b/Raspberry.IO.Components/Sensors/Light/BH1750Connection.cs @@ -0,0 +1,53 @@ +using Raspberry.IO.InterIntegratedCircuit; +using Raspberry.Timers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO.Components.Sensors.Light +{ + namespace RPI.Sensor.Sensors.Light + { + public class BH1750Connection + { + public I2cDeviceConnection Connection { get; set; } + public BH1750Connection(I2cDeviceConnection connection) + { + Connection = connection; + } + + public void SetOff() + { + Connection.Write(0x00); + } + public void SetOn() + { + Connection.Write(0x01); + } + public void Reset() + { + Connection.Write(0x07); + } + + public double GetData() + { + Connection.Write(0x10); + HighResolutionTimer.Sleep(TimeSpanUtility.FromMicroseconds(150 * 1000)); + byte[] readBuf = Connection.Read(2); + + var valf = readBuf[0] << 8; + valf |= readBuf[1]; + return valf / 1.2 * (69 / 69) / 1; + + // var valf = ((readBuf[0] << 8) | readBuf[1]) / 1.2; + // return valf; + + // return Math.Round(valf / (2 * 1.2), 2); + + } + + } + } + +} From bb25fcffcf35cd9fc2b3e1b2215fc02df02626d9 Mon Sep 17 00:00:00 2001 From: lkroliko Date: Sat, 7 Jan 2017 22:59:49 +0100 Subject: [PATCH 227/227] Add more PWM channels to PCA9685 hello :) PCA9685 have 16 channels https://www.adafruit.com/product/815 --- Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs b/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs index 696d332..0104072 100644 --- a/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs +++ b/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.Components.Controllers.Pca9685 +namespace Raspberry.IO.Components.Controllers.Pca9685 { ///

/// Denotes available PWM channels @@ -17,5 +17,9 @@ public enum PwmChannel C9 = 9, C10 = 10, C11 = 11, + C12 = 12, + C13 = 13, + C14 = 14, + C15 = 15 } -} \ No newline at end of file +}
diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs index 2f5f576..fc9f72d 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs @@ -41,8 +41,7 @@ void IDisposable.Dispose() public decimal Read(Mcp3008Channel channel) { - spiConnection.SelectSlave(); - try + using(spiConnection.SelectSlave()) { // Start bit spiConnection.Write(true); @@ -61,10 +60,6 @@ public decimal Read(Mcp3008Channel channel) return data*scale/1024m; } - finally - { - spiConnection.DeselectSlave(); - } } public void Close() diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs index 6cd019c..298c40b 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs @@ -1,6 +1,10 @@ +#region References + using System; using Raspberry.IO.GeneralPurpose; +#endregion + namespace Raspberry.IO.SerialPeripheralInterface.Components { /// @@ -16,6 +20,8 @@ public class Mcp4822SpiConnection : IDisposable #endregion + #region Instance Management + public Mcp4822SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin mosi, decimal scale) { spiConnection = new SpiConnection(clock, ss, null, mosi, Endianness.LittleEndian); @@ -27,20 +33,23 @@ void IDisposable.Dispose() Close(); } - private void Close() + #endregion + + #region Methods + + public void Close() { spiConnection.Close(); } public void Write(Mcp4822Channel channel, decimal data) { - spiConnection.SelectSlave(); - try + using (spiConnection.SelectSlave()) { var value = (uint) (data*4096m/scale); if (value > 0xFFF) value = 0xFFF; - + // Set active channel spiConnection.Write(channel == Mcp4822Channel.ChannelB); @@ -56,10 +65,8 @@ public void Write(Mcp4822Channel channel, decimal data) // Write 12 bits data (some lower bits are ignored by MCP4802/4812 spiConnection.Write(value, 12); } - finally - { - spiConnection.DeselectSlave(); - } } + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index 25cbd8f..5a77321 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -47,6 +47,7 @@ + diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs index 4c4a50b..97e8538 100644 --- a/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiConnection.cs @@ -69,12 +69,13 @@ public void Close() driver.Release(miso.Value); } - public void SelectSlave() + public SpiSlaveSelection SelectSlave() { driver.Write(ss, false); + return new SpiSlaveSelection(this); } - - public void DeselectSlave() + + internal void DeselectSlave() { driver.Write(ss, true); } diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiSlaveSelection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiSlaveSelection.cs new file mode 100644 index 0000000..ff55731 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/SpiSlaveSelection.cs @@ -0,0 +1,31 @@ +#region References + +using System; + +#endregion + +namespace Raspberry.IO.SerialPeripheralInterface +{ + public class SpiSlaveSelection : IDisposable + { + #region Fields + + private readonly SpiConnection connection; + + #endregion + + #region Instance Management + + internal SpiSlaveSelection(SpiConnection connection) + { + this.connection = connection; + } + + void IDisposable.Dispose() + { + connection.DeselectSlave(); + } + + #endregion + } +} \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index ba2df1e..a88d6c2 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.SerialPeripher EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.MCP4822", "Gpio.Test.MCP4822\Gpio.Test.MCP4822.csproj", "{54075457-7C1D-4C8F-BE7D-CFCA34F11228}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpio.Test.HDD44780", "Gpio.Test.HDD44780\Gpio.Test.HDD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -80,6 +82,16 @@ Global {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|Mixed Platforms.Build.0 = Release|x86 {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|x86.ActiveCfg = Release|x86 {54075457-7C1D-4C8F-BE7D-CFCA34F11228}.Release|x86.Build.0 = Release|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Any CPU.ActiveCfg = Debug|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|x86.ActiveCfg = Debug|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Debug|x86.Build.0 = Debug|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Any CPU.ActiveCfg = Release|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Mixed Platforms.Build.0 = Release|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|x86.ActiveCfg = Release|x86 + {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 1f9e421aaa9dcc3ddecb0462507deab8860cf8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 30 Oct 2012 00:46:58 +0100 Subject: [PATCH 056/227] Updated assemblyinfo.cs --- Gpio.Test.HDD44780/Properties/AssemblyInfo.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs b/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs index e3e3175..76ec5a3 100644 --- a/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs +++ b/Gpio.Test.HDD44780/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -10,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Gpio.Test.HDD44780")] -[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyCopyright("www.raspberry-sharp.org, 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] From 0e9003d1fff7259cdf85655a0d7ddcb992439bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 30 Oct 2012 21:51:03 +0100 Subject: [PATCH 057/227] Added dependency and reference on Raspberry.System Removed equivalent code --- Gpio.Test.Chaser/Board.cs | 139 ----------------- Gpio.Test.Chaser/Gpio.Test.Chaser.csproj | 6 +- Gpio.Test.Chaser/Program.cs | 1 + Gpio.Test.Chaser/packages.config | 4 + Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj | 14 +- Gpio.Test.HDD44780/Hdd44780LcdConnection.cs | 4 +- Gpio.Test.HDD44780/Program.cs | 8 +- Gpio.Test.HDD44780/packages.config | 4 + Gpio.Test.MCP3008/Gpio.Test.MCP3008.csproj | 1 + Gpio.Test.MCP4822/Gpio.Test.MCP4822.csproj | 6 +- Raspberry.IO.GeneralPurpose.nuspec | 6 +- .../Behaviors/PinsBehavior.cs | 2 +- .../FileGpioConnectionDriver.cs | 2 +- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 2 +- Raspberry.IO.GeneralPurpose/Host.cs | 121 -------------- Raspberry.IO.GeneralPurpose/Interop.cs | 3 - .../MemoryGpioConnectionDriver.cs | 2 +- Raspberry.IO.GeneralPurpose/PinMapping.cs | 6 +- .../Raspberry.IO.GeneralPurpose.csproj | 9 +- .../Time/HighResolutionTimer.cs | 135 ---------------- Raspberry.IO.GeneralPurpose/Time/ITimer.cs | 46 ------ .../Time/StandardTimer.cs | 109 ------------- Raspberry.IO.GeneralPurpose/Time/Timer.cs | 44 ------ Raspberry.IO.GeneralPurpose/packages.config | 4 + .../Raspberry.System.1.0.1.nupkg | Bin 0 -> 25430 bytes .../Raspberry.System.1.0.1.nuspec | 27 ++++ .../lib/net40/Raspberry.System.dll | Bin 0 -> 9728 bytes .../lib/net40/Raspberry.System.xml | 147 ++++++++++++++++++ .../lib/net40/libbcm2835.so | Bin 0 -> 30169 bytes packages/repositories.config | 6 + 30 files changed, 229 insertions(+), 629 deletions(-) delete mode 100644 Gpio.Test.Chaser/Board.cs create mode 100644 Gpio.Test.Chaser/packages.config create mode 100644 Gpio.Test.HDD44780/packages.config delete mode 100644 Raspberry.IO.GeneralPurpose/Host.cs delete mode 100644 Raspberry.IO.GeneralPurpose/Time/HighResolutionTimer.cs delete mode 100644 Raspberry.IO.GeneralPurpose/Time/ITimer.cs delete mode 100644 Raspberry.IO.GeneralPurpose/Time/StandardTimer.cs delete mode 100644 Raspberry.IO.GeneralPurpose/Time/Timer.cs create mode 100644 Raspberry.IO.GeneralPurpose/packages.config create mode 100644 packages/Raspberry.System.1.0.1/Raspberry.System.1.0.1.nupkg create mode 100644 packages/Raspberry.System.1.0.1/Raspberry.System.1.0.1.nuspec create mode 100644 packages/Raspberry.System.1.0.1/lib/net40/Raspberry.System.dll create mode 100644 packages/Raspberry.System.1.0.1/lib/net40/Raspberry.System.xml create mode 100644 packages/Raspberry.System.1.0.1/lib/net40/libbcm2835.so create mode 100644 packages/repositories.config diff --git a/Gpio.Test.Chaser/Board.cs b/Gpio.Test.Chaser/Board.cs deleted file mode 100644 index 13d4ad7..0000000 --- a/Gpio.Test.Chaser/Board.cs +++ /dev/null @@ -1,139 +0,0 @@ -#region References - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -#endregion - -namespace Gpio.Test.Chaser -{ - /// - /// Represents the Raspberry Pi mainboard. - /// - internal class Board - { - #region Fields - - private static readonly Lazy board = new Lazy(LoadBoard); - private readonly Dictionary settings; - - private const string raspberryPiProcessor = "BCM2708"; - - #endregion - - #region Instance Management - - private Board(Dictionary settings) - { - this.settings = settings; - } - - #endregion - - #region Properties - - /// - /// Gets the current mainboard configuration. - /// - public static Board Current - { - get { return board.Value; } - } - - /// - /// Gets a value indicating whether this instance is a Raspberry Pi. - /// - /// - /// true if this instance is a Raspberry Pi; otherwise, false. - /// - public bool IsRaspberryPi - { - get { return Processor == raspberryPiProcessor; } - } - - /// - /// Gets the processor. - /// - public string Processor - { - get - { - string hardware; - return settings.TryGetValue("Hardware", out hardware) ? hardware : null; - } - } - - /// - /// Gets the board firmware version. - /// - public int Firmware - { - get - { - string revision; - int firmware; - if (settings.TryGetValue("Revision", out revision) && !string.IsNullOrEmpty(revision) && int.TryParse(revision, out firmware)) - return firmware; - - return 0; - } - } - - /// - /// Gets the board revision. - /// - public int Revision - { - get - { - var firmware = Firmware; - switch (firmware) - { - case 2: - case 3: - return 1; - case 4: - case 5: - case 6: - return 2; - - default: - return 0; - } - } - } - - #endregion - - #region Private Helpers - - private static Board LoadBoard() - { - try - { - const string filePath = "/proc/cpuinfo"; - var settings = File.ReadAllLines(filePath) - .Where(l => !string.IsNullOrEmpty(l)) - .Select(l => - { - var separator = l.IndexOf(':'); - if (separator < 0) - return new KeyValuePair(l, null); - else - return new KeyValuePair(l.Substring(0, separator).Trim(), l.Substring(separator + 1).Trim()); - }) - .ToDictionary(p => p.Key, p => p.Value); - - return new Board(settings); - } - catch - { - return new Board(new Dictionary()); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj index d4fe975..ba2fb26 100644 --- a/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj +++ b/Gpio.Test.Chaser/Gpio.Test.Chaser.csproj @@ -66,11 +66,11 @@ - + @@ -80,7 +80,11 @@ + + ..\packages\Raspberry.System.1.0.1\lib\net40\Raspberry.System.dll + + diff --git a/Gpio.Test.Chaser/Program.cs b/Gpio.Test.Chaser/Program.cs index 37553e1..3b099d3 100644 --- a/Gpio.Test.Chaser/Program.cs +++ b/Gpio.Test.Chaser/Program.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using Raspberry; using Raspberry.IO.GeneralPurpose; using Raspberry.IO.GeneralPurpose.Behaviors; diff --git a/Gpio.Test.Chaser/packages.config b/Gpio.Test.Chaser/packages.config new file mode 100644 index 0000000..39c8cc2 --- /dev/null +++ b/Gpio.Test.Chaser/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj b/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj index d8cd8f9..11095ca 100644 --- a/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj +++ b/Gpio.Test.HDD44780/Gpio.Test.HDD44780.csproj @@ -35,15 +35,12 @@ 4 + + ..\packages\Raspberry.System.1.0.1\lib\net40\Raspberry.System.dll + + - - - - - - - @@ -61,6 +58,9 @@ Raspberry.IO.GeneralPurpose + + + + \ No newline at end of file diff --git a/Raspberry.IO.Display/packages.config b/Raspberry.IO.Display/packages.config new file mode 100644 index 0000000..7846929 --- /dev/null +++ b/Raspberry.IO.Display/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index f474dee..0104d73 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP4822", "Test.G EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HD44780", "Test.Gpio.HD44780\Test.Gpio.HD44780.csproj", "{6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Display", "Raspberry.IO.Display\Raspberry.IO.Display.csproj", "{F3E6F476-7088-4169-8E09-AE19EBE46C0E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -92,6 +94,16 @@ Global {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|Mixed Platforms.Build.0 = Release|x86 {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|x86.ActiveCfg = Release|x86 {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC}.Release|x86.Build.0 = Release|x86 + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Release|Any CPU.Build.0 = Release|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F3E6F476-7088-4169-8E09-AE19EBE46C0E}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Test.Gpio.HD44780/Program.cs b/Test.Gpio.HD44780/Program.cs index 142c2d2..affc29c 100644 --- a/Test.Gpio.HD44780/Program.cs +++ b/Test.Gpio.HD44780/Program.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Net.NetworkInformation; +using Raspberry.IO.Display.Components; using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; @@ -20,7 +21,8 @@ static void Main(string[] args) ScreenHeight = 2, }; - using (var connection = new Hd44780LcdConnection(settings, + using (var connection = new Hd44780LcdConnection( + settings, ConnectorPin.P1Pin22.ToProcessor(), ConnectorPin.P1Pin18.ToProcessor(), diff --git a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index aa650ad..4d6fd84 100644 --- a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -43,18 +43,14 @@ - - - - - - - - + + {F3E6F476-7088-4169-8E09-AE19EBE46C0E} + Raspberry.IO.Display + {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose diff --git a/packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nupkg b/packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..60cd1e329829c20c1072219b11f5b0a565875bf0 GIT binary patch literal 42384 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 literal 0 HcmV?d00001 diff --git a/packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nuspec b/packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nuspec new file mode 100644 index 0000000..c1aa240 --- /dev/null +++ b/packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nuspec @@ -0,0 +1,30 @@ + + + + Raspberry.IO.GeneralPurpose + 1.5.2 + Raspberry.IO.GeneralPurpose + Eric Bézine + Eric Bézine + http://opensource.org/licenses/GPL-2.0 + https://github.com/raspberry-sharp/raspberry-sharp-io/wiki/Raspberry.IO.GeneralPurpose + https://raw.github.com/raspberry-sharp/raspberry-sharp-io/master/Icon.png + true + Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. + + It is an initiative of the Raspberry# Community, aimed at providing tools and information concerning use of Raspberry Pi boards with Mono/.NET framework. + Parts of this work are based on [BCM2835 C library](http://www.open.com.au/mikem/bcm2835/). + + Visit project [Github site](https://github.com/raspberry-sharp/raspberry-sharp-io/) for documentation and samples. + Raspberry.IO.GeneralPurpose is a Mono/.NET assembly providing access to Raspberry Pi GPIO features. + en-US + Raspberry Pi Mono GPIO + + + + + + + + + \ No newline at end of file diff --git a/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.XML b/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.XML new file mode 100644 index 0000000..ee0aa78 --- /dev/null +++ b/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.XML @@ -0,0 +1,1017 @@ + + + + Raspberry.IO.GeneralPurpose + + + + + Represents a connection driver using files. + + + + + Provides an interface for connection drivers. + + + + + Modified the status of a pin. + + The pin. + The pin status. + + + + Reads the status of the specified pin. + + The pin. + The pin status. + + + + Reads the status of the specified pins. + + The pins. + The pins status. + + + + Allocates the specified pin. + + The pin. + The direction. + + + + Releases the specified pin. + + The pin. + + + + Initializes a new instance of the class. + + + + + Modified the status of a pin. + + The pin. + The pin status. + + + + Reads the status of the specified pin. + + The pin. + + The pin status. + + + + + Reads the status of the specified pins. + + The pins. + + The pins status. + + + + + Allocates the specified pin. + + The pin. + The direction. + + + + Represents a simple blink behavior. + + + + + Represents the pins behavior base class. + + + + + Initializes a new instance of the class. + + The configurations. + + + + Gets the first step. + + The first step. + + + + Processes the step. + + The step. + + + + Tries to get the next step. + + The step. + true if the behavior may continue; otherwise behavior will be stopped. + + + + Gets the configurations. + + + + + Gets or sets the interval. + + + The interval. + + + + + Gets the connection. + + + + + Initializes a new instance of the class. + + The configurations. + + + + Gets the first step. + + + The first step. + + + + + Processes the step. + + The step. + + + + Tries to get the next step. + + The step. + + true if the behavior may continue; otherwise behavior will be stopped. + + + + + Gets or sets the number of times the behavior may blink. + + + The number of times the behavior may blink. + + + + + Provides helper methods for mapping pins between processor and connectors + + + + + Convert the specified connector pin to a processor pin. + + The connector pin. + The processor pin. + + + + Convert the specified processor pin to a connector pin. + + The processor pin. + The connector pin. + + + + Provides extension methods for and objects. + + + + + Enumerates the specified pins. + + The pins. + The pins. + + + + Represents a processor pin. + + + + + Represents the configuration of a pin. + + + + + Initializes a new instance of the class. + + The pin. + + + + Gets the pin. + + + + + Gets the direction. + + + + + Gets or sets the name. + + + The name. + + + + + Gets or sets a value indicating whether this is reversed. + + + true if reversed; otherwise, false. + + If set to true, pin value will be enabled when no signal is present, and disabled when a signal is present. + + + + Gets or sets the status changed action. + + + The status changed action. + + + + + Represents a connection to the GPIO pins. + + + + + Initializes a new instance of the class. + + The pins. + + + + Initializes a new instance of the class. + + The pins. + + + + Initializes a new instance of the class. + + The settings. + The pins. + + + + Initializes a new instance of the class. + + The settings. + The pins. + + + + Opens the connection. + + + + + Closes the connection. + + + + + Clears pin attached to this connection. + + + + + Adds the specified pin. + + The pin. + + + + Determines whether the connection contains the specified pin. + + Name of the pin. + + true if the connection contains the specified pin; otherwise, false. + + + + + Determines whether the connection contains the specified pin. + + The pin. + + true if the connection contains the specified pin; otherwise, false. + + + + + Determines whether the connection contains the specified pin. + + The pin. + + true if the connection contains the specified pin; otherwise, false. + + + + + Determines whether the connection contains the specified pin. + + The pin configuration. + + true if the connection contains the specified pin; otherwise, false. + + + + + Removes the specified pin. + + Name of the pin. + + + + Removes the specified pin. + + The pin. + + + + Removes the specified pin. + + The pin. + + + + Removes the specified pin. + + The pin configuration. + + + + Toggles the specified pin. + + Name of the pin. + + + + Toggles the specified pin. + + The pin. + + + + Toggles the specified pin. + + The pin. + + + + Toggles the specified pin. + + The pin configuration. + + + + Blinks the specified pin. + + Name of the pin. + The duration, in millisecond. + + + + Blinks the specified pin. + + The pin. + The duration, in millisecond. + + + + Blinks the specified pin. + + The pin. + The duration, in millisecond. + + + + Blinks the specified pin. + + The pin configuration. + The duration, in millisecond. + + + + Raises the event. + + The instance containing the event data. + + + + Gets a value indicating whether connection is opened. + + + true if connection is opened; otherwise, false. + + + + + Gets or sets the status of the pin having the specified name. + + + + + Gets or sets the status of the specified pin. + + + + + Gets or sets the status of the specified pin. + + + + + Gets or sets the status of the specified pin. + + + + + Gets the pins. + + + + + Occurs when the status of a pin changed. + + + + + Represents a chaser behavior. + + + + + Initializes a new instance of the class. + + The configurations. + + + + Gets the first step. + + + The first step. + + + + + Processes the step. + + The step. + + + + Tries to get the next step. + + The step. + + true if the behavior may continue; otherwise behavior will be stopped. + + + + + Gets or sets a value indicating whether to roundtrip. + + + true if roundtrip is enabled; otherwise, false. + + + + + Gets or sets a value indicating whether this must loop. + + + true if loop is enabled; otherwise, false. + + + + + Gets or sets the width of the enlightned leds. + + + The width. + + + + + Represents a connected pin. + + + + + Toggles this pin. + + + + + Blinks the pin. + + The blink duration, in millisecond. + + + + Gets the configuration. + + + + + Gets or sets a value indicating whether this is enabled. + + + true if enabled; otherwise, false. + + + + + Occurs when pin status changed. + + + + + Represents event arguments related to pin status. + + + + + Gets the configuration. + + + + + Gets a value indicating whether this is enabled. + + + true if enabled; otherwise, false. + + + + + Represents connected pins. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Gets the enumerator. + + The enumerator. + + + + Gets the status of the specified pin. + + + + + Gets the status of the specified pin. + + + + + Gets the status of the specified pin. + + + + + Gets the status of the specified pin. + + + + + Represents a connection driver that uses memory. + + Based on bmc2835_gpio library. + + + + Initializes a new instance of the class. + + + + + Releases unmanaged resources and performs other cleanup operations before the + is reclaimed by garbage collection. + + + + + Modified the status of a pin. + + The pin. + The pin status. + + + + Reads the status of the specified pin. + + The pin. + + The pin status. + + + + + Reads the status of the specified pins. + + The pins. + + The pins status. + + + + + Allocates the specified pin. + + The pin. + The direction. + + + + Represents the direction of a pin. + + + + + Pin is an input pin. + + + + + Pin is an output pin. + + + + + Represents a connector pin. + + + + + Represents configuration of an input pin. + + + + + Initializes a new instance of the class. + + The pin. + + + + Gets the direction. + + + + + Represents the configuration of an input pin acting as a switch. + + + + + Initializes a new instance of the class. + + The pin. + + + + Gets the direction. + + + + + Gets or sets a value indicating whether this is enabled. + + + true if enabled; otherwise, false. + + + + + Provides extension methods for pin configuration. + + + + + Configures the specified pin as an input pin. + + The pin. + The pin configuration. + + + + Configures the specified pin as an output pin. + + The pin. + The pin configuration. + + + + Configures the specified pin as an input pin. + + The pin. + The pin configuration. + + + + Configures the specified pin as an output pin. + + The pin. + The pin configuration. + + + + Configures the specified input pin as a switch. + + The pin. + The pin configuration + + + + Configures an action executed when the pin status changes. + + The configuration type. + The configuration. + The action. + The pin configuration. + + + + Configures the name of the specified pin configuration. + + The configuration type. + The configuration. + The name. + The pin configuration. + + + + Reverts the bit value of the specified pin. + + The configuration type. + The configuration. + The pin configuration. + + + + Indicates the specified pin is enabled on connection. + + The configuration. + The pin configuration. + + + + Indicates the specified pin is disabled on connection. + + The configuration. + The pin configuration. + + + + Indicates the specified pin is enabled on connection. + + The configuration. + The pin configuration. + + + + Indicates the specified pin is disabled on connection. + + The configuration. + The pin configuration. + + + + Represents the configuration of the GPIO connection. + + + + + The default poll interval, in milliseconds. + + + + + Gets or sets the name of the driver type. + + + The name of the driver type. + + + + + Gets or sets the board revision. + + + The board revision. + + + + + Gets or sets the poll interval, in milliseconds. + + + The poll interval, in millisecond. + + + Default value is 50ms. + Values lower than 1ms may be specified on Raspberry Pi using decimal notation. + + + + + Provides extension methods for . + + + + + Starts the specified behavior on the connection. + + The connection. + The behavior. + + + + Stops the specified behavior. + + The connection. + The behavior. + + + + Represents the configuration of an output pin. + + + + + Initializes a new instance of the class. + + The pin. + + + + Gets or sets a value indicating whether this is enabled on connection. + + + true if enabled; otherwise, false. + + + + + Gets the direction. + + + + + Represents settings for . + + + + + Gets the default blink duration, in milliseconds. + + + + + Initializes a new instance of the class. + + + + + Gets or sets a value indicating whether this is opened on initialization. + + + true if opened on initialization; otherwise, false. + + + + + Gets or sets the duration of the blink. + + + The duration of the blink, in milliseconds. + + + + + Gets or sets the driver. + + + The driver. + + + + + Gets or sets the poll interval. + + + The poll interval, in milliseconds. + + + + + Gets the default poll interval, in milliseconds. + + + + + Gets the default driver. + + + + + Represents a pattern behavior. + + + + + Initializes a new instance of the class. + + The configurations. + The patterns. + + + + Initializes a new instance of the class. + + The configurations. + The patterns. + + + + Gets the first step. + + + The first step. + + + + + Processes the step. + + The step. + + + + Tries to get the next step. + + The step. + + true if the behavior may continue; otherwise behavior will be stopped. + + + + + Gets or sets a value indicating whether this must loop. + + + true if loop is enabled; otherwise, false. + + + + + Gets or sets a value indicating whether to roundtrip. + + + true if round-trip is enabled; otherwise, false. + + + + diff --git a/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.dll b/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.dll new file mode 100644 index 0000000000000000000000000000000000000000..b947a59005ca535b72a41fcf19b4d5c932d4886a GIT binary patch literal 32256 zcmeHw3wTu3)%H4P&YW{*k_?$i$b@Sq0y^df;U-wb0O2Me5rTpuVUi3mkmSUf2^SGe zDqf4$3$@<93SPcyYg=t=TdP*6)YjHs?9-cnt;J%kwf)=L`xXCpt$og12=%ky_doyh zKhO6K&U@Bc`?mJlYp=b}J}2Xfi*F_$5gGWt{Wj6(aOF>n;5)-0l0!A057DOsU$6a~ zw*2e0?ORfrSby5toKEz{x)ObTPBzw=jHL(qVyV7Z>&n%!UZ*?RR8|(8=vLjfkZ8H) zqi?)*SDV+`G16;GG@B?32`>EUyA=?__aMHkT?`jp=?zNs=PMn<7jpjisO4&+a``WR zby<~#s!{K1rVpYiHp0oD!$hT!ZMlVL?8#~G#K&@~OD-Gyl7jqA+2l^{UN#Ltn)KDx z8=QP%L>rsZnRFL8(d{4z6W{Il7JOP@kfwC9$3aHcl@8;}bzOmP!Ka02egP|F8`~8h z)=eirUDpB=Vk9&c{wF?{>+ve0U_1(NssW89Y1Gx983p?CIvO*@M;D-8$inFzNbv1H z9b9}gl7nXYT1et!K$oO%18E6em4W4hrMA&%r9TB}y+8d~T%2)`z7n(>Oxr@*Jbc9CgsB!*8vVj+OlcG}Jν)AXuz$F+(AHL4!p6obw~J^WEFhi<|k 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 Dw-FxM literal 0 HcmV?d00001 diff --git a/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/libbcm2835.so b/packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/libbcm2835.so new file mode 100644 index 0000000000000000000000000000000000000000..3b62da41cf7363864afb2aa1078feca3ee3eadd4 GIT binary patch literal 30169 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 literal 0 HcmV?d00001 diff --git a/packages/repositories.config b/packages/repositories.config index 2d92be0..0426e84 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,6 +1,8 @@  + + \ No newline at end of file From e6be593752ba1b107138a97f9f24d9afc773c976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 13 Nov 2012 00:08:54 +0100 Subject: [PATCH 070/227] Fixed MCP4822SpiConnection comments --- .../Components/Mcp4822SpiConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs index 298c40b..061ddf2 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs @@ -8,7 +8,7 @@ namespace Raspberry.IO.SerialPeripheralInterface.Components { /// - /// Represents a SPI connection to a MCP4802/4012/4022 DAC. + /// Represents a SPI connection to a MCP4802/4812/4822 DAC. /// /// See http://ww1.microchip.com/downloads/en/DeviceDoc/22249A.pdf for specifications. public class Mcp4822SpiConnection : IDisposable From edbfd3985c04ff90fed64d4dad7d929013c5197f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Tue, 13 Nov 2012 00:31:07 +0100 Subject: [PATCH 071/227] Improved dependencies --- .../Raspberry.IO.Display.csproj | 15 +- Raspberry.IO.Display/packages.config | 1 - ...pberry.IO.SerialPeripheralInterface.csproj | 13 +- .../SpiConnection.cs | 4 +- .../packages.config | 0 Test.Gpio.HD44780/Program.cs | 30 +- Test.Gpio.HD44780/Test.Gpio.HD44780.csproj | 16 +- .../Raspberry.IO.GeneralPurpose.1.5.2.nupkg | Bin 42384 -> 0 bytes .../Raspberry.IO.GeneralPurpose.1.5.2.nuspec | 30 - .../lib/net40/Raspberry.IO.GeneralPurpose.XML | 1017 ----------------- .../lib/net40/Raspberry.IO.GeneralPurpose.dll | Bin 32256 -> 0 bytes .../lib/net40/libbcm2835.so | Bin 30169 -> 0 bytes packages/repositories.config | 3 +- 13 files changed, 40 insertions(+), 1089 deletions(-) rename {Test.Gpio.HD44780 => Raspberry.IO.SerialPeripheralInterface}/packages.config (100%) delete mode 100644 packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nupkg delete mode 100644 packages/Raspberry.IO.GeneralPurpose.1.5.2/Raspberry.IO.GeneralPurpose.1.5.2.nuspec delete mode 100644 packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.XML delete mode 100644 packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/Raspberry.IO.GeneralPurpose.dll delete mode 100644 packages/Raspberry.IO.GeneralPurpose.1.5.2/lib/net40/libbcm2835.so diff --git a/Raspberry.IO.Display/Raspberry.IO.Display.csproj b/Raspberry.IO.Display/Raspberry.IO.Display.csproj index 4570e30..383560f 100644 --- a/Raspberry.IO.Display/Raspberry.IO.Display.csproj +++ b/Raspberry.IO.Display/Raspberry.IO.Display.csproj @@ -31,20 +31,11 @@ 4 - - ..\packages\Raspberry.IO.GeneralPurpose.1.5.2\lib\net40\Raspberry.IO.GeneralPurpose.dll - ..\packages\Raspberry.System.1.0.4\lib\net40\Raspberry.System.dll - - - - - - @@ -60,6 +51,12 @@ + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + \ No newline at end of file diff --git a/Test.Gpio.HCSR04/app.config b/Test.Gpio.HCSR04/app.config new file mode 100644 index 0000000..e365603 --- /dev/null +++ b/Test.Gpio.HCSR04/app.config @@ -0,0 +1,3 @@ + + + From 04bbf1b813561c408efffb272c763744d6cce09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 20 Feb 2013 23:16:58 +0100 Subject: [PATCH 073/227] Improved HCSR04 test Refactored code to use extension methods for waiting and timing the echo pin --- .../Components/Hd44780LcdConnection.cs | 1 + .../GpioConnectionDriverExtensionMethods.cs | 58 +++++++++++++++++++ Test.Gpio.HCSR04/Program.cs | 42 +++++++------- Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 2 + Test.Gpio.HCSR04/Units.cs | 19 ++++++ 5 files changed, 102 insertions(+), 20 deletions(-) create mode 100644 Test.Gpio.HCSR04/GpioConnectionDriverExtensionMethods.cs create mode 100644 Test.Gpio.HCSR04/Units.cs diff --git a/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs b/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs index 10806ed..027be2e 100644 --- a/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs @@ -275,6 +275,7 @@ public void Write(string text, decimal animationDelay = 0m) if (string.IsNullOrEmpty(line)) continue; + Console.WriteLine(line); var bytes = encoding.GetBytes(line); foreach (var b in bytes) { diff --git a/Test.Gpio.HCSR04/GpioConnectionDriverExtensionMethods.cs b/Test.Gpio.HCSR04/GpioConnectionDriverExtensionMethods.cs new file mode 100644 index 0000000..2b97a04 --- /dev/null +++ b/Test.Gpio.HCSR04/GpioConnectionDriverExtensionMethods.cs @@ -0,0 +1,58 @@ +using System; +using Raspberry.IO.GeneralPurpose; + +namespace Test.Gpio.HCSR04 +{ + internal static class GpioConnectionDriverExtensionMethods + { + /// + /// Waits for the specified pin to reach a given state. + /// + /// The driver. + /// The pin. + /// if set to true, waits for the pin to become up; otherwise, waits for the pin to become down. + /// The timeout. + /// + /// true is the pin has reached the expected status, false if a timeout occurred. + /// + public static bool Wait(this IGpioConnectionDriver driver, ProcessorPin pin, bool waitForUp = true, int timeout = 0) + { + if (timeout == 0) + timeout = 5000; + + var startWait = DateTime.Now; + while (driver.Read(pin) != waitForUp) + { + if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) + return false; + } + + return true; + } + + /// + /// Measures the time the specified pin remains up. + /// + /// The driver. + /// The measure pin. + /// if set to true, waits for the pin to become down; otherwise, waits for the pin to become up. + /// The timeout. + /// + /// The time the pin remains up, in milliseconds. + /// + public static decimal Time(this IGpioConnectionDriver driver, ProcessorPin pin, bool waitForDown = true, int timeout = 0) + { + if (timeout == 0) + timeout = 5000; + + var waitDown = DateTime.Now; + while (driver.Read(pin) == waitForDown) + { + if (DateTime.Now.Ticks - waitDown.Ticks >= 10000 * timeout) + return decimal.MinValue; + } + + return (DateTime.Now.Ticks - waitDown.Ticks) / 10000m; + } + } +} \ No newline at end of file diff --git a/Test.Gpio.HCSR04/Program.cs b/Test.Gpio.HCSR04/Program.cs index 67ffaaf..6590274 100644 --- a/Test.Gpio.HCSR04/Program.cs +++ b/Test.Gpio.HCSR04/Program.cs @@ -1,14 +1,18 @@ -using System; +#region References + +using System; using System.Collections.Generic; using System.Linq; using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; +#endregion + namespace Test.Gpio.HCSR04 { - class Program + internal class Program { - static void Main(string[] args) + private static void Main(string[] args) { var interval = GetInterval(args); @@ -25,6 +29,8 @@ static void Main(string[] args) var distance = GetDistance(driver, triggerPin, echoPin); if (distance != decimal.MinValue) Console.WriteLine("{0:0.0}cm", distance*100); + else + Console.WriteLine("(Timeout)"); Timer.Sleep(interval); } @@ -33,33 +39,29 @@ static void Main(string[] args) driver.Release(echoPin); } + #region Private Helpers + private static decimal GetDistance(MemoryGpioConnectionDriver driver, ProcessorPin triggerPin, ProcessorPin echoPin) { driver.Write(triggerPin, true); Timer.Sleep(0.01m); - var waitStart = DateTime.Now; driver.Write(triggerPin, false); - while(DateTime.Now.Ticks - waitStart.Ticks < 10*1000*1000*5) // 5s max - { - if (driver.Read(echoPin)) - { - var upStart = DateTime.Now; - while (driver.Read(echoPin)){} - var upTime = (DateTime.Now.Ticks - upStart.Ticks) / 10000000m; - - return upTime*340/2; - //(high level time * sound velocity (340M/S) / 2. - } - } - - Console.WriteLine("Timeout"); - return decimal.MinValue; + return driver.Wait(echoPin) + ? Units.Velocity.Sound.ToDistance(driver.Time(echoPin)) + : decimal.MinValue; } private static int GetInterval(IEnumerable args) { - return args.SkipWhile(a => a != "-interval").Skip(1).Select(int.Parse).DefaultIfEmpty(1000).First(); + return args + .SkipWhile(a => a != "-interval") + .Skip(1) + .Select(int.Parse) + .DefaultIfEmpty(1000) + .First(); } + + #endregion } } diff --git a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index d277f5b..ec82a26 100644 --- a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -42,8 +42,10 @@ + + diff --git a/Test.Gpio.HCSR04/Units.cs b/Test.Gpio.HCSR04/Units.cs new file mode 100644 index 0000000..2b5330a --- /dev/null +++ b/Test.Gpio.HCSR04/Units.cs @@ -0,0 +1,19 @@ +namespace Test.Gpio.HCSR04 +{ + internal static class Units + { + public static class Velocity + { + public static class Sound + { + public static decimal ToDistance(decimal time) + { + if (time == decimal.MinValue) + return decimal.MinValue; + + return (time/1000m)*340/2; + } + } + } + } +} \ No newline at end of file From 120582c8afb5c79f820242bd0d7845ddd42c212f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Fri, 22 Feb 2013 00:44:50 +0100 Subject: [PATCH 074/227] Added Fritzing file for HC-SR04 sample --- .../Properties/Test.Gpio.HCSR04.fzz | Bin 0 -> 26190 bytes .../Properties/Test.Gpio.HCSR04.png | Bin 0 -> 111867 bytes Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 4 ++++ 3 files changed, 4 insertions(+) create mode 100644 Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.fzz create mode 100644 Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.png diff --git a/Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.fzz b/Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.fzz new file mode 100644 index 0000000000000000000000000000000000000000..5864ae9ad765386da933e42d10fe067a2a934ee5 GIT binary patch literal 26190 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 jf0vE>8C%aD-Jp3cLk|6U3F*WG^r8X)oB literal 0 HcmV?d00001 diff --git a/Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.png b/Test.Gpio.HCSR04/Properties/Test.Gpio.HCSR04.png new file mode 100644 index 0000000000000000000000000000000000000000..526b4dadea40f821eb25a1c98eefdb68eff2f069 GIT binary patch literal 111867 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 literal 0 HcmV?d00001 diff --git a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index ec82a26..816dc44 100644 --- a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -55,6 +55,10 @@ + + + + + \ No newline at end of file diff --git a/Raspberry.IO.InterIntegratedCircuit/packages.config b/Raspberry.IO.InterIntegratedCircuit/packages.config new file mode 100644 index 0000000..aa2c82e --- /dev/null +++ b/Raspberry.IO.InterIntegratedCircuit/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 83020d6..accf7ff 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -26,6 +26,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.HCSR04", "Test.Gp EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{15ECD485-B3FD-4B6F-8491-7489DFFC89BC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.MCP23017", "Test.Gpio.MCP23017\Test.Gpio.MCP23017.csproj", "{266EDDBC-F741-48F8-83B7-2CD37BACE62B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.InterIntegratedCircuit", "Raspberry.IO.InterIntegratedCircuit\Raspberry.IO.InterIntegratedCircuit.csproj", "{63B8403E-BC56-43F9-A045-F61ECC3871F3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -118,15 +122,36 @@ Global {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|Mixed Platforms.Build.0 = Release|x86 {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|x86.ActiveCfg = Release|x86 {0A18AC47-CA6D-442C-A31C-6864F7DDD97D}.Release|x86.Build.0 = Release|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Any CPU.ActiveCfg = Debug|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|x86.ActiveCfg = Debug|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Debug|x86.Build.0 = Debug|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Any CPU.ActiveCfg = Release|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|Mixed Platforms.Build.0 = Release|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|x86.ActiveCfg = Release|x86 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B}.Release|x86.Build.0 = Release|x86 + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Debug|x86.ActiveCfg = Debug|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Any CPU.Build.0 = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {63B8403E-BC56-43F9-A045-F61ECC3871F3}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} - {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {0A18AC47-CA6D-442C-A31C-6864F7DDD97D} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {5D9D1834-4C4B-4E03-B635-5F205205B6F8} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection EndGlobal diff --git a/Test.Gpio.MCP23017/Program.cs b/Test.Gpio.MCP23017/Program.cs new file mode 100644 index 0000000..4a28c4a --- /dev/null +++ b/Test.Gpio.MCP23017/Program.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading; +using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.InterIntegratedCircuit; +using Raspberry.IO.InterIntegratedCircuit.Components; + +namespace Test.Gpio.MCP23017 +{ + class Program + { + static void Main(string[] args) + { + var sdaPin = ConnectorPin.P1Pin03.ToProcessor(); + var sclPin = ConnectorPin.P1Pin05.ToProcessor(); + + using (var driver = new I2cDriver(sdaPin, sclPin)) + { + var deviceConnection = new Mcp23017I2cConnection(driver.Connect(0x20)); + deviceConnection.SetDirection(Mcp23017Pin.B0, Mcp23017PinDirection.Output); + + while (!Console.KeyAvailable) + { + deviceConnection.Toogle(Mcp23017Pin.B0); + Thread.Sleep(1000); + } + } + } + } +} \ No newline at end of file diff --git a/Test.Gpio.MCP23017/Properties/AssemblyInfo.cs b/Test.Gpio.MCP23017/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fc0d275 --- /dev/null +++ b/Test.Gpio.MCP23017/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test.Gpio.MCP23017")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test.Gpio.MCP23017")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7f472591-835d-460f-a318-ed6627b6bf97")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj b/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj new file mode 100644 index 0000000..925c1b6 --- /dev/null +++ b/Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj @@ -0,0 +1,62 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {266EDDBC-F741-48F8-83B7-2CD37BACE62B} + Exe + Properties + Test.Gpio.MCP23017 + Test.Gpio.MCP23017 + v4.0 + Client + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + {63B8403E-BC56-43F9-A045-F61ECC3871F3} + Raspberry.IO.InterIntegratedCircuit + + + + + \ No newline at end of file diff --git a/Test.Gpio.MCP23017/libbcm2385.so b/Test.Gpio.MCP23017/libbcm2385.so new file mode 100644 index 0000000000000000000000000000000000000000..95ecc29008f77715f4ce17e64e026b535d535d90 GIT binary patch literal 37860 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 literal 0 HcmV?d00001 diff --git a/packages/repositories.config b/packages/repositories.config index f4339d0..7621b89 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -2,6 +2,7 @@ + \ No newline at end of file From 788d8cf7088c62c2fae4f32ca523849ddcee063f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Mon, 25 Feb 2013 22:50:46 +0100 Subject: [PATCH 077/227] Created Raspberry.IO.Components project Moved components to new project. Removed Raspberry.IO.Display project. --- .../Converter/Mcp3008}/Mcp3008Channel.cs | 2 +- .../Mcp3008}/Mcp3008SpiConnection.cs | 3 +- .../Converter/Mcp4822}/Mcp4822Channel.cs | 2 +- .../Mcp4822}/Mcp4822SpiConnection.cs | 3 +- .../Display/Hd44780}/Command.cs | 2 +- .../Display/Hd44780}/CursorShiftFlags.cs | 2 +- .../Display/Hd44780}/DisplayFlags.cs | 2 +- .../Display/Hd44780}/EntryModeFlags.cs | 2 +- .../Display/Hd44780}/Functions.cs | 2 +- .../Display/Hd44780}/Hd44780A00Encoding.cs | 1144 ++++++++--------- .../Display/Hd44780}/Hd44780LcdConnection.cs | 2 +- .../Hd44780}/Hd44780LcdConnectionSettings.cs | 2 +- .../Mcp23017}/Mcp23017I2cConnection.cs | 4 +- .../Expander/Mcp23017}/Mcp23017Pin.cs | 2 +- .../Mcp23017}/Mcp23017PinDirection.cs | 2 +- .../Expander/Mcp23017}/Mcp23017PinPolarity.cs | 2 +- .../Expander/Mcp23017}/Mcp23017PinResistor.cs | 2 +- .../Properties/AssemblyInfo.cs | 12 + .../Raspberry.IO.Components.csproj | 49 +- .../packages.config | 0 .../Properties/AssemblyInfo.cs | 23 - .../Raspberry.IO.GeneralPurpose.csproj | 3 + .../Properties/AssemblyInfo.cs | 26 +- ...Raspberry.IO.InterIntegratedCircuit.csproj | 8 +- .../Properties/AssemblyInfo.cs | 23 - ...pberry.IO.SerialPeripheralInterface.csproj | 7 +- RaspberrySharp.IO.sln | 25 +- .../AssemblyInfo.cs => SharedAssemblyInfo.cs | 16 +- ...pers.cs => CommandLineExtensionMethods.cs} | 2 +- Test.Gpio.Chaser/Properties/AssemblyInfo.cs | 27 +- Test.Gpio.Chaser/Test.Gpio.Chaser.csproj | 6 +- Test.Gpio.HCSR04/Properties/AssemblyInfo.cs | 26 +- Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 4 +- Test.Gpio.HCSR04/app.config | 3 - Test.Gpio.HD44780/Program.cs | 2 +- Test.Gpio.HD44780/Properties/AssemblyInfo.cs | 27 +- Test.Gpio.HD44780/Test.Gpio.HD44780.csproj | 10 +- Test.Gpio.MCP23017/Program.cs | 2 +- Test.Gpio.MCP23017/Properties/AssemblyInfo.cs | 26 +- Test.Gpio.MCP23017/Test.Gpio.MCP23017.csproj | 7 + Test.Gpio.MCP3008/Program.cs | 2 +- Test.Gpio.MCP3008/Properties/AssemblyInfo.cs | 27 +- Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj | 12 +- Test.Gpio.MCP4822/Program.cs | 2 +- Test.Gpio.MCP4822/Properties/AssemblyInfo.cs | 27 +- Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj | 12 +- packages/repositories.config | 1 + 47 files changed, 717 insertions(+), 880 deletions(-) rename {Raspberry.IO.SerialPeripheralInterface/Components => Raspberry.IO.Components/Converter/Mcp3008}/Mcp3008Channel.cs (78%) rename {Raspberry.IO.SerialPeripheralInterface/Components => Raspberry.IO.Components/Converter/Mcp3008}/Mcp3008SpiConnection.cs (94%) rename {Raspberry.IO.SerialPeripheralInterface/Components => Raspberry.IO.Components/Converter/Mcp4822}/Mcp4822Channel.cs (59%) rename {Raspberry.IO.SerialPeripheralInterface/Components => Raspberry.IO.Components/Converter/Mcp4822}/Mcp4822SpiConnection.cs (94%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/Command.cs (84%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/CursorShiftFlags.cs (79%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/DisplayFlags.cs (82%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/EntryModeFlags.cs (80%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/Functions.cs (82%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/Hd44780A00Encoding.cs (97%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/Hd44780LcdConnection.cs (99%) rename {Raspberry.IO.Display/Components => Raspberry.IO.Components/Display/Hd44780}/Hd44780LcdConnectionSettings.cs (92%) rename {Raspberry.IO.InterIntegratedCircuit/Components => Raspberry.IO.Components/Expander/Mcp23017}/Mcp23017I2cConnection.cs (97%) rename {Raspberry.IO.InterIntegratedCircuit/Components => Raspberry.IO.Components/Expander/Mcp23017}/Mcp23017Pin.cs (86%) rename {Raspberry.IO.InterIntegratedCircuit/Components => Raspberry.IO.Components/Expander/Mcp23017}/Mcp23017PinDirection.cs (58%) rename {Raspberry.IO.InterIntegratedCircuit/Components => Raspberry.IO.Components/Expander/Mcp23017}/Mcp23017PinPolarity.cs (59%) rename {Raspberry.IO.InterIntegratedCircuit/Components => Raspberry.IO.Components/Expander/Mcp23017}/Mcp23017PinResistor.cs (58%) create mode 100644 Raspberry.IO.Components/Properties/AssemblyInfo.cs rename Raspberry.IO.Display/Raspberry.IO.Display.csproj => Raspberry.IO.Components/Raspberry.IO.Components.csproj (54%) rename {Raspberry.IO.Display => Raspberry.IO.Components}/packages.config (100%) rename Raspberry.IO.Display/Properties/AssemblyInfo.cs => SharedAssemblyInfo.cs (62%) rename Test.Gpio.Chaser/{Helpers.cs => CommandLineExtensionMethods.cs} (96%) delete mode 100644 Test.Gpio.HCSR04/app.config diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008Channel.cs b/Raspberry.IO.Components/Converter/Mcp3008/Mcp3008Channel.cs similarity index 78% rename from Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008Channel.cs rename to Raspberry.IO.Components/Converter/Mcp3008/Mcp3008Channel.cs index 3ff880e..f522f94 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008Channel.cs +++ b/Raspberry.IO.Components/Converter/Mcp3008/Mcp3008Channel.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.SerialPeripheralInterface.Components +namespace Raspberry.IO.Components.Converter.Mcp3008 { public enum Mcp3008Channel { diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs b/Raspberry.IO.Components/Converter/Mcp3008/Mcp3008SpiConnection.cs similarity index 94% rename from Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs rename to Raspberry.IO.Components/Converter/Mcp3008/Mcp3008SpiConnection.cs index fc9f72d..ba0d492 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp3008SpiConnection.cs +++ b/Raspberry.IO.Components/Converter/Mcp3008/Mcp3008SpiConnection.cs @@ -2,10 +2,11 @@ using System; using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.SerialPeripheralInterface; #endregion -namespace Raspberry.IO.SerialPeripheralInterface.Components +namespace Raspberry.IO.Components.Converter.Mcp3008 { /// /// Represents a connection to MCP3004/3008 ADC converter. diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822Channel.cs b/Raspberry.IO.Components/Converter/Mcp4822/Mcp4822Channel.cs similarity index 59% rename from Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822Channel.cs rename to Raspberry.IO.Components/Converter/Mcp4822/Mcp4822Channel.cs index 77b12a4..763d95c 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822Channel.cs +++ b/Raspberry.IO.Components/Converter/Mcp4822/Mcp4822Channel.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.SerialPeripheralInterface.Components +namespace Raspberry.IO.Components.Converter.Mcp4822 { public enum Mcp4822Channel { diff --git a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs b/Raspberry.IO.Components/Converter/Mcp4822/Mcp4822SpiConnection.cs similarity index 94% rename from Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs rename to Raspberry.IO.Components/Converter/Mcp4822/Mcp4822SpiConnection.cs index 061ddf2..85d3ff0 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Components/Mcp4822SpiConnection.cs +++ b/Raspberry.IO.Components/Converter/Mcp4822/Mcp4822SpiConnection.cs @@ -2,10 +2,11 @@ using System; using Raspberry.IO.GeneralPurpose; +using Raspberry.IO.SerialPeripheralInterface; #endregion -namespace Raspberry.IO.SerialPeripheralInterface.Components +namespace Raspberry.IO.Components.Converter.Mcp4822 { /// /// Represents a SPI connection to a MCP4802/4812/4822 DAC. diff --git a/Raspberry.IO.Display/Components/Command.cs b/Raspberry.IO.Components/Display/Hd44780/Command.cs similarity index 84% rename from Raspberry.IO.Display/Components/Command.cs rename to Raspberry.IO.Components/Display/Hd44780/Command.cs index 9a617d9..8fdde9d 100644 --- a/Raspberry.IO.Display/Components/Command.cs +++ b/Raspberry.IO.Components/Display/Hd44780/Command.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { internal enum Command { diff --git a/Raspberry.IO.Display/Components/CursorShiftFlags.cs b/Raspberry.IO.Components/Display/Hd44780/CursorShiftFlags.cs similarity index 79% rename from Raspberry.IO.Display/Components/CursorShiftFlags.cs rename to Raspberry.IO.Components/Display/Hd44780/CursorShiftFlags.cs index 59d3641..6107a41 100644 --- a/Raspberry.IO.Display/Components/CursorShiftFlags.cs +++ b/Raspberry.IO.Components/Display/Hd44780/CursorShiftFlags.cs @@ -1,6 +1,6 @@ using System; -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { [Flags] internal enum CursorShiftFlags diff --git a/Raspberry.IO.Display/Components/DisplayFlags.cs b/Raspberry.IO.Components/Display/Hd44780/DisplayFlags.cs similarity index 82% rename from Raspberry.IO.Display/Components/DisplayFlags.cs rename to Raspberry.IO.Components/Display/Hd44780/DisplayFlags.cs index b23a912..6810a14 100644 --- a/Raspberry.IO.Display/Components/DisplayFlags.cs +++ b/Raspberry.IO.Components/Display/Hd44780/DisplayFlags.cs @@ -1,6 +1,6 @@ using System; -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { [Flags] internal enum DisplayFlags diff --git a/Raspberry.IO.Display/Components/EntryModeFlags.cs b/Raspberry.IO.Components/Display/Hd44780/EntryModeFlags.cs similarity index 80% rename from Raspberry.IO.Display/Components/EntryModeFlags.cs rename to Raspberry.IO.Components/Display/Hd44780/EntryModeFlags.cs index 0f6f798..8eb0047 100644 --- a/Raspberry.IO.Display/Components/EntryModeFlags.cs +++ b/Raspberry.IO.Components/Display/Hd44780/EntryModeFlags.cs @@ -1,6 +1,6 @@ using System; -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { [Flags] internal enum EntryModeFlags diff --git a/Raspberry.IO.Display/Components/Functions.cs b/Raspberry.IO.Components/Display/Hd44780/Functions.cs similarity index 82% rename from Raspberry.IO.Display/Components/Functions.cs rename to Raspberry.IO.Components/Display/Hd44780/Functions.cs index 73bb9af..746035e 100644 --- a/Raspberry.IO.Display/Components/Functions.cs +++ b/Raspberry.IO.Components/Display/Hd44780/Functions.cs @@ -1,6 +1,6 @@ using System; -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { [Flags] internal enum Functions diff --git a/Raspberry.IO.Display/Components/Hd44780A00Encoding.cs b/Raspberry.IO.Components/Display/Hd44780/Hd44780A00Encoding.cs similarity index 97% rename from Raspberry.IO.Display/Components/Hd44780A00Encoding.cs rename to Raspberry.IO.Components/Display/Hd44780/Hd44780A00Encoding.cs index 74803d5..dac45bd 100644 --- a/Raspberry.IO.Display/Components/Hd44780A00Encoding.cs +++ b/Raspberry.IO.Components/Display/Hd44780/Hd44780A00Encoding.cs @@ -1,573 +1,573 @@ -#region References - -using System; -using System.Collections.Generic; -using System.Text; -using System.Linq; - -#endregion - -namespace Raspberry.IO.Display.Components -{ - /// - /// Represents encoding for HD44780 LCD with Japanese character set (ROM code A00) - /// Based on http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf - /// And http://en.wikipedia.org/wiki/Katakana - /// - public class Hd44780A00Encoding : Encoding - { - #region Fields - - private static readonly Dictionary charMap = GetMap().GroupBy(p => p.Key, p => p.Value).ToDictionary(g => g.Key, g => g.First()); - private static readonly Dictionary byteMap = GetMap().GroupBy(p => p.Value, p => p.Key).ToDictionary(g => g.Key, g => g.First()); - - private const byte missingChar = 0x3F; - private const char missingByte = '\uFFFD'; - - #endregion - - #region Properties - - /// - /// Gets the supported characters. - /// - public static IEnumerable SupportedCharacters - { - get { return charMap.Keys.Except(new[]{'\r', '\n'}); } - } - - #endregion - - #region Methods - - public override int GetByteCount(char[] chars, int index, int count) - { - return count; - } - - public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) - { - Array.Copy( - chars - .Skip(charIndex) - .Take(charCount) - .Select(c => - { - byte b; - return charMap.TryGetValue(c, out b) ? b : missingChar; - }) - .ToArray(), - 0, - bytes, - byteIndex, - charCount); - - return charCount; - } - - public override int GetCharCount(byte[] bytes, int index, int count) - { - return count; - } - - public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) - { - Array.Copy( - bytes - .Skip(byteIndex) - .Take(byteCount) - .Select(b => - { - char c; - return byteMap.TryGetValue(b, out c) ? c : missingByte; - }) - .ToArray(), - 0, - chars, - charIndex, - byteCount); - - return byteCount; - } - - public override int GetMaxByteCount(int charCount) - { - return charCount; - } - - public override int GetMaxCharCount(int byteCount) - { - return byteCount; - } - - #endregion - - #region Private Helpers - - private static IEnumerable> GetMap() - { - // CR/LF - yield return new KeyValuePair('\u000A', 0x0A); - yield return new KeyValuePair('\u000D', 0x0A); - - // Custom characters - yield return new KeyValuePair('\u0000', 0x00); - yield return new KeyValuePair('\u0001', 0x01); - yield return new KeyValuePair('\u0002', 0x02); - yield return new KeyValuePair('\u0003', 0x03); - yield return new KeyValuePair('\u0004', 0x04); - yield return new KeyValuePair('\u0005', 0x05); - yield return new KeyValuePair('\u0006', 0x06); - yield return new KeyValuePair('\u0007', 0x07); -/* - yield return new KeyValuePair(' ', 0x08); - yield return new KeyValuePair(' ', 0x09); - yield return new KeyValuePair(' ', 0x0A); - yield return new KeyValuePair(' ', 0x0B); - yield return new KeyValuePair(' ', 0x0C); - yield return new KeyValuePair(' ', 0x0D); - yield return new KeyValuePair(' ', 0x0E); - yield return new KeyValuePair(' ', 0x0F); - - yield return new KeyValuePair(' ', 0x10); - yield return new KeyValuePair(' ', 0x11); - yield return new KeyValuePair(' ', 0x12); - yield return new KeyValuePair(' ', 0x13); - yield return new KeyValuePair(' ', 0x14); - yield return new KeyValuePair(' ', 0x15); - yield return new KeyValuePair(' ', 0x16); - yield return new KeyValuePair(' ', 0x17); - yield return new KeyValuePair(' ', 0x18); - yield return new KeyValuePair(' ', 0x19); - yield return new KeyValuePair(' ', 0x1A); - yield return new KeyValuePair(' ', 0x1B); - yield return new KeyValuePair(' ', 0x1C); - yield return new KeyValuePair(' ', 0x1D); - yield return new KeyValuePair(' ', 0x1E); - yield return new KeyValuePair(' ', 0x1F); -*/ - yield return new KeyValuePair(' ', 0x20); - // Variants - yield return new KeyValuePair('\u0009', 0x20); - yield return new KeyValuePair('\u000B', 0x20); - yield return new KeyValuePair('\u000C', 0x20); - yield return new KeyValuePair('\u0085', 0x20); - yield return new KeyValuePair('\u00A0', 0x20); - yield return new KeyValuePair('\u1680', 0x20); - yield return new KeyValuePair('\u180E', 0x20); - yield return new KeyValuePair('\u2000', 0x20); - yield return new KeyValuePair('\u2001', 0x20); - yield return new KeyValuePair('\u2002', 0x20); - yield return new KeyValuePair('\u2003', 0x20); - yield return new KeyValuePair('\u2004', 0x20); - yield return new KeyValuePair('\u2005', 0x20); - yield return new KeyValuePair('\u2006', 0x20); - yield return new KeyValuePair('\u2007', 0x20); - yield return new KeyValuePair('\u2008', 0x20); - yield return new KeyValuePair('\u2009', 0x20); - yield return new KeyValuePair('\u200A', 0x20); - yield return new KeyValuePair('\u2028', 0x20); - yield return new KeyValuePair('\u2029', 0x20); - yield return new KeyValuePair('\u202F', 0x20); - yield return new KeyValuePair('\u205F', 0x20); - yield return new KeyValuePair('\u3000', 0x20); - - yield return new KeyValuePair('!', 0x21); - - yield return new KeyValuePair('"', 0x22); - //Variants - yield return new KeyValuePair('“', 0x22); - yield return new KeyValuePair('”', 0x22); - yield return new KeyValuePair('„', 0x22); - yield return new KeyValuePair('‟', 0x22); - - yield return new KeyValuePair('#', 0x23); - yield return new KeyValuePair('$', 0x24); - yield return new KeyValuePair('%', 0x25); - yield return new KeyValuePair('&', 0x26); - - yield return new KeyValuePair('\'', 0x27); - // Variants - yield return new KeyValuePair('‘', 0x2F); - yield return new KeyValuePair('’', 0x2F); - yield return new KeyValuePair('‛', 0x2F); - yield return new KeyValuePair('′', 0x2F); - - yield return new KeyValuePair('(', 0x28); - yield return new KeyValuePair(')', 0x29); - yield return new KeyValuePair('*', 0x2A); - yield return new KeyValuePair('+', 0x2B); - yield return new KeyValuePair(',', 0x2C); - - yield return new KeyValuePair('-', 0x2D); - // Variants - yield return new KeyValuePair('‐', 0x2D); - yield return new KeyValuePair('‒', 0x2D); - yield return new KeyValuePair('–', 0x2D); - yield return new KeyValuePair('—', 0x2D); - yield return new KeyValuePair('―', 0x2D); - - yield return new KeyValuePair('.', 0x2E); - - yield return new KeyValuePair('/', 0x2F); - // Variants - yield return new KeyValuePair('⁄', 0x2F); - - yield return new KeyValuePair('0', 0x30); - yield return new KeyValuePair('1', 0x31); - yield return new KeyValuePair('2', 0x32); - yield return new KeyValuePair('3', 0x33); - yield return new KeyValuePair('4', 0x34); - yield return new KeyValuePair('5', 0x35); - yield return new KeyValuePair('6', 0x36); - yield return new KeyValuePair('7', 0x37); - yield return new KeyValuePair('8', 0x38); - yield return new KeyValuePair('9', 0x39); - yield return new KeyValuePair(':', 0x3A); - yield return new KeyValuePair(';', 0x3B); - - yield return new KeyValuePair('<', 0x3C); - // Variant - yield return new KeyValuePair('‹', 0x3C); - - yield return new KeyValuePair('=', 0x3D); - // Variant - yield return new KeyValuePair('゠', 0x3D); - - yield return new KeyValuePair('>', 0x3E); - // Variant - yield return new KeyValuePair('›', 0x3E); - - yield return new KeyValuePair('?', 0x3F); - // Variant - yield return new KeyValuePair('¿', 0x3F); - - yield return new KeyValuePair('@', 0x40); - - yield return new KeyValuePair('A', 0x41); - // Variants - yield return new KeyValuePair('À', 0x41); - yield return new KeyValuePair('Á', 0x41); - yield return new KeyValuePair('Â', 0x41); - yield return new KeyValuePair('Ã', 0x41); - yield return new KeyValuePair('Ä', 0x41); - yield return new KeyValuePair('Å', 0x41); - - yield return new KeyValuePair('B', 0x42); - - yield return new KeyValuePair('C', 0x43); - // Variant - yield return new KeyValuePair('Ç', 0x43); - - yield return new KeyValuePair('D', 0x44); - - yield return new KeyValuePair('E', 0x45); - // Variants - yield return new KeyValuePair('È', 0x45); - yield return new KeyValuePair('É', 0x45); - yield return new KeyValuePair('Ê', 0x45); - yield return new KeyValuePair('Ë', 0x45); - - yield return new KeyValuePair('F', 0x46); - yield return new KeyValuePair('G', 0x47); - yield return new KeyValuePair('H', 0x48); - - yield return new KeyValuePair('I', 0x49); - // Variants - yield return new KeyValuePair('Ì', 0x49); - yield return new KeyValuePair('Í', 0x49); - yield return new KeyValuePair('Î', 0x49); - yield return new KeyValuePair('Ï', 0x49); - - yield return new KeyValuePair('J', 0x4A); - yield return new KeyValuePair('K', 0x4B); - yield return new KeyValuePair('L', 0x4C); - yield return new KeyValuePair('M', 0x4D); - - yield return new KeyValuePair('N', 0x4E); - // Variant - yield return new KeyValuePair('Ñ', 0x4E); - - yield return new KeyValuePair('O', 0x4F); - // Variants - yield return new KeyValuePair('Ò', 0x4F); - yield return new KeyValuePair('Ó', 0x4F); - yield return new KeyValuePair('Ô', 0x4F); - yield return new KeyValuePair('Õ', 0x4F); - yield return new KeyValuePair('Ö', 0x4F); - yield return new KeyValuePair('Ø', 0x4F); - - yield return new KeyValuePair('P', 0x50); - yield return new KeyValuePair('Q', 0x51); - yield return new KeyValuePair('R', 0x52); - yield return new KeyValuePair('S', 0x53); - yield return new KeyValuePair('T', 0x54); - - yield return new KeyValuePair('U', 0x55); - // Variants - yield return new KeyValuePair('Ù', 0x55); - yield return new KeyValuePair('Ú', 0x55); - yield return new KeyValuePair('Û', 0x55); - yield return new KeyValuePair('Ü', 0x55); - - yield return new KeyValuePair('V', 0x56); - yield return new KeyValuePair('W', 0x57); - yield return new KeyValuePair('X', 0x58); - - yield return new KeyValuePair('Y', 0x59); - // Variant - yield return new KeyValuePair('Ý', 0x59); - - yield return new KeyValuePair('Z', 0x5A); - yield return new KeyValuePair('[', 0x5B); - yield return new KeyValuePair('¥', 0x5C); - yield return new KeyValuePair(']', 0x5D); - yield return new KeyValuePair('^', 0x5E); - - yield return new KeyValuePair('_', 0x5F); - // Variant - yield return new KeyValuePair('‗', 0x5F); - - yield return new KeyValuePair('`', 0x60); - - yield return new KeyValuePair('a', 0x61); - // Variants - yield return new KeyValuePair('à', 0x61); - yield return new KeyValuePair('á', 0x61); - yield return new KeyValuePair('â', 0x61); - yield return new KeyValuePair('ã', 0x61); - yield return new KeyValuePair('å', 0x61); - - yield return new KeyValuePair('b', 0x62); - - yield return new KeyValuePair('c', 0x63); - // Variant - yield return new KeyValuePair('ç', 0x63); - - yield return new KeyValuePair('d', 0x64); - - yield return new KeyValuePair('e', 0x65); - // Variants - yield return new KeyValuePair('è', 0x65); - yield return new KeyValuePair('é', 0x65); - yield return new KeyValuePair('ê', 0x65); - yield return new KeyValuePair('ë', 0x65); - - yield return new KeyValuePair('f', 0x66); - yield return new KeyValuePair('g', 0x67); - yield return new KeyValuePair('h', 0x68); - - yield return new KeyValuePair('i', 0x69); - // Variants - yield return new KeyValuePair('ì', 0x69); - yield return new KeyValuePair('í', 0x69); - yield return new KeyValuePair('î', 0x69); - yield return new KeyValuePair('ï', 0x69); - - yield return new KeyValuePair('j', 0x6A); - yield return new KeyValuePair('k', 0x6B); - yield return new KeyValuePair('l', 0x6C); - yield return new KeyValuePair('m', 0x6D); - - yield return new KeyValuePair('n', 0x6E); - // Variant - yield return new KeyValuePair('ñ', 0x6E); - - yield return new KeyValuePair('o', 0x6F); - // Variants - yield return new KeyValuePair('ò', 0x6F); - yield return new KeyValuePair('ó', 0x6F); - yield return new KeyValuePair('ô', 0x6F); - yield return new KeyValuePair('õ', 0x6F); - yield return new KeyValuePair('ö', 0x6F); - yield return new KeyValuePair('ø', 0x6F); - - yield return new KeyValuePair('p', 0x70); - yield return new KeyValuePair('q', 0x71); - yield return new KeyValuePair('r', 0x72); - yield return new KeyValuePair('s', 0x73); - yield return new KeyValuePair('t', 0x74); - - yield return new KeyValuePair('u', 0x75); - // Variants - yield return new KeyValuePair('ù', 0x75); - yield return new KeyValuePair('ú', 0x75); - yield return new KeyValuePair('û', 0x75); - yield return new KeyValuePair('ü', 0x75); - - yield return new KeyValuePair('v', 0x76); - yield return new KeyValuePair('w', 0x77); - yield return new KeyValuePair('x', 0x78); - - yield return new KeyValuePair('y', 0x79); - // Variants - yield return new KeyValuePair('ý', 0x79); - yield return new KeyValuePair('ÿ', 0x79); - - yield return new KeyValuePair('z', 0x7A); - yield return new KeyValuePair('{', 0x7B); - yield return new KeyValuePair('|', 0x7C); - yield return new KeyValuePair('}', 0x7D); - yield return new KeyValuePair('→', 0x7E); - yield return new KeyValuePair('←', 0x7F); - - yield return new KeyValuePair(' ', 0x80); - yield return new KeyValuePair(' ', 0x81); - yield return new KeyValuePair(' ', 0x82); - yield return new KeyValuePair(' ', 0x83); - yield return new KeyValuePair(' ', 0x84); - yield return new KeyValuePair(' ', 0x85); - yield return new KeyValuePair(' ', 0x86); - yield return new KeyValuePair(' ', 0x87); - yield return new KeyValuePair(' ', 0x88); - yield return new KeyValuePair(' ', 0x89); - yield return new KeyValuePair(' ', 0x8A); - yield return new KeyValuePair(' ', 0x8B); - yield return new KeyValuePair(' ', 0x8C); - yield return new KeyValuePair(' ', 0x8D); - yield return new KeyValuePair(' ', 0x8E); - yield return new KeyValuePair(' ', 0x8F); - - yield return new KeyValuePair(' ', 0x90); - yield return new KeyValuePair(' ', 0x91); - yield return new KeyValuePair(' ', 0x92); - yield return new KeyValuePair(' ', 0x93); - yield return new KeyValuePair(' ', 0x94); - yield return new KeyValuePair(' ', 0x95); - yield return new KeyValuePair(' ', 0x96); - yield return new KeyValuePair(' ', 0x97); - yield return new KeyValuePair(' ', 0x98); - yield return new KeyValuePair(' ', 0x99); - yield return new KeyValuePair(' ', 0x9A); - yield return new KeyValuePair(' ', 0x9B); - yield return new KeyValuePair(' ', 0x9C); - yield return new KeyValuePair(' ', 0x9D); - yield return new KeyValuePair(' ', 0x9E); - yield return new KeyValuePair(' ', 0x9F); - - yield return new KeyValuePair(' ', 0xA0); - yield return new KeyValuePair('▫', 0xA1); -// yield return new KeyValuePair('', 0xA2); -// yield return new KeyValuePair('', 0xA3); - yield return new KeyValuePair('ヽ', 0xA4); - yield return new KeyValuePair('・', 0xA5); - yield return new KeyValuePair('ヲ', 0xA6); - yield return new KeyValuePair('ァ', 0xA7); - yield return new KeyValuePair('ィ', 0xA8); - yield return new KeyValuePair('ゥ', 0xA9); - yield return new KeyValuePair('ェ', 0xAA); - yield return new KeyValuePair('ォ', 0xAB); - yield return new KeyValuePair('ャ', 0xAC); - yield return new KeyValuePair('ュ', 0xAD); - yield return new KeyValuePair('ョ', 0xAE); - yield return new KeyValuePair('ッ', 0xAF); - - yield return new KeyValuePair('ー', 0xB0); - yield return new KeyValuePair('ア', 0xB1); - yield return new KeyValuePair('イ', 0xB2); - yield return new KeyValuePair('ウ', 0xB3); - yield return new KeyValuePair('エ', 0xB4); - yield return new KeyValuePair('オ', 0xB5); - yield return new KeyValuePair('カ', 0xB6); - yield return new KeyValuePair('キ', 0xB7); - yield return new KeyValuePair('ク', 0xB8); - yield return new KeyValuePair('ケ', 0xB9); - yield return new KeyValuePair('コ', 0xBA); - yield return new KeyValuePair('サ', 0xBB); - yield return new KeyValuePair('シ', 0xBC); - yield return new KeyValuePair('ス', 0xBD); - yield return new KeyValuePair('セ', 0xBE); - yield return new KeyValuePair('ソ', 0xBF); - - yield return new KeyValuePair('タ', 0xC0); - yield return new KeyValuePair('チ', 0xC1); - yield return new KeyValuePair('ツ', 0xC2); - yield return new KeyValuePair('テ', 0xC3); - yield return new KeyValuePair('ト', 0xC4); - yield return new KeyValuePair('ナ', 0xC5); - yield return new KeyValuePair('ニ', 0xC6); - yield return new KeyValuePair('ヌ', 0xC7); - yield return new KeyValuePair('ネ', 0xC8); - yield return new KeyValuePair('ノ', 0xC9); - yield return new KeyValuePair('ハ', 0xCA); - yield return new KeyValuePair('ヒ', 0xCB); - yield return new KeyValuePair('フ', 0xCC); - yield return new KeyValuePair('ヘ', 0xCD); - yield return new KeyValuePair('ホ', 0xCE); - yield return new KeyValuePair('マ', 0xCF); - - yield return new KeyValuePair('ミ', 0xD0); - yield return new KeyValuePair('ム', 0xD1); - yield return new KeyValuePair('メ', 0xD2); - yield return new KeyValuePair('モ', 0xD3); - yield return new KeyValuePair('ヤ', 0xD4); - yield return new KeyValuePair('ユ', 0xD5); - yield return new KeyValuePair('ヨ', 0xD6); - yield return new KeyValuePair('ラ', 0xD7); - yield return new KeyValuePair('リ', 0xD8); - yield return new KeyValuePair('ル', 0xD9); - yield return new KeyValuePair('レ', 0xDA); - yield return new KeyValuePair('ロ', 0xDB); - yield return new KeyValuePair('ワ', 0xDC); - yield return new KeyValuePair('ン', 0xDD); - - yield return new KeyValuePair('゛', 0xDE); - - yield return new KeyValuePair('゜', 0xDF); - // Variant - yield return new KeyValuePair('°', 0xDF); - - yield return new KeyValuePair('α', 0xE0); - - yield return new KeyValuePair('ä', 0xE1); - // Variant - yield return new KeyValuePair('ӓ', 0xE1); - - yield return new KeyValuePair('β', 0xE2); - // Variant - yield return new KeyValuePair('ß', 0xE2); - - yield return new KeyValuePair('ε', 0xE3); - yield return new KeyValuePair('μ', 0xE4); - yield return new KeyValuePair('σ', 0xE5); - yield return new KeyValuePair('ρ', 0xE6); - yield return new KeyValuePair('ɡ', 0xE7); - yield return new KeyValuePair('√', 0xE8); -// yield return new KeyValuePair('', 0xE9); - yield return new KeyValuePair('ј', 0xEA); - yield return new KeyValuePair('\u033D', 0xEB); - - yield return new KeyValuePair('¢', 0xEC); - // Variants - yield return new KeyValuePair('\u023B', 0xEC); - yield return new KeyValuePair('¢', 0xEC); - -// yield return new KeyValuePair('', 0xED); - yield return new KeyValuePair('ñ', 0xEE); - yield return new KeyValuePair('ö', 0xEF); - - yield return new KeyValuePair('ρ', 0xF0); -// yield return new KeyValuePair('', 0xF1); - yield return new KeyValuePair('θ', 0xF2); - yield return new KeyValuePair('∞', 0xF3); - yield return new KeyValuePair('Ω', 0xF4); - yield return new KeyValuePair('ü', 0xF5); - yield return new KeyValuePair('Σ', 0xF6); - yield return new KeyValuePair('π', 0xF7); -// yield return new KeyValuePair('', 0xF8); - - yield return new KeyValuePair('У', 0xF9); - // Variant - yield return new KeyValuePair('у', 0xF9); - -// yield return new KeyValuePair('', 0xFA); -// yield return new KeyValuePair('', 0xFB); -// yield return new KeyValuePair('', 0xFC); - yield return new KeyValuePair('÷', 0xFD); - yield return new KeyValuePair(' ', 0xFE); - yield return new KeyValuePair('█', 0xFF); - } - - #endregion - } +#region References + +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +#endregion + +namespace Raspberry.IO.Components.Display.Hd44780 +{ + /// + /// Represents encoding for HD44780 LCD with Japanese character set (ROM code A00) + /// Based on http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf + /// And http://en.wikipedia.org/wiki/Katakana + /// + public class Hd44780A00Encoding : Encoding + { + #region Fields + + private static readonly Dictionary charMap = GetMap().GroupBy(p => p.Key, p => p.Value).ToDictionary(g => g.Key, g => g.First()); + private static readonly Dictionary byteMap = GetMap().GroupBy(p => p.Value, p => p.Key).ToDictionary(g => g.Key, g => g.First()); + + private const byte missingChar = 0x3F; + private const char missingByte = '\uFFFD'; + + #endregion + + #region Properties + + /// + /// Gets the supported characters. + /// + public static IEnumerable SupportedCharacters + { + get { return charMap.Keys.Except(new[]{'\r', '\n'}); } + } + + #endregion + + #region Methods + + public override int GetByteCount(char[] chars, int index, int count) + { + return count; + } + + public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + Array.Copy( + chars + .Skip(charIndex) + .Take(charCount) + .Select(c => + { + byte b; + return charMap.TryGetValue(c, out b) ? b : missingChar; + }) + .ToArray(), + 0, + bytes, + byteIndex, + charCount); + + return charCount; + } + + public override int GetCharCount(byte[] bytes, int index, int count) + { + return count; + } + + public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + { + Array.Copy( + bytes + .Skip(byteIndex) + .Take(byteCount) + .Select(b => + { + char c; + return byteMap.TryGetValue(b, out c) ? c : missingByte; + }) + .ToArray(), + 0, + chars, + charIndex, + byteCount); + + return byteCount; + } + + public override int GetMaxByteCount(int charCount) + { + return charCount; + } + + public override int GetMaxCharCount(int byteCount) + { + return byteCount; + } + + #endregion + + #region Private Helpers + + private static IEnumerable> GetMap() + { + // CR/LF + yield return new KeyValuePair('\u000A', 0x0A); + yield return new KeyValuePair('\u000D', 0x0A); + + // Custom characters + yield return new KeyValuePair('\u0000', 0x00); + yield return new KeyValuePair('\u0001', 0x01); + yield return new KeyValuePair('\u0002', 0x02); + yield return new KeyValuePair('\u0003', 0x03); + yield return new KeyValuePair('\u0004', 0x04); + yield return new KeyValuePair('\u0005', 0x05); + yield return new KeyValuePair('\u0006', 0x06); + yield return new KeyValuePair('\u0007', 0x07); +/* + yield return new KeyValuePair(' ', 0x08); + yield return new KeyValuePair(' ', 0x09); + yield return new KeyValuePair(' ', 0x0A); + yield return new KeyValuePair(' ', 0x0B); + yield return new KeyValuePair(' ', 0x0C); + yield return new KeyValuePair(' ', 0x0D); + yield return new KeyValuePair(' ', 0x0E); + yield return new KeyValuePair(' ', 0x0F); + + yield return new KeyValuePair(' ', 0x10); + yield return new KeyValuePair(' ', 0x11); + yield return new KeyValuePair(' ', 0x12); + yield return new KeyValuePair(' ', 0x13); + yield return new KeyValuePair(' ', 0x14); + yield return new KeyValuePair(' ', 0x15); + yield return new KeyValuePair(' ', 0x16); + yield return new KeyValuePair(' ', 0x17); + yield return new KeyValuePair(' ', 0x18); + yield return new KeyValuePair(' ', 0x19); + yield return new KeyValuePair(' ', 0x1A); + yield return new KeyValuePair(' ', 0x1B); + yield return new KeyValuePair(' ', 0x1C); + yield return new KeyValuePair(' ', 0x1D); + yield return new KeyValuePair(' ', 0x1E); + yield return new KeyValuePair(' ', 0x1F); +*/ + yield return new KeyValuePair(' ', 0x20); + // Variants + yield return new KeyValuePair('\u0009', 0x20); + yield return new KeyValuePair('\u000B', 0x20); + yield return new KeyValuePair('\u000C', 0x20); + yield return new KeyValuePair('\u0085', 0x20); + yield return new KeyValuePair('\u00A0', 0x20); + yield return new KeyValuePair('\u1680', 0x20); + yield return new KeyValuePair('\u180E', 0x20); + yield return new KeyValuePair('\u2000', 0x20); + yield return new KeyValuePair('\u2001', 0x20); + yield return new KeyValuePair('\u2002', 0x20); + yield return new KeyValuePair('\u2003', 0x20); + yield return new KeyValuePair('\u2004', 0x20); + yield return new KeyValuePair('\u2005', 0x20); + yield return new KeyValuePair('\u2006', 0x20); + yield return new KeyValuePair('\u2007', 0x20); + yield return new KeyValuePair('\u2008', 0x20); + yield return new KeyValuePair('\u2009', 0x20); + yield return new KeyValuePair('\u200A', 0x20); + yield return new KeyValuePair('\u2028', 0x20); + yield return new KeyValuePair('\u2029', 0x20); + yield return new KeyValuePair('\u202F', 0x20); + yield return new KeyValuePair('\u205F', 0x20); + yield return new KeyValuePair('\u3000', 0x20); + + yield return new KeyValuePair('!', 0x21); + + yield return new KeyValuePair('"', 0x22); + //Variants + yield return new KeyValuePair('“', 0x22); + yield return new KeyValuePair('”', 0x22); + yield return new KeyValuePair('„', 0x22); + yield return new KeyValuePair('‟', 0x22); + + yield return new KeyValuePair('#', 0x23); + yield return new KeyValuePair('$', 0x24); + yield return new KeyValuePair('%', 0x25); + yield return new KeyValuePair('&', 0x26); + + yield return new KeyValuePair('\'', 0x27); + // Variants + yield return new KeyValuePair('‘', 0x2F); + yield return new KeyValuePair('’', 0x2F); + yield return new KeyValuePair('‛', 0x2F); + yield return new KeyValuePair('′', 0x2F); + + yield return new KeyValuePair('(', 0x28); + yield return new KeyValuePair(')', 0x29); + yield return new KeyValuePair('*', 0x2A); + yield return new KeyValuePair('+', 0x2B); + yield return new KeyValuePair(',', 0x2C); + + yield return new KeyValuePair('-', 0x2D); + // Variants + yield return new KeyValuePair('‐', 0x2D); + yield return new KeyValuePair('‒', 0x2D); + yield return new KeyValuePair('–', 0x2D); + yield return new KeyValuePair('—', 0x2D); + yield return new KeyValuePair('―', 0x2D); + + yield return new KeyValuePair('.', 0x2E); + + yield return new KeyValuePair('/', 0x2F); + // Variants + yield return new KeyValuePair('⁄', 0x2F); + + yield return new KeyValuePair('0', 0x30); + yield return new KeyValuePair('1', 0x31); + yield return new KeyValuePair('2', 0x32); + yield return new KeyValuePair('3', 0x33); + yield return new KeyValuePair('4', 0x34); + yield return new KeyValuePair('5', 0x35); + yield return new KeyValuePair('6', 0x36); + yield return new KeyValuePair('7', 0x37); + yield return new KeyValuePair('8', 0x38); + yield return new KeyValuePair('9', 0x39); + yield return new KeyValuePair(':', 0x3A); + yield return new KeyValuePair(';', 0x3B); + + yield return new KeyValuePair('<', 0x3C); + // Variant + yield return new KeyValuePair('‹', 0x3C); + + yield return new KeyValuePair('=', 0x3D); + // Variant + yield return new KeyValuePair('゠', 0x3D); + + yield return new KeyValuePair('>', 0x3E); + // Variant + yield return new KeyValuePair('›', 0x3E); + + yield return new KeyValuePair('?', 0x3F); + // Variant + yield return new KeyValuePair('¿', 0x3F); + + yield return new KeyValuePair('@', 0x40); + + yield return new KeyValuePair('A', 0x41); + // Variants + yield return new KeyValuePair('À', 0x41); + yield return new KeyValuePair('Á', 0x41); + yield return new KeyValuePair('Â', 0x41); + yield return new KeyValuePair('Ã', 0x41); + yield return new KeyValuePair('Ä', 0x41); + yield return new KeyValuePair('Å', 0x41); + + yield return new KeyValuePair('B', 0x42); + + yield return new KeyValuePair('C', 0x43); + // Variant + yield return new KeyValuePair('Ç', 0x43); + + yield return new KeyValuePair('D', 0x44); + + yield return new KeyValuePair('E', 0x45); + // Variants + yield return new KeyValuePair('È', 0x45); + yield return new KeyValuePair('É', 0x45); + yield return new KeyValuePair('Ê', 0x45); + yield return new KeyValuePair('Ë', 0x45); + + yield return new KeyValuePair('F', 0x46); + yield return new KeyValuePair('G', 0x47); + yield return new KeyValuePair('H', 0x48); + + yield return new KeyValuePair('I', 0x49); + // Variants + yield return new KeyValuePair('Ì', 0x49); + yield return new KeyValuePair('Í', 0x49); + yield return new KeyValuePair('Î', 0x49); + yield return new KeyValuePair('Ï', 0x49); + + yield return new KeyValuePair('J', 0x4A); + yield return new KeyValuePair('K', 0x4B); + yield return new KeyValuePair('L', 0x4C); + yield return new KeyValuePair('M', 0x4D); + + yield return new KeyValuePair('N', 0x4E); + // Variant + yield return new KeyValuePair('Ñ', 0x4E); + + yield return new KeyValuePair('O', 0x4F); + // Variants + yield return new KeyValuePair('Ò', 0x4F); + yield return new KeyValuePair('Ó', 0x4F); + yield return new KeyValuePair('Ô', 0x4F); + yield return new KeyValuePair('Õ', 0x4F); + yield return new KeyValuePair('Ö', 0x4F); + yield return new KeyValuePair('Ø', 0x4F); + + yield return new KeyValuePair('P', 0x50); + yield return new KeyValuePair('Q', 0x51); + yield return new KeyValuePair('R', 0x52); + yield return new KeyValuePair('S', 0x53); + yield return new KeyValuePair('T', 0x54); + + yield return new KeyValuePair('U', 0x55); + // Variants + yield return new KeyValuePair('Ù', 0x55); + yield return new KeyValuePair('Ú', 0x55); + yield return new KeyValuePair('Û', 0x55); + yield return new KeyValuePair('Ü', 0x55); + + yield return new KeyValuePair('V', 0x56); + yield return new KeyValuePair('W', 0x57); + yield return new KeyValuePair('X', 0x58); + + yield return new KeyValuePair('Y', 0x59); + // Variant + yield return new KeyValuePair('Ý', 0x59); + + yield return new KeyValuePair('Z', 0x5A); + yield return new KeyValuePair('[', 0x5B); + yield return new KeyValuePair('¥', 0x5C); + yield return new KeyValuePair(']', 0x5D); + yield return new KeyValuePair('^', 0x5E); + + yield return new KeyValuePair('_', 0x5F); + // Variant + yield return new KeyValuePair('‗', 0x5F); + + yield return new KeyValuePair('`', 0x60); + + yield return new KeyValuePair('a', 0x61); + // Variants + yield return new KeyValuePair('à', 0x61); + yield return new KeyValuePair('á', 0x61); + yield return new KeyValuePair('â', 0x61); + yield return new KeyValuePair('ã', 0x61); + yield return new KeyValuePair('å', 0x61); + + yield return new KeyValuePair('b', 0x62); + + yield return new KeyValuePair('c', 0x63); + // Variant + yield return new KeyValuePair('ç', 0x63); + + yield return new KeyValuePair('d', 0x64); + + yield return new KeyValuePair('e', 0x65); + // Variants + yield return new KeyValuePair('è', 0x65); + yield return new KeyValuePair('é', 0x65); + yield return new KeyValuePair('ê', 0x65); + yield return new KeyValuePair('ë', 0x65); + + yield return new KeyValuePair('f', 0x66); + yield return new KeyValuePair('g', 0x67); + yield return new KeyValuePair('h', 0x68); + + yield return new KeyValuePair('i', 0x69); + // Variants + yield return new KeyValuePair('ì', 0x69); + yield return new KeyValuePair('í', 0x69); + yield return new KeyValuePair('î', 0x69); + yield return new KeyValuePair('ï', 0x69); + + yield return new KeyValuePair('j', 0x6A); + yield return new KeyValuePair('k', 0x6B); + yield return new KeyValuePair('l', 0x6C); + yield return new KeyValuePair('m', 0x6D); + + yield return new KeyValuePair('n', 0x6E); + // Variant + yield return new KeyValuePair('ñ', 0x6E); + + yield return new KeyValuePair('o', 0x6F); + // Variants + yield return new KeyValuePair('ò', 0x6F); + yield return new KeyValuePair('ó', 0x6F); + yield return new KeyValuePair('ô', 0x6F); + yield return new KeyValuePair('õ', 0x6F); + yield return new KeyValuePair('ö', 0x6F); + yield return new KeyValuePair('ø', 0x6F); + + yield return new KeyValuePair('p', 0x70); + yield return new KeyValuePair('q', 0x71); + yield return new KeyValuePair('r', 0x72); + yield return new KeyValuePair('s', 0x73); + yield return new KeyValuePair('t', 0x74); + + yield return new KeyValuePair('u', 0x75); + // Variants + yield return new KeyValuePair('ù', 0x75); + yield return new KeyValuePair('ú', 0x75); + yield return new KeyValuePair('û', 0x75); + yield return new KeyValuePair('ü', 0x75); + + yield return new KeyValuePair('v', 0x76); + yield return new KeyValuePair('w', 0x77); + yield return new KeyValuePair('x', 0x78); + + yield return new KeyValuePair('y', 0x79); + // Variants + yield return new KeyValuePair('ý', 0x79); + yield return new KeyValuePair('ÿ', 0x79); + + yield return new KeyValuePair('z', 0x7A); + yield return new KeyValuePair('{', 0x7B); + yield return new KeyValuePair('|', 0x7C); + yield return new KeyValuePair('}', 0x7D); + yield return new KeyValuePair('→', 0x7E); + yield return new KeyValuePair('←', 0x7F); + + yield return new KeyValuePair(' ', 0x80); + yield return new KeyValuePair(' ', 0x81); + yield return new KeyValuePair(' ', 0x82); + yield return new KeyValuePair(' ', 0x83); + yield return new KeyValuePair(' ', 0x84); + yield return new KeyValuePair(' ', 0x85); + yield return new KeyValuePair(' ', 0x86); + yield return new KeyValuePair(' ', 0x87); + yield return new KeyValuePair(' ', 0x88); + yield return new KeyValuePair(' ', 0x89); + yield return new KeyValuePair(' ', 0x8A); + yield return new KeyValuePair(' ', 0x8B); + yield return new KeyValuePair(' ', 0x8C); + yield return new KeyValuePair(' ', 0x8D); + yield return new KeyValuePair(' ', 0x8E); + yield return new KeyValuePair(' ', 0x8F); + + yield return new KeyValuePair(' ', 0x90); + yield return new KeyValuePair(' ', 0x91); + yield return new KeyValuePair(' ', 0x92); + yield return new KeyValuePair(' ', 0x93); + yield return new KeyValuePair(' ', 0x94); + yield return new KeyValuePair(' ', 0x95); + yield return new KeyValuePair(' ', 0x96); + yield return new KeyValuePair(' ', 0x97); + yield return new KeyValuePair(' ', 0x98); + yield return new KeyValuePair(' ', 0x99); + yield return new KeyValuePair(' ', 0x9A); + yield return new KeyValuePair(' ', 0x9B); + yield return new KeyValuePair(' ', 0x9C); + yield return new KeyValuePair(' ', 0x9D); + yield return new KeyValuePair(' ', 0x9E); + yield return new KeyValuePair(' ', 0x9F); + + yield return new KeyValuePair(' ', 0xA0); + yield return new KeyValuePair('▫', 0xA1); +// yield return new KeyValuePair('', 0xA2); +// yield return new KeyValuePair('', 0xA3); + yield return new KeyValuePair('ヽ', 0xA4); + yield return new KeyValuePair('・', 0xA5); + yield return new KeyValuePair('ヲ', 0xA6); + yield return new KeyValuePair('ァ', 0xA7); + yield return new KeyValuePair('ィ', 0xA8); + yield return new KeyValuePair('ゥ', 0xA9); + yield return new KeyValuePair('ェ', 0xAA); + yield return new KeyValuePair('ォ', 0xAB); + yield return new KeyValuePair('ャ', 0xAC); + yield return new KeyValuePair('ュ', 0xAD); + yield return new KeyValuePair('ョ', 0xAE); + yield return new KeyValuePair('ッ', 0xAF); + + yield return new KeyValuePair('ー', 0xB0); + yield return new KeyValuePair('ア', 0xB1); + yield return new KeyValuePair('イ', 0xB2); + yield return new KeyValuePair('ウ', 0xB3); + yield return new KeyValuePair('エ', 0xB4); + yield return new KeyValuePair('オ', 0xB5); + yield return new KeyValuePair('カ', 0xB6); + yield return new KeyValuePair('キ', 0xB7); + yield return new KeyValuePair('ク', 0xB8); + yield return new KeyValuePair('ケ', 0xB9); + yield return new KeyValuePair('コ', 0xBA); + yield return new KeyValuePair('サ', 0xBB); + yield return new KeyValuePair('シ', 0xBC); + yield return new KeyValuePair('ス', 0xBD); + yield return new KeyValuePair('セ', 0xBE); + yield return new KeyValuePair('ソ', 0xBF); + + yield return new KeyValuePair('タ', 0xC0); + yield return new KeyValuePair('チ', 0xC1); + yield return new KeyValuePair('ツ', 0xC2); + yield return new KeyValuePair('テ', 0xC3); + yield return new KeyValuePair('ト', 0xC4); + yield return new KeyValuePair('ナ', 0xC5); + yield return new KeyValuePair('ニ', 0xC6); + yield return new KeyValuePair('ヌ', 0xC7); + yield return new KeyValuePair('ネ', 0xC8); + yield return new KeyValuePair('ノ', 0xC9); + yield return new KeyValuePair('ハ', 0xCA); + yield return new KeyValuePair('ヒ', 0xCB); + yield return new KeyValuePair('フ', 0xCC); + yield return new KeyValuePair('ヘ', 0xCD); + yield return new KeyValuePair('ホ', 0xCE); + yield return new KeyValuePair('マ', 0xCF); + + yield return new KeyValuePair('ミ', 0xD0); + yield return new KeyValuePair('ム', 0xD1); + yield return new KeyValuePair('メ', 0xD2); + yield return new KeyValuePair('モ', 0xD3); + yield return new KeyValuePair('ヤ', 0xD4); + yield return new KeyValuePair('ユ', 0xD5); + yield return new KeyValuePair('ヨ', 0xD6); + yield return new KeyValuePair('ラ', 0xD7); + yield return new KeyValuePair('リ', 0xD8); + yield return new KeyValuePair('ル', 0xD9); + yield return new KeyValuePair('レ', 0xDA); + yield return new KeyValuePair('ロ', 0xDB); + yield return new KeyValuePair('ワ', 0xDC); + yield return new KeyValuePair('ン', 0xDD); + + yield return new KeyValuePair('゛', 0xDE); + + yield return new KeyValuePair('゜', 0xDF); + // Variant + yield return new KeyValuePair('°', 0xDF); + + yield return new KeyValuePair('α', 0xE0); + + yield return new KeyValuePair('ä', 0xE1); + // Variant + yield return new KeyValuePair('ӓ', 0xE1); + + yield return new KeyValuePair('β', 0xE2); + // Variant + yield return new KeyValuePair('ß', 0xE2); + + yield return new KeyValuePair('ε', 0xE3); + yield return new KeyValuePair('μ', 0xE4); + yield return new KeyValuePair('σ', 0xE5); + yield return new KeyValuePair('ρ', 0xE6); + yield return new KeyValuePair('ɡ', 0xE7); + yield return new KeyValuePair('√', 0xE8); +// yield return new KeyValuePair('', 0xE9); + yield return new KeyValuePair('ј', 0xEA); + yield return new KeyValuePair('\u033D', 0xEB); + + yield return new KeyValuePair('¢', 0xEC); + // Variants + yield return new KeyValuePair('\u023B', 0xEC); + yield return new KeyValuePair('¢', 0xEC); + +// yield return new KeyValuePair('', 0xED); + yield return new KeyValuePair('ñ', 0xEE); + yield return new KeyValuePair('ö', 0xEF); + + yield return new KeyValuePair('ρ', 0xF0); +// yield return new KeyValuePair('', 0xF1); + yield return new KeyValuePair('θ', 0xF2); + yield return new KeyValuePair('∞', 0xF3); + yield return new KeyValuePair('Ω', 0xF4); + yield return new KeyValuePair('ü', 0xF5); + yield return new KeyValuePair('Σ', 0xF6); + yield return new KeyValuePair('π', 0xF7); +// yield return new KeyValuePair('', 0xF8); + + yield return new KeyValuePair('У', 0xF9); + // Variant + yield return new KeyValuePair('у', 0xF9); + +// yield return new KeyValuePair('', 0xFA); +// yield return new KeyValuePair('', 0xFB); +// yield return new KeyValuePair('', 0xFC); + yield return new KeyValuePair('÷', 0xFD); + yield return new KeyValuePair(' ', 0xFE); + yield return new KeyValuePair('█', 0xFF); + } + + #endregion + } } \ No newline at end of file diff --git a/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnection.cs similarity index 99% rename from Raspberry.IO.Display/Components/Hd44780LcdConnection.cs rename to Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnection.cs index 027be2e..8846512 100644 --- a/Raspberry.IO.Display/Components/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnection.cs @@ -9,7 +9,7 @@ #endregion -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { /// /// Based on https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_CharLCD/Adafruit_CharLCD.py diff --git a/Raspberry.IO.Display/Components/Hd44780LcdConnectionSettings.cs b/Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnectionSettings.cs similarity index 92% rename from Raspberry.IO.Display/Components/Hd44780LcdConnectionSettings.cs rename to Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnectionSettings.cs index fb3b045..a67382d 100644 --- a/Raspberry.IO.Display/Components/Hd44780LcdConnectionSettings.cs +++ b/Raspberry.IO.Components/Display/Hd44780/Hd44780LcdConnectionSettings.cs @@ -1,6 +1,6 @@ using System.Text; -namespace Raspberry.IO.Display.Components +namespace Raspberry.IO.Components.Display.Hd44780 { public class Hd44780LcdConnectionSettings { diff --git a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017I2cConnection.cs b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017I2cConnection.cs similarity index 97% rename from Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017I2cConnection.cs rename to Raspberry.IO.Components/Expander/Mcp23017/Mcp23017I2cConnection.cs index 2bed665..d9c76e1 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017I2cConnection.cs +++ b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017I2cConnection.cs @@ -1,4 +1,6 @@ -namespace Raspberry.IO.InterIntegratedCircuit.Components +using Raspberry.IO.InterIntegratedCircuit; + +namespace Raspberry.IO.Components.Expander.Mcp23017 { /// /// Represents a I2C connection to a MCP23017 I/O Expander. diff --git a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017Pin.cs b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017Pin.cs similarity index 86% rename from Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017Pin.cs rename to Raspberry.IO.Components/Expander/Mcp23017/Mcp23017Pin.cs index 9dc8681..c06f055 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017Pin.cs +++ b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017Pin.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.InterIntegratedCircuit.Components +namespace Raspberry.IO.Components.Expander.Mcp23017 { public enum Mcp23017Pin { diff --git a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinDirection.cs b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinDirection.cs similarity index 58% rename from Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinDirection.cs rename to Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinDirection.cs index 85b6ae1..f32c738 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinDirection.cs +++ b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinDirection.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.InterIntegratedCircuit.Components +namespace Raspberry.IO.Components.Expander.Mcp23017 { public enum Mcp23017PinDirection { diff --git a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinPolarity.cs b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinPolarity.cs similarity index 59% rename from Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinPolarity.cs rename to Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinPolarity.cs index 9d14c4b..aacb81d 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinPolarity.cs +++ b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinPolarity.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.InterIntegratedCircuit.Components +namespace Raspberry.IO.Components.Expander.Mcp23017 { public enum Mcp23017PinPolarity { diff --git a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinResistor.cs b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinResistor.cs similarity index 58% rename from Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinResistor.cs rename to Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinResistor.cs index bdb99e1..3a225c3 100644 --- a/Raspberry.IO.InterIntegratedCircuit/Components/Mcp23017PinResistor.cs +++ b/Raspberry.IO.Components/Expander/Mcp23017/Mcp23017PinResistor.cs @@ -1,4 +1,4 @@ -namespace Raspberry.IO.InterIntegratedCircuit.Components +namespace Raspberry.IO.Components.Expander.Mcp23017 { public enum Mcp23017PinResistor { diff --git a/Raspberry.IO.Components/Properties/AssemblyInfo.cs b/Raspberry.IO.Components/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..08038bb --- /dev/null +++ b/Raspberry.IO.Components/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Raspberry.IO.Components")] +[assembly: AssemblyDescription("Raspberry Pi IO Components")] +[assembly: AssemblyConfiguration("")] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4fa05c29-4c49-48c9-a04c-7edfcd3dd944")] diff --git a/Raspberry.IO.Display/Raspberry.IO.Display.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj similarity index 54% rename from Raspberry.IO.Display/Raspberry.IO.Display.csproj rename to Raspberry.IO.Components/Raspberry.IO.Components.csproj index 383560f..f79c5a0 100644 --- a/Raspberry.IO.Display/Raspberry.IO.Display.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -5,11 +5,11 @@ AnyCPU 8.0.30703 2.0 - {F3E6F476-7088-4169-8E09-AE19EBE46C0E} + {8388CFCA-E3DB-43F7-B049-2CB195211CE8} Library Properties - Raspberry.IO.Display - Raspberry.IO.Display + Raspberry.IO.Components + Raspberry.IO.Components v4.0 512 @@ -35,27 +35,48 @@ ..\packages\Raspberry.System.1.0.4\lib\net40\Raspberry.System.dll + - - - - - - - - + + Properties\SharedAssemblyInfo.cs + + + + + + + + + + + + + + + + + + - - - {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {63B8403E-BC56-43F9-A045-F61ECC3871F3} + Raspberry.IO.InterIntegratedCircuit + + + {326342E5-0411-40E8-9F2D-563D6B192568} + Raspberry.IO.SerialPeripheralInterface + + + + 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%0A5^@5i4stoA74iV3 z6VgplXEN2opDAg`$n$OOQ90kJm|}`Lw<$S~QUs}^Bp^>w${}khRSzL5mhhVr4&GZq!dB6tFY}!K#C~kkdrA@kV`2|kUJ=CkPb>05{Pq=t-TadK&gbpDRq!iN-Ly_(g|s%^guc(X-F?6D(70&3um5f zPXVNWQUr-p5|C0#Ii!kG1!<-4Kyw>bgg@aQLORt_-A@k}KCDDrOEP25F+iAumyq zkPVay$hMc+x@sYNQ<@>uDeaJpDcz7pin>}-Eqt2d$Tf|U9!fssXG$St_yXIW6379R zQpik7CFGx!I>=H=E9BplPA!d2ugK2w3vS|-RJ1a!aky2Z`orrl?M170( zFYX#h3XzZoZtQ9H-v7QsjP-om^ke6H0Cq zX%pGmRc99^%S8SyGRn=Bg=NS$`2*8dMoB{?k33Zlp%5sP%$H}urZ?`2T~?M zPNS$ZkSbM6nGLz0vJmnHWr>!0XOoE9oBrl5)6$pokhD1^Ega*n(PH);HDbHFYX``i z(y!g!O-7=V&vu;mMfPy}Aq`2#S*yjDvy0=bbhfO@(R2sv8TIWfP5`7 z!A%*7j*;>CNu>!nNK1B`PIBW~8l$_O=Q#c^jx)(E(NfQSXOi2gB|FC^ zxhWIl%$CesN~r_gn4F~s?xzR2g<7(u4su7xnM3W}S4b%}dk=QiSxQNR$aaz^?pA53 z)|qz_In?dYlAX_oxhu3}Gau$|K%NIA&uA%C?8fAHsxrR`IovJNlFc*OovkICXR_OX zQa_{A5pFkR$7++g#2q4g{=l9d>E>z4<~h<;M^9Dz5h!((TlxP=9qm^AzfwoLt^Y4( zire=8Vy3t~TI!v@OJ+6l$GG`&EEw3HscwOm>=vBrs@X3wdVg2*XR2EVIaZDUYW_@h zmq2>t47-P9KGto4tQXl^OB=+_)r8v)v2!)yu7KFNdYrooV(02{ZV%)i(hJp|X>Kp% zY7y0*Y3>F{Jz|b`)lpCN;x5D-?>e%b2KIfr8`aY2JR&g@rOngbd5~vB4iP!Q?#n}8 z6FE}kB+4fusy$ix@=sEHy5kI$*~^%qUt*5edHVlfdroqF`TuMSPu4LLv|OdHZPeG! zlWwtziH292+D~?;K(-N4qj9pEgp8KjRSRdhrI39@RLl&wMN8ix+ly1&Wf0qoQ{3fR zs-vTj`4qPkF}7bb-7bh7pPB9kBRRIGGu>P%Kk)1@)6Iw2v%^fc3}Vj?r@C!g%s!~v ze5yO-DwU_+*;oFb*)kfZaa$~%ZF-s&J2SIl=V4Y3l|1UNNMvQ|pX6kbxqqnZ>_5r8 zKgm@h>N+!<+0O8+G)s)yI$2rvCwcx)^7@~|&iQPfcO*uA2|p`eiCp;y86;zQ!yn|= za~lqH1oaex2c}@@gMUV%DAE#vr5R z-^V1+nQkFuKl%3=Et8DsIj^os&T@+pQzHMW%xAe%AScVeYHpn6CLy-=GPe|BYcF$W z8)4?N-Fb+y^XF`L0pvXSS7koit%ax=rD~t$)!o9%;&o$kVldEe0PzSzCm_w%yt{JR7Z2=8sIIdYqr~r7(0f4 zcUzIij^W?k_FUEG3U@u^HMF_HO+(ba ztYR*7qgR`G_%32Dbn_r;Usf@5-4PHqmTKhZx-p2_yH(6ZZXx6w#9ZV~f~cc}ikasY zLpCF3o}19pH^?3nE_RcM87wXRQMS&-ZW&_iQDVM38!`4gINz;Aj6H5#;#MJMH_4;g ze2KdVG4@DO={6u{Z^Tr(&4{tbjeoeUh_UC&f4IvLV~;&^c1k%zSv{Y#MWYBgZ>e{B-T?CmZ zqRs`?ZY$(e$_mI;lwQb#BI+zt?H1Ik_IxsE6{QriQA8b$tKFh&O-#P@Mjf%M-BH&W zIYvYs)vMhyE!q9O+O5@6?<|m*nDpXGw;Q6ya&M8V+zHp~(cm#^p*u-Sz4NfdOp=&| z?i9!yB8Q1w?M{b$BclFxNsU_u$(8<{Byx>A8?vWJnMkcW4|0ac-$kxp*PtH@1m9^?~| z$3*Jf5s)2Zbk&yu>)i>E<3(N;x!IkkrO~-qWR=Kbw;wTAio7e*;C9_$>bgnfW070j z{5m6di)<8Wa(lHjI{y;+Rpd6euHMAFC^D$uaqe&@+-&3nk!?kmxEaU>kzGXYbZZxz znBPPSMV7h^4Mw(*ZF``|UG5slE+Ugfn%xbM{X|X@x!cXX#gsZ)WR}Q1ZX9yD$R#58 zx=G08BI@t9w73f(cZ%F9a-Z7;=@4lZx!?60P3HGR9v6AQ9Rb-WqP~IH>c%0VY`3>W z9&{HO;XUI+?piH1(H$j59Yr5<*F$y_QAf6i+_aYLoPXHOyH(ZRm!qyB*GcAOZlRWy zj=hF_#GRrgdms0RJ6%imJot!PYGQcZ@`zgwu~!a{xbq-|s)bV5qwWI8!6M&lsnwEg z;bU%(iQyjC=Jsl7bf!wF%~Gn(jW(%XG&-|HJo#?p<8CSBA0knaC)_&7jUwt^_+M^| zmU?FiVwSs=x9M%cQGL=)YcYM#k+aN`u5-JJsfntyuzCXXlpEDj9aU#x74wvvr=`(( zS~71XwLk5~wA4GVL)zUGWWC6?67!53zeCsVq(%NJ@~qnl*(@?rq{AJx#Kc5pulk$F z^X?SLUq#e2&llV($T$&owE4GN2bn6Oj!~U%vk~_6MR${yYL4@ZZoihs=o~3EUg~<$ z_3u=*_vP5@)fe5Umh4P;+0D~pMrss>ki7$X z#a%EU&r}`LHb7>Gyy{L^YPN-%QRVWD<1Tj+#NJzVxy4$tnY-L_E%nZ2(yuclPZ#fi z)YCb&@4V(#m^>Vf*WAhhqV6kSa~BQ}bzk|qTc@ROkj?WSce$2&=NhT2T4aS-@6@J`f_Z)zIRs)5Y?|A+*J_UuZ-I> zKvchecGp8}zkYSo5ZkZc+#c23?WuPj6Ui0%ixC3U(YmB!EFWw+pXuN`8y;9lOMhfIv!f)l**hfQ6hB+nU= zXFo4@nTfI6bfVV@vDIT2FqE1#u)zOtA>bhmRSBIF@h&jP) zLQD^0PVia~vra_K%oDw3h}k5f?hsG(q?_{J${@T+RwreKpX9acn7$ks3PT7CA}ee6JSrsK{v|v%NaVb0X)9{M~DUbctLpGRJFyyerZm za)GxT@~OyDkqf;QkZ&P#y)}^EMedWBi@dd38l9naInJXZ^Sl(~^uNnBi^zO0_LS;Z zqcc)sUKP2-Yl2J=c}wInZ^Y9kX0pgfB3F2E$O$5!iCpECLCQqF5xK^j2bnMOlgPDR z26DN`5GTjE-kZ>FGAkJ_vdC+ITr0At$c^4A$YPNLMC!bvXU(>FOk}c1y_bY^icAw} z@JbaRqS32F%og<~=2ou?F(XA(%&p!c6Qk#I zC^M?bOKCCJ{AE(t?cS*8R134${C99q*}WjZEzn{{Y=z`` z%xl&nZ{W!FnEEpNp+V!qTdg)2=dC4+M0 znSxgi@o&zNKW~!bJm)Qf>>#qeNQc)B*;8Z}kr%v8kc5c3v+MN6zN#`eI%kONAu%s{ zlOTVGyzEWUQXgF)vY*7f;&o_Q;oKxLS?(rY@luebkd!b?>WQftKv- zea(w$$!@RLya`$wo#&<0fl}9N-U7&*BE=%Fd$HHdXnZO%Rb-V{_J)yfL{1WU(`$zO zDsr00+g=xBkUZx&M`VrH3&|ImBl517fs7JS?+Crey=hO8?_^JTpHloMIrUF+-k;>M z|0gSk+Es@4y&bQ(m|S@?ag+z8LPJ#5dpr^sElT&q)p<#H}K zSMG^=yb4{)jQnMi`2(+NfLtT;k(YQ=)t+64{n$%tsgBxp*pIz3#I#6z)N$i~-fYA? zBchI?|MMylqwY@|By+DN+ojJbkEZotNy^Ep#@E zs8Z{^g#+XXkx#uIEsf4r@?7c}k@a55TV`&kd)Q8q&%Ei7Z6xMZkv?yxmTG5j5tZk2 zuR%+8uBN;eEi0U(Bxbe5q`YNX8l5ES`ofF8t?F7FJxk2JF<*I$-Z5={N@SzR*IwQlBd?46DDsUrUCUxe$!{WQZ^OGL<`a?7&2hf< zHbFLtsJ?&aIq#_$)2}UM&;8!Z9U$rmxydUSAVVe3k6x9L=$5ybE5@I_4#)^f-upUp zbb^SwhWy!^0GWcAU%Um7nTYwtTcV}jnJuD@NWXGE&lOQ;tA5JWBI-F(R&EthSFl<6 z*PrCoKgru7!=+!@QoSO(4wT@nQpXwp2l+{2)QUVyac#ZdTdRAqkb7mnw_Z!%AiGM{ z?`=Te?J8BjmqCnrKBk`h|K>S8W(@6H4ZnFqwDb+Kt5lo4JjB>ls?A;jV(j|z?_LZs zYL#k#>BaBf1jN`CXUCs}7_~~JVjRB&F?J0)$4?+etu7rZF**KB#Mo77*DphiTFFu| zu3v!|yH4%-m55O*St`c!7b3=PW#6xb*sbjQiy(F-%l8|Q$F5}gelue1N><>vBF3&{ z1^#lx*p;l%??8-Q$qM~0#MqUrh~JGEyOI_0*CNKQQbqmsh$&uZj($-;jTpO1HOS8( z#;#Hg^8F9gR?e<+4)%v=$*yt^_VW>AXZRNW2#B5GTlk|Oc7|`^#~^lwZ{Zhesfljc zD6>~aehYsRV(fa{5Wg5Pc0F#0pFoUSBU9@{L;WOT)Ee0dl4q!2h8Vm0zokDLF=~yh zRARRDD-mP&udVzg5c`I}R(^|?>Zp2_f4-F3%5T%MGRN+5x&C@nD#z}XxxNgb{I`<( zpp_NDM9HJ}+^ifSqW11we}m4mP_MbD_X=|Tf{)a;xWzd`V$|_xYrjED_C2&={t_+q z&czaQiR2mPw`eg(QFYe)i(j->@45O2pq>cj`AY`KLMgSaKjgnE#yrowNo0G!Kub;Z zX34CMV>|d0v@DDsJwu+vYnh~FrDNZ3*}+d}S>f28?%K^_)E!nG-asGk`?7Q)lz`h%w6}9g4 znA|&L8R3uLMMdWCa!zeko<;e3Yxx?`r z%os-P+5BjK3B;bekM>&zjPq-9)qS+zff&2Sag4uKi@EN-TrwZyM^k3@+BL+fehgyY zZJuh|Gt`bDg(F58YDaadA2)e&>=;hf(_t=`Ye!9i1V^I`v#V={IS)Dq1L+mr1FU z{btA^B2Q>prX~Apiy3|g#P)rL-)V%uwwU2h`a+F!Uykj?48HQREE2K})rBiO4FEGyPV`wIc6}oaJ|DF-Ly2@09r~v}E5! zFY||drD|UsweO;r`FRlgE_#_i0&<6BR`2|u?N5L_PniN)ODTh7C<`F@x7$1okbNl2 zAjeWxKrW!Hg)E|Mg4|CTvcdH0HOeT+7nDhm@DAIa>5#FM*^px?3n3R!mOyTxEQhpG zRzcK?u^Gelkad)PNX`-)llQgh#SWCQkb^13kkcqLA(v9-L2jiif;>)X(URSp&h|S7 z$avO(lLfBgVaZ_3T_Hw}MK1K~w3wNx-lLx9uhL>x z?bZ947yD~WDZOg1GGFZXBBo2)tgaL0`zgeHB%;nc^ZiX)%$<1P%axNq{To$#qq9+B zhKN-9WssjBm-_Rx)H~swInFi`v%t?!n^N0}s61Er6SUMjV?}lrsq!nd^yM5XGDf7@ z?-(HCMXvOVztwr7QzT|zk*oYNh+0usaL}?^JtMI`*C9I=>8J&js~9a^%o5&rJsKLLpJF={9W7aex4C$yuANB zOY+?Amkf{#MDFyPv{XAAC3B@nv+w_)^3*%7tmoH=-0M%*QsWF4QR~$A`Au4?ofxFm z&->Aoii^}qsfYbyE!ECUk=sNb^;@(oc4mp(Bl5WK{A5Zk5LqVjFF%=4QtjL#qMj!_ z>33+UcUnZ$bM+_v3`9L6dQM6`WzTU#?R9uN#h$IQ(k^+__0Kbm8CB{yyUG<>R>q6$ z{s&owQqQuKJ?mxV6N!0Q+LM(ZA7>*^UbGTi zeVVN6Nqb)UgY<~J@&{Qb@*3rC$)ifW@dr^c-G7h`B5Np*p;XTwM3wr;%1}G<|D)KE z&x#%StUP(4!2_?^*c}@(D}*1X)KJ)@-)Lr<6j-ddd{YXO#0HeUw_r z=T?GN5jBRXKZqKQuP7Z7(=YPPA4HYX?*;^z>@;E`i-oMNdNj-JU3G#ndd!-RCkf%n$gaNX(h#ySR zV$Mx}6Nv=NwDjfJ_G}Rp|7!N`AEnJD60=26(r+ZVJI6UzWJoamHzRo>Gem|4b(@Xs zftam=!rztj<=B4Z2EC4Y4W`~XN@8Y7sjY*e93_1@wx`2_a)|BeUxHRG_0FkMYOa*Z z3zkFXi!2b?Cg_4(57{Y5gQFQQsFJQx8PdXFjf z*B}PjO+>|v2qr-eLCg+8sg_3P6pj=StYW2Py~5E^pCJ2kQ}|Rx46c*WN+egX>b>W+24pb#>o@)%mE@pv`9tr-^yT`$X`Sz21y;0y=yxtm^VQFB4?R{f+a@yCgH(Bit3b~ZB400Q#4bnzgu4Q3#mB`N0o`Zu9E!ENYMRwEDg;MKKDjuxTQsev}qQ)m4 zv_{O__(f!#lsY7c%8%>SnR>ex6LV;=Ov{R#u_F6O%wa(rLZC4x0Z9NYIqumPfGi|XldLGEDHixrL?jcGximKx_9Y2h?EVjqw3Ss4tuPu{(h zQqw6rid-ymLeOGL>Am1ekrRUsBisv;!3r(ey&xHMBWA4RStO-S4tfx?pUBNx)@#XL zEzbyww@_`)UK`H{mP72d@hO2nM8%jfyiM|)5{xhsJybF`i_8p0X{nA*7f~@YgF?ip z-$1FDQ-dOi`VEwdIW;JT%#u=S?>;S2}11+AEN(*ej5%ERa0v zzNyrf3a%EpU+T)rTcz^0n8=xoxkX}z%RD@r(juasOwOXTiKzRpb12V=sCPKaDJvo8 zQq-Fm|B{&V{vc0F?XxNGA@dx{=OQa4<^sxhkP6DLBL9(?3n^RNZ)7fITgXMhay_cq zcRc0=9a_wrGjB_tdBF-TeS_>c&kI&T>^RR0dLVY3FAjQ*D2Uze_XcHJ7COgB zU25-c36^MCk#m}e>gjz!o0h&DyG`%6dlR1$KVT)8Bc;|!n;!@^=~8AZe<9KuO#h2& zPv0Q>Z27@pk&zr*>cJqT#rz83TPgKWkcKRf%o&k~gAC*bk>5p@1%95&Z0ZUlInEa_Ib+%2V!5P3RSrR9^H$3zlZ)|i+I8O(?kPRXy=$I7bSCLb+ zY%r1&eL&9CTKsKvPqkbi(jJsT4x8aPl_JjsYX?ZR$g@F8OSO~tfc#QPf}`{e)qpci7Vx<3foc2K3Nor|PBr%C4j2L6slDn;gt{4a=W z>C3TeNuLCZAa;#xeXtCrYNS+^lv*EjX<6*tA#$t8XF(dJ?Ak3K^_z75cxJ(0C`SCmHIAN2zgcHKO)};iy$A0 zs4L-3K@;R_$PYmaB$W61Kaf&C2ECANMAX&tPeBT@n}~XwHxs0_WRE{T2N^9j&i)e9 zCwYDjq9aXD?GfqMpiqn1?rJ@yKPVX>>Im5%lnoGdF8D22FhJCr)bByl0NE&Y<%Iq& zs;=yu_rp9bHC&VO!x0d>Cgq1Ql(I832*+y4uHy&c1TERst{{w?QkU6uXNz00yN|7aUwVWRo|4qfL z$XO_Iw3OODoHszGi3|^0wA4GdO3VzA5n&qgsK{9&JB1lYC!`>hk4mXt=(`fNhPZP$ zN=sw(eTkVXrACH@S{6H>id1T;)w0sDM4pl6iK34bCu|54;ST;bWN$q38d0H0B&rHqg(%7(JfGm`lv0=ZK zdS|G_G>VK1C+(p!XRq1Dhvi0`Jc&^~9Um^xVy>3&)Ur@Z_KJFZxJXNOj~gF07~vUz zeAuKVTUTM&qQ&fS_e$o%FlB^m;`@eaE!9!`hTFbjKVs}E`F^24PW8h40#vOx?HA^1 zsfmu1Ui?ck7lrwdB9UjbjDpzTD()YSMIQB=S#<}!e^`W=sZvUvQznLS#GEIh-bkDn zPC-l!Vh#wWBc>TK2ZW_sviF{o!di&E_dGD{hS)Xw1H+m6GhAkUr&HQ|VA!O^jF>ti z9TYAfD6*#<9L5UGXxLSTL&8FcU1c~VoTR13+45|8hgvcp8YTzGTUx3h&q^=Us{LW% zGRR8E;o(}y+al`ygd@Vt08#Ht92pkusoGQHd?YbzCG(VUx|V83l}d>u!g&MaN0I4a z?Ou9jIzLKGFj(&K!>YY?zZ`i@*BK@{tbt3=KY7eX!+xmjdZ*bKQ^)vuc9XCl99 z$<@;6{2=0PA?*%}OpHE`sbkBWFpijhiP=(O=7h-svYp5UVda2Q1tJ%QwTRhnH+do} zGB<1=AbW~j6n1Ip%h_s~IgZT>d$eTt_j#dTWVXe25~JSxniod3EOthTsCVP%g_9tA zK`stwn^Js(Yks&;OJg)HG3qOh^TS1uX_N*d&fi5;UGu{wf6B8QG1o}ULDGx);U>t9 zBC0)?gvtF?n;RV^M@UR%*bQkBIY#8tPy*z?l|vsFIZ@=Flvg2_Q|xN#6%@N#S`{WI z>TRmG*O`*1IxIKh^h%!DB3Fjpkd%nprdNf%TC(>$SA{7p+54TV!n7%+GppaoUlsNb zkc%Yq!Z7auGo#XySv^Op2}fwDj&2rFN1K{3hL|Cbn75{{2@4TZAfhr~6HYQQx~_jn z=Gw4%fK-cI7j818bjyywPWwU8p48u zRH^I}yvDFdi#cN7CGBYpXKTs!v?;9BlI>|zSoi<(G;y{ZCjC+?&RIEDM4g+ma=wT< zH&KFXMAY-T+iafTPRQ+6hN_wQu(a?Fikg{9mQWs*QcsKAN$G?vwGyb&cv)iZ`h&bF z(oA_*N_`@74`rRmMv;3dYUF5sg8axZT5%AbBVCQ#ON8Ndb%u(#?Ab( zqw#1s0%H61SU4MEN8|CZ4Pr;*iLeu5x8T3RUWna-%R}c7RadnWdDQH=Plowg>YW`# z21^T{3>Row>`V~(i^x-9Ct{|Gj1YM`Odh84)H}08b`@z4D~gR&i>Tw_v*9u=)y_>K zs_)N*9f)~QWKS(CARQtHiFAZ(As>nyF7kYsd$`G*5jj!hg>X7#+sEXHE%NVh9%O>Z zbt0W%Gh~{G%KT#34yh1%P~@es8*(FJUJg@`Wsnu2GuhO>TBJ=%y%Od_(jqU4tPBev z!`e(;uZBgC2_mYlt}tPQ=cd;@woZGO?xIzarP@^(a+($be>Tlh|xe}o#1z8u@aHDQsKl{uG5 z=3FWDZdigC+rsz4ssW-}_ zim7%^7g5&m8BpA{~$pDYZ@{Khh297Wr0W z`$#Wjy~t*f;gK{XBeKPo^3A451~TMdW|e$IL_RjFM{I(~aEaL=64jDjH{UUmtHsRl zoh4?+$V?;rdhkw>GA-F(t?m@5K#Y2`T3sy{L>5BSo7HN26-4SFGo^MFvvZ^gc`gu9 zF*`?E5OXDBMn;w)W(i_OM%oec6k>LXbRy;z#OxATg_t#n85P+8`4lmuA{oech}ktF zAKFzjGwLlj?b$UlL`zLHPeiqObR-WkF~p3H6d-02Vs?wf5R*X6ZjlKl#wint$*9I6 z=^3i7>@hqRaZXWU-sT;rV@hWlxj;(oC-S#Qg%KC7!U z+qYi#h!jHX)0J_NDlPTS^-}6+DK#!qrv*ng*$c);)*Eq_NX#^e*)tM9U1hFu+8}#H z3QCpKJFkkIDlvOU5|DRA)SRCXsnb&Js4v5)Cl&id+7R=N#FR;?eIv;;Odjt^IrfU| z7pc%v?d&LWrASev4l(0JYPF;wQ$%hSnHb4HW{KP@azI2rNUK{|C9+&(QY31GS1AWZ zVpbF#IZ^_7O=O%%Nkkef|E(Nqf7Nm%MLp$HZ;WTf?oC;-`(Rc+mCXA|<|88s zT~{B!33g;8sU^EF9~mh_jIHaa$ZW)@-^{AF(~pW&BF5H!bfgL~c3(a^vIsG@JyRkL zh_T0nDUoKx*cKiWY1LBW^h=x7G2xiVl(Wr<?);Bl2X$mGa>&++x^GoHUIwuKegt1o$EU1RV-ve7{W~6 zhDIzFdcS4w-o!$Pg~rebA(SOyD9g;`tv8vFY17_92$@U>VJ0+^OeVxKneXHIdOcs~ zTwVLTzn{_Cvz#ZULP{a0dvXHgR>&EF4pnL( z%4E(C#9Tx*4@8+vejr21V(T9$bw5fK1gexQQSu1n!a$dj8tV*XRzT(j`sPtR{wU@L z29@|%jphf&!ZOdH)ck;RF_l{5_2<$+9*gNuQ6TXW%HXpM+IknIiUVm%%B@QwpF*xS zBXw_t(6O$>lSL3(7rrcm(C6-Jz0AYg$SMe(#rc^|2z?UwWFpPB@eNwP&eSvUb7W|K z5?_WPbSLTcfh^r;b)AIPa%mt(i9Q~Fk9tZ2jVyGm+YGre(5%E?hBukE+&@q=-4*VO z^Q`W(FMB}7XQp|XHdV9#?s-#SM2VjHWGh-nJ@aYFFSL$DshBvDG?u?Xc7iMnl(L)- zp}9V83DhaUcR(zafuu{R9{-Bst$|b}{=GRyr2o$iq&r%ntRpQtDV4z;ffNicr zJ{ag_G1npg8Aw>5ma4i=LU(OE6v$yQ*CFcz)k^eUN!MHc6^Oq=moj_G!+}H=v!^^9 zNLI4OHhan=ffSa{&}XXWkw6-Y*>@TO8A@;+8yVUM8vpA>jseloDMSZD4;hOU%01)5m?#igDK zv@6lywqK6^tO#_ltVV|JB54kEa;aA!*C4YhFs#I1U#kL`jvM{aasx8Y1QL|2QS<-M z@n>})S&K01Yjq%%#jKsxfpjGc#Rq8XR@AdP(4eH;qWNuTeXS0(DS17r-^&bg=10h# zs#MO^)So4|c?DNMA^#3EDA7HvhqMN|!sH3abAgy^{879Bc_A=GiJmcO4WunFm1Q^7 zO!d4NNMlK6c`1;^ayX<5nU@23EGM$G2j;V!$?{5|l;r}JR|AV!u3&jBP{(pTOGluI z8j2M%oz|Vp$LAg}fOU(_(Lc z&>SXj1)LIEVgvSf5PBziD-fq8ijK5Y&s%{67IOurE0CKd;{z-wD)l#=P&m8))E6A~ICZ zyMboTn0KP?Kr3es7IVJwQ6ODOjdeO|?nhhe&3o>|X58m;F0Mj+7O1+O+S1>o z|A0(ipjyd5l*#l3YFW%YOJ4<+D)HAvf1qB8f8_5EG=*h;LCyVvby~#5=nw6u-vs)U zl#A;ibX@%=FvJ;i$H8D=gfr%jgTVl%yQd?GcZc=20ineI&B?cccqIe2xod1=Ae+V9 zHTGR#5sSI|Y$(vlV(vcsJ`i&QwKZUyyT&#J(pk)1V?P8+SKp$t!?|-%ihBz}NU*GrlXTZ8iFCX)}xIY7q zl1hv2p`&$biIgy*YhO_!N6DHf%Fta}6YvZ+sz(dm$rTVyN(NMh?z{_%9wim3=6$ey zq=+x0Qsow1as3Nql4w#=p(G8mqew2NOojCfMoPbF-$^tpDYsr_*;$m`OqoiH?!}`% zCy0hHp+4^-I>TfZYTi{0DOnRmrDznpi@b$?J=E4-qBKmhP-<^cr$m>ck?teidX#iTeFw=wJqL(kmQj`i1s*GaQFKIY_kzw$6^Sf6upA^(S@vX^ zCNfzLW;s|CC@Hs&hMa}AQbe_qN{jArq&x2p5iLsajUj~Ys+%rECAF@FmPV?`Q?gK% zDnLDHBKcN7Lt{@DB}!_nlhM{fT=AGC%9Q9m&%@~xP`0R2;?G|74^gd4dB5%Xhp6L>`EAcBqJcAJ_Nr4vGiQz| z(?_;bMJs2_>{X|V4i=id>VEVvM|3GE7c_g-!%Eh1hGws#%xR*JGcI{*_88b80nIeNTW@f50MK)*5%v5KIT+W!8sm>AwoG~*~<%#*6F*8%;i4xA3 znW@eeWt_>V(0lILVi60?OhwD^98s&JT+qx^v<%M?^<0mc8|qxq$feBOQ0Iyk7MdHX z38nHy8`nc~Lp`gclj})DhMwqjp6KSxx!9gxL*_iu%k|8IybC#B^mC>hvR=tB*JEaj znkz;*V`ht*D`IY^b-KYe&pjy+4vTs2Nr8xGxgRytJ8XeSW-(7fDG(_vCs*Q^Bj|I1 zNLAv`(^VkSl~j69BPtMCIum7{RCR&qx`X;tV?Bqq1~7^X#SqKKke?tIiJV0`vzet( zlqy+lh1zh<9GQ6{?oP@qw)TQJJK%RjBI7QSay5Gu?aP;nIwh6XG05zWOpzG5n=+Nw ziI9CD3q)?UE_E8@5XhCHn`JI!2IMLccaP2#oo`v`kgG+zk{at&Ja;J*a-GOoOqm+% zGL$+Ea)W4Lxfb##j_PFsk1SD{g^+w?%0&swGRQ@cn?)nbvkL2sT89u$q=gNR$(pCrHsrK6nCyqlYT-Ocqo`DwgCWm~ z34ATNphf9j<{&sdoQc||lS(ZBaQ2lA>&uGg7IP!G*L z`d)8y=ob`ki}*)$rU=r8%sV1S$zqG1Jo`H2T`{#m zXXrTA1?d(Ek7`+nQXfFx6V7ri4?@;M-WSy@k3+tJ^oRzQS0I}pABtg?Pa&HjABp(K zbUi;own9D@g)HtXI8%O8oC8J{KvRG51n^AyPSGp27Ep$ly!`YNk*9eIkoxF@(;(`a~{^nV)}y z$Y(M0^KTIISsvzkz7)kQ&0NoyqKqXMzZ|A_y{|+S%LNcRpZ`kKvRuKLeo@DA6KDEG zBg;$N*4Lt$)`EObsw_533GS6|e$vThM+oY{o6OxJ|Bh)kBKSM@h6zl&^^ogtL@UF5MG1fj8yi2{~mAT;(d(aiF9 z2tAGH57DZmT+D+Uj`j72=-|vk2z{HgRdlf|g-}~t#X6R!IP<3%WHEE1{wao8UPOlW zuRq0@k^$Syl4{v8O?s)CSyC-Kj-?Z&($SwNJAq{#`;}%5Ic$a9%tFtlqP1+>tt|9pRa(oo-NCX2 zOM@~&yNf0Gn$866bu5!1lnL2=EQfL?WDhABu+7Z3jy=MeEM#b%I=1x`t-%5NzI*j? z)wP9^N|DbQ*N*3m`E(=gM9!E`H_}dKp(l`1e`4(v7J33HjVsnpQ&KKUxzBNS21^z9 zInK^zG1u$1w+oak6t&2ljO}N8dp=7&YTBam)LqTR^S2I+(BW}{mCTQl)P2;KX(yC?lDdyEtMy;hPZ zH1i~t+H0IpW^cPqwWa$^TjoA?SD4VIVYvs+orOj(E9BP?d7tRw7{)w*Ug<5sFYpT*3$HN$RHqLpi$5 zelKG8v&6oRvr{F*T#uQf>^OUr>v?4X?yW@TI6LN9JyLVEd6u2PVy-sNvZp9n6Giie z(YBFcXNCz~xjo*VA0~8V@ zA9jzDj;L8Ir`UNf>U#1ayJHlm+8s&;qReb#r`bJ9DlMAFjQV`KJrX9g_0F;5U!r=} zM47qH&alhEg!-IkcPJ^huI1LxwG&^}t-pUBuIu2t{(L)^@4mx{iIdJ;L%n%Qbe~8eQ{7mJ)j^OUxQw>RLOK#msnoon6hc2QstK zpX==|7IPi@276RVjdeUS=OS~Xo&JVyYYwDXNw$(2>n6x;keloRmd79uL(1$zF7+;C zBd!(PY?pFoGvs+>7TQ&u+2aj-f`r^+*K_7X$Y+pByOHH`$R^0Gc8e0d=hC^~ZFWbP zj3RTp-4iB%Lhi70JM}24P!BzW=1x2PO%nfi7kAs)EarC?)pkCMx&N!iE@d&lyST?* z%0j;%+j9c$FtYoVREj6i7QJ^bwuhAX_mVHR@!(6^dc7G87TfVk%DuCK#dejFg~FT_ zEVgTP#%f2+_D;A)WOuR9vvszIEV28P__G`=wMUfra}g}H$KFz7k23c-KVbK~t;NiW z{GeU7I`9pSUx0Wcp6VYtg^>+OGTFjgVkJ`yBW-fw9?P3-)$9SVXy+@ZKp*hB% zu=778sj<2-F1lmoDZ7@1o+h*l#r6qSP~%TZAW(z z_p90^HAJ*#c&BWfMrmO|9iY3(>IRvv`T-v4b+Ww`)CzkPbv&eh_5d(vvp zSK@C`t#%`e*`l7a`&rBu^}L<*v056o*`i*s^ORJI%h48{dA8XFO3K9|2py5y>>?#= zq8^7Fj8VL3x9L(ANgAZxUb>EI#*qZ_SIBF2BMWUUv=?;PtxEi}oi%piCwg6cfKv2p zmNj+~%NG#(HA|;=2J#&w8#S*TC%KTfJoycob0J;!6jhJ@cIhI>J9e59{TZKTb?dgX zSm^WnO~|}&=jqnHUr2sn$E?>qq$g)pBJ+Wr&Jyz`W(@k)Dk)fmddOP`3>S3jI zB+I9E4$BD;df(}_8(2<*P(7d7eJtm)d~PT9>UzvCOun$EE7=fr5i-Z(ewi=q9F|28 zYW)j4kENNV&n{s37(#QnZLq7AR9b&R?!(gf((X}GZaHi5+c8MLo$#4z-P^(k>~tkH z)=tQ*L}tLwWZ56G2J(%a9af6A)j@lHn9vp1Z|!;|dP|^p^Nn`g=hT+|jpEy=XUI-h z;y=w{lby|Cp60O0&ijH&b$HKi*km`bm?vUvvWJwETgRY>>rwM2JExCIm0PDm`jrf` zn5Q|Qo((!P7a7_IH`#+M#hy(4k}`{}+adJaicNMI%TfrTf=rI z3qAjWO8sbevpj-Q?KqD8WcRYPL+E>upY0)*Pf1YEh&{scD}?I##U5jE-@wMN0Ink~>3wvpbax*c;0A()iu(R#Gmepe*~pnOyWeDP)|oMTm@{VfhCl34B^&I6P!By*=?^=xpZYuyWj^cuVNX@!U*-G5 zo~}fXg8KZ2ovurHzZlaVFk3q?M9 zNS~nNf=gM7A#}|lF4&-?Lzo#Fw-2@{sSxJOeEVRBl5%0r%(oAAbH>aIx^u4Z`=AvATn)eFkDXFoZLRDPVl*|_!Ez#m+BzuMr9^LaRsxO-!C@tO>)jD@Sa8Y@)aOcZDN4~?lt%}r zvXn#aSCXov!!qmQm|z8qne%gIutSM%i+^N1*16U^2@SkiROKuB5{w;-cVumaAC`gT*ZMEc1e;EUhdT2P>46 zTip<<`I2C@61{D#M4#seN0j*Ib(aOlSj>6dWkGAR>Y<=x<_jowSx~UhG4mBA@htsl zi_QTq4<;(96cgXkcgS8IoT6kP%G{%Rd2qTeW$la%oiSb>tm2HhNA>bxGmE)LwJ12u zVm^N@2*!_64+o;m=dUY+IV|Q=TXC>JNu{+P+M-{*ULCCBjF}R>aA`TTWFQ2eHA zHlM$)4OX*I4{83N(qKD_xq5I@a8OCPbrjm_#PTT%jt;&&GdgS9OA5Sl@*B3RFIHOno*CYC!PU!k7LU<*qV*K=#IljSYWR0X@0 zEU`91hEVFZU_Z<65Nhl8;MCu#hfA!OcXj5DU?0oQ5IWad6tu>4W*^AUsOQdL63ct} zxGi}X{GuaRz;Y-uOHp%8u$W~Q%RRvg7J8m4WflkfSIy%AWsK7SkfW%+n!ayE|xPOw7#AR_Ojdv*?>|l!9kY0 zxYX+4Fw4Iobo}{uaFk^&WDupE4JJqH)<1{PyLoFch2+2E1nSQcD*P4CYg{xC|}89>vGgg;)I5j)F?Rv zvVABssOzEYTJs>2LbWWnpwyj^T|!+U%3w}-$V$i_A;;0B=-SuIkUc}wmEc?ynNG-F zp*ogVAfG|@33Y|Z2xQ+-s;g`M5E(lWXQ!bGmW_}}ko`kLN)}t&y^p^j2ZdUsF0~7U zw$*8&HkJcf4i0s&%!C|{QYoPxma{o?NT`?PItc9-e+l)oR6}T+KQuJN@+5?g64OH? zENeJ(SZIvpTgczh*5RS)vATy7KERcD$Pu9omfcuVLpdx*Kxh;*LU~G-SahVl9Hov7 zm9P|@k2@(LM~AAy>NB97nC=&Q{b+rA`Q?h6$C*42d0d=4@mhhny73 zWhr7gIaC-X)SthHT3K#DW;NuLkTpryQv>-FXWgfTGQ#8~WafnWlq|98Idf(xGhUZk z1EEY_s5wmDft(u}VWIh`>35aqhZ1(AQZ?4cDD^oqb3^GYUqS{U7lf)9!7nBttF>#j(tU90j>Nl%Pb>j*{st7eUTblCETpH~+?hP_52**P5;f)hY3>U0f0B)}rnky&Uyi5n882 ze^Q|HpDROsN|uOM@m?9g^|32M$ve|1mUvIoyE2r*VxFdVWhj;92K11g1Xmo&W_i$) zLY9|2DP#H6lcg+MJZWaxqn-C^(=>b(#kT&lWvwPJQ-xU!xL*4-RF8w5?ES2Nn!cHlT4Pt$EH8| zEW3JA!g7=+)hwrY(#W#FlXjMJPu8*2dos-OiYH>S9>qtVB(eP9Nh(Wdo#}Hn%M4En zS+Z)G{rlWvxIo(!_w=ZTf5``qeD0?TKfq_AxFsc9>dWr`>H zEGKwU!g8@E)hrdBG_ox7q@CqePu8()@MM?;4|3uqFLu+TIKY!6mh(MHWx3mvY?d}p z3R%{BQpWPLCrep&{LHl8%yNV$oh)Z~(#NvElTnu2J&D_0kD|$wWR~|mNoV=ilU$aa zJ~#a-VmZN+DwaY|>RA?f(#o>ZlWvyxJQ-x!;)%6~?(;!knAQ_mW_yyta+xQYEOnmb zvpnZX3Cr7_RI?0u(#YcUnbzA`_V;8R%S=y(SR*t0$=}k9(5M@~S6= zEMIt1#v(SD9xi3s*OO+JnVxjATyIimet6-47oAXpk%T27NiGK9_m(tCnMlDc;7%4hDKQy=i`^5kjhYU zGSyRKeTh>ht{!7{8CGGsE;KcLT5xZp<$MNA#_G`PiTxK6+&l3 zwIOGJ-PTDEIwQI_6wh)FgxXpXN@Q68IRPZz)_st zL@D~VeZ41#Kq&L6CsCZ~^@NTsG{fF!M%*Q+nXcG>Ze-#mDD@#~_T?(BxzEeY;hHyu zM)lJ0w)rnZz0+y==xv_*^JQo>Oz3GBUxlU~rZV2V`d^2pEAi*m|2mY;ne(s=Y0mtC zP$p*nXu`%p_N)w9@&{#qZSHigD!=$iL~>=}da z%|j(eYB>~=iF$@Ztt=Ukze9cuWv1y&E+iN7b7(2c1rYje&q%237@b)Fc>}Hg66$2B zVEHu^m##C*Am^c;&7l#N=OEPQ-$HT6>I})n$ZQE!u+Y0zG31X>+i{dxY`u>Rjlyz9 zS-yhYhD?-`G)rf;K<$0>MVujd3Nq2j&!AE@)~+l8r;p_b$g{}U zPQ~#$^LNNAkdPxz&{7C_3*tIuN)}tUKt6`VI{7E+{=CHXZ140csj;>|9E@U;lboqD z!Ef~M6Lxg6l+;+eL+FUKlas^pSC*Zf0+wQy1gDtgA(ma73YN8y4d~Bgr;lX-@(W~F zXOJa&5c3%%;T_!>W!W8a5M+19`l}x4k&t5`dpLq+4rDeY$w^=-hMW!A(@E6g?Uj2u zO(#=5ORO4X79g{iGs^NL;{?TB(r2e_JJJlRI!}TlIbLzu4}#) zG7XuNoMt68Ru$whNS4#iaxWwea>N4K>KG7B=>X=Hg7axx^_>0o(>Gp9J~SbAA< zoFSI)Ao(bDx--i1C!`pX>sYzEtw|g43scA$j$qjrau?)GCr*hz8o!IPi?f_$En)^T zA4AS|Qdo|M^eRbJ;vZMfcIsKooR()hBP`~Av~!&FGpIj)Tjw~rTD-RMoqU!#+*ZC* zsKjq8-|1#CZRI;t&ZL^xSf;J>oFXNDTjx1dTD-RAI@K%-xUIR)Qm)6`TQS$M&eAoT zw&prHET*jjr(TKQR)N#1Mcl;8@It4ZrHb3S(COrQOj{Q^DS6}Dy3na$F>PJsbSv@O zy2u&SBI>xUdCoA)!`#+9XO!zPZOwD?&mP~_Jg0@lv~{s#okJPFt&5!mE#A21J4q}n zxvlw5vJ!uN&3CF<%rczs^s|_@E_G7Q9pBcaPNo*|3Xkh@C!1w0w{^LbtHf{Xa;Kfe zv~{@?pRY%1+A4DLmH6W-a!Ry_Pq?isoH7>E))h__*JGC970xh=Y3m9nsn`6iQm?>jwql~l_K<=K5ks^#Ia0;&~f8> zCqaq7zOHx5Sj@PtcY0V%Tcu9Y1*&Fsg`AF2rB13AZ(KJz=`2TcTQ@qHO8mBNbedUA zTQ@o}7wVCkwr+B=mH6Yj$tlz#GI(6&P7%um+*Y|$!u6PCSnl+(n6}ED=@*S}>t?4+ ziQm@E&QdMjxGJ1_mId5ah11COn6@gMxI$gCX{*91U@_ym#c5XJw{?rtsYTqx+p2O#wTMP;>vqSwnCht%|K_%CcZ3pu zeckR9v6yk)?sTx2w(fA^E>ZP(+r}MEvKDU{-sz;UbZ}dDI;l$hw(fN5Sxj4ZIwLHm zt-GA``QzKV%gNQ^wN>rpv%Jr3RXc@B{I;r{ZWhy4wKL^Xy;MzGHBONde;L*|Ra(5Z z7CY4}bR?nuYq7JG>oMzVv147PYc_2yc5+xuTeVKT62Gllr&WvSE= zxgOKj5+~*I@og<}Dp*Wg_c`54{I>3M2DNzaU-vu1ETi1k{mv-YW7@jk$uAn;*8NTk zi)m|_V=bVJ-_|lGL5tT`os+~u@6@ym>zrgI{`#tOs#(l3taJKVOj{2+DOZed>p>?| zi~0;p=TQ$i*(`KtJ+<|aldHsU>mjF|#kBR16Mv;1scEa;$yef!tKKQmB4UU1vG-x8 zjAaUh+IrZj;(E+7eApRgF>O8UWE78Y>k+3~iQm>EPNNoaD7W>f)66o1+j`V#<$6q8 zk2*6%Sjk2=LHW?ajib|rpW%bj&vL?*Y@==8D7;kFu`L9WNN)#zkjJ-)3*r-8+^ z^|&*v#Bb|yM_fatD!pyvNhglQEW;0vQ#H91Kos%GyP)#RjV z5f}2fRygS_xAM4FIGIZPwpKXJET*j$PRzA>q^7N>ooprkxSn6CCiW*M$@`dCa`E1l`rjc;p}Q>MgkYn8K9i&(*JwK(-GFK}BeP9xW2+G=s)uGcl2 zwpyG57BjBZPO}oft<_Ga7H@q$>vXfc$!$IBtmAr2ThBV_rQ_Rr)~RJNZM8amO8mB3 zolz~`x#;tbbpzE?DL&@5o_B;2e|5Kh6ej|fxjIVhal82Ca-4l8qG-W!+ z$>YeZ9VaUxZ+jBYHNQVjs8r85p;8}vvKvah9l%j?oVwX!Er*FjZTqTV*2+RbQSb_r&>w5brMR^cLAH6cAc>Q*nkY(3AouwV|m<@ zEG3oJ3dpx8wb^M6lOG_zIsHn?trwA@`vQ303wmM@h z=2tOWotRsw&x^%DsF{96@TZf=a=IteS#I0x=slOdLGJc+5&eco}z)SSqY;mLHCYdy(gY4W6ik>%HP^Bn>q!$! zsV5yQk9pF|^0p@+%7 z0Eq3*zgw58gHX*OH@;fSvk>~WE953CskGjJOh+ll&E(7m7S}Cd`4d7%8|eTX^U5j-%N*#w%ac&z+CWK1u;C3nTp9-;qEAF9s zI;`1VCRK^9`ERIa2RAQFPJzU`rD2i>*~x9tV$DH4)SsQ*UX~)31UG)M>a$e?q3`u} zaf_9dTTeo0iA{D}m8`K$pLcaTS=x}HQS9ojV|kV9+0`9nc^5Jl{Yi93Sw4kOfA(-i zEw#SJ8h~7aOp=?x@++hWvZtHO5;dwzO>t9MBqV(YTz_}7SayX_fA)6^SPt@}nB^Ex zDp+Pis6YF=wJc|I<^Z>WWdVfVJr8hOSQc@qscuJ@P@fNSdsyy8W&rOXDef@K;}E)= z=}_0YSC5^9`aIo@V`<}3)7>O3;vGl{YCghE;ml_c>hlq9I?K0^8<9zMvst2l)0rdP zd?os>Rch-fcYc^upwv-rNtoOLNptJ9h#gQ5?M=tHjVy;jXcWh|EiAd5nd!E%T)~-{ zZYRqk$i1jJ-R)+16!L%)YzFw(G4Ul5)O@Vl%b5~y-iEc}nd=2@VoBB`6=%W_(`D8a!i#QOaXr0b>vstD?Xza7ye3lFdooCK=7qOh` zNvjq$iV;=MIxXHhJ;hCWNVP8LdQ{Bb_$`r}!cu^GXf2=OX0u%8Ns$)oMo3VVYT`@{ zw|=VI%ksDPu)ZDx@ig~VRqMEhP{1O+tr7U}()Do1s#I0jF2=Wl*GPh01LhEQqBV>U)q@>(B z5%M(T3ODX4s<|U7wn@JiT>FUQYpUhq>eLNJZa<1#6L|v9W3z>S{Eg5w=QMv4Wa&A>()N4 z`fSnINv?C-Sf(Mf2IIQk9c4-5Ql)NLvo7@y&fMTOvJ|k~==QQ)#d4FIyHb~`guIQK z%iKDa`yd}eZg#s^o`&>77P^_Mbg7piG>Qthl;uqbt-)K|R+b)5raYrdeGb`xdTw!Z zS?HG!v_;+O&R0@tZA6Bo$}QuJ+3Id{m$Lkb3@xAA-ARp2(7_IZbFN0 z{a{aeSdQ}~Z?(>3L+HGBk=w*Fmos;|{Ve4WT0VEWRsW_^9rhB=+~rm)sSuAs9!3xE za_c$M>Se}Q-iCaKdhT+qXH`8>pL>}UB^A~XWIgU?y30)ulOIv4+RYA=Es(`-UYJBp z!T#(nQqmE%nQLC=*6NHf=ReEbK^Akiv&nHhX#D{g~qq#;A{sJlpse@?sHtyQ9*+_xv{S?)F~@sBpk-Bu<3yTfv~O-YAkme_K)sf}6> zFV&(XJkzyJrblOl**2EDyhYHi;*?wgbD3m%ia7i*$MAxkGb=eEU~U^#2t_r z*W+$QSmsd3lWudE91VHOU8lu+Cwkf)WHIkVPrETMss0FauJyE=#A431o_5oetVur& zOMZ9s=V`Z4XS{RBm2MH2nu`p*>#cOFl`OOtKK450FZq1P3vRm>@e^vMKELR8 zDk-;|Xx--*-6`!i!6XZ45>Cl;%k*S1qxQQ%15V}Ua#+@1__aO6z zo5n(CadnV4-7FS*muZB&GFd_sqE)FbH|7m0H4sIgq@G4S zZ@U>v{Ii00+#b%*c>>k^uG_CO-dVxBZhR-zJ?t>$Iy;^Sf@E7Ry|X?{=HC zh`rGtT7&PoEi6Ys==14&Zad3K5IR1;?{=~jKmi{`pWDIWeS_fk zg^BtG!5w4qzCmyk-qQ7usBaM5=}OA2M=^>usQG($ewffvbd%ezWU=);GH)aEgFC{~ z1^Ec_lbhT{HFsF%v-z)XixU3``K#NuO=eh0h4m%sq4oZ&oBOuvp?BQ))y>~Vij;)6 zRkBT{Vw=q1Hd63TWLxu<_*edabxV{~i0{!u`h@ta+xTweNaMOA>q$@&-ovtOGF97T zTHcGSr%j8nVxp}tv7CQ(J6I+`hLv=)>W`@7%x|uv#alaD+=MVu-_*EEl~jmUl=>4r{N3$R;xCQg-LxL6 zd9ipKnTh*QCXZ#kC#5Vuds3&Q!V(kp`}^;%_>k(UuqH!7sAtTbuB6tQ0ofk1)vf-B zGUe9Ekli5BvMx-fKqko4bvkn%GISO>iXXEP$$>wdORf}~GYNqE`hNSbkDrK!;abzaTTF43Lp(}H>cxy+> ze9jC|50R0wg=I5KtQ?Cd6(?i9&~1tBqODUbz#GflKK{jy4%$2u`Y|`S* zdbf*gS5kv{1f#9%Q1dP_cLTLmW6gxz4cS#LRWe|k`(+Yky^?Z~i*Ly%;g|V|vPp?Q z!`^PPTZz9V>?YS~vHpgdm!js~^~rM+}KN& zX^EN{&`0CFWED$+CyTh$O^_zlR;?1fH0TI`w!(yt>U+yJE!Gn#Me`c%E!Rb4rpP|d zJdaE>YMvrTA~O5PG0v>z%sw)q-`{?yt$k&Z7HbQh{775xzA`T?^DJaPIbR8$Q@p^k z(y^A4Wv$MLFHtisjRRyI%Wn`miXI>vS!hP_S5VJ^vYCZu6n{fWn-*`KPL&5@&Ldq2-ez zv$x6Qa%LVfbR0{Og%O!UWD#esUxZKnXzLJJ6_GhqR&%D7`+TUZkH}1yjhtD5Oh4+G zF54n9hsh4kyvUiuWPe2Fa5==8Zq6Jo(+0+G2}j5bE!IY4zC&9_$h?S5sx08l7S5!~ z5+xg=TpN1|O3jeHEM{+-A^Ta(-ZVq@eXIAT(@|0!Ebl=wYNms6GaJv>%s=~CWad8}+^G0X5+*~(&ic&zLl z8Q;TWWxp1$hsVkx7SqFHWy&w(dw8r&RpR&XSedKD-x7|KCAyT?!{cNxi|OHUvY*BD z@HkoY>-Zj`9xYxEkCSCAriaJL3NB@q;c;@262FJX$tEsk*6A!6w^_C2?K`t%0*mR- zESWnxzCW{Mz80@Pvt%KQ>CY_L&819#X32F*{Qk_6qe}cGmLU^Wdn;7jJEy)$&^hjyF+F` z{wiBoQXuJ&zsWY1;~*zOPLdr;Hbmt>W<#=M;_u^^VV0c2VwPc+tkz<$LMaz#7g=&C zXJ+DDg8G~#>sib)%#saU$}Gby*`&l@hFP+UOUY2Qm5ctIET@c(@6X9{DvRmQ$+Gni zm9ei!sq%HgPG_pV_iSiQk{uvL{SvIsaYuYQbIH(N-bG{&zVg zO0^zk`kXCGS>Q2WNSp`6xq(1-!ZOIWKNOY5t&ovI?lL`et$nz4k_`s=Ny?aK`#w6 z_8ghTV#b~$TeW!GbB=81%uL>%b7Uur8GDZG;!I#ET%uF$sR6c`g5A>RpR&OG&vR~v@TAUF%zjjmDavk zhBsq5pDvTMc<0!2WHM(?K!%>QI7gO7WO8K%XU;+9Hq?_VYnAw)+Rl(eEM{GtAxBuu z*w2vp0lgiXPi<$&LM`5Qc!n%uF=IbNws0vk_A_Lg5`XMx$X+GoRtb7YV?R@laXsd9 z<(V=^j9)uv$~+d+!!u>C7VmTAnX;cVX6>9QhgeJx&y>Sl%JlF|IjY3(;h8eQ)~#2f zhbQ7w?OC#l#VoP2WHpQF&sj1hq?g$1C`EVBoF!AWcuVXona*PRbC#^&Ql>v=$yz0T zf6kIEO7P8}tCv`w>&AuS>f8Tuao967==8A6|z&ykoWfVMF)jH};EQR-YN zShhmawkL_#;%#;LGEs{)1@-(BrSfG}MCLqM&6&R-L)VeclVz@I%d6*nS)~QP7K*kW zM?L4uYAxbq$ZAM|T*`7bBp<&JD3A>-zdx(L%f3K1v4mRr*AcRn|TE^lDKN_NjqA`Nc5l&Lkm2&+(Zrha)nV$x+T6$(hS!#`da*A{Rp2 zbCJwaQZ6ol(Dqy;b2($40=z)xbH+Rcc!8YH8S@n2D`YWe%u|4`kYzff_6vH#@0GGC zOlVuZTDEAhu0ZRbV)y>upx?@y_W*J5oKtNT+bGa@oK$SlrGMuvWmbc4)` z$lNFkIFpRbk7(;gS*%5*LAF3{lBFysKw|bIsba~7&{fbfSmVQDC|WL?wRlIZn`P@Z(yqn27&XVD^_yi+L}sDvw&o|YlL-CnM*w{d)z`<8z!{XRmeImR!m&9wGaASA)6vHx5yUGtj2o*E$3Tg*EX3R&g_DEX#2TE zIy;ZwS}J9{7Hc154ntd&GMVKN2-SS6%#0{?tIX!i(a0Q!Qn$*2h)k87&zWpwPC}+i zmPKT4lU1BKhwHgbHb!J_m(85H2ANY(&+T$FB6Ekd64bb?YGm?}xkDCe@wT5uvWPQv z$P^;8NG^)V+$n20^8_+iBXg%*7m>M3_HpJ_&fF!Z>@t3--YutUv3iiHLOplO%&<%i zq*~@{5$378_sBveQeW~DJ++8siiVKqSXB| zlQTCXQ->qu{W4F9e`dZ+wzHUhaGC66G5g>$S(`}x@xM=5ChN3#``|L!z+(2nWin?s zUCQi(%VeGse;-^XOO=#c_tLnq%|9UPSQ4WItj4-{KrUr5%jW@E&tjI(1F~>0J<>yVh_+r`>w_p9f^Wl5(pQHPcAzWX#^DXKGG`mf(_)>9Qahra zM`dk9X1T264842Oa$YVww#jsH<|@=f-$gE$BT6~~uiEOochBWAhs7*; z)V!a{*e{?Iy?ZW~U0S>?bGhtcF)n5<_p z+v;PoJFJw>tkYusiBj|p!eeq!i`X$f+M0qT)+mQr_J*V=8DlvFLfhfvGG>43VWmii z&{}?6#%b}^&J!{rOuol=e^1C1B^_4#68)*9Nv4KnsE185U5oX1)J*T5O)@7U^OVfv z%=yUBw~9~6A|)H5E{7bAKCh6SEateeLUyy5wX;Iz9;lad3rbnrQK@__-r89q3t7zC zSs|Oblvz6~WUCT??W~aNl$2YWQ8SI}X*n8}(PB+i%g{RDNnBS(pP!cTTD)c0EE731 zamQ#Y2bpG>5|LRcQ#rE>GG`&PQf4dJ5Opl%e8?)m5B$dQHTQ}v|l_Yv$S~QdQRqOv5r87wz22rqHQv@oH@zMbZHUhsgBRd z9+q>xwtBwy_uFh!*Q&l%lINFUYi%@k_olPTcL952(jO{RGp zY28NJw~@|mq+5%1722ZZyhiqKlNsX79mu?dCALO7hmIdtr;OKP(eD9h&+U{`w#iK8 z%)e028r0J%Ga@o?$}G;jgbZzCZ^}F+{&xy%WebZrj;)n#Eao`2RwhrU9&Yfi;jfh` zTD;@fTA9jXj$>hZ_hhpYe|!Ewc5fr= zv{)hmXJ{z(fgEGm3u5n&nMP#l;p5lfhcaD@m4-|LG9Svkh|EW_fHPUh(9``sk`)n| zkL4oHxQ&t(>`r>Ol|J$>bx(_vaItqQ$C4hJLU0iOh(|te07wd5AOX zWobm_Q(3{8XE^hz?25?r${xUIHJ@hIm)F5xYQ<@ zm9Dl8Yn0^&S;i9DHQL&U-&73CS|yl68$vbzDC<~KSbmZXx|Fx|{w$lgo>|D;i)Hw; z>Dj#KO1`{cVt zIxJ?}*dmwC(%Z(KiP6?UXnl*U*Wzs(TVx}P**3PwCN5>RjV-c8iN9@Zkv(BT+s5y* zSBrHC+M>PtcR3W18IvQNxrsAlGA3jElK(?GTC7Jn^M_1~$ZVBUIP(=}w#w-dnLlM3 zXZGDK+FFMt_NUB=$XKy?oJr@56Z`O8*ozAicg!(fnHjU*-&PUNBAap#8k1b$X2%&G}<711Itg+@`j!l|#X2;lWCAbEQ49QNh z^G~E6mRtXVBw-Xg$F{LN1=$ah5ZlG_3WWNzOKd;OJD#Lx>U!2gsODW_OId#4%;Z?{ zSIVprF?--sE$&a59GjrUGPCPUj!kAUGw@7~O;w`rW}1fnOpa~m%=V}!6|#Hm{J-he zcVXEhwvpvP$V_CCV%wAqM4bSkZDY^ab}hEKCv?x)P8M@d=$^6NN-D)EUa56THbk8V zp}Y9^j2+TqKL(+7x>xL&62H%T#ZEbidg!;lZ)~y_ul0RnQ&>#v`^KV(HGzLuZ~{hQ zWKGmC+M?@G$(&gewV4E&{XLnG6m89cOpQ%dHR~fAt-*t0)3sPGGE~n&u>}#CX|eM; zvnMjN#HPh|Y?JBY%nW4cR~FM^`?kppa^?hN=-pvj?5Gm|)7G@u>?~S7{`Z5^Vslx{ zaUQK}@jh)$i|yjfO#TJewAdaNbDW+DpF6z$DZuef_x`2_1~_W!Owk>yRfySV%kuJ@l2 zfA9TQ8s`M-DdjQVxLY`9@}(*lZT*e=b%uJ4;c^qbavfaGyuQhQn^!$9d_Tu-UjLK7 z#kv1({QtlH|Ly;>eOhMp@BiKQv7X!cRV`P1!dI`+*17+nb|zRG`TvdYb&77^{M{N+ zF5@I!Zkl?Hu^v|cKhgT%=S;geUyZ2mXKr8DgQt9)NcBf^KPOnay%HeAZ zqU*z_^BHQvXpZ8zB zMq6{)ujALd_|=TV)N5Yj)$+leb!t7~_b&YR=_l*{=^WnmxgN8;O-`?OJn4-8-{j4B z-{9r9BI5t`-xI87BfN~;?@%6Xy~Y3E&3}K&fA{mN>Cd{kQ-A zYu4isAO9Vd_m_`ZPUbu!p8r4cZ&OdRs>gpnGk=di-@x+=GpYa4mU%y|Q{(Z^m-bZc zM0@88pYZ#cakD+{&$&amUo-gCtRK_Qqaxh=e-^vRneh#%?JnBV%VmOPmWx?_k?)h* zF&?h(LiHMLJ(W)5#BYz;U*hfE95>B+xsvl{c}KqL@#5O0dY_nJT{>IWYsT?EeU0pQ zWVy)yFXeve+yw8u;J+(p{{QB2<<0u_&o9RRzhA%kymBuuw}-i&r~b>oC;Tt&-UKe| zD*GS5pU<=KJZysCLZU#CNm8lNLQz37rNxv_(PB|ap+zwjMT^BuGBPtc(PCj~QAyHb zQIicVHq=PcqS2HSZ4*tB)Wl?q6D>|u|Mxlfp8Lor8Jll@|F7Tgr!QXTeb2e~+;jK! zb04M057GbQsW-i1x6uEod}zAFo*k!qxcq*^q+iQ@W;>`{$k4K4MWAhZtplXV!o?B;dVfEnEplQp;nhR!zh7lw*Htp}${hW{%M75=S;FI4zK zA2V{HQf`u;uNt}Vg^K(wBbR-oO~x(sbB|oY>-`_RtYr2Fq@HW)+J5ujCcN~YLZw`E ze)FI;WZZh-c;dNA_I`t{d~tA$)uhYWxr7yB>eoIUf>E+%k`e>ZuvV-}dh`HCO}+?!F}rkY zufvt2Pd#Vi)#V@6v!ik2`h7zpi(~=gWJ> zpX7tMKVyDWkHjnaHniNMjehA@ry94=Tg<+;P`yuwyOPGA z?AysWC{*}*KN#QR8UHdL6e|A2&SK+F=I^q;*5%~m{)o~m^>BM~+E%}?b{pLXk#TRX39s9=PhDc-k$spt z;}-jcE;Qj9jaGdJ@jZMA`)q@v@O!(srmHjKd zp21y8!`Jmn)-^uMmwMx+Qg4K2n|-Ydj6Uh7gr*pIpP7Hv8h@f!;=kHs&obk_-_TEt zo+pf3>btHVj*@!vq>&GG`&5_VOT7QL(f5q~_2zt6@^_2j%eW!?=|kN<Tz{U)!;I-nwEN zH*wCuIOF1+Pu9_^SRUPH7QRruFCFb)hq`@A&*O2A)6_dXez~fd$1|V$gBjNjVu}~# z4gVdppRMf&I2C-A9*WdQtj(XhWi#{KadEpQDKZXmx zeSS2bq+UpQ3YGRG<5Z`~|Mg6L>J_Gb^}4ZdIQhFqE_$SY7|O?uNu&1@&AI(dxaquYmWfB^0cRP1=Ni7`!_J~Qz4#3V*6&l&?zhkPt9oO{ z(DsFXf%$$L{w8+gWhReaZ#XTFh7-A-H~LKYs9fw?W%NG9RQfk*-#(?~ekJn%?feqE zbvyfEeu&&__m54_|16*I%bjMwTeq9&eC`#KZ<@Ml<96LX_0@mm`&B}*9*=Vj%^N~p zHPg7u4IR!Nu}{`R7a0FuD&y*osOXV(qCOABuf1}+$1QZz{;N$q+voe$H6FRtBkdpW z4x0VS#m1jdNsrk1ppk1DowtfUp--|u*PMg<)JrCu$i4K>JWjjjJYCwaUwvW5ZyEn3 zoUU*9*2$cg52bjS!h{>j$9J-ZFVrg+x1?9*S+c(?c8EXGBUH})MLv{9=RcATp)#Jl zzJq)c|I#17!TX(ZzJ;-p&!c^6C|~3|qH-Q6{&0W5*dzV>kEQ>&*!eF{eh*FGj`HKj z<`2#zJ>}$e|Fm+G@`_TqCpa`cGQQx~+D*E3e~w?K_?hnigmxKw6PX{~Z_@kOewAkY zd*zdu?^hGKodwMPcTnwX{A)hWnN2(NQrXX%>XHB4*dhLB8+~OS{!ew!GkS%J9a5jY zw95F`_h#_I0lP774#{5`&n5q(ZryJT-|tcXPV=d~%=$#`QA+xUTkl+L>=OH=oPX>( zXt?#2oSWQW^a~ZfQ0YIV|C4@E_(Ekqq321GKhbrQUO(Yo7!#j&9W~VLv;Ms0Bz6du zcx62y`Llg~w7kCLa`4_uMY|iq7q?J7KTg7%5W1a5+o{+?>u6fH47EqxK0CjD(&WSI zhU)n`zV$M0(YK>?$bCfd?~VU^*5|6xN9cY*?uSV}4fXF++3e46*69JYKio-4L3NA? z?=6oVxn(?*^_KKwvOW>F=#hI^L+z6KB>9NfM?CpF)E(Vt*goHH(^Gc1E-&pbdOum_ z2me_f*nu9rILrEly2frD57nazldrOmd8u*VctH?y+Lul?e9qKf1p7)Fz|f8}7%tr5#B-`Hc19 z1yrMVW|7V(p>lt9NBz9?lS0KF(c`6hKOZl}&Cu<#$edTpy6`mHt`W`pkC3_}jkz zXuqew4{??L{=@sdTEOlPd;RI}LHy>NDq!aGLF-@l6EZK2?qfc6g^ zuF~IU`-~jkby|VA~wsGtHkKUKoa#wx0 z-Ta8AU*BtYOg`dmXY<{tt```AkJ9r8sV6!=_4hh-{~`@?8n*-H{^IWJKUyxr7k#?i zd}^xEd#Isu?xNFycgf7XCONkes{3WU5NXc2#4S|njqG2_dDwIlkJsPN3}4pupP70# za|e9MhvSVup~8>j`$V`$$n(T#y&Ni!=DYZ(`iQR#)YoQS=k;I4@!_puraq<52mB@; zuf8AdQ_^=;v`&|Nk^B(8w_ZxU(==Ki#C?TH|4_Hj)*In3^!StZEPPpC$oB*?ZxZ*7 zCcL=iy8v;^eRi$KRr39U=)Kc~7xy1L`lSBp^tS^3iLLzCRPS@5kP!5q&bx z7PnWw)C)=P|IR!tpeC7mBz9=}!~0S@npb-5m-V6OmGOD#_inD5ZsHfYrt%&W-uXB8 zbA_H@%18F8WM5p?sd6q+X7qadWvO2~qTX;`_i*R7QeNKj8|udISDN!ix@Y^J?z74{ zi1(f>om){4w4-~w-gKUC@=vG7XV(ofo(wGq{Ki(H?q{wr`6>JRUcJM)Wj{gJ1H3b0 z=B2g94liHondJ91CSLD;h1dOw=|^uh{xx;goyOf_;(Nfjz57Qp4tn{rZ#5iW>bI9l zd+_rAvpah4iNe#pfya%#QZBL&Cim7Q-P#>JXV>2+N8NJIT;i8|=)(8Tvt@oLaxWFR zj7P(L4=w)W9Tq)K$aj@~b6+#MALsR_*Xw?B4<%syNB85r{$>A8hl}1{(fb84b{}uJ z`s(FNehsCrTFd3)v+u;bZt7RB;gf%w&wpmhPr}Q*QK;|(CAys@GL?5$%cNA&yr4|a-T%zQ(Dgt z_m76=Q?z{y)e|ibx!f)mn0r-U-TS7 z<^_kD@Zvt!<4$5d_BeS>H&x2$k@^ zHTw0u#b>_n@!Rivq#a87#Vz$=s9Wyk$a`FJ{-F8PzwQh@^nI%S-XNf^G5NH8JEHxi z_8%P9zpigP_P=bq@p;o5b?bRG&a+HC^4cl!?kGJw@~6j9pVIb8J_k(wjgG%k|8@CA z+qu}K=gHB1dM{sp=Oy_cO{eY$C0z6#xr7(FjQ5gWxo`es{Ym?hepkY2zK_3yqxwPL zo6$J|*-Q80?@xqwgYVeApU z*e~y!3SY`2#QOX;oW4ik^0_hXn~j$Ec)wfoX&l$_xN0KHeQJNRu9NUuj&aNAC%KDu zcA&9ud*NxEIMBp*goh57U-JE|Pzk5=8Sir&J#vp%_Uok_w@>j-fe9z|WFEV*uW$IG z=OW`4J#z0$Q~8cBdJkXUV?(}~d-qovz4Gpv%ui&!INUl}5~ zV^6jzU->>*#}oZ7P2BD=x_{b{do=sQFQOa&62G{I3twRT7n}4+K8StNzYa&`K8o}g zn&MYtP5NZK9FEF;x)mrd>er7k_6)}_GwCG%)Njf<$Lp5&^F+RVH^xEPm*ewXytiuf zO8l#hTZea*z7OWJ_rZqV5A&(#J$6aFqVHuRmvqQDBJO!6{X^aOorWFowSGta#`u%_ zvEKAwXYx<(?RxJ`dfj&z|IJ3P+yj++h(aZOEyka;GvPln4F3fWU+e2NRzgFY%f2PrM zj)(7^FN!^)U*~d{@3)$_kEg1&$EWQeM;NqH+JDW7@i-v)~+9${^9%`%jw0hf^vWB zs`pI4EBB$rE#)9?dFM#za+B}cUf0@tkJ0~tkrx)~dM<9EQr^NB;DD(p5Pe-lz6q>R0<2eKOw^f1+RJ_rvKg;P5y< zWIKII?4EA)4ks7=$C&UZ8vkb)dgc&{nZ23sO8I-Ke1{|T;v5tHVy3S8opH-Jt|{st z^L^^BA#zvgdgSFhYUsJKPo2--B<6qj1 ztb2rd%kL}WU&8-)6nPWT?N-7`I~qBJk9o)83jgrkq31iQ;oK7bITKFS)oDhrxF@n3 z_ZdBW?e^Js1-I|tZ{_=#@S0-1W89~j_vUmx_i;U=bPUJW_Q-uc$Lg1MWXA_{9w_69 z$A8e z-(T5G~fz6?kI zZv6dYh<{goVcdgE@qNy5RGvOHmMPwuVCtv?hESaI828T&J%K6qd)O|Yn#*p#y4=Y1 zJDE6VGv`@yzd@+{{++mGeIxt-axN$HXxXO{x6C8!J-@f+QvbZ=>UE1gFMWsg z;9V-FKJ}^5D|QY?C10ieiCgY_$-6Y(_{6Q>eTkNfe8(?(gi3i0M`xRMByz94!k6~# zJ6?}3Vuw(ve?sMZb#cqSzqqB`h06Yryu+aF$GL5xj!&q>HyoAk-bJr|zc1RqNI2QI zmiI~}opOIq!i!zf-lcyNxqR;`^*fdG$5mNOefB%e9FuQ4{dl+3xTXAMKUwOdoI}ZY z?7dGX_wVHUTnQ)T=dHhTA5G+9zwGA?{cbDzZkLq1_>=QAd5=Ty%S7*6$$qWGBmJ}7 zi}-<^=KBqs|K>bS-?xbVK7!~IyTvV3%1O>?rJN2o`7Hgc^y{KWsMt01+zRhY82cn1 zkqec2E$vU{jU^^tseh6$LM7f~j6bPAUMls@OLc!9eV1I~)%!+{lKhZxGA_t|#g6tf z%Goa2x9};Mr;PB7=hB{rqw`Gq66`x*X@ zz~7Phn}NTX`1`q<;vA#$@HfSYs6yvN^&9sj(33!C^WQzbQ$SCL-ZS854*tsFzZ~>T zRgb?s{7rG@!ltv;Qs*4}ou}?|YSc6SOI5dXxmu#GgsfKeIlob(1HXsv->Yo*8Z`-j zh0Zm=OVlj)X8bM1-!k=j;8xJv@YkfO@Hfl7L(TWyp}q{OtRQ>XhJP>P-Bt4?Lz;!Tl)y*13;E$Kz@_{^sCs7XD`7ugrY{;Z{So8oVb} zDgI`;e*&*v{VJvdHb1Y%`d)yp7ocN3^sk5h_0Yc_y!Ft(9{Sfq_9EObg1)4t_+C~A z`d(4*#k>OgD)e=$JA!Yh65kuZZ>n9xJ*vw0uDaZ}5r4fZ9e-ne@2NY&eTeUU^<=nT z)%*Iv?+1UgdM>fJ9?vGWD;@oP0Nb}RC9 zEAUq2={M>_-=MnM{TBMZg}!f*{%?`?Z&eBY%J5f(zghSz#NU3t@8R!z_;Z|H;#_Bz z>pBm+ekafIJ5!v1Q;)wq{7rF!POBS&EDRd!oQ%IJ{LRAOEBGsP6P+2p6l|rAbvoU# z&J5=$2c?U@(;R=`bf?mPI`GBNbun~Z=IpO7bJn?+IU_;m;%|wnMVM=xf8lSPdyV7b zZ?3uq{OiHH9=z+pyB@sj!Mg#x8^F5(yc@U%E>SmvcO!T=f_Ec$H^Sdd;N1k?P2k-G z-c8^&g4YOMBY2JAHG;PUyd~f*0dEO-OTfDsyqm$h8N8dpyBWNt&SUOU@RmBG6PALv z6uf25bM7+mmN_?%SO(rQ@NNa~R`6~G?^f_`1+NLbCh(fTYXYwcyyeih9K7Yww;a6X z;5CES3|=#M&EPeIcQ^9uZt(6#e%%e;-Qe8=-aX*m1KvI0-2>je&icT;;N9!|DtIq= z_k#DJv(b4F^jXNBh3r|#o`vjL@ZN-uH^F-oI^G2DP4If0yYRQp?Q!k^or}LE>RsoP z5$`gctKNs6_aT2DdftcpeegeWc6B}i?;~eV(7A9gQJ*@;gg*uEQ|DaJxo|I0gQy4J zI@6L8-N)QScOCvlCnUOaRU&$Vbaz)L9lUgRPtdt=FHyU@`{Qq&ySqCQbT0musEO{A zzKP&XbWcp02;M~S_Hjoh>;v9D?!2UZz}pABBKLiNky{)%9CQZan*sR@#5V)-8IUKd zlW%v_g?r*x>DBs7S1lY+Dy(*$t<-J*QfjtExfWHbH{tJcgveF-iyiekZah?~P2eqH zEgu_crTP-+H{iu{*du^4)p^i71DaFSU#`Q>=T@b1)OYaruPq9;jL34;HSm|LN{m$> z26ul9Hz7ti@b_&4#$t{m3;u3pv-VQYF$dmi9xsN(HZV)aO7QYC6LH8z|kTXtqjRfR!t(&rwt1FJ>~{ zDNxP#IO@n4?7XUhAkv2PW~;kL;w4X{x54IQgE|T~ARhjhc(W~{QT^r~;@uc<)pN+* zMjKm)ngI(&AdU`o4A4YIrvasXufQt@ng(8jddP(BQ1if>4&DY;1vHv1SP$tDyF03W z8_icidLsN)s^0>g&*<0RIqGttUUkG=#i>kHPovx@9b42j@b_y-`_(d_-vK!e)tn&G z+qR8nvOrr(Hj^!_R@%-;*R`gP@fIQ1gL~kwf#Yohx)CTxy#PcxnXFy|q8zVO?*ZKk z>07MjWANI!PQDELI&JOjvT>w2Eq6QWebn(ZrypT8`nN%qD!8kzP2F6A&CuM#<@O*@ zpRKWdHV-P*7?eJ>g&tedInIbyhg;87XC(AJfw0|d!P7wb&Lr^G0Tppxk(rSD(TCXl4z(F-AAUz#Ks?9$1*C(vEo@O$2=UI>lJ`f(QGK}_yuW>kI_~tY z#%no9QGxnkGk(7qVbh!ikX{E~nsW;fg_!T$X|&Wie+2U9qA#&w7dd|cF9cql^H-om zpgf!MVn^Cmfg>%dgr(HKbf}LJA_XB9J6`~00;O&v9kYj0lUScvn#cMM0ItGqpj|yx0jrO7%3|84W}&Wfl9I1?ej1vugA_D6J0W zQR%O8vfz*EbGCEh;|{m@9;>;}=F1j!GTI>JeYZolP|whmbVxryh#qbMG`{H^qLi<4iY~$_+g_+wuGGYMS8C!0rxIbQe787P z042iTIldX!qaC1s*7aZ)@Y0+HNU1GUalF(sKIq;2VT47 zHCWW4HXy{$AT73eP-^oa+x1NLwNEf*@3!*aW z;IV8Sc&*mvR$E4GHr_TXZMVEuH}Mrmy^F9LoHS@AeH)x9Ko#6m7XVSOT&a!(q8VAe z69J;WsngcAP8(aNtwWtQuez+X&&JzrrJHR|_PA0z2duvycW=z$K7xIEygX|H+Lq1J z9`{t(Led_tFEncOxO2gC(B697^MStPu+$HI%l@R^Ykj`GF-BSY{63kz`h8Nb25oE| z?j_I{j}RU1FM)Kv&^%%!chQEvcjWOPB1DXPV$?iI!{eiZ)GOOC+zKQYt7WhMLhqM6FRI4xD zq7L;Iq$faH?33Q7#3#Lvo)4W3X{k?gDBFguup!E9h$cHzsIt6V8zPSpwWu`TJBasu zXrAr-1L!iKG~YKs3mEw)V!j5H?<4E)U_>+3r+_+C9He3NfBi0vJ=4(p^t)rhqa51m ze$wQqx8ZLqOZzCSOS2JbJ(X&*@z-jt>a;U}Zfoa(wV+XfU<$Ms9yr(4Db=DpzgU&N4Ug&p z&0h*^Itu(Ue<`;9@_jVFKMY^4$%x= zwU6ezq;mGhc@gwKi?_7R|Q3g+?^b z(P%XK2#qEH^}7edf>)tMx6n^fPn-NwZY{Rldf6({(qc={@&62A-$hu*Kii35_+E_u$s__EYN6w z%w*F1A0RB{kVe`c@w7ie|hx1>r&ZP}XEE}C;$7v?ob?EV z*y8Mguo2cwv5^IKyPQ{*xfR0BE-V*Wg_WRPH|u zyk9c91SrdgIfI&q8Hz@~2anb+8`PaZ)GjO4GX~A(I2IyorT1+$LL1z`usHGp_#`Z^C-Q8-0~laxGci0MrYA@ockRo8AE) zjU>tHArr#!uLk-D{H0re%luv7eF9#G+6c6jrBq93CcTPtEomzHFh*m5)-lQe+Tia; zh&>s72b2f2MFp?ddmi(hxIJBU2zVO3j(%vhe;4qM0#9qE8kQT7o=~sZX@@1*-2?tk zfImGV(k@PMplB?1da##P9GC_41d!g}I0gPn0&ie#TF!`eNzMZ*wY<`R@Ja#`AibES zg335I=7U#Z^JR;zFI)YEuw@~nTm8oYQ9a$_uK*(JxB4#!TEx=d09_AsU+{ue82J(? z#EsxJfmf+c0&fLSO@MNj>f~%i7SPyTW8+=vP(OLWr|AEjWeD4f5Ltm$K&yZ{)Egh7 z1W+<*PKS{W+WB*<)zW5>-m9W|-x84Vywgg%Eb8acg;La^XtwzzVk-{Htf0sG>rk|^ z>4db;@&+s_4N4DJ8k9Ym(xCK-r9qip584oZ8%MlF=@wO4eN|RpmDN{e_2t?SH5TPr zv^gN_t<<2PY%6VHTPTP0T!qjw_ci41CZuv|V3R?M^!ypT#qMX|Q9T%BE!5u+2B{WP zuQC{v-XcHn9sJQA_aZkmS+`#u8-=J1N_n){7Eo`kYOtuuq85vq*k;nwYI*Gzbz0=N zGte%}>$a%RqRkfdInwJ51ZmDd`^tGSGG|@njzu~?MIPh?WG$&@&9u%dh>`lz=g>a- z@+9mgvu4Vd#^BHXiFpoCo8`3yPqMsxAZisoR@xJ+HqxG;NK0)TD|xj48n!HQXq`fP zcokM!7E^>(kvomr46PB9fs)-_VSQ&1V^rYXO?u5#&N)f-K4R-ZW3OFYOq?G7|~3+$Ib-XVx){(Z5g%O5cz)E!=rkt=N7b6-o;X?<6SYQBSojesvgVh zvAi^=5>l$W16Dd{HE*_PAVx}hAVymJK#bJv4s|KC&?qzzGqjhVi+J@8IITpwI32XE z@Q0+X_1F;pkgPCLLz3Qj>u-^JCE_>_`f|A32rc3qx)^Agdo853KFSIqjTg%*bv z&Q$92PY5js`gRkcKLdROUJ3i7@~E+^<1(AJ5^HmXwXZ|b+UkD9QMC>4eb~|oUXA6| zTZ9&XKKorrJ8k~;**JPavbWR|k{z^$ko4I-A=#H|wE9{tY6yLTc-?(*2E;r{M+0l2 zeU%1leM3lUMB6rDKS$UE4l8x2-AcD`D;o=GZAkj;rjVTC#fK@!?~J25L^~pT!Cx-( z$b#H(DSiumB*xI(@S#ArW9KAq8|f_Y!Ys{B!2ZER^js|E^>6rlShX+o<%Q#OT{QzJ zH7tAU#n#_a->+_P)Gi8rj@4WdJ{_7j^(pYq1saDqD#Ftc2klQr&(%t-ma4GKv}&xD zt?nqqOS6Kl?qAM8ePML#W<68b>b4k!5b$>#?5hb+HmD&iV^2ePU+_+cw9&@a5IzXJ zdEoWCM*v*`)L`Rn+6GBW>2OQouO9x2;_2k^YM@>>?g_kJ469Z;w30guYo?|!wM%Nh zEn#WDEn#W3xKDvHx`D%<4t+})T?lkMT3)M-w=FEQ^{ikWq_mUOYEzWO;{wH-6@32z zM|~4Z>9`jDsE2E{>CN#kz({;6;?N-ucgf~k;co?a{q931M2`Pypp|UPIwNhjdDX^< z))1XsMl>?@x^KhZGL(6a|20_f1uV$%i!IoPGgkGwA_Wg2zC@ku4u20sTDrrtM(DXf z7i*@S_g?pF*!+(X&=))jh*Dk@Ox_E#b?}OU6M!CurQK{5g_s)50gp7#4jurcFdLp4 zECSkquv3F40MUA(Ja`t+V+dOwyxgK2fSzXFT|mzJ3QK zg0%lkBS{+1$msN;$L3llkGg(@n9rs44noxNY`Bk*>OdTH0@xRpwP{~i)~1VtFG9K* z{x);I{L6;@7HGhR7_cFf|C<{fb-II{HXFhpE1LbWqB%a6TA42oE!j#_tu&pb6q`Qf zNrt~1^%iUy1C*>j02&W8+ebG7XoXe~D`Q1Ttn_Qmwsw}Xl;%Epu~%Z|(FIg&LzFS1 znL=5t>|K||O21nXEA6++hR`eAY*;Yg`4qP36%`>`QPo?2TY1cj%f_mMcNb`HQ=j|o zjj)xm2S6I#~<#<83xK+GFKJXLWEM z*2xtJp+|`Gf!bo_Or$+lP8!w)XF~H;kZ!hC#mC9)AvI2VsgB^Sn5mL2D|z)!eO;&3 zm*yM?EwpFUW=pz_^MKBUa;?5>tFJ9q<`!)>9cfO5(Nf0wLgP%HMa33XSyW?DiAD7m zHLzyt1q$M>HZ$Z>meM@CH100TYXYJ^r_F}#vZ&i4y)*k8cP!o7*JQKVNC@V%*30vL6QEn^2o9fU?_+g-}F0INR z1KPlK_bH%7cHKQShEDLG1usA5T4>$?G&P21BgFH^OB)z3)TXZO5KSa0dFiYthR`g6+niUPaSBYff;+SNaURCx&*X zsh;-O`EHM$4X0ZBraFIx7CITowY+qT;^U>o_wcDIojvvNNf(W#dGS(Dd+hmOUc8K} zJ+924I@G6#<71>F+iEVbsLY~bi%KmjiC=F@+Tpbyjj&ZLrL>jUQ@0vxO9Ss&QZ3%< zQfs81W|jH^7JLm0s%(m?;$=--&xmTQ-jn_g{#FOSMTq2nntN0KOw#$zQmo|s`(d>5 z2lvspF?6r@J#Kv9j2^sLNLL2~@RtmPQ&7XpcQXx|?+D6w_qDtzngQM}2%GPo43x!a z9?&G9Mw>597PVT`V$nc+BW`zmgt`1cd@B&m>IdSN1AWbCJx~kgodfYl#VK{bJA{tB z7dOSQ;v0y68qy%WO$}-D4LU1Zj0l zGeV?cU+)}W0d_fQY~0K>;!K2Sw6-)R&~Gtci+pahwk&q;Mc7jiTVulIBV08ORyA3x z=EwXI(m9Z}CP**UV)eCIe@_H1z7I1VK>Hwzofm;FLT;2L%E~Lx?kH7p2%14*Uj_ayhre2@r87Z#vxY>O z6*MGDAKPHVHd@rgh*H^RwdhgfMrdxbVcV^=%c2&G8m+(8!QYq}N?W3=?i#HvO&00% zHyTq~6F)XRaCf4Veve&s^w~HtBSU)W#^r$J)$)lB?bQ$1*m|tAn-SHGsR0@}DV59k zb^@KNMR1ml4VG*e}vSHREx4L%C#uZqGF3mEh@99!lFfdFM}+oZy~eV~uVg|-ng zeq0!oUayC9lKSkLgp=U!bHrPdaPaO*{gctr;L*OyX7=|twEda{iDLt&gVx;}Vh%tK zy@}k|5OX9D&9gVeOoyc!J&Ts|0Bqh6^QJ`)LHaoJ)>w2b5REe%V$K7i(V#X->gfg^ z8{b77ElFZQW0K69nv(49Q4+N+syX#ZC&HGG5Tcc}{2MtGMGb;s_Eu{BRc(VrI>@S{;i6+8*@0S2l2@= zSBX!Sxk`L8jV@<=MpBxqP;R8MKboryCQ&`z6`Ip+*mN5<-G)t1z9dDDDcLrxE@_>j zMX-ftU(q&`%l@d|=UOeP$<&Wi-!z!C0wG=isX>KY?_k)M ztZqV$pwryS7-_53F|R>d3~8~oJ~!bRNkdB6AbY!2F7O%-n=tNS}kWBw2PG zaufan9?db6LoJAd=8mOSU%8KNh0zX1X>wtzoD=_l)_LP~AFC0W)zB{r4GuH4Sw>VFNE z9se21x3SIITp5zx%SP`1_@rT^Sl}Nin)Qx9oglQ^u<;|Mr%AV{(@MK7>a%FG zMFSS)*|3cxzK4C&VdZ)U)c{YD3 z&QL`vf4m$ariQKss;964 z`WA&|6lLs>tS=k6(eyNBBR8Agr`2ldWJEQ)h3%vA=(6@TS)02puYIJ{wa$?=v!osM zE?aJmR`V7&4tcN?R&B9$qsN9#cE>?_C!{?irJg3c)4;n2ycX6>ZDEUh6nI(K^JuY_ z=GzmF9?RR_nN6S7vVEzXr}T}KmRw{{J@oy~2VqN{It3Oy3N$!Ub~Fb^%8q88sx(r6 z3iVBNqbEK^{Kcn;zf_je-lpDRq1i}oiqz*ki#o7Z=c*SF+ah;FBjyo69nM1VXb+{s zvG+xt8x607!%_*(w$?`&eT1;ZDKd{ONuhJtt>BfUNC}pt+yO20%|J=YeL(I3*lP*N zcPypWs$xbod#$ypthLe&?ka?(JI5N){$!;OF4c?qE(ZFioFataMsFhMVJ{QkV)9&$s>v_42*a z1A*$T%|*U32ut@iTbM_?#H}eS_Q4*=hiD7TqZ8hSl=0X(CTT;;B#ZVpyU7hHM_P1> zMRP5>$RgQ)Zb(|ogexc{88`Sma+EQ)+qMB38YZuC^cAG=(T+%c~ zHSj8d{FPbM$^M8pV3FQoE`^qL!C8oH4p3ca9uU>`x=_o>`X*al=pxJOD-&LEy)NIn zP@R>|z^){PEw-oYgDEmrtP5TTfAcuD^V@Ng2*{sGEsAp2pGv*$0`THfC4|E_8tDdN ze5#ByT{gYl7Nv4nx^Izg!}g@e>{V-_?|}Mji0o9k8Qjb{#A^*JEnurCuL@G>H$Umi zzY^wATPR5V5WE*LzbZ&Q7rUlIPbeRbNyQE4YjM6%X46)dD)l9LlKEkfEU3g8)dsg2 z`9i1WH8zf1i#qrY#_y3Yd6qZdS%MLVZXfG=0JlJz=G+G@^!?U+=NTZ{^=r1ZshQ7{ z>FjAG^HLeT1An(8Y#sMpucH@Oep(mEwy}l zLwQwic?}lnJN`5$Y_z;4ioqojQM-II`B-qp1u=b%L$G4mj$UAomVhd$}3%TPDE zIkx$6jygF+-v(WhhWcV{?y;8Yy^NRPPlu=j>KjG(Z9j{re6BY6oaVa>=y2pv7i*!m zl{%X0DWx)X^c_`-S23xhXK4#Ku-)d1V%rj;5M(KGNG@EoiZ*)uJ|w8ZBzFNRRASK#PBj^arUHwOfBx zi86bwN|ezcoBeU^93%OXK1Qr6uv)sTmXa~lYH6e^9V2bJZ}g1KdiSGm^hrQes+(4DL@wfHQJy?%NfOQz@9#%6tvKGpe~z^t}*o6 zSqbl9%{hjCb>|R_6}YAr9#caLeSn=MbTCayz@^jBMV zGor70{=kU(Q)=CnioPMIF)DAY)VevLJz(jbyNL8p@K?-IK0g|}8!S!3X)H;)RzFsDaat^DVnplYR;w@GqBe_kA4X|Q zwY+SL2FJ`ZbHSm8MBcE=iM?oN6^^kD{EU zII=keS&*H!&REdzK8Sii_q6mW{3nQ4qc4Hdd{04&B?rC?TMtCzQ7>*F0imQLPCpRs zZk1VEl9fMC`%6}-gy0X~WdQ}DB^=HLnl)O`$v_?IK=6_vP3H9=^Fsz6+l@rNeTL%puWBHYw#-770|MX(L$i>8T}Uh zOCwM%mlpM%^;}xicQ&L+Kh%&W^{+ln`c6G}qTYA&6X2}@FW&MthE9T(W1wYYs0QdXpmZy(O|!kcMKu;x@%?NX zqjGnVn%!k*s;z7l)#uiaJs@?GaG z&^I-(@;isW|A_FtAR410+zZe;YMHwRDWb1KB4N6TK)k7em%yWwpQ(X&4eC(+Ky>?k zG2h4=gl7LZd1E1U9QDAo+vp!B<53w~MR`!R%crKk{nYyBPe0V?^QRxR6ZEC0ml=KO=?iy) zzC3GRUiz&&L0?Jwy~e(h^uO!`eHGTeiu8>;L0@h9fU&POeV0Ridige{=RgbfSB>e1 z>;!$SHodLsk)5Eg)9UL?pSu(E^;ms9>C{qwYWo;SpKtPSApM%1U|;-r>Hp%#-@X&{ zWm|pOl)u^^mUDI*$Mjk#V!{sg1+1d{=>}tZ$b*tPpyB&6ZSItiYFYj6ZDl#pfwn+1CkY;w$NO; zWCE>SXl|RVzQP=s?!V}lQGy5IEXGH#UyJ}MnIJ2cvI(-vDw`lHmf7|@+}Qy-X{9gW zW(QVUMDKY}Y%|r>SWTosU#^lb2@Ck0EV@l!!S>PqZY9s)-@~e-GVI^aoL{nLy?Rdp zk5FZ}_!}KtW%zi5s`a`Du~kfULgezdn|w-P(@`BRfOG<^>gM+eX&LUKej=mVK3(HGRH4|h{x@LmxwR9`lqwTiu z3Uw>l&#vVh-yK%fv!%2)t+%%5mm{exmxYgn^>p4iJ0N==vjcKQKU*DR_CZ#0o=$~6 zjc6^T(Q)`LP$T-jwmG_o!l(?==I~#>#(S2G#sN{h&Ed*Zl{yIeI>INz0xI9;uvpL> zZa48Zho1qWug{vpF9Xq6h|S@*fyjd9@CQKjnoD!|OP~uGIfz3`6M+hGy4f7w%f@@C zMaNiwr&(S#5S=_Wha0Svkk-5e=mX?rb9f~X?d)izQ`Byy?*M5F`hkAMR=Ha>uiTdJ z<*_6GjWsuTafI_fT^+wP{0$wEQ6(IUGAU zh;{&JUAWTZX?5sQphDzxUHB@XnLtgp*42ftGya-vORfvwX?Xe_G`e|F7rq}nN>P(- z$t~No0IG?{LUW6)VRhk05#l~h8`-=Bt+6iL30@}bs}8*m6akvewd7>Bk9Mf29?TB+ zK}w}CJ1qW^W43^I2K@Efl=p_IEzAXPQTRJZtAH|NZ$!WG8e*#s#O<%^mA<=h1!6;g zfOdHUTQCMv>IL+xP4@(G(&gJ5Jo;93zI{VY_a!yZJl}T+r25UN<19Mept`WcRu?`S zJknejo)1K&+RyP)+UEPN2Co+SR&vUZf^=oL5xj+#M=h#4l!2Xzo7vL6fbImU3$HNx zs%=}Xwx{Mb;YT3-J+#!?Z=A}xZ)yauE=>EZw=w#Y(NY&)XA!;XGm+zX2RuR>!mCE= zbkwq?)XVEHkei{U#+E`&xE~>?1yqLyfLb|@zyYrMBcqW(ln2lPME2E% zKAc$T*ZSSr2tnmh7d{h6TY7;-vfEP~rgwFzX18&hp|c77WfQ$?FvqsvcH5%#+f>~M zp?7fK0cy8xD=Q}YauAKCq_2H~j0^evQtSI1LdMHZ+sZm^+nOJ~5|;W=Myp-A@Axr7 z=pKE5k(|kOO_2LOZPtRm2}j|+E!`36=JAb2tG)^HI&|Lzc`-WAz8X8gX`^vk8pXTpi>Z!(Ie7GX*9NBzi1L1mz0I=0S!Z}N{f}1b z(LULI9Xz_jH)t(*BL3a5tI{#c@Mp-5aJ)sS7NuKM&#w$qDzjn_MP5<7IkEHWG@2UQ zh+9L%%a2`bcxgNvp&F*qD5R)TeT;X&sV6MRC_Yl(h%d;XU!b77@dX?km1RMOya7>= zLBEef=T-$7@)|@z#`WOQ7i0w)@>Ntp#$({o3lRkwzm3Q1tr+(UGF}3YZu}Nxyk*h9 zfM~T{kP*V01HA6G--s1te28Cbq%RMm-y0NUq#1wR@$xECK}IfYW-SSH=1`G9vAH;3 zp!QpkQ4yojVu!v&&p^s6GUSbgvJCk~r!<3RMs$;?B17I-D9(5nrKNfD7DIl_X7F~0 zmf8$?C!vbNQhC&7$SVptLHX*uI!HbGWP~WNU#LzEehDp9n|j@UpQqc*)L*}~r*o(!wf*#hcgbCZvsg_rga zTW<1IKonbU^7TOUl~8W-tw0yCv<8UkOK!51U~Y0PtfvypP2Pey2=&KgqNSXUIC7KA z5#kpJJBPpi`67;Z(&BTIS0ZhfLYkL(H~cMNv<8SQ=t};pNpAsLN_TZT+$qpZZ{8O9 zOe2U>DzrrcDFjzT4w^vhfH`fX|EhY@{eu_SXf z`rS(8OPS4~&GuEFs!X|qQIjcSUQMQ5DP_vJ+GhJcO--hp0o7zmTi9%0zNy+qN;QI7 zXw^1ah)3zDvMK81`zlnQJ4a`uc2fQ8vA0yx$54%>zOLK)tIw1>81GAX za$|7J?@Yeb*ju)(nX(63t1{_gEYUaKGXcNBHh4q z;A`M-Ls(8w>%zr|gI4)^4`2zT^R2&B`<-UBot4gKM7>WPBbsF_vS=B9Z%@3%%%f3l znUyv(q8hQ15tYI!i&k5ISr$#TsKcUljGAC+j^%BzDBq&D7_ET6UPd&#?q@{tZec|B zZM8gyN9_9%BFu>VB{Sl=l;vrEB+atC97Yc#>{QFkXGHN9S>8-Wlz$P+o6YEPge_lEjCBF| zYxdv8G%av1)A4~;rdfeipoyv~P|4vh4D>Lq2^^bG{L2H+Fs%*jcM!Q31nvV3sm8!K zoLPj_(m*EDroiq@mj~#SJ%m>>_W?~*U4cBNg~2nJKPO0M+aXmEoX`Aog1=%~75toO zZSeI1jwkpL)B0d6&K?r++Tc{CF9c6v+7sN!SV zm?p*igK27vAA8A(YHUmj(@8NCK|^?ZWIEH0F*BH|(9c;uHgp`*^iVa^ywFWd4-7rb zv>@~j)51_9_J9-dB3%a48KEhlA@xe=c&6Q?_Ql68jp{yx7l}9vC~Skiu8Q9tIjx_r;#W?(W!M zFja9kGyjITx7pnpw~^h0adG&a1`F;G`EkADOH@oM~px0ue%%s{z}RPSe<0E#z@_V_!yPs=?V z`8!gT=N<_fQq6mnFui-P2q?bg+UG)+FP^d+^o~@wPnpE}XCAy9G*jW7zgd3*+8gMj zS!)dXeAaUYeKTu=LB7Zv2E|3*Gbkl;d9e;VF7hjbc8mPZpvjSY4B9vHfI$aGJ~wE3 zn0+4dZf|r0CMt=p$ zWb_757NZ^@Y?rC`R4-5=^L~x>P7$Nu0nK65094LsG0<5+*F=jfEF=t z1<-QlZ2)R!^g7T=mc9+NhIxTgVJV|nppA@10QE9T1yX*pAPvZ2Gyy1!(QZIRj3xoi z1e)gT1vH0wrvQ~RIs>SZr4>L6nAZqY$7mT)Gow3zIvA}0S_gDnH!J^O>=sIGMSe(2c^Zli9m(SyBugH^L`05hk1_zEnxH{&~iq925JGiEz$|J zhIuaobuzCTXe0C91?mTy=JWyK=QLqUZaDzZG-oPMCiBh)%3)p=P$Bak0V-njIM7U% zwgb&!-j_h-jJ^S?WT`q6mNM@kpgKl}0WD%_G0<}6T?f?6=q8|*EL{q;hIy|7bufAp zXdO%60ousCMvpY~G^UejzVsrse4oho*3YqsLP!Xd) z1I=V~W5a@x(cR-7Pra7Z3kV=*o05vlz0$RcTjsRN8 z{!Rp1!_r>^bujuJ&|3D_0JM(%-3+vmr7r^YGI|AQ6Z?A&sGt390#b358{_99HyG^- z6b72+>;aU?ymFu{M)QDn19~8G9#9VZy8@_)rS}2NWZr{7<;?pKsFHaf1JyBak9o)g zpo=59K#N#<1kiGzxX4vN&Ft?>pp`8B2523lyt9!umi_{$pLrJn;b&Trjt79kK+~Lu zfpQpq05p@)_;X+jqZ5D@FfHIkP6HpeTr9g#@ZU-u2bQjP}plQy%Ky#S)PoQ!}p8{2~bO2}p^L9BG z`Nt>&Xd%$#NH)+S_Ll?H%+fP}R}O())pWS^5spCYHVj z)X&m?06B@2%8BP;egHH%G8rfgG|ia;v>Ws00_8C8T%barO|$L6gefyx*ND2vfjpbkd21NAbxi~NltfA<1q0>wpIfwGu4<3d=) z=;uJ?jE)1UV{{TwGovz~UPk3WzOj@q^MJ~MHqAN@sE*NvKv`+Ty98)DP+a5+gFcFk ztVX}VJi4*B5a^>w9Z)le_#My+<~0CyFz-g7wamK(XcME`fqc7A*cCu?fHuuq3ABLG zLqN+J{Sjyd(B#MyKx>%y6wq4cJp;6ndCvo>aipaSD3j3!ph8Bk1I=OdHqZh_8-bQH zdLL*7(B#NJfz~kZQ=rUr(l-E9$Y?9j97f*(l{4~P1bvJ`Ky{1~fR-~F3DnGJ4A2@z z=|CNfvVb-+nh2!EQ*4ugG8s()DrB@D&{;r}BL@L31d59s2DA}qZR81{tO*qMDWDEU z&j9r@dLC#K&;yY!ASZ+Ty#?e0`aJS?pe*KX0@@AeqsWH_eG~b_Am4HB#aik+F5RNN zESe5f#9C$pl`}dWXdzHsTiz1DyplIr1&g0_M3j zu%3A_K+BmI543`L$v|tEHyUUoqj5l+7-brCO=Ne2Rz&6jsa?sI^MHInlOq=bWijs( zpdvSc5!&?ZJDK)&6{`Up@aqZ5I4 zV{|G|A)`4!MU3VGO=om2&>Th=0F^VU0XmD(e4qu4eg#y=Xd%!-MppwZXLK!4Gou@U zRxr8+Xbqz#pbkdOKx-M@1Jujt0iaEc9tLtIQaT<5@-cc6D2vgbfp%lm2~@~v9Z(UY zzW_~V^eRv}qc{IQ%I-Z*#`2FJ|9xAsyF*eUp=MhpBo!qIvzCy=tej7?Z9+~V zhoo|@h|IQ0%Au1Ksafj~l0-!*vzCyYLMi0;dcW-b;`e!cAHVP8_s46m=e)1$df)fl zJ3G6}?kto={Q`xly-%+eg0-L&)_#Lhsl!kjbsS2kPD7d0zfcx+0g6z?N8lb& zNl*@TC6r5D1LaZILHSe_sDQc&Dx|7G?yYvFw?PTiolpvO4-}vpKxtF}3Q^6VOzJ@> zOtpa`)FV)o>I~&jJ)jts1?5qFpg1)EDxiiyg-~vAM3D;Hjw#aQU<7ii+c~d+TxtX4 zr@n?#sBKVy`T-pkNO9SQ~yB)RKn9Zml}31iI7W` zhWymkPzqH63P8SKWhjlcXQ50g8;VfRLpjt-P>h-m-iK1Ck9MIk(x-eu4bdUMN5vfI`$C zP$qQ(3R8bU5$Y@yrJRxIOqGD*R5Ik$vSXBi{8Tw8Kvjf7)D2K3l?sKaTcHS53yM;A zLAg{tD4)6?ic@J&A@u;{+-}Eh1tm~zAwSg~N~O9$0jejIMm+|FsJ>8`8VF@mL!n&i zX(*q11}dbUgA!`naVJ8l)QeC$H4Vz5UV-wd*P%ix3MJfOdlx{d)Voj`wG2w9K8Bh? z+k>A$nXG*QWl{N1g!&4~rnW#i)OS!W^&^x|?S|r10aQT!1{G3=A?HpztK*PMorV&q ze<4400ZO5YkHXngNl<{g5=x`4fzqk#pb%9B%A{_BvZ!iMn7R#$P z0VtPh2F0icp**S$lutbZ6;Pd_LaGPk+-3JN3re8+Kz?cfltK-GQmGM8fEoj(Q4uJe zngE5U$xtRW70RM!L1AhR6rtur+0LaKS@&!MI66)AFw;PSKqB=oU zq3yx$P&#XmLRnOAD4XgJRZUU+s^NM z$WQ$QrBZvKs?he}J}AK2At;?X3WcbXP!@Ft3RCByanSZ)u`xJP)=EM#suYw@m4)I| zd8m-81o`i=_mLk;hYH(vhq9U$`S`U%RS_CWSiJa~UV*{mIca;c+GK6Mf*q|QJI_3dcqq2dtUAJ5?G zvQ`pGrAk5RR9PsCDi1vdZ4Xw0BCPqLZ0cqxhpGYPQnjHNRTs*m>O=WdBWNwOJ(v!~ zS!)3mP_3atDg$!wvvckUB~aa<6e<%+r5=X@kT2K|N@Hy|lui{uO`+|<-=Iv^4nq;@ zIFwDDhN9HJP!4qg%B6}wi+e;RL3z}bP(F1H6sN9(3aBbjA$1evHn96q4N9PHgHotF zp;YP~D2-|WrBeYYlWGQKQ4c~9stuG)Jp$!WouOQ+2lN)SJ(vZ>SnC7jQ3IfSY6ujk zMnDDB7|6Nb&N%|P)C9;+O@`8`sZbU*3(BVEK)KX>D4%)@N^NNU7C~v$QYfAJ2xPP$9J+N@!$f@H>=B9fQ)SQ;_|f zS7Fv8`a`+YU?`s&4i!?P zp@cL$Mi@$^#zR@u3s8ib0%cP(pR^63V4YK{2WCX_=hgmS6HP#*OGluvyE6;P|7LMjHi57-&3gA%AsP%5<* zN~d-}S=25loB9>Xr3#@u>L8R)9f1m{KcPbEZz!R;9qk;HO1TjngSrBWQa&h$x(bR> z*Ft&J^-uwIBUDILg;H8r=ju?1x*ZBrb)anOUMPoZ2<1^tpnR%1R6soh6;eScp`~^1 zV6#+LDCa?|g`gPZ3-*HYSUYX&sDB}+6@HX4;{xPDg>93c!DBGe5~ z4wVY!QMW<`R4r&9v?_QPp@}27rY>>AQm9X%G-@@JNv(k*)CMSr`Wnikwm}8d z50Kl|`uz;0P;n@Y+7IPHzToe+E@?$aaia`a`I>>#* zW;a18)K(~s+5u%!yPyd5E0jYOLV46dsDL^Gx$UjrpHK?*Hx%h$wR1Mx(d3T9EOiBx zM){yj>MAHgT?^$<*F$;KjZgtq6{_0F9ud`{OsKH!?NEfO1LaWnLU~j}sDNq$xt(oC zb0~#+2uh=ZwvOsx>$=#wuC|T}**dBhltVoMp5D22KiN~3B(nN)2kLe+(GsQOSI z)d(t}(xH?-)~^MWMzw}AsSGGWb%b)LZcrYT2^CO}LvCN|($CgWPue7v8V99Olb}rMWhg?;fO4qUpgd|GR6xB6x&5r)LMVk=45d*YK$+AhP=s0qIx`A`Jf!?DkzV-7Al~whuneI??xzdkf|yZp{heU)a_6nRR=1d?uFbZZAU{Wg=zw& zQO%)D>LDm+u&oP1c~l3efa(glLu@u=>!@C~j(Wn@QG;yVPJM8-oq!6czaV#%?KlgiP|hUmph`fQR5BEy%0M|(IVg{+2o+E_ zKxw0`Un-PI-3mphT2Kyk7nDcUg9@nop|ml!Hx0_99)KcLD=3F*3*}Mmp#rK4gew2&GUjLTS`AD3f{xicqgZIaCzN zqZU8~)Vq*7*7_}jQmBuiH0m?RzS}Hp`-RQgcLi}Zzw`N3FS~Dp*-q2sDPRbxwuNcjG0ghH4n1K zr7z=cD3e+SMW|1q94ZgWqc%YW)ON_l)%0cThEk~gP#Sd<%B22=A{72exsyXBL3z~G zPytm5a&cXK8C9Vasuq++-2-J(jiCtD0?MI+P#)C+v>|+KRUkYA4?2Pz89KNBxescFUJ> z5^vp?P3NE#ss!GqQCH$^CRG7%Ba|O+bExWgn@8P+w*^!KymhBozot+M)f!5pIzX9J zPbfn5fpVz9rg`?r9tGu5W1#|S9OS-Xvy-frV|v+YZ<=O6nQxh1gCf*CTer+=Z`!)| zO$(tEYB7{XeE?-rpFqWz+gHA;Y~81}BWCNUbyoY#YMZP^ZG|$a9Z=5aHoFVTqke@7 zs6r_13!6O%Wl~3=2=%9}TWhm_L+(1$IVk08lZ&g9MqL4AQa&g`T?IA$#?JX#C=V)Z zdp%S@-3aYFYqM2t-8oZrXc9CdcssNR`Y2cj+Q{0yP||t(Dcgonb;uWdph%m8+n|=L z{RH);dQC+?>NvEB8a)mDs4J%9XRN7dP||6EeGpZM@mP_3!86hjJfqlbdd9&b`GQw2@M=#MsX@l8&?2m>ld-%=zTir!^4qxQN%k0; zUZk2CbD^YUt5sNt`v&=fw-qThW0q=fK^yT`uQms-dk0;p6lfA&5hXRF2DAvm$Ex&B zks4&&un2oG+b*Lzbcnhgir2#KcFbp1X=`b4mO8kthI$U zveq7ov(^K$S2M#;2|#|T4-}vVKp|=f6oY)h5m5Mk+fnRY9E~ao1sYkcl+~cF8D$}- zv8g=drz+Vx$`8c?w&P~2rI~6#A*wbMrs_gbsy-B>8bNU?9der3-WHIbYHjP9SuMlX zQ5|jF16J#1>!?g9Ks^qHsD4nGdJ>9K!=M;73W`%>A*Z?Z8wdHRNv0Ndg zP>lKu3beG^Stvv~??De*tppTkZA!KpRR#)E<)A245sFhcK+eOqBNg&fw?YA`78IuL zf}&JCC`R26#i=yN-^RK;00pR4P>5;^g{k&XlfflhgA96CR-#d_>S^@>A51|mX0t!=~ zLs2RZic#yKIJFsa+F8GEAwTs!6rg^BLew58OznfB)FCKF9fji5NyvG``kjIN)OjdC z6s7xqMJr3c|6`@~0$WJ{9g}PX67!;;PK~ZWf6r;vL zacUCebhRBXLw;%o6rf&%LexAcOuY$3sfAFSS`0betjh;bjQYf8sZ}=H-DYEupIT?N z9#-1~g{ZAinA&0LX|ubaDD|t=GObn!Igi=L`9a7}^;?22)KMr(4PJ_Kp-w^mezteS zGOVMo* z_ZF*BH6dq=)$V{o&zSCp!qk0GbgUh>F%+ZTgyK|*4{^?6+tCLKPy?V4H3SM%BcLcX z28vM;C{9g)?1dZ(+fIi3)Kn-y&4NPI94Ji9hoaP5P>fmx#i^x`^PKhj2ntc3LSbq( z6s6WcF=_)8r@n^lr6da5ZiD>P4^V*m846KxC`|2#qSWtDj5-FzsZ)?M&iefWg{l9b zD3$OLc2J2>oGJ}D<88;)ke{jm1*pnUh)RK?)Gbhqs%h&c*n8^^TSv`>;t(D$AEWlX z&6bA3)Jss5`U;9c_zD2uzs9L#$eCodGLWAt2L-5#Q1k_xy#b0*sZgA{6>=uqY%R!7 z-30}xdQgbEABw+dXO(8NQ*Fm0o28aQVd^6&N_}dYX6sf%F=`DIr#3*&bnExE&Awvm zN`8V_subkBYPGVEpDGWHd(Fl7wUwZKlpm@(+iEx4ELFp5bF5YydW@!ACAZMZNs0R6|+n@k-ClsRYfx=V+C`tvO*gLkj z85E};v~}-Vt&Odt9HcC2Aiv847%E zvs0m_(Dq=3m3W*|m7#r93goP|b+mX0=gJfEo*h)>v&E6s9Iw zZLQT_hKjFq@iPfCpa6t_6SP@s9u%hDgrd|!C`K)Y;?xI_v)=Z80{N*`P=Ja-A!;2I zrZz!QYOB>Y*xnshqjo_t$QS$-3T?F6w9m1QdH{-2t)Ljy7K&5tA!n2A=mPnvo=|{# z3<^x>R~8GwS(eRC&>BHc65jQ)T2;<>J5dc{!o}2 z3`MEoP>dQ4#i=ml?6iL4AwTtk)qb&iKE-O(Oeg>qww-OY0@E8-qjI4T^$rxKmOxSJ zLnubAfa28Wkh9mik4hhPqvQQ1BIx4P?$OdMX94uj5-PV z_u1YvP=GoQg{Wd*U@uh?ic+PZ7*!UE@3+0>p}+xCB`8Gsp)hqb6g_COHEi~fskY5h zb#0ca55=fPP@GDKoZoFn3&>Bkh5}TE)ehVHqodWRZcy|OdkopXlE|*k5+vWMbZlErP<-QYcD&1jVRN zp*Xb~@}ISSYoGwN!Di1{?Q6(6Z`x+-s2^+{^)nQr;!v2{4>=cX$M2AzItB%(Q&5Qd z2MSaFK~XAU4bG2BgyK|b$X^_P>$C0EkW<1`!D>`xC_tq^A?g+=Ox1*<)E!Wax*Lj9 z_d(7T)~_+-rKv(!&etd!OEKyhjx$eIDTxW_wA!;2IrZz!Q zYAY0@c0h4z7vxm5y}v?!st^iL2cZyk1PW7sLQ(2(C`O%w;*^X3v2?Dtepf(#$_E9g ztDq2dEfl7%hoaPtkWU}6iEr;UNO31MX9=`TWno@C`L7c;#4~1RI}L@ke_M|1*i-tN_B){R5!?}ZfB4Q#i?A#f17pL z4+W^-p%8Tp3R9<`DD@8%qyB^9RKf;yu4P>kq3|7cjM7jH!cRy-acZ2cyVGiuAV2jo z6u8T3GoTRln$6a++B}=3-Za&<+Cp1LEr!C>2avr+KE4xy;`f+VK@R?o3!Vi`^-b#_ zKeY)8P+Or8wF3%MyPzobD-@#&ZQXs=<)E#jj@UZtPg_U*4f*f4b?2Y}<$i@7)D=*a z@e)JP>A{t3R6E?EzM?kTa7A!qSS9tj5=(yO>Et9o25?MEcGuGr!GK& zbX!+^BRW$_P?)+Bic;4=G3q)fPE~=NrndJc$WK*+!p*F98x*DPgksb^P@HN2IS<&n z02HR0K~d^K$luat+du*85hz4;hQd@2C`x5PF{oy+4-}^cK+c0!8v^;M5m0~{1BIvv z6s9IXQED<2qozV}Y8K?QvVL$e)7wSzYKrMtq)M6-1eE>zNPoNmJ3W`%P z$a&cMt%Cwk&EO^|L~Vt_)D9?0?Sf*|uTY#Sgq$|E_aNk_jz9tGPbftF4TY(5P?T~v zqYHHfA{y3R8bWQR*BNquj62 zkGcYK9^o~B{M1!YfVvh6QP)FZ>P9F^RfS?y^&;U}3W~G#0pzr|d-+L`Y6k0X!7)&) z8EgavsB|bqwSdA@YbZ)(KryOgk$k~!kiUa<-Uo#se8+;H?+R1>p(r&Nic!O%I5pa8 z9c@S0YLG8D9t!ocvx-4c$QN8!q?*AVTfJJA^d=PJj(t#^Is}Ctx6VhQFm)1&QfHtT zbsmaS#lFQA>TNqpLVl_g6rjpNA*#Hsd&17DlFdT+7aNO-hq1JCD6oT+|n9Wja zp(wQxic#M{acVo{JY_p}LVoHOC_wFnLev2$O#J~xsS{8fsu}zXa)z1CLVn8m4qd1c zP>4!~!c-Y3N|h^;FIdsm4Yw{Y**a=E6sKN=oDnuV7xGg%P=IHEPC$WC zw)Zb6M4g4gl(QXssS=Pg+SVmQeyR)g7!;!VLNRI}6sLwl&RE;~ zG~}nAfx^^tP?VYo#i$pdI5iClgl+FDP>6aR3R6)iN-cowCGNXsybJlMWl(_n7z$CJ zK{4tJC{E==&U3c+E67i6fx^^xP?Y)+ic!0vI8^`zvTg5gP>4DVg{k9ElsXML<80l( zke|8$1*qaXu$M}LV$_vToVo^b#@pWOAU{hQK}jgqi%!Z)SXaZg6+Kr3Q-N9 zFcpBJR5Qq#XzLz?{8Sq#Ks^G5sLoJ~>H)>6EXaA@_V$7N)Bq?<4S}N62q;F4f#OsI z3QV%S6QB?^846QVp(r&Aa$c}?b09x89|}-!K_O}p6r+|xaq1(;nQVJMh5XcNC`_$^ zqSOW`Mtu#%sclf;McexW6rz5H!c-iJQu`t2C0qA9!B(*xp;95LFWjQ+Gg7>TbxHYU}QU{8VEoKsALz zR7)sEJq*REc91j8_I85&RCg#$Jqkss-cXF{55@EB*>*7GtT7FT{M2YDK!u?YH6996 zFF;Xh3KXMen$}vE*^qyO=?y4A35(;my{i9TcTHK{2X36sI1A{9A2rZzw?Zhr-lgC`t{7;?!u!`PO!X ztwxQv+BU1b00pQiP>7ldMXA|PjCuo#Q@N1yo$Y-G3Q$X+5cMGxrB*;O>T_GS-FD>J zI%>VGqc+<*>RZU!Ve7t!{M1iSh}r{%seMq4It0b3qmci5+j|lUP-mbpbsmaR#eT#N zswCw6U^_}d0jew%qRK;2suC2V{E+jb?YJ58Q#GIvRT~OZb)hI#ABs_pAZMrTO^5tc z3n)ajhQd?^6o-7lj#BbYoZl{cY~(^A>K!OdErFuchfs`K0mY%N8J|PWPo_L5K&^*D z)MhA3eGA2?@1Z#L6Xg7Cd-p&AY9AD$4na}sC={bkLUHO0qY!~)YC7~!) z3W`x>A^$J7qdXL#DnVh&4@Ie)p*U3oa(=ZPwXH_gwb~x5)rSI9BPc|rLs6;)6r);0 zaVi6H;v z8IZrw_Pz!MsCiJBdJ~FL3!xab7>ZLLK>mHU_Y){Ut%AZ-42n|gAZNclnl?dxYAY0= zc0eI&m(_l=b-!ATDulw+K`2TcfnwC3P@MYPYKLv_Ijd3bPdM%$R=Wc7Q$8p_T?K`x zYoX{-TX#Jaqi%%aR8`11X0z2HKXp44pz7G{ak~ch+AP%&3QF6s4v^ zG3r&w`N!7Hh5S^G)y~@ay=^t>Jt#oE4~3}ZP?%Z?MX4{L7_}CPQyWd^>=@rb&Uw>z zC_wFmLewu%l-di$r~@|ppPkDeP?$Pl>!`nM9d*`p!8$uX<7iX~$nPYemJ9``GEkT* z2SurhCfC;80L7?O$SG#ETOmJH3kp$pL1C(%%_iHr`=J1pX0y}-P?Tx~#i_QCkveIak@bfsmgXYU{4H+S9gyW>k?TtbKY5^3c-i4ynGOJavbst-e`V5LwUqH@vHk%IxsIQ<9wZ&#{vf1w- zKlP){QoErrRRG1P-=H{k7%JwJ?sy!d>s*0G4T^1S>^i?ANdf%5a^yaw9WnqJf<%z# zkvEXVNFMSnQh*#o+%)`MUF0^T0rC*i6X}KYLxv-xipDt@a}fJYmhH$+#OC)P`;o&% zw-cMVP7|aZG8~zUc@=RuHbkxED-q$lzeG6ors%tUPMe2fc` z#mH*Jj^mxjdfeWIoJ4HRImA0g>E^CuDTg#d`XPgnkw_SsgiJ?XN8U$1L)IXL$l;># zBu2Ld-WSNth+R)R_C0VTq$AS3D47^7wx$opfygjqERu~(LS`Vdkx!A$$WG)}WFKOE zf5&(n`K#!5$(F8D3bFfqHAX*j3(_2EjdVinG0+|3Xk-HNBC-;(e)bsO2=7Jg`kcUc z2Kf&u{@}%Px7t;31;mb11>?O%Zd5c{z3F9su*hvOb||tv2D`xn5j*x%7)K#?eZm+g zATJhW8ph?wuASivB>i<<|6MF#d>`R+jE-5j$x1g zPf_~u+_dsnF5rX%x_1&Cc^Tl)e0DPnsp-@tbMyD{2zu{C?)gGI6H zbhOAecN#9%-gOd@tC8!G8i>u^f$<)s5z?$EtufkMJB)TsY_xPn9!L5k6Od`hYsg#3 z5@ai4j}7~{w)5PH+xw8C$SLGMB&h?QPmoH;y+|{p6*2%BicCOWMrILF_o^G1~P=?&vz#AvF+t9NdBNQN%vpEfb5Ji?I+ngxLOKo$&b&DUVb` zY9S4fbmT##2htm{wIeY;SCr>5&OsI+-uuC>n|&;Nh?>Rw7})~bb=`^aH{=iGB=QeZ zyfYqa$hAoA|4SakdWM(ktB9^Z4|w-CElOEIoOHXy$ve>`<8)*(VxJql&$FN7_8P>V-|V`41>4sq-(a-+y&L0EB%voh7a?PiiHN;VreS;) zvFBvF?{?qpnD!f;w#H&LJC?1tad}bQ*4uNLa%1hM`1 zU`$8sG5!!n@3EEz4@Tw|Wg*5T$VZ5Mj{Op&-Pa8mw;+$=nvkg`Z6#2%B?FxI&&_rvx% zqnXVkcAxmU4K+J<2h=i=KFDa~IphW84dgAv)_jO@D`H<4{etl~#NMBGJcetAG)00) zm!kB*I0Tu7*vI}G7#AR?5qpk4i_z_cuZ57ik%7o)B!WDTyo|h!EJi*?Rv{aa9f&JT+;=U?Wnm-*+*eBd&lyv!Fav#rmk`r(WjTm$|`ZZho2DUFM#bxnGe-V4PTF zd*9e&|8?A6TvYoU<62}h@;y?Bl5qk_j zk8ws(W@C(Ac6$+QS&pniHXwf>=a3S8@iiM#8Mz6miPS*?Nb{n!#n=JqiS$M6J`E}w z&7+HK-w$TP_Hpt&##a#U_5#@MgFP48yyX+rK1a;oU_6POMan$kIyWHpeL-!EcNgV; zjP|_XU5|9!ws^N&UFI&ZU6=kCry;K)D-k=^R*a?k;duhF=S=&0It9KPX@xw3*uQ(& zed_|-o)AX+Ubrtt`yST5wzltCpTuojXWy%Ow(nIv+xM!T?fX?*Yu~e4Z5T2Nc>%HS zS8dL|SDlL6_PyyGjBg|Medc0}_PwL6vF{(b7T3bQkNX&NcH6$6vvDPEd&gW0Z$#`q z{D0+Jtg)}xc46F)*!Kg6i=5OS?-Qf~QU$TE*R6jlY+r|0$7sjB2V)vyU;93Y(e9sp zZR?$jeGTe41M`+ni1)cA1V3@vZToy|eTSkJL8c;Ri+#Sx!T26xYwYul*V{htSk0c3 zZCrshs}UP5R$GH{BVzAsyB&4V5C3}iCjQ-Sy_4*0aD2|!PAO-LbER|0xym`^TzxZuW&GP-z2c5D!TvD`<4wgJr(@A*f3Mzdk0~0b7L9KgjjM~s?~BHx7{4od zsh{=z7q^`fj`Lqp{qo!YyWTslcOKqxz4P#n>z#*pT<<*ox8MK!b}?L+1YCoXxc`Yx zIVZ`v30J2ouFlQ4I=4EdojRCp=#+7q<0`dq$~vvFvaNHC(+;aUIM+H|aMhl0DmVjh z)rL7$@WAyBF!n5_@I-J_z+$ps`X{}5x=i9!+A4trjwgE+gXq}$9X4luJdldEvOP${m-**n;r5_F_e&`&*%LW|Bul4_#xZF9J_=$5WafS1D;-}8} z#Lt}n5?4CKl2$nhNuN6%M9!&bv zX_a)!c{u5`(=O?6r+?BJXJFDl&hVsjPHxh9{O$SwoTW(@oMlPH-1n1;yB{T$a91Q< z;eMJ_(#=asbk`&$x$E(=Ro^6C>26Od<9?rXjoUc+IyaDfy_=p~*=?45quV^$@3u@% zaa$$dUK`9?siSC;dW21>Gn*%&CN`%${_q?{l9? zZs3khzTb@`H*~X;8@c0?8@m&e1MZ~c2i(cY&D|H1Te_bnw{kyAe#l*!+}hoMf6m&N z+{WFK+}7QNf5wR?XSfB)kGKbu+q=h-JGsY`ySOLtEz9ZT9`0YsJ>9>PA9w#ve!@MQ z+|Rv`Jj6}#4RwqAM!1Q-XWV4pWVe)WihHGRs(Y1hx_h;6hFi`z(=G3tx;OcvZdG57dy8*@d#mqlw}x+_dz&=+?f@fEloeEZ!_z5{L--(k0#@0i=e zciIj4&bW{I&bg2It}NEeSGibk-_6DP`fe%K&sV$H0N?$^2KfTThWOHo4fi!EHp;G9L!&(tTXeIxw<#X0+{^qXccNR=P)`gLyT>2B4UNbRIc$GCLd zOM5S!RR}xw@eBq-hp5reiT|lhK<#hVUWU$7bD(1P+r4}fDoK3;m8MofWvO+l?SL*` zmpxDg&K`uSP=7V?wF<80;nxJFIVl-HQ0>W#ryU%baC&qZHhS^xZ^kNI4vDY z_0FYC2k-u-Ko`&NR;b(m+@t@~nby{hme9rHUOM|r=iF86p47VWl3lfndmqtb?NZHt zGWz1|BI!fu;+bw%ZKrCN-shLP{Hoal+HvV)rb0FR3MKFFQLVGR7vGo78+)^VYxdH6 z@X~uap`&-Emv&rw@0Y^t#eU_Wi$|+0U3!0{s8&a6CS7_Dc1P{v7#ZjYC~9C zp?+)C?|bOt8Q4#>U(}_K-#`9;uRD(&qyOg&+)m!vUxD{;gtL`VyLhcGeSFw6!$i*B zirH!ZqkB<%m9+pgmkLUcOQWT!(gJCvv{l+C{Ucr3**iw6bg$G}dQ=)JJul6ZK9n{{ zyQLG-6gt_=U#cs$kh)1vO5>#0q?J-! zx}uwRjN7CP>1pW=X|43TbX9k+%RN#z={e~g>2qm^^oLZuhu5#NR9AXPdQ2K4&6E~P zYo*=NDXDZ%?`Soo=F($QM0!J7CGC_>OIL@y&b6h7q`uMwX|D8%^sV%}R6Nt`e1mka zlp*z(CP-0frL;pjDkVSa9ixWyp!9_Fg7mJmN%~z%&Qd?=LFozU1?gSsOKGQcLP~zj z>zpdxFSVBjN)x51^qKUXbXY3h%R5Gj)I`dX#z_mL_0j<;@o}$Tb?HH=pY)=%MEXWL zB3;$n>sLqWAdQsfN?%HQr4oI-F1Jdpq=C{j>0@c5v{yPSmFw$ut|dJn^^~5Lrb+Kg z`Onkp@o)<{1|e@e;y zz0NmD_emMj6Vh|i9O*-8leAa*SGsC|ceEN(Q>lmav@~5>EUlN~(!WxmG(-dp7Off zBZZ_Fq>rUvrNm+0-n*o3(gf*!=_l#DRCT!5rIj>9nk~ho1JacvyuEiz-K1>kU1^(i zMyl|%*X1rLC_O1nk(NqZq(3CzNUvWFsio9Mnkc<3t&`45caQS=4U!f~g;JH#-nx#` zG-PzjV!O~o5v-Gc2 zeXQ57lQdEKMA|Qv3wt}#r6E#|^sRJ3x<2CVtuJ+wMo6zn%cULCN$Kk6ync5|ZKXld z%hD2Qjr6m0N-CZ0b-qPvEOn9wOD{;d(&y6m(ow18IPVxYNokV(zT?Hu*kh$Pq}9@H z>8y19cyDigsgpE9dPQ0;ZITM5bJDdFyw0~v%_aN&$&2SaQkpKkC#{u!k^Yj(O!T_k zBBe>)q!H3|X^HfeR4Dx?Reat%MqR0m^n^5CdR4a42C2wytX^=Eq%9oBv6<+rC-XnFE z#z^y}HPU`5af;Waru48hSehxVkbaWROa7@|zvj|FX_oZ4R464+^Y-2;b&|$PZ%bRG zQ&OerUY8cqNa>4cOr%i9~2BGLy^fmHSt zZ%3LmSjv&MN$#uOjyt7HX^1pYnk#)Et(Sh5j!Pw8^Nw-7R9k8)b(RK7+0qngzO+pG zQrar*k&a0hq%yO;v$|2LEj5PxMp?$RJBBF&H%NGqg`($CVLQt7$gx!fwHOFg8K(oAWYv`N}8IrF^E zm85&5pwwH6NUuxFrLEE-Dd7$87*(WtQc&tAjhE(2pGj+^tKxq<+#wX`!@1Iv|yddS_5gYA*GbCQ1vX4blOrWRChtjis*A2x*42Oxi3R zkP_bXI^QTYkUC03r76;T(r40U=@;pk$Y&ZUA>Q)(==lX^>|r72Rbv_je@9g|8g@QzzkYAN-W#!Is(*z zC_O2?B)uzbkoHOLLa*NqQUj@zG)$TqZ)=7U$)!+Aa zw38yzGU*q|_kp*gzSLWqCFM&eq#Hl<_O_NrON*o*q>>+bJMNYGN^_*m(mAQt$KKu^ z(iABsose!??(JwNjg)ewEz;jo$|v65R?;wOzO+#~DOFkF?QJd%mR^@uO20_Xr{3OF z=>e&)^rEy(`c676UH6&SuYuG1k<}^r5s>`cta7+Up#UdP^@$%cb2?!WZ7&8d6Yt zTADAdmySr~zVx~@mY$GiNipfLR6geIO_TaduS#pABhqzw-rjVnmo!=WK>ATSFQu;W zy0nxANwcI?Qh`)5-`iVDYA215=1Uu-V^W2+UYEvFZ)u9OLfRvhT<7hrEp?Q}O0%S8 z(nhIJIxkgN?{&UYY9;lO#!9oLkEAWq0qLxC%?9rnHKlZ^t29)aEagh8r0vpSDd8*c z7?q?tQd?=TG+p{g+992m%5U^K*ONL)Bc(agDrvWLUMj!I>sLo=D-DodkQPd7r2^?c zsnTYz^Sx4gX^1pMdPiC(?UgP_mB02n*Oxj-L#3(G5^0lkKq|h)>z5)mkUC2vq*>BO z(l+UsRQemQb4{tG)LR-ap6HI({Ev!xBvX(@HLw>Kz_m6k|9OG&?YJL*Zjq#4o&(st>zRN+^zOMR)U^o%rL z%99GE5_`NZ)ufhEKj{@|opee{jeA`(q=@vsv`4zKz}wMK>My-6ZIb?xYVY;-_LXv_ zU!)3!-nyVPSz0Gukm~RAb_|u4NC%{p{ocCP(lgQ$=@+T=Z{CiE(g10mv_(2E)jHtq z?Jm6}t(LY)ha~r)x3{8nr_@r)ltxO^q(xGmv`ac6B^~mPcC*w>>Lrbr7D(%){ZfhF z)lX_B^^(R*3#4_@A*t+PuU~yBQ<@}wAnlUeKfJxwrJyuY%8@ooC#14Rye@Z3ouy}_ z9BG|&NGg5Q>vE^mUK%OQlk%kfQpsapms(OgX{0n?S|=Tr${zQ+)RVeP+0r6ut8`i_ zb;9dXO===_m!6hpNK2)S(mv^ebp4;+G47VyO8umW^t!ZM+A1BA5>9%Zt4Q^vpwv$q zFU^-eleSC8q%x>MPBVR!aw@vj2H|8%VvRDbiUx3``Yl3tQlN(ZEJ_?_sBUlXQD z1EtrcucXt`O?d6ji+kHhW28mWHtD=ny_mPRy%dp_NV}vG3Eqx7rS8%sX}MG&l`ih> zy<5tZUXnhO_Df|;czYX4eWh7ao^(X2c!jsOnKW2>Sz0E2E1i(8F6nitBRwJwlU|Wl zNIRu}r0WyCehs8Yq`}h5(tFZZ(tfE}lGpD>>3*rRG+de?y)SK%4oW5Q8m<=~VYf)l zq{pOe=}jq5vR8t=*yVzB16~vMVy&UnO&TrDkycA_DWR0t)L)t+eJFh|oslY) z_WCuFGNn<{tJ25PHtDG3yVC1-tJF+-R2nPIl|GYxkWNZTc&*%v*DqCSD0P$uOOvGq z(wEXM>7-N|uf2Qm7}caSsjKvqG)-D6ZI%v7CCYl8Z;~2I-K3GyE7C{Ox6%=*G+rC{ z;yK?bwU2<-yp$uYmUc;} zrLxz0ooh)grC!o-X|fcRmP?zYJ<=&Dsl0cz8>Bi?3#q#_M4Bkgm6l82NCzYbud;mc zs#TQkl3GcRNzX{HNXw+Jqyp(LsSIAV`Qp)TmC~dx(opF|X@T^G^rLiKN~-7`<0h$r z)JYmC&5>3~yQTBe4cB{}8%rT6BE2c)OZ%h}mAo!DN)4s1(n#r5X}PprIw6&*>~*ds zwUYWu6Qu>xr_xsGH|e}ou8Mbzno<*~v-G4iQF=pKE`2Q(N`FbEZ}5&*Rcat*NPVTS z^s2N}S|{z6PD;r)dPhr<(xhI}Bx#AXO*$=A^n3jpN}1AlX_2%=Iw4(~;&o{t^^&GY zpGk#M>6^U0^`uN`vb0>t#JUcai+|HIt9fZ15@|NpwEqG*Z=DJ zJod|beeT1$*L{E1XD!>hJBxI`NRvcbCel`s_K0*uq%$Hp(_`CcAX00QvPJ4E(kPK8 zi!@)PRU&N_sY0ZmMABQtw%bsoERpUOX|zZ$ic~7nhay#p^ruLHjMz3>h?FDJ2$Awd zdRL^wB3UhCYsnDlZjmO4v|OZJBK;;(a%OBTH;FV1~lJMEX@Ece~j7t`;d=8y)ROgNT)^e-4I)I zx=1-94HjvVNQEM85~)(8lOnm>$JX3bq%I;26ls!3B_iz<>4ZqW8)NHhBT^rcCWurd zQn^USL~?hCttC^WULrjzQocxUiBu`lA0mZsimmTDk@|@Aq)3ZIdQYS(kuHkVpkr)( z9Yq={(oB)oi?m;)OCqIqimfGAq|qYH7io(~M?|ta$Ck|ysjEnXMS51Gr6Rp2(teTt z5GinTY|Sl2>L$`dB25)(xky>PV!zO|jau~Ar{cc=caYk$$Zs&ke+#af+RA_Xt4)81 zHHW*1y%MRLNDqnhvPiFsv|FUw-zY1KY_0a!?cV(VY`ed*2OA?>`-2qy4XgO?>zx<1 z+TQ@%66sgFr_p}3ze2X--!7})5?h~Jq%diBWQk^?)>5SSZ)e>oY6ryY_MexCuetUY z$Nv5P<B1bLqYlD%a7D=_oD!RVfV--!cM>3lJ+oKjgLYF&!4cXHM zk!N0etkNQ>_DE(%(skm|?xd_ptsg0RPCiA7zN(8v+9J{+QuI8yC{n$yvDc#$Df$}a zk)p5L5>oWJ#gBb4wJwqE)?N$I--K#?))%JTN^5}U|^xXC5#QHT7DOIFqq-ei(qIRoDwd;F4vc7)Q zo{FRgNztSGnCLfw^laqO+9h5P>7_`T!lQE|X)Y=HTcX7xy(7{#kvp(sLOBKk!nY-=zGt@)S}l>{D{Yo^8_A^{#I=KcU)(RTKrYGT)*01%G?!sjp9qhuj%-x zw}kcWjr3a~*1V3iFH(z-lOIuwj#pocbW$Yk_SmEKNL7(#Q$#JkY`hjG@5?x#OcApNv(cli8G{>NK(7UX5l`Ot|CQ`b1TySjMOag?~hd{`bEd~ zTS?I)bh+C7JlZs}-A6^gyW2@pMx+)$F7dIcc2tS(%LJB)rWZweRirYJ-Vv!>q)L(E zYmQ%+@ioV{R?QM^B760Jzr=@$u^IATtR;F}E{f#1BX)%9k)rQlX`*(msC5*z+B2d< zWMBUCn(ttV=n?8IQhaNJs72=tm)oleJlZ9)jhYs*U-q3&E&5viw|iQ^61kDJ)b4YS zNGhZj-K+SuA3rDKDL!(=N4WSk6Tb#8cP;$$OuBbuyR|dvX!?KS^G9^e|NP!PAhO-~ zCybRm^Wl+N{Jr~f^WrVy2*qc}@p*B4MzNoMkBekrFe@^+&M>jsda`uQ_3-w9SwOmb#&e3lYkM$ zj?ZK+H$%DHGoQ@*R!8>bB~o<0ak*Jbe9cSf_fBMq|GeG!Jg0UWpGKC5|HAzmYSHHr zpL1RASk>-xWn|e8SR#5%t4Psz$=aF1fykrBsU42)74MSKUqFw~!Y}aX|NMVMddAYV zB6Sz(A(5ttR3y?mk#>r7Sfo=TdG3mBBSoYRA`KGhNs;D@v|6O?B7G&&k0RCW728IJ zNF7A#E7HRvO%tg=q_raL7U}OIof64;cWi5IM7mR?heVn#(sGeDi*!(=KSfIJ9b0pI zkp_u0L!{LrZ5QdVNaj7UwWNyFU8E5r%@pZPkvu8EHNv{T@l$jj?akm){=yMm=78 z^D?zhM6G`h>3_bBU)59kpKs&W_lniVWXEdpep#Jj+xWg+Y`c9#zo&9y%f@Se+!CvO zFZ%7gF1GBKVqYG=C06@Z)Z+c#>K@ydwW42(+*mE%@2FU|G&{DwR$XKLPV#73cWothHMQe@3 z`nKK{t5u4>F=-|CrM>9aRn+3!jW3%oj#W?5?|!lDgQ9lfw%GGY-=?#&-7D;~~wnQ6|`inGOq|GAzBvNQ_Y}s2x$`k2zk@kvoN~FM$*t{u?^jBo` zc~0EfrdXs_JSugl{U#=xWJFRgkp_@lk=h86){c}Uf21~nTJ$W5-{0y*QClL?I+3=L zqU);=>3dRiySFrm-Noh@wdf4_cadtZ+N8*K<)N|dnj!^A(IwJEYEQZ%vcw%C#h+#T zxeese=w6K?T^U*8Y0}k^G?x^effkXX&-ZmwbZhU4^o8j6EvaQ>*&5Qdk#wFEUDowr z?D-~%luC*|dW}e(MCv2b0Fj1^^f)Pc{HBQ7Jkkx3?f&OitM(g*PLY1`^Z~r{@YJVlUX);#J7>|kF5DeQLFu&HzZO!M{PtT#rysLsdnQ-9HGd&WPJbTQG4`X z_W8f9U2c7st6lE+U9NV4eTlwv#`o{q;jycy_FK~@B71rRwWlK~{ykh*YSGsy{`Yy8 z``fPvduPi+?}Vmq({Xp4&iD^c=7Kd(P-_d5GG-9-;U*B1?HR z`rXatj_z6>&HtBI`V6(`JA2nz^8aite(W#t=z_=+`iR)RB#>T>)KWxhOZwNn8b)nZ zq+cE>`aGT{MgPtrzKt!^HvY?A)jr?oRi=-OEgQd9-J(`IB5jE*d%3gja$CFHaS5`% z==dDps~*&%-yFwl@xK+E&!f?Et%$TevInn=TDeFENzpa`M2e2>mm3{V@o4l2T@=e+ zuHXOpEG_8^m%=@3_hR%ew=(~$a+lj5T^jXcSo>$4JK$<)Nk6#^>c>&x&n9&PE$L^M zMg0VF2TAUbD^s&+zqlOKYf$0OPU;S{qzf(=^^2(RXE${hTGAy~0(HrqK;6w9b!G0X z>!B{Yz0?&{__L3?7cEJ3`$-ydmrCxqD|6@F0QHdxLFx~q!kiIqA8I%5SJhH*ptX?mUf_bjouz_1{sEI&o)V?huZa)ZEvcdO9l7 z%~Cq`E@(+Dd@ZPFpd#HOWl+yXOKRzBNj(!4?rNM#JqInRm9G``)~HCga_?jA7>*os z-!;@9Mn$?!YD2vna?E|#Qhx*$>2~gHEKA+dl3wy%M|~D@7fz`i^&V(RFZ-^iJ{uM3 zPAQ9ePgJD4c;2$q3%LiU)PdX^73m(Hw=DHRg*z>G#=r5*6sbSYLzV`hA`N2SW$6J_ zq+#qYciBco8qPj)hjdi9J9Bp&&0cViMYhRZwo#EDW1HN`8x`){+?zZW73m4KDRU3! zKIA8*zU1+!NKZ-q$P-YJo@Ot&yEiJ*GtxlvBvhnl*&{`oEDgqa(opL2QIQt1cZ#%# z{o>y3s7QtEmnRQJ9UpHzlw@f%$~~9a#W-e_LO_3qau~Er?T`KD$+{! zRF+;x{{DzPRiwl0BX=)HMLNPh%F_3!NY(74Ed79rbd-IRr5};M`IV-Se?mn%&b_J? z>1Xa#tw<-N8TgAd6IFQ@eKceokY|%E$qwXtmkY=)=c(zWs` za$8iST)7Nylh;t`hMb@BI&yd9oRrs-d!QoqmN$^^K}G5#ZzSJ~iqu!$M7|Fdsh_-= z{5Ry>legdic`KEH$Q?xGZRA0yNDs){$%9dmhREgQp{Pg?$~(xzP>~*zcan!AcL9}m zkw>B;JuL6WQSu%tk058PyqEkaDpH1DZ+JR22hj=YbYkBT%`-cK$-?)5Go zz+$-ym&=E!m!Kl8kPnkfQITGgkC0cQBE2qGlUJc4y&)eZm!Tr9mXDFwpdx)PA1CiY zMfzGkLEeXo^mn<2dzbN(RbkD_9GMW=EjGAb%2c2;aEH=`ouC{DaxabthQ zg98*F4pss4MKF**Hnb z!Dp3RoUC-i=alX^Md^XhD?M?l(hFZudgC;u4^CJ5;tZu9zNqxanaV(XNg0H*l)?D2 zG8AVk!*Gr=9P^ctI9C~k17yDaQ|#9k@-|i61JvaJ#Y_KT`H!xw02ORw{6ZQi-1^`*5eSA3s$N;4Y;K zKT{6jZsjn3t{lNVN;Q6=9L2rLG5k_FjupxY{7R|8O64Set(?Mr%4z&YIfMI^v-quY z4i6|7@St)Ds}xz`N>o%lr0Dn$#l*vkjo&FwJfgVqd&Ps*iVuHK0(evj;g3ofk15Ic zlTsItEA{bbr2(E$8sRTW3f3s8_^XnJCzYo7o6-zVDe3sTl7Xj{O#DM>jc1fL_@~kq z&noTkFC`1lDedvR(g80h9r2>l880baP*Sr|R&!8Mb5T{hp{906UG0H}+7nH+7h2p< zn)f5M4?5Jo=v4cmOYM(tbs#3FgV3W6Mz1;)ed;jutHUv%j>Mok3Pb8>OjPqQtd7AX zbu1>U*>#LLS3Ux9zP^Vx+bt*RE)<%ldSe=0>>P);+orS6DY;20oLepM-lrB}3$++C)Dmo|mSU#55?iUOu(eu-*Qjf- zjk*r6Ro7!%bpu|fZp3!#CcIwVj9Kayyg}WH?bU5~qq-eCsO5N*x&u3^JF%0x3p=a3 z@n&@oc2W1@Eoud3tCiSQ-G@2qe!NvZfVpZF-liVHZt7vYT|I)`)oQ#$J&HZlV|b@} z9DAxK@Gi9md#NY!ZhlsZ_h|Jr-lLwuKI&P#S3QS))eCr^dI|ffvda8WRk6RS;{esf zfvS!7t44h2z!s_>|fKC#W6qX|*#> zRJ-6aYBo+%bMRR;7bmOT@HzgkV~qc54}4zjiBr{H_=4ISr>T8#y4n|KsQvIowLi{O z2jWZWAe^NR#+TKhI9nZtbJXFOua3mI>L@HwN8>y-59h06@D+6|E>OqeLUlYYQYYYI zbs`q3lW>VT8JDV4aG5$4i_~fOsyYLU)tR_lorNXpY+Rw{W2stzuc`BKrMduLR~O+b zwGiJ>mtvV(gsatJT%(rYTD26{sVnhKbrr5x%kV9A4Q^1^;oItZ+^BBAchrrzN!^6+ zs+)1Mx&_};x8fFc8@{h@$E|8PexUBaZR$?^P~C;w)!q1!x(CbEz4)P*31jY7JJZC-H0b6z)?` z<2ULV+^?R+Z`E^nK)rwm)k|2V${ORps^TG4$A73M9#(DqPIclD)s5e)9;{Y<_=6h2 zqiP6$RKs{oO~#+px_Dfzk3Xvo@Pyh3e^FDgMoqYu%XllLC(t4w<^+AW$7oA!^bZPz3tqsHkZ4i32!RXb7qE8!!er-4gw2>IpMqx-B zjfq+whP5%6q>aU7Z5-Co#$#P=0@l+eVts8AUZG9K2HF&Cs7=L2+B9se&A=3GCSIw{ z!c=WGHqr7iO)J2wwE5UnTYy(9IZ9QN3~{{r={a#S_Y2MGVyV(HICKV;1gO~9H+IzC$%gbueHagv<^5y>xfTl zopGYp1)tHfagvsU&uY0iS?h++Y29&()&rl{dg4^A7rvnN#%Wp~oUZl78CpMlQR|O0 zwSoAOHV9{FgYji;D9+Y~;T&x^=4&Hyt~Lq_w9zltZl*fw5_;B+lKFJ+i|N_jvr_{aGSOhKh$>Nc5OF)r0v0SZ7+VTRp1V-5rX9lF+F|@$JA!+(YWzYwihH$V_@#CnE3^~%l~#k5+DZIcJB9nS z)A)^c2KQ@c@muX29?&k}LG2P&X|loiuc>%Q)A1jgiH9{Cztfy}M04Z!ng^>jAO4^P z@TeBTAGI(Z(~|Kgtu7wd>f_H^13aNM!e6u$tkF{OS1k=sYEAJstr?!u((!jK15az2 z_=naS&uDG%PpvJU)!N}-S{9zu+T(ex176TN;zg}9Uedatq-Ue7=b)nJqN;a8P4AAn z-UAK2Cz^UMwDjI+>wVCn_eH1P4_$hHbn62#K_7%3eK30Uq3F|xpoYJ#pNUuM zvoKYkjZO4?Ow$YSDt$gS)feE^`XX$m7h-dLDW>a1*g`MH47~(f>ZO>euf$gRDr~Kn z;WhdiY@@HkYxVWmR^Ncv=^L?~z6r0_H)EE*1#i%|VtaiX-l%WK4thD>r0>9v`cCYm z@50XdZoFCFgI)B!c#B?v*?J{*)%RhJz8`PZ4`8ldg}3R4u$z7uZ`Y4tcfA_#(2rsd z{TSY{T%kyFW`OpCG4lmCgZ=ZVt-x7 z0lJ9;bsO*3oj6E$;{&<}2kSl@q6cuO9>NFpFb>m`@gcn~4%h4B2)zN0)EnW$dJ2xx zQ}Gc!4M*!u@lm}Q=IQD9n4W=S^h|tQZ;fO1Hu!|z7RTxB@JT%j$LsC!DZK+u&^zMO zdS{%dcfn`$Y@DR$;In!zPS(5Ob9#52qW8e(^`1CY?}abuy>Xh}2dC?OafaRxU)1~K zOno4}qz}Sb`e1xnABwZ}VK_%0j`{jXoU4z*0(~^j)AMk?J_cXW$KnEg94^$y<05?m zF4iYvp*{(h=#z1&J_VQQQ?W>&hOg=~uvnjo%k^1UqR++^dOnuw1^AjiA6M!N@O6C= zuF?zf4Sgw==|#9&FUB=`39i*kah<*r-_%#(dc6$a(%0YyeI357ug8u027E`~h@13H z_^!SgH|tyQJ$)-~(YN9I`gYu^m*WTe4&0{i#1HjdxLx0kAL)CrT;Gcy>lL^|uf$LE zeYjKKkDuxXaF)=%L+ z{WN}~pTYh5S^QQ%hX?cvcu>EDRl003{_83p(slfYZsK9x#_x0|9?{+Sz3#zk-G@Ku z0X(XQ@JBt2$Mj_UNw15?_4@d;-T+VNjqn#e1#9$F{8dlGlX_G9O>c&$^mP1P&%o1q zCjOzf#xr^w{8Mj>XZ3dYm!5^^^!9jO?|>Kdj(Ab;jFhx(8#$;Lxu_c5P&2xt zZuCII=!vG$3oWBJ+D0FA7=6)c^h1}?AKk`4OfUwa#~6%WV<`HJVdyu8W55`RL1Pq# zjM12ANaxF=pbG z#w<)VW@8g0AJdEiyvmr5O^pS3wXq1B8HL!~Sc>UJ5wKE_$R*EolLjSG06aS8hwvd#E!sMz1o zae!gsK*PrS4JQsV-1vau!NG5gu@wmvC zfQyZZSZGYbCB|f2YD~dp##Agars1o`3@kQg;&NjamKd{fg^`b?MghKN%*U0+0({+A zgsY4~e8X6ZWkwOMHi~hLQG#oYQe0=O#5avqxZWtkw~RHo!B~fH8|!hSu>s#PHsU5@ z6TWL~#?8hSe9zd5Ta0b^zOfy*8s+$bu>-dmJMlwf7j8Fp<449GEI0Pz$3_M2Fe>pA zV;}A`_T#6<0o-L&;b+Dn+-)4j&y6Fv$Ee0HjH9^MIEG&u$FagVfnOOlSZSQZuZ>f< z&p3_W7-w+5aTdQd&fx*$0vZm5~v zQ8#;_VfIAR?1h%u8*Q@>I?TT4H2a~;?2m49ASRfD&|?lpuQ?Qb<}mb|!!clv#Gp9} zL*{5qH1jZQj=>~zEGC=du#Pz%>zWg=o;eZgo0ISgb22tCr(i>KDmF5wVPkU!rkFGF zN^=&bnzONqnU85^0bXU!$EM~2yxLrZ&CEh3_2y>GGPmFj=2mQPZo?bR?byLA$D7O@*wNgH zoy=X>+1!mcn|rW}xfgFSD=^!v#IEK(%rW=lt>yvDHLLJ8^AL735996T5$tYO;~nNv z>|q|mJI&+R(>#H9nKjtUJc)Okr?9tq8t*aBU?1}=-fN!2zUBqI&%A{FOxel!Z>ree z)Nz1m;y}~J`%NbfGTr!q>A}IK4~Lim9BPK}K{JfQ%w&AXtc%0V`Z&UDfFsRD_^_FR zqs&x%#7x7{W>b9BY=(JeIzDD*;21L#A2(a$ShEd2VYbC_W;=Y+%);?zdwk05fD_D) z__Wy>Cz@UG88aIvnK}5ZnTwOnZup$p9jBN*@OiT*PBnYs3ubSeX7<79W?!6P_QMy= z{y5Vdh%cFgaF#h3Up9y0Y;zdSF^6NmITGiZqp-jnjq}VroNtc7SIn`vz#NAQ&GER% zoPdkXiCAb(!X@TpTxw3iW#&{YGN<9I<_s)0XX0{m7M7T^afO+WrDg%XX3ocz<^p`( zT!gF4LVUwqie+XIt~QHtjahbnfw=>>nLF`Aa~EzmcjHIq9xONa;>TtM?l3Fy z6LTN#H234D<^kMgR^eynA>3^q#?Q?oxW}xB5*%uL3g%({5otdBpN4e*572!AnCu*OWqU(GZ;X*R{*%w~AXOvm5N z3_NXS;vZ&fJY%-OKh3sy)@+A=nOS(wY>(&74tT-rh!@Syc**R7l9i3Jm4k|vi>lQP zHLE-7Ru43+o@iRV(6V}?ZS_Hi)fb&sKXh6B(QOUH1Zxm_tikBDhN90JhJI@}2CR`7 zv_@gb8jXoo9)_(km}HH`WNRGOvBqOvYXa7@CSrYS5?*0V#s=0DY-mlzM%FZJY|X$F zYbIW4&B9b`Ha4;HG0iH#tE~Ch)LMX7TZ^!nRfx^4rI>CNVGFAmGprJ9X_aE8wGvxd ztFX0IhSykYu#L42ueH`=TWbSeXKloG)+W5(+KgG&7QDgQitVj!c%!u)J6Pp-leGgo zT060mwF^62yYXgg4|cKk;w@GMW?Plm)!K(S)_%OzI)J%W72akY!fw`Kyxls2-K}c8 z!#avRtYdhmbsT$IC-5$-276g2@owuB_O?#rJ=PiQW1Yo&t#jDdx`6jtm$08DyBYs2 z75iH{4zNrdXxVtb<-|dj8y~PdIN0*x5G#N~tq?wFg>jgbj1O6Laky0wm8mehfi8rINoZHPgxys zg4Ge9wmRcPs|!A3W#c3(2cNZaakAA7pR>B-6sre5Z}r5fRxf

W$N^J~-X#i!-c# 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 mK!UbO{yoHse~ + + + $(MSBuildProjectDirectory)\..\ + + + false + + + false + + + true + + + false + + + + + + + + + + + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) + $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) + + + + + $(SolutionDir).nuget + packages.config + + + + + $(NuGetToolsPath)\NuGet.exe + @(PackageSource) + + "$(NuGetExePath)" + mono --runtime=v4.0.30319 $(NuGetExePath) + + $(TargetDir.Trim('\\')) + + -RequireConsent + -NonInteractive + + "$(SolutionDir) " + "$(SolutionDir)" + + + $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) + $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols + + + + RestorePackages; + $(BuildDependsOn); + + + + + $(BuildDependsOn); + BuildPackage; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index 6c56e90..e2ba71d 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -12,6 +12,8 @@ Raspberry.IO.Components v4.0 512 + ..\ + true true @@ -81,6 +83,7 @@ + + \ No newline at end of file From 516fd49793267cccf9c134ca2bc6ac2574a660dd Mon Sep 17 00:00:00 2001 From: keneo Date: Fri, 27 Sep 2013 22:49:34 +0200 Subject: [PATCH 107/227] actually watch pin --- Test.Gpio.WatchPin/Program.cs | 49 ++++++++++++++++++-- Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj | 6 +++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Test.Gpio.WatchPin/Program.cs b/Test.Gpio.WatchPin/Program.cs index 7e1ad43..7c86aaa 100644 --- a/Test.Gpio.WatchPin/Program.cs +++ b/Test.Gpio.WatchPin/Program.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Raspberry.IO.GeneralPurpose; namespace Test.Gpio.WatchPin { @@ -19,18 +20,56 @@ static void Main(string[] args) return; } - var pin = args[0]; + var pinname = args[0]; - Console.WriteLine("\tPin: {0}", pin); + ConnectorPin userPin; + if (!Enum.TryParse(pinname, true, out userPin)) + { + Console.WriteLine("Could not find pin: "+pinname); + PrintUsage(); + return; + } + + Console.WriteLine("\tWatching Pin: {0}", userPin); Console.WriteLine(); - Console.WriteLine("//todo actually watch the pin"); //todo + var procPin = userPin.ToProcessor(); + + IGpioConnectionDriver driver = GpioConnectionSettings.DefaultDriver; + + try + { + driver.Allocate(procPin, PinDirection.Input); + + bool val; + + while (true) + { + val = driver.Read(procPin); + + Console.WriteLine(DateTime.Now + ": " + val); + + driver.Wait(procPin, waitForUp: !val, timeout: 60000); + } + + //driver.Allocate(procPin, PinDirection.Output); + //driver.Write(procPin, false); + + //driver.Allocate(procPin, PinDirection.Input); + } finally + { + //driver.Release(procPin); //not sure if its a good idea + } } private static void PrintUsage() { - Console.WriteLine("Usage: Test.Gpio.WatchPin [pin]"); //todo watch multiple pins - Console.WriteLine("//todo watch multiple pins"); + Console.WriteLine("Usage: Test.Gpio.WatchPin [pin]"); //todo allow watch multiple pins + Console.WriteLine("//todo allow watch multiple pins"); + Console.WriteLine("Available pins:"); + Enum.GetNames(typeof(ConnectorPin)).ToList().ForEach(Console.WriteLine); + Console.WriteLine("//todo allow to specify pin in diffrent ways, ie, by name, by wiringPi, etc"); //todo allow to specify pin in diffrent ways, ie, by name, by wiringPi, etc + Console.WriteLine("I.e.: sudo mono Test.Gpio.WatchPin.exe P1Pin23"); Console.WriteLine(); } } diff --git a/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj b/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj index 79d413a..300cf65 100644 --- a/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj +++ b/Test.Gpio.WatchPin/Test.Gpio.WatchPin.csproj @@ -47,6 +47,12 @@ + + + {281C71ED-C36D-408E-8BAA-75C381DC17E7} + Raspberry.IO.GeneralPurpose + + + \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index f29119b..75b5c96 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -7,6 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject Icon.png = Icon.png Raspberry.IO.GeneralPurpose.nuspec = Raspberry.IO.GeneralPurpose.nuspec + Raspberry.IO.nuspec = Raspberry.IO.nuspec README.md = README.md SharedAssemblyInfo.cs = SharedAssemblyInfo.cs EndProjectSection @@ -40,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{ACE64F17-87E5-43E7-97A0-BDDE19059C61}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -90,6 +93,10 @@ Global {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU {60B59A9C-69F6-4CEA-8385-C8542AE2BB98}.Release|Any CPU.Build.0 = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACE64F17-87E5-43E7-97A0-BDDE19059C61}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Test.Gpio.HCSR04/Program.cs b/Test.Gpio.HCSR04/Program.cs index 239156b..d2c44ca 100644 --- a/Test.Gpio.HCSR04/Program.cs +++ b/Test.Gpio.HCSR04/Program.cs @@ -29,7 +29,8 @@ private static void Main(string[] args) var interval = GetInterval(args); - using (var connection = new HcSr04Connection(triggerPin.ToProcessor(), echoPin.ToProcessor())) + var driver = GpioConnectionSettings.DefaultDriver; + using (var connection = new HcSr04Connection(driver.Out(triggerPin), driver.In(echoPin))) { while (!Console.KeyAvailable) { diff --git a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 8aba60c..c519086 100644 --- a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -77,6 +77,10 @@ {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} + Raspberry.IO + diff --git a/Test.Gpio.HD44780/Hd44780Configuration.cs b/Test.Gpio.HD44780/Hd44780Configuration.cs index abc1795..f6509de 100644 --- a/Test.Gpio.HD44780/Hd44780Configuration.cs +++ b/Test.Gpio.HD44780/Hd44780Configuration.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Raspberry.IO.Components; +using Raspberry.IO; namespace Test.Gpio.HD44780 { @@ -19,8 +19,8 @@ public void Dispose() driver.Dispose(); } - public IOutputPin RegisterSelect; - public IOutputPin Clock; - public IEnumerable Data; + public IOutputBinaryPin RegisterSelect; + public IOutputBinaryPin Clock; + public IEnumerable Data; } } \ No newline at end of file diff --git a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index 7355376..4236673 100644 --- a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -83,6 +83,10 @@ {63B8403E-BC56-43F9-A045-F61ECC3871F3} Raspberry.IO.InterIntegratedCircuit + + {ACE64F17-87E5-43E7-97A0-BDDE19059C61} + Raspberry.IO + + \ No newline at end of file From 625d43cb10cb2fe7f47e5a2be1941fc04f209361 Mon Sep 17 00:00:00 2001 From: neutmute Date: Sun, 24 Nov 2013 21:55:37 +1100 Subject: [PATCH 121/227] pca9685 - support arguments --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 89 +- .../Raspberry.IO.Components.csproj | 2 +- RaspberrySharp.IO.sln | 7 + Test.Gpio.Pca9685/PCA9685Options.cs | 66 + Test.Gpio.Pca9685/Program.cs | 73 +- Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj | 9 +- Test.Utils/Logger.cs | 15 + Test.Utils/Options.cs | 1175 +++++++++++++++++ Test.Utils/Properties/AssemblyInfo.cs | 36 + Test.Utils/Test.Utils.csproj | 59 + 10 files changed, 1430 insertions(+), 101 deletions(-) create mode 100644 Test.Gpio.Pca9685/PCA9685Options.cs create mode 100644 Test.Utils/Logger.cs create mode 100644 Test.Utils/Options.cs create mode 100644 Test.Utils/Properties/AssemblyInfo.cs create mode 100644 Test.Utils/Test.Utils.csproj diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index 4a0e7af..ee2eafc 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -8,67 +8,14 @@ namespace Raspberry.IO.Components.Expanders.Pca9685 { - /* - * - i2c = None - - # Registers/etc. - __SUBADR1 = 0x02 - __SUBADR2 = 0x03 - __SUBADR3 = 0x04 - __MODE1 = 0x00 - __PRESCALE = 0xFE - __LED0_ON_L = 0x06 - __LED0_ON_H = 0x07 - __LED0_OFF_L = 0x08 - __LED0_OFF_H = 0x09 - __ALLLED_ON_L = 0xFA - __ALLLED_ON_H = 0xFB - __ALLLED_OFF_L = 0xFC - __ALLLED_OFF_H = 0xFD - - def __init__(self, address=0x40, debug=False): - self.i2c = Adafruit_I2C(address) - self.address = address - self.debug = debug - if (self.debug): - print "Reseting PCA9685" - self.i2c.write8(self.__MODE1, 0x00) - - def setPWMFreq(self, freq): - "Sets the PWM frequency" - prescaleval = 25000000.0 # 25MHz - prescaleval /= 4096.0 # 12-bit - prescaleval /= float(freq) - prescaleval -= 1.0 - if (self.debug): - print "Setting PWM frequency to %d Hz" % freq - print "Estimated pre-scale: %d" % prescaleval - prescale = math.floor(prescaleval + 0.5) - if (self.debug): - print "Final pre-scale: %d" % prescale - - oldmode = self.i2c.readU8(self.__MODE1); - newmode = (oldmode & 0x7F) | 0x10 # sleep - self.i2c.write8(self.__MODE1, newmode) # go to sleep - self.i2c.write8(self.__PRESCALE, int(math.floor(prescale))) - self.i2c.write8(self.__MODE1, oldmode) - time.sleep(0.005) - self.i2c.write8(self.__MODE1, oldmode | 0x80) - - def setPWM(self, channel, on, off): - "Sets a single PWM channel" - self.i2c.write8(self.__LED0_ON_L+4*channel, on & 0xFF) - self.i2c.write8(self.__LED0_ON_H+4*channel, on >> 8) - self.i2c.write8(self.__LED0_OFF_L+4*channel, off & 0xFF) - self.i2c.write8(self.__LED0_OFF_H+4*channel, off >> 8) - * - * */ - ///

+ /// Driver for PCA9685 + /// 16-channel, 12-bit PWM Fm+ I2C-bus LED controller + + /// Ported from /// https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py /// - public class Pca9685I2cConnection + public class PCA9685I2cConnection { private readonly I2cDeviceConnection connection; @@ -92,10 +39,10 @@ private enum Register private void Log(string format, params object[] args) { - Trace.WriteLine(string.Format(format, args)); + Console.WriteLine(format, args); } - public Pca9685I2cConnection(I2cDeviceConnection connection) + public PCA9685I2cConnection(I2cDeviceConnection connection) { this.connection = connection; @@ -103,19 +50,21 @@ public Pca9685I2cConnection(I2cDeviceConnection connection) WriteRegister(Register.MODE1, 0x00); } - public void SetPWMFreq(int freq) + /// + /// Datasheet: 7.3.5 PWM frequency PRE_SCALE + /// + public void SetPWMUpdateRate(int frequencyHz) { - Log("Sets the PWM frequency"); - decimal prescaleval = 25000000.0m; // 25MHz - prescaleval /= 4096.0m;// 12-bit - prescaleval /= freq; + var preScale = 25000000.0m; // 25MHz + preScale /= 4096m;// 12-bit + preScale /= frequencyHz; - prescaleval -= 1.0m; + preScale -= 1.0m; - Log("Setting PWM frequency to {0} Hz", freq); - Log("Estimated pre-scale: {0}", prescaleval); + Log("Setting PWM frequency to {0} Hz", frequencyHz); + Log("Estimated pre-scale: {0}", preScale); - var prescale = Math.Floor(prescaleval + 0.5m); + var prescale = Math.Floor(preScale + 0.5m); Log("Final pre-scale: {0}", prescale); @@ -161,7 +110,5 @@ private byte ReadRegister(Register register) var value = connection.ReadByte(); return value; } - - } } diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index bcd35f7..f9eddb8 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -59,7 +59,7 @@ - + diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 6ac2982..544dd14 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -44,6 +44,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Test. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Utils", "Test.Utils\Test.Utils.csproj", "{B665A155-B08A-40EE-9970-50BCC3777CA0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -98,6 +100,10 @@ Global {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU + {B665A155-B08A-40EE-9970-50BCC3777CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B665A155-B08A-40EE-9970-50BCC3777CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B665A155-B08A-40EE-9970-50BCC3777CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B665A155-B08A-40EE-9970-50BCC3777CA0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -111,5 +117,6 @@ Global {266EDDBC-F741-48F8-83B7-2CD37BACE62B} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {60B59A9C-69F6-4CEA-8385-C8542AE2BB98} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {57A001A7-FCF7-45EC-8E25-A390EF044E94} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} + {B665A155-B08A-40EE-9970-50BCC3777CA0} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} EndGlobalSection EndGlobal diff --git a/Test.Gpio.Pca9685/PCA9685Options.cs b/Test.Gpio.Pca9685/PCA9685Options.cs new file mode 100644 index 0000000..689b58a --- /dev/null +++ b/Test.Gpio.Pca9685/PCA9685Options.cs @@ -0,0 +1,66 @@ +using System; +using NDesk.Options; +using Raspberry.IO.GeneralPurpose; + +namespace Test.Gpio.PCA9685 +{ + public class PCA9685Options + { + public int Channel { get; set; } + + public int PwmFrequency { get; set; } + + public int DeviceAddress { get; set; } + + public ConnectorPin SdaPin = ConnectorPin.P1Pin03; + + public ConnectorPin SclPin = ConnectorPin.P1Pin05; + + public int PwmOn { get; set; } + + public int PwmOff { get; set; } + + public bool ShowHelp { get; set; } + + public PCA9685Options(string[] args) + { + PwmFrequency = 60; + SdaPin = ConnectorPin.P1Pin03; + SclPin = ConnectorPin.P1Pin05; + DeviceAddress = 0x40; + PwmOn = 150; + PwmOff = 600; + + var p = new OptionSet { + { "c|Channel=", v => Channel = int.Parse(v) }, + { "f|PwmFrequency=", v => PwmFrequency = int.Parse(v) }, + { "b|PwmOn=", v => PwmOn = int.Parse(v) }, + { "e|PwmOff=", v => PwmOff = int.Parse(v) }, + { "h|?:", v => ShowHelp = true } + }; + p.Parse(args); + + + if (ShowHelp) + { + Console.WriteLine("Options:"); + p.WriteOptionDescriptions(Console.Out); + } + } + + public override string ToString() + { + return string.Format( + "Channel={1}{0}SdaPin={3}{0}SclPin={4}{0}DeviceAddress=0x{5:X}{0}PwmFrequency={2}{0}PwmOn={6}{0}PwmOff={7}{0}" + , Environment.NewLine + , Channel + , PwmFrequency + , SdaPin + , SclPin + , DeviceAddress + , PwmOn + , PwmOff); + } + + } +} \ No newline at end of file diff --git a/Test.Gpio.Pca9685/Program.cs b/Test.Gpio.Pca9685/Program.cs index c193409..81d88c1 100644 --- a/Test.Gpio.Pca9685/Program.cs +++ b/Test.Gpio.Pca9685/Program.cs @@ -3,52 +3,71 @@ using Raspberry.IO.Components.Expanders.Pca9685; using Raspberry.IO.GeneralPurpose; using Raspberry.IO.InterIntegratedCircuit; +using Test.Utils; -namespace Test.Gpio.Pca9685 +namespace Test.Gpio.PCA9685 { class Program { - static void Main() - { - const ConnectorPin sdaPin = ConnectorPin.P1Pin03; - const ConnectorPin sclPin = ConnectorPin.P1Pin05; - Console.WriteLine("Pca9685 Sample"); - Console.WriteLine(); - Console.WriteLine("\tSDA: {0}", sdaPin); - Console.WriteLine("\tSCL: {0}", sclPin); - Console.WriteLine(); + private static readonly Logger Log = new Logger(); + + static void Main(string[] args) + { + var options = new PCA9685Options(args); - using (var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor())) + if (options.ShowHelp) { - var device = new Pca9685I2cConnection(driver.Connect(0x40)); + return; + } + Log.Info("-=Pca9685 Sample=-"); + Log.Info("Running {0}", Environment.OSVersion); + Log.Info("Options:"); + Log.Info(options.ToString()); - int servoMin = 150; // Min pulse length out of 4096 - int servoMax = 600; // Max pulse length out of 4096 + int pulse = CalculatePulse(options.PwmFrequency, 1000); + Log.Info("Pulse={0}", pulse); -//def setServoPulse(channel, pulse): -// pulseLength = 1000000 # 1,000,000 us per second -// pulseLength /= 60 # 60 Hz -// print "%d us per period" % pulseLength -// pulseLength /= 4096 # 12 bits of resolution -// print "%d us per bit" % pulseLength -// pulse *= 1000 -// pulse /= pulseLength -// pwm.setPWM(channel, 0, pulse) + if (Environment.OSVersion.ToString().Contains("Windows")) + { + Log.Info("Windows. Exiting"); + return; + } + + Log.Info("Connecting..."); + + using (var driver = new I2cDriver(options.SdaPin.ToProcessor(), options.SclPin.ToProcessor())) + { + Log.Info("Creating device..."); + var device = new PCA9685I2cConnection(driver.Connect(options.DeviceAddress)); - device.SetPWMFreq(60); // # Set frequency to 60 Hz + Log.Info("Setting frequency..."); + device.SetPWMUpdateRate(options.PwmFrequency); // # Set frequency to 60 Hz while (!Console.KeyAvailable) { - //# Change speed of continuous servo on channel O - device.SetPWM(0, 0, servoMin); + Log.Info("Set channel={0} to {1}", options.Channel, options.PwmOn); + device.SetPWM(options.Channel, 0, options.PwmOn); Thread.Sleep(1000); - device.SetPWM(0, 0, servoMax); + Log.Info("Set channel={0} to {1}", options.Channel, options.PwmOff); + device.SetPWM(options.Channel, 0, options.PwmOff); Thread.Sleep(1000); } } } + + private static int CalculatePulse(int frequency, int pulse) + { + int pulseLengthMicroSeconds = 1000000; //# 1,000,000 us per second + pulseLengthMicroSeconds /= frequency; // # 60 Hz + Log.Info("{0} uSecs per period", pulseLengthMicroSeconds); + pulseLengthMicroSeconds /= 4096; // # 12 bits of resolution + Log.Info("{0} uSecs per bit", pulseLengthMicroSeconds); + pulse *= 1000; + pulse /= pulseLengthMicroSeconds; + return pulse; + } } } diff --git a/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index 08b2143..0b743dd 100644 --- a/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -7,8 +7,8 @@ {57A001A7-FCF7-45EC-8E25-A390EF044E94} Exe Properties - Test.Gpio.Pca9685 - Test.Gpio.Pca9685 + Test.Gpio.PCA9685 + Test.Gpio.PCA9685 v4.0 512 @@ -39,6 +39,7 @@ Properties\SharedAssemblyInfo.cs + @@ -55,6 +56,10 @@ {63b8403e-bc56-43f9-a045-f61ecc3871f3} Raspberry.IO.InterIntegratedCircuit + + {b665a155-b08a-40ee-9970-50bcc3777ca0} + Test.Utils + + \ No newline at end of file From 06404fbcd4bfb114382302aa1ebc639ec00187b9 Mon Sep 17 00:00:00 2001 From: neutmute Date: Wed, 27 Nov 2013 21:55:21 +1100 Subject: [PATCH 122/227] enum encourages more self documenting code --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 40 +++++++++++++++---- Test.Gpio.Pca9685/PCA9685Options.cs | 5 ++- Test.Gpio.Pca9685/Program.cs | 6 +-- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index ee2eafc..7868a55 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -8,6 +8,31 @@ namespace Raspberry.IO.Components.Expanders.Pca9685 { + + public enum PwmChannel + { + C0 = 0, + C1 = 1, + C2 = 2, + C3 = 3, + C4 = 4, + C5 = 5, + C6 = 6, + C7 = 7, + C8 = 8, + C9 = 9, + C10 = 10, + C11 = 11, + } + + public interface IPwmDevice + { + /// + /// Sets a single PWM channel + /// + void SetPwm(PwmChannel channel, int on, int off); + } + /// /// Driver for PCA9685 /// 16-channel, 12-bit PWM Fm+ I2C-bus LED controller @@ -15,10 +40,11 @@ namespace Raspberry.IO.Components.Expanders.Pca9685 /// Ported from /// https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py /// - public class PCA9685I2cConnection + public class PCA9685I2cConnection : IPwmDevice { private readonly I2cDeviceConnection connection; + private enum Register { SUBADR1 = 0x02, @@ -53,7 +79,7 @@ public PCA9685I2cConnection(I2cDeviceConnection connection) /// /// Datasheet: 7.3.5 PWM frequency PRE_SCALE /// - public void SetPWMUpdateRate(int frequencyHz) + public void SetPwmUpdateRate(int frequencyHz) { var preScale = 25000000.0m; // 25MHz preScale /= 4096m;// 12-bit @@ -85,12 +111,12 @@ public void SetPWMUpdateRate(int frequencyHz) /// /// Sets a single PWM channel /// - public void SetPWM(int channel, int on, int off) + public void SetPwm(PwmChannel channel, int on, int off) { - WriteRegister(Register.LED0_ON_L + 4*channel, on & 0xFF); - WriteRegister(Register.LED0_ON_H + 4*channel, on >> 8); - WriteRegister(Register.LED0_OFF_L + 4*channel, off & 0xFF); - WriteRegister(Register.LED0_OFF_H + 4*channel, off >> 8); + WriteRegister(Register.LED0_ON_L + 4*(int)channel, on & 0xFF); + WriteRegister(Register.LED0_ON_H + 4 * (int)channel, on >> 8); + WriteRegister(Register.LED0_OFF_L + 4 * (int)channel, off & 0xFF); + WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, off >> 8); } private void WriteRegister(Register register, byte data) diff --git a/Test.Gpio.Pca9685/PCA9685Options.cs b/Test.Gpio.Pca9685/PCA9685Options.cs index 689b58a..84b11e7 100644 --- a/Test.Gpio.Pca9685/PCA9685Options.cs +++ b/Test.Gpio.Pca9685/PCA9685Options.cs @@ -1,12 +1,13 @@ using System; using NDesk.Options; +using Raspberry.IO.Components.Expanders.Pca9685; using Raspberry.IO.GeneralPurpose; namespace Test.Gpio.PCA9685 { public class PCA9685Options { - public int Channel { get; set; } + public PwmChannel Channel { get; set; } public int PwmFrequency { get; set; } @@ -32,7 +33,7 @@ public PCA9685Options(string[] args) PwmOff = 600; var p = new OptionSet { - { "c|Channel=", v => Channel = int.Parse(v) }, + { "c|Channel=", v => Channel =(PwmChannel) Enum.Parse(typeof(PwmChannel), v)}, { "f|PwmFrequency=", v => PwmFrequency = int.Parse(v) }, { "b|PwmOn=", v => PwmOn = int.Parse(v) }, { "e|PwmOff=", v => PwmOff = int.Parse(v) }, diff --git a/Test.Gpio.Pca9685/Program.cs b/Test.Gpio.Pca9685/Program.cs index 81d88c1..2d5469f 100644 --- a/Test.Gpio.Pca9685/Program.cs +++ b/Test.Gpio.Pca9685/Program.cs @@ -44,14 +44,14 @@ static void Main(string[] args) var device = new PCA9685I2cConnection(driver.Connect(options.DeviceAddress)); Log.Info("Setting frequency..."); - device.SetPWMUpdateRate(options.PwmFrequency); // # Set frequency to 60 Hz + device.SetPwmUpdateRate(options.PwmFrequency); // # Set frequency to 60 Hz while (!Console.KeyAvailable) { Log.Info("Set channel={0} to {1}", options.Channel, options.PwmOn); - device.SetPWM(options.Channel, 0, options.PwmOn); + device.SetPwm(options.Channel, 0, options.PwmOn); Thread.Sleep(1000); Log.Info("Set channel={0} to {1}", options.Channel, options.PwmOff); - device.SetPWM(options.Channel, 0, options.PwmOff); + device.SetPwm(options.Channel, 0, options.PwmOff); Thread.Sleep(1000); } From 722df284978a823d02d5e6669d49882cb320f9ac Mon Sep 17 00:00:00 2001 From: neutmute Date: Wed, 27 Nov 2013 22:43:06 +1100 Subject: [PATCH 123/227] Full on/off support --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index 7868a55..f66aacb 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -31,6 +31,10 @@ public interface IPwmDevice /// Sets a single PWM channel ///
void SetPwm(PwmChannel channel, int on, int off); + + void SetFullOn(PwmChannel channel); + + void SetFullOff(PwmChannel channel); } /// @@ -47,19 +51,19 @@ public class PCA9685I2cConnection : IPwmDevice private enum Register { - SUBADR1 = 0x02, - SUBADR2 = 0x03, - SUBADR3 = 0x04, - MODE1 = 0x00, - PRESCALE = 0xFE, - LED0_ON_L = 0x06, - LED0_ON_H = 0x07, - LED0_OFF_L = 0x08, - LED0_OFF_H = 0x09, - ALLLED_ON_L = 0xFA, - ALLLED_ON_H = 0xFB, - ALLLED_OFF_L = 0xFC, - ALLLED_OFF_H = 0xFD, + SUBADR1 = 0x02, + SUBADR2 = 0x03, + SUBADR3 = 0x04, + MODE1 = 0x00, + PRESCALE = 0xFE, + LED0_ON_L = 0x06, + LED0_ON_H = 0x07, + LED0_OFF_L = 0x08, + LED0_OFF_H = 0x09, + ALLLED_ON_L = 0xFA, + ALLLED_ON_H = 0xFB, + ALLLED_OFF_L = 0xFC, + ALLLED_OFF_H = 0xFD, } @@ -119,6 +123,16 @@ public void SetPwm(PwmChannel channel, int on, int off) WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, off >> 8); } + public void SetFullOn(PwmChannel channel) + { + WriteRegister(Register.LED0_ON_H + 4 * (int)channel, 0x10); + } + + public void SetFullOff(PwmChannel channel) + { + WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, 0x00); + } + private void WriteRegister(Register register, byte data) { Log("{0}=>{1}", register, data); From 1abc6470f5d3df6b0382e6eafb498f236fcb1e57 Mon Sep 17 00:00:00 2001 From: neutmute Date: Wed, 27 Nov 2013 23:11:17 +1100 Subject: [PATCH 124/227] better syntax --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index f66aacb..87c00a2 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -32,9 +32,7 @@ public interface IPwmDevice /// void SetPwm(PwmChannel channel, int on, int off); - void SetFullOn(PwmChannel channel); - - void SetFullOff(PwmChannel channel); + void SetFull(PwmChannel channel, bool fullOn); } /// @@ -123,12 +121,24 @@ public void SetPwm(PwmChannel channel, int on, int off) WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, off >> 8); } - public void SetFullOn(PwmChannel channel) + public void SetFull(PwmChannel channel, bool fullOn) + { + if (fullOn) + { + SetFullOn(channel); + } + else + { + SetFullOff(channel); + } + } + + private void SetFullOn(PwmChannel channel) { WriteRegister(Register.LED0_ON_H + 4 * (int)channel, 0x10); } - public void SetFullOff(PwmChannel channel) + private void SetFullOff(PwmChannel channel) { WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, 0x00); } From 6c9d6f3a384dbf55ee6958a7273958c060c5246b Mon Sep 17 00:00:00 2001 From: neutmute Date: Wed, 27 Nov 2013 23:39:22 +1100 Subject: [PATCH 125/227] reduce log chatter --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index 87c00a2..7f32280 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -145,7 +145,7 @@ private void SetFullOff(PwmChannel channel) private void WriteRegister(Register register, byte data) { - Log("{0}=>{1}", register, data); + // Log("{0}=>{1}", register, data); connection.Write(new[] { (byte)register , data }); } From 3a322e6f77b992c2ef68e1d7301a1c34763286ca Mon Sep 17 00:00:00 2001 From: neutmute Date: Thu, 28 Nov 2013 22:27:57 +1100 Subject: [PATCH 126/227] full on off fix --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index 7f32280..c0f12e9 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -136,11 +136,13 @@ public void SetFull(PwmChannel channel, bool fullOn) private void SetFullOn(PwmChannel channel) { WriteRegister(Register.LED0_ON_H + 4 * (int)channel, 0x10); + WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, 0x00); } private void SetFullOff(PwmChannel channel) { - WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, 0x00); + WriteRegister(Register.LED0_ON_H + 4 * (int)channel, 0x00); + WriteRegister(Register.LED0_OFF_H + 4 * (int)channel, 0x10); } private void WriteRegister(Register register, byte data) From c779f1fbdde6bceafda9ec685fea764fac606d9d Mon Sep 17 00:00:00 2001 From: neutmute Date: Tue, 3 Dec 2013 22:07:40 +1100 Subject: [PATCH 127/227] more easily support IoC --- .../Expanders/Pca9685/Pca9685I2cConnection.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs index c0f12e9..570b4ee 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs @@ -27,6 +27,8 @@ public enum PwmChannel public interface IPwmDevice { + void SetPwmUpdateRate(int frequencyHz); + /// /// Sets a single PWM channel /// @@ -70,7 +72,15 @@ private void Log(string format, params object[] args) Console.WriteLine(format, args); } - public PCA9685I2cConnection(I2cDeviceConnection connection) + #region Ctor + + public static IPwmDevice Create(I2cDeviceConnection connection) + { + var pwmDevice = new PCA9685I2cConnection(connection); + return pwmDevice; + } + + private PCA9685I2cConnection(I2cDeviceConnection connection) { this.connection = connection; @@ -78,6 +88,9 @@ public PCA9685I2cConnection(I2cDeviceConnection connection) WriteRegister(Register.MODE1, 0x00); } + #endregion + + /// /// Datasheet: 7.3.5 PWM frequency PRE_SCALE /// From 5ae18000adacf91f3587c18239ed3822368bc7a9 Mon Sep 17 00:00:00 2001 From: neutmute Date: Wed, 4 Dec 2013 23:40:27 +1100 Subject: [PATCH 128/227] fix compile --- Test.Gpio.Pca9685/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test.Gpio.Pca9685/Program.cs b/Test.Gpio.Pca9685/Program.cs index 2d5469f..578a6bd 100644 --- a/Test.Gpio.Pca9685/Program.cs +++ b/Test.Gpio.Pca9685/Program.cs @@ -41,7 +41,7 @@ static void Main(string[] args) using (var driver = new I2cDriver(options.SdaPin.ToProcessor(), options.SclPin.ToProcessor())) { Log.Info("Creating device..."); - var device = new PCA9685I2cConnection(driver.Connect(options.DeviceAddress)); + var device = PCA9685I2cConnection.Create(driver.Connect(options.DeviceAddress)); Log.Info("Setting frequency..."); device.SetPwmUpdateRate(options.PwmFrequency); // # Set frequency to 60 Hz From 64a961e2b1b7029a7a9506de8c3131a0d61952d7 Mon Sep 17 00:00:00 2001 From: neutmute Date: Mon, 9 Dec 2013 22:01:58 +1100 Subject: [PATCH 129/227] fix namespace --- .../Controllers/Pca9685/IPwmDevice.cs | 20 +++++++ .../Pca9685/Pca9685Connection.cs} | 60 ++++--------------- .../Controllers/Pca9685/PwmChannel.cs | 21 +++++++ .../Raspberry.IO.Components.csproj | 7 ++- Test.Gpio.Pca9685/PCA9685Options.cs | 2 +- Test.Gpio.Pca9685/Program.cs | 4 +- 6 files changed, 61 insertions(+), 53 deletions(-) create mode 100644 Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs rename Raspberry.IO.Components/{Expanders/Pca9685/Pca9685I2cConnection.cs => Controllers/Pca9685/Pca9685Connection.cs} (75%) create mode 100644 Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs diff --git a/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs new file mode 100644 index 0000000..dfeff5d --- /dev/null +++ b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs @@ -0,0 +1,20 @@ +namespace Raspberry.IO.Components.Controllers.Pca9685 +{ + /// + /// Make it easier to IoC + /// + public interface IPwmDevice + { + void SetPwmUpdateRate(int frequencyHz); + + /// + /// Sets a single PWM channel with on / off values to control the duty cycle + /// + void SetPwm(PwmChannel channel, int on, int off); + + /// + /// Set a channel to fully on or off + /// + void SetFull(PwmChannel channel, bool fullOn); + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs b/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs similarity index 75% rename from Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs rename to Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs index 570b4ee..85d69fd 100644 --- a/Raspberry.IO.Components/Expanders/Pca9685/Pca9685I2cConnection.cs +++ b/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs @@ -1,53 +1,17 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; using Raspberry.IO.InterIntegratedCircuit; - -namespace Raspberry.IO.Components.Expanders.Pca9685 +namespace Raspberry.IO.Components.Controllers.Pca9685 { - - public enum PwmChannel - { - C0 = 0, - C1 = 1, - C2 = 2, - C3 = 3, - C4 = 4, - C5 = 5, - C6 = 6, - C7 = 7, - C8 = 8, - C9 = 9, - C10 = 10, - C11 = 11, - } - - public interface IPwmDevice - { - void SetPwmUpdateRate(int frequencyHz); - - /// - /// Sets a single PWM channel - /// - void SetPwm(PwmChannel channel, int on, int off); - - void SetFull(PwmChannel channel, bool fullOn); - } - /// - /// Driver for PCA9685 - /// 16-channel, 12-bit PWM Fm+ I2C-bus LED controller - + /// Driver for Adafruit 16-channel PWM/Servo Shield which uses the + /// NXP PCA9685 16-channel, 12-bit PWM Fm+ I2C-bus LED controller /// Ported from /// https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py /// - public class PCA9685I2cConnection : IPwmDevice + public class Pca9685Connection : IPwmDevice { - private readonly I2cDeviceConnection connection; - + private readonly I2cDeviceConnection _connection; private enum Register { @@ -64,7 +28,6 @@ private enum Register ALLLED_ON_H = 0xFB, ALLLED_OFF_L = 0xFC, ALLLED_OFF_H = 0xFD, - } private void Log(string format, params object[] args) @@ -76,14 +39,13 @@ private void Log(string format, params object[] args) public static IPwmDevice Create(I2cDeviceConnection connection) { - var pwmDevice = new PCA9685I2cConnection(connection); + var pwmDevice = new Pca9685Connection(connection); return pwmDevice; } - private PCA9685I2cConnection(I2cDeviceConnection connection) + private Pca9685Connection(I2cDeviceConnection connection) { - this.connection = connection; - + _connection = connection; Log("Reseting PCA9685"); WriteRegister(Register.MODE1, 0x00); } @@ -161,7 +123,7 @@ private void SetFullOff(PwmChannel channel) private void WriteRegister(Register register, byte data) { // Log("{0}=>{1}", register, data); - connection.Write(new[] { (byte)register , data }); + _connection.Write(new[] { (byte)register , data }); } private void WriteRegister(Register register, int data) @@ -171,8 +133,8 @@ private void WriteRegister(Register register, int data) private byte ReadRegister(Register register) { - connection.Write((byte)register); - var value = connection.ReadByte(); + _connection.Write((byte)register); + var value = _connection.ReadByte(); return value; } } diff --git a/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs b/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs new file mode 100644 index 0000000..696d332 --- /dev/null +++ b/Raspberry.IO.Components/Controllers/Pca9685/PwmChannel.cs @@ -0,0 +1,21 @@ +namespace Raspberry.IO.Components.Controllers.Pca9685 +{ + /// + /// Denotes available PWM channels + /// + public enum PwmChannel + { + C0 = 0, + C1 = 1, + C2 = 2, + C3 = 3, + C4 = 4, + C5 = 5, + C6 = 6, + C7 = 7, + C8 = 8, + C9 = 9, + C10 = 10, + C11 = 11, + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index f9eddb8..fb83b16 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -45,6 +45,8 @@ Properties\SharedAssemblyInfo.cs + + @@ -59,7 +61,7 @@ - + @@ -89,6 +91,9 @@ + + + - \ No newline at end of file From e10d70ed90a9c81dd7528946daffb4f61232df37 Mon Sep 17 00:00:00 2001 From: neutmute Date: Tue, 10 Dec 2013 22:09:35 +1100 Subject: [PATCH 133/227] throw exceptions when nlog misconfigured --- Test.Gpio.Pca9685/Program.cs | 11 ++++++----- Test.Gpio.Pca9685/app.config | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Test.Gpio.Pca9685/Program.cs b/Test.Gpio.Pca9685/Program.cs index cdb3645..60c41dd 100644 --- a/Test.Gpio.Pca9685/Program.cs +++ b/Test.Gpio.Pca9685/Program.cs @@ -30,7 +30,7 @@ static void Main(string[] args) Log.Info(m => m("Running {0}", Environment.OSVersion)); Log.Info("Options:" + Environment.NewLine + options); - int pulse = CalculatePulse(options.PwmFrequency, 1000); + int pulse = CalculatePulse(options.PwmFrequency, 50); Log.Info(m => m("Pulse={0}", pulse)); if (Environment.OSVersion.Platform != PlatformID.Unix) @@ -63,14 +63,15 @@ static void Main(string[] args) /// /// Ported but wasn't used in original? Ported from https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_PWM_Servo_Driver/Servo_Example.py + /// Not entirely sure what the result is meant to mean. /// private static int CalculatePulse(int frequency, int pulse) { - int pulseLengthMicroSeconds = 1000000; //# 1,000,000 us per second - pulseLengthMicroSeconds /= frequency; // # 60 Hz + int microSeconds = 1000000; //# 1,000,000 us per second + int pulseLengthMicroSeconds = microSeconds / frequency; // # 60 Hz Log.Info(m => m("{0} uSecs per period", pulseLengthMicroSeconds)); - pulseLengthMicroSeconds /= 4096; // # 12 bits of resolution - Log.Info(m => m("{0} uSecs per bit", pulseLengthMicroSeconds)); + int microSecondsPerBit = pulseLengthMicroSeconds / 4096; // # 12 bits of resolution + Log.Info(m => m("{0} uSecs per bit", microSecondsPerBit)); pulse *= 1000; pulse /= pulseLengthMicroSeconds; return pulse; diff --git a/Test.Gpio.Pca9685/app.config b/Test.Gpio.Pca9685/app.config index c0f7630..fee187a 100644 --- a/Test.Gpio.Pca9685/app.config +++ b/Test.Gpio.Pca9685/app.config @@ -18,7 +18,7 @@ - + From f7f00da64225dba5fde2f519cb4c3caca37dbce6 Mon Sep 17 00:00:00 2001 From: neutmute Date: Tue, 10 Dec 2013 22:10:32 +1100 Subject: [PATCH 134/227] camel casing --- Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj b/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj index f8af8d6..49ef8d1 100644 --- a/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj +++ b/Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj @@ -7,8 +7,8 @@ {57A001A7-FCF7-45EC-8E25-A390EF044E94} Exe Properties - Test.Gpio.PCA9685 - Test.Gpio.PCA9685 + Test.Gpio.Pca9685 + Test.Gpio.Pca9685 v4.0 512 ..\ From 63be78a93793cb313f107d4356fb5666397dd98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 2 Apr 2014 21:02:08 +0200 Subject: [PATCH 135/227] Merged pull request #9 --- .nuget/NuGet.targets | 4 +- .../Controllers/Pca9685/IPwmDevice.cs | 11 ++- .../Controllers/Pca9685/Pca9685Connection.cs | 95 ++++++++++--------- .../Mcp3008/Mcp3008SpiConnection.cs | 3 +- .../Mcp4822/Mcp4822SpiConnection.cs | 3 +- .../Expanders/Mcp23017/Mcp23017InputPin.cs | 40 ++++++++ .../Expanders/Mcp23017/Mcp23017OutputPin.cs | 5 +- .../Mcp23017/Mcp23017PinExtensionMethods.cs | 9 +- Raspberry.IO.Components/GpioOutputPin.cs | 28 ------ .../GpioPinExtensionMethods.cs | 17 ---- Raspberry.IO.Components/IOutputPin.cs | 9 -- .../Raspberry.IO.Components.csproj | 15 +-- .../Sensors/HcSr04/HcSr04Connection.cs | 23 ++--- Raspberry.IO.GeneralPurpose.nuspec | 2 + Raspberry.IO.GeneralPurpose/GpioInputPin.cs | 67 +++++++++++++ Raspberry.IO.GeneralPurpose/GpioOutputPin.cs | 55 +++++++++++ .../GpioPinExtensionMethods.cs | 64 +++++++++++++ .../Raspberry.IO.GeneralPurpose.csproj | 9 ++ ...pberry.IO.SerialPeripheralInterface.csproj | 6 +- .../SpiConnection.cs | 59 +++++------- Raspberry.IO/IInputPin.cs | 31 ++++++ Raspberry.IO/IOutputPin.cs | 24 +++++ Raspberry.IO/InputPinExtensionMethods.cs | 38 ++++++++ Raspberry.IO/Properties/AssemblyInfo.cs | 36 +++++++ Raspberry.IO/Raspberry.IO.csproj | 57 +++++++++++ RaspberrySharp.IO.sln | 9 +- Test.Gpio.HCSR04/Program.cs | 7 +- Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj | 4 + Test.Gpio.HD44780/Hd44780Configuration.cs | 2 +- Test.Gpio.HD44780/Test.Gpio.HD44780.csproj | 4 + Test.Gpio.MCP3008/Program.cs | 8 +- Test.Gpio.MCP3008/Test.Gpio.MCP3008.csproj | 4 + Test.Gpio.MCP4822/Program.cs | 7 +- Test.Gpio.MCP4822/Test.Gpio.MCP4822.csproj | 4 + Test.Gpio.Pca9685/PCA9685Options.cs | 59 +++++------- Test.Gpio.Pca9685/Program.cs | 90 +++++++++++++----- Test.Gpio.Pca9685/Test.Gpio.Pca9685.csproj | 17 ++-- Test.Gpio.Pca9685/app.config | 6 +- Test.Gpio.Pca9685/packages.config | 2 +- .../Raspberry.System.1.2.0.nuspec | 25 ----- 40 files changed, 684 insertions(+), 274 deletions(-) create mode 100644 Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputPin.cs delete mode 100644 Raspberry.IO.Components/GpioOutputPin.cs delete mode 100644 Raspberry.IO.Components/GpioPinExtensionMethods.cs delete mode 100644 Raspberry.IO.Components/IOutputPin.cs create mode 100644 Raspberry.IO.GeneralPurpose/GpioInputPin.cs create mode 100644 Raspberry.IO.GeneralPurpose/GpioOutputPin.cs create mode 100644 Raspberry.IO.GeneralPurpose/GpioPinExtensionMethods.cs create mode 100644 Raspberry.IO/IInputPin.cs create mode 100644 Raspberry.IO/IOutputPin.cs create mode 100644 Raspberry.IO/InputPinExtensionMethods.cs create mode 100644 Raspberry.IO/Properties/AssemblyInfo.cs create mode 100644 Raspberry.IO/Raspberry.IO.csproj delete mode 100644 packages/Raspberry.System.1.2.0/Raspberry.System.1.2.0.nuspec diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets index 83fe906..f864982 100644 --- a/.nuget/NuGet.targets +++ b/.nuget/NuGet.targets @@ -1,8 +1,8 @@ - $(MSBuildProjectDirectory)\..\ - + false diff --git a/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs index dfeff5d..280b263 100644 --- a/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs +++ b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs @@ -1,20 +1,29 @@ namespace Raspberry.IO.Components.Controllers.Pca9685 { /// - /// Make it easier to IoC + /// Make it easier to IoC /// public interface IPwmDevice { + /// + /// Sets the PWM update rate. + /// + /// The frequency, in hz. void SetPwmUpdateRate(int frequencyHz); /// /// Sets a single PWM channel with on / off values to control the duty cycle /// + /// The channel. + /// The on values. + /// The off values. void SetPwm(PwmChannel channel, int on, int off); /// /// Set a channel to fully on or off /// + /// The channel. + /// if set to true, all values are on; otherwise they are all off. void SetFull(PwmChannel channel, bool fullOn); } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs b/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs index 7bdd291..38321a4 100644 --- a/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs +++ b/Raspberry.IO.Components/Controllers/Pca9685/Pca9685Connection.cs @@ -1,8 +1,12 @@ -using System; +#region References + +using System; using Common.Logging; using Raspberry.IO.InterIntegratedCircuit; using Raspberry.Timers; +#endregion + namespace Raspberry.IO.Components.Controllers.Pca9685 { /// @@ -13,46 +17,25 @@ namespace Raspberry.IO.Components.Controllers.Pca9685 /// public class Pca9685Connection : IPwmDevice { - #region fields + #region Fields - private readonly I2cDeviceConnection _connection; - private static readonly ILog Log = LogManager.GetCurrentClassLogger(); + private readonly I2cDeviceConnection connection; + private static readonly ILog log = LogManager.GetCurrentClassLogger(); #endregion - #region Register enum + #region Instance Management - private enum Register + public static Pca9685Connection Create(I2cDeviceConnection connection) { - SUBADR1 = 0x02, - SUBADR2 = 0x03, - SUBADR3 = 0x04, - MODE1 = 0x00, - PRESCALE = 0xFE, - LED0_ON_L = 0x06, - LED0_ON_H = 0x07, - LED0_OFF_L = 0x08, - LED0_OFF_H = 0x09, - ALLLED_ON_L = 0xFA, - ALLLED_ON_H = 0xFB, - ALLLED_OFF_L = 0xFC, - ALLLED_OFF_H = 0xFD, - } - - #endregion - - #region Ctor - - public static IPwmDevice Create(I2cDeviceConnection connection) - { - var pwmDevice = new Pca9685Connection(connection); - return pwmDevice; + return new Pca9685Connection(connection); } private Pca9685Connection(I2cDeviceConnection connection) { - _connection = connection; - Log.Info(m => m("Reseting PCA9685")); + this.connection = connection; + + log.Info(m => m("Reseting PCA9685")); WriteRegister(Register.MODE1, 0x00); } @@ -61,8 +44,10 @@ private Pca9685Connection(I2cDeviceConnection connection) #region Methods /// - /// Datasheet: 7.3.5 PWM frequency PRE_SCALE + /// Sets the PWM update rate. /// + /// The frequency, in hz. + /// Datasheet: 7.3.5 PWM frequency PRE_SCALE public void SetPwmUpdateRate(int frequencyHz) { var preScale = 25000000.0m; // 25MHz @@ -71,12 +56,12 @@ public void SetPwmUpdateRate(int frequencyHz) preScale -= 1.0m; - Log.Trace(m => m("Setting PWM frequency to {0} Hz", frequencyHz)); - Log.Trace(m => m("Estimated pre-scale: {0}", preScale)); + log.Trace(m => m("Setting PWM frequency to {0} Hz", frequencyHz)); + log.Trace(m => m("Estimated pre-scale: {0}", preScale)); var prescale = Math.Floor(preScale + 0.5m); - Log.Trace(m => m("Final pre-scale: {0}", prescale)); + log.Trace(m => m("Final pre-scale: {0}", prescale)); var oldmode = ReadRegister(Register.MODE1); var newmode = (byte) ((oldmode & 0x7F) | 0x10); // sleep @@ -95,6 +80,9 @@ public void SetPwmUpdateRate(int frequencyHz) /// /// Sets a single PWM channel /// + /// The channel. + /// The on values. + /// The off values. public void SetPwm(PwmChannel channel, int on, int off) { WriteRegister(Register.LED0_ON_L + 4*(int) channel, on & 0xFF); @@ -103,16 +91,38 @@ public void SetPwm(PwmChannel channel, int on, int off) WriteRegister(Register.LED0_OFF_H + 4*(int) channel, off >> 8); } + /// + /// Set a channel to fully on or off + /// + /// The channel. + /// if set to true, all values are on; otherwise they are all off. public void SetFull(PwmChannel channel, bool fullOn) { if (fullOn) - { SetFullOn(channel); - } else - { SetFullOff(channel); - } + } + + #endregion + + #region Private Helpers + + private enum Register + { + SUBADR1 = 0x02, + SUBADR2 = 0x03, + SUBADR3 = 0x04, + MODE1 = 0x00, + PRESCALE = 0xFE, + LED0_ON_L = 0x06, + LED0_ON_H = 0x07, + LED0_OFF_L = 0x08, + LED0_OFF_H = 0x09, + ALLLED_ON_L = 0xFA, + ALLLED_ON_H = 0xFB, + ALLLED_OFF_L = 0xFC, + ALLLED_OFF_H = 0xFD, } private void SetFullOn(PwmChannel channel) @@ -129,7 +139,7 @@ private void SetFullOff(PwmChannel channel) private void WriteRegister(Register register, byte data) { - _connection.Write(new[] {(byte) register, data}); + connection.Write(new[] {(byte) register, data}); } private void WriteRegister(Register register, int data) @@ -139,12 +149,11 @@ private void WriteRegister(Register register, int data) private byte ReadRegister(Register register) { - _connection.Write((byte) register); - var value = _connection.ReadByte(); + connection.Write((byte) register); + var value = connection.ReadByte(); return value; } #endregion - } } diff --git a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs index 1f7ef82..57f3e25 100644 --- a/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs +++ b/Raspberry.IO.Components/Converters/Mcp3008/Mcp3008SpiConnection.cs @@ -1,7 +1,6 @@ #region References using System; -using Raspberry.IO.GeneralPurpose; using Raspberry.IO.SerialPeripheralInterface; #endregion @@ -25,7 +24,7 @@ public class Mcp3008SpiConnection : IDisposable #region Instance Management - public Mcp3008SpiConnection(ProcessorPin clock, ProcessorPin cs, ProcessorPin miso, ProcessorPin mosi, decimal scale) + public Mcp3008SpiConnection(IOutputPin clock, IOutputPin cs, IInputPin miso, IOutputPin mosi, decimal scale) { this.scale = scale; spiConnection = new SpiConnection(clock, cs, miso, mosi, Endianness.LittleEndian); diff --git a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs index 77fdd2e..3bd51fa 100644 --- a/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs +++ b/Raspberry.IO.Components/Converters/Mcp4822/Mcp4822SpiConnection.cs @@ -1,7 +1,6 @@ #region References using System; -using Raspberry.IO.GeneralPurpose; using Raspberry.IO.SerialPeripheralInterface; #endregion @@ -23,7 +22,7 @@ public class Mcp4822SpiConnection : IDisposable #region Instance Management - public Mcp4822SpiConnection(ProcessorPin clock, ProcessorPin ss, ProcessorPin mosi, decimal scale) + public Mcp4822SpiConnection(IOutputPin clock, IOutputPin ss, IOutputPin mosi, decimal scale) { spiConnection = new SpiConnection(clock, ss, null, mosi, Endianness.LittleEndian); this.scale = scale; diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputPin.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputPin.cs new file mode 100644 index 0000000..fb64be7 --- /dev/null +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputPin.cs @@ -0,0 +1,40 @@ +using System; + +namespace Raspberry.IO.Components.Expanders.Mcp23017 +{ + public class Mcp23017InputPin : IInputPin + { + private readonly Mcp23017I2cConnection connection; + private readonly Mcp23017Pin pin; + + public Mcp23017InputPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) + { + this.connection = connection; + this.pin = pin; + + connection.SetDirection(pin, Mcp23017PinDirection.Input); + connection.SetResistor(pin, resistor); + connection.SetPolarity(pin, polarity); + } + + public void Dispose(){} + + public bool Read() + { + return connection.GetPinStatus(pin); + } + + public void Wait(bool waitForUp = true, decimal timeout = 0) + { + var startWait = DateTime.Now; + if (timeout == 0) + timeout = 5000; + + while (Read() != waitForUp) + { + if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) + throw new TimeoutException("A timeout occurred while waiting"); + } + } + } +} \ No newline at end of file diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputPin.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputPin.cs index c0144ff..194b697 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputPin.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017OutputPin.cs @@ -5,13 +5,14 @@ public class Mcp23017OutputPin : IOutputPin private readonly Mcp23017I2cConnection connection; private readonly Mcp23017Pin pin; - public Mcp23017OutputPin(Mcp23017I2cConnection connection, Mcp23017Pin pin) + public Mcp23017OutputPin(Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { this.connection = connection; this.pin = pin; connection.SetDirection(pin, Mcp23017PinDirection.Output); - connection.SetPolarity(pin, Mcp23017PinPolarity.Normal); + connection.SetResistor(pin, resistor); + connection.SetPolarity(pin, polarity); } public void Dispose(){} diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs index faab3ab..ff702d1 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017PinExtensionMethods.cs @@ -2,9 +2,14 @@ namespace Raspberry.IO.Components.Expanders.Mcp23017 { public static class Mcp23017PinExtensionMethods { - public static Mcp23017OutputPin Out(this Mcp23017I2cConnection connection, Mcp23017Pin pin) + public static Mcp23017OutputPin Out(this Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) { - return new Mcp23017OutputPin(connection, pin); + return new Mcp23017OutputPin(connection, pin, resistor, polarity); + } + + public static Mcp23017InputPin In(this Mcp23017I2cConnection connection, Mcp23017Pin pin, Mcp23017PinResistor resistor = Mcp23017PinResistor.None, Mcp23017PinPolarity polarity = Mcp23017PinPolarity.Normal) + { + return new Mcp23017InputPin(connection, pin, resistor, polarity); } } } \ No newline at end of file diff --git a/Raspberry.IO.Components/GpioOutputPin.cs b/Raspberry.IO.Components/GpioOutputPin.cs deleted file mode 100644 index 92588e3..0000000 --- a/Raspberry.IO.Components/GpioOutputPin.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Raspberry.IO.GeneralPurpose; - -namespace Raspberry.IO.Components -{ - public class GpioOutputPin : IOutputPin - { - private readonly IGpioConnectionDriver driver; - private readonly ProcessorPin pin; - - public GpioOutputPin(IGpioConnectionDriver driver, ProcessorPin pin) - { - this.driver = driver; - this.pin = pin; - - driver.Allocate(pin, PinDirection.Output); - } - - public void Dispose() - { - driver.Release(pin); - } - - public void Write(bool state) - { - driver.Write(pin, state); - } - } -} \ No newline at end of file diff --git a/Raspberry.IO.Components/GpioPinExtensionMethods.cs b/Raspberry.IO.Components/GpioPinExtensionMethods.cs deleted file mode 100644 index 5c5ccca..0000000 --- a/Raspberry.IO.Components/GpioPinExtensionMethods.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Raspberry.IO.GeneralPurpose; - -namespace Raspberry.IO.Components -{ - public static class GpioPinExtensionMethods - { - public static GpioOutputPin Out(this IGpioConnectionDriver driver, ConnectorPin pin) - { - return driver.Out(pin.ToProcessor()); - } - - public static GpioOutputPin Out(this IGpioConnectionDriver driver, ProcessorPin pin) - { - return new GpioOutputPin(driver, pin); - } - } -} \ No newline at end of file diff --git a/Raspberry.IO.Components/IOutputPin.cs b/Raspberry.IO.Components/IOutputPin.cs deleted file mode 100644 index 324c8fc..0000000 --- a/Raspberry.IO.Components/IOutputPin.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Raspberry.IO.Components -{ - public interface IOutputPin : IDisposable - { - void Write(bool state); - } -} \ No newline at end of file diff --git a/Raspberry.IO.Components/Raspberry.IO.Components.csproj b/Raspberry.IO.Components/Raspberry.IO.Components.csproj index e40a9a5..651d9ba 100644 --- a/Raspberry.IO.Components/Raspberry.IO.Components.csproj +++ b/Raspberry.IO.Components/Raspberry.IO.Components.csproj @@ -36,6 +36,9 @@ ..\packages\Common.Logging.2.1.2\lib\net40\Common.Logging.dll + + ..\packages\NLog.2.0.1.2\lib\net40\NLog.dll + False ..\packages\Raspberry.System.1.2.0\lib\net40\Raspberry.System.dll @@ -62,12 +65,10 @@ + - - - @@ -78,10 +79,6 @@ - - {281C71ED-C36D-408E-8BAA-75C381DC17E7} - Raspberry.IO.GeneralPurpose - {63B8403E-BC56-43F9-A045-F61ECC3871F3} Raspberry.IO.InterIntegratedCircuit @@ -90,6 +87,10 @@ {326342E5-0411-40E8-9F2D-563D6B192568} Raspberry.IO.SerialPeripheralInterface + + {D2E41147-5BF6-4109-A497-C76284F3C020} + Raspberry.IO + diff --git a/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs b/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs index 61935cd..0cda9ab 100644 --- a/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs +++ b/Raspberry.IO.Components/Sensors/HcSr04/HcSr04Connection.cs @@ -1,7 +1,6 @@ #region References using System; -using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; #endregion @@ -22,9 +21,8 @@ public class HcSr04Connection : IDisposable private const decimal triggerTime = 0.01m; // Waits at least 10s = 0.01ms private const decimal echoUpTimeout = 500m; - private readonly IGpioConnectionDriver driver; - private readonly ProcessorPin triggerPin; - private readonly ProcessorPin echoPin; + private readonly IOutputPin triggerPin; + private readonly IInputPin echoPin; #endregion @@ -35,18 +33,13 @@ public class HcSr04Connection : IDisposable /// /// The trigger pin. /// The echo pin. - public HcSr04Connection(ProcessorPin triggerPin, ProcessorPin echoPin) + public HcSr04Connection(IOutputPin triggerPin, IInputPin echoPin) { this.triggerPin = triggerPin; this.echoPin = echoPin; Timeout = DefaultTimeout; - driver = GpioConnectionSettings.DefaultDriver; - - driver.Allocate(echoPin, PinDirection.Input); - driver.Allocate(triggerPin, PinDirection.Output); - try { GetDistance(); @@ -89,11 +82,11 @@ void IDisposable.Dispose() /// The distance, in meters. public decimal GetDistance() { - driver.Write(triggerPin, true); + triggerPin.Write(true); Timer.Sleep(triggerTime); - driver.Write(triggerPin, false); + triggerPin.Write(false); - var upTime = driver.Time(echoPin, true, echoUpTimeout, Timeout); + var upTime = echoPin.Time(true, echoUpTimeout, Timeout); return Units.Velocity.Sound.ToDistance(upTime); } @@ -102,8 +95,8 @@ public decimal GetDistance() ///
public void Close() { - driver.Release(triggerPin); - driver.Release(echoPin); + triggerPin.Dispose(); + echoPin.Dispose(); } #endregion diff --git a/Raspberry.IO.GeneralPurpose.nuspec b/Raspberry.IO.GeneralPurpose.nuspec index 0ddd06d..b01ae64 100644 --- a/Raspberry.IO.GeneralPurpose.nuspec +++ b/Raspberry.IO.GeneralPurpose.nuspec @@ -26,10 +26,12 @@ + + diff --git a/Raspberry.IO.GeneralPurpose/GpioInputPin.cs b/Raspberry.IO.GeneralPurpose/GpioInputPin.cs new file mode 100644 index 0000000..a7ccba7 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/GpioInputPin.cs @@ -0,0 +1,67 @@ +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents an input pin on a GPIO interface. + /// + public class GpioInputPin : IInputPin + { + #region Fields + + private readonly IGpioConnectionDriver driver; + private readonly ProcessorPin pin; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The driver. + /// The pin. + /// The resistor. + public GpioInputPin(IGpioConnectionDriver driver, ProcessorPin pin, PinResistor resistor = PinResistor.None) + { + this.driver = driver; + this.pin = pin; + + driver.Allocate(pin, PinDirection.Input); + driver.SetPinResistor(pin, resistor); + } + + #endregion + + #region Methods + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + driver.Release(pin); + } + + /// + /// Reads the current value. + /// + /// + /// The pin value. + /// + public bool Read() + { + return driver.Read(pin); + } + + /// + /// Waits the current pin to be up. + /// + /// if set to true, waits for the pin to be up; otherwise, waits for the pin to be down. + /// The timeout. + public void Wait(bool waitForUp = true, decimal timeout = 0) + { + driver.Wait(pin, waitForUp, timeout); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioOutputPin.cs b/Raspberry.IO.GeneralPurpose/GpioOutputPin.cs new file mode 100644 index 0000000..7f4b355 --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/GpioOutputPin.cs @@ -0,0 +1,55 @@ +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Represents an output pin on GPIO interface + /// + public class GpioOutputPin : IOutputPin + { + #region Fields + + private readonly IGpioConnectionDriver driver; + private readonly ProcessorPin pin; + + #endregion + + #region Instance Management + + /// + /// Initializes a new instance of the class. + /// + /// The driver. + /// The pin. + /// The resistor. + public GpioOutputPin(IGpioConnectionDriver driver, ProcessorPin pin, PinResistor resistor = PinResistor.None) + { + this.driver = driver; + this.pin = pin; + + driver.Allocate(pin, PinDirection.Output); + driver.SetPinResistor(pin, resistor); + } + + #endregion + + #region Methods + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + driver.Release(pin); + } + + /// + /// Writes the specified state. + /// + /// The pin state. + public void Write(bool state) + { + driver.Write(pin, state); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/GpioPinExtensionMethods.cs b/Raspberry.IO.GeneralPurpose/GpioPinExtensionMethods.cs new file mode 100644 index 0000000..7d803ce --- /dev/null +++ b/Raspberry.IO.GeneralPurpose/GpioPinExtensionMethods.cs @@ -0,0 +1,64 @@ +namespace Raspberry.IO.GeneralPurpose +{ + /// + /// Provides extension methods to create GPIO pins + /// + public static class GpioPinExtensionMethods + { + #region Methods + + /// + /// Created an output pin on the specified driver. + /// + /// The driver. + /// The pin. + /// The resistor. + /// + public static GpioOutputPin Out(this IGpioConnectionDriver driver, ConnectorPin pin, + PinResistor resistor = PinResistor.None) + { + return driver.Out(pin.ToProcessor(), resistor); + } + + /// + /// Created an output pin on the specified driver. + /// + /// The driver. + /// The pin. + /// The resistor. + /// + public static GpioOutputPin Out(this IGpioConnectionDriver driver, ProcessorPin pin, + PinResistor resistor = PinResistor.None) + { + return new GpioOutputPin(driver, pin, resistor); + } + + /// + /// Created an input pin on the specified driver. + /// + /// The driver. + /// The pin. + /// The resistor. + /// + public static GpioInputPin In(this IGpioConnectionDriver driver, ConnectorPin pin, + PinResistor resistor = PinResistor.None) + { + return driver.In(pin.ToProcessor(), resistor); + } + + /// + /// Created an input pin on the specified driver. + /// + /// The driver. + /// The pin. + /// The resistor. + /// + public static GpioInputPin In(this IGpioConnectionDriver driver, ProcessorPin pin, + PinResistor resistor = PinResistor.None) + { + return new GpioInputPin(driver, pin, resistor); + } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj index 5430108..2f2f6d1 100644 --- a/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj +++ b/Raspberry.IO.GeneralPurpose/Raspberry.IO.GeneralPurpose.csproj @@ -59,6 +59,9 @@ + + + @@ -82,6 +85,12 @@ + + + {D2E41147-5BF6-4109-A497-C76284F3C020} + Raspberry.IO + + + \ No newline at end of file diff --git a/RaspberrySharp.IO.sln b/RaspberrySharp.IO.sln index 6ac2982..0be8ade 100644 --- a/RaspberrySharp.IO.sln +++ b/RaspberrySharp.IO.sln @@ -42,7 +42,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{33C6FE EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.WatchPin", "Test.Gpio.WatchPin\Test.Gpio.WatchPin.csproj", "{60B59A9C-69F6-4CEA-8385-C8542AE2BB98}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Pca9685", "Test.Gpio.Pca9685\Test.Gpio.Pca9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.PCA9685", "Test.Gpio.Pca9685\Test.Gpio.PCA9685.csproj", "{57A001A7-FCF7-45EC-8E25-A390EF044E94}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.IO\Raspberry.IO.csproj", "{D2E41147-5BF6-4109-A497-C76284F3C020}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -98,11 +100,16 @@ Global {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Debug|Any CPU.Build.0 = Debug|Any CPU {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.ActiveCfg = Release|Any CPU {57A001A7-FCF7-45EC-8E25-A390EF044E94}.Release|Any CPU.Build.0 = Release|Any CPU + {D2E41147-5BF6-4109-A497-C76284F3C020}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2E41147-5BF6-4109-A497-C76284F3C020}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2E41147-5BF6-4109-A497-C76284F3C020}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2E41147-5BF6-4109-A497-C76284F3C020}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} = {93E87796-2109-444A-8852-7174C93E6F45} {B28253A7-BB93-40F7-B41C-B4AE369174ED} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {54075457-7C1D-4C8F-BE7D-CFCA34F11228} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} {6B5D38D3-7642-4DF9-A9AA-3AF7D00890BC} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC} diff --git a/Test.Gpio.HCSR04/Program.cs b/Test.Gpio.HCSR04/Program.cs index 239156b..71cb204 100644 --- a/Test.Gpio.HCSR04/Program.cs +++ b/Test.Gpio.HCSR04/Program.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using Raspberry.IO; +using Raspberry.IO.Components; using Raspberry.IO.Components.Sensors.HcSr04; using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; @@ -28,8 +30,11 @@ private static void Main(string[] args) Console.WriteLine(); var interval = GetInterval(args); + var driver = GpioConnectionSettings.DefaultDriver; - using (var connection = new HcSr04Connection(triggerPin.ToProcessor(), echoPin.ToProcessor())) + using (var connection = new HcSr04Connection( + driver.Out(triggerPin.ToProcessor()), + driver.In(echoPin.ToProcessor()))) { while (!Console.KeyAvailable) { diff --git a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj index 8aba60c..0929b7b 100644 --- a/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj +++ b/Test.Gpio.HCSR04/Test.Gpio.HCSR04.csproj @@ -77,6 +77,10 @@ {281C71ED-C36D-408E-8BAA-75C381DC17E7} Raspberry.IO.GeneralPurpose + + {D2E41147-5BF6-4109-A497-C76284F3C020} + Raspberry.IO + diff --git a/Test.Gpio.HD44780/Hd44780Configuration.cs b/Test.Gpio.HD44780/Hd44780Configuration.cs index abc1795..82fc5a5 100644 --- a/Test.Gpio.HD44780/Hd44780Configuration.cs +++ b/Test.Gpio.HD44780/Hd44780Configuration.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Raspberry.IO.Components; +using Raspberry.IO; namespace Test.Gpio.HD44780 { diff --git a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj index 7355376..d2e24f4 100644 --- a/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj +++ b/Test.Gpio.HD44780/Test.Gpio.HD44780.csproj @@ -83,6 +83,10 @@ {63B8403E-BC56-43F9-A045-F61ECC3871F3} Raspberry.IO.InterIntegratedCircuit + + {D2E41147-5BF6-4109-A497-C76284F3C020} + Raspberry.IO + + \ No newline at end of file diff --git a/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj.DotSettings b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj.DotSettings new file mode 100644 index 0000000..9bbc349 --- /dev/null +++ b/Raspberry.IO.Interop/Raspberry.IO.Interop.csproj.DotSettings @@ -0,0 +1,4 @@ + + True + True + True \ No newline at end of file diff --git a/Raspberry.IO.Interop/UnixFile.cs b/Raspberry.IO.Interop/UnixFile.cs new file mode 100644 index 0000000..bc4d928 --- /dev/null +++ b/Raspberry.IO.Interop/UnixFile.cs @@ -0,0 +1,128 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Raspberry.IO.Interop +{ + /// + /// A UNIX file that is controlled by the operation system. + /// + public sealed class UnixFile : IFile + { + #region Libc imports + [DllImport("libc.so.6", EntryPoint = "open")] + private static extern int open(string fileName, int mode); + [DllImport("libc.so.6", EntryPoint = "close")] + private static extern int close(int file); + #endregion + + #region Fields + private int descriptor; + private string filename; + #endregion + + #region Instance Management + private UnixFile(int descriptor) { + this.descriptor = descriptor; + } + + /// + /// Initializes a new instance of the class. + /// + /// A pathname for the file. + /// The file access mode. + public UnixFile(string filename, UnixFileMode fileMode) + :this(OpenFileDescriptor(filename, fileMode)) { + this.filename = filename; + } + + ~UnixFile() { + Dispose(false); + GC.SuppressFinalize(this); + } + #endregion + + #region Properties + /// + /// The file descriptor + /// + public int Descriptor { + get { return descriptor; } + } + + /// + /// The pathname for the file. + /// + public string Filename { + get { return filename; } + } + #endregion + + #region Methods + /// + /// Closes the file and frees all unmanaged system resources. See for more information. + /// + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Opens a UNIX file. + /// + /// The filepath. + /// The file access mode. + /// A opened file. + public static IFile Open(string fileName, UnixFileMode fileMode) { + return new UnixFile(fileName, fileMode); + } + + /// + /// Opens a UNIX file and returns the file descriptor. + /// + /// The filepath. + /// The file access mode. + /// The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process. + public static int OpenFileDescriptor(string fileName, UnixFileMode fileMode) { + var mode = unchecked ((int) fileMode); + return open(fileName, mode); + } + + /// + /// Closes a file descriptor, so that it no longer refers to any file and may be reused. Any record locks held on the file it was associated with, and owned by + /// the process, are removed (regardless of the file descriptor that was used to obtain the lock). + /// + /// The file descriptor the shall be closed. + /// true on success + /// + /// If is the last file descriptor referring to the underlying open file description, the resources associated with + /// the open file description are freed; if the descriptor was the last reference to a file which has been removed using unlink the file is deleted. + /// + public static bool CloseFileDescriptor(int fileDescriptor) { + if (fileDescriptor != 0) { + return close(fileDescriptor) == 0; + } + return false; + } + #endregion + + #region Private Helpers + private void Dispose(bool disposing) { + if (disposing) { + // free managed here + } + + Trace.Assert(disposing, + string.Format("ERROR: GC finalized a unix file '{0}' with open file descriptor {1} that was not disposed!", + filename, descriptor)); + + if (descriptor != 0) { + // we need to free unmanaged resources to avoid memory leeks + close(descriptor); + descriptor = 0; + filename = null; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.Interop/UnmanagedMemory.cs b/Raspberry.IO.Interop/UnmanagedMemory.cs new file mode 100644 index 0000000..1af4e84 --- /dev/null +++ b/Raspberry.IO.Interop/UnmanagedMemory.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; + +namespace Raspberry.IO.Interop +{ + /// + /// An memory buffer (reference) to unmanaged memory that can be used for P/Invoke operations. + /// + public class UnmanagedMemory : IMemory + { + #region Fields + private readonly bool owner; + private IntPtr memoryPointer; + private int length; + #endregion + + #region Instance Management + /// + /// Encapsulates the supplied memory address to unmanaged memory. + /// + /// Unmanaged memory address + /// Size in bytes + /// If true the memory will be released if the user calls . + public UnmanagedMemory(IntPtr memoryPointer, int length, bool owner) { + this.memoryPointer = memoryPointer; + this.length = length; + this.owner = owner; + } + + /// + /// Allocates unmanaged memory of the requested size. + /// + /// Memory size in bytes. + public UnmanagedMemory(int length) { + this.length = length; + memoryPointer = Marshal.AllocHGlobal(length); + owner = true; + } + + ~UnmanagedMemory() { + Dispose(false); + } + + /// + /// Free the unmanaged memory. + /// + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Free the unmanaged memory. + /// + /// The unmanaged memory will always be released to avoid memory leaks. If you don't want this, don't call this method () in your derived class. + protected virtual void Dispose(bool disposing) { + if (disposing) { + // free managed here + } + + Trace.Assert(disposing, + string.Format("ERROR: GC finalized unmanaged memory of {0} bytes for address {1} that was not disposed!", + length, memoryPointer.ToString("X8"))); + + if (memoryPointer != IntPtr.Zero && owner) { + // free unmanaged memory to avoid memory leeks + Marshal.FreeHGlobal(memoryPointer); + } + memoryPointer = IntPtr.Zero; + length = 0; + } + #endregion + + #region Properties + + /// + /// Pointer to the memory address. + /// + public IntPtr Pointer { + get { return memoryPointer; } + } + + /// + /// Size of the allocated unmanaged memory in bytes. + /// + public int Length { + get { return length; } + } + + /// + /// Indexer, which will allow client code to use [] notation on the class instance itself. + /// + /// Offset to memory + /// Byte at/from the specified position . + public byte this[int index] { + get { return Read(index); } + set { Write(index, value); } + } + + #endregion + + #region Methods + /// + /// Writes at . + /// + /// Offset + /// Data that shall be written. + public void Write(int offset, byte data) { + if (memoryPointer == IntPtr.Zero) { + throw new ObjectDisposedException("Unmanaged memory already disposed."); + } + + if (offset < 0 || offset >= length) { + throw new ArgumentOutOfRangeException("offset"); + } + + Marshal.WriteByte(memoryPointer, offset, data); + } + + /// + /// Reads a byte at . + /// + /// Offset + /// The data. + public byte Read(int offset) { + if (memoryPointer == IntPtr.Zero) { + throw new ObjectDisposedException("Unmanaged memory already disposed."); + } + + if (offset < 0 || offset >= length) { + throw new ArgumentOutOfRangeException("offset"); + } + + return Marshal.ReadByte(memoryPointer, offset); + } + + /// + /// Copies the bytes from to the memory. + /// + /// Source byte array. + /// Copies the data starting from . + /// Copies the data starting at to the memory. + /// Copies bytes. + public void Copy(byte[] source, int sourceIndex, int destinationIndex, int lengthInBytes) { + if (memoryPointer == IntPtr.Zero) { + throw new ObjectDisposedException("Unmanaged memory already disposed."); + } + + if (destinationIndex < 0 || destinationIndex >= length) { + throw new ArgumentOutOfRangeException("destinationIndex"); + } + + if (lengthInBytes < 0 || (destinationIndex + lengthInBytes) > length) { + throw new ArgumentOutOfRangeException("lengthInBytes"); + } + + Marshal.Copy(source, sourceIndex, memoryPointer + destinationIndex, lengthInBytes); + } + + /// + /// Copies data from the memory to the supplied byte array. + /// + /// Copies the data starting from . + /// Destination byte array. + /// Copies the data starting at to the destination byte array. + /// Copies bytes. + public void Copy(int sourceIndex, byte[] destination, int destinationIndex, int lengthInBytes) { + if (memoryPointer == IntPtr.Zero) { + throw new ObjectDisposedException("Unmanaged memory already disposed."); + } + + if (sourceIndex < 0 || sourceIndex >= length) { + throw new ArgumentOutOfRangeException("sourceIndex"); + } + + if (sourceIndex + lengthInBytes >= length) { + throw new ArgumentOutOfRangeException("lengthInBytes"); + } + + Marshal.Copy(memoryPointer + sourceIndex, destination, destinationIndex, lengthInBytes); + } + + /// + /// Returns an enumerator. + /// + /// An enumerator + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + /// + /// Returns an enumerator. + /// + /// An enumerator + public IEnumerator GetEnumerator() { + var tmp = new byte[length]; + Copy(0, tmp, 0, length); + + return ((IEnumerable) tmp) + .GetEnumerator(); + } + + /// + /// Allocates unmanaged memory for and copies its content into it. + /// + /// Structure type + /// The structure that shall be copied into the requested memory buffer. + /// The unmanaged memory buffer containing . + public static UnmanagedMemory CreateAndCopy(T structure) { + var requiredSize = Marshal.SizeOf(structure); + + var memory = new UnmanagedMemory(requiredSize); + Marshal.StructureToPtr(structure, memory.Pointer, false); + + return memory; + } + + /// + /// Allocates unmanaged memory with the size of . + /// + /// Structure type + /// The unmanaged memory buffer of size . + public static UnmanagedMemory CreateFor() { + var requiredSize = Marshal.SizeOf(typeof(T)); + return new UnmanagedMemory(requiredSize); + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiMode.cs b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiMode.cs new file mode 100644 index 0000000..a361cff --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiMode.cs @@ -0,0 +1,73 @@ +using System; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// SPI mode + /// + [Flags] + public enum SpiMode : uint + { + /// + /// Clock phase, if set CPHA=1, otherwise CPHA=0. + /// + ClockPhase = Interop.SPI_CPHA, + + /// + /// Clock polarity, if set CPOL=1, otherwise CPOL=0. + /// + ClockPolarity = Interop.SPI_CPOL, + + /// + /// Chip select is a high signal. + /// + ChipSelectActiveHigh = Interop.SPI_CS_HIGH, + + /// + /// The least significant bit comes first. + /// + LeastSignificantBitFirst = Interop.SPI_LSB_FIRST, + + /// + /// Special 3-wire configuration. + /// + ThreeWire = Interop.SPI_3WIRE, + /// + /// Three-wire serial buses + /// + SlaveInOutShared = Interop.SPI_3WIRE, + /// + /// Loopback + /// + Loopback = Interop.SPI_LOOP, + /// + /// Send no chip select signal. + /// + NoChipSelect = Interop.SPI_NO_CS, + /// + /// Slave pulls low to pause. + /// + Ready = Interop.SPI_READY, + /// + /// Slave pulls low to pause. + /// + SlavePullsLowToPause = Interop.SPI_READY, + + /// + /// CPOL=0, CPHA=0 + /// + Mode0 = Interop.SPI_MODE_0, + /// + /// CPOL=0, CPHA=1 + /// + Mode1 = Interop.SPI_MODE_1, + /// + /// CPOL =1, CPHA=0 + /// + Mode2 = Interop.SPI_MODE_2, + /// + /// CPOL=1, CPHA=1 + /// + Mode3 = Interop.SPI_MODE_3 + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs new file mode 100644 index 0000000..c1eacf1 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/EnumTypes/SpiTransferMode.cs @@ -0,0 +1,24 @@ +using System; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// Selects if data should be read, written or both. + /// + [Flags] + public enum SpiTransferMode + { + /// + /// Write data to the chip. + /// + Write = 1, + /// + /// Read data from the chip. + /// + Read = 2, + /// + /// Write and read data simultaneously. + /// + ReadWrite = 3 + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/ReadonlyTransferBufferException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/ReadonlyTransferBufferException.cs new file mode 100644 index 0000000..b89a163 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/ReadonlyTransferBufferException.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class ReadOnlyTransferBufferException : Exception + { + public ReadOnlyTransferBufferException() {} + public ReadOnlyTransferBufferException(string message) : base(message) {} + public ReadOnlyTransferBufferException(string message, Exception innerException) : base(message, innerException) {} + protected ReadOnlyTransferBufferException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/SendSpiMessageException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SendSpiMessageException.cs new file mode 100644 index 0000000..efdfe0e --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SendSpiMessageException.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class SendSpiMessageException : Exception { + public SendSpiMessageException() {} + public SendSpiMessageException(string message) : base(message) {} + public SendSpiMessageException(string message, Exception innerException) : base(message, innerException) {} + protected SendSpiMessageException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetBitsPerWordException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetBitsPerWordException.cs new file mode 100644 index 0000000..62a05a5 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetBitsPerWordException.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class SetBitsPerWordException : Exception { + public SetBitsPerWordException() {} + public SetBitsPerWordException(string message) : base(message) {} + public SetBitsPerWordException(string message, Exception innerException) : base(message, innerException) {} + protected SetBitsPerWordException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetMaxSpeedException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetMaxSpeedException.cs new file mode 100644 index 0000000..d339575 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetMaxSpeedException.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class SetMaxSpeedException : Exception { + public SetMaxSpeedException() {} + public SetMaxSpeedException(string message) : base(message) {} + public SetMaxSpeedException(string message, Exception innerException) : base(message, innerException) {} + protected SetMaxSpeedException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetSpiModeException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetSpiModeException.cs new file mode 100644 index 0000000..339a9e6 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/SetSpiModeException.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class SetSpiModeException : Exception { + public SetSpiModeException() {} + public SetSpiModeException(string message) : base(message) {} + public SetSpiModeException(string message, Exception innerException) : base(message, innerException) {} + protected SetSpiModeException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Exceptions/WriteOnlyTransferBufferException.cs b/Raspberry.IO.SerialPeripheralInterface/Exceptions/WriteOnlyTransferBufferException.cs new file mode 100644 index 0000000..d209d58 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Exceptions/WriteOnlyTransferBufferException.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.Serialization; + +namespace Raspberry.IO.SerialPeripheralInterface +{ +#pragma warning disable 1591 + [Serializable] + public class WriteOnlyTransferBufferException : Exception + { + public WriteOnlyTransferBufferException() {} + public WriteOnlyTransferBufferException(string message) : base(message) {} + public WriteOnlyTransferBufferException(string message, Exception innerException) : base(message, innerException) {} + protected WriteOnlyTransferBufferException(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +#pragma warning restore 1591 +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs new file mode 100644 index 0000000..5ec17ce --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/INativeSpiConnection.cs @@ -0,0 +1,82 @@ +using System; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// Native SPI connection that communicates with Linux's userspace SPI driver (e.g. /dev/spidev0.0) using IOCTL. + /// + public interface INativeSpiConnection : IDisposable + { + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. + /// + UInt16 Delay { get; } + /// + /// Maximum clock speed in Hz. + /// + UInt32 MaxSpeed { get; } + /// + /// SPI mode + /// + SpiMode Mode { get; } + /// + /// The device's wordsize + /// + byte BitsPerWord { get; } + + /// + /// Sets the . + /// + /// Delay in µsec. + void SetDelay(UInt16 delayInMicroSeconds); + + /// + /// Sets the maximum clock speed. + /// + /// The speed in Hz + void SetMaxSpeed(UInt32 maxSpeedInHz); + + /// + /// Sets the device's wordsize . + /// + /// Bits per word + void SetBitsPerWord(byte wordSize); + + /// + /// Sets the . + /// + /// SPI mode + void SetSpiMode(SpiMode spiMode); + + /// + /// Creates a transfer buffer of the given and copies the connection settings to it. + /// + /// Memory size in bytes. + /// The transfer mode. + /// The requested transfer buffer. + ISpiTransferBuffer CreateTransferBuffer(int sizeInBytes, SpiTransferMode transferMode); + + /// + /// Creates transfer buffers for . + /// + /// The number of messages to send. + /// Message size in bytes. + /// The transfer mode. + /// The requested transfer buffer collection. + ISpiTransferBufferCollection CreateTransferBufferCollection(int numberOfMessages, int messageSizeInBytes, SpiTransferMode transferMode); + + /// + /// Starts the SPI data transfer. + /// + /// The transfer buffer that contains data to be send and/or the received data. + /// An that contains the result of the transfer operation. + int Transfer(ISpiTransferBuffer buffer); + + /// + /// Starts the SPI data transfer. + /// + /// The transfer buffers that contain data to be send and/or the received data. + /// An that contains the result of the transfer operation. + int Transfer(ISpiTransferBufferCollection transferBuffers); + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs new file mode 100644 index 0000000..3dc8e1e --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBuffer.cs @@ -0,0 +1,53 @@ +using System; +using Raspberry.IO.Interop; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// A transfer buffer used to read from / write to the SPI bus. + /// + public interface ISpiTransferBuffer : IDisposable + { + /// + /// Temporary override of the device's wordsize + /// + byte BitsPerWord { get; set; } + /// + /// Temporary override of the device's bitrate (in Hz) + /// + UInt32 Speed { get; set; } + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. + /// + UInt16 Delay { get; set; } + /// + /// Set to true to deselect device before starting the next transfer. + /// + bool ChipSelectChange { get; set; } + /// + /// Pad + /// + UInt32 Pad { get; set; } + /// + /// Specifies if the transfer shall read and/or write. + /// + SpiTransferMode TransferMode { get; } + /// + /// Length of and buffers, in bytes + /// + int Length { get; } + /// + /// Holds pointer to userspace buffer with transmit data, or null. If no data is provided, zeroes are shifted out + /// + IMemory Tx { get; } + /// + /// Holds pointer to userspace buffer for receive data, or null + /// + IMemory Rx { get; } + + /// + /// The IOCTL structure that contains control information for a single SPI transfer + /// + SpiTransferControlStructure ControlStructure { get; } + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs new file mode 100644 index 0000000..6041e95 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/ISpiTransferBufferCollection.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// A collection of transfer buffers that can be used to read from / write to the SPI bus. + /// + public interface ISpiTransferBufferCollection : IDisposable, IEnumerable + { + /// + /// Number of structures. + /// + int Length { get; } + + /// + /// Can be used to request a specific from the collection. + /// + /// Index + /// The requested + ISpiTransferBuffer this[int index] { get; } + + /// + /// A method that returns a specific from the collection. + /// + /// Index + /// The requested + ISpiTransferBuffer Get(int index); + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Interop/Interop.cs b/Raspberry.IO.SerialPeripheralInterface/Interop/Interop.cs new file mode 100644 index 0000000..abc6f65 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Interop/Interop.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + // ReSharper disable InconsistentNaming + internal static class Interop + { + public const UInt32 SPI_CPHA = 0x01; + public const UInt32 SPI_CPOL = 0x02; + + public const UInt32 SPI_MODE_0 = (0 | 0); + public const UInt32 SPI_MODE_1 = (0 | SPI_CPHA); + public const UInt32 SPI_MODE_2 = (SPI_CPOL | 0); + public const UInt32 SPI_MODE_3 = (SPI_CPOL | SPI_CPHA); + + public const UInt32 SPI_CS_HIGH = 0x04; + public const UInt32 SPI_LSB_FIRST = 0x08; + public const UInt32 SPI_3WIRE = 0x10; + + public const UInt32 SPI_LOOP = 0x20; + public const UInt32 SPI_NO_CS = 0x40; + public const UInt32 SPI_READY = 0x80; + + public const UInt32 SPI_IOC_MESSAGE_BASE = 0x40006b00; + public const int SPI_IOC_MESSAGE_NUMBER_SHIFT = 16; + + private static readonly int transferMessageSize = Marshal.SizeOf(typeof(SpiTransferControlStructure)); + + internal static UInt32 GetSpiMessageRequest(int numberOfMessages) { + var size = unchecked((UInt32)(transferMessageSize * numberOfMessages)); + return SPI_IOC_MESSAGE_BASE | (size << SPI_IOC_MESSAGE_NUMBER_SHIFT); + } + } + + // ReSharper restore InconsistentNaming +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs b/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs new file mode 100644 index 0000000..98d7e05 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Interop/SpiTransferControlStructure.cs @@ -0,0 +1,52 @@ +using System; +using System.Runtime.InteropServices; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// A IOCTL structure that describes a single SPI transfer + /// + [StructLayout(LayoutKind.Sequential, Pack = 0)] + public struct SpiTransferControlStructure + { + /// + /// Holds pointer to userspace buffer with transmit data, or 0. If no data is provided, zeroes are shifted out + /// + public UInt64 Tx; + + /// + /// Holds pointer to userspace buffer for receive data, or 0 + /// + public UInt64 Rx; + + /// + /// Length of and buffers, in bytes + /// + public UInt32 Length; + + /// + /// Temporary override of the device's bitrate (in Hz) + /// + public UInt32 Speed; + + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer + /// + public UInt16 Delay; + + /// + /// Temporary override of the device's wordsize + /// + public Byte BitsPerWord; + + /// + /// Set to true to deselect device before starting the next transfer + /// + public Byte ChipSelectChange; + + /// + /// Pad + /// + public UInt32 Pad; + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs b/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs new file mode 100644 index 0000000..65cb4b2 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/NativeSpiConnection.cs @@ -0,0 +1,247 @@ +using System; +using System.Linq; +using Raspberry.IO.Interop; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// Native SPI connection that communicates with Linux's userspace SPI driver (e.g. /dev/spidev0.0) using IOCTL. + /// + public class NativeSpiConnection : INativeSpiConnection + { + #region Constants + internal const UInt32 SPI_IOC_RD_MODE = 0x80016b01; + internal const UInt32 SPI_IOC_WR_MODE = 0x40016b01; + internal const UInt32 SPI_IOC_RD_LSB_FIRST = 0x80016b02; + internal const UInt32 SPI_IOC_WR_LSB_FIRST = 0x40016b02; + internal const UInt32 SPI_IOC_RD_BITS_PER_WORD = 0x80016b03; + internal const UInt32 SPI_IOC_WR_BITS_PER_WORD = 0x40016b03; + internal const UInt32 SPI_IOC_RD_MAX_SPEED_HZ = 0x80046b04; + internal const UInt32 SPI_IOC_WR_MAX_SPEED_HZ = 0x40046b04; + #endregion + + #region Fields + private readonly IControlDevice deviceFile; + private UInt16 delay; + private UInt32 maxSpeed; + private UInt32 mode; + private byte bitsPerWord; + #endregion + + #region Instance Management + + /// + /// Creates a new instance of the class. + /// + /// A control device (IOCTL) to the device file (e.g. /dev/spidev0.0). + public NativeSpiConnection(IControlDevice deviceFile) { + this.deviceFile = deviceFile; + } + + /// + /// Creates a new instance of the class and initializes it. + /// + /// A control device (IOCTL) to the device file (e.g. /dev/spidev0.0). + /// Connection settings + public NativeSpiConnection(IControlDevice deviceFile, SpiConnectionSettings settings) + : this(deviceFile) + { + Init(settings); + } + + /// + /// Creates a new instance of the class and initializes it. + /// + /// Full path to the SPI device file (e.g. /dev/spidev0.0). + /// Connection settings + public NativeSpiConnection(string deviceFilePath, SpiConnectionSettings settings) + : this(new ControlDevice(new UnixFile(deviceFilePath, UnixFileMode.ReadWrite)), settings) + {} + + /// + /// Creates a new instance of the class. + /// + /// Full path to the SPI device file (e.g. /dev/spidev0.0). + public NativeSpiConnection(string deviceFilePath) + : this(new ControlDevice(new UnixFile(deviceFilePath, UnixFileMode.ReadWrite))) + {} + + /// + /// Dispose instance and free all resources. + /// + public void Dispose() { + GC.SuppressFinalize(this); + Dispose(true); + } + + /// + /// Disposes the instance. + /// + /// If true all managed resources will be disposed + protected virtual void Dispose(bool disposing) { + if (disposing) { + deviceFile.Dispose(); + } + } + + #endregion + + #region Properties + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. + /// + public UInt16 Delay { + get { return delay; } + } + + /// + /// Maximum clock speed in Hz. + /// + public UInt32 MaxSpeed { + get { return maxSpeed; } + } + + /// + /// SPI mode + /// + public SpiMode Mode { + get { return (SpiMode)mode; } + } + + /// + /// The device's wordsize + /// + public byte BitsPerWord { + get { return bitsPerWord; } + } + #endregion + + #region Methods + /// + /// Sets the . + /// + /// Delay in µsec. + public void SetDelay(UInt16 delayInMicroSeconds) { + delay = delayInMicroSeconds; + } + + /// + /// Sets the maximum clock speed. + /// + /// The speed in Hz + public void SetMaxSpeed(UInt32 maxSpeedInHz) { + maxSpeed = maxSpeedInHz; + deviceFile.Control(SPI_IOC_WR_MAX_SPEED_HZ, ref maxSpeedInHz) + .ThrowOnPInvokeError("Can't set max speed in HZ (SPI_IOC_WR_MAX_SPEED_HZ). Error {1}: {2}"); + deviceFile.Control(SPI_IOC_RD_MAX_SPEED_HZ, ref maxSpeedInHz) + .ThrowOnPInvokeError("Can't set max speed in HZ (SPI_IOC_RD_MAX_SPEED_HZ). Error {1}: {2}"); + } + + /// + /// Sets the device's wordsize . + /// + /// Bits per word + public void SetBitsPerWord(byte wordSize) { + bitsPerWord = wordSize; + deviceFile.Control(SPI_IOC_WR_BITS_PER_WORD, ref wordSize) + .ThrowOnPInvokeError("Can't set bits per word (SPI_IOC_WR_BITS_PER_WORD). Error {1}: {2}"); + deviceFile.Control(SPI_IOC_RD_BITS_PER_WORD, ref wordSize) + .ThrowOnPInvokeError("Can't set bits per word (SPI_IOC_RD_BITS_PER_WORD). Error {1}: {2}"); + } + + /// + /// Sets the . + /// + /// SPI mode + public void SetSpiMode(SpiMode spiMode) { + mode = (UInt32) spiMode; + deviceFile.Control(SPI_IOC_WR_MODE, ref mode) + .ThrowOnPInvokeError("Can't set SPI mode (SPI_IOC_WR_MODE). Error {1}: {2}"); + deviceFile.Control(SPI_IOC_RD_MODE, ref mode) + .ThrowOnPInvokeError("Can't set SPI mode (SPI_IOC_RD_MODE). Error {1}: {2}"); + } + + /// + /// Creates a transfer buffer of the given and copies the connection settings to it. + /// + /// Memory size in bytes. + /// The transfer mode. + /// The requested transfer buffer. + public ISpiTransferBuffer CreateTransferBuffer(int sizeInBytes, SpiTransferMode transferMode) { + return new SpiTransferBuffer(sizeInBytes, transferMode) { + BitsPerWord = bitsPerWord, + Delay = delay, + Speed = maxSpeed + }; + } + + /// + /// Creates transfer buffers for . + /// + /// The number of messages to send. + /// Message size in bytes. + /// The transfer mode. + /// The requested transfer buffer collection. + public ISpiTransferBufferCollection CreateTransferBufferCollection(int numberOfMessages, int messageSizeInBytes, SpiTransferMode transferMode) { + var collection = new SpiTransferBufferCollection(numberOfMessages, messageSizeInBytes, transferMode); + foreach (var transferBuffer in collection) { + transferBuffer.BitsPerWord = bitsPerWord; + transferBuffer.Delay = delay; + transferBuffer.Speed = maxSpeed; + } + return collection; + } + + /// + /// Starts the SPI data transfer. + /// + /// The transfer buffer that contains data to be send and/or the received data. + /// An that contains the result of the transfer operation. + public int Transfer(ISpiTransferBuffer buffer) { + if (buffer == null) { + throw new ArgumentNullException("buffer"); + } + + var request = Interop.GetSpiMessageRequest(1); + var structure = buffer.ControlStructure; + var result = deviceFile.Control(request, ref structure); + + result.ThrowOnPInvokeError("Can't send SPI message. Error {1}: {2}"); + + return result; + } + + /// + /// Starts the SPI data transfer. + /// + /// The transfer buffers that contain data to be send and/or the received data. + /// An that contains the result of the transfer operation. + public int Transfer(ISpiTransferBufferCollection transferBuffers) { + if (transferBuffers == null) { + throw new ArgumentNullException("transferBuffers"); + } + + var request = Interop.GetSpiMessageRequest(transferBuffers.Length); + + var structures = transferBuffers + .Select(buf => buf.ControlStructure) + .ToArray(); + var result = deviceFile.Control(request, structures); + + result.ThrowOnPInvokeError("Can't send SPI messages. Error {1}: {2}"); + + return result; + } + + #endregion + + #region Private Helpers + private void Init(SpiConnectionSettings settings) { + SetSpiMode(settings.Mode); + SetBitsPerWord(settings.BitsPerWord); + SetMaxSpeed(settings.MaxSpeed); + SetDelay(settings.Delay); + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs b/Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs index 7945fd9..05277c2 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs +++ b/Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -10,3 +11,6 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("5548a61b-6677-435f-be41-13aa4f05e994")] + +// Make the internal methods, classes etc. visible to the unit test project. +[assembly: InternalsVisibleTo("Tests.Raspberry.IO.SerialPeripheralInterface")] diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj index 4c0bfa3..c52e4de 100644 --- a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj @@ -20,7 +20,7 @@ full false bin\Debug\ - DEBUG;TRACE + TRACE;DEBUG prompt 4 bin\Debug\Raspberry.IO.SerialPeripheralInterface.XML @@ -47,12 +47,33 @@ Properties\SharedAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + {689CB6C4-3D23-45DA-8E00-87C28AEA32D0} + Raspberry.IO.Interop + {D2E41147-5BF6-4109-A497-C76284F3C020} Raspberry.IO diff --git a/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings new file mode 100644 index 0000000..ba0505e --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings @@ -0,0 +1,6 @@ + + True + True + True + True + True \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiConnectionSettings.cs b/Raspberry.IO.SerialPeripheralInterface/SpiConnectionSettings.cs new file mode 100644 index 0000000..3afc483 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/SpiConnectionSettings.cs @@ -0,0 +1,48 @@ +using System; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// SPI connection parameters + /// + public class SpiConnectionSettings + { + #region Fields + private uint maxSpeed = 5000000; + private ushort delay; + private byte bitsPerWord = 8; + #endregion + + #region Properties + /// + /// Clock speed in Hz + /// + public UInt32 MaxSpeed { + get { return maxSpeed; } + set { maxSpeed = value; } + } + + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer + /// + public UInt16 Delay { + get { return delay; } + set { delay = value; } + } + + /// + /// The device's word size + /// + public byte BitsPerWord { + get { return bitsPerWord; } + set { bitsPerWord = value; } + } + + /// + /// SPI mode + /// + public SpiMode Mode { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs new file mode 100644 index 0000000..e61ffc0 --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs @@ -0,0 +1,176 @@ +using System; +using Raspberry.IO.Interop; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// A transfer buffer used to read from / write to the SPI bus. + /// + public class SpiTransferBuffer : ISpiTransferBuffer + { + #region Fields + private readonly IMemory txBuf; + private readonly IMemory rxBuf; + + private readonly SpiTransferMode mode; + private SpiTransferControlStructure control; + + #endregion + + #region Properties + + /// + /// Temporary override of the device's wordsize + /// + public byte BitsPerWord { + get { return control.BitsPerWord; } + set { control.BitsPerWord = value; } + } + + /// + /// Temporary override of the device's bitrate (in Hz) + /// + public UInt32 Speed { + get { return control.Speed; } + set { control.Speed = value; } + } + + /// + /// If nonzero, how long to delay (in µ seconds) after the last bit transfer before optionally deselecting the device before the next transfer. + /// + public UInt16 Delay { + get { return control.Delay; } + set { control.Delay = value; } + } + + /// + /// Set to true to deselect device before starting the next transfer. + /// + public bool ChipSelectChange { + get { return control.ChipSelectChange == 1; } + set { + control.ChipSelectChange = value + ? (byte) 1 + : (byte) 0; + } + } + + /// + /// Pad + /// + public UInt32 Pad { + get { return control.Pad; } + set { control.Pad = value; } + } + + /// + /// Specifies if the transfer shall read and/or write. + /// + public SpiTransferMode TransferMode { + get { return mode; } + } + + /// + /// Length of and buffers, in bytes + /// + public int Length { + get { return unchecked((int)control.Length); } + } + + /// + /// Holds pointer to userspace buffer with transmit data, or null. If no data is provided, zeroes are shifted out + /// + public IMemory Tx { + get { return txBuf; } + } + + /// + /// Holds pointer to userspace buffer for receive data, or null + /// + public IMemory Rx { + get { return rxBuf; } + } + + /// + /// The IOCTL structure that contains control information for a single SPI transfer + /// + public SpiTransferControlStructure ControlStructure { + get { return control; } + } + + #endregion + + #region Instance Management + /// + /// Initializes a new instance of the class. + /// + /// Size of data that shall be transmitted. + /// Specifies read and/or write mode. + public SpiTransferBuffer(int lengthInBytes, SpiTransferMode transferMode) { + if (transferMode == 0) { + throw new ArgumentException("An appropriate transfer mode must be specified (read/write)", + "transferMode"); + } + + mode = transferMode; + + if ((TransferMode & SpiTransferMode.Write) == SpiTransferMode.Write) { + txBuf = new ManagedMemory(lengthInBytes); + } + if ((TransferMode & SpiTransferMode.Read) == SpiTransferMode.Read) { + rxBuf = new ManagedMemory(lengthInBytes); + } + + var txPtr = ReferenceEquals(Tx, null) + ? 0 + : unchecked((UInt64) Tx.Pointer.ToInt64()); + + var rxPtr = ReferenceEquals(Rx, null) + ? 0 + : unchecked((UInt64) Rx.Pointer.ToInt64()); + + control.Length = unchecked((uint)lengthInBytes); + control.Tx = txPtr; + control.Rx = rxPtr; + } + + /// + /// Finalizer for + /// + ~SpiTransferBuffer() { + Dispose(false); + GC.SuppressFinalize(this); + } + + /// + /// Release all unmanaged memory. + /// + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose the instance. + /// + /// The memory will always be released to avoid memory leaks. If you don't want this, don't call this method () in your derived class. + protected virtual void Dispose(bool disposing) { + if (disposing) { + // free managed stuff here + } + + control.Rx = 0; + control.Tx = 0; + control.Length = 0; + + // always free managed/unmanaged memory + if (!ReferenceEquals(txBuf, null)) { + txBuf.Dispose(); + } + if (!ReferenceEquals(rxBuf, null)) { + rxBuf.Dispose(); + } + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs new file mode 100644 index 0000000..133986d --- /dev/null +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Raspberry.IO.SerialPeripheralInterface +{ + /// + /// A collection of transfer buffers that can be used to read from / write to the SPI bus. + /// + public class SpiTransferBufferCollection : ISpiTransferBufferCollection + { + #region Fields + private ISpiTransferBuffer[] transferBuffers; + #endregion + + #region Instance Management + /// + /// Initializes a new instance of the class. + /// + /// Number of tranfer messages + /// Message size in bytes + /// Transfer mode + public SpiTransferBufferCollection(int numberOfMessages, int messageLengthInBytes, SpiTransferMode transferMode) { + if (numberOfMessages <= 0) { + throw new ArgumentOutOfRangeException("numberOfMessages"); + } + + transferBuffers = new ISpiTransferBuffer[numberOfMessages]; + for (var i = 0; i < numberOfMessages; i++) { + transferBuffers[i] = new SpiTransferBuffer(messageLengthInBytes, transferMode); + } + } + + /// + /// Finalizer for + /// + ~SpiTransferBufferCollection() { + Dispose(false); + } + + /// + /// Disposes the collection of . + /// + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose the collection of . + /// + /// If true all transfer buffers will be disposed. + protected virtual void Dispose(bool disposing) { + if (disposing) { + foreach (var buffer in transferBuffers) { + buffer.Dispose(); + } + transferBuffers = new ISpiTransferBuffer[0]; + } + } + #endregion + + #region Properties + /// + /// Number of structures. + /// + public int Length { + get { return transferBuffers.Length; } + } + + /// + /// Can be used to request a specific from the collection. + /// + /// Index + /// The requested + public ISpiTransferBuffer this[int index] { + get { return transferBuffers[index]; } + } + #endregion + + #region Methods + /// + /// A method that returns a specific from the collection. + /// + /// Index + /// The requested + public ISpiTransferBuffer Get(int index) { + return transferBuffers[index]; + } + + /// + /// Returns an enumerator. + /// + /// An enumerator + public IEnumerator GetEnumerator() { + return transferBuffers.OfType().GetEnumerator(); + } + + /// + /// Returns an enumerator. + /// + /// An enumerator + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + #endregion + } +} \ No newline at end of file diff --git a/Raspberry.IO.nuspec b/Raspberry.IO.nuspec index 4a122fe..cef409b 100644 --- a/Raspberry.IO.nuspec +++ b/Raspberry.IO.nuspec @@ -35,6 +35,10 @@ + + + + diff --git a/Raspberry.IO/ByteExtensionMethods.cs b/Raspberry.IO/ByteExtensionMethods.cs new file mode 100644 index 0000000..f8d1434 --- /dev/null +++ b/Raspberry.IO/ByteExtensionMethods.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Raspberry.IO +{ + /// + /// Provides extension methods for byte and byte arrays. + /// + public static class ByteExtensionMethods + { + /// + /// Converts a byte array/enumerable to a bit string. + /// + /// bytes to be converted. + /// A bit string + public static string ToBitString(this IEnumerable bytes) { + var sb = new StringBuilder(255); + foreach (var value in bytes.Select(@byte => Convert.ToString(@byte, 2))) { + if (value.Length < 8) { + sb.Append(new string('0', 8 - value.Length)); + } + sb.Append(value); + } + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Raspberry.IO/Raspberry.IO.csproj b/Raspberry.IO/Raspberry.IO.csproj index c89b011..0e7cdaa 100644 --- a/Raspberry.IO/Raspberry.IO.csproj +++ b/Raspberry.IO/Raspberry.IO.csproj @@ -46,11 +46,13 @@ Properties\SharedAssemblyInfo.cs + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711DeviceSpecs.cs b/UnitTests/Tests.Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711DeviceSpecs.cs new file mode 100644 index 0000000..af96d2b --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711DeviceSpecs.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using Raspberry.IO; +using Raspberry.IO.Components.Controllers.Tlc59711; +using Raspberry.IO.Interop; + +// ReSharper disable CheckNamespace +// ReSharper disable InconsistentNaming + +namespace Tests.Raspberry.IO.Components.Controllers.Tlc59711.Tlc59711DeviceSpecs +{ + [TestFixture] + public class If_the_user_creates_a_new_device_instance_with_default_settings : Spec + { + private const int COMMAND_SIZE = 28; + private const int NUMBER_OF_CHANNELS = 12; + private const int PWM_WORDSIZE = 2; + // 0x25, OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 1, BCB=0x7f, BCG=0x7f, BCR=0x7f + private const string EXPECTED_SETTINGS = "10010110111111111111111111111111"; + + private IMemory memory; + private ITlc59711Device device; + + protected override void EstablishContext() { + memory = new ManagedMemory(COMMAND_SIZE); + } + + protected override void BecauseOf() { + device = new Tlc59711Device(memory); + } + + [Test] + public void Should_the_device_set_to_BLANK() { + device.Blank.Should().BeTrue(); + } + + [Test] + public void Should_OUTTMG_set_to_TRUE() { + device.ReferenceClockEdge.Should().BeTrue(); + } + + [Test] + public void Should_EXTGCK_set_to_FALSE() { + device.ReferenceClock.Should().BeFalse(); + } + + [Test] + public void Should_TMGRST_set_to_TRUE() { + device.DisplayTimingResetMode.Should().BeTrue(); + } + + [Test] + public void Should_DSPRPT_set_to_TRUE() { + device.DisplayRepeatMode.Should().BeTrue(); + } + + [Test] + public void Should_the_memory_be_correctly_initialized() { + var expected_settings = EXPECTED_SETTINGS.BitStringToArray(true); + memory.Take(4) + .Should() + .ContainInOrder(expected_settings); + } + + [Test] + public void Should_all_channels_set_to_0x0000() { + memory.Skip(4) + .ToArray() + .Should() + .ContainInOrder(new byte[PWM_WORDSIZE * NUMBER_OF_CHANNELS]); + } + + protected override void Cleanup() { + if (!ReferenceEquals(memory, null)) { + memory.Dispose(); + memory = null; + } + } + } + + [TestFixture] + public class If_the_user_creates_a_new_device_instance_using_his_own_settings_settings : Spec + { + private const int COMMAND_SIZE = 28; + // 0x25, OUTTMG = 0, EXTGCK = 1, TMGRST = 0, DSPRPT = 0, BLANK = 0, BCB=0x00, BCG=0x00, BCR=0x00 + private const string EXPECTED_SETTINGS = "10010101000000000000000000000000"; + + private IMemory memory; + private ITlc59711Device device; + private ITlc59711Settings settings; + + protected override void EstablishContext() { + memory = new ManagedMemory(COMMAND_SIZE); + settings = new Tlc59711Settings { + Blank = false, + ReferenceClockEdge = false, + ReferenceClock = true, + DisplayTimingResetMode = false, + DisplayRepeatMode = false, + BrightnessControlB = 0, + BrightnessControlG = 0, + BrightnessControlR = 0 + }; + } + + protected override void BecauseOf() { + device = new Tlc59711Device(memory, settings); + } + + [Test] + public void Should_the_device_set_to_not_BLANK() { + device.Blank.Should().BeFalse(); + } + + [Test] + public void Should_OUTTMG_set_to_FALSE() { + device.ReferenceClockEdge.Should().BeFalse(); + } + + [Test] + public void Should_EXTGCK_set_to_TRUE() { + device.ReferenceClock.Should().BeTrue(); + } + + [Test] + public void Should_TMGRST_set_to_FALSE() { + device.DisplayTimingResetMode.Should().BeFalse(); + } + + [Test] + public void Should_DSPRPT_set_to_FALSE() { + device.DisplayRepeatMode.Should().BeFalse(); + } + + [Test] + public void Should_the_memory_be_correctly_initialized() { + var expected_settings = EXPECTED_SETTINGS.BitStringToArray(true); + memory.Take(4) + .Should() + .ContainInOrder(expected_settings); + } + + protected override void Cleanup() { + if (!ReferenceEquals(memory, null)) { + memory.Dispose(); + memory = null; + } + } + } + + [TestFixture] + public class If_the_user_changes_a_setting_after_initialization : Spec + { + private class TestCase : TestCaseData + { + public TestCase(string description, Action action) + : base(description, action) {} + } + + private const int COMMAND_SIZE = 28; + + private static IEnumerable TestCases { + get { + // MAGIC_WORD, OUTTMG, EXTGCK, TMGRST, DSPRPT, BLANK, BCB, BCG, BCR + yield return new TestCase("do nothing", s => { }) + .Returns("10010110111111111111111111111111"); + yield return new TestCase("Blank", s => s.Blank = false) + .Returns("10010110110111111111111111111111"); + yield return new TestCase("BrightnessControlR", s => s.BrightnessControlR = 0) + .Returns("10010110111111111111111110000000"); + yield return new TestCase("BrightnessControlG", s => s.BrightnessControlG = 0) + .Returns("10010110111111111100000001111111"); + yield return new TestCase("BrightnessControlB", s => s.BrightnessControlB = 0) + .Returns("10010110111000000011111111111111"); + yield return new TestCase("DisplayRepeatMode", s => s.DisplayRepeatMode = false) + .Returns("10010110101111111111111111111111"); + yield return new TestCase("DisplayTimingResetMode", s => s.DisplayTimingResetMode = false) + .Returns("10010110011111111111111111111111"); + yield return new TestCase("ReferenceClock", s => s.ReferenceClock = true) + .Returns("10010111111111111111111111111111"); + yield return new TestCase("ReferenceClockEdge", s => s.ReferenceClockEdge = false) + .Returns("10010100111111111111111111111111"); + } + } + + [Test, TestCaseSource("TestCases")] + public string Should_the_resulting_memory_be_correct(string description, Action action) { + using (var memory = new ManagedMemory(COMMAND_SIZE)) { + var device = new Tlc59711Device(memory); + action(device); + + Debug.Print("Running action on: {0}", description); + return memory + .Take(4) + .ToBitString(); + } + } + } + + [TestFixture] + public class If_the_user_changes_PWM_data_after_initialization : Spec + { + private const int NUMBER_OF_CHANNELS = 12; + private const int PWM_WORDSIZE = 2; + private const int COMMAND_SIZE = 28; + private const UInt16 VALUE = 0x1234; + + private static IEnumerable TestCases { + get { + for (var i = 0; i < NUMBER_OF_CHANNELS; i++) { + yield return new TestCaseData(i, VALUE) + .Returns(new byte[] {0x12, 0x34}); + } + } + } + + [Test,TestCaseSource("TestCases")] + public byte[] Should_the_memory_be_set_to_the_correct_values(int channel, UInt16 value) { + using (var memory = new ManagedMemory(COMMAND_SIZE)) { + var device = new Tlc59711Device(memory); + + device.Channels.Set(channel, value); + return memory + .Skip(4 + (channel * PWM_WORDSIZE)) + .Take(2) + .ToArray(); + } + } + } +} \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/Properties/AssemblyInfo.cs b/UnitTests/Tests.Raspberry.IO.Components/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b1b09ea --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Components/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("Tests.Raspberry.IO.Components")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tests.Raspberry.IO.Components")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("be948e15-5643-48a1-a32b-f5b98c6cc831")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj new file mode 100644 index 0000000..cc3c267 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Components/Tests.Raspberry.IO.Components.csproj @@ -0,0 +1,91 @@ + + + + + Debug + AnyCPU + {99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} + Library + Properties + Tests.Raspberry.IO.Components + Tests.Raspberry.IO.Components + v4.0 + 512 + + ..\..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + + + ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + {8388cfca-e3db-43f7-b049-2cb195211ce8} + Raspberry.IO.Components + + + {689cb6c4-3d23-45da-8e00-87c28aea32d0} + Raspberry.IO.Interop + + + {326342e5-0411-40e8-9f2d-563d6b192568} + Raspberry.IO.SerialPeripheralInterface + + + {ace64f17-87e5-43e7-97a0-bdde19059c61} + Raspberry.IO + + + {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + Tests.Raspberry.IO + + + + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Components/packages.config b/UnitTests/Tests.Raspberry.IO.Components/packages.config new file mode 100644 index 0000000..277a3fb --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Components/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/MemorySubsetSpecs.cs b/UnitTests/Tests.Raspberry.IO.Interop/MemorySubsetSpecs.cs new file mode 100644 index 0000000..9ec0917 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Interop/MemorySubsetSpecs.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using Raspberry.IO.Interop; + +// ReSharper disable CheckNamespace +// ReSharper disable InconsistentNaming + +namespace Tests.Raspberry.IO.Interop.MemorySubsetSpecs +{ + [TestFixture] + public class If_the_user_tries_to_create_a_subset_that_exceeds_the_memory_boundaries : Spec { + private ManagedMemory managedMemory; + + protected override void EstablishContext() { + managedMemory = new ManagedMemory(10); + } + + private static IEnumerable TestCases { + get { + yield return new TestCaseData(11, 1).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(0, 11).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(-1, 10).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(10, 1).Throws(typeof(ArgumentOutOfRangeException)); + } + } + + [Test,TestCaseSource("TestCases")] + public IMemory Should_it_throw_an_exception(int startOffset, int length) { + return new MemorySubset(managedMemory, startOffset, length, false); + } + + protected override void Cleanup() { + if (managedMemory != null) { + managedMemory.Dispose(); + managedMemory = null; + } + } + } + + [TestFixture] + public class If_the_user_tries_to_copy_data_to_a_memory_subset_exceeding_the_memory_boundaries : Spec { + private ManagedMemory managedMemory; + private MemorySubset subset; + + protected override void EstablishContext() { + managedMemory = new ManagedMemory(10); + subset = new MemorySubset(managedMemory, 2, 4, true); + } + + private static IEnumerable TestCases { + get { + yield return new TestCaseData(4, 1).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(0, 5).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(-1, 2).Throws(typeof(ArgumentOutOfRangeException)); + } + } + + [Test, TestCaseSource("TestCases")] + public void Should_it_throw_an_exception(int startOffset, int length) { + var data = new byte[length]; + subset.Copy(data, 0, startOffset, length); + } + + protected override void Cleanup() { + if (subset != null) { + subset.Dispose(); + subset = null; + } + } + } + + [TestFixture] + public class If_the_user_copies_data_to_a_memory_subset : Spec { + private ManagedMemory managedMemory; + private MemorySubset subset; + + protected override void EstablishContext() { + managedMemory = new ManagedMemory(10); + subset = new MemorySubset(managedMemory, 2, 4, true); + } + + protected override void BecauseOf() { + var data = new byte[] {0x1, 0x2, 0x3, 0x4}; + subset.Copy(data, 0, 0, data.Length); + } + + [Test] + public void Should_the_origin_memory_contain_the_correct_data() { + managedMemory.ToArray().Should().ContainInOrder(new byte[] { + 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0 + }); + } + + protected override void Cleanup() { + if (subset != null) { + subset.Dispose(); + subset = null; + } + } + } + + [TestFixture] + public class If_the_user_writes_data_to_a_memory_subset : Spec + { + private static IEnumerable TestCases { + get { + yield return new TestCaseData(-1, 0x1).Throws(typeof(ArgumentOutOfRangeException)); + + yield return new TestCaseData(0, 0x1).Returns(new byte[] { + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }); + + yield return new TestCaseData(1, 0x1).Returns(new byte[] { + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }); + + yield return new TestCaseData(2, 0x1).Returns(new byte[] { + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0 + }); + + yield return new TestCaseData(3, 0x1).Returns(new byte[] { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0 + }); + + yield return new TestCaseData(4, 0x1).Throws(typeof(ArgumentOutOfRangeException)); + } + } + + [Test,TestCaseSource("TestCases")] + public byte[] Should_the_origin_memory_contain_the_correct_data_when_using_the_WRITE_method(int startOffset, int value) { + using (var managedMemory = new ManagedMemory(10)) { + using (var subset = new MemorySubset(managedMemory, 2, 4, false)) { + subset.Write(startOffset, (byte) value); + return managedMemory.ToArray(); + } + } + } + + [Test, TestCaseSource("TestCases")] + public byte[] Should_the_origin_memory_contain_the_correct_data_when_using_the_INDEXER_method(int startOffset, int value) { + using (var managedMemory = new ManagedMemory(10)) { + using (var subset = new MemorySubset(managedMemory, 2, 4, false)) { + subset[startOffset] = (byte) value; + return managedMemory.ToArray(); + } + } + } + } + + [TestFixture] + public class If_the_user_reads_data_from_a_memory_subset : Spec { + private ManagedMemory managedMemory; + private readonly byte[] content = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + private MemorySubset subset; + + protected override void EstablishContext() { + managedMemory = new ManagedMemory(10); + managedMemory.Copy(content, 0, 0, 10); + subset = new MemorySubset(managedMemory, 2, 4, true); + } + + private static IEnumerable TestCases { + get { + yield return new TestCaseData(-1).Throws(typeof(ArgumentOutOfRangeException)); + yield return new TestCaseData(0).Returns((byte) 0x2); + yield return new TestCaseData(1).Returns((byte) 0x3); + yield return new TestCaseData(2).Returns((byte) 0x4); + yield return new TestCaseData(3).Returns((byte) 0x5); + yield return new TestCaseData(4).Throws(typeof(ArgumentOutOfRangeException)); + } + } + + [Test,TestCaseSource("TestCases")] + public byte Should_the_result_be_correct_when_using_the_READ_method(int startOffset) { + return subset[startOffset]; + } + + [Test, TestCaseSource("TestCases")] + public byte Should_the_result_be_correct_when_using_the_INDEXER_method(int startOffset) { + return subset[startOffset]; + } + + protected override void Cleanup() { + if (subset != null) { + subset.Dispose(); + subset = null; + } + } + } +} \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Properties/AssemblyInfo.cs b/UnitTests/Tests.Raspberry.IO.Interop/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f54f9d3 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Interop/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("Tests.Raspberry.IO.Interop")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tests.Raspberry.IO.Interop")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("1281d04f-7151-40bf-b80e-ebe7c7bfb3a3")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj new file mode 100644 index 0000000..6b0183d --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Interop/Tests.Raspberry.IO.Interop.csproj @@ -0,0 +1,83 @@ + + + + + Debug + AnyCPU + {CAF876A0-0FCB-44F7-96F1-53704CB6015F} + Library + Properties + Tests.Raspberry.IO.Interop + Tests.Raspberry.IO.Interop + v4.0 + 512 + + ..\..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + + + ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + {689cb6c4-3d23-45da-8e00-87c28aea32d0} + Raspberry.IO.Interop + + + {ace64f17-87e5-43e7-97a0-bdde19059c61} + Raspberry.IO + + + {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + Tests.Raspberry.IO + + + + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.Interop/packages.config b/UnitTests/Tests.Raspberry.IO.Interop/packages.config new file mode 100644 index 0000000..277a3fb --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.Interop/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Interop/InteropSpec.cs b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Interop/InteropSpec.cs new file mode 100644 index 0000000..14fcbf5 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Interop/InteropSpec.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections; +using System.Diagnostics; +using NUnit.Framework; +using Raspberry.IO.SerialPeripheralInterface; + +// ReSharper disable InconsistentNaming +// ReSharper disable once CheckNamespace +namespace Tests.Raspberry.IO.SerialPeripheralInterface.InteropSpec +{ + [TestFixture] + public class If_the_user_requests_the_size_of_N_spi_transfer_messages : Spec { + private static IEnumerable TestCases { + get { + yield return new TestCaseData(0).Returns(Interop.SPI_IOC_MESSAGE_BASE); + yield return new TestCaseData(1).Returns((UInt32)0x40206b00); + yield return new TestCaseData(2).Returns((UInt32)0x40406b00); + yield return new TestCaseData(3).Returns((UInt32)0x40606b00); + } + } + + [Test,TestCaseSource("TestCases")] + public UInt32 Shall_the_result_be_correct(int numberOfMessages) { + var result = Interop.GetSpiMessageRequest(numberOfMessages); + Debug.Print("SPI_IOC_MESSAGE({0}) = {1:x}", numberOfMessages, result); + return result; + } + } +} diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/NativeSpiConnectionSpecs.cs b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/NativeSpiConnectionSpecs.cs new file mode 100644 index 0000000..a8b4eaf --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/NativeSpiConnectionSpecs.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FakeItEasy; +using FakeItEasy.ExtensionSyntax.Full; +using FluentAssertions; +using NUnit.Framework; +using Raspberry.IO.Interop; +using Raspberry.IO.SerialPeripheralInterface; + +// ReSharper disable once CheckNamespace +// ReSharper disable InconsistentNaming +namespace Tests.Raspberry.IO.SerialPeripheralInterface.NativeSpiConnectionSpecs +{ + [TestFixture] + public class If_the_user_creates_a_native_SPI_connection_instance_providing_appropriate_connection_settings : Spec { + private const int BITS_PER_WORD = 8; + private const int DELAY = 500; + private const SpiMode SPI_MODE = SpiMode.Mode2; + private const int SPEED_IN_HZ = 500000; + + private SpiConnectionSettings settings; + private NativeSpiConnection connection; + private IControlDevice controlDevice; + + protected override void EstablishContext() { + settings = new SpiConnectionSettings { + BitsPerWord = BITS_PER_WORD, + Delay = DELAY, + Mode = SPI_MODE, + MaxSpeed = SPEED_IN_HZ + }; + + controlDevice = A.Fake(); + } + + protected override void BecauseOf() { + connection = new NativeSpiConnection(controlDevice, settings); + } + + [Test] + public void Should_it_write_the_max_speed_in_Hz_to_the_control_device() { + UInt32 speed = SPEED_IN_HZ; + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_WR_MAX_SPEED_HZ, ref speed)) + .MustHaveHappened(Repeated.Exactly.Once); + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_RD_MAX_SPEED_HZ, ref speed)) + .MustHaveHappened(Repeated.Exactly.Once); + } + + [Test] + public void Should_it_write_the_bits_per_word_to_the_control_device() { + byte bitsPerWord = BITS_PER_WORD; + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_WR_BITS_PER_WORD, ref bitsPerWord)) + .MustHaveHappened(Repeated.Exactly.Once); + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_RD_BITS_PER_WORD, ref bitsPerWord)) + .MustHaveHappened(Repeated.Exactly.Once); + } + + [Test] + public void Should_it_write_the_spi_mode_to_the_control_device() { + var spiMode = (UInt32)SPI_MODE; + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_WR_MODE, ref spiMode)) + .MustHaveHappened(Repeated.Exactly.Once); + + controlDevice + .CallsTo(device => device.Control(NativeSpiConnection.SPI_IOC_RD_MODE, ref spiMode)) + .MustHaveHappened(Repeated.Exactly.Once); + } + + [Test] + public void Should_it_set_the_delay() { + connection.Delay.Should().Be(DELAY); + } + + [Test] + public void Should_it_set_the_speed() { + connection.MaxSpeed.Should().Be(SPEED_IN_HZ); + } + + [Test] + public void Should_it_set_the_SPI_mode() { + connection.Mode.Should().Be(SPI_MODE); + } + + [Test] + public void Should_it_set_the_bits_per_word() { + connection.BitsPerWord.Should().Be(BITS_PER_WORD); + } + } + + [TestFixture] + public class If_the_user_requests_a_spi_transfer_buffer : Spec { + private const int BITS_PER_WORD = 16; + private const int DELAY = 500; + private const SpiMode SPI_MODE = SpiMode.Mode2; + private const int SPEED_IN_HZ = 500000; + private const int REQUESTED_SIZE = 100; + + private SpiConnectionSettings settings; + private IControlDevice controlDevice; + private NativeSpiConnection connection; + private ISpiTransferBuffer buffer; + + protected override void EstablishContext() { + settings = new SpiConnectionSettings { + BitsPerWord = BITS_PER_WORD, + Delay = DELAY, + Mode = SPI_MODE, + MaxSpeed = SPEED_IN_HZ + }; + + controlDevice = A.Fake(); + connection = new NativeSpiConnection(controlDevice, settings); + } + + protected override void BecauseOf() { + buffer = connection.CreateTransferBuffer(REQUESTED_SIZE, SpiTransferMode.ReadWrite); + } + + [Test] + public void Should_the_buffer_be_initialized_with_the_connections_wordsize() { + buffer.ControlStructure.BitsPerWord.Should().Be(BITS_PER_WORD); + } + + [Test] + public void Should_the_buffer_be_initialized_with_the_connections_delay() { + buffer.ControlStructure.Delay.Should().Be(DELAY); + } + + [Test] + public void Should_the_buffer_be_initialized_with_the_connections_speed() { + buffer.ControlStructure.Speed.Should().Be(SPEED_IN_HZ); + } + + protected override void Cleanup() { + if (!ReferenceEquals(buffer, null)) { + buffer.Dispose(); + buffer = null; + } + } + } + + [TestFixture] + public class If_the_user_starts_a_single_data_transfer : Spec { + private const int BITS_PER_WORD = 16; + private const int DELAY = 500; + private const int SPEED_IN_HZ = 500000; + private const int IOCTL_PINVOKE_RESULT_CODE = 1; + private const int SPI_IOC_MESSAGE_1 = 0x40206b00; + + private IControlDevice controlDevice; + private NativeSpiConnection connection; + private ISpiTransferBuffer buffer; + private int result; + private SpiTransferControlStructure controlStructure; + + protected override void EstablishContext() { + // SPI control structure we expect to see during the P/Invoke call + controlStructure = new SpiTransferControlStructure { + BitsPerWord = BITS_PER_WORD, + Length = 5, + Delay = DELAY, + ChipSelectChange = 1, + Speed = SPEED_IN_HZ + }; + + controlDevice = A.Fake(); + controlDevice + .CallsTo(device => device.Control(A.Ignored, ref controlStructure)) + .WithAnyArguments() + .Returns(IOCTL_PINVOKE_RESULT_CODE); + + connection = new NativeSpiConnection(controlDevice); + + buffer = A.Fake(); + buffer + .CallsTo(b => b.ControlStructure) + .Returns(controlStructure); + } + + protected override void BecauseOf() { + result = connection.Transfer(buffer); + } + + [Test] + public void Should_the_buffers_control_structure_be_sent_to_the_IOCTL_device() { + controlDevice + .CallsTo(device => device.Control(SPI_IOC_MESSAGE_1, ref controlStructure)) + .MustHaveHappened(Repeated.Exactly.Once); + } + + [Test] + public void Should_it_return_the_pinvoke_result_code() { + result.Should().Be(IOCTL_PINVOKE_RESULT_CODE); + } + } + + [TestFixture] + public class If_the_user_starts_a_multi_data_transfer : Spec + { + private const int BITS_PER_WORD = 16; + private const int DELAY = 500; + private const int SPEED_IN_HZ = 500000; + private const int IOCTL_PINVOKE_RESULT_CODE = 1; + private const int SPI_IOC_MESSAGE_1 = 0x40206b00; + + private IControlDevice controlDevice; + private NativeSpiConnection connection; + private ISpiTransferBufferCollection collection; + private ISpiTransferBuffer buffer; + private int result; + private SpiTransferControlStructure controlStructure; + + protected override void EstablishContext() { + controlDevice = A.Fake(); + controlDevice + .CallsTo(device => device.Control(A.Ignored, A.Ignored)) + .Returns(IOCTL_PINVOKE_RESULT_CODE); + + connection = new NativeSpiConnection(controlDevice); + + // SPI control structure we expect to see during the P/Invoke call + controlStructure = new SpiTransferControlStructure { + BitsPerWord = BITS_PER_WORD, + Length = 5, + Delay = DELAY, + ChipSelectChange = 1, + Speed = SPEED_IN_HZ + }; + + buffer = A.Fake(); + buffer + .CallsTo(b => b.ControlStructure) + .Returns(controlStructure); + + // setup fake collection to return our "prepared" fake buffer + collection = A.Fake(); + collection + .CallsTo(c => c.Length) + .Returns(1); + collection + .CallsTo(c => c.GetEnumerator()) + .ReturnsLazily(call => new List{buffer}.GetEnumerator()); + } + + protected override void BecauseOf() { + result = connection.Transfer(collection); + } + + [Test] + public void Should_the_buffers_control_structure_be_sent_to_the_IOCTL_device() { + controlDevice + .CallsTo(device => device.Control(SPI_IOC_MESSAGE_1, A.That.Matches(s => Predicate(s)))) + .MustHaveHappened(Repeated.Exactly.Once); + } + + private bool Predicate(IEnumerable control_structures) { + return control_structures.Contains(controlStructure); + } + + [Test] + public void Should_it_return_the_pinvoke_result_code() { + result.Should().Be(IOCTL_PINVOKE_RESULT_CODE); + } + } + +} \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..306c84b --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("Tests.Raspberry.IO.SerialPeripheralInterface")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tests.Raspberry.IO.SerialPeripheralInterface")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("904914b3-5dcc-4874-9f74-e6ac2d836716")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs new file mode 100644 index 0000000..69aea5c --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferSpecs.cs @@ -0,0 +1,247 @@ +using System; +using FluentAssertions; +using NUnit.Framework; +using Raspberry.IO.SerialPeripheralInterface; + +// ReSharper disable once CheckNamespace +// ReSharper disable InconsistentNaming +namespace Tests.Raspberry.IO.SerialPeripheralInterface.SpiTransferBufferSpecs +{ + [TestFixture] + public class If_the_user_creates_an_spi_transfer_buffer_for_transmission_only : Spec { + private const int REQUESTED_SIZE = 500; + private ISpiTransferBuffer buffer; + + protected override void BecauseOf() { + buffer = new SpiTransferBuffer(REQUESTED_SIZE, SpiTransferMode.Write); + } + + [Test] + public void Should_the_structure_contain_a_memory_buffer_for_transmission_data() { + buffer.Tx.Should().NotBeNull(); + } + + [Test] + public void Should_the_structure_contain_no_memory_buffer_to_receive_data() { + buffer.Rx.Should().BeNull(); + } + + [Test] + public void Should_the_buffer_size_be_equal_to_the_requested_size() { + buffer.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_transmission_data_buffer_size_be_equal_to_the_requested_size() { + buffer.Tx.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_transfer_mode_be_write_only() { + buffer.TransferMode.Should().Be(SpiTransferMode.Write); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_TX() { + buffer.ControlStructure.Tx.Should().Be(unchecked((UInt64) buffer.Tx.Pointer.ToInt64())); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_RX() { + buffer.ControlStructure.Rx.Should().Be(0L); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_length() { + buffer.ControlStructure.Length.Should().Be(REQUESTED_SIZE); + } + + protected override void Cleanup() { + if (!ReferenceEquals(buffer, null)) { + buffer.Dispose(); + buffer = null; + } + } + } + + [TestFixture] + public class If_the_user_creates_an_spi_transfer_buffer_for_receive_only : Spec + { + private const int REQUESTED_SIZE = 500; + private ISpiTransferBuffer buffer; + + protected override void BecauseOf() { + buffer = new SpiTransferBuffer(REQUESTED_SIZE, SpiTransferMode.Read); + } + + [Test] + public void Should_the_structure_contain_no_memory_buffer_for_transmission_data() { + buffer.Tx.Should().BeNull(); + } + + [Test] + public void Should_the_structure_contain_a_memory_buffer_to_receive_data() { + buffer.Rx.Should().NotBeNull(); + } + + [Test] + public void Should_the_buffer_size_be_equal_to_the_requested_size() { + buffer.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_receive_data_buffer_size_be_equal_to_the_requested_size() { + buffer.Rx.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_transfer_mode_be_read_only() { + buffer.TransferMode.Should().Be(SpiTransferMode.Read); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_RX() { + buffer.ControlStructure.Rx.Should().Be(unchecked((UInt64)buffer.Rx.Pointer.ToInt64())); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_TX() { + buffer.ControlStructure.Tx.Should().Be(0L); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_length() { + buffer.ControlStructure.Length.Should().Be(REQUESTED_SIZE); + } + + protected override void Cleanup() { + if (!ReferenceEquals(buffer, null)) { + buffer.Dispose(); + buffer = null; + } + } + } + + [TestFixture] + public class If_the_user_creates_an_spi_transfer_buffer_for_transmission_and_receive : Spec + { + private const int REQUESTED_SIZE = 500; + private ISpiTransferBuffer buffer; + + protected override void BecauseOf() { + buffer = new SpiTransferBuffer(REQUESTED_SIZE, SpiTransferMode.ReadWrite); + } + + [Test] + public void Should_the_structure_contain_a_memory_buffer_for_transmission_data() { + buffer.Tx.Should().NotBeNull(); + } + + [Test] + public void Should_the_structure_contain_a_memory_buffer_to_receive_data() { + buffer.Rx.Should().NotBeNull(); + } + + [Test] + public void Should_the_buffer_size_be_equal_to_the_requested_size() { + buffer.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_transmission_data_buffer_size_be_equal_to_the_requested_size() { + buffer.Tx.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_receive_data_buffer_size_be_equal_to_the_requested_size() { + buffer.Rx.Length.Should().Be(REQUESTED_SIZE); + } + + [Test] + public void Should_the_data_buffers_not_have_the_same_memory_address() { + buffer.Rx.Pointer.Should().NotBe(buffer.Tx.Pointer); + } + + [Test] + public void Should_the_transfer_mode_have_set_the_READ_flag() { + buffer.TransferMode.HasFlag(SpiTransferMode.Read).Should().BeTrue(); + } + + [Test] + public void Should_the_transfer_mode_have_set_the_WRITE_flag() { + buffer.TransferMode.HasFlag(SpiTransferMode.Write).Should().BeTrue(); + } + + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_RX() { + buffer.ControlStructure.Rx.Should().Be(unchecked((UInt64)buffer.Rx.Pointer.ToInt64())); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_address_for_TX() { + buffer.ControlStructure.Tx.Should().Be(unchecked((UInt64)buffer.Tx.Pointer.ToInt64())); + } + + [Test] + public void Should_the_transfer_structure_have_the_correct_memory_length() { + buffer.ControlStructure.Length.Should().Be(REQUESTED_SIZE); + } + + protected override void Cleanup() { + if (!ReferenceEquals(buffer, null)) { + buffer.Dispose(); + buffer = null; + } + } + } + + [TestFixture] + public class If_the_user_changes_various_transfer_settings : Spec { + private const int REQUESTED_SIZE = 100; + private const int REQUESTED_BITS_PER_WORD = 16; + private const bool REQUESTED_CHIP_SELECT_CHANGE = true; + private const int REQUESTED_DELAY_IN_USEC = 100; + private const int REQUESTED_SPEED_IN_HZ = 1000000; + private SpiTransferBuffer buffer; + + protected override void EstablishContext() { + buffer = new SpiTransferBuffer(REQUESTED_SIZE, SpiTransferMode.Write); + } + + protected override void BecauseOf() { + buffer.BitsPerWord = REQUESTED_BITS_PER_WORD; + buffer.ChipSelectChange = REQUESTED_CHIP_SELECT_CHANGE; + buffer.Delay = REQUESTED_DELAY_IN_USEC; + buffer.Speed = REQUESTED_SPEED_IN_HZ; + } + + [Test] + public void Should_the_control_structure_have_the_requested_wordsize() { + buffer.ControlStructure.BitsPerWord.Should().Be(REQUESTED_BITS_PER_WORD); + } + + [Test] + public void Should_the_control_structure_have_the_requested_chip_select_change_value() { + // ReSharper disable once UnreachableCode + buffer.ControlStructure.ChipSelectChange.Should().Be(REQUESTED_CHIP_SELECT_CHANGE ? 1 : 0); + } + + [Test] + public void Should_the_control_structure_have_the_requested_delay() { + buffer.ControlStructure.Delay.Should().Be(REQUESTED_DELAY_IN_USEC); + } + + [Test] + public void Should_the_control_structure_have_the_requested_speed() { + buffer.ControlStructure.Speed.Should().Be(REQUESTED_SPEED_IN_HZ); + } + + protected override void Cleanup() { + if (!ReferenceEquals(buffer, null)) { + buffer.Dispose(); + buffer = null; + } + } + } +} \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj new file mode 100644 index 0000000..99a037c --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj @@ -0,0 +1,89 @@ + + + + + Debug + AnyCPU + {17A2A965-36FA-4CDB-B2D6-AC69C9E9857F} + Library + Properties + Tests.Raspberry.IO.SerialPeripheralInterface + Tests.Raspberry.IO.SerialPeripheralInterface + v4.0 + 512 + ..\..\ + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + False + ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + + + ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + + + False + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + + + {689cb6c4-3d23-45da-8e00-87c28aea32d0} + Raspberry.IO.Interop + + + {326342e5-0411-40e8-9f2d-563d6b192568} + Raspberry.IO.SerialPeripheralInterface + + + {0bb6c3ce-422e-49f2-9165-dec06afe1b1a} + Tests.Raspberry.IO + + + + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings new file mode 100644 index 0000000..65668e8 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/Tests.Raspberry.IO.SerialPeripheralInterface.csproj.DotSettings @@ -0,0 +1,3 @@ + + True + True \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config new file mode 100644 index 0000000..277a3fb --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO.SerialPeripheralInterface/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/Properties/AssemblyInfo.cs b/UnitTests/Tests.Raspberry.IO/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5af4fa3 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("Tests.Raspberry.IO")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tests.Raspberry.IO")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("e0f37de3-8576-49c3-aae9-9578d7612264")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTests/Tests.Raspberry.IO/Spec.cs b/UnitTests/Tests.Raspberry.IO/Spec.cs new file mode 100644 index 0000000..4c35d07 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO/Spec.cs @@ -0,0 +1,53 @@ +using System; +using System.Diagnostics; +using NUnit.Framework; + +namespace Tests.Raspberry.IO +{ + /// + /// Abstract helper class to make nunit tests more readable. + /// + [DebuggerStepThrough, DebuggerNonUserCode] + public class Spec + { + [DebuggerStepThrough] + [TestFixtureSetUp] + public void SetUp() { + EstablishContext(); + BecauseOf(); + } + + [DebuggerStepThrough] + [TestFixtureTearDown] + public void TearDown() { + Cleanup(); + } + + /// + /// Test setup. Place your initialization code here. + /// + [DebuggerStepThrough] + protected virtual void EstablishContext() {} + + /// + /// Test run. Place the tested method / action here. + /// + [DebuggerStepThrough] + protected virtual void BecauseOf() {} + + /// + /// Test clean. Close/delete files, close database connections .. + /// + [DebuggerStepThrough] + protected virtual void Cleanup() {} + + /// + /// Creates an Action delegate. + /// + /// Method the shall be created as delegate. + /// A delegate of type + protected Action Invoking(Action func) { + return func; + } + } +} \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj new file mode 100644 index 0000000..56a90f9 --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj @@ -0,0 +1,70 @@ + + + + + Debug + AnyCPU + {0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} + Library + Properties + Tests.Raspberry.IO + Tests.Raspberry.IO + v4.0 + 512 + + ..\..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\FakeItEasy.1.20.0\lib\net40\FakeItEasy.dll + + + ..\..\packages\FluentAssertions.2.2.0.0\lib\net40\FluentAssertions.dll + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj.DotSettings b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj.DotSettings new file mode 100644 index 0000000..95561ee --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO/Tests.Raspberry.IO.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/UnitTests/Tests.Raspberry.IO/packages.config b/UnitTests/Tests.Raspberry.IO/packages.config new file mode 100644 index 0000000..277a3fb --- /dev/null +++ b/UnitTests/Tests.Raspberry.IO/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/repositories.config b/packages/repositories.config index 625f5e2..94e3276 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -6,4 +6,8 @@ - \ No newline at end of file + + + + + From feb08cd65f8227854dcd989e54c43ef2f2f64b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Wed, 4 Jun 2014 22:38:02 +0200 Subject: [PATCH 144/227] Updated Test.Gpio.HD44780 Sample I2C mode now uses the same pin layout as Adafruit HD44780 + MCP23017 kit --- Tests/Test.Gpio.HD44780/Program.cs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Tests/Test.Gpio.HD44780/Program.cs b/Tests/Test.Gpio.HD44780/Program.cs index 4381b96..7194dee 100644 --- a/Tests/Test.Gpio.HD44780/Program.cs +++ b/Tests/Test.Gpio.HD44780/Program.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Net.NetworkInformation; using System.Threading; -using Raspberry.IO.Components; using Raspberry.IO.Components.Displays.Hd44780; using Raspberry.IO.Components.Expanders.Mcp23017; using Raspberry.IO.GeneralPurpose; @@ -26,7 +25,7 @@ static void Main(string[] args) ScreenHeight = 2, }; - var useI2c = args.Contains("i2c"); + var useI2c = args.Contains("i2c", StringComparer.InvariantCultureIgnoreCase); using (var configuration = useI2c ? LoadI2cConfiguration() : LoadGpioConfiguration()) using (var connection = new Hd44780LcdConnection( @@ -38,15 +37,17 @@ static void Main(string[] args) connection.SetCustomCharacter(1, new byte[] {0x0, 0x0, 0x04, 0xe, 0x1f, 0x0, 0x0}); connection.SetCustomCharacter(2, new byte[] {0x0, 0x0, 0x1f, 0xe, 0x04, 0x0, 0x0}); - connection.Clear(); + if (args.Contains("viewMap", StringComparer.InvariantCultureIgnoreCase)) + { + connection.Clear(); + DisplayCharMap(connection); + } + connection.Clear(); connection.WriteLine("R# IP Config"); connection.WriteLine(Environment.OSVersion); - Thread.Sleep(1000); - // DisplayCharMap(connection); var delay = 0m; - while (true) { foreach (var t in NetworkInterface.GetAllNetworkInterfaces() @@ -117,14 +118,14 @@ static void Main(string[] args) private static Hd44780Configuration LoadI2cConfiguration() { - const Mcp23017Pin registerSelectPin = Mcp23017Pin.B0; - const Mcp23017Pin clockPin = Mcp23017Pin.B1; + const Mcp23017Pin registerSelectPin = Mcp23017Pin.B7; + const Mcp23017Pin clockPin = Mcp23017Pin.B5; var dataPins = new[] { + Mcp23017Pin.B1, Mcp23017Pin.B2, Mcp23017Pin.B3, - Mcp23017Pin.B4, - Mcp23017Pin.B5 + Mcp23017Pin.B4 }; Console.WriteLine(); @@ -140,9 +141,7 @@ private static Hd44780Configuration LoadI2cConfiguration() const ConnectorPin sdaPin = ConnectorPin.P1Pin03; const ConnectorPin sclPin = ConnectorPin.P1Pin05; - var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()); - driver.ClockDivider = 2048; - + var driver = new I2cDriver(sdaPin.ToProcessor(), sclPin.ToProcessor()) {ClockDivider = 512}; var connection = new Mcp23017I2cConnection(driver.Connect(0x20)); return new Hd44780Configuration(driver) @@ -180,7 +179,7 @@ private static Hd44780Configuration LoadGpioConfiguration() { RegisterSelect = driver.Out(registerSelectPin), Clock = driver.Out(clockPin), - Data = dataPins.Select(pin=>driver.Out(pin)) + Data = dataPins.Select(driver.Out) }; } From b1b19729db3ac85e24c563c44e21b0c906f65291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 5 Jun 2014 21:18:10 +0200 Subject: [PATCH 145/227] Improved exception messages --- .../Displays/Hd44780/Hd44780LcdConnection.cs | 6 ++--- .../Mcp23017/Mcp23017InputBinaryPin.cs | 2 +- .../FileGpioConnectionDriver.cs | 6 ++--- Raspberry.IO.GeneralPurpose/GpioConnection.cs | 2 +- .../GpioConnectionDriver.cs | 22 ++++++++++--------- .../MemoryGpioConnectionDriver.cs | 7 +++--- .../I2cDriver.cs | 21 +++++++++--------- .../SpiTransferBufferCollection.cs | 3 ++- .../CommandLineExtensionMethods.cs | 21 +++++++++++++++++- 9 files changed, 57 insertions(+), 33 deletions(-) diff --git a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs index 9789125..6eeb491 100644 --- a/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs +++ b/Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs @@ -85,14 +85,14 @@ public Hd44780LcdConnection(Hd44780LcdConnectionSettings settings, IOutputBinary width = settings.ScreenWidth; height = settings.ScreenHeight; if (height < 1 || height > 2) - throw new ArgumentOutOfRangeException("ScreenHeight", height, "Screen must have either 1 or 2 rows"); + throw new ArgumentOutOfRangeException("settings", height, "ScreenHeight must be either 1 or 2 rows"); if (width * height > 80) throw new ArgumentException("At most 80 characters are allowed"); if (settings.PatternWidth != 5) - throw new ArgumentOutOfRangeException("PatternWidth", settings.PatternWidth, "Pattern must be 5 pixels width"); + throw new ArgumentOutOfRangeException("settings", settings.PatternWidth, "PatternWidth must be 5 pixels"); if (settings.PatternHeight != 8 && settings.PatternHeight != 10) - throw new ArgumentOutOfRangeException("PatternHeight", settings.PatternWidth, "Pattern must be either 7 or 10 pixels height"); + throw new ArgumentOutOfRangeException("settings", settings.PatternWidth, "PatternWidth must be either 7 or 10 pixels height"); if (settings.PatternHeight == 10 && height == 2) throw new ArgumentException("10 pixels height pattern cannot be used with 2 rows"); diff --git a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs index f4a0112..b81dbda 100644 --- a/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs +++ b/Raspberry.IO.Components/Expanders/Mcp23017/Mcp23017InputBinaryPin.cs @@ -33,7 +33,7 @@ public void Wait(bool waitForUp = true, decimal timeout = 0) while (Read() != waitForUp) { if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) - throw new TimeoutException("A timeout occurred while waiting"); + throw new TimeoutException("A timeout occurred while waiting for pin status to change"); } } } diff --git a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs index 44e559c..2b3eb26 100644 --- a/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/FileGpioConnectionDriver.cs @@ -60,7 +60,7 @@ public void Allocate(ProcessorPin pin, PinDirection direction) /// The resistor. public void SetPinResistor(ProcessorPin pin, PinResistor resistor) { - throw new NotSupportedException(); + throw new NotSupportedException("Resistor are not supported by file GPIO connection driver"); } /// @@ -74,7 +74,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - throw new NotSupportedException(); + throw new NotSupportedException("Edge detection is not supported by file GPIO connection driver"); } /// @@ -93,7 +93,7 @@ public void Wait(ProcessorPin pin, bool waitForUp = true, decimal timeout = 0) while (Read(pin) != waitForUp) { if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) - throw new TimeoutException("A timeout occurred while waiting"); + throw new TimeoutException("A timeout occurred while waiting for pin status to change"); } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnection.cs b/Raspberry.IO.GeneralPurpose/GpioConnection.cs index e80a196..6d3b6da 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnection.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnection.cs @@ -127,7 +127,7 @@ public bool this[PinConfiguration pin] OnPinStatusChanged(new PinStatusEventArgs {Enabled = value, Configuration = pin}); } else - throw new InvalidOperationException("Input pin value cannot be set"); + throw new InvalidOperationException("Value of input pins cannot be modified"); } } diff --git a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs index 6518efe..a9eea0a 100644 --- a/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/GpioConnectionDriver.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Runtime.InteropServices; using Raspberry.IO.Interop; @@ -130,7 +131,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) break; default: - throw new ArgumentOutOfRangeException("resistor"); + throw new ArgumentOutOfRangeException("resistor", resistor, string.Format(CultureInfo.InvariantCulture, "{0} is not a valid value for pin resistor", resistor)); } WriteResistor(pud); @@ -180,9 +181,9 @@ public void Wait(ProcessorPin pin, bool waitForUp = true, decimal timeout = 0) break; } else if (waitResult == 0) - throw new TimeoutException(string.Format("Operation timed out after waiting {0}ms for the pin {1} to be {2}", actualTimeout, pin, (waitForUp ? "up" : "down"))); + throw new TimeoutException(string.Format(CultureInfo.InvariantCulture, "Operation timed out after waiting {0}ms for the pin {1} to be {2}", actualTimeout, pin, (waitForUp ? "up" : "down"))); else - throw new IOException("epoll_wait failed"); + throw new IOException("Call to epoll_wait API failed"); } } @@ -254,10 +255,11 @@ private static int GetActualTimeout(decimal timeout) { if (timeout > 1) return (int)timeout; - else if (timeout > 0) + + if (timeout > 0) return 1; - else - return 5000; + + return 5000; } private void InitializePoll(ProcessorPin pin) @@ -272,7 +274,7 @@ private void InitializePoll(ProcessorPin pin) pinPoll.PollDescriptor = Interop.epoll_create(1); if (pinPoll.PollDescriptor < 0) - throw new IOException("epoll_create failed with the following return value: " + pinPoll.PollDescriptor); + throw new IOException("Call to epoll_create(1) API failed with the following return value: " + pinPoll.PollDescriptor); var valuePath = Path.Combine(gpioPath, string.Format("gpio{0}/value", (int)pin)); @@ -289,7 +291,7 @@ private void InitializePoll(ProcessorPin pin) var controlResult = Interop.epoll_ctl(pinPoll.PollDescriptor, Interop.EPOLL_CTL_ADD, pinPoll.FileDescriptor, pinPoll.InEventPtr); if (controlResult != 0) - throw new IOException("epoll_ctl(EPOLL_CTL_ADD) failed with the following return value: " + controlResult); + throw new IOException("Call to epoll_ctl(EPOLL_CTL_ADD) API failed with the following return value: " + controlResult); pinPoll.OutEventPtr = Marshal.AllocHGlobal(64); polls[pin] = pinPoll; @@ -312,7 +314,7 @@ private void UninitializePoll(ProcessorPin pin) UnixFile.CloseFileDescriptor(poll.FileDescriptor); if (controlResult != 0) - throw new IOException("epoll_ctl(EPOLL_CTL_DEL) failed with the following return value: " + controlResult); + throw new IOException("Call to epoll_ctl(EPOLL_CTL_DEL) API failed with the following return value: " + controlResult); } } @@ -329,7 +331,7 @@ private static string ToString(PinDetectedEdges edges) case PinDetectedEdges.None: return "none"; default: - throw new ArgumentOutOfRangeException("edges"); + throw new ArgumentOutOfRangeException("edges", edges, string.Format(CultureInfo.InvariantCulture, "{0} is not a valid value for edge detection", edges)); } } diff --git a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs index 3b6e2d0..b1cf2a8 100644 --- a/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs +++ b/Raspberry.IO.GeneralPurpose/MemoryGpioConnectionDriver.cs @@ -1,6 +1,7 @@ #region References using System; +using System.Globalization; using System.Runtime.InteropServices; using Raspberry.IO.Interop; @@ -103,7 +104,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) break; default: - throw new ArgumentOutOfRangeException("resistor"); + throw new ArgumentOutOfRangeException("resistor", resistor, string.Format(CultureInfo.InvariantCulture, "{0} is not a valid value for pin resistor", resistor)); } WriteResistor(pud); @@ -125,7 +126,7 @@ public void SetPinResistor(ProcessorPin pin, PinResistor resistor) /// public void SetPinDetectedEdges(ProcessorPin pin, PinDetectedEdges edges) { - throw new NotSupportedException(); + throw new NotSupportedException("Edge detection is not supported by memory GPIO connection driver"); } /// @@ -144,7 +145,7 @@ public void Wait(ProcessorPin pin, bool waitForUp = true, decimal timeout = 0) while (Read(pin) != waitForUp) { if (DateTime.Now.Ticks - startWait.Ticks >= 10000 * timeout) - throw new TimeoutException("A timeout occurred while waiting"); + throw new TimeoutException("A timeout occurred while waiting for pin status to change"); } } diff --git a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs index e9f5c90..a1c62a8 100644 --- a/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs +++ b/Raspberry.IO.InterIntegratedCircuit/I2cDriver.cs @@ -1,6 +1,7 @@ #region References using System; +using System.Globalization; using System.Runtime.InteropServices; using Raspberry.IO.GeneralPurpose; using Raspberry.Timers; @@ -55,7 +56,7 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin) } if (bscAddress == (IntPtr) Interop.MAP_FAILED) - throw new InvalidOperationException(); + throw new InvalidOperationException("Unable to access device memory"); // Set the I2C pins to the Alt 0 function to enable I2C access on them SetPinMode((uint) (int) sdaPin, Interop.BCM2835_GPIO_FSEL_ALT0); // SDA @@ -177,11 +178,11 @@ internal void Write(int deviceAddress, byte[] buffer) } if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK - throw new InvalidOperationException("BCM2835_I2C_REASON_ERROR_NACK"); + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout - throw new InvalidOperationException("BCM2835_I2C_REASON_ERROR_CLKT"); + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); if (remaining != 0) // Not all data is sent - throw new InvalidOperationException(string.Format("BCM2835_I2C_REASON_ERROR_DATA. Missing {0} bytes", remaining)); + throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); WriteUInt32Mask(control, Interop.BCM2835_BSC_S_DONE, Interop.BCM2835_BSC_S_DONE); } @@ -236,11 +237,11 @@ internal byte[] Read(int deviceAddress, int byteCount) } if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK - throw new InvalidOperationException("BCM2835_I2C_REASON_ERROR_NACK"); + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status"); if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout - throw new InvalidOperationException("BCM2835_I2C_REASON_ERROR_CLKT"); + throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status"); if (remaining != 0) // Not all data is received - throw new InvalidOperationException(string.Format("BCM2835_I2C_REASON_ERROR_DATA. Missing {0} bytes", remaining)); + throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining)); WriteUInt32Mask(control, Interop.BCM2835_BSC_S_DONE, Interop.BCM2835_BSC_S_DONE); @@ -286,17 +287,17 @@ private static uint GetBscBase(ProcessorPin sdaPin, ProcessorPin sclPin) case 1: if (sdaPin == ProcessorPin.Pin0 && sclPin == ProcessorPin.Pin1) return Interop.BCM2835_BSC0_BASE; - throw new InvalidOperationException("I2C cannot be initialized for specified pins"); + throw new InvalidOperationException("No I2C device exist on the specified pins"); case 2: if (sdaPin == ProcessorPin.Pin28 && sclPin == ProcessorPin.Pin29) return Interop.BCM2835_BSC0_BASE; if (sdaPin == ProcessorPin.Pin2 && sclPin == ProcessorPin.Pin3) return Interop.BCM2835_BSC1_BASE; - throw new InvalidOperationException("I2C cannot be initialized for specified pins"); + throw new InvalidOperationException("No I2C device exist on the specified pins"); default: - throw new InvalidOperationException("Board revision not supported"); + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Board revision {0} is not supported", GpioConnectionSettings.BoardConnectorRevision)); } } diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs index 133986d..4ef0b46 100644 --- a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBufferCollection.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.Linq; namespace Raspberry.IO.SerialPeripheralInterface @@ -23,7 +24,7 @@ public class SpiTransferBufferCollection : ISpiTransferBufferCollection /// Transfer mode public SpiTransferBufferCollection(int numberOfMessages, int messageLengthInBytes, SpiTransferMode transferMode) { if (numberOfMessages <= 0) { - throw new ArgumentOutOfRangeException("numberOfMessages"); + throw new ArgumentOutOfRangeException("numberOfMessages", numberOfMessages, string.Format(CultureInfo.InvariantCulture, "{0} is not a valid number of messages", numberOfMessages)); } transferBuffers = new ISpiTransferBuffer[numberOfMessages]; diff --git a/Tests/Test.Gpio.Chaser/CommandLineExtensionMethods.cs b/Tests/Test.Gpio.Chaser/CommandLineExtensionMethods.cs index 0dcc5de..11b8006 100644 --- a/Tests/Test.Gpio.Chaser/CommandLineExtensionMethods.cs +++ b/Tests/Test.Gpio.Chaser/CommandLineExtensionMethods.cs @@ -1,12 +1,19 @@ +#region References + using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using Raspberry.IO.GeneralPurpose; +#endregion + namespace Test.Gpio.Chaser { internal static class CommandLineExtensionMethods { + #region Methods + public static bool GetLoop(this IEnumerable args) { return args.SkipWhile(a => a != "-loop").Any(); @@ -31,6 +38,15 @@ public static IGpioConnectionDriver GetDriver(this IEnumerable args) { var driverName = args.SkipWhile(a => a != "-driver").Skip(1).DefaultIfEmpty("").First(); + return GetDriver(driverName); + } + + #endregion + + #region Private Helpers + + private static IGpioConnectionDriver GetDriver(string driverName) + { switch (driverName) { case "default": @@ -43,8 +59,11 @@ public static IGpioConnectionDriver GetDriver(this IEnumerable args) return null; default: - throw new InvalidOperationException("Unsupported driver"); + throw new ArgumentOutOfRangeException("driverName", driverName, + string.Format(CultureInfo.InvariantCulture, "{0} is not a valid driver name", driverName)); } } + + #endregion } } \ No newline at end of file From 8d0fba7b484035ce7b5eda08438fc1f4c44ea687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 5 Jun 2014 21:18:30 +0200 Subject: [PATCH 146/227] Removed useless code blocks --- .../ExtensionMethods/ByteExtensionMethods.cs | 6 ++---- .../Controllers/Tlc59711/Tlc59711Cluster.cs | 8 +++----- .../Controllers/Tlc59711/Tlc59711ClusterChannels.cs | 9 +++------ .../Controllers/Tlc59711/Tlc59711Connection.cs | 6 ++---- .../Controllers/Tlc59711/Tlc59711Device.cs | 12 ++---------- .../SpiTransferBuffer.cs | 3 +-- 6 files changed, 13 insertions(+), 31 deletions(-) diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs index a953a2b..df41b01 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs @@ -10,12 +10,10 @@ internal static class ByteExtensionMethods #region Methods public static void ThrowOnInvalidBrightnessControl(this byte value) { - if (value <= BRIGHTNESS_CONTROL_MAX) { + if (value <= BRIGHTNESS_CONTROL_MAX) return; - } - var message = String.Format("The maximum value for brightness control is {0}. You set a value of {1}.", - BRIGHTNESS_CONTROL_MAX, value); + var message = String.Format("The maximum value for brightness control is {0}. You set a value of {1}.", BRIGHTNESS_CONTROL_MAX, value); throw new ArgumentException(message, "value"); } diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs index 10e6fbc..c7588c6 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Cluster.cs @@ -28,13 +28,11 @@ public class Tlc59711Cluster : ITlc59711Cluster /// Memory to work with. /// Number of s connected together. public Tlc59711Cluster(IMemory memory, int numberOfDevices) { - if (ReferenceEquals(memory, null)) { + if (ReferenceEquals(memory, null)) throw new ArgumentNullException("memory"); - } - if (numberOfDevices <= 0) { + if (numberOfDevices <= 0) throw new ArgumentOutOfRangeException("numberOfDevices", "You cannot create a cluster with less than one device."); - } - + var minimumRequiredMemorySize = (numberOfDevices * COMMAND_SIZE); if (memory.Length < minimumRequiredMemorySize) { var message = string.Format("For {0} device(s) you have to provide a minimum of {1} bytes of memory.", numberOfDevices, minimumRequiredMemorySize); diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs index db618ea..6a2d9de 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711ClusterChannels.cs @@ -37,18 +37,15 @@ public int ChannelIndex { /// /// TLC59711 devices public Tlc59711ClusterChannels(IEnumerable devices) { - if (devices == null) { + if (devices == null) throw new ArgumentNullException("devices"); - } foreach (var device in devices) { - if (ReferenceEquals(device, null)) { + if (ReferenceEquals(device, null)) continue; - } - for (var i = 0; i < device.Channels.Count; i++) { + for (var i = 0; i < device.Channels.Count; i++) deviceMap.Add(new Mapping(device, i)); - } } } diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs index e37734e..66923b7 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Connection.cs @@ -29,13 +29,11 @@ public class Tlc59711Connection : ITlc59711Connection /// If true the SPI connection will be initialized with common data transfers settings. /// Number of s connected together. public Tlc59711Connection(INativeSpiConnection connection, bool initializeWithDefault, int numberOfDevices) { - if (ReferenceEquals(connection, null)) { + if (ReferenceEquals(connection, null)) throw new ArgumentNullException("connection"); - } - if (numberOfDevices <= 0) { + if (numberOfDevices <= 0) throw new ArgumentOutOfRangeException("numberOfDevices", "You need at least one device."); - } this.connection = connection; diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs index 0dec9ca..682578f 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/Tlc59711Device.cs @@ -38,23 +38,15 @@ public class Tlc59711Device : ITlc59711Device #endregion #region Instance Management - /// - /// Creates a new instance of the class. - /// - /// Memory to work with. - public Tlc59711Device(IMemory memory) - :this(memory, null) - {} /// /// Creates a new instance of the class. /// /// Memory to work with. /// Initial settings - public Tlc59711Device(IMemory memory, ITlc59711Settings settings) { - if (ReferenceEquals(memory, null)) { + public Tlc59711Device(IMemory memory, ITlc59711Settings settings = null) { + if (ReferenceEquals(memory, null)) throw new ArgumentNullException("memory"); - } if (memory.Length < COMMAND_SIZE) { throw new ArgumentException( diff --git a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs index e61ffc0..c844188 100644 --- a/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs +++ b/Raspberry.IO.SerialPeripheralInterface/SpiTransferBuffer.cs @@ -108,8 +108,7 @@ public SpiTransferControlStructure ControlStructure { /// Specifies read and/or write mode. public SpiTransferBuffer(int lengthInBytes, SpiTransferMode transferMode) { if (transferMode == 0) { - throw new ArgumentException("An appropriate transfer mode must be specified (read/write)", - "transferMode"); + throw new ArgumentException("An appropriate transfer mode must be specified (read/write)", "transferMode"); } mode = transferMode; From a362dead4b584afab78bcd08439155ba7e30b0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9zine?= Date: Thu, 5 Jun 2014 22:05:07 +0200 Subject: [PATCH 147/227] Added regions and comments --- .../Controllers/Pca9685/IPwmDevice.cs | 4 + .../ExtensionMethods/ByteExtensionMethods.cs | 8 +- .../Controllers/Tlc59711/IPwmChannels.cs | 16 +++- .../Controllers/Tlc59711/IPwmDevice.cs | 6 ++ .../Controllers/Tlc59711/ITlc59711Cluster.cs | 17 +++- .../Tlc59711/ITlc59711Connection.cs | 14 +++- .../Controllers/Tlc59711/ITlc59711Device.cs | 4 + .../Controllers/Tlc59711/ITlc59711Settings.cs | 16 ++-- .../Controllers/Tlc59711/Tlc59711Channels.cs | 8 +- .../Controllers/Tlc59711/Tlc59711Cluster.cs | 8 +- .../Tlc59711/Tlc59711ClusterChannels.cs | 16 +++- .../Tlc59711/Tlc59711Connection.cs | 8 +- .../Controllers/Tlc59711/Tlc59711Device.cs | 6 +- .../Mcp3008AnalogPinExtensionMethods.cs | 11 +++ .../Mcp3008/Mcp3008InputAnalogPin.cs | 27 +++++++ .../Mcp3008/Mcp3008SpiConnection.cs | 8 ++ .../Mcp4822AnalogPinExtensionMethods.cs | 11 +++ .../Mcp4822/Mcp4822OutputAnalogPin.cs | 31 +++++++- .../Mcp4822/Mcp4822SpiConnection.cs | 9 ++- .../Displays/Hd44780/Hd44780A00Encoding.cs | 54 +++++++++++++ .../Displays/Hd44780/Hd44780LcdConnection.cs | 78 +++++++++++++++++++ .../Hd44780/Hd44780LcdConnectionSettings.cs | 44 +++++++++++ .../Mcp23017/Mcp23017InputBinaryPin.cs | 47 ++++++++++- .../Mcp23017/Mcp23017OutputBinaryPin.cs | 37 ++++++++- .../Mcp23017/Mcp23017PinExtensionMethods.cs | 27 ++++++- .../Sensors/HcSr04/HcSr04Connection.cs | 2 +- .../Sensors/HcSr04/Units.cs | 17 +++- .../EnumTypes/SpiTransferMode.cs | 2 + .../INativeSpiConnection.cs | 20 ++++- .../ISpiTransferBuffer.cs | 55 ++++++++++++- .../ISpiTransferBufferCollection.cs | 16 +++- .../Interop/SpiTransferControlStructure.cs | 14 +++- .../NativeSpiConnection.cs | 7 +- .../SpiTransferBuffer.cs | 8 +- .../SpiTransferBufferCollection.cs | 12 ++- Raspberry.IO/ByteExtensionMethods.cs | 19 ++++- Raspberry.IO/StringExtensionMethods.cs | 19 +++-- 37 files changed, 656 insertions(+), 50 deletions(-) diff --git a/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs index 280b263..687580e 100644 --- a/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs +++ b/Raspberry.IO.Components/Controllers/Pca9685/IPwmDevice.cs @@ -5,6 +5,8 @@ /// public interface IPwmDevice { + #region Methods + /// /// Sets the PWM update rate. /// @@ -25,5 +27,7 @@ public interface IPwmDevice /// The channel. /// if set to true, all values are on; otherwise they are all off. void SetFull(PwmChannel channel, bool fullOn); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs index df41b01..e89c951 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ExtensionMethods/ByteExtensionMethods.cs @@ -1,4 +1,8 @@ -using System; +#region References + +using System; + +#endregion namespace Raspberry.IO.Components.Controllers.Tlc59711 { @@ -9,6 +13,7 @@ internal static class ByteExtensionMethods #endregion #region Methods + public static void ThrowOnInvalidBrightnessControl(this byte value) { if (value <= BRIGHTNESS_CONTROL_MAX) return; @@ -17,6 +22,7 @@ public static void ThrowOnInvalidBrightnessControl(this byte value) { throw new ArgumentException(message, "value"); } + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/IPwmChannels.cs b/Raspberry.IO.Components/Controllers/Tlc59711/IPwmChannels.cs index 7ff453d..6b5e422 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/IPwmChannels.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/IPwmChannels.cs @@ -1,4 +1,8 @@ -using System; +#region References + +using System; + +#endregion namespace Raspberry.IO.Components.Controllers.Tlc59711 { @@ -6,17 +10,25 @@ namespace Raspberry.IO.Components.Controllers.Tlc59711 /// The Pulse-width modulation (PWM) channels. /// public interface IPwmChannels { + + #region Properties + /// /// Indexer, which will allow client code to use [] notation on the class instance itself to modify PWM channel values. /// /// channel index /// The current PWM value from UInt16 this[int index] { get; set; } + /// /// Returns the number of channels. /// int Count { get; } + #endregion + + #region Methods + /// /// Returns the PWM value at the specified channel . /// @@ -30,5 +42,7 @@ public interface IPwmChannels { /// Channel index /// The PWM value void Set(int index, UInt16 value); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/IPwmDevice.cs b/Raspberry.IO.Components/Controllers/Tlc59711/IPwmDevice.cs index 113fd1a..81360d2 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/IPwmDevice.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/IPwmDevice.cs @@ -4,9 +4,15 @@ /// A pulse-width modulation (PWM) device ///
public interface IPwmDevice { + + #region Properties + /// /// The PWM channels /// IPwmChannels Channels { get; } + + #endregion + } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Cluster.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Cluster.cs index 5521064..158faf8 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Cluster.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Cluster.cs @@ -1,4 +1,8 @@ -using System.Collections.Generic; +#region References + +using System.Collections.Generic; + +#endregion namespace Raspberry.IO.Components.Controllers.Tlc59711 { @@ -8,26 +12,37 @@ namespace Raspberry.IO.Components.Controllers.Tlc59711 ///
public interface ITlc59711Cluster : IEnumerable, IPwmDevice { + #region Properties + /// /// Number of TLC59711 devices chained together /// int Count { get; } + /// /// Returns the TLC59711 device at the requested position /// /// TLC59711 index /// TLC59711 device ITlc59711Device this[int index] { get; } + + #endregion + + #region Methods + /// /// Returns the TLC59711 device at the requested position /// /// TLC59711 index /// TLC59711 device ITlc59711Device Get(int index); + /// /// Set BLANK on/off at all connected devices. /// /// If set to true all outputs are forced off. void Blank(bool blank); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Connection.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Connection.cs index 80ca6d7..357b2d0 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Connection.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Connection.cs @@ -1,4 +1,8 @@ -using System; +#region References + +using System; + +#endregion namespace Raspberry.IO.Components.Controllers.Tlc59711 { @@ -7,14 +11,22 @@ namespace Raspberry.IO.Components.Controllers.Tlc59711 ///
public interface ITlc59711Connection : IDisposable { + #region Properties + /// /// A chained cluster of Adafruit's 12-channel 16bit PWM/LED driver TLC59711. /// ITlc59711Cluster Devices { get; } + #endregion + + #region Methods + /// /// Creates a TLC59711 command and sends it to the first device using the SPI bus. /// void Update(); + + #endregion } } \ No newline at end of file diff --git a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Device.cs b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Device.cs index 894b6f7..320bfb8 100644 --- a/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Device.cs +++ b/Raspberry.IO.Components/Controllers/Tlc59711/ITlc59711Device.cs @@ -5,9 +5,13 @@ ///