From 062784102557dff0033d4b4932bb31b413bd14ae Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Wed, 9 Sep 2015 21:41:41 -0400 Subject: [PATCH] Channels for raw SI commands Configurable poll interval --- config.c | 41 +++++++++++++++++ config.h | 2 + hiddata.c | 18 ++++---- main.c | 13 +++++- requests.h | 5 ++ tool/Makefile | 2 +- tool/gcn64.h | 1 - tool/gcn64ctl | Bin 0 -> 36400 bytes tool/gcn64lib.c | 77 +++++++++++++++++++++++++++++++ tool/gcn64lib.h | 11 +++++ tool/gcn64utils.h | 5 ++ tool/main.c | 114 ++++++++++++++++++++++++++++++---------------- tool/mempak.c | 34 ++++++++++---- tool/mempak.h | 2 +- 14 files changed, 266 insertions(+), 59 deletions(-) create mode 100755 tool/gcn64ctl create mode 100644 tool/gcn64lib.c create mode 100644 tool/gcn64lib.h create mode 100644 tool/gcn64utils.h diff --git a/config.c b/config.c index 8010d55..0f3b8b4 100644 --- a/config.c +++ b/config.c @@ -10,10 +10,15 @@ struct eeprom_data_struct g_eeprom_data; * values. */ void eeprom_app_write_defaults(void) { + int i; const char default_serial[SERIAL_NUM_LEN] = { '0','0','0','0','0','1' }; memcpy(g_eeprom_data.cfg.serial, default_serial, SERIAL_NUM_LEN); g_eeprom_data.cfg.mode = CFG_MODE_STANDARD; + + for (i=0; i 1 + case CFG_PARAM_POLL_INTERVAL1: + *value = g_eeprom_data.cfg.poll_interval[1]; + return 1; +#endif +#if NUM_CHANNELS > 2 + case CFG_PARAM_POLL_INTERVAL2: + *value = g_eeprom_data.cfg.poll_interval[2]; + return 1; +#endif +#if NUM_CHANNELS > 3 + case CFG_PARAM_POLL_INTERVAL3: + *value = g_eeprom_data.cfg.poll_interval[3]; + return 1; +#endif } return 0; @@ -50,6 +73,24 @@ unsigned char config_setParam(unsigned char param, const unsigned char *value) case CFG_PARAM_SERIAL: config_set_serial((char*)value); return 1; + case CFG_PARAM_POLL_INTERVAL0: + g_eeprom_data.cfg.poll_interval[0] = value[0]; + return 1; +#if NUM_CHANNELS > 1 + case CFG_PARAM_POLL_INTERVAL1: + g_eeprom_data.cfg.poll_interval[1] = value[0]; + return 1; +#endif +#if NUM_CHANNELS > 2 + case CFG_PARAM_POLL_INTERVAL2: + g_eeprom_data.cfg.poll_interval[2] = value[0]; + return 1; +#endif +#if NUM_CHANNELS > 3 + case CFG_PARAM_POLL_INTERVAL3: + g_eeprom_data.cfg.poll_interval[3] = value[0]; + return 1; +#endif } return 0; diff --git a/config.h b/config.h index 8ac7efa..03ede3d 100644 --- a/config.h +++ b/config.h @@ -1,10 +1,12 @@ #ifndef _config_h__ #define _config_h__ +#define NUM_CHANNELS 4 #define SERIAL_NUM_LEN 6 struct eeprom_cfg { uint8_t serial[SERIAL_NUM_LEN]; uint8_t mode; + uint8_t poll_interval[NUM_CHANNELS]; }; void eeprom_app_write_defaults(void); diff --git a/hiddata.c b/hiddata.c index 891c872..d115dc5 100644 --- a/hiddata.c +++ b/hiddata.c @@ -38,9 +38,8 @@ uint16_t hiddata_get_report(struct usb_request *rq, const uint8_t **dat) /*** Get/Set report called from interrupt context! */ uint8_t hiddata_set_report(const struct usb_request *rq, const uint8_t *dat, uint16_t len) { - int i; - #ifdef DEBUG + int i; printf("Set data %d\n", len); for (i=0; iTd+wEd&Ep1(w)>|TOOO5WXSY}u7HlJ@YLlBG@*cvyeLOo zhYYPE1h`5DJzD7zTe)B2X&&W@0}@17B_k$0t_?Gx$shB^zezfOliUG7gaZu3LU|tw zr7wV6@n*b^@m&`yhFup2WWrx3*vCS^09=Bfit&bszre z*z4=2kTw;6#{b*@={%S4-k3|=bo_mS;n{ahS`hr{yU)D-h0h%On>Ca6@AzHbCGT}j zn)Bj^h41|2w|U=r@WVo|4SW476c0y?X21tB;C~72!|Ayw1OIsN`-ib;dj>t1Wzh3x z2L2Z^;BU>Kry~RZwHf&D%Ygr82K;py@Xuwy7iGYQGT@)eVEDmx2H9GVp&l1OKQD_{kaY3!vYRzw~Qw2L8=p9M1j+GVosqet)`hz#B90 z-vs<R2oiQ{ux5*Eh8` z2_zLp7?+XA1|6x7Mk3)zYoa9*t&TUfwJNHHBNA$BkFtIDSRx_S{JU5 zRL2w1NH`j4Z;NW((P&##@-{@`=?utvEwejM)YmsBVvVAn>c#rnSZi(jM$y(DZ)&X* z?GdS?r6v}Qw}B>N@u;M?C*m=ITWw=?RMb{CH@DT2)(jObk(O8_4ydjz5hp}_^~zkR zsBLM77i;4i+auwcFy)X|b+my3NKL?2AV6qs5cTV$P4S4Rj<+?5`u1p3YrLKcTiQBU z63l`wiI(c7RzVkvaHOs}UJYtZET)J+AtzTaUA&+oJg4*`J2rc+9i3D9Nme+w{AZ>k zYS89g;muvq-Ezbmq8cnmM7MD1f0S|IPhBp^e1xbOcZ-^uMv?zr*)D{*xBE*zj-(%G zI5Dv)hk9LF!9aPHR0Jk5PR7*Dv?oqmIHsD*v=8Dr#+u8t1L8{z5}|2l#Lsl#ix*T$ zC>wW}W?y~>-sF+Q=?*-{esh&M@TSd@Hs66~+U5#4@J!oWAqU>{MWn58;Ndv?TI0Zv zu(3i^IqY z@O=*aBnSSa1An#yKj6ThRIl^p0{XG)?G+{QK{+$wz5@t8izeU2g z5T^P4?Gmmb%%;;{CE*(gv&rvY%2W$3135)O{Bj}!V3tqY4rOgd?{fziT(l! z&mqjF&@UuBlQ5e=|H;!pOr1=aRlonZgeMYamG3_);X=Z!>ixYE9zmE@ynmmB-Go`S z`+Fq(hl>D@CA?F@?-6EI?%yKecL=iz_qR*<*MwPh`>Q1U3&O0j{VOE=W5TSe{Q(L8 zfH13Qf0=~8N0?Q!-!I{(3A0M}7fATqgjp5)g@nIO_*}v#|HS-1NZ3#KIN;g;u{inC z&7tJ4L!ED&T(Nrb;of%4U_yrv3K<;UT^JC3PeReD`uuYjqP;$hiA-gvg#CV~b09C2 ze6!=M{m>?>;pm$VkT7^0%v*^RH@#5LtJJ{HlU^CR{Wnse}VP;KtX_pT_qCU6JLa! zt?YLc7(9AY|ED3t_<`-nVc$~t;Q4PNc3?kllDls&a0gfe`+oBgVsDdg3UMbHo5)!4 zOvDNp3ozzmY!_o6QKFBr_ZX8}_A)mA6TrR3*b2s8W^5N@KVa+_W4(-(U5MBdj7iyM z#@dK`kg@HI?PBaGV|O!FT!PqE#-zlhjNL?BJ7XIdt7oj2u^SmHE=6o5W9^KE7(2$; zm5AN+0=PsfxI2`1}L7bT075pevdo|s>RQ1al@ z?C73nmvq1?gH`k4-Tf%F!4tQh_yiLO?bvqwgTcYjj-6ZsFc54h1G_52H;`(mtMa5x zd?l1T+&7m=ZtG1vjZB;*;%#(HFc+dLZP7;{3Y=|oZ>|u@=a!y=!sK@Y2o492(IKJ3 z!J`ayehvo*6m&`jCmDd}NIf(o>?7RoMz*?wFLw4_)j4o+{+;gwm+TF7W&Kmn9CXgd zVeU?(@HFfc&r^U#PG??r+(!cFJ<^bup58(hPN&F{APX`!9bT-SeP2W6=zmyJPKiWm=cWN6y|7N(QEuDON11n_dO!2i zAA?NaAsUkm?mto4x#^UMUts*ZftAlMP&O<);8|I{}f!|gM9z~@;DiWWEBlolX!bD5da%qSkp8QG~oqh0Wj!nvw ztD(McCOv%)=o>Y?z^2!eKElpnHycM+@F)`ysOZS(J|wbFB*q-rK-O!KBjt>GupW4X zxXXY$?9G90>7^Xm!0uatGEzmvnh9^bANt1O;2VgeCLL#hN?qcDNaw)Z{5vZ!Ur^P$ zYObu-UEUXFF*k?%mcTLFw^3jI6FOiovJYv?1o~#e0MvGJ!1#Sn(TwMrM@p|kr2kFK zPMjP8C&#{gBprOTbJL@)gg+&TqjnO9KSZ6`11 z>=6=q@aglJ8jU(IK!5!$eaOzKe=;&1>KgltQe>2dqwOe08h$^_>c4O}!>NiKALbdu zeTk`uwq1w(vul%nfP*H@F%HV1^}m8x|Estim~InJqD~%?0_dXNpk9;>gZ}T}PMf6N zOzafR`8$IJi!|XiV!2|Ww4k5eA(I~}jq;}g;9Z0*${bck^ zD~HhS0Y<>Tqk@xrIbBsDUe;o0n{JS=Z8-8 zc>^$GU?^G4Y6egO10p_+gix29x#pWVyg6NF6(q!e_?|s`fyq)fnK()2r$=HgV~^2W zDI+H`>?>ZI=|{O7e0mzpP<@3p4}C?O$z*>U41^LWQjc%_bAjmcej9Rlnj3MTjO_c6 zwoKr_-%dw%USbl-?@6&_!H_h1^DD`IJJ_W&`bXQ^6V&P;2O2E9RQ0lI%^s0w+~sh~C;8j~QC1D+DjVMT1B*l>8AL z+38Rd>I%TH%7M_1&vSg$Y#3z!weQ9hHuy+!VbpPQb^K1+G;m_(P?9U=%Q*6CV&xVr6L&+Dw2Sl*1EBI_@ zuZ#2U&Uaj)WaV*07bkyQ{tPXb@uTH@c_Bi(o-SZOHrLUo7=K#gKm1+j*4~29j2Ef6 zvlkf)9)tE{huBFxt7i1aLOVh(AbXK(7Q-iD-B8M1%P4>upDf8sPO_Q5+_~vxv5^%C z_``iK|5jH{@2{u%#q&GiIG|Mx+7AIaM4s?UL@4=csOu)}rvHuHJ8~90W;fx3%!2I~ z?ex^FmxASttpEHsChKoske>DDAfU2-IsIiS+^jD6ug{eX9_5_xvuAUXCZDVvnM!(s)=_9d`k5?g>$6kqx z6RKDGF8ht2+cu)Lp`e$sJ1~X47ERme@IyzI){$-N_#t)N2OTGTOey}1{p^%vxBbI< z`IvbbnXmdpF`alHR}0`G5R^Zr&I?|qYae`gf$?@r|X zH!j{!Lr-VqhsW_OgE3j0xFG+@${(VgB@h1O56PpQ$6e@C^Vsfo|L8ds{I(mU)Aa}YtnI_?(_6^5b+O5JAr*CbZ=LLydcOk@`8f>}j)z>|%YSkiqkXE2z6ts}2mEoi`jt}P z;M0XLNVWPI(AoDotf#L|t-=5u|Uu~<|=meF7d zb!{VpKKTLCJg}66fqpvTzLO*vx_tQM0FP8z;#s3T&Z2nTx)Ii-y&h%hR*%$(F093;S~^!p0#}g((r<=Wm4af6n!CA zFBi9-6qp806#>EN*!W>n#$Z+olaccyeU4-wP}AkdCGI2t?VCOt#5?l*yU#=3okgDF zP%JDRM}CxFpMt3Ex5Ir=v_j?A9ukK0>wd66f+{#`X|?nHno>o=^IL&sIend_V=udn zK5z%{eSZ(6sttdm%j3k=7!A05CW|ro($kz$+jX7%crtdy&pvP$!Kfh8MSUMs$2}@UBK-iOLtZuW%vgC8%xPuRH9oN!L|^3x;e!E)tYIQl3O+UP}If zCHwDK7)SFMOj?ZG$TVUPAOIy98G_U?Y= z*dYghPAXTE3F%-pm(#whRNh+yy)d|PZ}P~}WUyyp@&_o$$F~RfZLi#|rnN|GUuUm} zqokV89z%3-^5yd9SQTX4%xzQVvj-gW*$>Z{&vM3c^pM!X0RDR%Zq(6z+gG3lVf^DP zYDdU}aIg00r`}=@BF(`xCI5*{yWv!5TGrE5`9tvSFHa88t=qAFkqjQ`+;l{`^~j0Y zAogG;4aJxV^x}~hi(hKo@6l=W=o(gnG)TmZcSocTMNobd-elNsL+W>yUtgXaEWd7X z@`Liq#mS$RuU@)iYTr0NUXko5VYq7Pj5lZhGIa1y9#l@N&-(@%(6;}GpJU#qEKR<% zH2J|o=olRHYN+!CSLl)xiFf!SaNSKzt^DTlFkZpfDZc*#yv%op`c3FJDNYRLm~LKNggzXlso}+nW9HHr(plqWzO{XRvU3>UR>{QZ8Hfvg)a0bViA9R zQ`EK($;BhJ@kkwq3E0_2eb|>$-_%S-+;Cl+h+`{@0_nzRq`JK1^;0nBZ))|oG&Q3VL_n%TiNlZ5t|7e+eI_dHf`If8 zikZxQ8X?N-I;vZ1fg17{tyOw!+S=mHZPnNcWE7=^DLNx@EP<+o zeNjxdskI?Z3BXm@W+aUwHQpF;Lv>1?=|{GA zlrdDq6K56iUO;dAIyeWc4iH55E5KGiH z`m1Apv`l|H3M|qZPf15L+Ate!is=$qNGualT+%;KfCMVhm#lA!H#&NZc$;5tNkf+_ zyNelOYT29(c$d#Ulieh?(V?#rL#?0t*>nRILseCz6uWRbIR(%jH|+G5j5~59(rUU$ zt+7IPcG4uf!Ah%!AX$rqko`KFe`G@(en>Rep`VSTWAMujerUUOe7h|cwIy2Zj(pnG z=Ge3gO%EiY5n`$#Pmj&O$OQHgqOm!4X-9qArFeDG+ELxyWcOOCyBq5IF;We6$d}5Y zOBq<%8bue>(AxBAbRO6;h=$o3FZHjEZp45#Lab_PX>Z=>XEB&Itp_O%o4Cr2l{!V# zAdEUK35*uVBZiJTqfCybEp1WuFeuR$xh1nyW*&O3M{g)c8l~PZGi`Kh4=j|!qx7H7 z|ME7|&1-}Ra&sjInpWDYl$H9YFKqK~Y)kkXt2-io3_>kU7%4DrUo}Ipt!*q7=(1%F zWtWN}I}(LISta5277X+&*wq?59H_8HN{tnC$tpEuYi}4o%=2?oXEg@RD0C?vRSK)n zq0-W6x3JA1y`c&{4fRD1f7Hv?#OAA-=entNH(lx%=pxR*8AjG?&9)N#ZF5{2U9&MB zi9u5Qs3-uh3-Q5U!~d2aZcp>q7t`Q$e?FLj{*4THBcGpv{&|h>92byw|4xTzPf+k* z!~Z)!l#f^PU(%tsSivSdrQt3e-lF-o=6l(2Oh^;Y%jRylR0Vt*advwcyW@?Q zq9=__8v!XZ^l)ptUvF*4w47Vp{nIhv%ow3NPcl%s?tL_Rl|W2r`)7e+epy-BD3#`={#A{%BZ|&=gcz|9X9Lc|kk%CE z{KM8!TOF-qUnukJ*V6<}IK=hX)6P`%6hh~DJ!THvfUmc_Q>$>D<+&^iOFrByaPSzyb-x}Q96)#*!eXo=+<|aD z!hb}#2H}qpZa|p#I^+?)jECC&2(Nq-@(3Fc4j_!+;o0vI;>%q6Kp4Ps4R@mcC&KLr zw_(v~FT!)No_7SHz>;Pk!X|_k-Ye!}Rd+hV8?n|MLfC>AHQc%S8-&{t{tPcI_92{! z_ftm^HsYn%0K#Jk16YFQHAV%(_34$uwV}Xu*2rvYrz^XFcy7Y%ePwWPrsiQVJipqz zOaAtkktgI$1Irbntak=xafLFophiw)`p3 ze+l}hoPO{uwaa4++T=*IRc=eL^Y0mH)8~TzC(v(C(f=8#pMG8q`pszL{Z9JTcX>Lq z-2Wz-fTx|G0pGc3`>ULM?&Y?g-Jq`oJ*B)B@9^A})#>$2QDwFevM++K5q*bzpkI(z zaF08fSA4f8nCIV-70jD{mp7DGc84#NH@`D`Sze$yZ+>}RS$W>{1$q7jdBxygkY~w$ zU}P5BA@smKf4%d>6qG-smB`O68KZqC=A zrC|(_@|tMiK$VQK|KMflzdt?LM!3oyz2nX!ahyc;{W4;`5lAwggQnABo3@H!pV>##$Icj)j-I{XJ6KB2=yI($WkZ|U#@9s2Th`Z~Nohx2r}NQc+y zuwI89I+RZMAG|G?rR+;jqERER&OmS0^rac-^_sp?(@i}y>9{oFrVR2tC&8;R1N}lx zk7b~jX!`9L=%t!|cLq9lAoF@K1AVrpe=`HUOw*swK$mk6=>Jg$I)C?p*S~4H1{D(b zHXVC21D*RxdA*-O|0mNGD)uw(S65VAieheZ5e_tDgv+N zv+g74@_in>+5ZNHV_CoFkGoiWah~--4er8vAH=Lb-ovQ%I`JPdUSLhfsFL+3#)~cf z5<=E##{Jf}$TP_J^c?I`L55uf%5t(O;F7@n93ET9a!VkPb0aBP5(wq|h7_*^R^;HV zp~&({U`@_12w1LffuSnrM`Rn}`YwXToI?agx@y4Co->i!3M3HENzk%F7vBJH$hnfh zIM*ToTXM?DHr~Yt-p}Q{L`t#i8R+TEnNMJn>z@H^&*6_qWKDJ52DY6!w=$hl7d^cz zCrV(J1bT8d5-5|v-kdE2W=mjS&YcA2xJn?iKZoZzvgS(LdUM{P>Upl0!0@6Nk>#zt z46$6!BD`ys;hy`qVDR2ZtQg6nT7uZ9I}q`RJj=VX8KCtdK=0}r+=cZC#&2Q?;?O>7 zvGCqZk^Fm^>iyY#wk^);q5rH1nI2$NSll?C^&mZIS=TWB4>dp+2%q&?;C$9@Kr(%L zM5a&ddH@ppD}yZp_H6(Kv^9GSH2HmvGmy6Rb;NzQkWpCd#e6L_j9RyV=xZfQ!Dy`c z3tt=Y#n8jBup9#Jh01t}4cRAK{Af zsn^qev_+iNhM3Qy*rZA_ZlxFx=JJw@I0#+4&q0rM_Ltxk#o+0Fw(;y+BuI*8FQp7;}Lm7u#jq>M@`qjt7TJW1l` zr$Dj0J1}tzRJgh*>F#cxSj9v&)Hv~42UIt)3u(LVQk+#2`71ZByJt%Cb~a7?EQ$B9 z>Up~NZ=U!t)7VK69zVyd^s{^5^*CHyjCYc*FE5t)+0rD=eMqk=^VAxz;@Xxv;d<** znLux2F-q-irtRt8y?Npf5pne?Q&vx0!L<7owBp=pdi1%2T5$PM#tUTSc6ToY?6cTU z`YifGRy`&mtKMcYk~QEO179W1<8Q`TUuT;=kJEPFC6ql6f5LY)6CC+2NVge*0x@|$ zVAl<|0+Zv}Qc(pKTpJ*pCHVU`dO-RG(&m7aK2nZ^^j`-gG5mnE8qTo?B=$Q0?*^nQ zXtM{Tb^w2g0jUG&U_eS8HJC{~YA|X>4Q4le)HokFHEQH?B%s+N??8lD4o(t#hrt$! zQ5pOBJk_~-bN>i#*|~d1GAi0*=kMCl}M_AV|ehJwNtRFCbIq}6-Ho6<%mBjn4GU5Y_Pq!Xryn;Ms)L zsh;vY$~{(&s5_W|Eq{-ZAN|j?_da@XP)nb-r8(#+>H8?n0dK4vt?pC9;l9mTNRY+q4DwGeqP19~EdpUIF`$u3^Ry~|*)x)G<4zangmzk2{LsmVKV%67Qmb@X~gmEB0+}$e*=QD3o z7~^!|wGvXaKw*i47NRjPC}Wz%gilk+*#vVuF9xe*dXv=R&XJxzOu)F7!H{3%!o# zLNBIe(4(FUz0T)Cuk*Rk>wGTsI-d)@&gVj}H4J-4xcGddhGDPsxzOu;F7!H| z3%$wGTsI-d)@&gVj}^SRLLd@l6P zbKQ<~^f2tz4{zQcW>OBr-Uk>}!?5>3W>*cvUi;y#6gZ#7GL!=@&9;YOmZrpZ8!R8* zz6@X#`|`XjYZl*@=X1qki#wk`!@4CapFb$O#meVVsx1ZiHxTL1-$JNY*qP7X|F; zTmfdZ+aG{>A?}iQCdBb`^dD$RfKl|sMc50189UkC-EGudQ3G~pF1p2z*Nyp>R%IUb zisJZ%K-Xf$TE!xvhOy63bq%p+pBKPg2>GfNp=k1!cmK(HpV2j;j-Va&nm#f6s zHl}qOMV{2Q{R(kjuHAmnlx?@A+IE|3ce|_@ z-3?-FkfuID)?JeWxZ{Pjywi%CZ7Uw36?m8|lF!oLAOW4W8l+kQ$UL1Z#$G^ePg0xf z{D9Q+psnp`TicUL+nUk*@f6pS%mar2>HMddLDVTRb|Q5hp{}oKUGgQ~o(Z zU0L171~(PHM{PeKDXaVV;3n3cf2KI5M65eHjvC6$PX*ifI}pJkud#PiQa(_gni2pG zmC_zqzX(Q^RG*#H=oTPdeQefQ-A7H*@7PHf`ba-PQFnJ$VJ@L}wJE3$T=VoiHgLs$D z|7A?V(;e{T$*Jk(w1d5R-hL*d!N)h#I~v%(S>!VT?V1qzM!Tlw73F&J&dM9@D$Fhz zkFp&nJb9PqUY5JK2nwf&+}tZcM-|pltk`?=fkmZbK(6c}mnSbbmqIRp)+k%Ue6Zzc z(7U*Z;E3_AA=ca>R@5DrYjF`3jKV&;qFLb0D{}DW8^iFJb^#dBq9JW5Q>nR7Gaw-> zZ%UiI#-=et32|CFwp5!qZ36QhDE`ud3Fs3_kq=5Zu(W5q*G|V>jK)1T1)MM>wYbRE zM!AV#)UKr5Sw#RZM>>;AT~|#oDW%DrjkFvx=j5V@3bU#0TouJLuTCHNq}ua_Qn_jZ z)lYUJ$nn2Y%tNJ>Ysz(`Dc4cXl0qS)_ShwrpITA{#%ZHJ#%YDAPAe)EL;kf(1S{KT zmeiLQOrUSark3zH?P1hz`ft25XvU>bBN&%j9OI=6(QMiBbmRCK z7Y_AVru#ylm8JSDuc?;oBYYoY0+yIe-@;s2sd>yv&D03f6An|=P4VXq*-nM|Y!qmk z7J6~FIK)Qk`eWWG+~wPNR43Q0L@dfrGT=05?JRtYA&hf}>cb2Tt%+H9|2wOxwYE8d zvu=`817~v9G~qY8oh;aWi{HsEtwo~zwe7k{eQ6^GZNcB-jv)$@kZe;MqL_)T=P?i! z#Th2Nm(Xz@QAJegFwE%g-R5PEXR>R_9_xxdnXcJy3wM^Mn>Y8A(Fk0=Ykb@GcrGY? zY(sa#`hG{*68E%x>ub+gSCV+eY-@c-r?q5#=hn5>*Q`$W^djr~Jso8U{9D_TD0|FW zTV{RVQ}tEP6nB}cr(w?nQf0lb!TSCK-DM5#DMc5#rxkfRN&}d!349Z+uzcZQid}Z@jJtqY0eC7t=+*i2q>)x)< zpbXqX4(ETtx*&J^|GAYxG0Rd{znHITfI2aNUuN$Zwnmt>Qq+jYy4S9qy=3j|?|-o& zF?sFmt=6n1v!6*k^VYNT-nVW*p+E4<4SOE2I-kMq%02E`W8BlmSZ|`(;7dqFxT3%6X z1blTWj_vRDOXgTNzqMq^lE)I(H#^W?I!IbO+X}z6^cvwbs(L7yW)K8l!tM+AsCCNwsTyyLzBt%AU9OSdTSqd&bdj+!vVMq3JC)B$v-U zr;w5sD@4{B-h444eAmc(6YrjmuOeWd;u&>>v9%XjckX#}kG0k6v=WIu>$_2>_B=z@ zcFow@L(sKWw#F{h1Gn5db4G2z*-UhPC<;|-4(HS3<_T=Pb;ptp_5n96YrqO16kkz> zOuN^NO+1DbaS}SeXpIBUR77RMv)!dd?(0E+%-Yjqz29(yH3qfSor?;Ij+b9zK){bA zgv0n21I`LZ!g0jWMGN^^gvwZT13!s?Jpl;}3yp0pky+8|_QqLd3vo=PWfo3^H$8y~QcXCA}$?+gffLjGcafK-PF$G9#MZfmX!x7F9<9Ir^=2vY-3G|6vW zRM+B14`Sr4RRvH3GooQQxURLjB_f85vE^tL-J-IK6zD{mitXE)YJAHhoM`14)Hy@` zpbM{FUg@t;d%gT6E%8Ka z2}L$6K>p!n0aCIiTR|A>3`j%IFL;EE z@0G&zA!-*?^S2gS+fW{j{8UG4Se}8E1}|E?G^jYq#~f7G-kNAf0H2`7qV!F^Bucs) zr^R&Tf}!%Kqulo33mrW0bzqH;x$U$l|wpxVH-O|ccqki~T& z{3=Fsqz=u#If60`YXg*AtTBNP#jI}?sJHd_(F-0eMg>8eiA3wGYi(})v_=9jzj1?F ztMaBau&k6xF(kp$!}K>hBsvHd#Kh$hQILOQkhg%9@gt2QW$5o>N+5AP!>)l%7&Z9wglO^2M-%_ufT z674vXF7r5Fw%1j%Uy(-1q}a4tBh4bZVW@&)#6(XM$7xXf8i;7e>GBrRSxmAFNk{jt z=>~<;G10L8kprG=XRU^07^{~y8Q*SN)l{KQpo_RlS&Il!8r#@{d?1WRRoG}^vYNGv zQvA$8q_lj&;*vPJ00rS$tF$K3gpcB(g_IJ)$kHfE>o&GRp9)bXl7cqEBl;;o7&O%Q zY6|FBdvjcr$}%YBPb`R1`8}vov=e@^s5H_Tu7_tL=u07MASHnzEn2-%NtpO8wP1tx z>XxQjB;5vuxRuIOltz35NtE(vEPf{etdW{T1BBW20k1&W;0>v!CW;2FAvii>;_w$A z_&(>$6qMS`I}V!B4GupoG2Oh;M5#H-;sWKaC&CAb0QvmiE5yH zIDV`tFBlGAECLn7;fKC2CmfeYaDVTamq(b>M5#27JcXEwBjgchpNW+Cb28x1Jp+## zjyF2L8%!sR1j03p->@c&+CNI{%MYZ8@W)7qKbeLv*ZA~vSl0vZ!uR)jgH?zzuC96+ zKeHUU!It{Xxh~Bvz9RY0tPlHvA1+@9v>vmtV|MBOK;zRl>EZ`vWxDCxZGW9X|2x1l zUuL&Q7GPcj_@n*lJEU@v@!{;`&S~A8^!;7f<;?T&A>T*I`l4$Yt5ev^{_%=Wbh_(J5DUk~DiWes_8 z2RKUojO$^cU^i_d1*&ezRmayblHphd&E={~6W@aWU}2eP?osd?Vr@XrE2 z8mAbxR8$FGe)xsgKV{(mc?SIJz|;SMiYkiR*GZ{=g5ZaGc;U5xyt3f%;qp5Hc)#Xx z26Ce(>WNv_G&~o9e>4{NLlsp{b`i*+|N0F0TO@we8Ji?JG(LSt127npq&7Zzk_8Q=sE82m+Sf}x3f$w%L z)T;66+gdkEyi>D^-wjJb{AA!+ z&(r-@3jA>PaHj$NnZAegdW}!tVcaC~XU?nJB>v0{ZwH?J=l)=oB${?DYNJ@M!FmFo zAj9EnDprPs#nh(E4t1# zJLfuweDLM!MamM*Fl#RA!C(5}%$0|xhk zaP9K)Ws57o<)C1V8ebs}U%m9&1?5Y__&v#0!PVi_JR@rmYCvi{a|D$-uIRv(p4B{Ey;L(*t` zT-#D50}o(5K9yB}E;<#N_VsS*0_~@8U92sPr7Nsd3j1@{snW<|N`1lyq_qdQ9O#VO zOM_Tm=F2*~Ucve&t>^lw`i8ek++P0Fnz(>xmJ01wB1=+zraRRlrNg=UYnSTKa+`b` zpi?tT&)RXc$o}azy-J$0%rY#*lNr+s!^jH1(4A_k{B^Tbl(NaWDvOmx z{32#5*KnU$SCY;}cYY!~RZixOUsqSZsFq3$hw)W+)4TC=?`9B4`PjQk#$L%+ptBn` zb;t2F^PzMu((k8+F#0p&XAWflO$=8)T=>(|WJCghaB0LO1=)A!}f;-@Zq zT-We>_=L@_XF@KmzN7G7u|tf|wpiKN)#!zmeB zMBJ13bIP0b(kd;{_Bs#A2^q&CDDR0(& zd*&;l)oB9h>Gy(-CbA94D^R6F6{Pd0!`!JvR~vb=o@E98Jo#f_qy0wStTz|@nezVz zS=K!xZ`P%Ywfu4IKT|)A{iYtg1zBhMX8n4g90Xj3UqM5#!Jh!ZDQ~ZH>jvf5>1UGX zhIyxaprT5$1}bD=_k#)=>JJS32SjL#$-j9X>j^53>4s5GJ1ikbmzcCG|Pe@o6RL^0PC@ z$7_|q3{!D3$X}u5)BX2%O-i7ggQMdz>6>sgXr}BOY~rVX_onY~%1@6f iXfHc$T$Ay4IsQz&HT^&Px8c%1`dJWg?fx(F|9=3!lx{`< literal 0 HcmV?d00001 diff --git a/tool/gcn64lib.c b/tool/gcn64lib.c new file mode 100644 index 0000000..f74c0fb --- /dev/null +++ b/tool/gcn64lib.c @@ -0,0 +1,77 @@ +#include +#include "gcn64lib.h" +#include "../requests.h" + +int gcn64lib_getConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *rx, unsigned char rx_max) +{ + unsigned char cmd[2]; + int n; + + cmd[0] = RQ_GCN64_GET_CONFIG_PARAM; + cmd[1] = param; + + n = gcn64_exchange(hdl, cmd, 2, rx, rx_max); + if (n<2) + return n; + + n -= 2; + + // Drop the leading CMD and PARAM + if (n) { + memmove(rx, rx+2, n); + } + + return n; +} +int gcn64lib_setConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *data, unsigned char len) +{ + unsigned char cmd[2 + len]; + int n; + + cmd[0] = RQ_GCN64_SET_CONFIG_PARAM; + cmd[1] = param; + memcpy(cmd + 2, data, len); + + n = gcn64_exchange(hdl, cmd, 2 + len, cmd, sizeof(cmd)); + if (n<0) + return n; + + return 0; +} + +int gcn64lib_suspendPolling(gcn64_hdl_t hdl, unsigned char suspend) +{ + unsigned char cmd[2]; + int n; + + cmd[0] = RQ_GCN64_SUSPEND_POLLING; + cmd[1] = suspend; + + n = gcn64_exchange(hdl, cmd, 2, cmd, sizeof(cmd)); + if (n<0) + return n; + + return 0; +} + +int gcn64lib_rawSiCommand(gcn64_hdl_t hdl, unsigned char channel, unsigned char *tx, unsigned char tx_len, unsigned char *rx, unsigned char max_rx) +{ + unsigned char cmd[3 + tx_len]; + int cmdlen, rx_len, n; + + cmd[0] = RQ_GCN64_RAW_SI_COMMAND; + cmd[1] = channel; + cmd[2] = tx_len; + memcpy(cmd+3, tx, tx_len); + cmdlen = 3 + tx_len; + + n = gcn64_exchange(hdl, cmd, cmdlen, rx, max_rx); + if (n<0) + return n; + + rx_len = rx[2]; + + memmove(rx, rx + 3, rx_len); + + return rx_len; +} diff --git a/tool/gcn64lib.h b/tool/gcn64lib.h new file mode 100644 index 0000000..54d89a8 --- /dev/null +++ b/tool/gcn64lib.h @@ -0,0 +1,11 @@ +#ifndef _gcn64_lib_h__ +#define _gcn64_lib_h__ + +#include "gcn64.h" + +int gcn64lib_suspendPolling(gcn64_hdl_t hdl, unsigned char suspend); +int gcn64lib_setConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *data, unsigned char len); +int gcn64lib_getConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *rx, unsigned char rx_max); +int gcn64lib_rawSiCommand(gcn64_hdl_t hdl, unsigned char channel, unsigned char *tx, unsigned char tx_len, unsigned char *rx, unsigned char max_rx); + +#endif // _gcn64_lib_h__ diff --git a/tool/gcn64utils.h b/tool/gcn64utils.h new file mode 100644 index 0000000..ab714fb --- /dev/null +++ b/tool/gcn64utils.h @@ -0,0 +1,5 @@ +#ifndef _gcn64_utils_h__ +#define _gcn64_utils_h__ + +#endif // _gcn64_utils_h__ + diff --git a/tool/main.c b/tool/main.c index ae9cb8a..5475b9b 100644 --- a/tool/main.c +++ b/tool/main.c @@ -26,6 +26,7 @@ #include "version.h" #include "gcn64.h" +#include "gcn64lib.h" #include "mempak.h" #include "../requests.h" #include "../gcn64_protocol.h" @@ -36,19 +37,22 @@ static void printUsage(void) printf("Control tool for WUSBmote adapter. Version %s\n", VERSION_STR); printf("\n"); printf("Options:\n"); - printf(" -h, --help Print help\n"); - printf(" -l, --list List devices\n"); - printf(" -s serial Operate on specified device (required unless -f is specified)\n"); - printf(" -f, --force If no serial is specified, use first device detected.\n"); - printf(" -o, --outfile Output file for read operations (eg: --n64-mempak-dump)\n"); + printf(" -h, --help Print help\n"); + printf(" -l, --list List devices\n"); + printf(" -s serial Operate on specified device (required unless -f is specified)\n"); + printf(" -f, --force If no serial is specified, use first device detected.\n"); + printf(" -o, --outfile file Output file for read operations (eg: --n64-mempak-dump)\n"); printf("\n"); printf("Configuration commands:\n"); printf(" --set_serial serial Assign a new device serial number\n"); printf(" --get_serial Read serial from eeprom\n"); + printf(" --set_poll_rate ms Set time between controller polls in milliseconds\n"); + printf(" --get_poll_rate Read configured poll rate\n"); printf("\n"); printf("Advanced commands:\n"); printf(" --bootloader Re-enumerate in bootloader mode\n"); - printf(" --suspend_polling Stop polling controller\n"); + printf(" --suspend_polling Stop polling the controller\n"); + printf(" --resume_polling Re-start polling the controller\n"); printf("\n"); printf("Raw controller commands:\n"); printf(" --n64_getstatus Read N64 controller status now\n"); @@ -58,6 +62,17 @@ static void printUsage(void) printf(" --n64_mempak_dump Dump N64 mempak contents (Use with --outfile to write to file)\n"); } +static void printHexBuf(unsigned char *buf, int n) +{ + int i; + + for (i=0; i= 0) { + printf("N64 Get status[%d]: ", n); + printHexBuf(cmd, n); + } break; case OPT_GC_GETSTATUS_RUMBLE: - cmd[0] = RQ_GCN64_RAW_SI_COMMAND; - cmd[1] = 0x03; // Length of SI command - cmd[2] = GC_GETSTATUS1; - cmd[3] = GC_GETSTATUS2; - cmd[4] = GC_GETSTATUS3(0); - cmdlen = 5; + case OPT_GC_GETSTATUS: + cmd[0] = GC_GETSTATUS1; + cmd[1] = GC_GETSTATUS2; + cmd[2] = GC_GETSTATUS3(opt == OPT_GC_GETSTATUS_RUMBLE); + n = gcn64lib_rawSiCommand(hdl, 0, cmd, 3, cmd, sizeof(cmd)); + if (n >= 0) { + printf("GC Get status[%d]: ", n); + printHexBuf(cmd, n); + } break; case OPT_N64_GETCAPS: - cmd[0] = RQ_GCN64_RAW_SI_COMMAND; - cmd[1] = 0x01; // Length of SI command - cmd[2] = N64_GET_CAPABILITIES; // N64 GET status - cmdlen = 3; + cmd[0] = N64_GET_CAPABILITIES; + n = gcn64lib_rawSiCommand(hdl, 0, cmd, 1, cmd, sizeof(cmd)); + if (n >= 0) { + printf("N64 Get caps[%d]: ", n); + printHexBuf(cmd, n); + } break; case OPT_N64_MEMPAK_DUMP: @@ -282,7 +318,7 @@ int main(int argc, char **argv) break; } - if (cmd[0]) { + if (do_exchange) { int i; n = gcn64_exchange(hdl, cmd, cmdlen, cmd, sizeof(cmd)); if (n<0) diff --git a/tool/mempak.c b/tool/mempak.c index 66d087f..554bb76 100644 --- a/tool/mempak.c +++ b/tool/mempak.c @@ -3,6 +3,7 @@ #include #include #include "gcn64.h" +#include "gcn64lib.h" #include "mempak.h" #include "../gcn64_protocol.h" #include "../requests.h" @@ -122,30 +123,42 @@ int mempak_writeBlock(gcn64_hdl_t hdl, unsigned short addr, unsigned char data[3 int mempak_readBlock(gcn64_hdl_t hdl, unsigned short addr, unsigned char dst[32]) { unsigned char cmd[64]; - int cmdlen; + //int cmdlen; int n; uint16_t addr_crc; unsigned char crc; addr_crc = __calc_address_crc(addr); + cmd[0] = N64_EXPANSION_READ; + cmd[1] = addr_crc>>8; // Address high byte + cmd[2] = addr_crc&0xff; // Address low byte + +/* cmd[0] = RQ_GCN64_RAW_SI_COMMAND; cmd[1] = 3; cmd[2] = N64_EXPANSION_READ; cmd[3] = addr_crc>>8; // Address high byte cmd[4] = addr_crc&0xff; // Address low byte cmdlen = 5; - +*/ //printf("Addr 0x%04x with crc -> 0x%04x\n", addr, addr_crc); - n = gcn64_exchange(hdl, cmd, cmdlen, cmd, sizeof(cmd)); - if (n != 35) + n = gcn64lib_rawSiCommand(hdl, 0, cmd, 3, cmd, sizeof(cmd)); + if (n != 33) { + printf("Hey! %d\n", n); return -1; + } - memcpy(dst, cmd + 2, 0x20); +// n = gcn64_exchange(hdl, cmd, cmdlen, cmd, sizeof(cmd)); +// if (n != 35) +// return -1; + + //memcpy(dst, cmd + 2, 0x20); + memcpy(dst, cmd, 0x20); crc = __calc_data_crc(dst); - if (crc != cmd[34]) { + if (crc != cmd[32]) { fprintf(stderr, "Bad CRC reading address 0x%04x\n", addr); return -1; } @@ -184,7 +197,7 @@ int mempak_readAll(gcn64_hdl_t hdl, unsigned char dstbuf[0x8000]) return 0; } -void mempak_dump(gcn64_hdl_t hdl) +int mempak_dump(gcn64_hdl_t hdl) { unsigned char cardbuf[0x8000]; int i,j; @@ -193,7 +206,10 @@ void mempak_dump(gcn64_hdl_t hdl) mempak_init(hdl); printf("Reading card...\n"); - mempak_readAll(hdl, cardbuf); + i = mempak_readAll(hdl, cardbuf); + if (i<0) { + return i; + } for (i=0; i