📄 inand.lst
字号:
752 1 AUTOPTR1H = MSB(tmp); AUTOPTR1L = LSB(tmp);
753 1 do
754 1 {
755 2 if (!(P_XAUTODAT1 & MSB(cBLK_uMSK)))
756 2 {
757 3 bFreeFound = 1; // Mark found a free erased block
758 3 return;
759 3 }
760 2 P_XAUTODAT1;
761 2 gFreeBlk++; // Search Next block
762 2 if (gFreeBlk & cMaxBlock)
763 2 gFreeBlk = 0, AUTOPTR1H = MSB(gLog2Phy), AUTOPTR1L = LSB(gLog2Phy);
764 2 } while (--i); // 1-256 search entries
765 1 }
766
767 //==========================================================================
768 // Write NAND Pages: support both interleave and non-interleave code
769 // Use gFreeBlk as the back ground searching free erased block
770 //==========================================================================
771 void nWritePages()
772 {
773 1 #ifdef NAND_2K
774 1 BYTE xdata wcmd;
775 1 bit prog;
776 1 if (gPartialCpy==0) Log2Phy();
777 1 // Need to queue up more buffers to avoid hang up on the Write transfer
778 1 // for 512-byte just wait for empty
779 1 if ((gSectorcount>1) || !EZUSB_HIGHSPEED())
780 1 while (!(P_EP2CS & bmEPFULL)); // wait for host send all data
781 1 else
782 1 while ((P_EP2CS & bmEPEMPTY)); // Wait for host to send data
783 1 ARM_EP2();
784 1 P_EP2FIFOCFG = bmAUTOOUT | bmOEP; // set auto mode
785 1 NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3));
786 1 do
787 1 {
788 2 P_GPIFTCB1 = MSB(cNAND_DSIZE);
789 2 P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE);
790 2 GPIFTRIG = cEP2;
791 2 //-----------------------------------------------------
792 2 // PreProcess calculation while waiting transfer done
793 2 //-----------------------------------------------------
794 2 bCnt = --gSectorcount;
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 14
795 2 dwLBA++; // next sector
796 2 prog = (xLBA3 & 3)==0;
797 2 wcmd = cNAND_PROGRAM_CACHE;
798 2 bReload = (xLBA3 == 0);
799 2 if (bReload || !bCnt) wcmd = cNAND_PROGRAM_PAGE;
800 2 bReload &= bCnt;
801 2
802 2 if (prog) { xPhyAdd++; xSrcAdd++; } // next address
803 2 prog |= !bCnt;
804 2 while (!gpifIdle());
805 2 WriteRedundant();
806 2 if (prog)
807 2 {
808 3 nand_send_command(wcmd);
809 3 if (bReload) { nEraseBlock(); Log2Phy(); }
810 3 if (bCnt) n2k_set_wadd();
811 3 }
812 2 } while (bCnt);
813 1 gPartialCpy = xLBA3;
814 1 // partial block must leave the nand chip select asserted
815 1 if (gPartialCpy)
816 1 gPartialCpy = 0-gPartialCpy;
817 1 else
818 1 {
819 2 nEraseBlock();
820 2 DISABLE_NAND();
821 2 }
822 1 P_EP2FIFOCFG = 0;
823 1 #else
if (gPartialCpy==0) Log2Phy();
// Need to queue up more buffers to avoid hang up on the Write transfer
// for 512-byte just wait for empty
if ((gSectorcount>1) || !EZUSB_HIGHSPEED())
while (!(P_EP2CS & bmEPFULL)); // wait for host send all data
else
while ((P_EP2CS & bmEPEMPTY)); // Wait for host to send data
ARM_EP2();
P_EP2FIFOCFG = bmAUTOOUT | bmOEP; // set auto mode
do
{
P_GPIFTCB1 = MSB(cNAND_DSIZE);
P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE);
if (bInterLeave)
{
#ifdef USE_2NAND
if (bLBA0) { CE1_ON(), CE0_OFF(); nand_ready1(); } // bank1
else { CE0_ON(), CE1_OFF(); nand_ready0(); } // bank0
#else
if (bLBA0) { IOD=gEnableBank1; nand_ready1(); } // bank1
else { IOD=gEnableBank0; nand_ready0(); } // bank0
#endif
}
else nand_ready3();
n512_setadd(cNAND_WRITE_DATA,gPhyAdd); // send program pages
GPIFTRIG = cEP2;
//-----------------------------------------------------
// PreProcess calculation while waiting transfer done
//-----------------------------------------------------
bCnt = --gSectorcount;
dwLBA++; // next sector
if (bInterLeave)
gPartialCpy = xLBA3 & cInterLeaveMsk;
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 15
else
gPartialCpy = xLBA3 & (c512PageSize-1);
if (!bLBA0 || bInterLeave==0) { xPhyAdd++; xSrcAdd++; } // next address
bReload = bCnt && gPartialCpy==0;
while (!gpifIdle());
WriteRedundant();
nand_send_command(cNAND_PROGRAM_PAGE);
// nSearchFreeBlock(64);
if (bReload) { nEraseBlock(); Log2Phy(); }
} while (bCnt);
// partial block must leave the nand chip select asserted
if (gPartialCpy)
{
if (bInterLeave) gPartialCpy = 64-gPartialCpy;
else gPartialCpy = c512PageSize-gPartialCpy;
}
else
{
nEraseBlock();
DISABLE_NAND();
}
P_EP2FIFOCFG = 0;
#endif
882 1 }
883
884 //==========================================================================
885 // Redundant mappping for Configuration block
886 // 0-9: 0xff, 01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
887 // a-f: ecc1b0, ecc1b1, ecc1b2, ecc2b0, ecc2b1, ecc2b2
888 // Redundant mappping for data block
889 // 0-7: 0xff, 0xff, ecc1b0, ecc1b1, ecc1b2, ecc2b0, ecc2b1, ecc2b2
890 // 8-b: add1, add2
891 // c-f: ignore
892 // set b2BitErr when more than 2 bit ECC error
893 //==========================================================================
894 bit CorrectData()
895 {
896 1 BYTE xdata a,b,c,x,i;
897 1
898 1 for (i=0; i<2; i++)
899 1 {
900 2 b = ecc0[0] ^ ecc1[0];
901 2 a = ecc0[1] ^ ecc1[1];
902 2 c = ecc0[2] ^ ecc1[2];
903 2 if (a|b|c)
904 2 {
905 3 if ((((a^(a>>1)) & 0x55) == 0x55) && // Does each pair of parity bits contain
906 3 (((b^(b>>1)) & 0x55) == 0x55) && // one error and one match?
907 3 (((c^(c>>1)) & 0x54) == 0x54))
908 3 {
909 4 x = (a & 0x80); // If so, there's a one-bit error in data[].
910 4 if (a & 0x20) x |= 0x40; // Find which byte is in error...
911 4 if (a & 0x08) x |= 0x20;
912 4 if (a & 0x02) x |= 0x10;
913 4 if (b & 0x80) x |= 0x08;
914 4 if (b & 0x20) x |= 0x04;
915 4 if (b & 0x08) x |= 0x02;
916 4 if (b & 0x02) x |= 0x01;
917 4 a = 0; // ... and which bit...
918 4 if (c & 0x80) a |= 0x04;
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 16
919 4 if (c & 0x20) a |= 0x02;
920 4 if (c & 0x08) a |= 0x01;
921 4 EP6FIFOBUF[x+ (WORD)(i<<8)] ^= (1 << a); // ... and correct it.
922 4 // one bit is ok
923 4 }
924 3 else { b2BitErr=1; return cFail; } // two bits return error
925 3 }
926 2 ecc0[0] = ecc0[3];
927 2 ecc0[1] = ecc0[4];
928 2 ecc0[2] = ecc0[5];
929 2 ecc1[0] = ecc1[3];
930 2 ecc1[1] = ecc1[4];
931 2 ecc1[2] = ecc1[5];
932 2 }
933 1 return cOK;
934 1 }
935
936 #ifdef NAND_2K
937 //==========================================================================
938 // Internal Move:
939 // Partial page will use nCopyPages, the full 2K page will use
940 // internal move
941 //==========================================================================
942 void nNandMove(BYTE cnt, BYTE cc)
943 {
944 1 BYTE xdata z, msk = cc&3;
945 1
946 1 if (!bInternalMove) {nCopyPages(cnt,cc); return; }
947 1
948 1 if (msk) { z = 4-msk; nCopyPages(z, msk); cnt -= z; }
949 1 msk = cnt/4;
950 1
951 1 // if the src is blank, need to have valid page
952 1 if (cc==0 && msk && bFreeBlk)
953 1 {
954 2 nCopyPages(4, 0); // ONLY need to copy 1st page
955 2 cnt -= 4;
956 2 msk--;
957 2 }
958 1 for (z=0; z<msk; z++)
959 1 {
960 2 nand_ready3();
961 2 NAND_CLE=1,P_XGPIFSGLDATLX=0, NAND_CLE=0;
962 2 NAND_ALE = 1;
963 2 P_XGPIFSGLDATLX = 0; cnt -= 4; P_XGPIFSGLDATLX = 0;
964 2 P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[3];
965 2 P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[2];
966 2 P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[1];
967 2 NAND_ALE = 0;
968 2 NAND_CLE=1, P_XGPIFSGLDATLX=0x35, NAND_CLE=0;
969 2
970 2 nand_ready3(); // wait for tr
971 2 NAND_CLE=1,P_XGPIFSGLDATLX=0x85, NAND_CLE=0;
972 2 NAND_ALE = 1;
973 2 P_XGPIFSGLDATLX = 0; xSrcAdd++; P_XGPIFSGLDATLX = 0;
974 2 P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[3];
975 2 P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[2];
976 2 P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[1];
977 2 NAND_ALE = 0;
978 2 NAND_CLE=1, P_XGPIFSGLDATLX=0x10, NAND_CLE=0;
979 2 xPhyAdd++;
980 2 }
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 17
981 1 if (cnt) nCopyPages(cnt, 0);
982 1 }
983 #endif
984
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 2827 ----
CONSTANT SIZE = 20 ----
XDATA SIZE = 2054 18
PDATA SIZE = ---- ----
DATA SIZE = 32 11
IDATA SIZE = ---- ----
BIT SIZE = ---- 1
EDATA SIZE = ---- ----
HDATA SIZE = ---- ----
XDATA CONST SIZE = ---- ----
FAR CONST SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -