📄 mal_2k.c
字号:
return;
}
else{
malPaddr = (malPaddr & ~(0x3fff));
DTC_SMC_Mark_Bad();
SMC_Lookup_Map_Bad();
if (SMC_Wstate & SMC_OLD_CLUSTER) {
SMC_Lookup_pTable[1000] = SMC_Paddr | 0x10;
}
else {
SMC_Lookup_pTable[SMC_Laddr] = SMC_Paddr | 0x10;
}
DTC_Error = 0;
SMC_Write();
return;
}
}
}
#endif
if (SMC_Wstate & SMC_WRITE_FLAG) {
if (SMC_Cluster_Size != 64) {
if(DTC_Error)
SMC_Npage -= malNpage;
_MAL_INC_Block_Param(SMC_Npage);
}
else {
if (DTC_Error) //for 2K page Bad Block
SMC_Npage512 -= malNpage;//No. of 512 byte pages decremented
_MAL_INC_Block_Param(SMC_Npage512);
}
}
DTC_Current_Func = DTC_SMC_WRITE;
switch (SMC_Wstate) {
case SMC_PREMARK: // 0
case SMC_PRECOPY: // 1
case SMC_PREHOLEMARK: // 8 Never use
case SMC_PREHOLECOPY: // 9 Never use
malNpage = SMC_Cluster_Size - SMC_Npage;
if (SMC_Cluster_Size != 64){
if (malNpage > MAL_Block_Numbers) {
malNpage = (unsigned char)MAL_Block_Numbers;
SMC_Wstate |= SMC_HOLE_ACTION;
}
SMC_Npage = malNpage; //counter for no. of pages to be written
}
else {
malNpage = ((malNpage * 4) - SubBlock);
if (malNpage > MAL_Block_Numbers) {
malNpage = (unsigned char)MAL_Block_Numbers;
SMC_Wstate |= SMC_HOLE_ACTION;
// SMC_Npage = malNPage;
}
SMC_Npage512 = malNpage; //for decrement of MAL_Block_Numbers, counter for 512 byte page
SMC_Npage = (SubBlock + malNpage)/4; //counter for no. of 2K pages
if (SMC_Npage == 0 && SubBlock)
SMC_Npage = 1;
}
Test_page = Test_page - malNpage;
// Launch DTC to write several pages;
SMC_Wstate |= SMC_WRITE_FLAG;
_MAL_BufMgr_Download();
DTC_SMC_Write_USB(0);
// Now SMC_Wstate = SMC_PRENEWWRITE or SMC_PREOLDWRITE or
// SMC_Wstate = SMC_HOLENEWWRITE or SMC_HOLEOLDWRITE
// SMC_Wstate = 2 : 3 : A : B
return;
case SMC_POSTNEWWRITE: // 6
case SMC_POSTOLDWRITE: // 7
// All data from USB has been written. MAL_Block_Numbers must be 0
malNpage = (unsigned char)(SMC_Cluster_Size - SMC_Npage);
SMC_Ppage = SMC_Npage;
SMC_Wstate &= ~SMC_WRITE_FLAG; // Clear WRITE flag
Post_Mark_Copy:
if(SMC_Cluster_Size == 64){
Col = ((Buffer_Param[0x24] + 0x02) & 0x06); //get the number of coloumns after write operation
// malNpage = malNpage - 1;
if (Col == 0x02) //set the 1st adr byte for src and destination
SubBlock = 3;
else if (Col == 0x04)
SubBlock = 2;
else if (Col == 0x06)
SubBlock = 1;
else {
SubBlock = 0;
// malNpage = malNpage + 1; // One more big page to copy
}
} // if it is 2K pag
SMC_Npage = malNpage;
if (SMC_Wstate & SMC_OLD_CLUSTER) {
// This was an overwrite operation, copy the remain pages
// malRaddr = Map_DTC_Addr(SMC_Zone, SMC_Raddr, SMC_Ppage);
// Map_To_DTC_Addr(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage);
if (SMC_Ppage == 0x40 && malNpage == 0) {
asm NOP;
goto Label_SMC_Write_Interrupt;
}
SMC_Npage = malNpage;
Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage,0);//for 2K page
Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage,0);//for 2K page
if (SMC_Cluster_Size == 64){
if ((Buffer_Param[0x24]/2+1) > SMC_Npage512) { // The current big page is complete
Buffer_Param[0x1A] = 0; // No pre-copy nor post-copy
if (SubBlock) {
SubBlock = 0;
// malNpage = malNpage + 1; // One more big page to copy
}
else
asm NOP;
}
else { // Check if the current big page has small pages to copy
if (SubBlock == 0)
asm NOP;
SubBlock = Buffer_Param[0x24]/2 + 1; // Remain small pages to copy
Buffer_Param[0x18] = 0; // Column start addrsss
Buffer_Param[0x19] = 0; // Must be 0x0000
Buffer_Param[0x16] = SubBlock * 2; // Length of blank area
Buffer_Param[0x17] = SubBlock * 0x10; // 0x210, 0x420, 0x630
Buffer_Param[0x1A] = 3;
if (malNpage == 0xffff)
asm NOP;
// malNpage = malNpage + 1; // One more big page to copy
}
((unsigned char *)(&(malPaddr)))[3] = 0x00; //col byte is always 0
// Buffer_Param[0x27] = Buffer_Param[0x25]= 0x00; //col byte is 0 in copypages
}
// Launch the DTC to copy several pages
// Copy malNpage pages from malRaddr to malPaddr
_MAL_BufMgr_Normal();
DTC_Error = DTC_SMC_Copy_Pages();
DTC_Error--;
// Now SMC_Wstate = SMC_POSTCOPY; // 5
}
else {
// This was a new cluster operation, mark the remain pages
// Launch the DTC to several several pages start from malPaddr
//----------------------------------------------------------------
Buffer_Param[0x25] = ((4 - SubBlock) * 0x10) & 0x30; // added by HYJ
malNpage = Test_page / 4;
SubBlock = Test_page % 4;
// if (Buffer_Param[0x24] == 0 || SMC_Npage512 > 4 || (Buffer_Param[0x24] + SMC_Npage512) == 4)
// malNpage = malNpage - 1; // One more big page to Mark
// else
// asm NOP;
SMC_Npage = malNpage;
//----------------------------------------------------------------
DTC_Error = DTC_SMC_Mark_Pages();
DTC_Error--;
// Now SMC_Wstate = SMC_POSTMARK; // 4
}
// Mask off this line if DTC interrupts
goto Label_SMC_Write_Interrupt;
return;
case SMC_HOLENEWWRITE: // A
case SMC_HOLEOLDWRITE: // B
SMC_Ppage += SMC_Npage;
SMC_Wstate = (SMC_Wstate & SMC_OLD_CLUSTER) | SMC_POST_ACTION; // Keep OLD flag
malNpage = SMC_Cluster_Size - SMC_Ppage; // Pages left to be marked or copied
goto Post_Mark_Copy; // The following actions are same as above
case SMC_POSTMARK: // 4
case SMC_POSTCOPY: // 5
case SMC_POSTHOLEMARK: // C
case SMC_POSTHOLECOPY: // D
case SMC_PRENEWWRITE: // 2
case SMC_PREOLDWRITE: // 3
case SMC_FULLNEWWRITE: // E
case SMC_FULLOLDWRITE: // F
// Now we have finished one cluster
SMC_Update_Lookup();
if (MAL_Block_Numbers == 0) {
// All data from the USB has been written to the SMC
MAL_Error = MAL_GOOD;
MAL_Finish(TRUE);
DTC_Current_Func = 0;
return;
}
#if ALLOW_OUT_RANGE
if (Mal_Addr_Out_Range & 0x02) {
SMC_Wstate = SMC_OUT_RANGE;
goto Write_Out_Range;
}
#endif
// Further more data to be written to the media
#ifdef THUMB_DRIVE
NAND_INC_Logical_Addr();
#endif
SMC_Wstate = SMC_FULL_ACTION | SMC_WRITE_FLAG;
if (SMC_Log2Phy()) {
// This is an existing cluster
SMC_Wstate |= SMC_OLD_CLUSTER;
SMC_Raddr = SMC_Paddr; // old cluster
SMC_Paddr = SMC_Get_Free(); // new cluster
}
if (SMC_Cluster_Size == 64)
SMC_Paddr &= 0xffef; //reset the flag for mapped
else
SMC_Paddr &= 0x7FFF;
SMC_Ppage = 0;
// the next writing must start from beginning of the cluster
malNpage = SMC_Cluster_Size;
if (SMC_Cluster_Size != 64) {
if (malNpage > MAL_Block_Numbers) {
SMC_Wstate &= ~0x08; // change from SMC_FULL_ACTION to SMC_POST_ACTION
malNpage = (unsigned char)MAL_Block_Numbers;
}
// malPaddr = Map_DTC_Addr(SMC_Zone, SMC_Paddr, 0);
SMC_Npage = malNpage;
}
else {
malNpage = malNpage * 4; //No. of 2K pages
if (malNpage > MAL_Block_Numbers){
SMC_Wstate &= ~0x08; // change from SMC_FULL_ACTION to SMC_POST_ACTION
malNpage = (unsigned char)MAL_Block_Numbers;
}
SMC_Npage512 = malNpage; //for decrement of MAL_Block_Numbers
SMC_Npage = malNpage / 4; //counter for 2K pages
}
Test_page = 256 - malNpage;
// Map_To_DTC_Addr(malPaddr, SMC_Zone, SMC_Paddr, 0);
Col = 0x00;
Buffer_Param[0x25] = 0x00; //added as it is the start of the cluster
SMC_Paddr_To_DTC_Addr();
// Launch DTC to write malPpage pages to malPaddr
_MAL_BufMgr_Download();
DTC_SMC_Write_USB(MAL_Block_Finish & 1);
// Now SMC_Wstate = SMC_POSTNEWWRITE or SMC_POSTOLDWRITE or
// SMC_Wstate = SMC_FULLNEWWRITE or SMC_FULLOLDWRITE
// SMC_Wstate = 6 : 7 : E : F
return;
#if ALLOW_OUT_RANGE
case SMC_OUT_RANGE:
if (MAL_Block_Numbers == 0) {
// All data from the USB has been written to the SMC
MAL_Error = MAL_GOOD;
MAL_Finish(TRUE);
DTC_Current_Func = 0;
return;
}
Write_Out_Range:
// assume MAL_Block_Numbers < 256
// malNpage = SMC_Cluster_Size;
// if (malNpage > MAL_Block_Numbers)
// malNpage = (unsigned char)MAL_Block_Numbers;
SMC_Npage = malNpage = (unsigned char)MAL_Block_Numbers;
DTC_SMC_Dummy_Write(MAL_Block_Finish & 1);
return;
#endif
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
MAL_SMC_Write
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
static unsigned char l= 0;
unsigned char SMC_Write(void)
{
Get_Chip_Number(); // Map the MAL address within a chip
// Get the logical cluster address
NAND_Get_Logical_Addr(); // SMC_Zone:SMC_Laddr:SMC_Ppage = MAL_Block_Address
NAND_Select(NAND_Chip); // Enable the chip select of the chip
MAL_Block_Numbers_t = MAL_Block_Numbers;
MAL_Block_Finish = 0;
//set 1st col adr byte as per the adr issued by the PC
asm {
LD A, SubBlock
SWAP A
LD Buffer_Param[0x25], A
}
Col = SubBlock * 2; // set 2nd col adr byte
// Get the physical cluster address
SMC_Wstate = 0; // PRE actions, NEW cluster, no WRITE
if (SMC_Log2Phy()) { // Check if it is an existing cluster
SMC_Wstate |= SMC_OLD_CLUSTER; // Yes, PRECOPY may be necessary
SMC_Raddr = SMC_Paddr; // old cluster
SMC_Paddr = SMC_Get_Free(); // new cluster
}
if (SMC_Cluster_Size == 64)
SMC_Paddr &= 0xffef; // Reset the flag for mapped
else
SMC_Paddr &= 0x7FFF;
Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, 0, 0); //for 2K flash
DTC_Current_Func = DTC_SMC_WRITE;
if ((SMC_Ppage) || (SubBlock)) { //for 2K flash
// the new pages are not start from beginning of the cluster
// Buffer_Param[0x25]= Buffer_Param[0x27] = 0x00; // ALways from the start of the page start copy or mark
SMC_Npage = malNpage = SMC_Ppage;
_MAL_BufMgr_Normal(); // switch back to normal mode first
if (SMC_Wstate & SMC_OLD_CLUSTER) {
unsigned char Num_subBlock;
Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, 0, 0); //for 2K Flash
if (SubBlock) {
malNpage++;
if (SMC_Ppage == 0) // only copy <4 small pages
Buffer_Param[0x1A] = 0x03; // Flag for Pre-copy
else
Buffer_Param[0x1A] = 0x02; // Flag for Post-copy
}
else
Buffer_Param[0x1A] = 0x0;
Buffer_Param[0x18] = SubBlock * 2; // Column start addrsss
Buffer_Param[0x19] = SubBlock * 0x10; // 0x210, 0x420, 0x630
Num_subBlock = 4 - SubBlock;
if (Num_subBlock > MAL_Block_Numbers)
Num_subBlock = MAL_Block_Numbers;
Buffer_Param[0x16] = Num_subBlock * 2; // Length of blank area
Buffer_Param[0x17] = Num_subBlock * 0x10; // 0x210, 0x420, 0x630
// Launch the DTC to copy several pages
// Copy malNpage pages from malRaddr to malPaddr
DTC_Error = DTC_SMC_Copy_Pages();
DTC_Error--;
if (SMC_Cluster_Size == 64) {
if (SubBlock) {
Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage, 0); //for 2K Flash
Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage, 0); //for 2K Flash
}
// if (SMC_Ppage != 0)
((unsigned char *)(&(malPaddr)))[3] = Col;
Buffer_Param[0x25] = Col << 3;
}
// Now SMC_Wstate == SMC_PRECOPY
}
else { // This is a new logical cluster
// Launch the DTC to mark several pages
Buffer_Param[0x25] = 0; // Added by HYJ
Test_page = 256 - (malNpage * 4) - SubBlock;
DTC_Error = DTC_SMC_Mark_Pages(); // Mark the starting pages
DTC_Error--;
if (SMC_Cluster_Size == 64) {
Buffer_Param[0x26] = Buffer_Param[0x12]; //as 0xe6 may contain 2 after markpages
asm {
LD A, SubBlock
SLL A
LD malPaddr:3, A
LD A, SubBlock
SWAP A
LD Buffer_Param[0x25], A
}
}
// Now SMC_Wstate == SMC_PREMARK
}
// Mask off this line if DTC interrupts
SMC_Write_Interrupt();
}
else {
// the new pages are start from beginning of the cluster
malNpage = SMC_Cluster_Size;
if (SMC_Cluster_Size != 64){
if (malNpage > MAL_Block_Numbers) {
// Do not write the whole cluster
malNpage = (unsigned char)MAL_Block_Numbers;
SMC_Wstate |= SMC_POST_ACTION | SMC_WRITE_FLAG;
}
else
SMC_Wstate |= SMC_FULL_ACTION | SMC_WRITE_FLAG;
SMC_Npage = malNpage;
}
else {
Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, 0, 0); // added by HYJ for 2K Flash
malNpage = malNpage * 4;
if (malNpage > MAL_Block_Numbers){
malNpage = (unsigned char)MAL_Block_Numbers;
SMC_Wstate |= SMC_POST_ACTION | SMC_WRITE_FLAG;
}
else
SMC_Wstate |= SMC_FULL_ACTION | SMC_WRITE_FLAG;
SMC_Npage512 = malNpage;
SMC_Npage = malNpage / 4;
}
Test_page = 256 - malNpage;
// Launch DTC to write malPpage pages to malPaddr
_MAL_BufMgr_Download(); // Switch to DOWNLOAD mode
DTC_SMC_Write_USB(0);
// Now SMC_Wstate = SMC_POSTNEWWRITE or SMC_POSTOLDWRITE
// SMC_Wstate = SMC_FULLNEWWRITE or SMC_FULLOLDWRITE
}
return MAL_GOOD;
}
#ifdef THUMB_DRIVE
static unsigned short NAND_Blocks;
#pragma DATA_SEG DEFAULT_RAM
unsigned char Startup_VAR = 0;
extern void SMC_Restore_Parameters(void);
extern unsigned char NAND_Format(void);
unsigned char NAND_Init()
{
unsigned char iChip, MAL_Status;
DTC_SMC_Init();
MAL_Status = NAND_Read_Capacity();
if (MAL_Status != MAL_GOOD)
return MAL_Status;
/*******************************************
Get the 2K page Flash on board to remap the Bad clusters in the media
*******************************************/
#ifdef Factory_bad
for (NAND_Chip = 0; NAND_Chip < MAX_NUM_NAND; NAND_Chip++) {
if (Cluster_Size[NAND_Chip] != 64)
continue;
NAND_Select(NAND_Chip);
SMC_Cluster_Size = 64;
malPaddr = 0;
if (!(DTC_SMC_Chk_Spare(format) & 0x02)) {
unsigned long *paddr;
malNpage = 0;
SubBlock = 1;
DTC_SMC_Mark_Bad();
malPaddr = 0x4000;
malNpage = SMC_Cluster_Size;
Buffer_Param[0x3e] = (Chip_Size[NAND_Chip]/8); //number of zones
asm { //initialise DTC buffer
CLR A
CLR X
Clr_Buf0: LD (Buffer_0, X), A
LD (Buffer_0:256, X), A
DEC X
JRNE Clr_Buf0
}
DTC_SMC_Chk_Spare(init);
paddr = (unsigned long *) Buffer_0;
while (*paddr & 0x08) {
malNpage = 0;
SubBlock = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -