blob: ccc232475df653f7a82d18f217439d7d85e34e58 [file] [log] [blame]
/*
* FreeRTOS+FAT SL V1.0.1 (C) 2014 HCC Embedded
*
* The FreeRTOS+FAT SL license terms are different to the FreeRTOS license
* terms.
*
* FreeRTOS+FAT SL uses a dual license model that allows the software to be used
* under a standard GPL open source license, or a commercial license. The
* standard GPL license (unlike the modified GPL license under which FreeRTOS
* itself is distributed) requires that all software statically linked with
* FreeRTOS+FAT SL is also distributed under the same GPL V2 license terms.
* Details of both license options follow:
*
* - Open source licensing -
* FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and
* distributed without charge provided the user adheres to version two of the
* GNU General Public License (GPL) and does not remove the copyright notice or
* this text. The GPL V2 text is available on the gnu.org web site, and on the
* following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
*
* - Commercial licensing -
* Businesses and individuals who for commercial or other reasons cannot comply
* with the terms of the GPL V2 license must obtain a commercial license before
* incorporating FreeRTOS+FAT SL into proprietary software for distribution in
* any form. Commercial licenses can be purchased from
* http://shop.freertos.org/fat_sl and do not require any source files to be
* changed.
*
* FreeRTOS+FAT SL is distributed in the hope that it will be useful. You
* cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as
* is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the
* implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all
* conditions and terms, be they implied, expressed, or statutory.
*
* http://www.FreeRTOS.org
* http://www.FreeRTOS.org/FreeRTOS-Plus
*
*/
#include "../../api/fat_sl.h"
#include "../../psp/include/psp_string.h"
#include "drv.h"
#include "util.h"
#include "volume.h"
#include "../../version/ver_fat_sl.h"
#if VER_FAT_SL_MAJOR != 5 || VER_FAT_SL_MINOR != 2
#error Incompatible FAT_SL version number!
#endif
F_DRIVER * mdrv = NULL; /* driver structure */
/****************************************************************************
*
* _f_checkstatus
*
* checking a volume driver status, if media is removed or has been changed
*
* RETURNS
*
* error code or zero if successful
*
***************************************************************************/
unsigned char _f_checkstatus ( void )
{
if ( mdrv->getstatus != NULL )
{
if ( mdrv->getstatus( mdrv ) & ( F_ST_MISSING | F_ST_CHANGED ) )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/
return F_ERR_CARDREMOVED;
}
}
return F_NO_ERROR;
}
/****************************************************************************
*
* _f_writesector
*
* write sector data on a volume, it calls low level driver function, it
* writes a complete sector
*
* INPUTS
* sector - which physical sector
*
* RETURNS
* error code or zero if successful
*
***************************************************************************/
unsigned char _f_writeglsector ( unsigned long sector )
{
unsigned char retry;
if ( mdrv->writesector == NULL )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*no write function*/
return F_ERR_ACCESSDENIED;
}
if ( sector == (unsigned long)-1 )
{
if ( gl_file.modified )
{
sector = gl_file.pos.sector;
}
else
{
sector = gl_volume.actsector;
}
}
if ( sector != (unsigned long)-1 )
{
if ( mdrv->getstatus != NULL )
{
unsigned int status;
status = mdrv->getstatus( mdrv );
if ( status & ( F_ST_MISSING | F_ST_CHANGED ) )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/
return F_ERR_CARDREMOVED;
}
if ( status & ( F_ST_WRPROTECT ) )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/
return F_ERR_WRITEPROTECT;
}
}
gl_volume.modified = 0;
gl_file.modified = 0;
gl_volume.actsector = sector;
for ( retry = 3 ; retry ; retry-- )
{
int mdrv_ret;
mdrv_ret = mdrv->writesector( mdrv, (unsigned char *)gl_sector, sector );
if ( !mdrv_ret )
{
return F_NO_ERROR;
}
if ( mdrv_ret == -1 )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/
return F_ERR_CARDREMOVED;
}
}
}
return F_ERR_ONDRIVE;
} /* _f_writeglsector */
/****************************************************************************
*
* _f_readsector
*
* read sector data from a volume, it calls low level driver function, it
* reads a complete sector
*
* INPUTS
* sector - which physical sector is read
*
* RETURNS
* error code or zero if successful
*
***************************************************************************/
unsigned char _f_readglsector ( unsigned long sector )
{
unsigned char retry;
unsigned char ret;
if ( sector == gl_volume.actsector )
{
return F_NO_ERROR;
}
if ( gl_volume.modified || gl_file.modified )
{
ret = _f_writeglsector( (unsigned long)-1 );
if ( ret )
{
return ret;
}
}
for ( retry = 3 ; retry ; retry-- )
{
int mdrv_ret;
mdrv_ret = mdrv->readsector( mdrv, (unsigned char *)gl_sector, sector );
if ( !mdrv_ret )
{
gl_volume.actsector = sector;
return F_NO_ERROR;
}
if ( mdrv_ret == -1 )
{
gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/
return F_ERR_CARDREMOVED;
}
}
gl_volume.actsector = (unsigned long)-1;
return F_ERR_ONDRIVE;
} /* _f_readglsector */