blob: 06b50fb7208dc7dfefae4876391a2d31fb2e01fd [file] [log] [blame]
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/
#include "board.h"
#include "memories.h"
#include "diskio.h"
#include "integer.h"
#include "fatfs_config.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#define MAX_MEDS 1
extern Media medias[MAX_MEDS];
/*-----------------------------------------------------------------------*/
/* Initialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive number (0..) */
)
{
DSTATUS stat = STA_NOINIT;
switch (drv)
{
case DRV_SDRAM :
stat = 0;
break;
case DRV_MMC :
stat = 0;
break;
case DRV_NAND:
stat = 0;
break;
}
return stat;
}
/*-----------------------------------------------------------------------*/
/* Return Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive number (0..) */
)
{
DSTATUS stat=STA_NOINIT;
switch (drv)
{
case DRV_SDRAM :
stat = 0; // ok
break;
case DRV_MMC :
stat = 0; // ok
break;
case DRV_NAND:
stat = 0;
break;
}
return stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
unsigned char result;
DRESULT res = RES_ERROR;
unsigned int addr, len;
if (medias[drv].blockSize < SECTOR_SIZE_DEFAULT)
{
addr = sector * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
len = count * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
}
else
{
addr = sector;
len = count;
}
result = MED_Read(&medias[drv], addr, (void*)buff, len, NULL, NULL);
if( result == MED_STATUS_SUCCESS )
{
res = RES_OK;
}
else
{
TRACE_ERROR("MED_Read pb: 0x%X\n\r", result);
res = RES_ERROR;
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
/* The FatFs module will issue multiple sector transfer request
/ (count > 1) to the disk I/O layer. The disk function should process
/ the multiple sector transfer properly Do. not translate it into
/ multiple single sector transfers to the media, or the data read/write
/ performance may be drasticaly decreased. */
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive number (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
DRESULT res=RES_PARERR;
unsigned int result;
void * tmp;
tmp = (void *) buff;
unsigned int addr, len;
if (medias[drv].blockSize < SECTOR_SIZE_DEFAULT)
{
addr = sector * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
len = count * (SECTOR_SIZE_DEFAULT / medias[drv].blockSize);
}
else
{
addr = sector;
len = count;
}
result = MED_Write(&medias[drv], addr, (void*)tmp, len, NULL, NULL);
if( result == MED_STATUS_SUCCESS )
{
res = RES_OK;
}
else
{
TRACE_ERROR("MED_Write pb: 0x%X\n\r", result);
res = RES_ERROR;
}
return res;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
// Command Description
//
//CTRL_SYNC Make sure that the disk drive has finished pending write process.
// When the disk I/O module has a write back cache, flush the dirty sector immediately.
// In read-only configuration, this command is not needed.
//
//GET_SECTOR_COUNT Returns total sectors on the drive into the DWORD variable pointed by Buffer.
// This command is used in only f_mkfs function.
//
//GET_BLOCK_SIZE Returns erase block size of the memory array in unit
// of sector into the DWORD variable pointed by Buffer.
// When the erase block size is unknown or magnetic disk device, return 1.
// This command is used in only f_mkfs function.
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive number (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res=RES_PARERR;
switch (drv)
{
case DRV_SDRAM :
switch (ctrl)
{
case GET_BLOCK_SIZE:
*(DWORD*)buff = 1;
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if (medias[DRV_SDRAM].blockSize < SECTOR_SIZE_DEFAULT)
{
*(DWORD*)buff = (DWORD)(medias[DRV_SDRAM].size /
(SECTOR_SIZE_DEFAULT /
medias[DRV_SDRAM].blockSize));
}
else
{
*(DWORD*)buff = (DWORD)(medias[DRV_SDRAM].size);
}
res = RES_OK;
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
if (medias[DRV_SDRAM].blockSize < SECTOR_SIZE_DEFAULT)
{
*(WORD*)buff = SECTOR_SIZE_DEFAULT;
}
else
{
*(WORD*)buff = medias[DRV_SDRAM].blockSize;
}
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
res = RES_OK;
break;
default:
res = RES_PARERR;
}
break;
case DRV_MMC :
switch (ctrl)
{
case GET_BLOCK_SIZE:
*(DWORD*)buff = 1;
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if (medias[DRV_MMC].blockSize < SECTOR_SIZE_DEFAULT)
{
*(DWORD*)buff = (DWORD)(medias[DRV_MMC].size /
(SECTOR_SIZE_DEFAULT /
medias[DRV_MMC].blockSize));
}
else
{
*(DWORD*)buff = (DWORD)(medias[DRV_MMC].size);
}
res = RES_OK;
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
if (medias[DRV_MMC].blockSize < SECTOR_SIZE_DEFAULT)
{
*(WORD*)buff = SECTOR_SIZE_DEFAULT;
}
else
{
*(WORD*)buff = medias[DRV_MMC].blockSize;
}
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
res = RES_OK;
break;
default:
res = RES_PARERR;
}
break;
case DRV_NAND :
switch (ctrl)
{
case GET_BLOCK_SIZE:
*(DWORD*)buff = 1;
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if (medias[DRV_NAND].blockSize < SECTOR_SIZE_DEFAULT)
{
*(DWORD*)buff = (DWORD)(medias[DRV_NAND].size /
(SECTOR_SIZE_DEFAULT /
medias[DRV_NAND].blockSize));
}
else
{
*(DWORD*)buff = (DWORD)(medias[DRV_NAND].size);
}
res = RES_OK;
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
if (medias[DRV_NAND].blockSize < SECTOR_SIZE_DEFAULT)
{
*(WORD*)buff = SECTOR_SIZE_DEFAULT;
}
else
{
*(WORD*)buff = medias[DRV_NAND].blockSize;
}
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
MED_Flush(&medias[DRV_NAND]);
res = RES_OK;
break;
default:
res = RES_PARERR;
}
}
return res;
}
//------------------------------------------------------------------------------
/// Current time is returned with packed into a DWORD value.
/// The bit field is as follows:
/// bit31:25 Year from 1980 (0..127)
/// bit24:21 Month (1..12)
/// bit20:16 Day in month(1..31)
/// bit15:11 Hour (0..23)
/// bit10:5 Minute (0..59)
/// bit4:0 Second / 2 (0..29)
//------------------------------------------------------------------------------
DWORD get_fattime (void)
{
unsigned int time;
time = ((2010-1980)<<25)
| ( 9<<21)
| (15<<16)
| (17<<11)
| (45<<5)
| ((59/2)<<0);
return time;
}