b~~q^'^L s1L8`^\Q2Dܝ,Ǭ#S;)gkO`2%+XS&:Ft@i(To`zѱ&x"L0acfOξ1'~GW'آQwyRЀ\:( J -h]s7I5Co9P Sr:r`8VHKWRQJ);mذv w5 H/N%iCϠDzߐAy{n=OC37Sc2Xxb[ϏfXuKF6S#ʸ7K@e2]C `(?r|s CB0W"/~rn `ߐ qm$w_ppK P^pBE*J,k(@ fX[Ti,7uHF =(Q ?Plc9È / U3L wlF s'NT!=ɈL<:90\>蠐L3WiLHl@X ?80hV#䙁cHeP!Gr·ܠax! 1_|'e\`kSL5 8DAxT04@_ m4P0@lIwl@I૭KA_@3G-Saƨd Zi`1@KP9<(:7(U&>_CNƒ{KnR{Ƈ 7/oLjƝƨ!`7,V ٷΕ I/d9S4 aP!)- OHنqI|k )aHF!'v}Jε{M@|ݺ>28Yԍ,o=[#:TOV #Vmb:iAF}ZXqM "Hو t0X0Uh00}`nɸH5Z1~`>yJ2pcAu,}SLէ0gdݗ&fo6&G !OKlF| hU#b`{i08b; Ѽƒ{Lӆa8v/cĐDq"nfB6<@I:C~<@874xG@"a:X'ATi>|8L8a:8V0yIK*Z3`\o|?`[\Sd o,V4̠`D LJI[A+rQXφu'uC@1y+{ (gmn?>0pX>qABPp0 O6>5*Ih7e?WqT8|xq `,G*P1 @0m-BFrd/gagǨ((ɁN&i Cuu,H|'<Ү1HbhK1Ee0ט+dnt#%,=RX?>B6Pfegoօ5kxд Ve}1?d 7d'$F &&Ha(C ٟ5JNǸRJXgvX Hꌆ$ᄔ W;,w_%fǁ/gCR[YK0Xc [1<!4PiX?$ 03 Io aK-)BKFBz:[fdqJIsi FlgZ[>=zdeM<'0Db6 4n>H'au8`:w%3:ƞ;oc^R$c JiOD0?%-T+ Pk챋=<kذdYl:"D4ZaA0)c ? dQ1d c\8? 1c!DLBH7Yk]bCxMB>mǀچ d} K1-S#kplz@08 9Å&4N*OZ d{g/E_,L `/uۊc0xt4M@rN7D6$ Jtqu"ܕƀ凒6XXqB`ك7X qKaS$[}#pH=p bOQu{pz9ч@`%f0sIW[1>,H[8iOyȑP("RN@/$!`'ΐ031KbAYR`f1"a(F,(|VdfK?J^h$ %%rKs_a[!) |5f@sCn}Ȳ AY-e$c'n0 %)|-$QH!`t MǨ!̥Mr* U F}fj?eLwl!F JUd؋vɓ($N'iCq=r ,8(wFtvnE DiA`-{S1s"xRoa āBi].R cs+pݰS AwN, cO#pX| mr#r2%-g€8($?tφf,Y+uJvdYiL <׎eG0Y`24 @cf K>?ȣAe Q4nI*p-!`z!B"v} 1[Ew,#uHuNDǜ5 l'Xyg,S\e0y4'p(ca$3' xo/7aaWNVRNٔߚ'9pb8>,C{h˶ǏR24ͣU`u Įn-aѴ _u P=d"q8*p _u8mKݧcfϻy>b`'`#3@ JR sbbcWA @Ap |!@Q`b Aaj c *X0 Qa@(~3+`\a@& gĔO ][0En.@ XAp <sgu`,\!:؉8F P["[E3=XxO~Iń9f9W,9q `gǃγAT_+(> gy`t`F,-՛`cpE@?ccXȳ\$<=:<@aЈ,-D{D: ZԱd쵀X~P?Vwt"JxqoFG.n ~Fd5l#1aH~O-qM E~@^$$i}}9;!yZ 8kv~TL`рe$f8l\u\' TjMOwLR/|AH18Z0p.3sV |bIw8/(\40oqnc; 3cG'Xl8(ynOYa19|H/\Z8"Z3>Y=^ N3(RE_ٟ`#lxֳd@Zé`;n!C`>2!D0~? q?|xp \̲[w<5LR0D5kN0!xqqgAܟ hX^|<ŠY|9aY8/'\yr ^5Xy쥹vqkf1:c_!DLr:lyx"1-ǀoqB(5"NP/:0(Y;Ŏ6IG r[&vo" ݝC=ZK 'Oq {p;,$ P8%M0G3l:@(9qWkC|!G4? uARX# "'7?73@D@r9aI]x9"s0GJqՖ!ҳG-ù<`$Kh֣Ih!N(i Cـ{Ø`%™߇LTʌ4l9cPU%lVYvHL;,8{P2  J+A8i#n+z3<-Mְ=?NɾtGɾtG)i ɾtGJZs53!Q.nMi]q;.{]8K PEWQ0-$G$Ou\OUD:&{QݠNað0 _>6?6#͌`=ˡq1}8 hY!CB|XX`g$%IH2`esO[40LG|,m16P:g7؎=! r<[`/?d`.wl,h&y@])Đ0[M>ƒ,d4W7 !pљK%RPZ/ ΄OФMs@U;A.8P<@6@`Ap:j<~FFU)"pxzRÃ*uoNiR . %s/8 |Msӌ8R\AuOT2uH*C"SJq 4??[E1@c{0qzac݃7 o@F"5yCUCo"NQ$^OHJVKc6#9AX' t8&3 O JP F#`"Ul!N#@|L@sȀLo%II A5õ~I*FhkWѽ4ՏB'9Kv!A4@Ut?Ye`N18Dm8N ~.…O=i_(=$?܋{vl:.r萈42DQu>7pfk;%|b ӈUx `c¥Θx;Ә7 ?z Ґ1!Q'ˤ)n1\S\@ r\ԁӺ_S%iǪbw2tḧ́t崹g1G }>Ejync0+#Q&vDzQqHH181s"bp4E "=7lq\>7UnC 'kh(s@@i' "Ҙ}#HSvt<V[ 'Sd`k 2XZc^gy9ҍNV߸`68;,E4@SNnߚ<ُ4P)(*)H 2ۥY9*zqV*/ӝ5q4.`\}8fUҐ2::%T-Hwx:|N!Y=㳀BEo4'|mӖ'st(:)QϜL @tR,0oS-Xΰ Kyp0H0?D]"P(lȉ> $8X[Gƻw^>պ_e J/M"28@T.#Ӗ($qr-(=M@0rْf!:j6m\\p*26r8Su|>@P`dU(afu@_u0)H:Z;y JC`bf8m8hvqGy qNYκsx]Wxv4#X 6` gM:(vO"@WY,R_M;<8t{N" P 2([7CC}ب hpV NN#@x(p|U9o)@l8rM(AX )5M;:@A$J ~8:0qGvϖ<&\<JAb«꘦uEIw\t}Uh E 0dj]: &.Ŷ> /ju eSdh>6{T0lss!a(vXr07 #~YS}qhM)Vt""L/jP!ayq|q4(tZ e7K#bS qݘ`WqxoA0XE7:s3Ddt FSj8̇x9aB> 'V"DR 4}?(4t~H8<yfhvOw O@ 'R'H9g ;8c=Pn_A"Rpu`5CR X?L2n3-, ?N!ig].u8꩝U]`ԋV0}d UАTu O]aJLj@L;eu[ jop*1|0o}9wArOOsi]g<8y?_8w>nX/n&(+!;xz$XvW< Hǀz$*"J7d [2?aۚޖ<cPv8p'O&9k*@!rn<QLu8vZ9Xr ]dΉN*iB_@Ǒ̭fN٧>a܍n>9B?FJ5`E0z$HVnj%ְ#_DgeBN+iDB(9af4F'}4`(]?CSDO{B<3,-)%!EcJ?ػUM/U!@vOY@|,` 7 u(S_D+ e4dskZ q`uQHf7#I̺[j}>bDww'q<,xc@~ n$770 Fed*pL| g \ϪbLs]RN:F"ә$  W)QttAeuI@X  O81]ӈ36_JaFP;s XۊEـvg5Yj|L7#zk0r,Ȑh/2OoeGs/3ޕua"ib073&C;Y;v/bR%1 ſ hOid!ִ?!csB &FKrEbjCu4s qlf`IѠ5P" 4 Iܺq0 z(P1>m n1I1gP:S50EH9іA *`L3'Q2U ]ּcn1ء *<lE .Bl N>QMD @*\+2> 4X}cmL`/r||=5='mx$\53HXy򪕯M8KqCȷEj#Y/ 1/*FRI?o_q:H4tHz !A]\ШN^m{MǑH$[dpHs ۇ$,b};(0G3"ĒW[ponCڂIO Y8v3 >tMqA:bOYc@+Hk$/,Qٳ+]b:^9w-6cyҁR :'#ib܏޻qI;`8Up<dn,Y)dQk\:+3r|N8\>رEwxn `aDžnA:rŃ'!^v"qBHn]SJa 2|S0 sNк,˛0fmu'PVlHH1 ) 'XVUNf! l,Nq|mMqҟc馥G[NTM YI % `JAJp\jh@bBD'B#4G6B 0 =hfnH1`G q3~ '~/MQTF ?205܂O`$Ǟ( DƠV 0_8x_vk0 b0iH_>J11Eag[ Alyy)%M?%F0 ZbIh[fd#  /Q<@ҰxtGQCss"/ C"9 D؏@346~$WIEN,iGBDз$=ܝL'z'D' X-Zܞy>;؈@ ߜ@4) |kq_<|e_$K݂utцpt>yc'|?buƃ9>#^ Oyfҹ ]8r2rPpp2[JA4`J` M]@HX2SaP'X1}q q @/s6`;6UbBF| DEPzD[g% " Bd 51|BB} 2*+%μab;9j!a ob(0 f>fK (PPtA&Xccu6bp]ۨM>c{E}(HF& $ h/ mӨHp -r֢ ch X9|Lspc}0l (X kͮ N03-20TvaWi"N\=)'P:va`TNy>#-_ߎдҸ%2K(P?Qqwd9=3Jxx`cȠFŖ u 9<Yr!m=5"@]#A8 8#߱h@ q>G.<.0X$JPVsÎ4pRj*Po8 lqͳcf ħBX~agX5D2Sg_` |A[5 ܒf{_=H&H/OƇl)";πfBi PnN5_snjK%;eZ/R a& t<Lf i xv1_49٣Q#o Xx} S:|7@>AaO.ϳv1>'4ϘQ:{  d,Z3vH[Ĭ#%[8CcD3g n< (plK] AUQ8ʼn/(H +uJA2R 8˼ NXE~@;,܂ ?Us,zS Q>@d$l-`|AްC!Ezb ˧ĕ^hPBpb;yY3H9ҡ[AH0>@zlDue)}ǰa3Icv3G^O=&OqhaL.1m'B3IAgSt B$p19^8?_OYHp& EjX65UAEHtltL򭬉ݙ mW[:#ͿRV؎A_K8:ז"=Ӕ*,1ã9]sWv.|&`72]N0E-0L*j"N-iBͺS7XK iTNf u}8Ũ F1h`>.hM wn3(*Pg`Ds`xux '|,:a|-1(9Ӟu)]8Õ*ʐ0fˮ2e % CSãbۢjzvU$4n×58:N{Ґ~!!8X W'v Ja*]]LT(# Wf6$5ž-pqSeh|A"@d bIAWO À~Rԯ{MVh~l7 HҞFI`2tZ~ mYA[8Hfw/.0 g\en4 r<3 bnbpb|0tLCwPT  )̊ w4``Crbl(D@Z<%¸(  nLOk䲐4 Vp(y?nF4bd{r5'pOI /8 _י'iL],-KJVb5ϻN5;} .tD%)`؎WI Fpl) _`Ig25r@4.޸ÏNeJ`) 7*3.ΜAsG De0œ`5A5U[v<.{-`ț0aCfuLU Z;gP$8#Sf4ddeoJZci# _aG Nf3r8NF #5P;zFU@b9t2 "t q^@Pz9|wc4qKeNI[C@'0ż`x"f @, NB|w(0>9No{\wD ,@,yv1c #}LI,755)g6(_UHzZ"QHρjB揉}#08K;T[E8$2 sOj@ YW⫏q lQ}5ŰgqbiGǀw-Ȱ0:J74}tqa@n y2y:624#FaNANG%:E .՚H%j\.K>Oq%xtr9>w8WښQX}Q!:n0@BlstLٔPv0G0Db}.g(v$. AB+}|Ħ\}ӛH0ہ; XqX>Fc^1gz,bgX1`,HRRCD(%Ph(=İ{KX3 Qu G ]yD@Z?L?tTZ4;3Qxb2 @g(!kqv)#0/ -őN.iGB"hAM( OqD}ހd@]@ޠ`B!"9\N1g(Y<BOAc4-F HƱ%$d yE}7~; @xb_QFc@v+ h$.jq.<syq.4 p >v'ҨA|àd ?6u_-YN a/%P!ѰbUNMJcP0.`anY4A>#7 x  ¬yLh7t']TѶlADp:P*OPP0}j}8G]㨠`K 4ht|lm9/jh BQ!n&I>;GWChDhVD"$y{WӔ!.a9$`!aV'8p8$!\HdGYa~ X81+P]yIŹ; yhIv F6})e1YCm6@4Ac]<z  ƀpa˧ u@9NJci]묩dMEf~ Vu0N#*pT)dlx$(~Ȝ"0L,W` 1FuCJOqh b| `}6XаkJZ /o L}݌9 lxU ,Cӌ2V ,@аlR1JGW4! ڲȠzo# =XE}$gX})wO]A g"s ݃S ^v3u ?0FmN wie0ãBૺ ]uU:q${Hs%Qmئd ;dπC`)Y>Hl!gFu4A/:VC Y1壆d Xi `H7̀pJ).% ο1|xXsB5F#| d$=!9F}-tg@8>އml4( ^P[x8v]8t? h 1`2>JiiȯNR5 Ve(`b}8zy$j Y,kLG6] bw0nv<0m tXul>EHm `xбGz0AV=y Q9b11Fg8B㒮\y>]0paӌYRӬScӴU2è#(pyS H:DZ{=)! H6x>hߡa$c'EB| 1}e=…`9 XxN:/ZKWCOgC`0-8Ж#iŇ _Nfc8/(y(蠐X<-`,3 C{(0Zluq&f f~ 7=+;1I:scź4b0>P^%|}yF!pxń;H/UaQf S3!`)q`w\W0^u4jr_uIp24At$@?HP̼3jDeIqY0r c0M)f=c`[?( !|cA5XЙ+#Zr@p3{yo)σF%={)d Z_#ȼp`eXW gƝ4(o0Í II# ݎ6T\A0po 9<+:o䥋ryBoР ,v8>P9Ӟ\cT-rC32y Jcgr1h`?AvB6= @_vf,<,}EAa<<8vwtGxtGC& iot m˧u^9xpv㸏ߺvTi8M>O:4at΃BܩS[5Ͳ/- }ƽ HYc9%.@-c]YuzKXj8Zy\G*=mˆ 5C.nF9lg8jol&dA6A(۽ñ[jWJʧ."/c {,/͏N(h^HmkSv/PK:#<=OTK2N9ŕLO/\=R&c:M`ft>o>t4h| L1)Y?ADLYlHZ͑!0Kr%m% 212%ĸA;PX2@Nln;dgm\| aE;겼a]aֵjֹ؈wwwwfkII$@ 2@c =# (0,ee\vQ 8RQ9]3$H)EhF36EħO}ؚ0k=FXk\LV3ehHW)> ʗA¨uq gUeZo!r8ю>neD=|--!խk`ֶ &Thd\y[WASʃ b*l8+,n{Ɔ|Φ.™#B`}jxx>a1%io9aUlf~Sl$;{/`mBJ$wiZ N9AtGBtG0iGAtGJӸ53!Qd{D;aGuN0˗\aιN!q#]v]u?]cκ}uWUd**{P4huˮaXNp` Q:bx -@>Рt8&(3l)<"VbfX@5ApPVh<jP;o',€$0%qdWb`a `\yyN} p37S[N2:@W0&9oi@>5x=z0*\h"nAf7A1c 7;(ChPu8-q! ;pb|/0 3~)v8Ph(\NB0#*sOT5!@ď0ELS% 6$ ?uTZ1A ?PgINS^-JJ@V-* @|Hq*XR.E0$$,h/#f' wZxEDǍNdŤ`ѥw7Ȱ 8 o z萂Ed"MB5%i8x7.O0v[2)!a _%; }bx Sd445 V1#+D$-$O6FwBXydĸԉ) O#"m B HzoIcLL%쁽{r?#( c{t4u ]|[,Xb\o&G'($8cĻss",QX@/MDT&k\D#iPmEYq\bBLQR]e[Ґ.i@qOB8lUHMp X,ڐ.u4Tɳ]C}:)B\׌?n|}oH"N |[ab'dȗx?7`K9%;__o%y,0#|3q9̥? y\ L78#rx  HXiE(C&H"ڛr9O@7 [^1JѼ1EׂJ4VP#xƄ(|:@HQ@IMq$ yB"N0`NG? ߌ`a IZ X6$"<҇(H`)`1`8Nֶ "#\&8bwl"&JROY(2: A `$YM0d _}Bb˵jρki>:nrAi5冃ʮ FiJaAP|(F ?@ڐKI(wΎZ\Nţ| ]A0]А s`/"S P0D @," `oJ6AuҐjS &)#ScU fX W$N:1iDB % uH_ 1Er꫺ƗD,ӈ}rzq1U672R ~Qd!#=%B,E y`d@J1#<=`4 3lߎ$Z ӈPyh-\8Gx<"wp4@\G)Zqx88I XФc$Rى{Y\C岀QwSͼ)mF|yO[K0jD2m`@0 @k>6;si(4 % d86?J `\@$4 œ%@U d*6 X-8Rva𚫮!N=) .1l͕yb݃ӌV!m` n uˆykTj8, fJsz?=@hIue?s^@ƍv"EvpN p*HcjYXg.b$O~A\6񒘻$p<0oa9IXK^A$bUGR] xWna}:øHHq<5y~fH`*[nh哬)dk cp$YgX b0^=&l(m\"1 p00 1uLYR\0>JCLLSUd}8EB)rU_R *6*H )VJC +MNPw\b6B!?8pIDž6Expbk)c ͻ F&}H6т~iHTOJ0;6#D/԰&֐6D84S:qs2Ap1 RB cAN(1NQ;^Hx,y;Ɯey'D2 g#Z@>(*$K3PZ8Fkx]G0Vaxt (;7@p}hQp}@ktf\CJL9./` OUepM) I~@!ѱLꐿM ` %:T z wW6ڹxozݤ b)b[0?:X$v76ҝ"@*T."S=h̭>m4ȖPtg p4,37) ?t8+PP'iPСP\?M]zXI T'T,mtHF.0iZQ\"i"H h{}v |'Xp 5D^@ޔ9G zPI 2?3ܞ[= h`@)e7ؓ K@rw( IXg]ߚ~RxQ9O'Ypr;@^P01#z Ǽh i*14(_`td B5)pnwx?X9O j/@a6+l1VxS*#)H BTRVEEF81 h[bp (6:ˏJCjbڨ AON0mN;2iHB]M[zqx n O O޺ H).a sU el >NaE'1AKֈ4]ipnַI?*6 XfUOA"ټ |QBYx]V(#ty-^IN/=)anϰ Idg]P ~x HI=0O<+آ  a1&0 ܌Dbb`;%sCWxHZ >kB8d.xsă* r(/lXQ.Z-EaHٍD Q0J3$Nj# -`؛Pa s-b٣F|a+FϻNiUS 'ϩ)u,uL7).N0Nh2mr2t턕<  %S (a@nNZzw\`Ú]q ?So\@>\@"]Q20B;1I4 K t($Ž<|u@VB;DaR4htLdUxBQAVa'="DJ cW 1x[x(wŰA'Q_Xz̔ 3фE\v ^ 5CGP2f\?b8`?BIm8/P5exS0%$ , ex "e`ruF H$25QŖolMI@woyw\luSbQ93zX#:o\`Pu `J@q WMTi+˥2`zu +YH[U7()|BbwxԐh>2q6}# XyE`'%g3KH-g?p 3xJ,8#PHD[gSƿ8'!?߈Njm1ZYFy\oBGJ -9AHNwEKǮW *LYv"`5DR ?E)@-;ݟ,%hx}xѮ9Ÿ``4PlPJ#7qEif<`/7?4;f oAYb[XYB"#ٌ]Ǟ= $|F`k6V; iG<XtI>eo=@1c~;ΐ>˺RNQ'[cuH;l;!  4:+(Ϊ5  骘.%0BL:}$4($urr$-Xx`"=p* pk`9ԦY`Ǜxn+P` 0p) s3]g? $L%"nv 4NK Egcȣ0'"rebF iB@c9yN<3iB`γvHxx #v-1X9,p4O ̓Аwx ׈R4xG `GqL8 Tŕ Lhn0I똧SҘ2, Bp8xHR:ŋ]JuV4,#ʮx1tBAEu,?dBEқbkbۺA X4ì$-BEud&*$Fn/hД兵'|ۺC?,L@AIſ<5<3x KYcN|ɡhP刕DHNe3 I@Uj'GJA: H#ed !;㉥{wp6K[zOX8'#XYwa0P5dzHnvmmċEs0@ ,LQ2Dɴ 05%cH&?HaX,WZĥJ/+wsuZɗ]I0ܑNl- N^nGId}Dn^`6A{} Gh35l@jg7;GU]K 0j78[̍6=[Zw8@ ZQES _Ff,vr t000pmxž˃. CqeFTA_puzr."MVW(u,MS]a};Bzi/w=s<˼`)ΩlU`A47}O%|y)~!uB-M>lj$I.#BcƬ*f19<q[#Gy@?!bY$\vEh˵H n62H`АWB1 g@_'  )$#Аa0i "e6uyl-6(j*6- wBawd!H?h*DN63MnSu@=Pbp  Р&uGX=a'ttzԘ"H|Fp\h6 |H r TUReZ E5U 2\.o2:&e*@: P3:$(D,} T]:#`v{Bg4p c7 >c@-D3n *;<@b)A0(n?``0P8YpciBD3I n/k+RF ͢B5`W?O'?`01c]$v*C)x4ᢾP|.n8ϖ;y@$30 u@xR{'$c lvi\(#b"IJp2 WTurَ `/dPG$JXX`2,=j|x~ H)O,B=Qe?C `-DvRgf'0=VO EXB o!ʮ0}qS8bs6ڜb`. kqhWRTɕ d @H V}uPcTl`nݽR0]wyN@T1A"cW@a\ 0#OBcRF婽x<}Q }֝d͢zQе>P%>Hpox7%‡<'?|XD*H QH,b⁰g !l&c޲# @HT;c6C8`b pRR (K|e2_ t`$laFG-h+$"RĴGx(%$Y%xWBN=4iB%'b]Xщ0 7EQN3D?8?zuRmLs^ V,* 2gpk]R|O N2lŖ(0@OqOx 0b;CR%ys<8)-=Iw F2@@âuw ] *1'IG#CRrp̽JHM 3pT8KTʮ3` QtCIa7?I8|:ø?bs ,u &UL 6l _.`tLu atZqpҨ5R 2.U >HqkB 0M%]beѡ wNSa4)QHJa) 8"K8Q3i #L|4|${DHY8S,_Wq;:ײѰ[6ŤiG=kš;#OvfEh #Jqh~k`=s(ȴ9GvG-<3rK*ڄyfh!,0 %nK߸$-,ZCr :3KFHp;ݵ_nni$ao#RB|pHo">}sk<bGPD#Ca#K(PB-!v~Rx @&,`T dVCJ#-)0Pܱ :!/2J) 97[pa|M $9d@lĒD IA@tK-pjM7ֵQmw%hd}ݿ Ǭ?n}1Q3I?V/;%RJo0,|y [p^ ,1yР<Ĺ9_P}L9) 0P\?* )Z@nFD|<+VNa;@YecK_$Y]hnGLH5hRLrH|ƫn}H6 j#]ܖ&i&g_`lIdxw)0f]5-tA%_ZO]z5Qj@>M $i8͒B! o JÀoiE%bnϰK3'aC~&@% {˻PZjL!A0P#O- C &?%-lRD6O@ vnjHmT D* X8py1&VZWƆV=_JKL z_-&19\L 4iz@{eqn@i$&96DLQ o>[,=s @m휉; FED){ԿIQ8p I?pG8_| ?1=q% G"N>5iBW>Lq4rI (S+dq_*n.} e/W t aH}u hTskuITixXA],ʫ*bcwFA6p)W` =p ays2a)Ejxb[s [4$.> BE(&Kcd.paEJS$j{ .w&f'")`Lf[b-PH͐{J?5! ⑇zp! ?:b߁? z xR.v=C]rW9 !pPLmB0O2NGEY C~c5]G|4-DhQJDnp"wD.5vXcr6HPHMd@{ iZ}boJ )A0`cl ?Fk $ @1dm70eHrNRCx(@Uؠ. jfH[:>3#AUQ =Pl\klqS>> nze,@(s9TaJ5+g۞{pCiq D)f@ K'G껷BYòFÈn wvdD%~{--{t$,c 輖l*b)TH?'z @ EKb>. }RQ4ľs'n<PӈX6;hqļ36oj8@N `RzҬf[|sU0@lWW 92EtS„1ֈ=bt.rc #p-YE:#Pd^ Z!ѥL I$n_ߏ2_1IoP30cmj``(;Qϑ@ְlā| Ao8p?A"06Ak.S|4'>0Kn8$gp:/cwݘpPB@EAhƑԧt@Ep'Eru@$i.i:*r,xk/@ۺf(yӈ,dx0 o:Q}q|t,( Uc t>%YR&ΠF;X >>}BLxu d]B0N=w5Hs=wzE(+-1~KHa =|'ߓdNISnGB[Z$ sD1Mjh n"A!MFhbFv? Jrxi5U/1 Y$+0N?6iBG#FO0OΔy(ȏug%ihK{$r:\$ΰ$d,'`nl a8>l.WۺL~,jL ; EGb\=q^Xt>n=a@ڳ ďqf4|D6'<"X@بT:&_k5Py$xq\BȮU U6ugP]`*Q#`QBhB6Nwl.>ljNVG%BkXF!j nn5yE~~5,>J{O?LrF'8ss$!3,$_ +ݔ~+qa`idHG͖)+ s? ÀU A;3pEu4t TŷP Pq>2@yi<  E dEã^|u!@p.p ^4 |XbA @p]q}R$[ ءkbZnr(Neí0:'/ӖZވ 5U D*- ˆDa1CQwp<0zy;9i`p1  v_vs10eK+>'EvGZ~na!?^p헰"^Pl H@?-ԣ̺fvOYhu2b6=O Z}Fؘ² OV ,uj@/tȰ%%> ^s_Np/ѱBKaB?ҹ[/ć@Dox†,Q; ¶S2sIou}РdX蠐63 ǀϳ}-a&g[06Yu$a)q0 #~hG`FO]C,Kvkık" 6Z/gu~/ S3w- /a_ssrp yn}G- 81 a_`!bMAjbX+ˡ EDTꨝ}4AqR?U d:,(:eî BrF'vy='e0|`xH<x炂]z b 9&]Gq N9) s9ugÅP @ f4i v"B71`_2HV2P[/xs A2;#0]^ہ4dܗRJC Ƅ ͆lnGv.eqىCa.X"^=€zLxyJQ,蠐h3 qOxjAVxC̈"{NR#DF2nh`tѵ5ꭜ=uhu:L7P1}uӌXEk@:2 qH48GӔ m]\!V51Hw|BbfVlO'@7@Op  qfKq<=A/ap1j戊O%<δ-Oop5(;)x  APxC r|ï4 X1 1O)a/חBF`ssy󀨎E5ܶ@C}S@? 뢂$ N|@7iB|_A#Fex ];xF/X! 904SR H)CꩻN fuLqGR#͂4űX.Y`Eπ]kaF8oPLspYڜbԡ3@S4&"8*qВ2 E6B:SĒ0c3Cov>@7L-h6K P,Qp{-Z Z_{[ewl܍>s3n8(${"-Ƞr"k].8HI 1GakJpa07‡gَO8 }I =N``4P7=KDže3=@>((6947 [ӌz6\`wN kwhi1jyX<*u9iE1k9fh<AvtGtGD& b}twwwwfkm$@Pߠ `< ZUenhvZvZ( V`iSwX&:bfO }֍V'eb"Ih>H55lٟq\\exhvgz-|)SZ߉ Q\::wJ5/6N}M)*>ʟ.Ǎ/% kARMEj)J͜nⷵ*T8jW}v~x>jZR̍(vu,Uヒ5_nx{$Yf*Fڧ5PFugWGd6ؑHA *TT3c6d)" Ii&P qzDGNIOu { W i.BRErG09e줷gDdr@xNEV9aW綅 )s+Mt&YkZZa#f]Je]D+ r5g p{CxXqלaAsPTdd+J;54)VtG>tG8bO>tGK!O 9jU \v~ ڪLP0M\`MQ> wÇu9_pzG1L8;*;u 7lbH"c-'j`;a0«?G6Qeˈש8Q$>wr1j_ps\| `s1be$$80 ˸&YD;D7>pqHKb k1nXDq )ߎr|z{1bx;3Ac@:6M'G$ @0H0c ,,KXO ` LR椢 y-QDbb14B 1`1@!0cHI=0X`cH֍wGq: p('k1a.glh`cDG@ c]sƓ#v if/`z{C؋# DT `.fgv1gUt,r_KlG""fA K`͈tȭ7{a_Ɓ+FhZ8@r0ih$`qV$)kcaj(,t 'N~@x|tPhg3>T|,h2s&0WSZDf %%€@wn8]#؀  m3]ՍLg9Pd*&"~&Osg\}`AK\,:: 1 ;ݚ*/1 ,()qp?qp5 xFl ÌlitxppX=(@Ա%DxQ9@v4 :#D;]lƛ†~OaR@ekcRQ_P`BKp jxӀJK,c~儌w )'6(BaH(Q7III/0QW 1c֒l 0LM 00m'p68P`jC/oHJT``ϔ\y$P&NJAI-B/d4DQ1b&A%dq 3>5??J;<n'd†I:!@uicAЂhbrߤ1tYi( pO"#dC,KGi~ M72FmAq(5[5%L7's=0@!3#J#p@0 h6X0rs#/mO$gyQe1%` Xo5ۑ,3uZ!BXPO1b?m?fɐ ,Dv(p ?* |pPa|`1K[_0kÀ;u87-.!`tG `9qA::N?@ O1βxMg)ceЄ`/sgc! 4@l= ɮ ֺˈXtș6 Uc@ 灐hVǖ6 /׈RNSֺokLj?{ !6`8 g'\ +FYA7je#) E-0deZ2 w>cHuLYL$pt|ۑw AA(ٷs:p΂JU8;i*p` 8jNC9bCR]?XnfRofd I]Bu BwfϺGr7f] T{N~@hL+}(}~)ErA-D[ (b]ѲPOɤ D&nXG8CZ8 .4LR6f?앓:Vc'ϝ?9O~NLA]S ^23@i 1NlG[g |8pGbѓBLH`cn3$b Bp4e^(L_S#@{)<(,BaBPn[5`r//1EIu 8 LsB0d[~*? TŽsgwP}&Ik!l6a@ǃg5\@3 y V1p8G6[#€,do7Z$z&"1D Yo-ecq:NcM7k07/֘p 7{?f ::pb@41Њd 6:NF}p1\OIWV81 ƏFPj\ ʃѴ0/p:*[֞ wX@A8蠘0 <8סy{ Y/K@2 !`M ؁$S|FW#"CK&)F"q28ѯo:rw#6:8('iB!ܽߠ3@I|^+__A3up2L/} &ģy>- v"p~R }҂ 5~j4nNNWۘKHp<]g;_' cAaЀ#X1#Z.fd xSâf-?A`gN`~|$mqe _$ ` YEw C~9XiAA $y(o oOgR_"cWhbVg)l ?30! ]j{e>Op"@SN WJ5`̫1xg ݆m?pi@ (usw,.#S؁v.te(2Fֱà"h{3CY {l-#ϼc`oʄ8rqST*.},$"(n0pch80 Klv> ]=ux %vO[.UֈX}iz\UD0`;6#f,K9 vD9!VDJJY{PϏp5&yXI'He,1g!-e@E$l9`a8I^+ =ґdA1D??fHNW!"nÔyJ԰DaX -q?RzM3r&dy,P \a1 %1_S׷y4mDŽN#ͺvRf8`5Ư, u#{0 hB9 ND:bCC%=bNlA N}\f=L` ar/ 1O $q �"R J 5A[$(  ,|w(!@|gbsh= 0~!AA;)B:K By*~P\dpԊN9fc+l5ĈGھd`N~Py=Ȩjz![0D&Ё-8V^44GD6!ɘ0f+b3?o# % Qt`)P‡˜F^p:1ws0<yt<P1 p=,(9t{ ca`ۡ BuVՍrDs]GP໌עbPg݀ *::vZ3^u(($ -@;]r( @0@͙f8@79jOQD,(+E`mOdD옣ƭ[N\0AGهy;U F@85C1vJ|0I'}))?,%r~,k#fJMQNsO| !`'"! 2g":eVCV\Y,IƟff7vߜ`Pއ`6q8b?`\Q:=@R#H)\%nio1R-*ˈE5pLFMK,yB.;tRaŁ;$(C;;Ӱ2t̺WL"$ b9wVohm' Z)DOJBwy_'l}oqa!D~w3R>x}$ $jYPui;[n8 ' ;,idP"e5##݀{_/lSq< 49'@ك9[}wB2@{d_ [~hRȄlB@vq"!7`ۈQjNH;bC8p1dnE Ce8 7Ԣpw@XBP ,s:Ä}j' n(:)P =2.P >\0Farh b(NJ7 RdIҁkUdxuu֐d\D{F\0۲BD3ŭ(I|Rāvf7fɮCs0҇s S0$X#5Z d3H_7p5:F;s1$KIbH47`zW`('Z0@Ks"Hq@u@ o@Wy- N(p,ET,~v' a)gIE^9dI >:ъD!broB~@Y+jF \YJ! Aܔ8/N)@-vvb>wF} Ipy:n$ - :ȾV,Y[GI@gb4ԥ1`\fуz?=_ *XjCȃ>7#$z=wX1\BG~Жe Q䑹EHu@h}3ؾCb<a $s 3l.b!59n> #=on!Br1}Xp H͉Ӎ26Qv?{BPg|*% QXkÈPƃC`aA~|O>ȯ.-jz;٬q>jIuFPX93"EG][\%C81|5UJP6 0wgV  km]ਵҜ1Dk ]C|A@-C,f&)e;b$\o3 _B@8#%N @(uh8H ~yng_܁@2\vmr5:0u Y8ƍA-IFdbR'#yJFX`÷ Q."wrR Ia/HI| a)W *6c9>)@v#t`(76X㍊(%!PGmŌAI GƁ1tcTOU::8\H2@nB!# #+te`~5(BpH$I(-̄'YJG ='~{8÷<:QpϕԈBlPo'U3d{=Gi usec pause and then returns ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Pause75: ; banksel PIR1 movlw HI_75 ; Set up value in CCPR1 movwf CCPR1H movlw LO_75 movwf CCPR1L clrf TMR1H ; Clear the timer clrf TMR1L bcf PIR1,CCP1IF ; Clear the OC flag Check75Timer: pagesel Check75Timer btfss PIR1,CCP1IF ; Check output compare flage goto Check75Timer ; Loop if flag is not set pagesel Timer75Expired goto Timer75Expired Timer75Expired: bcf PIR1,CCP1IF ; clear the output compare flag return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Pause60 ;Creates a 60 usec pause and then returns ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Pause60: ; banksel PIR1 ; Clear the OC flag movlw HI_60 ; Set up value in CCPR1 movwf CCPR1H movlw LO_60 movwf CCPR1L clrf TMR1H ; Clear the timer clrf TMR1L bcf PIR1,CCP1IF Check60Timer: pagesel Check60Timer btfss PIR1,CCP1IF ; Check output compare flage goto Check60Timer ; Loop if flag is not set pagesel Timer60Expired goto Timer60Expired Timer60Expired: bcf PIR1,CCP1IF ; clear the output compare flag return ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;iButtonFind ;Reads and writes iButton line until an iButton is found ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; iButtonFind: ; iButton_check_admiral: bcf STATUS,RP0 bcf STATUS,RP1 ; switch to bank 0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto iButtonFindLoop call HandlePacket ;It's ok to immediately respond when you get a packet. bsf send_flag,0 ;Check if the command is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;if Z == 1. This is from the admiral goto iButtonFindLoop ;Check if this is a ping command movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;if Z == 1. This is from the admiral goto iButtonFindLoop ;Formulate the ping responds packet movlw ADMIRAL_ADDRESS_MSB movwf Tx_Destination_MSB movlw ADMIRAL_ADDRESS_LSB movwf Tx_Destination_LSB ;this is the ping responds header. This is constant and never changes movlw PING_RESPONSE movwf Tx_Info_Byte0 ;This the state that you are in with your ibutton pairing. ;0x01=waiting for ibutton ;0x02=ibutton read and waiting for pairing ;0x04=if ibutton is paired. movlw WAITING_IBUTTON movwf Tx_Info_Byte1 ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired) movlw UNPAIRED movwf Tx_Info_Byte2 call send_packet iButtonFindLoop: banksel TRISA bcf TRISA,0 ; Set A0 as an output banksel PORTA bcf PORTA,0 ; Set A0 low nop call Pause500 ; Wait for 500 usec banksel TRISA bsf TRISA,0 ; Set A0 as an input nop call Pause50 ; Wait for 50 usec banksel PORTA btfss PORTA,0 ; Test the state of A0 return goto iButton_check_admiral ; Repeat if no iButton found, will also check for admiral command ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;ResetSequence ;Conducts reset sequence that must be done at the beginning of any new ;read ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ResetSequence: ; banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 low nop pagesel Pause500 call Pause500 pagesel Pause500 call Pause500 ; Wait for 500 usec bsf PORTA,0 ; Set A0 high nop pagesel Pause500 call Pause500 ; Wait for 500 usec return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;SendReadROM ;Sends 0x33 out, LSB first ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SendReadROM: ; ; The Read ROM command is sending 0x33 (00110011) out, LSB first ; ; Run through Read ROM routine pagesel WriteOne call WriteOne pagesel WriteOne call WriteOne pagesel WriteZero call WriteZero pagesel WriteZero call WriteZero pagesel WriteOne call WriteOne pagesel WriteOne call WriteOne pagesel WriteZero call WriteZero pagesel WriteZero call WriteZero return ; WriteOne: banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 as low nop pagesel Pause5 call Pause5 ; wait 5 usec banksel TRISA bsf TRISA,TRISA0 ; Set A0 as input nop pagesel Pause5 call Pause5 ; wait 5 usec nop pagesel Pause5 call Pause5 ; wait 5 usec nop pagesel Pause60 call Pause60 ; wait 60 usec return ; WriteZero: banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 as low nop pagesel Pause60 call Pause60 ; wait 60 usec banksel TRISA bsf TRISA,TRISA0 ; Set A0 as input nop pagesel Pause5 call Pause5 ; wait 5 usec nop pagesel Pause5 call Pause5 ; wait 5 usec nop pagesel Pause5 call Pause5 ; wait 5 usec return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;ReadiButton ;Reads last two bytes of the SN and stores the information ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ReadiButton: ; ; Will read out the LSB first ; nop pagesel Pause5 call Pause5 nop pagesel Pause5 call Pause5 nop pagesel Pause5 call Pause5 First_Read: pagesel Read_Family goto Read_Family ; ReadLoop: bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 movlw 0x01 ; test status of low_byte_full xorwf first_byte_full,W ; if Z=1, the low_byte is full pagesel Read_Family btfss STATUS,Z goto Read_Family pagesel Read_Low btfss second_byte_full,W goto Read_Low pagesel Read_High goto Read_High ; DecreaseLoop: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 incf bit_count pagesel ReadLoop decfsz loop_count goto ReadLoop return ; Switch_Bytes1: bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 ; In this situation we only decf loop_count ; increment loop count, bit count pagesel ReadLoop goto ReadLoop ; =0 again ; Switch_Bytes2: bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 ; In this situation we only decf loop_count ; increment loop count, bit count pagesel ReadLoop goto ReadLoop ; =0 again ; Read_Family: bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 rrf SN_Family_byte,f banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 as low nop pagesel Pause5 call Pause5 ; Wait 5 usec banksel TRISA bsf TRISA,TRISA0 ; Set A0 as an input pagesel Pause5 call Pause5 ; Wait 5 usec nop pagesel Pause5 call Pause5 ; Wait 5 usec bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 btfsc PORTA,0 ; test state of A0 bsf SN_Family_byte,7 nop movlw 0x07 ; test status of bit count xorwf bit_count,W ; Z=1 if bit_count=7 pagesel Last_Bit1 btfsc STATUS,Z goto Last_Bit1 pagesel Pause50 call Pause50 pagesel DecreaseLoop goto DecreaseLoop ; Last_Bit1: nop pagesel Pause40 call Pause40 bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 bsf first_byte_full,0 ; set low_byte_full=1 movlw 0x00 movwf bit_count ; reset bit_count for high byte pagesel Switch_Bytes1 goto Switch_Bytes1 ; Read_Low: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 rrf SN_Low_byte,f banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 as low nop pagesel Pause5 call Pause5 ; Wait 5 usec banksel TRISA bsf TRISA,TRISA0 ; Set A0 as an input pagesel Pause5 call Pause5 ; Wait 5 usec nop pagesel Pause5 call Pause5 ; Wait 5 usec bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 btfsc PORTA,0 ; test state of A0 bsf SN_Low_byte,7 nop movlw 0x07 ; test status of bit coun xorwf bit_count,W ; Z=1 if bit_count=7 pagesel Last_Bit2 btfsc STATUS,Z goto Last_Bit2 pagesel Pause50 call Pause50 pagesel DecreaseLoop goto DecreaseLoop ; Last_Bit2: nop pagesel Pause40 call Pause40 bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 bsf second_byte_full,0 ; set low_byte_full=1 movlw 0x00 movwf bit_count ; reset bit_count for high byte pagesel Switch_Bytes2 goto Switch_Bytes2 ; Read_High: bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 rrf SN_High_byte,f banksel TRISA bcf TRISA,TRISA0 ; Set A0 as an output nop banksel PORTA bcf PORTA,0 ; Set A0 as low nop pagesel Pause5 call Pause5 ; Wait 5 usec banksel TRISA bsf TRISA,TRISA0 ; Set A0 as an input pagesel Pause5 call Pause5 ; Wait 5 usec nop pagesel Pause5 call Pause5 ; Wait 5 usec bcf STATUS,RP1 ; switch to bank 0 to bcf STATUS,RP0 btfsc PORTA,0 ; test state of A0 bsf SN_High_byte,7 pagesel Pause50 call Pause50 pagesel DecreaseLoop goto DecreaseLoop ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; send_packet: ; Test the ability to have a .2 s pause before sends bcf STATUS,RP0 bcf STATUS,RP1 ; switch to bank 0 ; SendPause btfsc send_flag,0 ; if the flag is set we can proceed to sending (this is the .2 second wait for the send) goto PrePacketChecksum goto end_send_packet ; timer is not expired, exit funtion PrePacketChecksum: call CalculateCheckSum PrePacketPause1: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause1 ; SENDING START_DELIMETER Byte 1 banksel TXREG ; go to bank with TXREG. Both TXREG and SN_HIGH_BYTE is in bank 0 movlw START_BYTE ; move START_BYTE to W movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause2: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause2 ; SENDING LENGTH_MSB Byte 2 banksel TXREG ; go to bank with TXREG. Both TXREG and SN_HIGH_BYTE is in bank 0 movlw LENGTH_MSB ; move MSB of frame length to W movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause3: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause3 ; SENDING LENGTH_LSB Byte 3 banksel TXREG ; go to bank with TXREG. Both TXREG and SN_HIGH_BYTE is in bank 0 movlw LENGTH_LSB ; move LSB of frame length to W movwf TXREG PrePacketPause4: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause4 ; SENDING API_IDENTIFIER Byte 4 banksel TXREG ; go to bank with TXREG. Both TXREG and SN_HIGH_BYTE is in bank 0 movlw API_TX ; move LSB of frame length to W movwf TXREG PrePacketPause5: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause5 ; SENDING FRAME_ID Byte 5 banksel TXREG movlw FRAME_ID ; move FRAME_ID to W movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause6: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause6 ; SENDING MSB of Destination Address Byte 6 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf Tx_Destination_MSB,W ; move Craft MSB to W banksel TXREG movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause7: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause7 ; SENDING LSB of Destination Address Byte 7 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf Tx_Destination_LSB, W ; move Craft LSB to W (this is the LSB of OUR craft) ** this will change once we start syncing to other boats!! banksel TXREG movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause8: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause8 ; SENDING OPTIONS Byte (0x00) default Byte 8 banksel TXREG movlw OPTIONS_DEFAULT ;move otpions default to W movwf TXREG ; move W to TXREg - this transmits the byte PrePacketPause9: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause9 ; SENDING ME218C Header (Data Byte 0) Byte 9 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ; indicate that we are sending a command from the helm ** this can change once we start sending different types of messages!! movf Tx_Info_Byte0, W banksel TXREG movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause10: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause10 ; SENDING ME218C (Navigation Byte) Byte 10 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf Tx_Info_Byte1, W ; indicate that we are telling motors to turn off banksel TXREG movwf TXREG ;move W to TXREG - this transmits the byte PrePacketPause11: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause11 ;SENDING ME218C Special Byte Byte 11 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf Tx_Info_Byte2,W ; indicate that we are turning off all special functions banksel TXREG movwf TXREG ; move W to TXREG - this transmits the byte PrePacketPause12: banksel TXSTA btfss TXSTA, TRMT ; check to see if the transmit register is clear goto PrePacketPause12 ;SENDING CHECK SUM bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf CheckSumValue, W ; this is a value calcualted by a special sub function ** DON"T FORGET TO WRITE THIS!!!!!!!!' banksel TXREG movwf TXREG ; move CheckSumValue to W - this transmits the byte bcf STATUS,RP0 bcf STATUS,RP1 ; switch to bank 0 clrf send_flag ; clear the send_flag clrf send_tof_count ; clear the number of tof counts end_send_packet: return ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Calculating Check Sum ; This function calculates the check sum. Check sum is calculated by: adding up the value of all bytes (excluding the Start delimter ; and frame length Bytes). Keep only the lowest 8 bits of the result and subtract from 0xFF. ; To verify that the checksum is correct, add all byte (excluding delimter and length but include the checksum). If it is correct, ; the sum should = 0xFF. ; In our case, we will add up bytes 4 through 11 THIS IS IN THE CASE THAT WE'RE TRANSMITTING THIS WILL BE FOR THE PIC ON THE HELM ; DO WE NEED TO WORRY ABOUT THE CARRY BIT? !!!!!!!!!!!!!!!!!! THIS IS A KARL QUESTION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CalculateCheckSum: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ; go to bank with CheckSumValue clrf CheckSumValue ; clear value in checksum Add_API: movlw API_TX ; move API_TX to W addwf CheckSumValue, f ; add API_TX to CheckSumValue, store back in CheckSumValue Add_FrameID: movlw FRAME_ID ; move FRAME_ID to W addwf CheckSumValue,f ; add FRAME_ID to CheckSumValue, store back in CheckSumValue Add_DestMSB: movf Tx_Destination_MSB, W ; move value in Destination_MSB to W addwf CheckSumValue,f ; add Destination_MSB to CheckSumvalue, store back in CheckSumValue Add_DestLSB: movf Tx_Destination_LSB,W ; move value in Destinatino_LSB to W addwf CheckSumValue,f ; add Destination_LSB to CheckSumValue, store back in CheckSumValue Add_Options: movlw OPTIONS_DEFAULT ; move options Default literal value (0x00) to W addwf CheckSumValue,f ; add Options value to CheckSumValue, store back in CheckSumValue Add_Header: movf Tx_Info_Byte0, W ; move value in Header_Byte to W addwf CheckSumValue,f ; add Header_Byte value to CheckSumValue, store back in CheckSumValue Add_Navigation: movf Tx_Info_Byte1, W ; move value in Navigation_Byte to W addwf CheckSumValue, f ; add Navigation_Byte value to CheckSumValue, store back in CheckSumValue Add_Special: movf Tx_Info_Byte2, W ; move value in Special Byte to W addwf CheckSumValue, f ; add Special_Byte value to CheckSumValue, store back in CheckSumValue ; do we have to do anything special to keep the lowest 8 bits? or just assume that the variable registers are only 8 bits...? movf CheckSumValue, W ; move value in CheckSum to W sublw 0xFF ; 0xFF - CheckSumValue, result stored back into W movwf CheckSumValue ; move results of subtraction back into CheckSumValue return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SENDSSP_F: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; function for sending data from an address through the SSP ; The argument is the address of the data to be sent ; ;stores what was in the literal so that it can be restored. banksel PORTC bcf PORTC,SLAVE_SELECT_LINE ;Set the SS low so that transmissions can be recieved. bcf STATUS,RP0 bcf STATUS,RP1 MOVF tx_ssp_byte,W ;prep the W reg with your data to send. banksel SSPBUF MOVWF SSPBUF ;sends out your transmit data. sspcomplete: ; wait until the flag is set banksel SSPSTAT pagesel sspcomplete BTFSS SSPSTAT, BF ; checks the status of the reg2 flag in the reg1 register. GOTO sspcomplete banksel SSPBUF MOVF SSPBUF, W ;contents of the SSBUF is now in w register bcf STATUS,RP0 bcf STATUS,RP1 MOVWF rx_ssp_byte ;This is just done so that the BF Flag gets reset (data is thrown away) banksel PORTC bsf PORTC,SLAVE_SELECT_LINE ;Set the SS high so that no more transmissions are sent. return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Handle Packet Function ; This function will one day become more meaningful than this. I promise. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HandlePacket: StoreData: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf byte_6,W movwf Rx_AddressLSB_Byte ; move Byte 7 into Rx_AddressLSB_Byte movf byte_9,W movwf Rx_Info_Byte0 ; move Byte9 into Rx_Info_Byte0 movf byte_10, W movwf Rx_Info_Byte1 ; store Byte10 into Rx_Navigation Byte movf byte_11,W movwf Rx_Info_Byte2 ; store Byte 11 into Rx_Info_Byte2 clrf full_packet clrf byte_count return ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RespondToMatch ; This function stores the appropriate data to Paired_Hull_LSB ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; respond_to_match: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf Rx_AddressLSB_Byte,W movwf Paired_Hull_LSB ; the sender's address is officially the address of our paired hull movlw CRAFT_MSB movwf Paired_Hull_MSB ; determine if you are on the red or blue team btfss Paired_Hull_LSB,0 ; if the number is odd, bit 0 is set, red team goto set_blue_team goto set_red_team ; designate that we are on the red team led_number: ;Store what boat you are controlling into the LSB movf Paired_Hull_LSB,W movwf led_data bcf led_data,4 bcf led_data,5 bcf led_data,6 bcf led_data,7 goto exit_respond set_red_team: bsf led_data,4 goto led_number set_blue_team: bcf led_data,4 goto led_number exit_respond: return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ping_response ; This function generates an appropriate ping response ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ping_response: ;Formulate the ping responds packet movlw ADMIRAL_ADDRESS_MSB movwf Tx_Destination_MSB movlw ADMIRAL_ADDRESS_LSB movwf Tx_Destination_LSB ;this is the ping responds header. This is constant and never changes movlw PING_RESPONSE movwf Tx_Info_Byte0 ;This the state that you are in with your ibutton pairing. ;0x01=waiting for ibutton ;0x02=ibutton read and waiting for pairing ;0x04=if ibutton is paired. btfss current_state,WAIT_BOAT_BT goto paired_ping_response movlw WAITING_PAIR movwf Tx_Info_Byte1 ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired) movlw UNPAIRED movwf Tx_Info_Byte2 goto exit_ping_response paired_ping_response: movlw PAIRED movwf Tx_Info_Byte1 ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired) movf Paired_Hull_LSB,W movwf Tx_Info_Byte2 exit_ping_response: call send_packet return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; STATE MACHINE STATES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_for_ibutton: banksel PORTA bcf PORTA,1 call iButtonFind call ResetSequence call SendReadROM call ReadiButton movlw WAIT_BOAT_st movwf current_state return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_for_boat: ; banksel PORTA ; bsf PORTA,1 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto ibutton_broadcast call HandlePacket bsf send_flag,0 ;we are checking to see if the packet is from the water craft. movlw MATCHED_0 xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from boat goto wait_for_boat_check_admiral ;We now know that the command sent to us is from the watercraft ;Is the command from the watercraft a match command? movlw MATCHED_2 xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a matched goto wait_for_boat_check_admiral ;We now know that the command is a matched command from the watercraft ;Store the information you need about the Boat call respond_to_match ;Change states: movlw WAIT_GAME_st movwf current_state goto exit_wait_for_boat wait_for_boat_check_admiral: ;we are checking to see if the packet is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from admiral goto ibutton_broadcast movlw HARD_RESET xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is from admiral goto wait_for_boat_check_ping ;It is a hard reset so change the state and exit this state: movlw WAIT_IBUTTON_st movwf current_state goto exit_wait_for_boat wait_for_boat_check_ping: movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is from admiral goto ibutton_broadcast ;It is now a Ping command from the admiral we will respond to ping and then continue broadcast the ibutton call ping_response goto ibutton_broadcast ibutton_broadcast: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for a broadcast of the ibutton movlw BROADCAST_ADDRESS_MSB movwf Tx_Destination_MSB movlw BROADCAST_ADDRESS_LSB movwf Tx_Destination_LSB movlw IBUTTON movwf Tx_Info_Byte0 movf SN_High_byte, W movwf Tx_Info_Byte1 movf SN_Low_byte, W movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you exit_wait_for_boat: ; banksel PORTA ; bcf PORTA,1 return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_for_game: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto send_no_action call HandlePacket bsf send_flag,0 ;we are checking to see if the packet is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from admiral goto send_no_action movlw HARD_RESET xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is from admiral goto wait_for_game_check_ping ;It is a hard reset so change the state and exit this state: movlw WAIT_IBUTTON_st movwf current_state goto exit_wait_for_game wait_for_game_check_ping: movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is from admiral goto wait_for_game_check_game_start ;It is now a Ping command from the admiral we will respond to ping and then continue broadcast the ibutton call ping_response goto send_no_action wait_for_game_check_game_start: movlw START_GAME xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is from admiral goto send_no_action ;It is a hard reset so change the state and exit this state: movlw PLAY_GAME_st movwf current_state ;we are prepping the send packet for the game start ack movlw ADMIRAL_ADDRESS_MSB movwf Tx_Destination_MSB movlw ADMIRAL_ADDRESS_LSB movwf Tx_Destination_LSB movlw ACK movwf Tx_Info_Byte0 movf Rx_Info_Byte1,W movwf Tx_Info_Byte1 movf Rx_Info_Byte2,W movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you goto exit_wait_for_game send_no_action: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for a broadcast of the ibutton movf Paired_Hull_MSB,W movwf Tx_Destination_MSB movf Paired_Hull_LSB,W movwf Tx_Destination_LSB movlw NAVIGATION movwf Tx_Info_Byte0 movlw NO_ACTION_1 movwf Tx_Info_Byte1 movlw NO_ACTION_2 movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you exit_wait_for_game: return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; play_game: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto playing_game call HandlePacket bsf send_flag,0 ;we are checking to see if the packet is from the helm movlw WATERCRAFT xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from watercraft goto pg_check_if_admiral goto pg_check_for_stand_down pg_check_for_stand_down: ;We are checking to see if the command is a stand down movlw STAND_DOWN_RECEIVED_2 xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is stand down command goto playing_game goto pg_stand_down pg_check_if_admiral: ;we are checking to see if the packet is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from admiral goto playing_game goto pg_check_for_end_game pg_check_for_end_game: ;We are checking to see if the command is a end game movlw END_GAME xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is end game command goto pg_check_hard_reset goto pg_end_game pg_check_hard_reset: ;We are checking to see if the command is a Hard Reset movlw HARD_RESET xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a Hard reset goto pg_check_ping goto pg_hard_reset pg_check_ping: ;We are checking to see if the command is a ping movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a ping goto pg_check_red_base goto pg_ping_response pg_check_red_base: ;We are checking to see if the command to change active base to red movlw RED_GOAL xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command red base goto pg_check_blue_base ;goto pg_blue_base bsf led_data,4 bcf led_data,5 goto exit_playing_game pg_check_blue_base: ;We are checking to see if the command to change active base to blue movlw BLUE_GOAL xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command blue base goto exit_playing_game bcf led_data,4 bsf led_data,5 goto exit_playing_game pg_ping_response: ;It is now a Ping command from the admiral we will respond to ping call ping_response goto exit_playing_game pg_hard_reset: ;It is a End Game so change the state and exit this state: movlw WAIT_IBUTTON_st movwf current_state goto exit_playing_game pg_end_game: ;It is a End Game so change the state and exit this state: movlw END_GAME_st movwf current_state ;we are prepping the send packet for the game start ack movlw ADMIRAL_ADDRESS_MSB movwf Tx_Destination_MSB movlw ADMIRAL_ADDRESS_LSB movwf Tx_Destination_LSB movlw ACK movwf Tx_Info_Byte0 movf Rx_Info_Byte1,W movwf Tx_Info_Byte1 movf Rx_Info_Byte2,W movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you goto exit_playing_game pg_stand_down: ;It is a Stand Down so change the state and exit this state: movlw STAND_DOWN_st movwf current_state bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 clrf Standown_Timer_LSB clrf Standown_Timer_MSB ;send acknowldge: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for the stand down ack movf Paired_Hull_MSB,W movwf Tx_Destination_MSB movf Paired_Hull_LSB,W movwf Tx_Destination_LSB movlw ACK movwf Tx_Info_Byte0 movf Rx_Info_Byte1,W movwf Tx_Info_Byte1 movf Rx_Info_Byte2,W movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you goto exit_playing_game playing_game: ;put led data into tx_ssp_byte movf led_data,w movwf tx_ssp_byte pg_check_helm_helper_ssp: call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;check if the byte is a header bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movlw HELM_HEADER ;Move the header into the w xorwf rx_ssp_byte,w btfss STATUS,Z ; if the z==1. goto pg_check_helm_helper_ssp ;if it is a header we will grab the next two bytes from the ssp (Helper) call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;save the rx_ssp_byte to where it should be (Navigation Byte). bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf rx_ssp_byte,W movwf Tx_Info_Byte1 call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;save the rx_ssp_byte to where it should be (Special Byte). bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;Check for pump: ;============================================== btfss rx_ssp_byte,5 goto do_nothing add_more_info: bsf rx_ssp_byte,0 bsf rx_ssp_byte,1 bsf rx_ssp_byte,2 bsf rx_ssp_byte,3 do_nothing: movf rx_ssp_byte,W movwf Tx_Info_Byte2 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for a broadcast of the ibutton movf Paired_Hull_MSB,W movwf Tx_Destination_MSB movf Paired_Hull_LSB,W movwf Tx_Destination_LSB movlw NAVIGATION movwf Tx_Info_Byte0 call send_packet ;Send packet does nothing if you exit_playing_game: return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; stand_down: ;we are checking to see if MSB of the timer overflow counter has reach our set value movlw STANDOWN_TOF_MSB xorwf Standown_Timer_MSB,W btfss STATUS,Z ;If Z==1 the command is from admiral goto stand_down_checking_admiral goto finish_stand_down ;we are checking to see if LSB of the timer overflow counter has reach our set value ; movlw STANDOWN_TOF_LSB ; xorwf Standown_Timer_LSB,W ; btfss STATUS,Z ;If Z==1 the command is from admiral ; goto stand_down_checking_admiral ; goto finish_stand_down stand_down_checking_admiral: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto stand_down_no_action call HandlePacket bsf send_flag,0 sd_check_if_admiral: ;we are checking to see if the packet is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from admiral goto stand_down_no_action goto sd_check_for_end_game sd_check_for_end_game: ;We are checking to see if the command is a end game movlw END_GAME xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is end game command goto sd_check_hard_reset goto sd_end_game sd_check_hard_reset: ;We are checking to see if the command is a Hard Reset movlw HARD_RESET xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a Hard reset goto sd_check_ping goto sd_hard_reset sd_check_ping: ;We are checking to see if the command is a ping movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a ping goto sd_check_red_base goto sd_ping_response sd_check_red_base: ;We are checking to see if the command to change active base to red movlw RED_GOAL xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command red base goto sd_check_blue_base ;goto pg_blue_base bsf led_data,4 bcf led_data,5 goto exit_stand_down sd_check_blue_base: ;We are checking to see if the command to change active base to blue movlw BLUE_GOAL xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command blue base goto exit_playing_game bcf led_data,4 bsf led_data,5 goto exit_stand_down sd_ping_response: ;It is now a Ping command from the admiral we will respond to ping call ping_response goto exit_stand_down sd_hard_reset: ;It is a End Game so change the state and exit this state: movlw WAIT_IBUTTON_st movwf current_state goto exit_stand_down sd_end_game: ;It is a End Game so change the state and exit this state: movlw END_GAME_st movwf current_state goto exit_stand_down stand_down_no_action: ;put led data into tx_ssp_byte movf led_data,w movwf tx_ssp_byte sd_check_helm_helper_ssp: call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;check if the byte is a header bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movlw HELM_HEADER ;Move the header into the w xorwf rx_ssp_byte,w btfss STATUS,Z ; if the z==1. goto sd_check_helm_helper_ssp ;if it is a header we will grab the next two bytes from the ssp (Helper) call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;save the rx_ssp_byte to where it should be (Navigation Byte). bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf rx_ssp_byte,W movwf Tx_Info_Byte1 call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for a broadcast of the ibutton movf Paired_Hull_MSB,W movwf Tx_Destination_MSB movf Paired_Hull_LSB,W movwf Tx_Destination_LSB movlw NAVIGATION movwf Tx_Info_Byte0 movlw NO_ACTION_1 movwf Tx_Info_Byte1 movlw NO_ACTION_2 movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you goto exit_stand_down finish_stand_down: movlw PLAY_GAME_st movwf current_state exit_stand_down: return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end_game: end_game_checking_admiral: bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;see if you got something from the admiral when waiting for your ibutton btfss full_packet,0 goto end_game_control call HandlePacket bsf send_flag,0 eg_check_if_admiral: ;we are checking to see if the packet is from the admiral movlw ADMIRAL xorwf Rx_Info_Byte0,W btfss STATUS,Z ;If Z==1 the command is from admiral goto end_game_control goto eg_check_hard_reset eg_check_hard_reset: ;We are checking to see if the command is a Hard Reset movlw HARD_RESET xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a Hard reset goto eg_check_ping goto eg_hard_reset eg_check_ping: ;We are checking to see if the command is a ping movlw ADMIRAL_PING xorwf Rx_Info_Byte2,W btfss STATUS,Z ;If Z==1 the command is a ping goto end_game_control goto eg_ping_response eg_ping_response: ;It is now a Ping command from the admiral we will respond to ping call ping_response goto exit_end_game eg_hard_reset: ;It is a End Game so change the state and exit this state: movlw WAIT_IBUTTON_st movwf current_state goto exit_end_game end_game_control: eg_check_helm_helper_ssp: ; call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;check if the byte is a header bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movlw HELM_HEADER ;Move the header into the w xorwf rx_ssp_byte,w btfss STATUS,Z ; if the z==1. goto eg_check_helm_helper_ssp ;if it is a header we will grab the next two bytes from the ssp (Helper) call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;save the rx_ssp_byte to where it should be (Navigation Byte). bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf rx_ssp_byte,W movwf Tx_Info_Byte1 call Pause500 call Pause500 call Pause500 call Pause500 call SENDSSP_F ;save the rx_ssp_byte to where it should be (Special Byte). ;Control of movement is still kept bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 movf rx_ssp_byte,W movwf Tx_Info_Byte2 bcf STATUS,RP1 ;switch to bank 0 to bcf STATUS,RP0 ;we are prepping the send packet for a broadcast of the ibutton movf Paired_Hull_MSB,W movwf Tx_Destination_MSB movf Paired_Hull_LSB,W movwf Tx_Destination_LSB movlw NAVIGATION movwf Tx_Info_Byte0 ;we can't turn on our water pumps or other specials movlw NO_ACTION_2 movwf Tx_Info_Byte2 call send_packet ;Send packet does nothing if you exit_end_game: return ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END " title="" id="id2" style="height: 32753px; left: 26px; position: absolute; top: 130px; width: 693px; z-index: 1; " />