From 1162b3f9efaa110a02db453453148c03cbe9633c Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Thu, 6 Oct 2016 20:07:49 +1000 Subject: [PATCH] Parity checking --- CHANGELOG | 3 +- doc/SCSI2SD_QuickStartGuide.odt | Bin 17587 -> 18596 bytes rtl/fpga_bitmap.o | Bin 32724 -> 32724 bytes src/firmware/config.c | 2 +- src/firmware/disk.c | 16 ++++++---- src/firmware/scsi.c | 41 ++++++++++++-------------- src/firmware/scsiPhy.c | 50 +++++++++++++++++--------------- src/firmware/scsiPhy.h | 7 ++++- src/firmware/sd.c | 1 - src/firmware/sd.h | 1 - 10 files changed, 64 insertions(+), 57 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a6cd8c64..f58e8e33 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ -20160922 6.0.?? +20161006 6.0.12 - Fixed SCSI timing issue - Added glitch filter on SCSI signals. + - Re-implemented SCSI parity checking. 20160912 6.0.10 - Fixed write issue with UHS-I Speed Class 3 SD cards. diff --git a/doc/SCSI2SD_QuickStartGuide.odt b/doc/SCSI2SD_QuickStartGuide.odt index 6d929b39a5c1f7c6d43c98d82a85dd5c7434980f..fd6616910ba2e317da240bc44182df86cd7de84a 100644 GIT binary patch delta 16697 zcmZv@19V``vM3x*Y;)pFILXAeZQHi7gNcoaZQItwwrwX9^PlhBd)_va@S; zacT4R?hFhJjEIOxNJz-Y$jHynFE1~zudnay>FC(#@9!TQ8|&%Wnw_0p1J>3C26o2A_NS+h=I2k=)-Lw;_Rh}E_V;hj&+q^I zQ=UFPKK}Oa^Yb%nxN;K&1cOyVSU}l*^+E^1YmK#fW3$l#b*(M^H&TvF_5;F`tL@U*Rt-8mM+)df`wvFJrm22G3RoAnoIf}>2BAdA?;`>Flr?WX`l@Nr5UC)>` znZC=F4O=%# z9W|amWnXQ8TT@TW#kC=kje%;48EyA8)i#)@_ZtcD(;xE93(=}&2?j{c76tZoL>o(bS?RFU}U7wxXwd|Gxa_e=MJla=pTqh`xJ$QciaES6< zDRTCLtlIXuYTAr7@Z?2tVOvC=)tPtwYsl|x@<4NO!0G|ZmE>8aWw}#er>*Bxi3M+} z?4i-8w@;g7@sxpZ(fv;TV*azc6WD%l_U%hah1xBI{9`G*gFE!=x!c6l+63A>u|Yc4 zL~~BppSZl`?ct1)A10R4iCzS+EfNzv23DVKgLlPHu9eZsx6A2`2Z>6Z3*1Ob(~_My zp}=^Q2pRxoNeQm`$laV+z!slGT`PGcUw)NH!`m0aA-_YUlK{P!A7~X8`uoB$rm!H( zHMeE45Drn_AewlbJxo+iFpK?g+M#5-;E6~M-RG9^&aY{JImA(Kz70<%Q1NxeA+gW z=0Z^5ft+CX3Vr&fx64l;biczm#In_HQWz5^G|{LJa?>pnqFhO#i`~3h?kic|bsn3F zPQyvp{01(*tfrt=MO+}bN{(JdWf~Ss0&fvbr8o|s8}o|{MAx)K zDwk&!+F~^gSE*6&H7}}VRo~*_y7Tu;kyd@}Qd-QzYt&4~+E@qyS%iq5{9pA>WWVTE zUM#4$EBLKm-Z89EPW4Aw>D`Oo1Nm|@b^@8w6PP=SIh_#7Fy|poh}K^^mA|-H_Hnpo zNnt{!$F9ymN0O**6rng#!7CBwAZd*Tl@@|kn#))PDgM&EPUTRd z%Jl|6-GP~Rko+P9f*l)xDHfX2xjeRS^Zi2jC=||VbvSCnK=H^RHG|+w3?Tl88=X}= z@+NmiIDXe+sncrroB)|O3Fl~p_yGRm1)+pRMGo1%5utk8mMoG|Ec{@l1?s0;2(jH-KB0bBQ6YZmEL*(e9zy8%X9NHS8bN+ZlCs_UuXxG!KRqwN3eM>eVe}@1uV#CC z^@p<%CFjZT#elZhvNHA(b9~q*JfF`01``{mi16`YFF6H>xy72NZhqTI; zzT#v~?8{<)YbV;kY(>LaeTY@SI|u_fU+=plb^8vfzMOs3NEE42WXqjL%a8hJ@ezmR zou3Tg*Y-a?!p7`PevYs7`?_L;jPQs-bFOv7aSxGkYGXSwJ9|T!ghWiu*7c2z6q?)> zHC}qKlZb4y6;fZzIOG4wK;vQv;V^
    +~c`Vr?N7}pXANEOia`laU2*^8bV;OlJ* znzD-_kwhU?D&6T-3T+Rvx);1&je@!67MS*r<$T3TPJ|mb)UJ$z+kaeF`LJZAO zv{Jm12Xe{-{G<|CzXp{Sw8d0h3KRROKPn{31}Rg+#d&EiiBl57JXxtu1R*ppkij(r zpSwpWqc0<97Cw_Vi0P4o;usn=OyPn3Vk`~5f!0VCG<&TzH zgHp9T`7-JFBLT4qbm%cC-rXmz1(~^IWT|u;4KgpHd_^XWbc00Z_mHqvVfqQy0_(9n z2gZ~P=TKbXBYp)eafN8i0<==0ef{bB6=r8{Yb~9@e=OX)`s}gLq<(RYEy_=Yo1r4G zBg6|Jnfj?7Mak%5JAnuR=ApCiPQw`(#nfAhXujI)>VCW4*?sFjI0$(J-ad9>#v+iu z^J(j9e|&U(`g%CreB3^=ecybD7~|X2+rEEwyW0G`Dbv&L==27BJ)+$vKcCX$AhS)P zC!xxwy;-fS=1`rC)05~2=XRX^l+aQCfXxF4X@-b_Cz5r8-PzrofZNB;?(XjS+r-N6 z@};kvou6CHM|OJIncc6Q-F!ob&%d9apWEx%uIz)Zwz}Foyj^@hfTJU`EBeW;56_R& z`}FRyXU8BT5q$^-_KHI^a!@Y8BUp8jRIT&TR+jV*WH9hvjB9<=4Q@JX?GE?nTL94Q z@cr}hcD}H(^1QNgre@aN`Eq~1QvH3i%iYKIVQmcS`({R``_0Smi29}PQ@UN=H*05G zy6>(ZhxcP@cDh|p_vZ(8)%1kU+JU*7R*uh(af6We#JRG%!Qj1}IFw&`V;?l_hMO)w zPcE>qF9WmBhu-efx0zp=d=k~Xf8POC2WLq((!;Ce14-DX^+QDycXoG;cl_y+21jJp zq2O;6lv#mr)4sk^cnG~VyA?sS1lHkPUw64hT_YEnqBzx9+ z!|F*##B3)aV`T0}xK@Ib=*))h)Wmr&XJxOVIHRrcA~uXOIKqqex1%-Uv+e-){0PMa za}K&g`Ci7~N)cJx>==!yZs~4G*gN?F9fIDQWiCmtZ*{IjB6GN6D|E@ z@|6>de>-jQx;)Fw~Va5U(ICQd5 z!nQ8iFe(e{0+iV~I!+X)YA7Juvo;Fuv|7}GR_$amdzkifV9G}x(D;1-4A!i}v8Y|8 zOIp6J%&fH)a+vd{xT~nu2i%QkH$HJOwubsh4mv9_8(i}!5x%FS&fA<&j1^rn;*5Uh|g~q zU*FNLSOmM=XHK$D&R(Np;cpEZy2PeqW5hxWghXr*ztm7pQ#?OG=OhUcEZHYhd&{;6 zVGkY{%~O4~*5i{{JMJ#|#{Evpz3;(KoYW$#>6b`$`tjIc$3#`VE*F(N?M-8G1RsQik zrNEGKHKCh;GCNJo#-CqY3RV+g z6NU1H&aC2e-~muizrCcrY*BKppV{ts95TXCi%XfO>Pk=q`jXPN_l<=Gk~zvxDDQz+ z4N)gOK6mY@Ra?c7V|$#ZkM}cUDw7Ys=F9VX?T1U64ZN;NTkoQwbP>k((L{{}vqrLp zq@7XY)*+xexYBwJ%m?6xW!uyK1XoP*D#o|7x2lqrbRpbddFOpF+KvB1pGgd+cJ<57 zV7;Y8lW~im36pT!9lEuGsG4s>*X9}W^;{^UjF<04iNUy-yfyMAM_e=6dF#bgrr&C!wj65hWVrR*yyXOd93nVVm zcCKW>C`t9h)O?rg_2v6uqpxiBy&V1f#dGE3snsWWeRB-Yy9IXj*Vl`)?sOl=vq#TI zw)gcZ)@VsqPcyw_?mPw0cK!i>h6T&<=;J@?EWltRT@tkkg_J8V?Zi@FR~q=1KQ5yC zzCMn~ojFR0m*ySVTFU7WF~zcIEf}u-Cvi z)og&8kK3znGKQ>LCsHpB%;bucpbZi9l!NOyn5cG!J_()V{kSy{ zDvQRQ?A>R|eK>h}iSkcW$3Cq$+fjW`{k5?57sJKYMsJ-%>gJxqPAqq&!eH<{Z@_4W zHju<+6^i%J*~TRDk3=N>gtvZ1bq!sMjA0Pz#5GLHCX3}$pgRuaW)8lp9#FpJp7X-V zGxKe7ZhuKik55;xSYa|>Lq-gas!(p^pmC|mjaq6dyW;m!IVWwiYz`YJ5u8LLmm*_# zcXbf0-dE=Ccvx-M5IyKRn679=WP*|WHn;b8jA~8~EaMvW z`F`%F0qA&;zeYKs*tRh7VaS=4xrHNb+mzVF%TN}x1E%coGTEL)-zsQvI zuOY{l_a9slB=G)k!r#j0)6H`}PQFt_v>6!hcj70D9b45TWYL{esH3KZv?$yrRu(8q z#)`pWzaXo(a3=9#h$4Q(uCuNfkf}r$ok>);?+{y%sS`#Pajm)!7fkSwc$X?zoNxpCbks z`yFyt8s&Csb3Virwlv9H5{Oa|30!!2P!^3j;%&@=YI?TTMQucj2<`R6nz=T4k;KY3 zJb7$XJ9yKM78Wxzo)!f1vs@d>imiBcUx5&q5^jJZ_lRf7xtg|$E;_1XWWyM!{ANp{l{%gS!@zSGLTEtL} zwR|K)GPpa1M7MBwB@fE=F-o5e4lYVrKUwr(83GA%Rcy=`0ib-VKp70#GA%q775OIh zt4~b6Qo;J*r$}=BLUDt7ga|fmS8UJ29mvqV-sVKzd$Ux27}you^|{E;iqXkNvQu5u z#~&uouo!vbLg5d;y4GR`Z@wUnoL}rv3SE{6pwrF<39x&?SKIVs!{=(AB2bo_V6I_i zwdJ8~hJatrE&?bXSVe@t!903P^`Rj3JlD-vc)pzSk_{`uEQ8@#-b8hh#Y>P}kk@K8 zWo;NTK#uu^tmn>&HKIh9YAUGKiX%KH0X^qehIm->pPciB_I9sc-irzj%e%P>w7(9D z?0@lK;X;PBZnfsTJ8^vcXQQLIM2_-RjO}v1vqDXiyl(R(8W)WO{F=9MBofY0*G9P# z8(q}@GC_GX%5Cd^A5|jO&HsAOerJa-0-rNP!qFaMHpy$6BkKT1o)xe_kN_RP2FDst z!@5K0Lkqw(^w}PS?G=fWDy`{$$sn5`73Gq{bhr=3O{U_)r%(j$TDqJz_q0%H>>#(# z@`Nzw`H=5dXrXy%uWqU;Z$im-C+9BShJh4ynHyoRl}83Y|9RZ=PkTSNc|N zNZ_o3R7n=jlQ(6wY7jpQloe>CRjAKwKxEG)NdZ5>7D|#fS9sQk66YOr>Zg>qTYH%9 z*<~Kt-45k*vjvkbt*h8l4XIr}J7}M;@(G>FSq2hmIHY#qCT+7Aop2;XY9klG@?kxG zl3-zxzEvdAcz-u{(H3TFgg3!ycW+!97#z7IH!m$G<>Aib{_7{pNu65^|Wy>!=-~{ z*ARiEdkX1|E4Q3oyvvcVC+8h^NNSnTM*(>J-29~6QB(7pTOj9(f?5gDEkijWC(0Cb}Gv$ll6XP9s-Mbkr3Jvta;Y|U-Yw@`{OGphvUm& z!K%jJuq%j!h^%mxpnkxA#gd_+q5p{`C*)y~&>@@Y>qBoF>+9DBGOqin=MB=icSi=THUD=O6W24=I;Cyc%6!4K& zY0!iDbHOG}cweHlFKf-cSD(D^n>fthKF+g!x4WjaJ$D`0-~fw6Rvp5^>t@h=Qir_D zEY>qjb3TcJ58PSc*)35j&}4rn#UXBI~BMK==VESa(srAD{L>vh5X z22z`J*sgGG?0^)Q#6c?^uDrH%1MQsUK?AXjgvv*3)3{<{5NVpSDuToaYT2%*_6kYW zkd^YDthnL|E7=WqN3`-Vm77WwIk=&ePcVp`(xM$|q%46rV^$E{t+oKvsKKU1(|UKF&G zPco1O>MFHC9~#u`ddlbH4xGrEi<=Hub2%i4kdV(vGr_R|pzTlA4<>1^>x!bW|a_CU%v z1k()hfWWZv4DTQGyRlRC&_Df_3o*p)4AU4oM8G)CjctSL7NERCs9eseCm4>VaS$A1 z6ha#uaVOJrLBIo|`t}lLkDs4nf3htU^-uKj01ktYVmq)q1?A^Er^%R`R)+3BL2}fn z3n5+iXs19EKaneU1CUzz=P2oIJm(PxR**)M0jy+%d%R~}8*c~!db@rUC{oDoOr;>& z7M&K3bO?g_oSr8crIPl_i3sf?GL81(^$9N8Th`pWc;Pqq_6?c{UCxlDk%noU3O3xXAlx@G-en0GC%^W$ z06$^g8@1_BRrTq1h&4u5SR_)MiC9vUPPZoUrd9N1{9T|H>5r@TrJ7PJQDrcaY(*sd z+pm>>%x%!Nph8u;_zLP#YQVM>kK2rTz(SFHX6!w}7B__7GnZ30?C0-So5IV+Qc&d! zqRFL(z@#oPLG}B?ahDrsL0H2h(&zY60~&Od9Z?8>?j=Qu&=BevG`Gccv`wY-mex6n z7A`@YTsSzo-DGKp&XL><4(=`8)94WbL}a%WQ<1W>2L_aWnXOqPy+WgD2RAyMq~{#F#%jj_zF;iE+y?g6c@9;U$D94)EMOuKKp|19Z9_ zdiq(x+iSyw@+jF!(o7UEIFw{r`)u1_O&1Z4dhM8v#LirSu|428AH6i5kO+Wirqf zT}v%^f(QFzGHX8rvV@=a$C_(ZFsAWjqNMoWKdCY+F@yUrEv)C7iEqi2A7#_KFA zv-AM|C0{e$ySYSLg8itLG|1&qzf+a{wJWaNCdmzH|B)nvwbhGtEClY>1Cj13i&Y)= zcUC)fSQS}{EF(+x?+y|WRxm!GsMFe4CoyVsonc$V7@m$v_8Y*u4l4D5Ioim1h zePb@JvCqXUDp7@IizjNi=Jx$iJgq2L(`}UDgCC~pR=!K@ap^(UVjvo|!AsY!p^{dW znT2ebO09&dm*?*5d1l`Se)buwARV+ZqenMnai`Ms)(8xF_(Oz^r&!JHAbo`~?|t*<%~c@6-dh z5A^pre4o@w_^EmD1nxdmet>4OozJVZfThh#RoSesbLG)!+~-1Gv9i;mSr--smsH{K zd{S{5L4V-svY-jnhqyN;rY-2i-q~~y>b7f+)}GQIyRJWk*E2ppeb8Q|X(>N|nL&Vd z7Wr?E=F>u(Tb87|zc+w-Nqi_b@6Q3nQCGmHReL?-rQs zYAzcHV~FMh4tCyxR?AgLRG#LJ<3B{(N~bJhIb8Vh@d`kG1N$4qjJtNl_w1SRuVS$; zCUH;+S*&R`^+(S4nXzO>m?uyeccH2AYT?=*-xIUS2dLPH6~HOAB6J=`j^g2U>NMpl z25#*>y?WFU*EZVp%ZRmRI=<^?Wcoi>e{!koTi36ZhC~q7vZ-@&_1|6qh?tl|4KFN@ zQoP1?JhoN1~T~Lrha#q*a4{|_|dgl1^sB5KuXxLzl>!59IOag)bt^<%=WGpxZE_f zU#n{E&r$HbAi6tKoX=6XCDfyN0x03eYsIc13^*R3v%WD55%!`59W0Z&$M^i@lfy_B zIze$>e1M)GyTS5;@U+Kd6*+u8KWwU%Z8Guipp-qXvfpKcB6@vaw9032$NYBQ z$yy!Ne~q(U^QhRt3R{oW`B7xB>~)X{u26q_xmeMW-1d!6>c{(HOkP}FWKAoq!I?e^ zZz$M1^rFDRjaUm}$vR(vi#(v?PpS4F3lth#=JtnO|nlyN7uF`b?>k z%$Heaw+*)z@s(X0CK+ZGeO)g7X>y~;8=;!rra&TiOOB3rF74-2(-Il2%#{-x+B4Ma z-2^+LZ8{-Fjvj*K4G*6Q^WArxDAQ~&ovxCU+mujn$F+S8T%abDwejYlskq`&2icfJ zW$Rq0Q!r|z>Q-)U(+2Ztic8KhE|%)NaAgfi)zYS}1K|KK;$R`@*&srvtJT{~PZ#?$ zj`6YF|4LmvD*MNwLg%1ye}k*peS_=Xc??;Y-%^moH2ux%F6Gmy?Awm>n(P)KJd|s( z9YV!skM6-87NEN{qKJFCbpu;fA-i{ODHx^wg96^rxf`3XbFg|44{JTt-7=Ia?B<6% zTz_3Rwo;Oxl0g?re02{;WUKpQcJSA0_AVB~Yml&=Ji3&@_Pf{SPt3v400t^H2)N$1 zC}?9SR6>#YptBx+-ty8$R1b07p(gr%&ZXAkY%kwDFwhd*@5EZy2<4zbV@=uwtbl8G{tv-x# z%q)v}6!$^{mnGaqJi=$|jM9xxecf{53p#j42pOdwtVohxQwF(`0obB8p7#KaAIT$C(Rt#w7m{da!+~K1!CzfvAap+#P zoi`AOCwFx}5l>~?9!q9+MM$vq%-emdkup}8PpTYY`To7RZ`%Xl^{yP)%#T=P*Jy;e zmK28TezVrw~U&djJ}>pxBgpgHu%!I7@TL3aY4TMe^L@?(^6G#cgbk_Gl`|j* zNsdT`l2)D`#spOqgavv%WE!lLOdK|P{N-ew8{WOj9JMZ#9~uB_dBfhp-vl*BlnMM2 zo2Ad{ERcKdZha3b=Gtu4(Sv(y;&ZmBq5|)+ih6-z+(x~6$buG|Nv?kpdtgfl1K@z{ zd)LqqVJwbpuanuVvn~>!|DrGOCo?$72SW9RY3_DYq1!k=^(0ygv;3wOLBSO!@tzAN-LN1G@cul>~wc&ri} zf3dko1+5@dA?HRUmLFsrx5ZrP390%Vm;Sb#55VBb6wD z-AzzkSvk5iD^c*^g+87~CApN|w04ySXU|TXdf?4OW44_P&Dp_oo(qkX6Cjq~=`laY z)R!@eMZeLg;7i8EQf=P5YnLrH`a4r=Cx}qxlX{rCv2~RW{=B`}<(^ z2TL>^xW7#3?h4mK%sQrjZ;Z(xq@7kE;F(qHs32m7g?+<>g!DQtlw3s2uu^pv)34gh zMrKw!|1#|mu#Ic%@Squ02w)^}eirtzP?Q_(dsDW!Jiu@nE?BqFYKhw_;MHXpakB(j zqfep2?j>}+L*`QmZ}iw%&L&si>SowhT??Qfd%Caj_YC875j3-?ePQ}c_LBs zC$+!wozvDY!G-~$?cI0j)P*zCcIgCZ?c%a*C<^lli$jlyi5 zu~;O(@QqLSmggL{0gwh-Wg2CuJ6#Loi}|Xo&Q8%{Aolj90!whprv(T7fCtJbg^^Cz z;xJ6iP+dd(LFn2Vo>ur(XrV2D8(N|Ld%A|GW;&v|S{afG^OoQg+xK((r|N;4s1%W1 zlPWoA9>E%t)g8*WAIKICPSx=3?=HL*jRuKEmG|Cu8mO`gRzS89(rXAt$41R{a=8_( ze0r92uK*hN*Zlg;8d(kF5Dha9`TP-I!!QD9Xx$kzXK?w{*7aCX(xG_`7JCyS3Gdxe z+rlHW_-S{ADs#&w;E#kf=txt9-Z8!sQ=Y{cC|=iELwisohed?#brOf(=%!b2%fa#! zE}YZvpLjOTHNfI3F9X{SwrLb!-SFNV^`U8_OEM=`^5*m#ZJu*Y&NxgkHmI8lJ;ccG zjNWZ=`~6dU{;Pwx@tls-16l_^(*|adpzxl$CVumLy*OK?ms1jZBCyt340LpB-xGV% z+i-9?mz>&m7d37ra~TXxy5Dz3sa-mcw8s8dFL>ap%s>>vVK=HT_FZ*)JALeS_b*Bv ze7{WD7UD6aRGu++ulwGX>w2jg;bm$ig1IW3DPemWC*RO6}>=$94KlF!x)Wj=?D4r!-M~?G725b#5|GdqI;F-o# z<|-N=mIFf5f*PZx$2k+=a%UeZ9%7R-elh*##lx0fGdr5!UpNQVA8&5u+#a$X3Yb%trRpYWNEiEZ6w}PoMjczRmzWC5}$+a~)0@R_X8fcr7+GCOl^@pbv2y%JYE_ z1+9M)FPLHsgv=956Q)Q^Lc?A$V0$Gm2~7uoJ^=yI*kPL4Vj792l<5Q@WDg{Pr_hQT zNv4~T#Tou-gS!2`)X9eeDf4k#uh+p8Q*Ccn_f>K-;;;wBac8 z<`bq^h7}d2ogd%_LjNfL_%)n0vVQZFc3ZpAoa22iRC=X8sXwiCFZ|y3`P5u_SmzKp zoH2xqR%Mz`s0Tlw;(sjz8+tBqMnnmua@-Lj=-)L~sEV z<~zMCnxY>)Gogl#KXHC}*I0#9LJE(!;kaujea#eS181%5JB8X6G-r7+U2_Row=5%dGSkhI6feVZ}0=u;>zvDhVPxe%1`8;r76T(^?_<(!!dHDP%0C*jPF55lV>vY4WuQ4Xf@q7lxn%gg z&-Ga`+m6lkUca91%tAPsd)#cnq(g6i_!X0ORF0DZ9r_J#i3U)cQ$n(k$InrP$*nPs zid8h%cc3e-P$q)N+R$$7>gCk2C&UG}sjAn2Pp|Q#y;CW;>2F=PXa1rqPl)TPj8=Pw zA=e{}{lvU>O#J4VciCQ-o+9DGm1}cyFtL(yW@BSRSh2D%?1089Nur85bsHYeV1W!* z46Q%iC_4C*5^&e~70#(=$cl|SFw{B%31*lZX5 zG+0m3obbq>2y_BV%V1+6qo^HpC8(mKy>rUzwt!@*ii)#5BK1O4@mzV>%Z0sNOr0Ih zP725Qh{6MeNtj5+p-&E|9y4e(G9N4x%eu7mD%b5j@N*~rhb@K%0+PI+to4Rf|DW+I z-2hAVC0ZFT4S~!R2yFy-9&a-DSE1?fj3KP;s(O$g@R_G1sq5@64MNPB(1d5KHDogK zCRTV4Y7O-IsIk<{e(q|9q7X19b!&Mn0ahkBJVxS~G#MzGpo!b#?j@OuR}6{49vJap z@Ciw9K(QN*rt(7MBi&Zl(LW zcToIe?^MqHkWW{Ez98~%cs1ENpO9sEl0M}ifhiqzs?+_J*cg1q>R8MhFk(CG!LJGm zB0N9fE6D{=`dR4pQ;7tXwG>r~3p$EeNK>MCfo+?ZjPBfcRlv<%xnH4{Lxzz?la_o3 zX5bQIW#=wY@CtgL!=f`khGBcOTqW7T&oc6`M6F(IAk_Ja@>}sXUnSl(g1ijfB4pV+ z+-LNM)>pN$9h|(`u3h$SVag%tsrqdJTxo9y!RGS5Rr9o6j4~!2+w{0bMXTUZ1PQQy zpd1Jx|H(ei?tiN-U9cPJJ19?Nf=*rc)l`jb>6jWj%pHlCVT{&m%6YQPJ{X zejC$usH#V5Yjtp)NTy0^*!tfF%E|_EB7^F2n-gz?gcv9!s)w<1#2iLUw1UH3fT+dk zpKvR&{5U;0>f?OAjnD>&C!BBaHyV>wYNpT&_|$Eng*zyY2y)B>ddZlk`2o4UE7;+S zzmatT_C)F?Je*Arl0bAzjrjsDK{^+qHbc6Ti;x_RHdQigRKjyjD6uHanqv6#x{}L4 zbq+rNg{E%SSI0oO)*^#o#o?q}Kv{V(C~|*b(k5po*(L5;6XDw~EI-KKMSc%vBu zNg`f!LFjqiC562vn=LBPlR>jj=Ig8J9v!rPiU603=pFnxLCnIzC&Z}wigKBd1F$QF zS4zr6)8$427xab#>8C&j)?p%j4jgJ4gOOxdM4S!RpF&bYHhf0f!5LMIz*cBI=8i`( zL_65UAxM)REkegkKdo*sH8gBr7;Z8r{uO1U;!tvDzd#_5DEzAm)z9uW`0SjWX7`u1 z_@Y7@UAR1J&?<%x&K670K84-V=N+9yoW9NODKm$Vnt3(&HN*xFdO7uEe z{uRuNawUNwG=+lnRKMFdfW?!|RfolvoBhqaH0|spsQu)GCJUicVHNAuvyqQ*uz@-- zC9*4NrM&jw`fUBDY_7{*17$|z6etl!63!|Y{SU{HWcKZqu7msX@@M((c#)nj3HQMf z5KQmoTZQL1s{txxkQ{R-GM@Dr2t)S-iD*Y4u4F_ehQpu&IVOEK01;YrR~|yTP_hAg zr>LXU6NU|(pTTjMzn0jM6j*b|7sX_BM>v&6s@bP;g28z^kE~U>#xO#8h<Uno#cY}saL4rajr#OBKss>;gHK#U`XE8}OpOk@@E5WNXFepAi--qdQ)nh> zAzH7=7pmzd8y7?ES=##{%$487WxB!ZTg^94a&}`xuh~YJ86Q+F-rDnONYC3= z!7Evrny5DJt)c>7M^NVVje-7{D>rH=HPVeQ`6QL0ZEtM^dTdD(kL2Id^=~437|ryy z%r`HnJ7+=XXZDT}CK%qfIgnj|w(H{uJ;uwpES{x7CE68u(Vz z$f~{q@)^c~({v^$PBs~xGw;G6-L!(A^^-qnnd&{Ccf+Q`ZRU4skM3-Pc|AtYx(-eV zuMvHZ_PEmT;iq}ic<6uIKbvSJ@dHr?0Yee|E{QTo=Wu*En(gMnjDOR6&t+~ysd zWjlGt>gJZueE$dH)z4b^~UY|}| zfmnn>PyF)!jbQ)ea3bz>MYa^Naqb<&0w!XGfDr7XJ`aLGv^8q}oEptdb{Zs8z5`Dz zR{p#!R0?*Zv7Lcl0!x{AKGgAR=)@cu&;U_aK|H{<)@8s&>uJ5xlBXfsT%$PF*+%bg zNNfLdZHQ1tfQ?|vZhQr>3dCtkd}vZf!_DxbL{R>k1s)fzhdw*wj=OP3a-paxj@MUD z%Hw4qKIDWnebe#PY~|yeL9de`rFxGBX%e9jyn%$9Yj){7{K@m%VxY6o2~j09Fcp0_ z5h2J)C};M5GF{jZ%lgwy%=4o!HrnoWE?4RwmcJYqa6&I_e9~M$5hs_n$i%n)$~j@<-Kh+oGK$9r1j~FpXsE z(?&CTTvqLi=n;wu3ubX=88G8qfe*dU<=rf25ZxlknDvaVJnq&K+#>D+8}AD_aSawH z8pzAI32u9DlHg6}=(dC}ewUjMWg(AjRc=urp7OS@iw;bR88|i^YB4zMLmI`CF+*%| zjKAtldY0$gMP@mwfz%+id~@$JnmDFN`~A)STNEw<;Z$uR!*}~t9st`5FY!lA0AbPO zIhn}UAA>a!nWC$dmNQCEXbR{>Ti`f}U_k)bisjR#7DI3#b|sGEO&)^?kpb*{$v z=yf`GVJlr?ADWvTkwnj?*%7k{1x+BN4I0AYy{w6bJ|9wO8>Y1GV{y+gpY90I+?Ysx zjd+~LD(uTjRQjf-Z~?#@rfFmzx`cXx@VH!+ye_SbyOLIy{CW$6^S3x>uv9$SfTRt8 zJ20u9G{(2Mv!iihFQrh&7lo1;Rxk;vVOokZEJ#XluJ+Y=^IR7%Ee5x+=(9#s5GL|` z5`mtfHDt$tWnr4M?<*vH6i{TMNVt|hq6v8iB?;gP<#xAYDr2OWoAsama5mlaTk18R z{rp_xena}laYwM081{t&0r@KSza003&L6lyqLf_*1A5ToJ4UE6+~8pxP6V+cmX681 zWTyB=6n9g93nU&6TG40Mp+O&+5|z~C`z6oN690#LDb3ZdGu3ace+;mn36qr>iN`WO zy`M0x--dRjs&sWB4pOLA7qruI4ujpBRGQqWFWzLOD#ZVKWD*lv*56bSlB*!AEx2(3 znbAVj+o?%Dyg7Z4moB7NcI7q*`}U21+EaN^tf~`d7R5*~-J9NANQR$1wL*PU!MMvV zWQFsF%-c%GGl(JzU`1wP$!WExi=ec4;OVj0s2#AIThE)`Zwq~KdMy`-jN#t!qy-EC z%AgAw*o6_DIc9w{c5;seEZRrg6s#;jjGU{tex`>%NeZL_ZqB(Mkt`uYfB~l2F|i;{ z#*wz$e&lYmD)!1H`1&qcp98urYD&?Au>~SN>-8s68@22Wdws46PK|6#(eD_c_=~xx zBm6_5_qM2yLJT{&pPM`NyuIYf+A&#jy9LjW4!uMO3g&FSpJc{v93QL3L$o)5YESLV zDO>U2rZ&L_a3TB~%47bke)^u5$JH?G#~ z$Zh#53>|LaC7lx8eyz6GkHQQilLGW+ZojJcE>Bzzg#N^6WypF!M?v>9f3c8d!4_&h zM)TA@6?J{Cil<)TFKV?F#|*Shsqu#yzA%bfa%0P=KTrR)?dYJEikHA#ws7G1Z0qrX zxKN?l-r8E)R=%bsl&HkZHLv3OXr&hVv^&fjOE<_-o}HnW!nJ&@=D+6@St`8c# zzD%q|1)lFE;)U8+%d+aN6>g{uo9w0b-;!JY@|k*n8)s|lF7%6HEVZsqaS>F57}Y5B zaMkj$+O@CuNx}WZOf(vBv|!wsCw7{NIv zKtdA+l~zp?Ews;w$+D)=wglXJpl>VWQm3KP`Jyx&M@=ATLN~uy0sgIK(72X9>cd_$ zlZuTB>tEIu9p9gn4;OVW>U

    IySgV=Bui{PsOm5KMV6en>(0F4K>wsjzYo+)cEQQ zyW&OlvSaxt58-@9W5kjFTD z!dmrfil(!|@A1eR#wf~d!`+huQGGLzVG#|`S0h%OSO?EcoMggtpkP{9C&0lr3X_4b zV6-+y<^#=yJTw)V@a=7zBOSo2_WGR^eKF>?`1cf&2={in0HFT53d!vZ`NIf1tW+#g zXV=I5nVOQBfi5GRj^F#q0RyvwMdw<@3@=t1lAee0VmWvOD+&tT0~FXDfcrvs$VodR zBu{Md-BK($nOEOmFc#|xo6>Xxl$aKM3~3ph=@09izS&LEHj{;$T>)6j=%O zmtiTn#}$ZycfgcsRLu%ZMVuI3(TH@T_zUI7E)mH^ed>cLDu#3GY>}L<7c;E*Tmr9- zuMCN4&uBK|Kv+&UkAH{EuGvl;h(+1Z0T#$t*hvLG*b+N@bL#i#s$w+o<-a$Y4|+(O;upyVw^SJAlkT;n6J0 z?V|xxXly=*KW!~k+G4OmGpOCr8$pG~AcCooOy(Qu%6{RFn|FFc;eIC^hRRn(AkrDf6dq8-Z!jBm!%;%k8Wva5<%EkI@&?0JX z-J3=TghNCz<~`RGcw#rSW5C(BO$yu`ni!Lg*TLMRhHv56@w&XSR&avRE8@aeZ`Z;! zf#w#i&rM$3{s|H_++r(f5xwlKsG-o_^<9u)T-J%wc@# zJz((qmeNsHp=;1r<5vvKz1$_$-Z%f*k`BYhqphvIRAn1|PHalY z&$r7XtwHTgwkm6#YB|EUQAV&rc|M7)VyDlr!g_yO?;R6k{vqACGuK#2`aUr6=0B1c z*0iDdfXsB{2vLAXi>fvFt=)s)bN#a735ZSRV-t!WV@#MKEImKH5YJr~!;A_YkPl}Q z|4w5{khHu9EA;^(!V~MN`#uGxdj1o2elve$i%h`Fc5e22!jvi&FIAgL9IJEM9d_{O zd#>R9gdAwO2VcDP2lzjRMy7|ui{uLkh$+>-?aY5?t^b#uNjT3s=ESoRG|o2=(u~iC?*u|Apt|B2IwjM*ctioLnsb2ahZWpODQ3{jYi%7wf;< z)+_RGgZ_i8kK?ud7mxtP&-B02<`abY*@^zir2o&$j{lgz|6B4g6Vmx{HU44x&w%J( z_v$~&?cXGPBRgAX6IS~jI>>(yL*hRjGT8rU1_E+Goq#BSt@@Aje;eq3 z?DO9=|NkiItRNsZCe8-`FVX+0?f=>FKK2A}0o;G7C0hs&jF2zkhMOp1T?qDHD2=}; zb-n}|9(;uV>g&I!;vYgZUqU6(8V--k{ c7XGjCS^TZK2qxt4VkKk>BY)W!`bT;HAH#>j{Qv*} literal 17587 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 diff --git a/rtl/fpga_bitmap.o b/rtl/fpga_bitmap.o index 20717dbc1764963cae1f46b851dcfb1421ed6d8c..d9597043aa589c569dc46a9d7f23809272dd6126 100644 GIT binary patch literal 32724 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 literal 32724 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 U*x>JDy7OxV-O0dZAj9wf00IIE^#A|> diff --git a/src/firmware/config.c b/src/firmware/config.c index 7ab2001b..686698f4 100755 --- a/src/firmware/config.c +++ b/src/firmware/config.c @@ -37,7 +37,7 @@ #include -static const uint16_t FIRMWARE_VERSION = 0x060B; +static const uint16_t FIRMWARE_VERSION = 0x060C; // 1 flash row static const uint8_t DEFAULT_CONFIG[128] = diff --git a/src/firmware/disk.c b/src/firmware/disk.c index 7d6d4757..b3e612fe 100755 --- a/src/firmware/disk.c +++ b/src/firmware/disk.c @@ -669,10 +669,12 @@ void scsiDiskPoll() // int scsiActive = 0; // int sdActive = 0; + int parityError = 0; while ((i < totalSDSectors) && (likely(scsiDev.phase == DATA_OUT) || // scsiDisconnect keeps our phase. scsiComplete) && - likely(!scsiDev.resetFlag)) + likely(!scsiDev.resetFlag) && + likely(!parityError)) { // Well, until we have some proper non-blocking SD code, we must // do this in a half-duplex fashion. We need to write as much as @@ -681,8 +683,11 @@ void scsiDiskPoll() uint32_t rem = totalSDSectors - i; uint32_t sectors = rem < maxSectors ? rem : maxSectors; - scsiRead(&scsiDev.data[0], sectors * SD_SECTOR_SIZE); - sdTmpWrite(&scsiDev.data[0], i + sdLBA, sectors); + scsiRead(&scsiDev.data[0], sectors * SD_SECTOR_SIZE, &parityError); + if (!parityError) + { + sdTmpWrite(&scsiDev.data[0], i + sdLBA, sectors); + } i += sectors; #if 0 // Wait for the next DMA interrupt. It's beneficial to halt the @@ -825,9 +830,8 @@ void scsiDiskPoll() if (scsiDev.phase == DATA_OUT) { - if (scsiDev.parityError && - (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) && - (scsiDev.compatMode >= COMPAT_SCSI2)) + if (parityError && + (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY)) { scsiDev.target->sense.code = ABORTED_COMMAND; scsiDev.target->sense.asc = SCSI_PARITY_ERROR; diff --git a/src/firmware/scsi.c b/src/firmware/scsi.c index 176a0a7c..914c0774 100755 --- a/src/firmware/scsi.c +++ b/src/firmware/scsi.c @@ -97,7 +97,6 @@ void process_MessageIn() { // Go back to the command phase and start again. scsiDev.phase = COMMAND; - scsiDev.parityError = 0; scsiDev.dataPtr = 0; scsiDev.savedDataPtr = 0; scsiDev.dataLen = 0; @@ -201,18 +200,17 @@ static void process_DataOut() scsiDev.dataLen = sizeof(scsiDev.data); } - scsiDev.parityError = 0; len = scsiDev.dataLen - scsiDev.dataPtr; if (len > 0) { scsiEnterPhase(DATA_OUT); - scsiRead(scsiDev.data + scsiDev.dataPtr, len); + int parityError = 0; + scsiRead(scsiDev.data + scsiDev.dataPtr, len, &parityError); scsiDev.dataPtr += len; - if (scsiDev.parityError && - (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) && - (scsiDev.compatMode >= COMPAT_SCSI2)) + if (parityError && + (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY)) { scsiDev.target->sense.code = ABORTED_COMMAND; scsiDev.target->sense.asc = SCSI_PARITY_ERROR; @@ -242,16 +240,22 @@ static void process_Command() uint8_t control; scsiEnterPhase(COMMAND); - scsiDev.parityError = 0; memset(scsiDev.cdb + 6, 0, sizeof(scsiDev.cdb) - 6); - scsiRead(scsiDev.cdb, 6); + int parityError = 0; + scsiRead(scsiDev.cdb, 6, &parityError); group = scsiDev.cdb[0] >> 5; scsiDev.cdbLen = CmdGroupBytes[group]; - if (scsiDev.cdbLen - 6 > 0) + if (parityError && + (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY)) { - scsiRead(scsiDev.cdb + 6, scsiDev.cdbLen - 6); + // Don't try and read more bytes, as we cannot be sure what group + // the command should be. + } + else if (scsiDev.cdbLen - 6 > 0) + { + scsiRead(scsiDev.cdb + 6, scsiDev.cdbLen - 6, &parityError); } command = scsiDev.cdb[0]; @@ -274,9 +278,8 @@ static void process_Command() memset(scsiDev.cdb, 0xff, sizeof(scsiDev.cdb)); return; } - else if (scsiDev.parityError && - (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) && - (scsiDev.compatMode >= COMPAT_SCSI2)) + else if (parityError && + (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY)) { scsiDev.target->sense.code = ABORTED_COMMAND; scsiDev.target->sense.asc = SCSI_PARITY_ERROR; @@ -461,7 +464,6 @@ static void scsiReset() scsiPhyReset(); - scsiDev.parityError = 0; scsiDev.phase = BUS_FREE; scsiDev.atnFlag = 0; scsiDev.resetFlag = 0; @@ -507,7 +509,6 @@ static void enter_SelectionPhase() // Ignore stale versions of this flag, but ensure we know the // current value if the flag is still set. scsiDev.atnFlag = 0; - scsiDev.parityError = 0; scsiDev.dataPtr = 0; scsiDev.savedDataPtr = 0; scsiDev.dataLen = 0; @@ -559,7 +560,6 @@ static void process_SelectionPhase() } } if ((target != NULL) && (selStatus & 0x40)) -// TODO (goodParity || !(scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) || !atnFlag) { // We've been selected! // Assert BSY - Selection success! @@ -591,7 +591,7 @@ static void process_SelectionPhase() { scsiDev.compatMode = COMPAT_SCSI1; } - else if (scsiDev.compatMode == COMPAT_UNKNOWN) + else { scsiDev.compatMode = COMPAT_SCSI2; } @@ -622,13 +622,11 @@ static void process_MessageOut() scsiEnterPhase(MESSAGE_OUT); scsiDev.atnFlag = 0; - scsiDev.parityError = 0; scsiDev.msgOut = scsiReadByte(); scsiDev.msgCount++; - if (scsiDev.parityError && - (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) && - (scsiDev.compatMode >= COMPAT_SCSI2)) + if (scsiParityError() && + (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY)) { // Skip the remaining message bytes, and then start the MESSAGE_OUT // phase again from the start. The initiator will re-send the @@ -640,7 +638,6 @@ static void process_MessageOut() // Go-back and try the message again. scsiDev.atnFlag = 1; - scsiDev.parityError = 0; } else if (scsiDev.msgOut == 0x00) { diff --git a/src/firmware/scsiPhy.c b/src/firmware/scsiPhy.c index ca3b494a..68317598 100755 --- a/src/firmware/scsiPhy.c +++ b/src/firmware/scsiPhy.c @@ -28,18 +28,13 @@ #include -// Slowest timing. Aim for 1.5MB/s, but it's likely to be faster. -// Assumes a 96MHz fpga clock. -#define SCSI_SCSI1_DESKEW 0x7 -#define SCSI_SCSI1_TIMING ((0x7 << 4) | 0xF) - // 5MB/s sync and async. // Assumes a 96MHz fpga clock. // 2:0 Deskew count, 55ns // 6:4 Hold count, 53ns // 3:0 Assertion count, 80ns -#define SCSI_SCSI2_DESKEW 0x6 -#define SCSI_SCSI2_TIMING ((0x5 << 4) | 0x8) +#define SCSI_DEFAULT_DESKEW 0x6 +#define SCSI_DEFAULT_TIMING ((0x5 << 4) | 0x8) // 10MB/s // 2:0 Deskew count, 25ns @@ -161,7 +156,6 @@ scsiReadPIO(uint8_t* data, uint32_t count) { fifoData[i] = scsiPhyRx(); // TODO ASSUMES LITTLE ENDIAN } - // TODO scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read(); } void @@ -205,9 +199,10 @@ scsiReadDMAPoll() } void -scsiRead(uint8_t* data, uint32_t count) +scsiRead(uint8_t* data, uint32_t count, int* parityError) { int i = 0; + *parityError = 0; uint32_t chunk = ((count - i) > SCSI_FIFO_DEPTH) @@ -224,6 +219,7 @@ scsiRead(uint8_t* data, uint32_t count) while (i < count && likely(!scsiDev.resetFlag)) { while (!scsiPhyComplete() && likely(!scsiDev.resetFlag)) {} + *parityError |= scsiParityError(); scsiPhyFifoFlip(); uint32_t nextChunk = ((count - i - chunk) > SCSI_FIFO_DEPTH) @@ -456,22 +452,17 @@ void scsiEnterPhase(int phase) *SCSI_CTRL_TIMING = SCSI_FAST10_TIMING; } else { // 5MB/s Timing - *SCSI_CTRL_DESKEW = SCSI_SCSI2_DESKEW; - *SCSI_CTRL_TIMING = SCSI_SCSI2_TIMING; + *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW; + *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING; } *SCSI_CTRL_SYNC_OFFSET = scsiDev.target->syncOffset; } else { *SCSI_CTRL_SYNC_OFFSET = 0; - if (scsiDev.compatMode >= COMPAT_SCSI2) { - // 5MB/s Timing - *SCSI_CTRL_DESKEW = SCSI_SCSI2_DESKEW; - *SCSI_CTRL_TIMING = SCSI_SCSI2_TIMING; - } else { - *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW; - *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING; - } + // 5MB/s Timing + *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW; + *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING; } *SCSI_CTRL_PHASE = newPhase; @@ -506,8 +497,8 @@ void scsiPhyReset() *SCSI_CTRL_DBX = 0; *SCSI_CTRL_SYNC_OFFSET = 0; - *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW; - *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING; + *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW; + *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING; // DMA Benchmark code // Currently 11MB/s. @@ -601,6 +592,14 @@ void scsiPhyReset() } #endif + //#ifdef SCSI_FREQ_TEST + while(1) + { + *SCSI_CTRL_DBX = 0xAA; + *SCSI_CTRL_DBX = 0x55; + } + //#endif + } static void scsiPhyInitDMA() @@ -673,8 +672,8 @@ void scsiPhyInit() *SCSI_CTRL_DBX = 0; *SCSI_CTRL_SYNC_OFFSET = 0; - *SCSI_CTRL_DESKEW = SCSI_SCSI1_DESKEW; - *SCSI_CTRL_TIMING = SCSI_SCSI1_TIMING; + *SCSI_CTRL_DESKEW = SCSI_DEFAULT_DESKEW; + *SCSI_CTRL_TIMING = SCSI_DEFAULT_TIMING; } @@ -702,7 +701,10 @@ void scsiPhyConfig() *SCSI_CTRL_IDMASK = idMask; *SCSI_CTRL_FLAGS = - (scsiDev.boardCfg.flags & S2S_CFG_DISABLE_GLITCH) ? 1 : 0; + ((scsiDev.boardCfg.flags & S2S_CFG_DISABLE_GLITCH) ? + SCSI_CTRL_FLAGS_DISABLE_GLITCH : 0) | + ((scsiDev.boardCfg.flags & S2S_CFG_ENABLE_PARITY) ? + SCSI_CTRL_FLAGS_ENABLE_PARITY : 0); } diff --git a/src/firmware/scsiPhy.h b/src/firmware/scsiPhy.h index 7f52280c..1df96b95 100755 --- a/src/firmware/scsiPhy.h +++ b/src/firmware/scsiPhy.h @@ -29,6 +29,8 @@ #define SCSI_CTRL_DESKEW ((volatile uint8_t*)0x60000012) #define SCSI_CTRL_TIMING ((volatile uint8_t*)0x60000014) #define SCSI_CTRL_FLAGS ((volatile uint8_t*)0x60000016) +#define SCSI_CTRL_FLAGS_DISABLE_GLITCH 0x1 +#define SCSI_CTRL_FLAGS_ENABLE_PARITY 0x2 #define SCSI_STS_FIFO ((volatile uint8_t*)0x60000020) #define SCSI_STS_ALTFIFO ((volatile uint8_t*)0x60000022) @@ -36,6 +38,7 @@ #define SCSI_STS_SELECTED ((volatile uint8_t*)0x60000026) #define SCSI_STS_SCSI ((volatile uint8_t*)0x60000028) #define SCSI_STS_DBX ((volatile uint8_t*)0x6000002A) +#define SCSI_STS_PARITY_ERR ((volatile uint8_t*)0x6000002C) #define SCSI_FIFO_DATA ((volatile uint16_t*)0x60000040) #define SCSI_FIFO_DEPTH 512 @@ -61,6 +64,8 @@ #define scsiStatusSEL() ((*SCSI_STS_SCSI & 0x08) == 0x08) #define scsiStatusACK() ((*SCSI_STS_SCSI & 0x10) == 0x10) +#define scsiParityError() ((*SCSI_STS_PARITY_ERR & 0x1) == 0x1) + // Disable DMA due to errate with the STM32F205 DMA2 controller when // concurrently transferring FSMC (with FIFO) and APB (ie. sdio) // peripherals. @@ -78,7 +83,7 @@ void scsiEnterBusFree(void); void scsiSetDataCount(uint32_t count); void scsiWrite(const uint8_t* data, uint32_t count); -void scsiRead(uint8_t* data, uint32_t count); +void scsiRead(uint8_t* data, uint32_t count, int* parityError); void scsiWriteByte(uint8_t value); uint8_t scsiReadByte(void); diff --git a/src/firmware/sd.c b/src/firmware/sd.c index 204936db..71ec535c 100755 --- a/src/firmware/sd.c +++ b/src/firmware/sd.c @@ -278,7 +278,6 @@ void sdTmpWrite(uint8_t* data, uint32_t lba, int sectors) static void sdClear() { sdDev.version = 0; - sdDev.ccs = 0; sdDev.capacity = 0; memset(sdDev.csd, 0, sizeof(sdDev.csd)); memset(sdDev.cid, 0, sizeof(sdDev.cid)); diff --git a/src/firmware/sd.h b/src/firmware/sd.h index 74f89a6a..0a9d6328 100755 --- a/src/firmware/sd.h +++ b/src/firmware/sd.h @@ -24,7 +24,6 @@ typedef struct { int version; // SDHC = version 2. - int ccs; // Card Capacity Status. 1 = SDHC or SDXC uint32_t capacity; // in 512 byte blocks uint8_t csd[16]; // Unparsed CSD -- 2.38.5