📄 mal_2k.c
字号:
/*-*-*-*-*-*-*-*-*-*-* (C) 2000 STMicroelectronics *-*-*-*-*-*-*-*-*-*-*-*-*-*
PROJECT : ST7265 Media Access Library
COMPILER : ST7 C
MODULE : MAL_All.c
VERSION : V 0.5
CREATION DATE : 04/12/2000
AUTHOR : Liang Ping
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
DESCRIPTION : All functions except those with individual one
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Modification:
16/05/2002 Patch for NAND Thumb drive
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
VARIABLES VARIABLES VARIABLES VARIABLES VARIABLES VARIABLES
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#include "define.h"
#include "Map_7265.h"
#include "Mconfig.h" // Media configuration
#include "MSL.h"
#include "MAL_Map.h"
#include "MAL.h"
#include "2K_Mass.h"
#include "DTC_Func.h"
#include "NAND.h"
extern void Deselect(void);
#define USE_CACHE0 0
//#define PAGE2K_BAD
/*-*-*-*-*-*-*-*-*-*-*-*-*-* Variable declaration *-*-*-*-*-*-*-*-*-*-*-*-*-*/
#pragma DATA_SEG SHORT MAL_RAM0 // Frequently used variable
// SMC_Wstate keeps track the state of the SMC writing procedure
// Bits definition:
// bit0 = 0 actions on new cluster
// = 1 actions on old cluster
// bit1-0 = 00 MARKing
// = 01 COPYing
// = 10 WRITE to new cluster
// = 11 WRITE to old cluster
// bit3-2 = 00 PRE actions
// = 01 POST actions
// = 10 HOLE actions
// = 11 HOLE or FULL actions
/*static*/ unsigned char SMC_Wstate; // the state of the SMC writing procedure
#define SMC_OLD_CLUSTER 0x01
#define SMC_WRITE_FLAG 0x02
#define SMC_PRE_ACTION 0x00
#define SMC_POST_ACTION 0x04
#define SMC_HOLE_ACTION 0x08
#define SMC_FULL_ACTION 0x0C
#define SMC_ERROR_FLAG 0x10
#if ALLOW_OUT_RANGE
#define SMC_OUT_RANGE (0x20 | SMC_WRITE_FLAG)
#endif
#define SMC_PREMARK (SMC_PRE_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // 0
#define SMC_PRECOPY (SMC_PRE_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // 1
#define SMC_PRENEWWRITE (SMC_PRE_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // 2
#define SMC_PREOLDWRITE (SMC_PRE_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // 3
#define SMC_POSTMARK (SMC_POST_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // 4
#define SMC_POSTCOPY (SMC_POST_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // 5
#define SMC_POSTNEWWRITE (SMC_POST_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // 6
#define SMC_POSTOLDWRITE (SMC_POST_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // 7
#define SMC_PREHOLEMARK (SMC_HOLE_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // 8
#define SMC_PREHOLECOPY (SMC_HOLE_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // 9
#define SMC_HOLENEWWRITE (SMC_HOLE_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // A
#define SMC_HOLEOLDWRITE (SMC_HOLE_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // B
#define SMC_POSTHOLEMARK (SMC_FULL_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // C
#define SMC_POSTHOLECOPY (SMC_FULL_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // D
#define SMC_FULLNEWWRITE (SMC_FULL_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER) // E
#define SMC_FULLOLDWRITE (SMC_FULL_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER) // F
unsigned char SMC_Cluster_Size; // Size of a cluster
//statuc removed for 2K page
#define LOOKUP_THRESHOLD 250
unsigned char SubBlock; //block with in a page for 256MB
static unsigned char Col; //block with in a page for 256MB
unsigned char SMC_Zone;
static unsigned char SMC_Lookup_Zone0; // Zone of table0
static unsigned char SMC_Lookup_Zone1; // Zone of table1
static unsigned char SMC_Lookup_Count0; // Visit count of table0
static unsigned char SMC_Lookup_Count1; // Visit count of table1
static unsigned short *SMC_Lookup_pTable; // The pointer of the current table
// When the zone 0 is not in one of two lookup table
// The follow small lookup table keeps the initial few items of zone 0
static unsigned char SMC_Lookup_nCache0; // number of items in zone 0 Cache
// number of sectors for MBR, PBR, FAT & Root
static unsigned char flag2k;
#ifdef THUMB_DRIVE
static unsigned char NAND_Chip; // The current chip number
#endif
#if USE_CACHE0
#ifdef THUMB_DRIVE
#define CACHE0_NUM 16
#else
#define CACHE0_NUM 5
#endif
#define CACHE0_FREE 3
static unsigned short SMC_Lookup_pCache0[CACHE0_NUM];
// The following array is used to cache the free cluster
// for zone 0 when zone 0 is not in the lookup table area
static unsigned short SMC_Lookup_pFree0[CACHE0_FREE];
#endif // USE_CACHE0
static unsigned short SMC_Paddr;
static unsigned short SMC_Raddr; // An old physical cluster
static unsigned int SMC_Npage; // data type changed for 2K page.MAx page = 256
static unsigned int SMC_Npage512; // variable added for 2K dec/inc blocks
unsigned char SMC_Ppage;
unsigned short SMC_Laddr;
unsigned long malPaddr;
unsigned long malRaddr;
//unsigned char malNpage;
unsigned int malNpage; // data type changed for 2kflash
unsigned int Test_page; // data type changed for 2kflash
#ifndef THUMB_DRIVE
static unsigned char SMC_4MB; // The SMC is a 4MB card
#endif
static unsigned char DTC_Error;
static unsigned char DTC_Current_Func;
#define DTC_SMC_READ 0x01
#define DTC_SMC_WRITE 0x02
#define DTC_SMC_FORMAT 0x04
#pragma DATA_SEG MAL_RAM
#ifndef THUMB_DRIVE
static unsigned char SMC_Addr_Bytes;
static unsigned char CardID; // added for 2K Flash
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-* Variable declaration *-*-*-*-*-*-*-*-*-*-*-*-*-*/
// Buffer for redundant area
typedef struct _SPARE_AREA {
union {
unsigned long dwReserved;
unsigned short wReserved[2];
} R;
unsigned char Data_Status;
unsigned char Block_Status;
unsigned short Block_Address1;
unsigned char ECC2[3];
unsigned short Block_Address2;
unsigned char ECC1[3];
} SPARE_AREA;
static SPARE_AREA SMC_Spare;
#define Map_To_DTC_Addr(Target, zone, addr, page) \
{ ((_UDWORD*)&Target)->byte[3] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page); \
((_UDWORD*)&Target)->byte[2] = HIBYTE((unsigned int)(addr)); \
if (SMC_Cluster_Size == 32) { \
if (zone & 1) \
((_UDWORD*)&Target)->byte[2] |= 0x80; \
((_UDWORD*)&Target)->byte[1] = (unsigned char)zone >> 1; \
} \
else \
((_UDWORD*)&Target)->byte[1] = 0; \
((_UDWORD*)&Target)->byte[0] = 0; \
}
#define Map_To_DTC_Addr256(Target, zone, addr, page, col) \
{ if (SMC_Cluster_Size == 64) { \
((_UDWORD*)&Target)->byte[3] = ((unsigned char)(col)); \
((_UDWORD*)&Target)->byte[2] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page); \
((_UDWORD*)&Target)->byte[1] = HIBYTE((unsigned int)(addr)); \
((_UDWORD*)&Target)->byte[0] = zone; \
} \
else { \
((_UDWORD*)&Target)->byte[3] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page); \
((_UDWORD*)&Target)->byte[2] = HIBYTE((unsigned int)(addr)); \
if (SMC_Cluster_Size == 32) { \
if (zone & 1) \
((_UDWORD*)&Target)->byte[2] |= 0x80; \
((_UDWORD*)&Target)->byte[1] = (unsigned char)zone >> 1; \
} \
else \
((_UDWORD*)&Target)->byte[1] = 0; \
((_UDWORD*)&Target)->byte[0] = 0; \
} \
}
#define Map_DTC_Addr(zone, addr, page) \
(SMC_Cluster_Size == 32) ? \
/* 11111111 ZZZ: physical zone */ \
/* 765432109876543210 BBBBBBBBBB: physical cluster address */ \
/* ZZZBBBBBBBBBBPPPPP: PPPPP: physical page address */ \
((DWORD)(zone) << 15) | (unsigned int)(addr) | (unsigned char)(page) : \
/* 1111 */ \
/* 32109876543210 BBBBBBBBBB: physical cluster address */ \
/* BBBBBBBBBBPPPP: PPPP: physical page address */ \
(unsigned int)(addr) | (unsigned char)(page);
#pragma CODE_SEG SMC_CODE
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// Functions for the NAND Thumb-Drive
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
#ifdef THUMB_DRIVE
// The value expresses number of zone's
// 1=16MB, 2=32MB, 4=64MB, 8=128MB, etc.
// 3=48MB, 5=80MB, 6=96MB, 7=112MB, etc.
static unsigned char Chip_Size[MAX_NUM_NAND];
static unsigned char Cluster_Size[MAX_NUM_NAND];
//#define gZONE(Chip, Zone) (((Chip)<<4)|Zone) // Global zone number
//for debug
#define gZONE(Chip, Zone) (((Chip)<<5)|Zone) // Global zone number
void NAND_Select(unsigned char iChip)
{
switch (iChip) {
case 0: SELECT_NAND0; break;
case 1: SELECT_NAND1; break;
case 2: SELECT_NAND2; break;
case 3: SELECT_NAND3; break;
default: DESELECT_NAND; return;
}
if ((Chip_Size[iChip] >= 4) && (Chip_Size[iChip]< 16))
DTC_SMC_Address_bytes = 4;
else if (Chip_Size[iChip] >= 16)
DTC_SMC_Address_bytes = 5; //if device is of 256MB
else
DTC_SMC_Address_bytes = 3;
SMC_Cluster_Size = Cluster_Size[iChip];
}
unsigned char NAND_Capacity(unsigned char iChip)
{
unsigned char CardID;
unsigned char ChipSize, ClusterSize;
NAND_Select(iChip);
CardID = DTC_SMC_ReadID();
Deselect(); // Deselect the NAND flash
ClusterSize = 32;
if (CardID == 0x73) // 16MB
ChipSize = 1;
else if (CardID == 0x75) // 32MB
ChipSize = 2;
else if (CardID == 0x76) // 64MB
ChipSize = 4;
else if (CardID == 0x79) // 128MB
ChipSize = 8;
else if (CardID == 0xF1) { // 128MB-2K
ChipSize = 8;
ClusterSize = 64;
}
else if(CardID == 0xda){ // 256MB-2K
ChipSize = 16;
ClusterSize = 64;
}
else if(CardID == 0xdc){ // 512MB-2K
ChipSize = 32;
ClusterSize = 64;
}
else
ChipSize = 0;
Chip_Size[iChip] = ChipSize;
Cluster_Size[iChip] = ClusterSize;
return ChipSize;
}
unsigned char NAND_Read_Capacity(void)
{
unsigned char iChip;
unsigned char TotalSize;
TotalSize = 0;
for (iChip = 0; iChip < MAX_NUM_NAND; iChip++)
TotalSize += NAND_Capacity(iChip);
if (TotalSize == 0 || Chip_Size[0] == 0)
return MAL_CARD_UNKNOWN;
asm {
CLR A
LD MAL_Capacity:3, A
LD MAL_Capacity, A
LD A, TotalSize
LD X, #125
MUL X, A
LD MAL_Capacity:1, X
LD MAL_Capacity:2, A
}
// MAL_Capacity = (unsigned long)TotalSize * 32000L;
if (TotalSize <= (32 >> 4)) // <= 32MB
SMC_Lookup_nCache0 = 0; // No zone0 cache with card < 64MB
else
SMC_Lookup_nCache0 = 5; // Use the maximum value
return MAL_GOOD;
}
void Get_Chip_Number(void)
{
unsigned char iChip;
unsigned long Boundary;
NAND_Chip = 0;
for (iChip = 0; iChip < MAX_NUM_NAND; iChip++) {
asm {
CLR A
LD Boundary:3, A
LD Boundary, A
LD X, iChip
LD A, (Chip_Size,X)
LD X, #125
MUL X, A
LD Boundary:1, X
LD Boundary:2, A
}
// Boundary = (unsigned long)Chip_Size[iChip] * 32000L;
if (MAL_Block_Address < Boundary)
break;
MAL_Block_Address -= Boundary;
NAND_Chip++;
}
SMC_Cluster_Size = Cluster_Size[NAND_Chip];
}
// Pre-declarations
void SMC_Copy_Lookup_Cache0();
void SMC_Convert_Lookup(unsigned short *LUT);
/*
void show_LED(void)
{
PDDR |= 0x01;
PDDR |= 0x04;
if ((SMC_Lookup_Zone0 & 0xF0) == 0)
PDDR &= ~0x01;
if ((SMC_Lookup_Zone0 & 0xF0) == 0x10)
PDDR &= ~0x04;
if ((SMC_Lookup_Zone1 & 0xF0) == 0)
PDDR &= ~0x01;
if ((SMC_Lookup_Zone1 & 0xF0) == 0x10)
PDDR &= ~0x04;
}
*/
void NAND_Lookup_Updates(unsigned char Zone)
{
malRaddr = 1024; // number of clusters in the zone
malNpage = SMC_Cluster_Size;
if (SMC_Cluster_Size == 64) {
Buffer_Param[0x00] = 0x00; //flag to differnetiate between 2K and 512
Buffer_Param[0x02] = 0x00; //1st cmd for 2k
Buffer_Param[0x03] = 0xe3; // adr for page byte
}
else {
Buffer_Param[0x00] = 0x01; //flag to differnetiate between 2K and 512
Buffer_Param[0x02] = 0x50; //1st cmd for 512
Buffer_Param[0x03] = 0xe4; // adr for page byte
}
// Map_To_DTC_Addr(malPaddr, Zone, 0, 0); //commented for 2k
Map_To_DTC_Addr256(malPaddr, Zone, 0, 0,2); //new for 2K page
DTC_SMC_Map_Zone(SMC_Lookup_pTable);
SMC_Convert_Lookup(SMC_Lookup_pTable);
Deselect(); // Deselect the NAND flash
}
void NAND_Lookup_Update0(unsigned char Chip, unsigned char Zone)
{
NAND_Select(Chip);
SMC_Lookup_pTable = SMC_Lookup_Table0;
#if USE_CACHE0
if (SMC_Lookup_Zone0 == 0)
SMC_Copy_Lookup_Cache0();
#endif
SMC_Lookup_Count0 = 0;
SMC_Lookup_Zone0 = gZONE(Chip, Zone);
//show_LED();
NAND_Lookup_Updates(Zone);
}
//#pragma NO_OVERLAP
void NAND_Lookup_Update1(unsigned char Chip, unsigned char Zone)
{
NAND_Select(Chip);
SMC_Lookup_pTable = SMC_Lookup_Table1;
#if USE_CACHE0
if (SMC_Lookup_Zone1 == 0)
SMC_Copy_Lookup_Cache0();
#endif
SMC_Lookup_Count1 = 0;
SMC_Lookup_Zone1 = gZONE(Chip, Zone);
//show_LED();
NAND_Lookup_Updates(Zone);
}
static void NAND_INC_Logical_Addr(void)
{
SMC_Laddr++;
/*----for 2K Flash----- */
SubBlock = 0; //For next logical adr col offset is 0
Buffer_Param[0x01] = 4; //No. of cols in Read operation is resetted
Buffer_Param[0x25] = 0; //Col offset 0
if (SMC_Laddr >= 1000) {
SMC_Zone++;
if (SMC_Cluster_Size != 64) {
if (SMC_Zone == Chip_Size[NAND_Chip]) {
goto common;
// SMC_Zone = 0;
// NAND_Chip++;
// while (Chip_Size[NAND_Chip] == 0)
// NAND_Chip++; // Skip the bad of not exist chip
// NAND_Select(NAND_Chip);
}
}
else {
if (SMC_Zone == (Chip_Size[NAND_Chip] / 8)){
common: SMC_Zone = 0;
NAND_Chip++;
while (Chip_Size[NAND_Chip] == 0)
NAND_Chip++;
NAND_Select(NAND_Chip);
}
}
SMC_Laddr -= 1000;
}
}
void Adjust_Laddr(void)
{
while (SMC_Laddr >= 1000) {
SMC_Zone++;
SMC_Laddr -= 1000;
}
}
void NAND_Get_Logical_Addr(void)
{
unsigned short EndBlock;
unsigned char SMC_Ppage512; //for claculating Endblock
SMC_Zone = 0;
SubBlock = 0; //initialise
// if (MAL_Block_Address == 0x2f)
// asm nop;
if (SMC_Cluster_Size == 32){
asm {
LD A, MAL_Block_Address:3
LD X, MAL_Block_Address:2
LD Y, MAL_Block_Address:1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -