From 58cdfadf4e2c36ca1883ee625045921ed431416c Mon Sep 17 00:00:00 2001 From: Noel Eck Date: Wed, 8 Mar 2017 09:40:56 -0800 Subject: [PATCH] p9813: Chainable LEDS Initial commit of the p9813 chainable LED controller. Added C, C++, python, java, and node examples. Signed-off-by: Sergey Kiselev Signed-off-by: Noel Eck --- docs/images/p9813.jpg | Bin 0 -> 44496 bytes doxy/samples.mapping.txt | 1 + examples/c++/CMakeLists.txt | 1 + examples/c++/p9813.cxx | 48 +++++++++++ examples/java/CMakeLists.txt | 1 + examples/java/P9813Sample.java | 42 ++++++++++ examples/javascript/p9813.js | 40 +++++++++ examples/python/p9813.py | 48 +++++++++++ src/p9813/CMakeLists.txt | 7 ++ src/p9813/javaupm_p9813.i | 20 +++++ src/p9813/jsupm_p9813.i | 7 ++ src/p9813/p9813.c | 149 +++++++++++++++++++++++++++++++++ src/p9813/p9813.cxx | 146 ++++++++++++++++++++++++++++++++ src/p9813/p9813.h | 106 +++++++++++++++++++++++ src/p9813/p9813.hpp | 136 ++++++++++++++++++++++++++++++ src/p9813/p9813_fti.c | 67 +++++++++++++++ src/p9813/pyupm_p9813.i | 11 +++ 17 files changed, 830 insertions(+) create mode 100644 docs/images/p9813.jpg create mode 100644 examples/c++/p9813.cxx create mode 100644 examples/java/P9813Sample.java create mode 100644 examples/javascript/p9813.js create mode 100644 examples/python/p9813.py create mode 100644 src/p9813/CMakeLists.txt create mode 100644 src/p9813/javaupm_p9813.i create mode 100644 src/p9813/jsupm_p9813.i create mode 100644 src/p9813/p9813.c create mode 100644 src/p9813/p9813.cxx create mode 100644 src/p9813/p9813.h create mode 100644 src/p9813/p9813.hpp create mode 100644 src/p9813/p9813_fti.c create mode 100644 src/p9813/pyupm_p9813.i diff --git a/docs/images/p9813.jpg b/docs/images/p9813.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7fecfb4e4b1a37c5a5edd96a9ea96cd3ddffa309 GIT binary patch literal 44496 zcmeFZby!u+yEncz-AH$rfPi!hNK1D&o9=ED1r#YkKuPHa>F(|ZX^=)hkaSbO4L*6^ zbABh@@42q`k7u~n%sqF^+*6BLpS5P+ez{!%9z2thl>$H@002S%fZJ8})9NipUtsI>w#nred6->;m9q#e~$76PO0d@`n zb}mYG9szbffyX=m0Q(8_r*EHNelH)U@e}MHG&;1dyMO?K{Y@7E>f;~n0FnRM4iNoc z+W`amy$ld5%pYZARsJdtkb$Pq9{ZKv{-rOWjhDIO-tGfv_iZu~R{%h_2LQ%>4lsXy zXL&mhyaLdWkdTm((2$YQuuxG@vG6d_&@k}`ad7Z(a0s!`?!#}%ugt%VLFlNc=osh^ zFfbnAVqjq4-bEO=zf7?HD+S!P0$50Z7w`!dL=C`Tfnc#fw~Nqbquh3aM4(>6gYE;= z;ky6}fMDR@5fG7(QBa}N;qO8a00aBG@BsjV1Hr<;!N4OTAi=|;aYBVyuy9n^?C@eL zCOFj2FE|iz-=&v5rJ==BZ8PQMatRs}N2H5UJ6t_7bLGa*D1S*W5vy)4*`DdfLolxK z75t;(RmX(;+OZVF`>f!~xX#J-lkBRlsf|-j3y+Zaoa*lB%`;wUElbbPgxs2*nXPjy z00su?E!@3NhzRi9_byPeW5Yo`aHhtA=XmiB_s)Yh)v-fPTGLgRpcrvAJTq6WBRYgT z2N3DG+sC0!WD=N5YVf#$zy9IEf9wInpDx_a0cf!Ibz%V`z^QtSEFB|ljO;U6+8EUs zS=#qm10pm`17y|Zx@`+q&q_bLVyk57mB$PgT;@|Fy9!p`0+@@s+)dSwg&T1hMa!XP z&+g5BD@W;e^zUUxmm}lW3+|j}q%VPrvT}vEs1epK&EJX0DPp^-d%U-|f21quRJ4i> zn=~ICM6BsK{UkkMyx!K;83|v@U##_w?T4?M0u3V3*S($2SXh(e$g6N?_$Q2y4&F>3 zLWUViBR#(K5{#}L6!)CBct_p>h?W!pk`pAbr7HoO!C3UooXWqT1R&m`TFSGcT?3x$L8d zrJjM?T3sh(Qh%a4*=TI`?Ym$p?rQLcntl9ysL}T1Xh&($p;tgGZu!nOsi8;)ghFYz zNibhychztpbc>77*RLpl3>-Lb6Jn74oh83*UN{mM(?+$wLmx@b(uU*$w)-rJn} zfvP)0P>F2f$#QQx>~ZlWesi$DLAKhwSZ!c2*fazoeYk43RP`|}oPju!LF%seeB64d$l z#xXZm&9tqTGRoC(WF%*(q2-kN8_`U2g`P#z(=dnc5j&47DHd1-i*JFPIw97y5cVQM z?y&sNsLfOFH$(9o+`q6kkAAN(;rKpNFMO_L|KZGX)l?%P_(hz}L>FXg`r*zRC^G-c zI{ViY-FN%{uYq6 zgn(!BDmtZUpW}+eFHeEnWxJ7ipsVQNN8I}vHvVgdc`r}V_Sayq)nT z0IUAMq|~vQzl{(0K!^&tP`ho!Eg%%-Z zz9t}+OlzpOu*j`ZkJI7ArLbjhf0qcnlvG-o#L<%JSWsV7ut%?Xd3bmWSk4&b3=Xzz zYAT#GhweKspv6ByiWZ6eS?YN4>=t0RHg;P|H)J2`tgSoKJP%`k<649#(4t1N?*>T& z@3Pu27hESMCnvVZLG1MWC0&%Czm86c5ev@>M5qMQP@`FC6;So~^C+LI*;^#p(3KXq zqgpO3w)DFC4|-l0~DdpkA%xB z{{F|i25gw@ryDEg{AXZYf1eb|m>EgC@`AFDXUTi1>2k9HN-6~{RRM1&2L|inb&Te% zPdumW@z<~=Js*D|74DhfGXH8`SL|3n&%Ql)ow=j+y}Af3tnixV%lq7($fs3+Gv?4! zQckirCrwL;>e~j!JXf}hQYK@27$>FH*8@5ytd3V~&7~W~1Yb9yw?KI(#~-^zX~$<( z-V}43kH41{UE|9*3=qRUI%}{`Zq(7rwwNpJ>2)mc_R$(Mt(bts83=T*uWxRGtIsH^ zOx6~`;D+F;>H!Y>hQ)Vpsv_sXZfcHm!ur0Ym%KZ+=B?8Gb^%d4oZ^&%VZwouCl1Ba z5YMOC@s^AB)3aAY3c##M#Jp{Ba|-v-)kbPc;9+6vuCV)}V*njOLw;F$E?#6{#*yPT z6Okw9SZ~uu3cFJ5xsPY^kx^6DnI}ZrE!o;^JuOA6K8u2gRILd6)iaQ4efD`X4vx~Q zh!dj(*OcwcqFVrdM{9T9G$2Oj?ORKYN*uXs-p4k))rBMpvJ*F(?r3&GLXIbK6?yA{ zoG)zboL^$gp2F%gXY<1V#8}7FV1KQAb=MyYt6|eEbhB*6=%9^=zP|3x9$SA$!)1k^ zftH1PsV(1#ym13!Hr#K43W)uq>iXG_;=73STQ6)AQLk}a^{y%QNaT0}Mw*kh2WBH; zr~Czv$~AN&r92ey%jS=nX!iNChwZ&B;)nS0d@#U81DTE|Qi1J869K7G#N!o~5}8y( zz9Bq%9g5s&B*MzeTY1f!+_iB=5FfjppX%#VkZQ2I+d?>LloHkizgN>|K3^%3^8r&T zee)x)w3Vp_65i}}jgR45>e}#CUuL+!7dn3#(KtOQm~*&sXlTh?50q#*t>4e~yahCy zE7nd6{F$j!)0LB~N%_!){rs0#TD;SSRiJmnm6C>$df%ipr|!N}c8D)2?89~}t%9!s zLs1S=dS^WI{`=h?;54P5rRAe1pVp+)MCb0X6jnb$wtf!uAX?u@#1P` zTe`^*N`{D7YgoYA)eq>8z3(6D*k`pen>DJRtKckWteCkLu3VXkh1Bdmi3rSM&}{7p z;Dk(LXv`DOY&2hrSyy*NcSH7?ih43J_G}$*ENZl3!ErNZifOlijSG|Mx@q<0=Wq3c z@{ek&aygX@-bY!NY|UJq(Jf0;$G41^p6D3moIsa%oj7Ax&2)GEWO+Q~C*e}XqrM9K z&&!pkLUPPJoQU+*4b=56-)az=Gbf5p1&p#?62m2U!=DqAd4(SI8Rrw(Kb(bbSGrk! z>q9u_oFUze1^r8#1nj9vAHbbMR9~u1`Im?F`&lj#Zh?t_?$iD9b$OfmC-h+6sTkhL z%_og^VQE$#hcjvrhE>z%5k1dsBaMLE3whhXc1E*sIY)1f9zoMIg~ox0 zaJ(ACQO~T&BcSSR(5P%4vhkD8L+@FIk=icHu0lq#oFWfDciBuO;^GkrL%Pz1X~&@+u(t=~N%rj2`YeRRS)k*41$C&%!;Q72#f#Xg;*y+q zD#ahF>~hjR_1{cLYOGm|ZO=Dhc4NOmYloUi)u<;$0wWhIz1 zHAt>%-?hjUKATR#d`XCraz$aI8ArMTx_9G~84|nVV&hV(;iin1(Z#*$T@s_6@@tWC zh%aNF%TWSBT`odRO-^j0N(rivuGZV+Aw7oUH=b*?PQ|=W&ejAe>>V*ovUJZ5$|_R= zhVH4nOp|VuU{&;ZUAuQ#PoBFOqrVq|cDSOGPBN4ld489reM4L5#%?7vk!4}ow)_XZUIm{ zp&bTimpp_Oaqmh=a@aO`%hAbru6uhL;$CyESF;n~Gb(DH39q^T86L#|`e?v*J9(-; ziikWeEBA1g#9d9lSFvNqG5s0U?eE#yd!BRJi#&A^JZ&P4 z-_6bfrxO&fJ0z9pf?IoKuzAFQgChgIth&kToQ7-NLTtTiRFa#x$VJGr`5U|j-ZHR? z?}FY$eeejOlWzaeQrsi&n<#(i|Gu02DBJ76&Ek@T8_Vo(CDmtoZ@fP%WvsDA$SFaj zqOLBw-c8qYq6b=MkZ4c#;3Wijq{$IOS65MBSN@^p>WR{ZAjN|4*RBLSNM`NMWk;E_ z%V9;mg;-U1Q=FQ0LGr*uu23PEnVYZ)S03T!s(_Tp@}fjx-Mw1?J+gS+y#{Pj->{FC zKMc1rrDh>jWC7iWI}TGytUzApH{h7cGGiR!$x;;3h@?xvU@YOZ93K6UElBE zD;x)LSUBM2-Qf?vzMjWAtk*kmnu8BLPsui0y@_+vzJ`x9wvTd+jPVWBvOFl5ZJ)GXd@PFk%nIL3uOST7Lfhg*xkl=T( zP3ce!@mdLdE9xK3%zE77oBiE6L3l1kbC?xXdn_Xh*19wzOcWbGSVL6OUcqXVvE3!! z7Jxp0y@&p@p%b~C`n5e~$4;SrA2A5$^a6}d6Ku_Hmz7IFgG>H&=tNO)1#>L5=Y>$U zi1RH_TQ6q~hbOfsx}v+vBJdQ&YpHbnVG(4gNRYfbp{}CX-l4?IebHW|!DvF=>3TH| z%{q^Of5?r)0918pyU@ell2+$FONKS`La*4nKymX!41>qea_y9W4~qsFams;GXvh#I zUL#gRvHn5YOV?xyE1Ut2)SUgs`PeqZYGeIEHfhDM-!D=02@7f|joraS7s7TD7}5?U{tg#}b% z2aTa<7Bql<#fF6tVhu1MK#l_}>-X{@=*% z`{J%>Xxjkz``jIF2momJ@o&*R|M7hW;TITn&$(;EUAyiOID~r+(mm&{*PuKY(O=hZ zBXEaB0{3X%uMr`>%fdnduHSm*E(^dw#|fqpO2At(Ss{M-0I&e;(A-@O|2F)EcV}^D z`SI5M1r7&A_gjcJi)JW6{q)LG$P)?rx6KU=xgW@l~rdrx8hYP`(vY^WuoIoQI) z-Ode4B71;c-2NSP&EMI7S4TCq6nC_9booo?V*M)rsq`NLs0pCx=y2E9$Zn2KO73p1 z;J;2B6g%id`aig6rjBmV3H5*QQK3U@^>5Yh*WJUritg7ejL6|V{cDZgVgA3S@UQiG zzpAlDp}f0p`vkqbpyUbwtU^gBs!j;S#Q#Cj|3T3=&;CKt|3T6JLDBy~(f>iw|3T6J zLDBy~(f>iw|3T6JLDBy~(f>iw|3T6JLDByoL(%UsASx(?0{|M(>+VZZ022@c%mGKh z6aWL1fHGhOrQM*H>pkTJ)xh~rG$;XaKn>u!EASVZ^b5g8yvJ*yb=-bM)0Pz%H&Rwr zl9H8|yss8bM&8=N5e5pg+B>+ps7gPj)Yj3ZL>z{~tjJJ1D4=R$=IW%NCUu7e0xxE7vNQJrc*~#4A{EqH~(yu+-?*LX< zc_h{~rE-g}*EPC+XeT{!%$sxgRqS{@|ayKaKz7 zIc7lL20-7Rz()VcGyMnvHNgNtIQJ)y_7ijlzXE{jk-xMD|8Blmxw$zBu(5f1da_!B z%~++6|>ed~q^-~vR@Z`f&ohtT&x8~`sM2#5lbz%xJzPzQ7XL%#sId63RIn_te6ZrMO0c@H7O*a`0kC1P@vs@NC9w6d zJ+Kq7E3kX8Kj9GIaNsE6Sl|TVWZ*R5%;22i0^q{o65;aTs^L1}Cg4`#4&iR#(cwwq znc)TCW#P5qE#W=kL*V1#bKtAsyWpqbH{j0@5D@SY7!Y_7WDs-^Y!G}A!VyvsN)cKS z#t_yJP7x6ii4d6)g%OnyO%UA>Ll8eA79qAEjw5a$ULc_&Q6O<3Ng?SXIUofg#Um9U zH6x89Z6RGEKR~8K7C=@)Hb?eGjzZ2tu16k0-ax)Y!9rm`5k^r*u|au(@&Tm;r3+;N zRFh?-=9w0xU ze<1$AG1*h>83-9<8GIND z85SO*KNNZB{4nF;BqIVNAEPZ}3gajf3==n#6;l$^2r~>b53@CM3iH?__(%MY93Evn znqfg>5o7USDP&n?#b=dg4PvcfJz%3{(`9?d*28x5nESEa^FQSeoOhht7zKYU_nv3R$Ziz99*@zX19Xx&f)a7Z_({phFaewhv30Mhfi7<&_ zNo+|C$wbK|DQYQ8sY0nkX>Ms>=~fwd89AAEGBdJdvSzaRvWL%jpZP!QltYtKlS`EQ zD$gYEB44inqwq{2R$)PrPSHWJMhQ@oRf<(wRAx|iR&G#1P*GM%QrT2xSM^ivQNvL) zQY%n9Q-7)+r9Q9mP{UoLT@zDNUo&6xTuVYLMr%czP1|34K!;ezTBlYQQCCwpNB2}u zQZG(#L!VneM1R_V!NAL)&yd*A&alY{)5yfA!WiCI%ecV!%0$T|!{pRd)->7l&`jJc z!R(v4sQG*I9k4Js2E1hXnkZOW0PicZmVRQYkO;_ zWmjsCWN&O==YZ{C>(J>)?&#$>=EUq2;I$>-5j?F;8?=G*Q^<@dsG)nCj%JpdG78qgj{ z6Zk4{tLLxQf~A8CLoh;ILS{k*L(^Wvy|#Wm z{D$+*$2T`&=3)JBAHR)%dlhaL-XFmp@gd?i(jsy=iYF>H8X?*tditHnySx~z7@wH6 zScTZ?_muC$-k-!7#r4H=#iu2pB)BK6e31W8`;qoz^vA12tHi0Kr%9#Bq{(lR&r{4( z##2R8OVY^F-ljo5S%3PHE}dSTL7x$yiIC}$xtXPz)sxMaou5OT^ET%?*CBT$Pc^SI zpEp0hfV3d05T?+*aHmMWXtY?OxVD6)B)t^B^zCQhv-{`WGUKx8a=G&M3ciYxO1jGA zDx9jYYEZRz^pL{=iAX<>EOV2CBs}I+V*Y!7YHw(A+(63zPp^qL&2nf(4LrBp7OvuPc zC}_CoXsD=YMA$f(xMai>I6ukTbjF*SHJcv_c09U*TJjX zPCycR@(LDu@Cp_l0Unyd!$Y<2j%8sXK+j%@so+qXAmVa3zo2=l3O#*=$7$L&hEMAv zt`@{~L_jB@zG@y5+dd90h6q|d?BD8u77IPi1r@PkK}&=NXf?2K&;w4;0D^(Vx;xt? zhC{8wVd9MY;vGEA({xVNvbMh;f;vBu5S5UC`zMlsQ+Iu-7vqFqpR*ExZzq^u?G`Id zc+B^RpViK>b>V6{YuMbGNRWv&gY+k7n(OMQ_o_m5U zVkbx&l=b5vIE!pTYX0>BdjqLBDoYHHSbQzsF!Q_qGty8zVtJi0>KU~K&dMZ6@k@R3 z(aq$bbap`vEG%kjN@{AD|CQ+N5{-##9XwrOaUPo|(#2C$cMYkhp7WoyC1Quvlaq4@ zR4}m6Ng+(nvk=r`-aq6hjNHw?q{dxv5pUrLt3`V6lpid_WCAB8O}?tlx;W;>xT< z)u$8Z;waTo{-%;0B4M}!Xwhb|SPSB5)0r97>2S!mw)4GUq?O=Sazx1;QxxB9 ze@(*pl$OaviR5AQYiSZjcI7BZ`d4z6GJD<9;ONhJ3tna06Cabhr=on8{xJU)-bh9%z6KUHSY41x z1%^uKgh^=XsR?!tZcP6K60iTo zPD4APSdo*sKAoZcrS3|G)b2^dGT15;I$M~$)Ty4~AAV46Q&$MV!~Oh0OrFUsBOZq$ z(M}CHSfA;WKc4gMb4JiB+@6fWr==)Kx^Ikf2%QWKOs7<>FE{)jb&V_6mx$`!0(M8P zsFN9#e10=Qh7_y2f`z`Cay3)dU#F`pr6B-YhM} z9-k}EXj3Kj%F6J*l&Kh)WHV1M$*EK2D2NxMRU(25=yFbjFH_q4j^Nct(LjfVhx)Ic zzVOJ3ggIqt$~{B0u%1$*Yo}u13#R$Rn7;OfQ;n@xPvMwM^l7N1;anfSLh4iR+01>_ zx*4>LQi6L}7!j=}&z#KoiYo+9R25irH^k+N#C^VvC#unoVj^RQb1w00FObj>Ij@{s zav=~>Q|cb?==oxNZMAz@V*~P|O$n}w*N6JYn#g4}St~v2P+bCx&v%3>5=}zNXFY ztc(!RsO^82kW7ItnSbH`P5j*VVzBEXZY~F!8B1~n1^R0V!gV5v{S7kWX2$EX&X7k~ zRGGOr2tjMfkPR%3I#uZTKwFSjrn4)ECSxX)NG5Q}nZJGD#j^QWs?6(n8OHM0PYOQm zr8BJ^%R8iL=%0u`GhuJZC@4U2llNitl;DcQbMBKPVR92~H{l3|=LkzJ$aJUf3J45s z^rU2w%U>%9lPS>a!jlKbV65z?Wh`g~Zg-0iYQsNo1vZDm?1{bXyTkOr?FB)`UOUOJVm4cbtx{os%tpP`MO)d0{vp8Rk-O8FD{a3b0etx&DYX z(5`t4DDDa*!MCcn%YF42hxRUAK9CC7IlV)|sCyV8E z3@J;Z7}9a99FTR!$SJhi_L8~<3VwL)6j(aq=>8B~13T#zI3JRhv}Cs#<^=Bdobqoq z1x|d~ao-Qhdv0TZEOM?BHRZ;2s;tpTm-{j1^Yx}6mEXa3&YMo`&D73Eh3=d6v&ytN zc`=BQehg;Es7X$yX6^|Zn{y0Wp`)*BhuBI?>f^_?4m-5^O4ete7=-OjqkY(q^s`65 z_@PDXkU`B#_CLLcg}r*tq1elmab6X{>iSZbKgJ1W!*LEWV@Xel**xVQ$zZpfR0qGQ zHDu=An81^hKKSYuI2ldm@*B~}CBXkFc#1ab&6TUN&}0Ca>mF!eSvn!3i9~zuP3((Z zk5E@?7=+1vEZu}t1{+G6AZ<2%u1BMT%W-k?=@y_jINQUN%w#~|zF9cSq~Msp zT+3~sUda>ApUVNXCPrkgR-*algkA63lxemDuP_)@)aX zYVB;+&>zX(0zcsMiq8^qcVz826x450aV-&d)uot6RFIP^qg<92h|Qs62WX$#tr=S? z!USpro3x16E~^QD_oK}Dxv!O^Ft0j4I7 zqR>ws$o!k13}~q+T{XjBNOz)04z8y&&Adi#RYQD;d7)p3_0>U;Nj8!U5{Dodq}ZDO zbVJQm(VrBhJqk3zd&5A%ouvG|Y}LAtA!CNUbxNs4S%fkjQ~0a}xWO?`dTk-_k)~}^ zJSlCjv6=WKPR)hV<0jsDxR$HtAp)D+*b~zq{JWWN-+lEou7C3(r6Wl~&aWqw3qLv7 z3GY+oG=T;D6iKI z2@gi{`uA<_hjjMGDklb*uz(XH79x`^4L>%GeLe&9IkYA zt99I|d=B!O818)>3mIxAbN}RkpS%Q{Kn#O_avbH+ZASuZr7x z)$1QWnG&H$3Vyyd!z@iATxQ6A3}zuonDAC>y)4iydZi`J+CJPf$P}q?%0@bLT8-_|;20enQ7l zh}mkqVj*4dEjjV!nmBPTC&}Iw)1Y75*CQ06tm<-d-a0tY-uzkNvrBHVBSUDl>X@rx zo~ALk+hSSq-;q)h_sYO^8zclCMI{8_u|kb)p-b)ok%1_SRq zvs{>(sTiCv2brHCh(dpn0eOO%sAOl}7K#K|`PEbTo$`LGS<{}QM>$uc!L&rM zo5doosRbu#NSe+Gpxsw_a;7G}!^C5qvbuQ;9R@UKvLa3&nD{lV@KUkiIEH* z!gpYy_X%q$e+6%)&br*?6Is6ne|5FiqoJv$jyy69+i7bl5FCSSX4Pt z<^O3eGrEgE&wR9n$X2G8|D??@aBp*S5v%w>*H>M71-6Bx#*CbwFHr8qW`-JBRlraY zPl}vZam@^YKzdo|Q}K%cW6VzcHMN~Sx2`W^{KI~jj-=RvNl9NI!3~pV#oW>b;1<x zge^F5lZdyC(9UTbYU5;I<=#RM94x^qA?y`oP9JgttuasZMRKUAc0?Y_&hLcT=-Oy^ zSg%I%+yXLM1L7g1Ao9YkOT*F@-9(z~y1Fq8l}X-kOv(CN;A>?1N>8wOT336ZT@hzz zUvuJGoPx*6Ku%)Kf|>Km1G#aTv#a(Wwi|ZQPkfaV`MoIGf6}b)d1%kDfCK6)%L~5h zU~Q42uOMC)vps-)Wq&;#DT32IW_vc07K)AZSNcwHPN_xed?&V|*NA0{l zTHHjulu+iH_d3j}0nxL5>p>MX4!&|FmuC$h;~8ah2MfQhB^k0DVT@rBM4rC-Z!T%c zm#z(?Iy(`P{&G~|E?))HqIVmYe(nq81UxLpLh*WiDD7E1oXW%#GN>soQ z|yqIld_-CxkDt+QpPC$~lvhCex29sq5oL zBG+z3rwvp~P|y*xZJs4FtzLvf5B_8tFDj?Y({`ek#$q2RK+=DnHnS$$Wo!-{c%#>$bj{9P*aoOayo#3fhN+(p(T!88wt zMS-^Q`lBQI1THY`Fj6Rc)2U*_*yex+gKC zJUV)kuK5UgpDnvTgp!`NeqpuM+x9xyXKc_*{b@h!guuDUzV+R*eD6E4t+WmCxk15! zyl+ZJw~qSgILQQR+6-iO#=tVB$2KqmH<=~I;!23}il&85Q|O~mX1Aq7sk}2z%ib|* zAL|ea(>qcTeA0CexhG?l+$o2763Xkb-8YK_xlQE({h6yEgq4&iF7G767FG}bPKF{#7M|fOPw9V5Bmz^I*!wg_V#G- zWOwKJucm}f#C*%NgvBJF`8=YrzLD0fcXTdeotfv(BI@h09H`Npn-Yf=`Z-Ev*2dOK z*741Q-d({*Ou8SfEe0?IBfouoUFm>>v&LGSI}q6~q7cu5=f-VED8wc-=L>l>h*d*f zct9YrXFZ@Ctce~Lk4p#Jr^EEEqE8$N{X#7m)br$-3{{jQ0lX{9EAvm80K7Rb=~Q0# z?zU*G6Q;vA{2a?RWOga@lzFLT!wql)iRBN?WPjX_kMRYGGi_&8N=FtRTc4TPZvhNM zJLXsGs|uejiMGbvcLrY1@Xj?cSf|&iD4@Bs7OqmOM4uu23_32gB7SbbyyJj-gGyJJ z!#>13A2YhxN|88s>EbRwgX&8Jn<6PrlDH$_HPXEttv#vhFj3%!=BzxjV#L_kPE_Mp z0_%h*^q}^mC)RZ0ZkXUyKuB%_2fc7K`Qw!(h7hO2*dKaImQ(Rz-;gE}1o-t-&(qLH zrAT+f4|unqR_x84YKVDem&vJ9RZq$2a56aP_W&-f0SAf$V9yCH7A$Z3gT5|dRQe-A zpwG;ws-s4Dl5TLpe#*mUO-=)K&9f7>d!uev7h`zU15%@_UFsp#hKE}|Ei<~=EEeS{ zEGn#pN@9?l5(?fua?zcdO5ggysGZVT626xmyQp$-MAp?ly@xTvJ}3 zHX7;cW!cLCklXZIT8F%I0p;$xh`|c}I%fON6H!?Fz8^1)OR2BkDmc4i{a9tyh>NQr zPMo!fS3A!cUS=K8-imQjgzh>{ZI{yg$*OHyyzRxQfuBTL!71) zlk&EV`SYt0y9_{W>U!MgaNPqmYIbQ=gq~O2U-U;rnhSRMVvpHU7#Xul@*k**?!H;> zd&m1a?XU@^XRjb5kHdCv2~FHt33TjlFy>>AUa)M>dd~EaaiGRI;zgalL;6{on4{bK z>AdT+?5xVheG;XS(lM<7P5FwoNV0Aev&&M}@^7{oC1rB<1@A`3pRg0Tny*q~=#_X3 zs=eoNQ$x<&j?2RlPK+ zajAl#YA55YNDcPEFF7+GFeulnDyWuCkHU;0`W!IQpfAWKnD6A){M zVQs?4%$j-&2=fqe`dN7H5gVEOOwfgriniHfQv=KL{Vf62gSTl}~F27#$KWZP*$ux5T8~h6w6spaHSqQ=bO{Keerx_ z*fmNNCZ%qAp3hn?#Dju6eG-zNXw#wLnv)&#b-S_nuotWHN1yPEt>7MgM~&1`x2mCP z-M8<#xkAG+KPWYlJg1$t#8H&PQe>hG|9?o z*q6L%JMg^ZWWX8p&m#M*$&)v&F_#}bF$Bj|soW3|-R?lOgx^LN-7uu>MBct7-qj~yNzSi)bM}wBBnr9-CgKB*T->soP zx%h>9{<$#T_~_ZX>$c{CzINpPJiYv}uum}gpu>_;c`O}?GudTcSyzL|u@+*Gb27LG zz_47$@BLP5nbw&#!}Y^Shs!OF0Of^}IP9(k11US&+SaVwS&QY+IhE^VoJa@D{&EMy zKE=+?kIkCFsmHnxn?|1Lm}Esje=kZ>bV=-@R%&Zk(=WL_HH$+GFYFt=ulnzi5M8S^}{Re zxaWGcCaUiih*(MvqYUEU_e7B!cKoltuE8%#NVdI?Iq9l=Vct$i$$%8rf^i?|K;v(u?3N_*OZjAEU-yA;v1CP3}ati}^Ia z27$U_O)x(3SSYu4XW>#ar*4Ylx!Qyhck|;dg;lPGp$SS>L8;k;DdNb8$p;$aU8Ly~ z{e)&#R+|{!>vm1#^ZSB|)1AU!(@#{_2KzoZVWyMd`4rAceaN=GU>*{mKc@;$r8(}# z!>fL#>U>dLWo_&IQ$TmO_Mug7LEgKvE)vw_ExcoCEDwXRVb>N8EscWHMT?y9aUPJI zBL>Fdn}Ov>ed$Y9HNj#(A^e?#DdRY8MWXniZ*-MngUt zOC4ENCzYq&D-+B*9Um;vU6Z~9H5y~G>n$>5hZNNhNbRJ+u}je=%A9#1e}T!34Qctw zoBztVPb5<>^wT%J>ynp>f^zc|-`y)D7}s*2UqqVm5P1+JOzw~=QQ$1+eyio*_(X~s z&D>Nx=_CGBwK-N^WnxPIhCm48(E}&BJyAejAQ9w2c*2~fSj|;d zf)UO4nY5PcKw6(o#w;Y{%$sY-?4wJQ%o>jVcP={``)d+NT-)q+aQ{!obP;q(Il}KM z$!Vjkg>zuJgT(&S5rsq5?tTw0H{afyFWPlD8&hdhjZjlb?0Lf7hO+-iA6Izs-CD&j4-v( zN(gzOD|}ZZoN#At@&Uikqw1n*cjm80Rtr2Y<8dkA95%ae$8`;41T(Ks?fKFE>kvPwibZ5UHty=VAR`PXZ>>lIoYI# z4OSRJh1DFM9EOVriu}7`hc06c&BK;g)H*p*pAn86Q=csw*t0ahnTnezPfcmTS?7ab zYZ_?7ilN`(!PW=zY!xX~IJg zUi(yCe4BB9v$uH*5PgbO(h^99r99LV6gA)X>}>ZD%+pPp#DxfI_ZZ}`%E!VbhWRf{ zdzuI(qpWp%e%-a#jws*rv{|;8i}!WkOqI!FN`}pXHI-&08HEHVA0r))4-J$ zrCUa+so~TTQEn6RC-@X58eZ+|lvvLOMiS@Ig-Nw3Zd&jejF|i&oyL#yt9P9%J^bNC zb4M6eJkw-R?+W=_wD@=BC~1m4og zrI0CbiH#&ui|qbrBiycnOvp&=suXd(Do$J$lql~)xDxi7y>2f&m5TS-FUqW+v9+j= zS#?TYH2FAUkMuSK3r9+kq_3yhr3N?d)B|-gGAG-;eUS?bH4gVd6z0&oZr;{tcQP#) z^Bd+i9R-Glg)igcUk-2{b|WLE8${G78oJw~x%2we%-d5~kVwn(#_bVe5^X^D+MGDp zA5t>&PWHImjtuuEd>11NJ!BRK84l}QGozWut!(z@q=@nu^WW}ckZO$8CWOGSceQX% zmUwFHNX;gZ4bL((&N4mT-mw09SWydiwx^Zdwc)teKtK~!T3=#D>rl!*ZyX-kKemqa zZC06Yy;R!A)JOBp3~P1_v&OXHLyXZ$zALhqO$7N>ZTlG3@VQRX8poW5$ZgBQGl3bW zeN`78-?D-y%|m)P>pFcYBtv7nmY1V0J1i;Qt(_Tsd!0@)PXqg9Ws}dGk2DB(=EHyS zp-?%Vor~?wLhAU$shR}2h7jkd5)0|Y5mg|j1O15;gaz+lfhk~){%~-5{T5I?6;{Z- z1;WRU+S>cKLrlHbzwbPGJ507#*3A^cAM^Q8IC2w7bFFdQuaL>b?5#U1****HiyGzP zcVAdz_U+dOqq)4En@4pL@Hx#q5Nj1`V6(;7-6)OoZ*2Tf9H~B{7|1n@u$*C5qoMe$ zhn>Mq6t%%+H$|D>%|J6`N_odOPP`zUEj!;<_x!W>$Bvne`VGN?E#|l599rE5s>eD% zLNg59JU%pz2>X|+j;l(t&3%xyww2xVUS}0iuzq`bP#89aPZg$6nEdri8=`5)U?IMa zy<378lf!iPj2b8ZYqK=*7Ve3q>&!(P?Oj`uQ0ojcFTK|3gd4xmG1Fvk>nB|MIUHt{ z4#WMWipsiH%XwAy5;Fw_GERJ%U(L<(%+2f|ack!S^}bX73hvxOZbk1lj@p-Aelm>M z8_w07(P!}Q9nr8z6)VF#$4|RFT^!37EY@bq%I?; zU;XqTU$87_`f)W?5b_SrG9d2xqeCzf;-{6LM&J_9~0?~jd2gHLii(6no zr2Q)JV(q8t<!fn901!6YC`l}2q%NMO3)YEfp zJP8n5VqbiT>f@N`7sjp5-mR+fm?IQC_eF!zrP=&#oa_oD_&kdsahIhehNl%Q0fYd8l_cD}an&X8UE z{}_9#ueRPcS{n+K7AqArNL#G9L-10(xCBXpySqy%E$&d<9RdUm?(P;`3&Gv3!0+Se zJK1Brd;bGDSXpB|_jAuVubF2+@ivK~LbRdW-eKnIGu4f{S9X4#yso-qt}73oOOy*Y zHqf8jUoe3jvP?9aD)fi*`;b*}8jIhT^^a6K`g~2K4{K&CkHjFXrvuZ0{PGw{vhKeF z9;ki=j6qjBo`>(oJo0-w)_asnWle1Jy4KW(?2@0>8SU6XKM~6m-=6z5#GSx?8izE2s-ds+`l^W1X&^fimUg z2hfwmf9iD4rWk~RP&)s5xhd`5*f<$;%Pv#)xlz-NTLLJ&3Wptiw;8t#Gs>fK&EpOe zPdYO?aq9Q6Ax!l3!A-`>A3iphkoGAfU+dcOg^%>OOj)H`q?PP%hn%R)@2s6T@@MTN zz)S++>u%jKB8ju-_)@HimHyP7bhN*zOoM4Inbq0O4efjHe+0?93+l!Z9(9a^fF}L1 z^OtG>COK+CHha-hndlLw^EI^Mo$*=i!Tg#BhuJf}erojjmUM4{Y!U zUa>?O1P;?;yTylzCCe>Xapv#$A8f}s&e0jN*HZrodiCb*qTn+#4%1LMDxx}uO_M`( zN?&EVx*0G$Pr+N!rmUxS6$N1UeSyCr6b;IqNu*cTl&N5O+wW4ZaPkiJI+!{*HozN& z%qP#l zyCw{hkZ~W?iJRO3WJ}zR=H(veul2(iwK_^-{0rlC+cUORpPwC7;_Ox@?OQuvO5LyB z&T3Hyah)#?9GzG4!UIQ9E{DR4*XLc+Rx6ChPBUvZu>!S(BO===X-$zmCL-+I=Yd4rmy`^8C83ywJ-2-d}h8Q>&xxvZ}DMpmf-YfgnQe8=iK zWun-IpFQ%?UCtA17~idOELx@X?k%G=-#5H-ZQgZ1+nP?l7FW+XgxzBE$qh&5wFx}qCl~p2m~v*wUuaVejsx}< z|B^$!qO$lBmSz69?OcwnXBf6Du-D!&B^NUk73Tk@CeNcj{@h7G>mq=weE7tio}{y2 zmJ_GTEbv+OpnAUJxWoAl%lnp+F0cz#4%fTW<)FfXr=M2FHeeEX-z;s{l0;jOEEW6m zm)6^wiTFNTw_ z6mih7RV&{?zTTZg(44dYm0JC2mR_$bnF<|$zOp?L$`9IKi8vHyx7-%mvV_l`dKCT4 zHr}xK*Xb1nN3y{Q8X+?HCdOPnVh8-szLN%Yb_!$GPRxtPZQWSpv5PuPM`7 z+wFXi^qg`p(z0*0QnaVkKNU>1ro+UPoNHqzR&&gRrd98lPq>m>ZQ&zTLAd1^Qvx$n zJV24(=ib4ZJDEh~*kzxQGjFot7Ejb5dWH7uOlkg0y#(ue(LQEMbvKi1M(j{rrYHp{ zB(_fpSLj96R=8nHuUAl+GZYb;lytBHkh3X@R+-l&s~IDw1`tS4D2>_YKzaN=xntT1 zUDA2MpS9}YM-i&{%J*6z5e0)VH{UdJ0?+F^H|T2K#2chLvjME}mu=Y}DPDO%*R3-5 z&uOatWwI9Q(&2POXlA;9A=_Z=ok&1)l)v!=+qm{%&aO?&%-JlP%^%l)OpmeGjC0^;E>J6JYnGRtMjMtQHnmc zWWPKw0aS&BK6YWbVlUK?(-F}Fo9rTPYjnF*FUurCv8u_VO#(4&c@Te)Oe(I))EEs!! zr_1$1r>Flofi!hsxj!Q}yieb}I*GEL;6WDDdjn0)!sCk8AM^-J*qgZ;+ z-_%i3Or9^e)-!8p3I1@e$PO!{diRDHm?}o-&KdZ3hPRymd)N>?xxw8U?Wf?EeDRgI zEc>HMJDeLQ>NP-t2#1HNCipxncLM|(`?kbuHnkee@~w7iPL9*#O&mCB14u5Aehy9N zw>BNu)|lZ$imqre=Wz)H_SD+;VB16{;c7WFETa)!#g7Scj&;jS*wll~@&yUG=BnaE zB2NOi9Irr2AEugvrAMlD0o7O30TBIz;I zQk!v1-1oYxX#%LUgfgl^{U9B<4~)lj8s%~5CX2I#k^#uMpr}DFeSl$dmJ(_~s&X8* ze>}zip>E%4m1aujd67%MbD>$AMo@U2cQQ}^NtMn}B$dx-*~-&!!s}g*8T#Bbn`TP>z>UDNQYV|p zvXb1xjFplewi4wmY(2UF#YF!siX2lCw@%{Kp?g&egZB2Tl8C9q+!>w=JA$vFysZ`4 zEmOe_bzH~v1N>+xBb<|3cuATf=Ve^yiCf81=$>-%a{a$RyNhg;DS($MDP`swFKJNP zJu%)VX7#Vz^Us-f^V~dv9k;^0Ogdr5YLnHmhk^0fp8L`L^bcnPEcbxTCUQ8=eIg%h z!6Bw!&!b^^Hg?NT$a%rqvi8w;qbap8VD)~W^z(Zz?ZUq%EF0?rV+)tM1=4ACd!>>W zt6MhbGyL7AUuXze0X$TmcPwknPZV(YwL9I1@@YZw063D5313)JsC!Mo+`-#LTcH%u zCTPjCHT3ka91@Z6foEi+`yxI*0uAR#By~c+Oe29eNvnFr;1Aj7{1QL?*V`OkcrMyE z_}-Q^8Z-EeR{o>HffqBftHc5;4gy&Vx=^>4eHyDHk0R?iTOM|zu8Xn*GOO$k{Ol;7 z6bkH~4Z(Y?!X|I=qB@l{zVLigdHzZA;vb7q2TL!;qyApOus^xj@;m0)vc>w_n?t}Y0fH#dH8>5^4eeE#5MZb zw8dTWYp)s?3Qf26_oA-y2tL&bFJo08W-IM=05hzpF8CBnK9Ir%2_SA zT*>@Y(WgV~xLt5kp^%f_SiB0ne-4X_Vyh+35?hOmNXE{Zg#wy&v5M*HS3V<#JW8xq zf__LQKZZ??ZuFL3SsrDD4yP`1t|4bt-+G)F{BQfV0_@8>71;zO*3;sR-0weGu2t#O znHWrnS3PuN$8%AwEbq1W~QIZ46NIQ46?~feZWNz*_EOb zR@T1N&m)uQ-8ZRX4y`1bd+`c$E4Gf0p~4`ZBkI==ikHVEG@q3WSjW+?W8q(J}%op*}vy@?%B9xzC*N(hOg)rU^PGnU2qFYtw6n7UxXCth4GyGPq z?8He1zd9UkSiQj>18k&}iAvJ1YVBelD!NmR{B|I=x!2Az+Jn0=lg1enQbvgk=AYXf z%YFxjKal)K7PnRh1%=RiIjB^vk4@cTtW81i{L9v zGzh$;3dkDz53N*Q(!FA#aE5A(E!Aug3u0#L%0qUx0#N>7a1PujVSn}SrMb^BhnI`q zC^pPB6IcQ~KeXJFPQ&dx3(s z4?E>Xu~zqnteKhZ@`d&e%NzCpFpxgN_ja7OtW(v)+r4k0&%3<73@mJ#%8n8W&bG#V z1F*ari}};|JG8(=-{r~y;|lk4AzMvpONhN8fCPD7gc!TWK)|jBY0ar zrCdE-8C&$7--XO^6K-8%aZ!n1$pq0i+4QL$DW!+Tq7?L2nac}3)3Y%lkCFQ;u_wOS zGmn)YEy7c!JkG<4s(=*GTh_SuRhCzp0E!vFCKrciM!?l8c&hRuFC56u61D&XgtW-? zfqj(Hq71H?6Q{kDE(*6lHzf}$y_C|xrx*5mB61U6bw=40=$_rWYcFNksCEhe3VC9{ zBB5ev$QVk?>{#XcE4~#~O3gLoVQBW!kNsRTG^FCY@zC())fL}D1}`P_aw>*vmzI@* zq9!m>7(s%QG|E#ECzIYL(-5cZ1lpde${X`oo1+Lwdh-X3^BgM8I<|7xao@xH#?^aD@$RFay{0aN*rA3vx>?I8Lx>FwYrqfI-3QNV2cLAu1EA{b~qkW&_ zW^*U;NyxvBFZg16Hn|T__g&3w?GTL|S!Z>$bHY|usdDMBm7bDNlyhaH!oXxHS>M3= z72|PvOe{PpU_4f?eWhHd>q=51Yt6Gsq-AMEtv7{h9HqcTA8f)y&{kk)?^Xz9(UJ%0 zndJEbb}Sq(zFkMu{zAruixlnM$k2#|s7L{%r^w{SRsa!?B;5KXY=YZ3X`<2D#feO@ z-8#-CQ~-=0xSAfJ2}lc15PG6M9&fZy9EV|q{rhxpv{tn_+k$Iv+pr7QKm<6b?BxVx z{Sc;h*I3@y;K91CFu?v{Ie1UX{5Zu77;p@2 zDj!RpMl>0<_xYzV(u&zD_>n~AyD`hUugIDQ$h>-x;r)&9M}-6mFzdhz1sx%y<_?#s zt;|{uC53JOM4NEPt+o?E-5Z9nJ5GOBPQCsADCAVF>>lwAGECoxmOBGfA$*4U_Wab! zg-@lU#nx~~WqfY=l5CizPe8_4bTCF*eJ4bh-`g*>wbL=`<^F-48ao)AxR7`quuwzduFw zu#F27coWS6QzgL+4L7f9dyBwN$D(d==$#8+fuejIneRqW!ePg}e#!MJOJ7c|wd5$< z$~%KH4J49L8684Vkifp=gOZU#VQ?LlDfv@HoUZo8C(5PesDgsCXTzPAL-Alu`+CdOlcFpno}k zj+0W%W$Bd@%>v?!?cP4)RkW{<2La2}hkwG%r%m<;>JwQ%yrX(jokKZ1v9-Zy-Q$Q1?&ReU|_1U57UY(UOl1w zzG+E9cW~stmr)&T4ssFxT$++^Ma>aqmd?#sia=oQs`F{}a#>;u`B8JVV8A{FkDw6pmE*4{fJ*)UX3&5h$o$}~88Tmirpxl0%Y$Otn2=a|?;olCzS}ooPP25k6_80kNu>NZM)l$QbCKyqXg@Y*ZAuAEw21tS0liT(R_$7^q!ixN;i+BUY#qBgblaIf zCvoCi-b-(tP5K#Z8<=g48W;C=3kxO^Lm6BuhPPwkCV1{FjbqCX0cY!3k4a_!gr{Sm zEI;=8#g-3pLr24;jmHRly6*!n8ihUj^_l7nM)~W?k7}Ohj9Y6fcCAXbdI3t5aH1#q z*LmJ7#cIUtnuXhnxNBU$L*2h}3RFjgf;-z**ZPewagEXfqC6NZP5&OGrtn0bnnJe` zdAQT_(oHnnxx}hgDqf8%cgvo=iHENM9>#T;{`dW_h=*BQJ6Dmb*`yQIcKzXTgkOqZ zQp>+)IbVv7L8Xfk^wIo#W>Ss#uZ|s*XRONKgnWju#b(g4;iCe;N zQv*f}v@hHlrpsULJGClkAgVkz4F)YD((-0M!={_gS6HsC8dzp$MJB2OTh!!#w#nW~ zKavP2=apP;XBR|k_EXd?#u$ec@;68?L~&3r3H?o|x^^$#!^cb2YwdeO9o>-O(o<6A(yH2b2U!nT9xgg1r}?}?oG;UzcLAj_ zbY_zVJPqC|Q)u_P2sjPA^!-)HpHdlkliT7v1sxdYjgH4Y2FY4=akS!+$)ZzE&g)i-aTAR+APpj;;2%J*6~owN|V1zPdAA&eJAi9K2cU!c=mYN%Zo zjkPDtl|fK;@7f045b0Wr)|USoC*Q4&n6TPY7#yFzI;p;jg=rZ(|Ba8oBgz%ve~^4mIdBKHr+B8jzuw#3H!N(BR~lTpjtsM-V!^Ko z+~duhVZCk@Fv+dr!?{bt)e&Nns3EiddY@jZe;@z`D%WV=j@=U4KKI!fr3+5oJ09ze zqO5~g2`T;mL+fEW2XiTHx8D#{^~@C~(LFB%Sj|Bc@!jegG@hq9MTPE|CK1NK$M3`0 z*SaNacFwR8!@7=@5ri_?L-38R{n-zz`i~G9(}Mc?OuY{7tdysrOL8Oqw|P2i2ll+x zzInDh)zo-Y-iU^QyT5Ga!c%R$(?6Dq``-&?48Q0+oKuugp$36ipDN$>5()I+t(5@$ zOx+P$#kTVZ?eeD^%?`AJBJ@~EvGRxD<3^#e+N$|m+Zn{S)K|;o|7>&8&G<6f7R76P zzpf}T&)8nC>B!_;Ti9MsoNj364p(|@J{?e=@MSC%BBouoMRK(Ei}!nZAJ4iaI0(W7 zjTG2uj^o_v9Mpt|uNBM|o>MtPOm|F-1yfCz-8vNT7n!XM<7w-t2exqrw)bj#Lm6}q zu9WJp3!j^)Y=Hm;5# z&H0HP-n^2{dhS_zdRx|CGFV~{km?#GZVrZH1T^OHS1X9IgKh`jsnqPO^UqAH5%%j> z`pIrFktckac293T;D$Oyb!U`AsPKj4H?g1tB`fcsewmH_=9n6)8s8|_2?chtM3T~c5`ZB~u<`gvg~agh`(_B^K0xzzX^WM#1m%!+ z3oxT+e%%~bzB!>lVdtUfxV%tsidTE88Em_faG!odNs?nJV3S&xGwoGOzLYF>lqFON zMZ37G5ZQJIVFtW%B*6YO3jBD3<(T%tBvPh*xXk@D<3Z%biRA=wbLnpB9^33t z$TBW%=s5b(*q9~R0C>d{wtGce%K=IGRG5!>I~5_Y8R2u!rUz?-BSw5pp;vDrGXd1x zw;}eX(LK;ZeE)5^ZCG#bbZ@y(vX0M%#aWpZ(FWRmjK9EAW{bbp-j}Ts_ZWxz(q-af zT*$}nR41hccV0I=DNgTWC=$Q?=%p(P^4yj>C03;w}!!3=3|un>do)|%qg%mRL; zLKI0^BeL31BhgY$<9Xy`uTS3COa+^$_xVKLWtLV&mK&1~EY2eG(6bHDs=>xn_fzhT zdQ!xhR^ko~|9j7(L1SkH3&g4>DtY;$&9jutxSjXKss_}Xh$6_S3pO zByjEr{65Y;wla^abHl=__XmUjQq18IdJ;B>K=AlvdOr%h3ox({HC(2aS{Yq}zh8Zt_o28!x z%p6P<#J*M+TVy$uMv>k%Y{uU}rW0CjlnK~hBokNSkwn>F4PAN)hpmT1XLS?fX$}h| z0c~s2lSV)IRrr0dwA4SD^x*&UF(Yck>9$3fq40pdDUNtFl#0BwZq=wN4Uau?ei)3* z{ESBDS+~8FltW=9k&~r$U~TXjlD8ENM4isBU%HV9utE_va;mC4apRwc*FFu0g#%bv zQ2{cECR_PiMH7LqB|OqtzSdINJTMf4fsLh>vj`^cjg042atwnIfvGvz<_7ojC}>V$ zKiJ9p?pYdRyHEP2?J`Q*u-~+;Oye`^Pr)tXzr9t#@cGZpQEGCz->P}=txZyZrnK(0 z(`gKD&_Ak!mdSYa{j{@Sb**9OZXVU1yvj+9%ksY2cROWVFimIC%U~UN=E-Rr-@7D-FchtR>IseJrEfhhXa= zDXsUOxAth(f;@)OYGjzfiSt;p8AJ6#^4Z<)0)tfHlgTq)#*vDNyZsjwLdLFf9iQF9 z#=c|{c%bOu*hpO0Jf6T|jpy%AMObFoYfe^;A{&$gHWaJ5Y^s*r@4yU}q@pr2Nxs{& z3?wih`*^6dfI(+^e|vB}UKiTynNr^^L!3LExTk>Mvhp$Z*XW0F0ejnY;xTHArfM{D zw(_K+MP%*MaAQ*j;}P+Zx^+Ny^`1N#2S}ze#@L6t1s#fYAhB9|l?ZvJWT^Ij_?ga{ z#OA?(7OgL($R6~l*OcT2|9+#h%&m-I1#6=fXAkT%Mk()?%N#N5%z(Hu$s6)Bp)b3Y zWhvxTkWBwo8l0br{S2}u}R9z{OOqJ zpysN*+|*B2u~MWG;ifC6j=_X*D}v_-7;#F;eKcN~!;DN7mCtI`0Ll9hGe9E~SHQOm z-@a(?kRP*b$_og8jWCF~(yhy?6Fssg0Zcz#sB^rD(|Hs7ONciw23Mw33|ZHdqJ!1P z7#uc74&*>#qT)L@k#o4?t=m%z-z6m?@*BXcZv3K1T{%F>8c#fUJEn4`58Zw-oltK| znPwYZyIP|G+36vB<(E;Gu?w4XEitd35)aGDT>;LGOZ|2q*y~o9 zj!rTeM|pz8h-nhrDM88D|AOKt-qqiy$tdT;`@(d7PgnDZl63<;nh3ox5=xxGeGw7H z_G+zVn&E2n4E91iw|F~~OY zp_@S7r3;RF3$Xe<4bCJQ!6xQ8YawRHsSA`1WbcLm}1{rN|;#wa1)gy5%^ z?q@4pj}tEKh}M<2{#(Awt-~g1l)Eu~`I~yx_}<_je9F(kvIVQ0nhwM4A{#}a#^q(y zazYGLZg3g)YX)RJQda(12x>Xb`ziDLyvTHQgIg12Q<`#aEy0jMt`?C7`jy&Htj7P! zLhpxsJdv^zk4|mT@NkZk-sKEO)1Y}S9QLRY`S7Z*_iN?1=)=PGKs;y3&)-5ZuyMQt zu|JUGTQaXdtMdI0NiU^k4|SW)8lB?=3Bng$HC|N6&2_iQS_ffs;hbsRJak<>H!dT9 z8z_g(v&!(7FKlOv44erM&Ta{VineDwFQ*K|4c*$Nk7qF;Z9gE z?(Q?9%0owr3CKt{$G;K(xFT1cj>vk~9PE*L`_PEv%?oYrl|WI42-iL}s+ZL0rM>Pg zhZD@7^1Pco*PWz|cz>y}>_khQdQrD}u5%QRtf3dsQKf=jH?{~+a#U@ZQ!;wcux~57 z9w2xw6I_l-h%1pio&}zr2A9l3%mBp`WWVGcwfqJ({**K8ah)SG|KNLSyyb8yt808R zuYi-hEc>czfbCc&)muO+1+eN2RZQn8g1Sv<9ven(#i0NVdZxmyV4*K6P%B%lSJoCL zoa3*D-50uxMZ;^$6YZ_|zXL74kV&vI17Z7{4h+AKx+VlphMA$p_hiCX*W-`eo{v@@ z4-Kr<=wr$sU&`HK&CQEs=v64#T>P{zp!qaa&n5I98dVl(UTtEx-TaC}LQBY`aYULn zp~Zd~1>BsdYAqghF0ifMvTu>Yqhde{VlWO}?yeSy`~yj_USy6ge<%cAl_|piy7HyK zk-V!X8ppu=Rh&dT>>mLnKk{1(riQJ2dGB*-uWAn$&G8G-Y<_I*R+non$<$Jc&{ZFk z;TwNFBbUVv&zskZhB5|X&BFaPdR33llY7bp-t?;!Rz3gsOT#nSS=UA5)FrOh!!Pr$ zli1I2BYQ{cU*m#zoPa{7+)2~$u!;rg=+Mi{c&*t^UDa5;ARm$j{8P^8-1fuc9Vz$8 z6J*sm9i`D;@k)roL<2arun_*xFDi}L+WmZY43T!KP>_^UFPiMqVm0W2Bu#2DOk1Z@_ z+&4akCl2uAH+pDwi3m&a-%#;VUOswV} zlOA9_?M2t_)oM}BTNS}kFin#L4Q=4WH-2H6a1qCPx)n3GZ6nhApgqr=YJT};=Fw*p zY(eC^7zoAXJWznDG&U$TY<^o+kbdQ0P0bW9Z@9<59=)h!&Go3Fiht2BCbzgvMFVW7 zAgUF#-rb1yI3)y^uF=qTVJ@n*1jxFM(X5Z_YIY|!SBR|KW0|P23P#(}n^n$CS}Zc# zd^>^f18hT=x~=?wu|ytzUEBM|R;sLL^%xuo6W#A;s7#5*Zq9e~tE-F!=sEL?G;@wW2L2)J7k;yqe|Q1NI9YdbZQ4 zK8lgBK@-P*Eq*MYOwtK7B_hr#2oDiCqPCBcp>!UmBq8#hBT>|`h>Akl<%Ax2)7nCX z6%*jp!S$wn!aDRw^2_5Jc&>X<@jkfSVKRx>YJUhPEM*a;h>6GAUA2Xexf$bCfg46b z%rWG%OcTxkYwk|Eeb!Q1-b867#fX}M+AaP9;^QliHJ`+&_w4Hw8lMUg)}r6P(vRoxXFR02lqX$AY_vS^)LJ~&^M1#W`(@1L%G;a`Xg}M?fuT>s znrzZS{l4;|3VdakbD907@mRQ<4z$GFjr%q0IVKDt>*E+s$KiApm=5j0@vg~HP*T!a zq@6JJzfV{c4jiPN&cXade>Qen%ifw`^t{$wV!-sL<{tb9oCii7_*zX}fym-EcGQu; zGmo#2c~8EAp_>mO*0WK9g9hqiPK?Mk75r8XUmj_ zx~zRMPdkgfy<*EHWf|O$zuyGrWsO|vL;&xY%o(0anUzz_I6HXDtiiK9p4yZCqT;%i z+9Se=61stUvuw_41bstjCFo6b4%DEJ*)Nhe1HPu01h@^=@oS+yOfvG61e9N?zoJV3 zNr688pBwkwI{*N8)d8DV#fghh^~Cxm)N5VKX{8P%`2i&PRSEVJgoR@WBK#U?+3o66 zYLD}hx$k*2*gv>tLRPCl9Ctt9DrpQ$gWlo+N~~=`6cYAdsD&$N+9CL?lJR}7f9}v4 zuZw6^&URRRfqkZapGViu*#H&ptgab*DZ5OR7nwP4zl9?}nn&l#E-;)YuoNuZHImZ= zTFNxZD|TTMBgFW$#!*i+OL#+~PR#LyF;GqZu-e zyJHu}>ZmbWt1PZ4K(X3S{QeRY51no>0+4?q+Umt%OtMEIV#m07mFw<>RcRNR|OVLxUWRY#rcm-54F`DNk_wz`_@wb1@ zp2Nm_vTl}qrqJa-$IITBH!ZRHO}Q+weW1XrFm~vtvUS%Kn)C!PGMkq@QGVba1p$VI zU%op8+W5W*6tUH%4n1~tMkYlFb;Z<+#a-Jn(jiiLuLSjiNM`GV+XN_gTv|O=#$9(7 zS^FaYML+TO^m#tWCm{au1Z5^eU2UNn(}$g>82k&l4iAE53AQ?Y|bT4q%>( z>M7w5LgAJDmf0)cRx746{NX;I^#_)`C@u`$dH#w~x5eitYFSn=&A(Wu8fGu_X#<0d z^dkNr8<*tm-Ddrdw*+S+_I-%G9d{wyZlzU|yb`WXtyjWaJsYch&vAL9N(S%!LZ6G) z3x%T<+9RNzvV(Xl_GtoTHn2N0)`-Hu(Fqq4vV(kPIOho1i9Kt{6%eptx1| zqvJm`{cm}(@_MO7wSQZlxq!~CbynK0LRPk^YB`DFAVzC$3VmCk@G$lYC6_z&DIZzA zP`m?=>;gMHWb)rF#GaX4(3Yh|WtzH@&ECJ%k^wdE@1oyE^P>q;E0yNf33eVqzK4A; zp(Iiu7&+za5Q!tmcO}!KJm6#pHz9|9gpBJdtKBy>Qi^}?G6`)aF|onfFl0~UBY8~6 za0gyeh0o{|tbu$}mkf>BIC-j>>TBP=W(5i>iB; zp`5di>1of!_?ug|LoUric-uh!@ROR&`cGreO)Vm4 z*xd*n;c|pw=)b-qGn*wd869K|p>Rc?h|yol(V4Nu2po&{Z@|lB`E{;yvACWnqo~mN zA=vMo8=ay2$yGI9rl2TE4a$>()qW0ER~LF&c*ZGGY4V46)iLOja@H2stMBX{Cew`E z5#{-{@gG{aS9xn@znmg}v>Fyjmim1gan{!+C9c2R15T8G#SW8i2@zSs1;Uxl{FLn*60YqU|k+G3YO!jC>jMr!@a^&StEb+2Z#W z3kqNSza^{v2}l%V;#I&z`_Pq*^Yvq~8cwo0`uFFW1&#lMWg||)2`6>HB%=NQ0jo+O zC6nmltLf8Wg@ncp_D$hw)h&m1UZqMZEWj`J2@V&kG_Y5Ahy{wS4Fu(fx~AC~X>KW@ zs;qzZhg!B#u=g?_CgkuY>typuy(tF*IR%sWBD=?0zFzMDV8T^L!*vYR3(K_#U6vqu zXn+N07S_(#cp?WwHDsd_s@*Da4bnFv49bF}WQ_0Z?B7^f#9N;8JpLvB;H1A^VF+%cJ$ zWLz?ctEFpE8VirZv7|L56*G~2O*!u5iVyOxVQ+3L>NgY;CXlk)jGP#Nj6}7*(&xGJqkX|mQld-BrNN#nEzq=dnbIdso6O>snPtA7mlZRwdZ0o z80X`*nZEkII{+E+H^Rn~Na}!mTzc(FG{;rpx%EN?DX}hjXL2Ft6X(Epsi(~2cf!39 z+tC=s%4Q+VfSt@VA{@3Az0wEemLovhDzBTSqnPyd z97|GQ;ppT-FN+{_N-**7sLuDhJeyIrgg+Og&jQD7$D>v_fdnl)NoIf0rL{Yn%@?!% zK17-Qj>lcw6Z%7}Epzeq?!j-#%S~nfyEQ_+_Bw_`1?NV6@-ZOD=;~_Z&WHpF-t*tDe0ZS8476ixZETK*LUs&9ah{5?gfnMx!*&dqYW4GV04+`#q( zVJ}JI3nfs}%vE9qrto8FsTbiYVVT^OITx*u5L$=eitr-`CWW*WZM9FLcwGTDWTUPo@dIq;vi##3%7%f{ zUYUB~onA+Zoy)vx1RZ|EiYoG9y`0qnZ%{h`)mujwdr`r*yAl^ z>n3wNBuX6Vk0Wb`jsHyU>`MMAsJ*=0iu#=y&I?;YXZi<-BY6f_dPZ(mRJDRWo74G5 z4t%wC$H4hVgAR(oz`4*aU_!tSAiI%P4YS!i%>Ey73_fOC#aI>Nh!=d<*v#hwNoe?s zfBg{qKiK+2grK*Cs_K}q?5`S31yTd74FtXkN#{T<{b^T7T;nqQqeR16xid? zGXFLd?=i$ms)zNIgb6H#=0z#r)iYe^L@l$p#}0m@Sa}9q#d#FQ{*KC{!A&WvNDRAu z=wZkOzKOV`>^doWMg`M+vaquF#Ptr$<&}RJ59DfXR zyLA(*@5b~}I%XxhX6L5+M*p|w0>txI9R4r(jgBJfWmelu^pjl#dqnpqOv3fi0(&m- zj?_n1Z{2}Fqo$-jVH;9Ee#*I$zD*D1z*f$!-YqJXnHRX?*ro|GPUZDvlu{7Y?d5uX#S{3%XzN7M`@-b#z&j# z#tnKO7R+;;Nzy?&_iKBz87>vUtzxV8AT{0=rO4(Mg3Zf27GL?Ck2zK0D?xt`0&#z& zQ;B~xPZn#M)6@KtoG;IFcCO$lAHoLkFXoQ%=eM8K3irV(kIIzLu4@h(%@cV~KxE3gB{If}t!gs&(*ZW8$4bPXnj zl4LQB737i7Pe&@-ZJ)vSN-QYNCZ`qZCf+c^$X7`QLEK1_bicILkz3|@^o`I5(J%H41W!4p%cYmDLBnhz z6{Y1tZ%M7wPj`eccRnpuPzPCBT751lN|;oBJL1Iix3;Xbe1F{wW((@eA7?gxi&*~D zfZ-QT*8pi(zpm9vxW1uG3bFlj|59hH0w_(S4%X z7^n&$okPjp(yt+w+GUd7rig9Ruc9ym1Y$s7GjMb(46zq1s7|F8#8?K?4|{ehlE!UqMO+d7?)wOCGLq-m`z&6JES{ z6Y19=7w5N(5_!=d74N`#332a6jq)sQ$lgBI%Y@CC}NF?Fpv%_tQ)RS@Q6>8qlq@O(90hK#w0{zpd#z$GF zgBOjX7@atDp&cq!_K+}(kmavbx5h!UYQQ#t&0;z5z6-H;<(TStPb{1B?*xF4{T zD4gsr3cCoaefmz=n-sf^xTpzTI){*?@8tF;`2QvsOm5t=HZH!A15){QWVGj(AD-?Tc|7*&iE>PT5LQ(kDeyo4CY3MVld=$0#%S{H@!r7UuR zMQ{H@V@_nHeK+B@y_(}*4qOwuWY%&+r2K;IfrVALY0z$4Wnk4ww@Jj&$&T(gU;jg^ zHMlT#@G2LeBBOo7=1!TU0E7}O2+2U@X_)IVnH1=`hd)hnV~D&oy1dQg{wT zHr_EB8z#h4zevbfbVK^-mXn8QpbFP`#bc!ZLrbktJ}&nB;o2CfCnkC8zn~76U4kWg zJ1I+&ZkF!8cLIS0qhuKaz9+r180>OHKRx#TW1^hU{rmm$C2mS`)Yi1*(p2CMCXa!; z)_OsrK8GFIZFBaJ-x9Vn2A@wtQ%TukH1~OX15Q}N%MAc zQh8Eyr^!7sqBK$UU{%@VT5L4kp;O)J9LfO>4_|@^Rr(50A@zR^?IW>KKqx?=08)kk<`)i!^>-8dd~Z2()z<-;;mGx5G=yFFlm ziLD@dow~sG#1Bk{F(rAoWW(EUmVk*V9E`)bF7kui>-#@z6s~xAZS^rk$9T&xa0R3*s|~n?Gd;wl|ZsLFd&1C8s{L7Hynp`mLxA5KBO zKvPg^y8z#Y&AI~(7}XS%u;KFU4MbD%H|>={=|^)4HX^06lvQ{PzKa1XfNz)bPI7x? zK9l=>9Mo`Z6@f)e@0f{VPBt97Js2}iui6gq=Ip$T-7lk=`rrZxpFH~LnS={-pDS;T zCeyAWUp?FHo7vI6q?hs7=N}kw5|B!=#wUF<$Pg25 zlZi_YVngBNzD=uCU`z zXelz>^7xO$Yf8#*2GM~B;S~C_m%@rG2wgi7&7o`XE=aQaQsg$6kX~ZJjmzbQ4#?w5o*M|J5P|2MSBVQEjS} zwIqyVY|OoJ+V#wrygHufGE`J>1j2%U z!SI{$WQn(#d%LpsHOaCmu_otdn8C7RXAKO=ccy1mTongiiN4Py*1)VHq(ov* z_Ee^a2%^U?_XKp9v90sNt=imT?)&rebdttwhbCjT2HmgUXIHt?gWR67gHw2W(UqrTH7df`vQ$g>WlZ_iSa07=F zkHT#iZTy=C;txd(yvsEJ&YB7tjW{m#?0f zGR^^*>xPFdA18l%cJ`<#+GBS~QPESn*b4r@M%PBqT2In7gTZC4ch0n)zQ7E2S$NJj@>Cp$H$Wso)HZ5zu@xE-O%} zuw$V!VKP1}D!F^SG10iRA2&gBi;r4HuguN3S@NT+8If6#ry%y|9NsCpF z(%pozPk=9nKcWLQ;S}BkffIqQ(yXVkzX6|hiK&ifwE4yXAF&`l)RV#jRu{Mq(9}Yx z6ihDucv0|oqR0bJDp81y7J?WQqR?F;%V|=8a`L<;PieUj#UBhp6)0%{9dI}AXaA7t zkAaSdS{ABvWwy535LNuPr2%YYpWO%^)#!Yz)ol8szZ9bGG1;t0$Dw+eF-xAD`q zp-jJjyKEmkGdnwl(Dd;t^W3Uc_$0T7aY-V$^4oujSFV*xuXf&NgFb=|nwJG@*_iTOXYhKfiqo{^VCXJR%DDLoH@=R>sYE-P;*ty2+2`ox5pDQUEE06vRY z$@{=bjhRN~{nC0Q%0;(=R~)cG9jw{9C4G?2h8=&UH7FH@p$=Q`uKz2B{q2jv*T7Y% z-vY>LER;_qn)wjST_qLMJ6&+MU`xLW!M;`qA8R#oos8LA!{ODfnof?C{Wu_biyg`luRiVXwrO>frneslBfBXo>D-&g%)k zGr`XB>c+J;UXy1%c%;e&q(IUV+wDU(Rn=)m!d;ET;z1G zG6;@ZiI)B+wLkh69}AGuE&B|SkIXL8Dr@d5{18Bp2_Jd}$!pGQc9V&vi8KLdf}Vtn z`UC&qFD3&B^bzwp?jvR-V5Ox)t*u_$Di92Fe9;X`z3f0U?j{ytGQoMhu^%^0$wi&GnY5&R*^OCXXdnre$`gGia3QfFZkgy{D_NBVc<=x+%a(s85(oZ|rz5Eb|N zz?IRsdS^dr-{&lKR%sBS9+L~4@n=fHVD+;t;`i#tVOzJj{EEP6U+Tn?Wd>&?<=mWS z0W3YFuvUJn$J&_aDZ>Yk@3>%3OWJ_E!>@@*o9^@5@sE~REgwY|96qVA-ED2_l-D2 zTS=SEBZMUY?y~{Sei20THVfu@DuI3?J6oW*XroGGQjV*c7oZNJAnYL~d|X`U_htlt za)rN|o{?LEskx8V2_G?BrLR80(gWI3S1f3m2$jE`8h$(FR<}Uw{t1**?$_o20F-ar A_5c6? literal 0 HcmV?d00001 diff --git a/doxy/samples.mapping.txt b/doxy/samples.mapping.txt index 24263780..76b8da54 100644 --- a/doxy/samples.mapping.txt +++ b/doxy/samples.mapping.txt @@ -73,3 +73,4 @@ water.cxx WaterSample.java water.js water.py wt5001.cxx WT5001Sample.java wt5001.js wt5001.py yg1006.cxx YG1006Sample.java yg1006.js yg1006.py sensortemplate.cxx SensorTemplateSample.java sensortemplate.js sensortemplate.py +p9813.cxx P9813Sample.java p9813.js p9813.py diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 8e10b8d6..bb255b18 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -330,6 +330,7 @@ add_example (rf22-client) add_example (mcp2515) add_example (max30100) add_example (sensortemplate) +add_example (p9813) # These are special cases where you specify example binary, source file and module(s) include_directories (${PROJECT_SOURCE_DIR}/src) diff --git a/examples/c++/p9813.cxx b/examples/c++/p9813.cxx new file mode 100644 index 00000000..f624cc05 --- /dev/null +++ b/examples/c++/p9813.cxx @@ -0,0 +1,48 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * Based on the p9813 driver writen by Yannick Adam + * + * 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. + */ + +#include "p9813.hpp" +#include +#include +#include + +using namespace std; + +int +main(int argc, char** argv) +{ + //! [Interesting] + // Instantiate a chain of 2 LEDs using pin 2 for clock and pin 3 for data + upm::P9813 ledChain(2, 2, 3); + + // Set all LEDs to Red + ledChain.setAllLeds(255, 0, 0); + + // Set a single LED to green + ledChain.setLed(1, 0, 255, 0); + + //! [Interesting] + return 0; +} diff --git a/examples/java/CMakeLists.txt b/examples/java/CMakeLists.txt index f3a239c4..2e411c26 100644 --- a/examples/java/CMakeLists.txt +++ b/examples/java/CMakeLists.txt @@ -165,6 +165,7 @@ add_example(Ads1015Sample ads1x15) add_example(MAX30100_Example max30100) add_example(Ads1115Sample ads1x15) add_example(SensorTemplateSample sensortemplate) +add_example(P9813Sample p9813) add_example_with_path(Jhd1313m1_lcdSample lcd i2clcd) add_example_with_path(Jhd1313m1Sample lcd i2clcd) diff --git a/examples/java/P9813Sample.java b/examples/java/P9813Sample.java new file mode 100644 index 00000000..ce25384b --- /dev/null +++ b/examples/java/P9813Sample.java @@ -0,0 +1,42 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * Based on the apa102 driver writen by Yannick Adam + * + * 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. + */ + +public class P9813Sample { + + public static void main(String[] args) throws InterruptedException { + // ! [Interesting] + // Instantiate a chain of 2 LEDs using pin 2 for clock and pin 3 for data + upm_p9813.P9813 ledChain = + new upm_p9813.P9813(2, (short)2, (short)3, false); + + System.out.println("Set all LEDs to blue"); + ledChain.setAllLeds((short)0, (short)0, (short)255); + + System.out.println("Set a single LED to red at index 1"); + ledChain.setLed(1, (short)255, (short)0, (short)0); + + // ! [Interesting] + } +} diff --git a/examples/javascript/p9813.js b/examples/javascript/p9813.js new file mode 100644 index 00000000..e1c112e6 --- /dev/null +++ b/examples/javascript/p9813.js @@ -0,0 +1,40 @@ +/* +* Author: Sergey Kiselev +* Copyright (c) 2017 Sergey Kiselev +* Based on the p9813 driver writen by Yannick Adam +* +* 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. +*/ + +var lib = require('jsupm_p9813'); + +// Instantiate a chain of 2 LEDs using pin 2 for clock and pin 3 for data +var ledChain = new lib.P9813(2, 2, 3); + +// Set all LEDs to blue +ledChain.setAllLeds(0, 0, 255); + +// Set a single led to green +ledChain.setLed(1, 0, 255, 0); + + +// Exit +ledChain = null; +process.exit(0); diff --git a/examples/python/p9813.py b/examples/python/p9813.py new file mode 100644 index 00000000..3c57affd --- /dev/null +++ b/examples/python/p9813.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# Author: Sergey Kiselev +# Copyright (c) 2016 Sergey Kiselev +# Based on the apa102 driver writen by Yannick Adam +# +# 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. + +from __future__ import print_function +import time, sys, signal, atexit +from upm import pyupm_p9813 as mylib + +def main(): + # Instantiate a chain of 2 LEDs using pin 2 for clock and pin 3 for data + ledChain = mylib.P9813(2, 2, 3) + + ## Exit handlers ## + # This stops python from printing a stacktrace when you hit control-C + def SIGINTHandler(signum, frame): + raise SystemExit + + # Register exit handlers + signal.signal(signal.SIGINT, SIGINTHandler) + + print("Setting all LEDs to Green") + ledChain.setAllLeds(0, 255, 0) + + print("Setting LED 1 to Blue") + ledChain.setLed(1, 0, 0, 255) + +if __name__ == '__main__': + main() diff --git a/src/p9813/CMakeLists.txt b/src/p9813/CMakeLists.txt new file mode 100644 index 00000000..0212e2ab --- /dev/null +++ b/src/p9813/CMakeLists.txt @@ -0,0 +1,7 @@ +upm_mixed_module_init (NAME p9813 + DESCRIPTION "P9813 Chainable RGB LEDs" + C_HDR p9813.h + C_SRC p9813.c + CPP_HDR p9813.hpp + CPP_SRC p9813.cxx + REQUIRES mraa) diff --git a/src/p9813/javaupm_p9813.i b/src/p9813/javaupm_p9813.i new file mode 100644 index 00000000..1d422c5c --- /dev/null +++ b/src/p9813/javaupm_p9813.i @@ -0,0 +1,20 @@ +%module javaupm_p9813 + +%include "../upm.i" +%include "typemaps.i" + +%{ + #include "p9813.hpp" +%} +%include "p9813.hpp" + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_p9813"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/p9813/jsupm_p9813.i b/src/p9813/jsupm_p9813.i new file mode 100644 index 00000000..9d4cf8f9 --- /dev/null +++ b/src/p9813/jsupm_p9813.i @@ -0,0 +1,7 @@ +%module jsupm_p9813 +%include "../upm.i" + +%include "p9813.hpp" +%{ + #include "p9813.hpp" +%} diff --git a/src/p9813/p9813.c b/src/p9813/p9813.c new file mode 100644 index 00000000..cc7af954 --- /dev/null +++ b/src/p9813/p9813.c @@ -0,0 +1,149 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * + * 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. + */ + +#include +#include + +#include "p9813.h" + +p9813_context p9813_init(int ledcount, int clk, int data) { + + p9813_context dev = (p9813_context)malloc(sizeof(struct _p9813_context)); + + if(!dev) + return NULL; + + memset(dev, 0, sizeof(struct _p9813_context)); + dev->leds = ledcount; + + // Try to allocate and zero out buffer + if ((dev->buffer = (uint8_t*)malloc(dev->leds * 3))) { + memset(dev->buffer, 0x00, dev->leds * 3); + } else { + printf("%s: Failed to allocate LED buffer.\n", __FUNCTION__); + p9813_close(dev); + return NULL; + } + + dev->clk = NULL; + dev->data = NULL; + + if (!(dev->clk = mraa_gpio_init(clk))) { + printf("%s: mraa_gpio_init(clk) failed.\n", __FUNCTION__); + p9813_close(dev); + return NULL; + } + mraa_gpio_dir(dev->clk, MRAA_GPIO_OUT); + + if (!(dev->data = mraa_gpio_init(data))) { + printf("%s: mraa_gpio_init(data) failed.\n", __FUNCTION__); + p9813_close(dev); + return NULL; + } + + return dev; +} + +void p9813_close(p9813_context dev) { + assert(dev != NULL); + + if (dev->clk) + mraa_gpio_close(dev->clk); + if (dev->data) + mraa_gpio_close(dev->data); + if(dev->buffer) + free(dev->buffer); + free(dev); +} + +upm_result_t p9813_set_led(p9813_context dev, uint16_t index, uint8_t r, uint8_t g, uint8_t b) { + return p9813_set_leds(dev, index, index, r, g, b); +} + +upm_result_t p9813_set_leds(p9813_context dev, uint16_t s_index, uint16_t e_index, uint8_t r, uint8_t g, uint8_t b) { + assert(dev != NULL); + int i; + + for (i = s_index; i <= e_index; i++) { + dev->buffer[i * 3] = r; + dev->buffer[i * 3 + 1] = g; + dev->buffer[i * 3 + 2] = b; + } + return UPM_SUCCESS; +} + +upm_result_t p9813_send_byte(p9813_context dev, uint8_t data) +{ + for (uint16_t i = 0; i < 8; i++) { + // Write the data bit + mraa_gpio_write(dev->data, (data & 0x80) >> 7); + // Pulse the clock + mraa_gpio_write(dev->clk, 1); + usleep(20); + mraa_gpio_write(dev->clk, 0); + usleep(20); + + // Shift to the next data bit + data <<= 1; + } + + return UPM_SUCCESS; +} + + +upm_result_t p9813_refresh(p9813_context dev) { + uint16_t i; + uint8_t byte0, red, green, blue; + + assert(dev != NULL); + + // Begin data frame + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + + for (i = 0; i <= dev->leds; i++) { + red = dev->buffer[i * 3]; + green = dev->buffer[i * 3 + 1]; + blue = dev->buffer[i * 3 + 2]; + // The first byte is 11 followed by inverted bits 7 and 6 of blue, green, and red + byte0 = 0xFF; + byte0 ^= (blue >> 2) & 0x30; // XOR bits 4-5 + byte0 ^= (green >> 4) & 0xC0; // XOR bits 2-3 + byte0 ^= (red >> 6) & 0x03; // XOR bits 0-1 + p9813_send_byte(dev, byte0); + p9813_send_byte(dev, blue); + p9813_send_byte(dev, green); + p9813_send_byte(dev, red); + } + + // End data frame + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + p9813_send_byte(dev, 0x00); + + return UPM_SUCCESS; +} diff --git a/src/p9813/p9813.cxx b/src/p9813/p9813.cxx new file mode 100644 index 00000000..4f74c4e0 --- /dev/null +++ b/src/p9813/p9813.cxx @@ -0,0 +1,146 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * Based on the apa102 driver writen by Yannick Adam + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include "p9813.hpp" + +using namespace upm; + +P9813::P9813(uint16_t ledCount, uint16_t clkPin, uint16_t dataPin, bool batchMode) + : m_leds(ledCount), m_clkGpio(clkPin), m_dataGpio(dataPin), m_batchMode(batchMode) +{ + mraa::Result res = mraa::SUCCESS; + + // Set GPIO pins to output direction + res = m_clkGpio.dir(mraa::DIR_OUT); + if (res != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": GPIO failed to set direction"); + } + res = m_dataGpio.dir(mraa::DIR_OUT); + if (res != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": GPIO failed to set direction"); + } +} + +void +P9813::setLed(uint16_t ledIdx, uint8_t r, uint8_t g, uint8_t b) +{ + setLeds(ledIdx, ledIdx, r, g, b); +} + +void +P9813::setAllLeds(uint8_t r, uint8_t g, uint8_t b) +{ + setLeds(0, m_leds.size() - 1, r, g, b); +} + +void +P9813::setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t r, uint8_t g, uint8_t b) +{ + for (uint16_t i = startIdx; i <= endIdx; i++) { + m_leds[i].red = r; + m_leds[i].green = g; + m_leds[i].blue = b; + } + + if (!m_batchMode) { + pushState(); + } +} + +void +P9813::setLeds(uint16_t startIdx, uint16_t endIdx, std::vector colors) +{ + for (uint16_t i = startIdx, j = 0; i <= endIdx; i++) { + m_leds[i].red = colors[j].red; + m_leds[i].green = colors[j].green; + m_leds[i].blue = colors[j].blue; + } + + if (!m_batchMode) { + pushState(); + } +} + +void +P9813::pushState(void) +{ + // Begin data frame + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + + for (uint16_t i = 0; i <= m_leds.size(); i++) { + uint8_t red = m_leds[i].red; + uint8_t green = m_leds[i].green; + uint8_t blue = m_leds[i].blue; + // The first byte is 11 followed by inverted bits 7 and 6 of blue, green, and red + uint8_t byte0 = 0xFF; + byte0 ^= (blue >> 2) & 0x30; // XOR bits 4-5 + byte0 ^= (green >> 4) & 0xC0; // XOR bits 2-3 + byte0 ^= (red >> 6) & 0x03; // XOR bits 0-1 + sendByte(byte0); + sendByte(blue); + sendByte(green); + sendByte(red); + } + + // End data frame + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); +} + +/* + * ************** + * private area + * ************** +*/ + +void +P9813::sendByte(uint8_t data) +{ + for (uint16_t i = 0; i < 8; i++) { + // Write the data bit + m_dataGpio.write((data & 0x80) >> 7); + // Pulse the clock + m_clkGpio.write(1); + usleep(20); + m_clkGpio.write(0); + usleep(20); + + // Shift to the next data bit + data <<= 1; + } +} diff --git a/src/p9813/p9813.h b/src/p9813/p9813.h new file mode 100644 index 00000000..c11f32c4 --- /dev/null +++ b/src/p9813/p9813.h @@ -0,0 +1,106 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * + * 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. + */ +#pragma once + +#include +#include "upm.h" +#include "mraa/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file p9813.h + * @library p9813 + * @brief C API for controlling P9813/Chainable RGN LEDs + * + * @include p9813.c + */ + +/** + * Device context + */ +typedef struct _p9813_context { + // clock and data GPIO pins + mraa_gpio_context clk, data; + + uint8_t* buffer; + int leds; +} *p9813_context; + + +/** + * Instantiates a new P9813 Chainable RGB LEDs + * + * @param ledcount Number of LEDs in the chain + * @param clk Clock pin + * @param data Data pin + * @return an initialized p9813 context on success, NULL on error. + */ +p9813_context p9813_init(int ledcount, int clk, int data); + +/** + * P9813 close function + * + * @param dev The p9813_context to close + */ +void p9813_close(p9813_context dev); + +/** + * Sets the color for one LED in the buffer + * + * @param dev The p9813_context to use + * @param index Index of the LED (0 based) + * @param r Red component (0-255) + * @param g Green component (0-255) + * @param b Blue component (0-255) + * @return upm_result_t UPM success/error code + */ +upm_result_t p9813_set_led(p9813_context dev, uint16_t index, uint8_t r, uint8_t g, uint8_t b); + +/** + * Sets the color for multiple LEDs in the buffer + * + * @param dev The p9813_context to use + * @param s_index The start Index of the LED range (0 based) + * @param e_index The end Index of the LED range (0 based) + * @param r Red component (0-255) + * @param g Green component (0-255) + * @param b Blue component (0-255) + * @return upm_result_t UPM success/error code + */ +upm_result_t p9813_set_leds(p9813_context dev, uint16_t s_index, uint16_t e_index, uint8_t r, uint8_t g, uint8_t b); + +/** + * Writes the buffer to the LED controllers thus updating the LEDs + * + * @param dev The p9813_context to use + * @return upm_result_t UPM success/error code + */ +upm_result_t p9813_refresh(p9813_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/src/p9813/p9813.hpp b/src/p9813/p9813.hpp new file mode 100644 index 00000000..2949106e --- /dev/null +++ b/src/p9813/p9813.hpp @@ -0,0 +1,136 @@ +/* + * Author: Sergey Kiselev + * Copyright (c) 2017 Sergey Kiselev + * Based on the apa102 driver writen by Yannick Adam + * + * 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. + */ +#pragma once + +#include +#include + +namespace upm +{ +/** + * @brief P9813 Chainable RGB LEDs driver library + * @defgroup p9813 libupm-p9813 + * @ingroup adafruit gpio led + */ + +typedef struct { + uint8_t red, green, blue; +} RgbColor; + +/** + * @library p9813 + * @sensor p9813 + * @comname Chainable RGB LED driver + * @type led + * @man adafruit + * @con gpio + * @web https://www.adafruit.com/product/2343 + * + * @brief API for controlling P9813/Chainable RGB LEDs + * + * P9813 LED controller provides individually controllable LEDs through a two pin protocol + * For each LED, an RGB (0-255) value can be set. + * + * @image html p9813.jpg + * @snippet p9813.cxx Interesting + */ +class P9813 +{ + public: + /** + * Instantiates a new P9813 LED chain + * + * @param ledCount Number of P9813 leds in the chain + * @param clkPin Clock Pin + * @param dataPin Data Pin + * @param batchMode (optional) Immediately write to the LED controllers (false, default) or wait for a pushState + * call (true) + * @param csn (optional) Chip Select Pin + */ + P9813(uint16_t ledCount, uint16_t clkPin, uint16_t dataPin, bool batchMode = false); + + /** + * P9813 destructor + */ + virtual ~P9813() {}; + + /** + * Set the color for a single LED + * + * @param ledIdx Index of the LED in the chain (0 based) + * @param r Red component (0-255) + * @param g Green component (0-255) + * @param b Blue component (0-255) + */ + void setLed(uint16_t ledIdx, uint8_t r, uint8_t g, uint8_t b); + + /** + * Set the color for all LEDs + * + * @param r Red component (0-255) + * @param g Green component (0-255) + * @param b Blue component (0-255) + */ + void setAllLeds(uint8_t r, uint8_t g, uint8_t b); + + /** + * Set the color for a range of LEDs + * + * @param startIdx Start index of the range of LEDs in the chain (0 based) + * @param endIdx End index of the range of LEDs in the chain (0 based) + * @param r Red component (0-255) + * @param g Green component (0-255) + * @param b Blue component (0-255) + */ + void + setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t r, uint8_t g, uint8_t b); + + /** + * (Advanced) Manually control the colors and brightness of a range of LEDS + * Best used to maximize performance + * + * @param startIdx Start index of the range of LEDs to update (0 based) + * @param endIdx End index of the range of LEDs to update (0 based) + * @param colors Vector containing RgbColor structures for each LED + * No check done on the boundaries + */ + void setLeds(uint16_t startIdx, uint16_t endIdx, std::vector colors); + + /** + * Outputs the current LED data to the LED controllers + * Note: Only required if batch mode is set to TRUE + * + */ + void pushState(); + + private: + std::vector m_leds; + mraa::Gpio m_clkGpio; + mraa::Gpio m_dataGpio; + bool m_batchMode; + + void sendByte(uint8_t data); +}; +} diff --git a/src/p9813/p9813_fti.c b/src/p9813/p9813_fti.c new file mode 100644 index 00000000..2257fa3a --- /dev/null +++ b/src/p9813/p9813_fti.c @@ -0,0 +1,67 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2016 Intel Corporation. + * + * 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. + */ + +#include "p9813.h" +#include "upm_fti.h" + +/** + * This file implements the Function Table Interface (FTI) for this sensor + */ + +const char upm_p9813_name[] = "P9813"; +const char upm_p9813_description[] = "P9813/Chainable RGB LEDs"; +const upm_protocol_t upm_p9813_protocol[] = {UPM_GPIO}; +const upm_sensor_t upm_p9813_category[] = {}; + +// forward declarations +const void* upm_p9813_get_ft(upm_sensor_t sensor_type); +void* upm_p9813_init_name(); +void upm_p9813_close(void *dev); + +static const upm_sensor_ft ft = +{ + .upm_sensor_init_name = &upm_p9813_init_name, + .upm_sensor_close = &upm_p9813_close, +}; + +const void* upm_p9813_get_ft(upm_sensor_t sensor_type) +{ + switch(sensor_type) + { + case UPM_SENSOR: + return &ft; + default: + return NULL; + } +} + +void* upm_p9813_init_name() +{ + return NULL; +} + +void upm_p9813_close(void *dev) +{ + p9813_close((p9813_context)dev); +} diff --git a/src/p9813/pyupm_p9813.i b/src/p9813/pyupm_p9813.i new file mode 100644 index 00000000..8cbc6337 --- /dev/null +++ b/src/p9813/pyupm_p9813.i @@ -0,0 +1,11 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_p9813 +%include "../upm.i" + +%feature("autodoc", "3"); + +%include "p9813.hpp" +%{ + #include "p9813.hpp" +%}