📄 mal_2k.c
字号:
malPaddr = *paddr;
DTC_SMC_Mark_Bad();
paddr++;
}
// Format the chip in very first time of device power on
asm RIM;
NAND_Format();
while (MAL_Block_Numbers);
asm NOP;
}
}
#endif
if(!Startup_VAR )
SMC_Restore_Parameters();
if (Cluster_Size[0] != 64) {
extern unsigned char Flash_State;
if ((Flash_State & 0x01) == 0) {
// The first chip is not a 2K flash and is a new chip
// Format it and copy in the system blocks
asm RIM;
NAND_Format();
while (MAL_Block_Numbers != 0);
asm NOP;
}
}
SMC_Lookup_Zone0 = SMC_Lookup_Zone1 = -1; // There is no zone in both table
NAND_Lookup_Update0(0, 0); // Assume chip 0 must exist
if (SMC_Cluster_Size != 64){
if (MAL_Capacity >= 32768) { // Scan the 2nd zone
if (Chip_Size[0] > 1)
NAND_Lookup_Update1(0, 1);
else {
unsigned char iChip;
for (iChip = 1; iChip < MAX_NUM_NAND; iChip++)
if (Chip_Size[iChip]) {
NAND_Lookup_Update1(iChip, 0);
break;
}
}
}
}
else {
if(MAL_Capacity >= 512000) {
if(Chip_Size[0] >= 16)
NAND_Lookup_Update1(0, 1);
else {
unsigned char iChip;
for (iChip = 1; iChip < MAX_NUM_NAND; iChip++)
if (Chip_Size[iChip]) {
NAND_Lookup_Update1(iChip, 0);
break;
}
}
}
}
return MAL_GOOD;
}
#else // THUMB_DRIVE
unsigned char SMC_Init()
{
unsigned char MAL_Status;
DTC_SMC_Init();
MAL_Status = SMC_Read_Capacity();
if (MAL_Status != MAL_GOOD)
return MAL_Status;
SMC_Lookup_Zone0 = SMC_Lookup_Zone1 = -1; // There is no zone in both table
SMC_Lookup_Update0(0);
if (MAL_Capacity >= 32768) {
if(SMC_Cluster_Size != 64)
// Scan the 2nd zone
SMC_Lookup_Update1(1);
else {
if(MAL_Capacity == 512000)
SMC_Lookup_Update1(1);
}
}
return MAL_GOOD;
}
#endif // THUMB_DRIVE
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Variables and functions for SMC formation
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
unsigned char SMC_Format_State;
#define STEP_CHECK 0x01
#define STEP_PRE_ERASE 0x02
#define STEP_WRITE 0x03
#define STEP_READ 0x04
#define STEP_POST_ERASE 0x05
#define LED_ON_OFF { PFDR ^= 0x18; }
#ifdef THUMB_DRIVE
void NAND_Format_After(void)
{
extern void Logical_Format(unsigned char iCard);
SMC_Format_State = 0;
DTC_Current_Func = 0;
MAL_State = MAL_IDLE;
SMC_Init_Param();
NAND_Init();
/*
if (Chip_Size[0] == 1)
Logical_Format(2); // 16MB
else if (Chip_Size[0] == 2)
Logical_Format(3); // 32MB
else if (Chip_Size[0] == 4)
Logical_Format(4); // 64MB
else if (Chip_Size[0] == 8)
if (Cluster_Size[0] == 32)
Logical_Format(5); // 128MB
else
Logical_Format(6); // 128MB-2K
else if (Chip_Size[0] == 16)
Logical_Format(7); // 256MB-2K
else if (Chip_Size[0] == 32)
Logical_Format(8); // 512MB-2K
*/
DESELECT_NAND;
// LED_OFF; // testing
return;
}
void NAND_Format_Interrupt(void)
{
Formation_loop:
// Here I need to refresh a timer to ensure that the DTC formatting does not deadlocked
LED_ON_OFF;
DTC_Current_Func = DTC_SMC_FORMAT;
switch (SMC_Format_State) {
case STEP_CHECK:
// if(Buffer_Param[0x26] == 0x02)
// asm nop;
DTC_SMC_Format_Chk(format);
if (DTC_SMC_Format_Chk(format) & 0x02)
asm nop;
SMC_Format_State++; // going to move to STEP_PRE_ERASE
DTC_SMC_Format_Erase();
return;
case STEP_PRE_ERASE:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
SMC_Format_State++; // going to move to STEP_WRITE
DTC_SMC_Format_Write();
return;
case STEP_WRITE:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
SMC_Format_State++; // going to move to STEP_READ
if (SMC_Cluster_Size == 64)
Buffer_Param[0x3f] = malNpage;
DTC_SMC_Format_Read();
return;
case STEP_READ:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
if (SMC_Cluster_Size == 64){
if (Buffer_Param[0x3f] != 0x00){
DTC_SMC_Format_Read();
return;
}
}
SMC_Format_State++; // going to move to STEP_POST_ERASE
DTC_SMC_Format_Erase();
return;
case STEP_POST_ERASE:
if (DTC_Error & 0x02) {
mark_bad_cluster:
DTC_SMC_Mark_Bad();
if(SMC_Cluster_Size == 64)
Buffer_Param[0x26] = Buffer_Param[0x12]; //as 0xe6 may contain 2 after markpages
malNpage = SMC_Cluster_Size; // Pages in a cluster
break;
}
}
format_next_cluster:
MAL_Block_Numbers--;
NAND_Blocks--;
if (NAND_Blocks) { // move to the next cluster
if(SMC_Cluster_Size != 64){
asm { // malPaddr += 32
LD A, malPaddr:3
ADD A, #32
LD malPaddr:3, A
JRNC lab2
INC malPaddr:2
JRNE lab2
JRT lab1
}
}
else {
asm { // malPaddr += 64 << 8;
LD A,malPaddr:2
ADD A,#64
LD malPaddr:2, A
JRNC lab2
lab1: INC malPaddr:1
JRNE lab2
INC malPaddr
lab2:
}
}
}
else {
Format_Another_Chip:
NAND_Chip++;
if (NAND_Chip == MAX_NUM_NAND) { // all clusters have been formated
asm NOP;
NAND_Format_After();
return;
}
if (Chip_Size[NAND_Chip] == 0)
goto Format_Another_Chip;
NAND_Select(NAND_Chip);
if (SMC_Cluster_Size != 64)
asm {
LD X, NAND_Chip
LD A, (Chip_Size, X)
SLL A
SLL A
LD NAND_Blocks, A
CLR A
LD NAND_Blocks:1, A
}
// NAND_Blocks = Chip_Size[NAND_Chip] * 1024;
else
asm {
LD X, NAND_Chip
LD A, (Chip_Size, X)
SRL A
LD NAND_Blocks, A
CLR A
LD NAND_Blocks:1, A
}
// NAND_Blocks = Chip_Size[NAND_Chip] * 128;
malPaddr = 0;
malNpage = SMC_Cluster_Size; //cluster size could be different
}
SMC_Format_State = STEP_CHECK;
goto Formation_loop;
}
unsigned char NAND_Format(void)
{
unsigned char iChip, nZone;
unsigned char TotalSize;
TotalSize = 0;
MAL_Block_Numbers = 0;
for (iChip = 0; iChip < MAX_NUM_NAND; iChip++){
nZone = NAND_Capacity(iChip);
TotalSize += nZone;
if(Cluster_Size[iChip] == 32)
asm {
LD A, nZone
SLL A
SLL A
JRT Add_Block_Num
}
// MAL_Block_Numbers += nZone * 1024;
else
asm {
LD A, nZone
SRL A // nZone can not be an even number
Add_Block_Num: ADD A, MAL_Block_Numbers
LD MAL_Block_Numbers, A
}
// MAL_Block_Numbers += nZone * 128;
}
if (TotalSize == 0 || Chip_Size[0] == 0)
return MAL_CARD_UNKNOWN;
// MAL_Capacity is used to report the format progress
MAL_Capacity = MAL_Block_Numbers;
// Start from chip0
NAND_Chip = 0;
NAND_Select(0);
SMC_Cluster_Size = Cluster_Size[0];
if(SMC_Cluster_Size != 64)
asm {
LD A, Chip_Size
SLL A
SLL A
LD NAND_Blocks, A
CLR A
LD NAND_Blocks:1, A
}
// NAND_Blocks = Chip_Size[0] * 1024;
else
asm {
LD A, Chip_Size
SRL A
LD NAND_Blocks, A
CLR A
LD NAND_Blocks:1, A
}
// NAND_Blocks = Chip_Size[0] * 128;
malPaddr = 0;
malNpage = SMC_Cluster_Size; // Pages in a cluster
SMC_Format_State = STEP_CHECK;
// SMC_Format_Interrupt(1); // I can not start with this,
// because the compiler will treat the routine as non-interrupt
// so that the variables will be allocated overlapped
DTC_Current_Func = DTC_SMC_FORMAT;
DTC_SMC_Format_Start(); // Use this way to start the procedure, it will generate an interrupt
return MAL_GOOD;
}
#else // THUMB_DRIVE
void SMC_Format_Interrupt()
{
Formation_loop:
// Here I need to refresh a timer to ensure that the DTC formatting does not deadlocked
DTC_Current_Func = DTC_SMC_FORMAT;
switch (SMC_Format_State) {
case STEP_CHECK:
if (DTC_SMC_Format_Chk() & 0x02) {
// asm nop;
#ifndef FORCE_ERASE
// break;
#endif
}
SMC_Format_State++; // going to move to STEP_PRE_ERASE
DTC_SMC_Format_Erase();
return;
case STEP_PRE_ERASE:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
SMC_Format_State++; // going to move to STEP_WRITE
DTC_SMC_Format_Write();
return;
case STEP_WRITE:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
SMC_Format_State++; // going to move to STEP_READ
if (SMC_Cluster_Size == 64)
{
Buffer_Param[0x3f] = malNpage;
}
DTC_SMC_Format_Read();
return;
case STEP_READ:
if (DTC_Error & 0x02)
goto mark_bad_cluster;
if (SMC_Cluster_Size == 64)
{
if (Buffer_Param[0x3f] != 0x00)
{
DTC_SMC_Format_Read();
return;
}
}
SMC_Format_State++; // going to move to STEP_POST_ERASE
DTC_SMC_Format_Erase();
return;
case STEP_POST_ERASE:
if (DTC_Error & 0x02) {
mark_bad_cluster:
DTC_SMC_Mark_Bad();
malNpage = SMC_Cluster_Size; // Pages in a cluster
break;
}
}
format_next_cluster:
MAL_Block_Numbers--;
if (MAL_Block_Numbers == 0) { // all clusters have been formated
SMC_Format_State = 0;
MAL_State = MAL_IDLE;
DTC_Current_Func = 0;
SMC_Init();
return;
}
if (SMC_Cluster_Size != 64)
malPaddr += SMC_Cluster_Size; // move to the next cluster
else
{
malPaddr += (SMC_Cluster_Size << 8);
}
SMC_Format_State = STEP_CHECK;
goto Formation_loop;
}
unsigned char SMC_Format()
{
unsigned char CardID;
// Know the card capacity
CardID = DTC_SMC_ReadID();
// MAL_Block_Numbers is used as number of blocks in the medium
SMC_Cluster_Size = 16;
if (CardID == 0xE3 || CardID == 0xE5)
MAL_Block_Numbers = 0x200; // 4MB
else if (CardID == 0xE6)
MAL_Block_Numbers = 0x400; // 8MB
else {
SMC_Cluster_Size <<= 1;
MAL_Block_Numbers = 0x400;
#define hMAL_Block_Numbers *((unsigned char *)&MAL_Block_Numbers)
switch (CardID) {
case 0x79: // 128MB
hMAL_Block_Numbers <<= 1;
case 0x76: // 64MB
hMAL_Block_Numbers <<= 1;
case 0x75: // 32MB
hMAL_Block_Numbers <<= 1;
case 0x73: // 16MB
break;
case 0xf1: // 2k 128mB
SMC_Cluster_Size <<= 1;
DTC_SMC_Address_bytes = 4;
break;
case 0xda: //2k 256MB
SMC_Cluster_Size <<= 1;
hMAL_Block_Numbers <<= 1;
DTC_SMC_Address_bytes = 5;
break;
default:
return MAL_CARD_UNKNOWN;
}
}
MAL_Capacity = MAL_Block_Numbers; // Number of clusters in the media
if (SMC_Cluster_Size != 64) {
if (MAL_Block_Numbers <= 2048) {
DTC_SMC_Address_bytes = 3; // Less than 32MB
}
else {
DTC_SMC_Address_bytes = 4; // 64MB & 128MB
}
}
// 64MB & 128MB
malPaddr = 0;
malNpa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -