⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avrfat16.c

📁 butterfly MP3源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**	@file	avrfat16.c	@brief	Fat16 Functions	@author	Nick Lott 	@date	September 2004	Copyright (C) 2004 Nick Lott <brokentoaster@sf.net>	This is a simple implementation of the FAT16 file system. It is designed	to be small for use with MP3 players and MMC cards. Currently it is 	readonly.NOTE: The code acknowledges only the first partition on the drive.		This program is free software; you can redistribute it and/or	modify it under the terms of the GNU General Public License	as published by the Free Software Foundation; either version 2	of the License, or (at your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software Foundation, 	Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.		Target(s)...: ATmega169	Compiler....: AVR-GCC 3.3.1; avr-libc 1.0**/#include <avr/io.h>#include <avr/pgmspace.h>#include <avr/interrupt.h>#include "types.h"#include "avrfat16.h"#include "utils.h"//void FAT_PrintRecord(uint8 *pRecord);/***   FAT_initFat16*	@brief		read MBR and bootsector and set global fat variables*	@return 	non zero for error.**/uint8 FAT_initFat16(void) {	uint8 	result,type,lba_begin,sectors_per_cluster,number_of_fats;	uint16	bytes_per_sector,number_of_reserved_sectors,BPB_RootEntCnt;	uint16	sectors_per_fat;		// Assume read and write routines have been setup and are not NULL :)		// read the first sector (MBR)	/*	check for 55 AA signature	Read Partition info at 		446+4 = type check it's a vfat etc		446+8..11 = LBA Begin		446+12..15 =# of Sectors	*/	result = FAT_read(0);		if (result)		return result; // abort on read error		if (FAT_buffer[510] != 0x55 || FAT_buffer[511] != 0xAA)		return 0xAA; // abort if signature bytes not found in MBR			type = FAT_buffer[PARTITION_START+4]; // get type code for partition one		// TODO: check here for valid MMC types ie FAT16 = 0x		// get start of FAT partition.	lba_begin = FAT_buffer[PARTITION_START+11];	lba_begin <<=8;		lba_begin += FAT_buffer[PARTITION_START+10];	lba_begin <<=8;		lba_begin += FAT_buffer[PARTITION_START+9];	lba_begin <<=8;		lba_begin += FAT_buffer[PARTITION_START+8];			/*	Read Boot Sector at lba Begin			bytes_per_sector at 0x0B			sectors_per_cluster at 0x0D			number_of_reserved_sectors at 0x0E			number_of_fats	at 0x10			secters_per_fat at 0x24			root_director_first_cluster 0x2c	*/		// read FAT Volume ID	result = FAT_read(lba_begin);	if (result) return result; // abort on read error		//if (FAT_buffer[510] != 0x55 || FAT_buffer[511] != 0xAA)	//	return 0xAA; // abort if signature bytes not found in MBR		sectors_per_cluster= FAT_buffer[0x0D];			number_of_reserved_sectors = FAT_buffer[ 0x0f];	number_of_reserved_sectors <<=8;	number_of_reserved_sectors += FAT_buffer[ 0x0e];		number_of_fats = FAT_buffer[0x10];		bytes_per_sector = FAT_buffer[0x0c];	bytes_per_sector <<=8;	bytes_per_sector += FAT_buffer[0x0b];	// BPB_FATSz16	sectors_per_fat = FAT_buffer[0x17];	sectors_per_fat <<=8;	sectors_per_fat += FAT_buffer[0x16];		//BPB_RootEntCnt	BPB_RootEntCnt = FAT_buffer[0x12];	BPB_RootEntCnt <<=8;	BPB_RootEntCnt += FAT_buffer[0x11];		/*	FOR FAT32....	sectors_per_fat = FAT_buffer[0x27];	sectors_per_fat <<=8;	sectors_per_fat += FAT_buffer[0x26];	sectors_per_fat <<=8;	sectors_per_fat += FAT_buffer[0x25];	sectors_per_fat <<=8;	sectors_per_fat += FAT_buffer[0x24];		root_director_first_cluster = FAT_buffer[0x2f];	root_director_first_cluster <<=8;	root_director_first_cluster += FAT_buffer[0x2e];	root_director_first_cluster <<=8;	root_director_first_cluster += FAT_buffer[0x2d];	root_director_first_cluster <<=8;	root_director_first_cluster += FAT_buffer[0x2c];	*/		// note: FAT16 clusters start after root directory.	FAT16_fat_begin_lba = lba_begin + number_of_reserved_sectors;	FAT16_root_dir_first_cluster = FAT16_fat_begin_lba + ( number_of_fats * sectors_per_fat);	FAT16_cluster_begin_lba = FAT16_root_dir_first_cluster+		((BPB_RootEntCnt*32) + (bytes_per_sector-1))/bytes_per_sector;	//	((BPB_RootEntCnt*32) + (bytes_per_sector))/bytes_per_sector;	FAT16_sectors_per_cluster = sectors_per_cluster;		FAT16_dir_first_cluster=FAT16_root_dir_first_cluster;	FAT16_parent_dir_first_cluster = FAT16_root_dir_first_cluster;		return 0;}/***   FAT_get_label*	@brief		copys the volume label*	@param		destentaion for label*	@return 	non zero for error.**/uint8 FAT_get_label(uint8 label[]){	uint8 result,i,j;		// read root dir	result = FAT_read(FAT16_root_dir_first_cluster);	if (result) return result; // abort on fail		// find entry with ATTR_VOLUME_ID	for (i=0;i<512/32;i++){		if (FAT_buffer[(i*32)+11] == FILE_ATTR_VOLUME_ID){			for (j=0;j<11;j++)				label[j]=FAT_buffer[(i*32)+j];			label[11]=0;			return 0;// we have a volume		}	}		return 1;		}/***   FAT_readCluster*	@brief		Reads a sector from a cluster into the buffer*	@param		cluster		Clusterto read from*	@param		sector_offset	Sector to read from within cluster*	@return		error code from FAT_read()**/uint8 FAT_readCluster(uint32 cluster, uint8 sector_offset) {	uint8	result=0;	uint32 lba_addr;		// calculate sector to read	lba_addr = FAT16_cluster_begin_lba + ((cluster-2) * FAT16_sectors_per_cluster);	lba_addr += sector_offset;		result = FAT_read(lba_addr);		return result;}/***   FAT_NextCluster*	@brief		looks up a cluster in fat*	@param		cluster 	current cluster*	@return		next cluster*	@return 	0 for error *	@return  	0xffffff for end of file.**/uint32 FAT_NextCluster(uint32 cluster){	uint8 result=0;	uint32 sector,position,next;		if (cluster ==0 ) cluster = 2; // check for reserved cluster mishap ;)		//sector = cluster / 128; 	sector = cluster / 256; // for fat 16		result = FAT_read(FAT16_fat_begin_lba+sector);	if (result) return 0;		//position = (cluster - (sector * 128)) * 4; for fat 32	position = (cluster - (sector * 256)) * 2; // for fat 16		/*	// read 4 bytes (FAT32)	next = FAT_buffer[position+3];	next <<= 8;	next += FAT_buffer[position+2];	next <<= 8;	next = FAT_buffer[position+1];	next <<= 8;	next += FAT_buffer[position];	*/		// read 2 Bytes (FAT16)	next = FAT_buffer[position+1];	next <<= 8;	next += FAT_buffer[position];	// mask off last 4 bits (FAT32)	// next &= 0x0ffffff;		if (next == 0xffff) next = 0xffffffff;		return next;}/***   FAT_read *	@param		filenumber 32bit uInt pointing to file of interst. *	@param		dir_first_entry 32bit uInt pointing to first cluster of directory *	@return		error code * *	Read any directory of the disk and obtain details  *	about FAT entry number <filenumber> * *	error codes: *	0x00	mp3file found *	0x02	end of directory *	0x59	deleted file * **/uint8	FAT_readFile(uint32 filenumber, uint32 dir_first_cluster){	uint8 result,i,lfn;	uint8 record,lfn_record,nmeChkSm,lfnchksm;	uint8 attrib;	uint16 lfn_entry,fat_entry; // position in buffer of entry 0-512	uint32 sector,lfn_sector;//	uint16 cluster;//	uint32 size;	record = filenumber & 0x0F;	sector = filenumber >> 4;	fat_entry =	record << 5;		// read the root dir	result = FAT_read(dir_first_cluster+sector);	if (result) return result; // abort on non-zero reply 	// check firstByte	if (FAT_buffer[fat_entry] == 0x00){ // end of directory		FAT16_entryMAX = filenumber;		return 2;	}	else if (FAT_buffer[fat_entry] != 0xe5){ // not used (aka deleted)				// exit on . and ..		if (FAT_buffer[fat_entry]=='.')			return 0x59;				// get the attrib byte		attrib = FAT_buffer[fat_entry+FAT16_LDIR_Attr];		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -