Beispiel #1
0
FRESULT pf_read (
	void* dest,		/* Pointer to the destination object */
	WORD btr,		/* Number of bytes to read (bit15:destination) */
	WORD* br		/* Pointer to number of bytes read */
)
{
	DRESULT dr;
	CLUST clst;
	DWORD sect, remain;
	WORD rcnt;
	BYTE *rbuff = dest;
	FATFS *fs = FatFs;


	*br = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_READ))
			return FR_INVALID_OBJECT;

	remain = fs->fsize - fs->fptr;
	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */

	for ( ;  btr;									/* Repeat until all data transferred */
		rbuff += rcnt, fs->fptr += rcnt, *br += rcnt, btr -= rcnt) {
		if ((fs->fptr % 512) == 0) {				/* On the sector boundary? */
			if ((fs->fptr / 512 % fs->csize) == 0) {	/* On the cluster boundary? */
				clst = (fs->fptr == 0) ?			/* On the top of the file? */
					fs->org_clust : get_fat(fs->curr_clust);
				if (clst <= 1) {
					fs->flag = 0; return FR_DISK_ERR;
				}
				fs->curr_clust = clst;				/* Update current cluster */
				fs->csect = 0;						/* Reset sector offset in the cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) {
				fs->flag = 0; return FR_DISK_ERR;
			}
			sect += fs->csect;
			fs->dsect = sect;
			fs->csect++;							/* Next sector address in the cluster */
		}
		rcnt = 512 - ((WORD)fs->fptr % 512);		/* Get partial sector data from sector buffer */
		if (rcnt > btr) rcnt = btr;
		if (fs->flag & FA_STREAM) {
			dr = disk_readp(dest, fs->dsect, (WORD)(fs->fptr % 512), (WORD)(rcnt | 0x8000));
		} else {
			dr = disk_readp(rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
		}
		if (dr) {
			fs->flag = 0;
			return (dr == RES_STRERR) ? FR_STREAM_ERR : FR_DISK_ERR;
		}
	}

	return FR_OK;
}
Beispiel #2
0
static
FRESULT dir_read (
	DIR *dj,		/* Pointer to the directory object to store read object name */
	BYTE *dir		/* 32-byte working buffer */
)
{
	FRESULT res;
	BYTE a, c;


	res = FR_NO_FILE;
	while (dj->sect) {
		res = disk_readp(dir, dj->sect, (dj->index % 16) * 32, 32)	/* Read an entry */
			? FR_DISK_ERR : FR_OK;
		if (res != FR_OK) break;
		c = dir[DIR_Name];
		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
		a = dir[DIR_Attr] & AM_MASK;
		if (c != 0xE5 && c != '.' && !(a & AM_VOL))	/* Is it a valid entry? */
			break;
		res = dir_next(dj);			/* Next entry */
		if (res != FR_OK) break;
	}

	if (res != FR_OK) dj->sect = 0;

	return res;
}
Beispiel #3
0
static
FRESULT dir_find (
	DIR *dj,		/* Pointer to the directory object linked to the file name */
	BYTE *dir		/* 32-byte working buffer */
)
{
	FRESULT res;
	BYTE c;


	res = dir_rewind(dj);			/* Rewind directory object */
	if (res != FR_OK) return res;

	do {
		res = disk_readp(dir, dj->sect, (dj->index % 16) * 32, 32)	/* Read an entry */
			? FR_DISK_ERR : FR_OK;
		if (res != FR_OK) break;
		c = dir[DIR_Name];	/* First character */
		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
		if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
			break;
		res = dir_next(dj);					/* Next entry */
	} while (res == FR_OK);

	return res;
}
Beispiel #4
0
static
BYTE check_fs (	/* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
	BYTE *buf,	/* Working buffer */
	DWORD sect	/* Sector# (lba) to check if it is an FAT boot record or not */
)
{
	if (disk_readp(buf, sect, 510, 2))		/* Read the boot sector */
		return 3;
	if (LD_WORD(buf) != 0xAA55)				/* Check record signature */
		return 2;
	if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146)	/* Check FAT12/16 */
		return 0;
	if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146)	/* Check FAT32 */
		return 0;
	return 1;
}
Beispiel #5
0
static
FRESULT dir_find (
	DIR *dj,		/* Pointer to the directory object linked to the file name */
	BYTE *dir		/* 32-byte working buffer */
)
{
	FRESULT res;
	BYTE c;


	res = dir_rewind(dj);			/* Rewind directory object */
	if (res != FR_OK) return res;

	do {
		if ( (dj->index & 7) == 0 )
		{ // Need to read data
			res = disk_readp( Abuff.DirBuffer, dj->sect, (WORD)((dj->index & 8) * 32), 256)	/* Read half a sector */
				? FR_DISK_ERR : FR_OK;
		}
		else
		{
			res = FR_OK ;
		}
		if (res != FR_OK) break;
		memcpy( dir, &Abuff.DirBuffer[((dj->index % 8) * 32)], 32 ) ;
		c = dir[DIR_Name];	/* First character */
		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
		if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
			break;
		res = dir_next(dj);					/* Next entry */
	} while (res == FR_OK);

	return res;
}
Beispiel #6
0
static
FRESULT dir_read (
	DIR *dj,		/* Pointer to the directory object to store read object name */
	BYTE *dir,		/* 32-byte working buffer */
	char *lfn_buffer        /* 256-byte lfn buffer */
)
{
	FRESULT res;
	BYTE a, c;

	int lfn = 0;
	char *lfn_pos = &lfn_buffer[255];
	lfn_buffer[255] = '\0';

	res = FR_NO_FILE;
	while (dj->sect) {
		res = disk_readp(dir, dj->sect, (dj->index % 16) * 32, 32)	/* Read an entry */
			? FR_DISK_ERR : FR_OK;
		if (res != FR_OK) break;
		c = dir[DIR_Name];
		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
		a = dir[DIR_Attr] & AM_MASK;

	//	printf("LFN2:%x:%x:%x:%x\n",a&AM_LFN==AM_LFN,dir[0],dir[0x1a],dir[0x1c]);
		if (a&AM_LFN == AM_LFN && ((dir[0]&0xbf) < 16) && dir[0x1a]==0) // && dir[0x1c]!=0)
		{
			lfn_pos-=13;
			char * ptr = lfn_pos;
			int i;
			for (i=1;i!=32;i+=2)
			{
				if (i==0xb) i=0xe;
				if (i==0x1a) i=0x1c;
				char b1 = dir[i];
				char b2 = dir[i+1];
				if (b2==0) *ptr++ = b1; else *ptr++ = '_';
			}
			//printf("LFN seq:%d %c%c%c%c%c%c%c%c%c%c%c%c%c \n",dir[0],dir[1],dir[3],dir[5],dir[7],dir[9],dir[14],dir[16],dir[18],dir[20],dir[22],dir[24],dir[28],dir[30]);
			lfn = 1;
		}


		if (c != 0xE5 && c != '.' && !(a & AM_VOL))	/* Is it a valid entry? */
			break;
		res = dir_next2(dj);			/* Next entry */
		if (res != FR_OK) break;
	}

	lfn_buffer[0] = '\0';
	if (lfn)
	{
		strcpy(&lfn_buffer[0],lfn_pos);
	}

	if (res != FR_OK) dj->sect = 0;

	return res;
}
Beispiel #7
0
static
CLUST get_fat (	/* 1:IO error, Else:Cluster status */
    CLUST clst	/* Cluster# to get the link information */
)
{
    BYTE buf[4];
    FATFS *fs = FatFs;

    if (clst < 2 || clst >= fs->n_fatent)	/* Range check */
        return 1;

    switch (fs->fs_type) {
#if _FS_FAT12
    case FS_FAT12 : {
        UINT wc, bc, ofs;

        bc = (UINT)clst;
        bc += bc / 2;
        ofs = bc % 512;
        bc /= 512;
        if (ofs != 511) {
            if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
        } else {
            if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
            if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
        }
        wc = LD_WORD(buf);
        return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
    }
#endif
#if _FS_FAT16
    case FS_FAT16 :
        if (disk_readp(buf, fs->fatbase + clst / 256, ((UINT)clst % 256) * 2, 2)) break;
        return LD_WORD(buf);
#endif
#if _FS_FAT32
    case FS_FAT32 :
        if (disk_readp(buf, fs->fatbase + clst / 128, ((UINT)clst % 128) * 4, 4)) break;
        return LD_DWORD(buf) & 0x0FFFFFFF;
#endif
    }

    return 1;	/* An error occured at the disk I/O layer */
}
Beispiel #8
0
FRESULT pf_read (
	void* buff,		/* Pointer to the read buffer (NULL:Forward data to the stream)*/
	WORD btr,		/* Number of bytes to read */
	WORD* br		/* Pointer to number of bytes read */
)
{
	DRESULT dr;
	CLUST clst;
	DWORD sect, remain;
	WORD rcnt;
	BYTE cs, *rbuff = buff;
	FATFS *fs = FatFs;


	*br = 0;
	if (!fs) return FR_NOT_ENABLED;		/* Check file system */
	if (!(fs->flag & FA_OPENED))		/* Check if opened */
		return FR_NOT_OPENED;

	remain = fs->fsize - fs->fptr;
	if (btr > remain) btr = (WORD)remain;			/* Truncate btr by remaining bytes */

	while (btr)	{									/* Repeat until all data transferred */
		if ((fs->fptr % 512) == 0) {				/* On the sector boundary? */
			cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));	/* Sector offset in the cluster */
			if (!cs) {								/* On the cluster boundary? */
				clst = (fs->fptr == 0) ?			/* On the top of the file? */
					fs->org_clust : get_fat(fs->curr_clust);
				if (clst <= 1) goto fr_abort;
				fs->curr_clust = clst;				/* Update current cluster */
			}
			sect = clust2sect(fs->curr_clust);		/* Get current sector */
			if (!sect) goto fr_abort;
			fs->dsect = sect + cs;
		}
		rcnt = (WORD)(512 - (fs->fptr % 512));		/* Get partial sector data from sector buffer */
		if (rcnt > btr) rcnt = btr;
		dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
		if (dr) goto fr_abort;
		fs->fptr += rcnt; rbuff += rcnt;			/* Update pointers and counters */
		btr -= rcnt; *br += rcnt;
	}

	return FR_OK;

fr_abort:
	fs->flag = 0;
	return FR_DISK_ERR;
}
Beispiel #9
0
FRESULT pf_read (
        FATFS* fs,          /* Filesystem descriptor */
        void* buff,		/* Pointer to the read buffer (NULL:Forward data to the stream)*/
        UINT btr,		/* Number of bytes to read */
        UINT* br		/* Pointer to number of bytes read */
        )
{
    DRESULT dr;
    CLUST clst;
    DWORD sect, remain;
    UINT rcnt;
    BYTE cs, *rbuff = buff;


    *br = 0;
    if (!fs) return FR_NOT_ENABLED;		/* Check file system */
    if (!(fs->flag & FA_OPENED))		/* Check if opened */
        return FR_NOT_OPENED;

    remain = fs->fsize - fs->fptr;
    if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */

    while (btr)	{									/* Repeat until all data transferred */
        if ((fs->fptr % 512) == 0) {				/* On the sector boundary? */
            cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));	/* Sector offset in the cluster */
            if (!cs) {								/* On the cluster boundary? */
                if (fs->fptr == 0)					/* On the top of the file? */
                    clst = fs->org_clust;
                else
                    clst = get_fat(fs, fs->curr_clust);
                if (clst <= 1) ABORT(FR_DISK_ERR);
                fs->curr_clust = clst;				/* Update current cluster */
            }
            sect = clust2sect(fs, fs->curr_clust);		/* Get current sector */
            if (!sect) ABORT(FR_DISK_ERR);
            fs->dsect = sect + cs;
        }
        rcnt = 512 - (UINT)fs->fptr % 512;			/* Get partial sector data from sector buffer */
        if (rcnt > btr) rcnt = btr;
        dr = disk_readp(&fs->disk, !buff ? 0 : rbuff, fs->dsect, (UINT)fs->fptr % 512, rcnt);
        if (dr) ABORT(FR_DISK_ERR);
        fs->fptr += rcnt; rbuff += rcnt;			/* Update pointers and counters */
        btr -= rcnt; *br += rcnt;
    }

    return FR_OK;
}
Beispiel #10
0
static FRESULT dir_read(DIR *dj)
{
    FRESULT res;
    u8 adir,c,*dir;
    
	res = FR_NO_FILE;
	dir = FatFs->buf;
	while (dj->sect) {
		res = disk_readp(dir, dj->sect, (u16)((dj->index % 16) * 32), 32)	/* Read an entry */
			? FR_DISK_ERR : FR_OK;
		if (res != FR_OK) break;
		c = dir[DIR_Name];
		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
		adir = dir[DIR_Attr] & AM_MASK;
		if (c != 0xE5 && c != '.' && !(adir & AM_VOL))	/* Is it a valid entry? */
			break;
		res = dir_next(dj);				/* Next entry */
		if (res != FR_OK) break;
	}

	if (res != FR_OK) dj->sect = 0;

	return res;
}
Beispiel #11
0
FRESULT pf_mount (
	FATFS *fs		/* Pointer to new file system object */
)
{
	BYTE fmt, buf[36] = {0};
	DWORD bsect, fsize, tsect, mclst;


	FatFs = 0;

	if (disk_initialize() & STA_NOINIT)	/* Check if the drive is ready or not */
		return FR_NOT_READY;

	/* Search FAT partition on the drive */
	bsect = 0;
	fmt = check_fs(buf, bsect);			/* Check sector 0 as an SFD format */
	if (fmt == 1) {						/* Not an FAT boot record, it may be FDISK format */
		/* Check a partition listed in top of the partition table */
		if (disk_readp(buf, bsect, MBR_Table, 16)) {	/* 1st partition entry */
			fmt = 3;
		} else {
			if (buf[4]) {					/* Is the partition existing? */
				bsect = LD_DWORD(&buf[8]);	/* Partition offset in LBA */
				fmt = check_fs(buf, bsect);	/* Check the partition */
			}
		}
	}
	if (fmt == 3) return FR_DISK_ERR;
	if (fmt) return FR_NO_FILESYSTEM;	/* No valid FAT patition is found */

	/* Initialize the file system object */
	if (disk_readp(buf, bsect, 13, sizeof (buf))) return FR_DISK_ERR;

	fsize = LD_WORD(buf+BPB_FATSz16-13);				/* Number of sectors per FAT */
	if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);

	fsize *= buf[BPB_NumFATs-13];						/* Number of sectors in FAT area */
	fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
	fs->csize = buf[BPB_SecPerClus-13];					/* Number of sectors per cluster */
	fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13);		/* Nmuber of root directory entries */
	tsect = LD_WORD(buf+BPB_TotSec16-13);				/* Number of sectors on the file system */
	if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
	mclst = (tsect						/* Last cluster# + 1 */
		- LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
		) / fs->csize + 2;
	fs->n_fatent = (CLUST)mclst;

	fmt = 0;							/* Determine the FAT sub type */
	if (_FS_FAT12 && mclst < 0xFF7)
		fmt = FS_FAT12;
	if (_FS_FAT16 && mclst >= 0xFF8 && mclst < 0xFFF7)
		fmt = FS_FAT16;
	if (_FS_FAT32 && mclst >= 0xFFF7)
		fmt = FS_FAT32;
	if (!fmt) return FR_NO_FILESYSTEM;
	fs->fs_type = fmt;

	if (_FS_32ONLY || (_FS_FAT32 && fmt == FS_FAT32))
		fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13));	/* Root directory start cluster */
	else
		fs->dirbase = fs->fatbase + fsize;				/* Root directory start sector (lba) */
	fs->database = fs->fatbase + fsize + fs->n_rootdir / 16;	/* Data start sector (lba) */

	fs->flag = 0;
	FatFs = fs;

	return FR_OK;
}