www.pudn.com > NAND.rar > NandFAT.c
/* * FileName: fat.c *Copyright(c) 2004 VIA Technologies, Inc. All Rights Reserved. * * Author: penson Version: 1.00 Date: 2004-10-25 * Description: this file define functions about sd card * Version: * Function List: * 1. * History: *<10-25> */ //#define _DEBUG_ON_ //#include //#include //#include "driversys.h" #include "drivermmiif.h" #include "Driverosif.h" //#include "driverprim.h" //#include "type_zac.h" #include "NANDFAT.h" //#include "OSModule_MemoryManagement.h" //#include"BadBlockManagement.h" const UINT8 BPBTaBle[512] = /*{ 0xEB, 0x3C, 0x90, 'V' , 'I', 'A', 'T', 'E', 'C', 'T', 'H', 0x00, 0x02, 0x02, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x29, 0xCA, 0x61, 0x58, 0x30, 0x4C, 0x4F, 0x56, 0x45, 0x42, 0x45, 0x4E, 0x46, 0x45, 0x4E, 0x20, 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x33, 0xC9, 0x8E, 0xD1, 0xBC, 0xF0, 0x7B, 0x8E, 0xD9, 0xB8, 0x00, 0x20, 0x8E, 0xC0, 0xFC, 0xBD, 0x00, 0x7C, 0x38, 0x4E, 0x24, 0x7D, 0x24, 0x8B, 0xC1, 0x99, 0xE8, 0x3C, 0x01, 0x72, 0x1C, 0x83, 0xEB, 0x3A, 0x66, 0xA1, 0x1C, 0x7C, 0x26, 0x66, 0x3B, 0x07, 0x26, 0x8A, 0x57, 0xFC, 0x75, 0x06, 0x80, 0xCA, 0x02, 0x88, 0x56, 0x02, 0x80, 0xC3, 0x10, 0x73, 0xEB, 0x33, 0xC9, 0x8A, 0x46, 0x10, 0x98, 0xF7, 0x66, 0x16, 0x03, 0x46, 0x1C, 0x13, 0x56, 0x1E, 0x03, 0x46, 0x0E, 0x13, 0xD1, 0x8B, 0x76, 0x11, 0x60, 0x89, 0x46, 0xFC, 0x89, 0x56, 0xFE, 0xB8, 0x20, 0x00, 0xF7, 0xE6, 0x8B, 0x5E, 0x0B, 0x03, 0xC3, 0x48, 0xF7, 0xF3, 0x01, 0x46, 0xFC, 0x11, 0x4E, 0xFE, 0x61, 0xBF, 0x00, 0x00, 0xE8, 0xE6, 0x00, 0x72, 0x39, 0x26, 0x38, 0x2D, 0x74, 0x17, 0x60, 0xB1, 0x0B, 0xBE, 0xA1, 0x7D, 0xF3, 0xA6, 0x61, 0x74, 0x32, 0x4E, 0x74, 0x09, 0x83, 0xC7, 0x20, 0x3B, 0xFB, 0x72, 0xE6, 0xEB, 0xDC, 0xA0, 0xFB, 0x7D, 0xB4, 0x7D, 0x8B, 0xF0, 0xAC, 0x98, 0x40, 0x74, 0x0C, 0x48, 0x74, 0x13, 0xB4, 0x0E, 0xBB, 0x07, 0x00, 0xCD, 0x10, 0xEB, 0xEF, 0xA0, 0xFD, 0x7D, 0xEB, 0xE6, 0xA0, 0xFC, 0x7D, 0xEB, 0xE1, 0xCD, 0x16, 0xCD, 0x19, 0x26, 0x8B, 0x55, 0x1A, 0x52, 0xB0, 0x01, 0xBB, 0x00, 0x00, 0xE8, 0x3B, 0x00, 0x72, 0xE8, 0x5B, 0x8A, 0x56, 0x24, 0xBE, 0x0B, 0x7C, 0x8B, 0xFC, 0xC7, 0x46, 0xF0, 0x3D, 0x7D, 0xC7, 0x46, 0xF4, 0x29, 0x7D, 0x8C, 0xD9, 0x89, 0x4E, 0xF2, 0x89, 0x4E, 0xF6, 0xC6, 0x06, 0x96, 0x7D, 0xCB, 0xEA, 0x03, 0x00, 0x00, 0x20, 0x0F, 0xB6, 0xC8, 0x66, 0x8B, 0x46, 0xF8, 0x66, 0x03, 0x46, 0x1C, 0x66, 0x8B, 0xD0, 0x66, 0xC1, 0xEA, 0x10, 0xEB, 0x5E, 0x0F, 0xB6, 0xC8, 0x4A, 0x4A, 0x8A, 0x46, 0x0D, 0x32, 0xE4, 0xF7, 0xE2, 0x03, 0x46, 0xFC, 0x13, 0x56, 0xFE, 0xEB, 0x4A, 0x52, 0x50, 0x06, 0x53, 0x6A, 0x01, 0x6A, 0x10, 0x91, 0x8B, 0x46, 0x18, 0x96, 0x92, 0x33, 0xD2, 0xF7, 0xF6, 0x91, 0xF7, 0xF6, 0x42, 0x87, 0xCA, 0xF7, 0x76, 0x1A, 0x8A, 0xF2, 0x8A, 0xE8, 0xC0, 0xCC, 0x02, 0x0A, 0xCC, 0xB8, 0x01, 0x02, 0x80, 0x7E, 0x02, 0x0E, 0x75, 0x04, 0xB4, 0x42, 0x8B, 0xF4, 0x8A, 0x56, 0x24, 0xCD, 0x13, 0x61, 0x61, 0x72, 0x0B, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5E, 0x0B, 0x49, 0x75, 0x06, 0xF8, 0xC3, 0x41, 0xBB, 0x00, 0x00, 0x60, 0x66, 0x6A, 0x00, 0xEB, 0xB0, 0x4E, 0x54, 0x4C, 0x44, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x4E, 0x54, 0x4C, 0x44, 0x52, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6E, 0x67, 0xFF, 0x0D, 0x0A, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0xFF, 0x0D, 0x0A, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xBF, 0xCC, 0x55, 0xAA }; */ { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x02, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0xF8, 0xFB, 0x00, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x01, 0x29, 0xBE, 0x48, 0x2D, 0xF8, 0x4E, 0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x33, 0xC9, 0x8E, 0xD1, 0xBC, 0xF0, 0x7B, 0x8E, 0xD9, 0xB8, 0x00, 0x20, 0x8E, 0xC0, 0xFC, 0xBD, 0x00, 0x7C, 0x38, 0x4E, 0x24, 0x7D, 0x24, 0x8B, 0xC1, 0x99, 0xE8, 0x3C, 0x01, 0x72, 0x1C, 0x83, 0xEB, 0x3A, 0x66, 0xA1, 0x1C, 0x7C, 0x26, 0x66, 0x3B, 0x07, 0x26, 0x8A, 0x57, 0xFC, 0x75, 0x06, 0x80, 0xCA, 0x02, 0x88, 0x56, 0x02, 0x80, 0xC3, 0x10, 0x73, 0xEB, 0x33, 0xC9, 0x8A, 0x46, 0x10, 0x98, 0xF7, 0x66, 0x16, 0x03, 0x46, 0x1C, 0x13, 0x56, 0x1E, 0x03, 0x46, 0x0E, 0x13, 0xD1, 0x8B, 0x76, 0x11, 0x60, 0x89, 0x46, 0xFC, 0x89, 0x56, 0xFE, 0xB8, 0x20, 0x00, 0xF7, 0xE6, 0x8B, 0x5E, 0x0B, 0x03, 0xC3, 0x48, 0xF7, 0xF3, 0x01, 0x46, 0xFC, 0x11, 0x4E, 0xFE, 0x61, 0xBF, 0x00, 0x00, 0xE8, 0xE6, 0x00, 0x72, 0x39, 0x26, 0x38, 0x2D, 0x74, 0x17, 0x60, 0xB1, 0x0B, 0xBE, 0xA1, 0x7D, 0xF3, 0xA6, 0x61, 0x74, 0x32, 0x4E, 0x74, 0x09, 0x83, 0xC7, 0x20, 0x3B, 0xFB, 0x72, 0xE6, 0xEB, 0xDC, 0xA0, 0xFB, 0x7D, 0xB4, 0x7D, 0x8B, 0xF0, 0xAC, 0x98, 0x40, 0x74, 0x0C, 0x48, 0x74, 0x13, 0xB4, 0x0E, 0xBB, 0x07, 0x00, 0xCD, 0x10, 0xEB, 0xEF, 0xA0, 0xFD, 0x7D, 0xEB, 0xE6, 0xA0, 0xFC, 0x7D, 0xEB, 0xE1, 0xCD, 0x16, 0xCD, 0x19, 0x26, 0x8B, 0x55, 0x1A, 0x52, 0xB0, 0x01, 0xBB, 0x00, 0x00, 0xE8, 0x3B, 0x00, 0x72, 0xE8, 0x5B, 0x8A, 0x56, 0x24, 0xBE, 0x0B, 0x7C, 0x8B, 0xFC, 0xC7, 0x46, 0xF0, 0x3D, 0x7D, 0xC7, 0x46, 0xF4, 0x29, 0x7D, 0x8C, 0xD9, 0x89, 0x4E, 0xF2, 0x89, 0x4E, 0xF6, 0xC6, 0x06, 0x96, 0x7D, 0xCB, 0xEA, 0x03, 0x00, 0x00, 0x20, 0x0F, 0xB6, 0xC8, 0x66, 0x8B, 0x46, 0xF8, 0x66, 0x03, 0x46, 0x1C, 0x66, 0x8B, 0xD0, 0x66, 0xC1, 0xEA, 0x10, 0xEB, 0x5E, 0x0F, 0xB6, 0xC8, 0x4A, 0x4A, 0x8A, 0x46, 0x0D, 0x32, 0xE4, 0xF7, 0xE2, 0x03, 0x46, 0xFC, 0x13, 0x56, 0xFE, 0xEB, 0x4A, 0x52, 0x50, 0x06, 0x53, 0x6A, 0x01, 0x6A, 0x10, 0x91, 0x8B, 0x46, 0x18, 0x96, 0x92, 0x33, 0xD2, 0xF7, 0xF6, 0x91, 0xF7, 0xF6, 0x42, 0x87, 0xCA, 0xF7, 0x76, 0x1A, 0x8A, 0xF2, 0x8A, 0xE8, 0xC0, 0xCC, 0x02, 0x0A, 0xCC, 0xB8, 0x01, 0x02, 0x80, 0x7E, 0x02, 0x0E, 0x75, 0x04, 0xB4, 0x42, 0x8B, 0xF4, 0x8A, 0x56, 0x24, 0xCD, 0x13, 0x61, 0x61, 0x72, 0x0B, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5E, 0x0B, 0x49, 0x75, 0x06, 0xF8, 0xC3, 0x41, 0xBB, 0x00, 0x00, 0x60, 0x66, 0x6A, 0x00, 0xEB, 0xB0, 0x4E, 0x54, 0x4C, 0x44, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x4E, 0x54, 0x4C, 0x44, 0x52, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6E, 0x67, 0xFF, 0x0D, 0x0A, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0xFF, 0x0D, 0x0A, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xBF, 0xCC, 0x55, 0xAA }; /* *THIS part is created according tro SD CARD file allocation system spec */ FATSYS_STRUCT gNandFATSYS ; UINT32 gNandFFBuffAddr; UINT8 gNandFileName[14] ; UINT8 gNFLASHBuf[512] ; extern UINT8 HD_NFlashWrite(UINT32 src_addr, UINT32 dst_addr) ; extern UINT8 HD_NFlashRead(UINT32 src_addr, UINT32 dst_addr) ; //cmd17 /*----------------------------------------------------------------------*/ /* * Function: NandValidFileChar() * DeSCRiption: Function to see if the character is a valid FILENAME character .please to refer microsoft datasheet * Calls: * Called By: * Table Accessed: * Table Updated: * Input: UINT8 file_char * Output: none * Return: true and false * Others: */ UINT8 NandValidFileChar(UINT8 file_char) { if (file_char < 0x20) { return (SW_PARA_ERR); } else if ((file_char == 0x22) || (file_char == 0x2A) || (file_char == 0x2B) || (file_char == 0x2C) || (file_char == 0x2E) || (file_char == 0x2F) || ((file_char >= 0x3A) && (file_char <= 0x3F)) || ((file_char >= 0x5B) && (file_char <= 0x5D)) || (file_char == 0x7C) || (file_char == 0xE5)) { return (SW_PARA_ERR); } else { return (SW_PARA_OK); } } /* * Function: clust_to_addr() * DeSCRiption: Convert a cluster number into a read address * Calls: * Called By: * Table Accessed: * Table Updated: * Input: UINT32 clust_no * Output: none * Return: UINT32 clust_addr * Others: */ UINT32 NandClusterToAddr(UINT16 clust_no) { UINT32 clust_addr; if (clust_no < 2) { return SW_PARA_ERR; } gNandFATSYS.FirstSectorofCluster = ((clust_no - 2) * (UINT32) gNandFATSYS.Bpb50.bpbSecPerClust) + (UINT32) gNandFATSYS.FirstDataSector; clust_addr = (UINT32) gNandFATSYS.FirstSectorofCluster * (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec + gNandFATSYS.PartitionAddr; return (clust_addr); } /* * Function: NandInitializeFat () * DeSCRiption: initial SD card and reads the card's partition table and * boot sector, storing the card information needed to * handle the file system * Calls: * Called By: * Table Accessed: * Table Updated: * Input: none * Output: none * Return: true and flase * Others: */ #define FAT_DEBUG UINT8 NandInitializeFat(void) { UINT32 i; UINT8 error = HW_ERR_NONE ; gNandFATSYS.Bpb50.bpbBytesPerSec = 512 ;// Initialize sector size to 512 (all SD cards have a 512 sector size) // *(unsigned int *) (0x4003002c) = 1 ; error = HD_NFlashRead(0,(UINT32) gNFLASHBuf) ; if (error != HW_ERR_NONE) { #ifdef _DEBUG_ON_ #endif return error; } // *(unsigned int *)(0x4003002c) = 0 ; //get the relative sector from partition table //gPartRecord.prStartLBA = ((UINT32) gNFLASHBuf[0x1c6] | (UINT32) gNFLASHBuf[0x1c7] << 8) ; gNandFATSYS.PartRecord.prStartLBA = ((UINT32) gNFLASHBuf[0x1c6] | (UINT32) gNFLASHBuf[0x1c7] << 8) ; if ((((gNFLASHBuf[0] == 0xEB) && (gNFLASHBuf[2] == 0x90)) || (gNFLASHBuf[0] == 0xE9)) && ((gNFLASHBuf[510] == 0x55) && (gNFLASHBuf[511] == 0xAA))) { //gPartRecord.prStartLBA = 0 ; gNandFATSYS.PartRecord.prStartLBA = 0; } gNandFATSYS.PartitionAddr = gNandFATSYS.PartRecord.prStartLBA * gNandFATSYS.Bpb50.bpbBytesPerSec; //GET THE PARTITION BOOT SECTOR ADDRESS if (gNandFATSYS.PartRecord.prStartLBA) { error = HD_NFlashRead(gNandFATSYS.PartitionAddr,(UINT32) gNFLASHBuf) ; if (error != HW_ERR_NONE) //READ THE FDC DESCRIPTOR //AND THE RESULT STORE IN gNFLASHBuf { #ifdef _DEBUG_ON_ #endif return error; } } gNandFATSYS.BootSector.bsJump[0] = gNFLASHBuf[0] ; /* jump inst E9xxxx or EBxx90 */ gNandFATSYS.BootSector.bsJump[1] = gNFLASHBuf[1] ; gNandFATSYS.BootSector.bsJump[2] = gNFLASHBuf[2] ; gNandFATSYS.Bpb50.bpbBytesPerSec = ((UINT16) gNFLASHBuf[0xC] << 8) | (UINT16) gNFLASHBuf[0xB]; /* bytes per sector (in sd card max=512bytes,so get the last two bytes)*/ gNandFATSYS.Bpb50.bpbSecPerClust = gNFLASHBuf[0xD] ; /* sectors per cluster */ gNandFATSYS.Bpb50.bpbResSectors = ((UINT16) gNFLASHBuf[0xF] << 8) | (UINT16) gNFLASHBuf[0xE]; /* number of reserved sectors */ gNandFATSYS.Bpb50.bpbFATs = (UINT8) gNFLASHBuf[0x10] ; /* number of FATs */ gNandFATSYS.Bpb50.bpbRootDirEnts = ((UINT16) gNFLASHBuf[0x12] << 8) | (UINT16) gNFLASHBuf[0x11]; /* number of root directory entries */ gNandFATSYS.Bpb50.bpbFATsecs = ((UINT16) gNFLASHBuf[0x17] << 8) | (UINT16) gNFLASHBuf[0x16]; /* number of sectors per FAT */ gNandFATSYS.Bpb50.bpbSectors = ((UINT16) gNFLASHBuf[0x14] << 8) | (UINT16) gNFLASHBuf[0x13]; //* total number of sectors 16bits */ //gFatTable.Total_FAT_Cluster_Number = (gBpb50.bpbFATsecs * gBpb50.bpbBytesPerSec / 2) ; if (gNandFATSYS.Bpb50.bpbSectors == 0) { gNandFATSYS.Bpb50.bpbHugeSectors = ((UINT32) gNFLASHBuf[0x23] << 24) //* total number of sectors 32bits */ | ((UINT32) gNFLASHBuf[0x22] << 16) | ((UINT32) gNFLASHBuf[0x21] << 8) | ((UINT32) gNFLASHBuf[0x20]); } gNandFATSYS.ExtBoot.exVolumeID[3] = gNFLASHBuf[0x2A] ; /* volume ID number */ gNandFATSYS.ExtBoot.exVolumeID[2] = gNFLASHBuf[0x29] ; gNandFATSYS.ExtBoot.exVolumeID[1] = gNFLASHBuf[0x28] ; gNandFATSYS.ExtBoot.exVolumeID[0] = gNFLASHBuf[0x27] ; for (i = 0; i < 11; i++) gNandFATSYS.ExtBoot.exVolumeLabel[i] = gNFLASHBuf[(0x2b + i)]; /* volume label */ //get the the first fat address gNandFATSYS.FAT1_addr = gNandFATSYS.PartitionAddr + (UINT32) gNandFATSYS.Bpb50.bpbResSectors * (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec; //gFatTable.FAT_Table_1 = (UINT32 *) gNandFATSYS.FAT1_addr ; //get the the second fat address gNandFATSYS.FAT2_addr = gNandFATSYS.FAT1_addr + (UINT32) gNandFATSYS.Bpb50.bpbFATsecs * (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec ; //gFatTable.FAT_Table_2 = (UINT32 *) gNandFATSYS.FAT2_addr ; //get the root directory address gNandFATSYS.RootAddr = (UINT32) gNandFATSYS.Bpb50.bpbFATs * (UINT32) gNandFATSYS.Bpb50.bpbFATsecs + gNandFATSYS.Bpb50.bpbResSectors; gNandFATSYS.RootAddr *= (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec; gNandFATSYS.RootAddr += gNandFATSYS.PartitionAddr; //determine the count of sectors occupied by the root directory: gNandFATSYS.RootDirSectors = ((gNandFATSYS.Bpb50.bpbRootDirEnts * 32) + gNandFATSYS.Bpb50.bpbBytesPerSec - 1) / gNandFATSYS.Bpb50.bpbBytesPerSec; //The start of the data region gNandFATSYS.FirstDataSector = (gNandFATSYS.Bpb50.bpbFATs * gNandFATSYS.Bpb50.bpbFATsecs) + gNandFATSYS.Bpb50.bpbResSectors + gNandFATSYS.RootDirSectors ; //get the data cluster total if (gNandFATSYS.Bpb50.bpbSectors != 0) { gNandFATSYS.DataClusTot = gNandFATSYS.Bpb50.bpbSectors - gNandFATSYS.FirstDataSector; } else { gNandFATSYS.DataClusTot = gNandFATSYS.Bpb50.bpbHugeSectors - gNandFATSYS.FirstDataSector; } gNandFATSYS.DataClusTot /= gNandFATSYS.Bpb50.bpbSecPerClust; //get the file allocation system infomation if (gNandFATSYS.DataClusTot < 4085) // FAT12 { gNandFATSYS.FAT_type = PART_TYPE_FAT12 ; } else if (gNandFATSYS.DataClusTot < 65525) // FAT16 { gNandFATSYS.FAT_type = PART_TYPE_FAT16 ; } else { gNandFATSYS.FAT_type = PART_TYPE_UNKNOWN ; return SW_PARA_ERR; } gNandFATSYS.DIR_adrr = gNandFATSYS.RootAddr; // Set current directory to root address return SW_PARA_OK; } /* * Function: NandNextCluster() * DeSCRiption: Find the cluster that the current cluster is pointing to * Calls: * Called By: * Table Accessed: * Table Updated: * Input: UINT32 current_cluster, UINT8 mode * Output: none * Return: true and false * Others: */ UINT16 NandNextCluster(UINT32 current_cluster) { UINT16 calc_sec, calc_offset, next_clust; UINT32 addr_temp; UINT8 error = HW_ERR_NONE ; if (current_cluster <= 1) // If cluster is 0 or 1, its the wrong cluster { return SW_PARA_ERR; } if (gNandFATSYS.FAT_type == PART_TYPE_FAT16) // if FAT16 { // FAT16 table address calculations calc_sec = current_cluster / (gNandFATSYS.Bpb50.bpbBytesPerSec / 2) + gNandFATSYS.Bpb50.bpbResSectors; calc_offset = 2 * (current_cluster % (gNandFATSYS.Bpb50.bpbBytesPerSec / 2)); addr_temp = gNandFATSYS.PartitionAddr + (calc_sec * 0x200); if (addr_temp != gNandFFBuffAddr) { error = HD_NFlashRead(addr_temp,(UINT32) gNFLASHBuf) ; if (error != HW_ERR_NONE) { return error; } } next_clust = (((UINT16) gNFLASHBuf[calc_offset + 1]) << 8) | gNFLASHBuf[calc_offset]; } else // not FAT12 or FAT16, return 0 { return SW_PARA_ERR; } return (next_clust); } /* * Function: NandQuickFormat * DeSCRiption: Quickformat of a card (erase cluster table and root directory) * Calls: * Called By: * Table Accessed: * Table Updated: * Input: * Output: * Return: * Others: */ UINT8 NandQuickFormat(void) { UINT16 c ; UINT32 temp_addr; UINT32 temp_addr1 ; UINT32 temp_addr2 ; UINT32 temp_addr3 ; UINT8 error = HW_ERR_NONE; for (c = 0; c < gNandFATSYS.Bpb50.bpbBytesPerSec; c++) // initialize gNFLASHBuf to all zero gNFLASHBuf[c] = 0; temp_addr = gNandFATSYS.FAT1_addr + 0x200; temp_addr3 = gNandFATSYS.RootAddr + (0x200 * gNandFATSYS.RootDirSectors); while (temp_addr < temp_addr3) { error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr) ; if (error != HW_ERR_NONE) { return error; } temp_addr += 0x200; } gNFLASHBuf[0] = 0xF8; gNFLASHBuf[1] = 0xFF; gNFLASHBuf[2] = 0xFF; if (gNandFATSYS.FAT_type == PART_TYPE_FAT16) { gNFLASHBuf[3] = 0xFF; } temp_addr1 = gNandFATSYS.FAT1_addr ; temp_addr2 = gNandFATSYS.FAT2_addr ; error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr1) ; if (error != HW_ERR_NONE) { return error ; } error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr2) ; if (error != HW_ERR_NONE) { return error ; } return HW_ERR_NONE; } /* * Function: NandFatTableRecord * DeSCRiption: this function is used to write the value(NextNum) to the position(CurNum), to update Fat table * Calls: * Called By: * Table Accessed: * Table Updated: * Input: * Output: * Return: * Others: */ UINT8 NandFatTableRecord(UINT16 CurNum, UINT16 NextNum) { UINT32 tmp_addr = 0 ; UINT32 tmp_addr1 = 0 ; UINT32 tmp_addr2 = 0 ; UINT16 offset = 0 ; UINT8 error = HW_ERR_NONE; tmp_addr = (CurNum * 2) / 512 ; offset = (CurNum * 2) % 512 ; tmp_addr1 = gNandFATSYS.FAT1_addr + tmp_addr * 256 ; tmp_addr2 = gNandFATSYS.FAT2_addr + tmp_addr * 256 ; error = HD_NFlashRead(tmp_addr1,(UINT32) (gNFLASHBuf)) ; if (error != HW_ERR_NONE) { return error ; } gNFLASHBuf[offset + 1] = (UINT8) ((NextNum & 0xff00) >> 8); gNFLASHBuf[offset] = (UINT8) (NextNum & 0x00ff) ; error = HD_NFlashWrite((UINT32) (gNFLASHBuf),tmp_addr1) ; if (error != HW_ERR_NONE) { return error ; } error = HD_NFlashWrite((UINT32) (gNFLASHBuf),tmp_addr2) ; if (error != HW_ERR_NONE) { return error ; } return TRUE ; } /* * Function: NandFileNameConversion() * DeSCRiption: this function is used to convert a constant string file name into the proper format * Calls: * Called By: * Table Accessed: * Table Updated: * Input: UINT8 *current_file * Output: none * Return: true and fasle * Others: */ UINT8 * NandFileNameConversion(UINT8 *current_file) { UINT8 n, c; UINT8 filename[14] ; c = 0; for (n = 0; n < 14; n++) { if (NandValidFileChar(current_file[n]) == TRUE) // If the character is valid, save in uppeRCAse to file name buffer { gNandFileName[c++] = toupper(current_file[n]); } else if (current_file[n] == '.') // If it is a period, back fill buffer with [spaces], till 8 characters deep { while (c < 8) gNandFileName[c++] = 0x20; } else if (current_file[n] == 0) { // If it is NULL, back fill buffer with [spaces], till 11 characters deep while (c < 11) gNandFileName[c++] = 0x20; break; } else { return FALSE; } if (c >= 11) { break; } } filename[c] = 0; // Return the pointer of the filename return (gNandFileName); } UINT32 NandGetFileEntry(INT8 *filename) { UINT8 n; UINT16 s, calc_temp; UINT32 addr_temp; UINT8 *sp, *qp; UINT8 error = HW_ERR_NONE ; // Get the filename into a form we can use to compare qp = NandFileNameConversion((UINT8 *) filename); if (qp == FALSE) //name error { return (FALSE); } for (s = 0; s < gNandFATSYS.Bpb50.bpbBytesPerSec; s++) { // Scan through directory entries to find file addr_temp = gNandFATSYS.DIR_adrr + (0x200 * s); error = HD_NFlashRead(addr_temp,(UINT32) gNFLASHBuf) ; if (error != HW_ERR_NONE) { return error; } for (n = 0; n < 16; n++) { calc_temp = (UINT16) n * 0x20; qp = &gNandFileName[0]; sp = &gNFLASHBuf[calc_temp]; if (*sp == 0) { return (FALSE); } if (strncmp((INT8 *)qp,(INT8 *)sp,11) == 0) // Does this entry == Filename { return (calc_temp + addr_temp); } } } return(FALSE); } /* * Function: FatParaCaculate * DeSCRiption: this function is used to calculate the format parameter according to the card capacivity * Calls: * Called By: * Table Accessed: * Table Updated: * Input: none * Output: gFsType ,gNFLASHBuf ,gBpb50 * Return: none * Others: */ #if 1 static void FatParaCaculate(void) { UINT16 nbHeads ; UINT16 SectorperTrack ; UINT8 SectorperCluster ; UINT32 HiddenSectors ; UINT32 totalsize ; UINT16 fatsec; UINT16 i ; gNandFATSYS.FAT_type = PART_TYPE_FAT16 ; nbHeads = 8 ; SectorperTrack = 2 ; SectorperCluster = 2 ; HiddenSectors = 39 ; totalsize = 125440 ; fatsec = 244 ; //junp command gNFLASHBuf[0] = 0xEB ; gNFLASHBuf[1] = 0x00 ; gNFLASHBuf[2] = 0x90 ; //system indentifier gNFLASHBuf[3] = 'V' ; // gNFLASHBuf[4] = 'I' ; // gNFLASHBuf[5] = 'A' ; // gNFLASHBuf[6] = 'T' ; // gNFLASHBuf[7] = 'E' ; // gNFLASHBuf[8] = 'C' ; // gNFLASHBuf[9] = 'T' ; // gNFLASHBuf[10] = 'H' ;// //sector size(bytes per sec ) gNFLASHBuf[11] = (UINT8) (512 & 0xff) ; gNFLASHBuf[12] = (UINT8) ((512 & 0xff00) >> 8); //sector per cluster gNFLASHBuf[13] = SectorperCluster ; //reserved sector count (for fat16 and fat12 this is 1 ) gNFLASHBuf[14] = (UINT8) (1 & 0x00ff) ; gNFLASHBuf[15] = 0 ; //number of fats gNFLASHBuf[16] = 2 ; //number of root directory entries gNFLASHBuf[17] = (UINT8) (512 & 0xff) ; gNFLASHBuf[18] = (UINT8) ((512 & 0xff00) >> 8); //total sectors (16bits) gNFLASHBuf[19] = 0 ; gNFLASHBuf[20] = 0 ; //medium indentifier gNFLASHBuf[21] = 0xf8 ; //sectors per fat gNFLASHBuf[22] = (UINT8) (fatsec & 0xff) ; gNFLASHBuf[23] = (UINT8) ((fatsec & 0xff00) >> 8); //sectors per track gNFLASHBuf[24] = (UINT8) (SectorperTrack & 0xff) ; gNFLASHBuf[25] = (UINT8) ((SectorperTrack & 0xff00) >> 8); //number of slide(head) gNFLASHBuf[26] = (UINT8) (nbHeads & 0xff) ; gNFLASHBuf[27] = (UINT8) ((nbHeads & 0xff00) >> 8); //number of hidden sectors gNFLASHBuf[28] = (UINT8) (HiddenSectors & 0x000000ff) ; gNFLASHBuf[29] = (UINT8) ((HiddenSectors & 0x0000ff00) >> 8); gNFLASHBuf[30] = (UINT8) ((HiddenSectors & 0x00ff0000) >> 16); gNFLASHBuf[31] = (UINT8) ((HiddenSectors & 0xff000000) >> 24); //total sectors (32bits) gNFLASHBuf[32] = (UINT8) (totalsize & 0x000000ff) ; gNFLASHBuf[33] = (UINT8) ((totalsize & 0x0000ff00) >> 8) ; gNFLASHBuf[34] = (UINT8) ((totalsize & 0x00ff0000) >> 16) ; gNFLASHBuf[35] = (UINT8) ((totalsize & 0xff000000) >> 24) ; //physical disk number gNFLASHBuf[36] = 0x80; //reserved gNFLASHBuf[37] = 0x00; //extend boot record signature gNFLASHBuf[38] = 0x29 ; //volume ID number gNFLASHBuf[39] = 0x01 ; gNFLASHBuf[40] = 0x23 ; gNFLASHBuf[41] = 0x45 ; gNFLASHBuf[42] = 0x67 ; //volume label for (i = 0 ; i < 11; i++) { gNFLASHBuf[43 + i] = (0x41 + i); } //a~a+10) //file system type gNFLASHBuf[54] = 'F' ; gNFLASHBuf[55] = 'A' ; gNFLASHBuf[56] = 'T' ; gNFLASHBuf[57] = '1' ; gNFLASHBuf[58] = '6' ; gNFLASHBuf[59] = 0 ; gNFLASHBuf[60] = 0 ; gNFLASHBuf[61] = 0 ; //not restricted for (i = 0 ; i < 448; i++) { gNFLASHBuf[62 + i] = 0; } //signature word gNFLASHBuf[510] = 0x55 ; gNFLASHBuf[511] = 0xaa ; gNandFATSYS.Bpb50.bpbBytesPerSec = 512 ; gNandFATSYS.Bpb50.bpbResSectors = 1 ; gNandFATSYS.Bpb50.bpbFATsecs = fatsec ; gNandFATSYS.Bpb50.bpbFATs = 2 ; gNandFATSYS.Bpb50.bpbRootDirEnts = 512 ; return ; } #endif /* * Function: FAT_Format(void) * DeSCRiption: format the sd card completely * Calls: * Called By: * Table Accessed: * Table Updated: * Input: none * Output: none * Return: true and false * Others: */ /*********************************************************************** *-Sector size is 512 bytes *-2 fats management *-512 entries in the root directory *---------------------------------------------------------------------------- *REQUIREMENTS : need to call initial ************************************************************************/ #if 1 UINT8 NandFATFormat(void) { UINT32 c, i; UINT32 temp_addr1 ; UINT32 temp_addr2 ; UINT8 error = HW_ERR_NONE; #if 0 FatParaCaculate() ; error = HD_NFlashWrite((UINT32) gNFLASHBuf, 0) ; //error =NFTL_Write(0, gNFLASHBuf) ; #endif #if 1 error = HD_NFlashWrite((UINT32) BPBTaBle,0) ; gNandFATSYS.Bpb50.bpbBytesPerSec = 512 ; gNandFATSYS.Bpb50.bpbResSectors = 1 ; gNandFATSYS.Bpb50.bpbFATsecs = 251 ; //255 gNandFATSYS.Bpb50.bpbFATs = 2 ; gNandFATSYS.Bpb50.bpbRootDirEnts = 512 ; #endif if (error != HW_ERR_NONE) { return error ; } gNandFATSYS.PartitionAddr = 0; //get the the first fat address gNandFATSYS.FAT1_addr = gNandFATSYS.PartitionAddr + (UINT32) gNandFATSYS.Bpb50.bpbResSectors * (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec; //get the the second fat address gNandFATSYS.FAT2_addr = gNandFATSYS.FAT1_addr + (UINT32) gNandFATSYS.Bpb50.bpbFATsecs * (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec ; //get the root directory address gNandFATSYS.RootAddr = (UINT32) gNandFATSYS.Bpb50.bpbFATs * (UINT32) gNandFATSYS.Bpb50.bpbFATsecs + gNandFATSYS.Bpb50.bpbResSectors; gNandFATSYS.RootAddr *= (UINT32) gNandFATSYS.Bpb50.bpbBytesPerSec; gNandFATSYS.RootAddr += gNandFATSYS.PartitionAddr; //determine the count of sectors occupied by the root directory: gNandFATSYS.RootDirSectors = ((gNandFATSYS.Bpb50.bpbRootDirEnts * 32) + gNandFATSYS.Bpb50.bpbBytesPerSec - 1) / gNandFATSYS.Bpb50.bpbBytesPerSec; for (c = 3; c < 512; c++) // initialize gNFLASHBuf to all zero { gNFLASHBuf[c] = 0; } gNFLASHBuf[0] = 0xF8; gNFLASHBuf[1] = 0xFF; gNFLASHBuf[2] = 0xFF; if (gNandFATSYS.FAT_type == PART_TYPE_FAT16) { gNFLASHBuf[3] = 0xFF; } temp_addr1 = gNandFATSYS.FAT1_addr ; temp_addr2 = gNandFATSYS.FAT2_addr ; error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr1) ; if (error != HW_ERR_NONE) { return error ; } error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr2) ; if (error != HW_ERR_NONE) { return error ; } gNFLASHBuf[0] = 0x0; gNFLASHBuf[1] = 0x0; gNFLASHBuf[2] = 0x0; gNFLASHBuf[3] = 0x0; for (i = 1 ; i < gNandFATSYS.Bpb50.bpbFATsecs ; i++) { temp_addr1 = gNandFATSYS.FAT1_addr + i * 0x200 ; temp_addr2 = gNandFATSYS.FAT2_addr + i * 0x200 ; error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr1) ; if (error != HW_ERR_NONE) { return error ; } error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr2) ; if (error != HW_ERR_NONE) { return error ; } } temp_addr1 = gNandFATSYS.RootAddr ; for (i = 0 ; i < gNandFATSYS.RootDirSectors ; i++) { error = HD_NFlashWrite((UINT32) gNFLASHBuf,temp_addr1) ; if (error != HW_ERR_NONE) { return error ; } temp_addr1 += 0x200 ; } return (TRUE); } #endif