2016-11-09 00:56:41 +00:00
/*
* flash_eep . c
*
* Created on : 19 / 01 / 2015
* Port RTL87xx : 15 / 10 / 16
* Author : pvvx
*/
# include <rtl8195a.h>
//#include <FreeRTOS.h>
//#include <queue.h>
# include <osdep_api.h>
# include <osdep_service.h>
# include "device_lock.h"
# include "flash_api.h"
# include "flash_eep.h"
//-----------------------------------------------------------------------------
# ifdef CONFIG_DEBUG_LOG
# define DEBUGSOO CONFIG_DEBUG_LOG
# else
# define DEBUGSOO 0
# endif
# define mMIN(a, b) ((a < b)? a : b)
# define align(a) ((a + 3) & 0xFFFFFFFC)
typedef union // заголовок объекта сохранения feep
{
struct {
2017-02-01 11:33:55 +00:00
unsigned short size ;
unsigned short id ;
2016-11-09 00:56:41 +00:00
} __attribute__ ( ( packed ) ) n ;
2017-02-01 11:33:55 +00:00
unsigned int x ;
2016-11-09 00:56:41 +00:00
} __attribute__ ( ( packed ) ) fobj_head ;
# define fobj_head_size 4
# define fobj_x_free 0xffffffff
# define MAX_FOBJ_SIZE 512 // максимальный размер сохраняемых о б ъeкто в
# define FMEM_ERROR_MAX 5
//-----------------------------------------------------------------------------
flash_t flash ;
//QueueHandle_t flash_mutex;
//-----------------------------------------------------------------------------
/*-------------------------------------------------------------------------------------
К о п и р у е т д а н н ы е и з о б л а с т и align ( 4 ) ( flash , registers , . . . ) в о б л а с т ь align ( 1 ) ( ram )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void FLASH_EEP_ATTR copy_align4_to_align1 ( unsigned char * pd , void * ps , unsigned int len )
{
union {
unsigned char uc [ 4 ] ;
unsigned int ud ;
} tmp ;
unsigned int * p = ( unsigned int * ) ( ( unsigned int ) ps & ( ~ 3 ) ) ;
unsigned int xlen = ( unsigned int ) ps & 3 ;
// unsigned int size = len;
if ( xlen ) {
tmp . ud = * p + + ;
while ( len ) {
len - - ;
* pd + + = tmp . uc [ xlen + + ] ;
if ( xlen & 4 ) break ;
}
}
xlen = len > > 2 ;
while ( xlen ) {
tmp . ud = * p + + ;
* pd + + = tmp . uc [ 0 ] ;
* pd + + = tmp . uc [ 1 ] ;
* pd + + = tmp . uc [ 2 ] ;
* pd + + = tmp . uc [ 3 ] ;
xlen - - ;
}
if ( len & 3 ) {
tmp . ud = * p ;
pd [ 0 ] = tmp . uc [ 0 ] ;
if ( len & 2 ) {
pd [ 1 ] = tmp . uc [ 1 ] ;
if ( len & 1 ) {
pd [ 2 ] = tmp . uc [ 2 ] ;
}
}
}
// return size;
}
/*------------------------------------------------------------------------------------
К о п и р у е т д а н н ы е и з о б л а с т и align ( 1 ) ( ram ) в о б л а с т ь align ( 4 ) ( flash , registers )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void FLASH_EEP_ATTR copy_align1_to_align4 ( void * pd , unsigned char * ps , unsigned int len )
{
union {
unsigned char uc [ 4 ] ;
unsigned int ud ;
} tmp ;
unsigned int * p = ( unsigned int * ) ( ( ( unsigned int ) pd ) & ( ~ 3 ) ) ;
unsigned int xlen = ( unsigned int ) pd & 3 ;
// unsigned int size = len;
if ( xlen ) {
tmp . ud = * p ;
while ( len ) {
len - - ;
tmp . uc [ xlen + + ] = * ps + + ;
if ( xlen & 4 ) break ;
}
* p + + = tmp . ud ;
}
xlen = len > > 2 ;
while ( xlen ) {
tmp . uc [ 0 ] = * ps + + ;
tmp . uc [ 1 ] = * ps + + ;
tmp . uc [ 2 ] = * ps + + ;
tmp . uc [ 3 ] = * ps + + ;
* p + + = tmp . ud ;
xlen - - ;
}
if ( len & 3 ) {
tmp . ud = * p ;
tmp . uc [ 0 ] = ps [ 0 ] ;
if ( len & 2 ) {
tmp . uc [ 1 ] = ps [ 1 ] ;
if ( len & 1 ) {
tmp . uc [ 2 ] = ps [ 2 ] ;
}
}
* p = tmp . ud ;
}
// return size;
}
/*------------------------------------------------------------------------------------
З а п и с ь б а й т а в о б л а с т ь align ( 4 ) ( flash , registers )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void FLASH_EEP_ATTR write_align4_chr ( unsigned char * pd , unsigned char c )
{
union {
unsigned char uc [ 4 ] ;
unsigned int ud ;
} tmp ;
unsigned int * p = ( unsigned int * ) ( ( unsigned int ) pd & ( ~ 3 ) ) ;
unsigned int xlen = ( unsigned int ) pd & 3 ;
tmp . ud = * p ;
tmp . uc [ xlen ] = c ;
* p = tmp . ud ;
}
/*------------------------------------------------------------------------------------
Ч т е н и е б а й т а и з о б л а с т и align ( 4 ) ( flash , registers )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
unsigned char FLASH_EEP_ATTR get_align4_chr ( const unsigned char * ps )
{
return ( * ( ( unsigned int * ) ( ( unsigned int ) ps & ( ~ 3 ) ) ) ) > > ( ( ( unsigned int ) ps & 3 ) < < 3 ) ;
}
/*------------------------------------------------------------------------------------
С р а в н е н и е д а н н ы х в о б л а с т и align ( 4 ) ( flash , registers , . . . ) с о б л а с т ь ю align ( 1 ) ( ram )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int FLASH_EEP_ATTR cmp_align1_align4 ( unsigned char * pd , void * ps , unsigned int len )
{
union {
unsigned char uc [ 4 ] ;
unsigned int ud ;
} tmp ;
unsigned int * p = ( unsigned int * ) ( ( unsigned int ) ps & ( ~ 3 ) ) ;
unsigned int xlen = ( unsigned int ) ps & 3 ;
if ( xlen ) {
tmp . ud = * p + + ;
while ( len ) {
len - - ;
if ( * pd + + ! = tmp . uc [ xlen + + ] ) return 1 ;
if ( xlen & 4 ) break ;
}
}
xlen = len > > 2 ;
while ( xlen ) {
tmp . uc [ 0 ] = * pd + + ;
tmp . uc [ 1 ] = * pd + + ;
tmp . uc [ 2 ] = * pd + + ;
tmp . uc [ 3 ] = * pd + + ;
if ( * p + + ! = tmp . ud ) return 1 ;
xlen - - ;
}
if ( len & 3 ) {
tmp . ud = * p ;
if ( pd [ 0 ] ! = tmp . uc [ 0 ] ) return 1 ;
if ( len & 2 ) {
if ( pd [ 1 ] ! = tmp . uc [ 1 ] ) return 1 ;
if ( len & 1 ) {
if ( pd [ 2 ] ! = tmp . uc [ 2 ] ) return 1 ;
}
}
}
return 0 ;
}
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL void _fwrite_word ( unsigned int addr , unsigned int dw )
2016-11-09 00:56:41 +00:00
{
//Write word
HAL_WRITE32 ( SPI_FLASH_BASE , addr , dw ) ;
// Wait spic busy done
SpicWaitBusyDoneRtl8195A ( ) ;
// Wait flash busy done (wip=0)
if ( flashobj . SpicInitPara . flashtype = = FLASH_MICRON )
SpicWaitOperationDoneRtl8195A ( flashobj . SpicInitPara ) ;
else
SpicWaitWipDoneRefinedRtl8195A ( flashobj . SpicInitPara ) ;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_bscfg
// Опции:
// false - поиск текушего сегмента
// true - поиск нового сегмента для записи (pack)
// Returns : новый адрес сегмента для записи
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL FLASH_EEP_ATTR unsigned int get_addr_bscfg ( bool flg )
2016-11-09 00:56:41 +00:00
{
2017-02-01 11:33:55 +00:00
unsigned int x1 = ( flg ) ? 0 : 0xFFFFFFFF , x2 ;
unsigned int faddr = FMEMORY_SCFG_BASE_ADDR ;
unsigned int reta = FMEMORY_SCFG_BASE_ADDR ;
2016-11-09 00:56:41 +00:00
do {
x2 = HAL_READ32 ( SPI_FLASH_BASE , faddr ) ; // if(flash_read(faddr, &x2, 4)) return -(FMEM_FLASH_ERR);
if ( flg ) { // поиск нового сегмента для записи (pack)
if ( x2 > x1 | | x2 = = 0xFFFFFFFF ) {
x1 = x2 ;
reta = faddr ; // новый адрес сегмента для записи
}
}
else if ( x2 < x1 ) { // поиск текушего сегмента
x1 = x2 ;
reta = faddr ; // новый адрес сегмента для записи
} ;
faddr + = FMEMORY_SCFG_BANK_SIZE ;
} while ( faddr < ( FMEMORY_SCFG_BASE_ADDR + FMEMORY_SCFG_BANKS * FMEMORY_SCFG_BANK_SIZE ) ) ;
if ( ( ! flg ) & & ( x1 = = 0xFFFFFFFF ) & & ( reta = = FMEMORY_SCFG_BASE_ADDR ) ) {
_fwrite_word ( reta , - - x1 ) ; // if(flash_write(reta, &x1, 4)) return -(FMEM_FLASH_ERR);
}
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " base seg: %p [%d] \n " , reta , x2 ) ;
# endif
return reta ;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fobj
// Опции:
// false - Поиск последней записи объекта по id и size
// true - Поиск присуствия записи объекта по id и size
// Returns : адрес записи данных объекта
// 0 - не найден
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj ( unsigned int base , fobj_head * obj , bool flg )
2016-11-09 00:56:41 +00:00
{
// if(base == 0) return 0;
fobj_head fobj ;
2017-02-01 11:33:55 +00:00
unsigned int faddr = base + 4 ;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align ( fobj_head_size ) ;
unsigned int reta = 0 ;
2016-11-09 00:56:41 +00:00
do {
fobj . x = HAL_READ32 ( SPI_FLASH_BASE , faddr ) ; // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if ( fobj . x = = fobj_x_free ) break ;
if ( fobj . n . size < = MAX_FOBJ_SIZE ) {
if ( fobj . n . id = = obj - > n . id ) {
if ( flg ) {
return faddr ;
}
obj - > n . size = fobj . n . size ;
reta = faddr ;
}
faddr + = align ( fobj . n . size + fobj_head_size ) ;
}
else faddr + = align ( MAX_FOBJ_SIZE + fobj_head_size ) ;
}
while ( faddr < fend ) ;
return reta ;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fend
// Поиск последнего адреса в сегменте для записи объекта
// Returns : адрес для записи объекта
// ret < FMEM_ERROR_MAX - ошибка
// ret = 0 - не влезет, на pack
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj_save ( unsigned int base , fobj_head obj )
2016-11-09 00:56:41 +00:00
{
fobj_head fobj ;
2017-02-01 11:33:55 +00:00
unsigned int faddr = base + 4 ;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align ( obj . n . size + fobj_head_size ) ;
2016-11-09 00:56:41 +00:00
do {
fobj . x = HAL_READ32 ( SPI_FLASH_BASE , faddr ) ; // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if ( fobj . x = = fobj_x_free ) {
if ( faddr < fend ) {
return faddr ;
}
return 0 ; // не влезет, на pack
}
if ( fobj . n . size < = MAX_FOBJ_SIZE ) {
faddr + = align ( fobj . n . size + fobj_head_size ) ;
}
else faddr + = align ( MAX_FOBJ_SIZE + fobj_head_size ) ;
}
while ( faddr < fend ) ;
return 0 ; // не влезет, на pack
}
//=============================================================================
// FunctionName : pack_cfg_fmem
// Returns : адрес для записи объекта
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL FLASH_EEP_ATTR unsigned int pack_cfg_fmem ( fobj_head obj )
2016-11-09 00:56:41 +00:00
{
fobj_head fobj ;
2017-02-01 11:33:55 +00:00
unsigned int fnewseg = get_addr_bscfg ( true ) ; // поиск нового сегмента для записи (pack)
2016-11-09 00:56:41 +00:00
if ( fnewseg < FMEM_ERROR_MAX ) return fnewseg ; // error
2017-02-01 11:33:55 +00:00
unsigned int foldseg = get_addr_bscfg ( false ) ; // поиск текушего сегмента
2016-11-09 00:56:41 +00:00
if ( foldseg < FMEM_ERROR_MAX ) return fnewseg ; // error
2017-02-01 11:33:55 +00:00
unsigned int faddr = foldseg ;
unsigned int rdaddr , wraddr ;
unsigned short len ;
unsigned int * pbuf = ( unsigned int * ) malloc ( align ( MAX_FOBJ_SIZE + fobj_head_size ) > > 2 ) ;
2016-11-09 00:56:41 +00:00
if ( pbuf = = NULL ) {
# if DEBUGSOO > 1
DBG_FEEP_ERR ( " pack malloc error! \n " ) ;
# endif
return - ( FMEM_MEM_ERR ) ;
}
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " repack base to new seg: %p \n " , fnewseg ) ;
# endif
SpicSectorEraseFlashRtl8195A ( fnewseg ) ; // if(flash_erase_sector(fnewseg)) return -(FMEM_FLASH_ERR);
faddr + = 4 ;
wraddr = fnewseg + 4 ;
do {
fobj . x = HAL_READ32 ( SPI_FLASH_BASE , faddr ) ; //if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); // последовательное чтение id из старого сегмента
if ( fobj . x = = fobj_x_free ) break ;
if ( fobj . n . size > MAX_FOBJ_SIZE ) len = align ( MAX_FOBJ_SIZE + fobj_head_size ) ;
else len = align ( fobj . n . size + fobj_head_size ) ;
if ( fobj . n . id ! = obj . n . id & & fobj . n . size < = MAX_FOBJ_SIZE ) { // объект валидный
if ( get_addr_fobj ( fnewseg , & fobj , true ) = = 0 ) { // найдем, сохранили ли мы е г о уже? нет
rdaddr = get_addr_fobj ( foldseg , & fobj , false ) ; // найдем последнее сохранение объекта в старом сенгменте, size изменен
if ( rdaddr < FMEM_ERROR_MAX ) return rdaddr ; // ???
if ( wraddr + len > = fnewseg + FMEMORY_SCFG_BANK_SIZE ) {
# if DEBUGSOO > 1
DBG_FEEP_ERR ( " pack segment overflow! \n " ) ;
# endif
return - ( FMEM_OVR_ERR ) ;
} ;
#if 0
copy_align4_to_align1 ( ( uint8 * ) pbuf , rdaddr , len ) ;
# else
2017-02-01 11:33:55 +00:00
SpicUserReadFourByteRtl8195A ( len , rdaddr , ( unsigned int * ) pbuf , flashobj . SpicInitPara . Mode . BitMode ) ;
2016-11-09 00:56:41 +00:00
# endif
int i = 0 ;
int size4b = len > > 2 ;
// перепишем данные obj в новый сектор
while ( size4b - - ) {
_fwrite_word ( wraddr , pbuf [ i + + ] ) ; // if(flash_write(wraddr, &pbuf[i++], 4)) return -(FMEM_FLASH_ERR);
} ;
} ;
} ;
faddr + = len ;
} while ( faddr < ( foldseg + FMEMORY_SCFG_BANK_SIZE - align ( fobj_head_size + 1 ) ) ) ;
free ( pbuf ) ;
// обратный счетчик стираний/записей секторов как id
_fwrite_word ( fnewseg , HAL_READ32 ( SPI_FLASH_BASE , foldseg ) - 1 ) ; // if(flash_write(fnewseg, &foldseg + SPI_FLASH_BASE, 4)) return -(FMEM_FLASH_ERR);
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " free: %d \n " , FMEMORY_SCFG_BANK_SIZE - ( faddr & ( FMEMORY_SCFG_BANK_SIZE - 1 ) ) ) ;
# endif
return get_addr_fobj_save ( fnewseg , obj ) ; // адрес для записи объекта;
}
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
LOCAL signed short FLASH_EEP_ATTR _flash_write_cfg ( void * ptr , unsigned short id , unsigned short size )
2016-11-09 00:56:41 +00:00
{
fobj_head fobj ;
fobj . n . id = id ;
fobj . n . size = size ;
bool retb = false ;
2017-02-01 11:33:55 +00:00
unsigned int faddr = get_addr_bscfg ( false ) ;
2016-11-09 00:56:41 +00:00
if ( faddr > = FMEM_ERROR_MAX ) {
2017-02-01 11:33:55 +00:00
unsigned int xfaddr = get_addr_fobj ( faddr , & fobj , false ) ;
2016-11-09 00:56:41 +00:00
if ( xfaddr > FMEM_ERROR_MAX & & size = = fobj . n . size ) {
if ( size = = 0
| | cmp_align1_align4 ( ptr , ( void * ) SPI_FLASH_BASE + xfaddr + fobj_head_size , size ) = = 0 ) {
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " write obj is identical, id: %04x [%d] \n " , id , size ) ;
# endif
return size ; // уже записано то-же самое
}
# if DEBUGSOO > 100
else {
int i ;
uint8 * p = ( uint8 * ) ( SPI_FLASH_BASE + xfaddr + fobj_head_size ) ;
uint8 * r = ( uint8 * ) ptr ;
for ( i = 0 ; i < size ; i + = 8 ) {
DBG_8195A ( " buf[%d] \t %02X %02X %02X %02X %02X %02X %02X %02X \n " ,
i , r [ i ] , r [ i + 1 ] , r [ i + 2 ] , r [ i + 3 ] , r [ i + 4 ] , r [ i + 5 ] , r [ i + 6 ] , r [ i + 7 ] ) ;
DBG_8195A ( " obj[%d] \t %02X %02X %02X %02X %02X %02X %02X %02X \n " ,
i , p [ i ] , p [ i + 1 ] , p [ i + 2 ] , p [ i + 3 ] , p [ i + 4 ] , p [ i + 5 ] , p [ i + 6 ] , p [ i + 7 ] ) ;
}
}
# endif
}
}
# if DEBUGSOO > 2
DBG_FEEP_INFO ( " write obj id: %04x [%d] \n " , id , size ) ;
# endif
fobj . n . size = size ;
faddr = get_addr_fobj_save ( faddr , fobj ) ;
if ( faddr = = 0 ) {
faddr = pack_cfg_fmem ( fobj ) ;
if ( faddr = = 0 ) return FMEM_NOT_FOUND ;
}
else if ( faddr < FMEM_ERROR_MAX ) return - faddr - 1 ; // error
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " write obj to faddr %p \n " , faddr ) ;
# endif
_fwrite_word ( faddr , fobj . x ) ; // if(flash_write(faddr, &fobj.x, 4)) return FMEM_FLASH_ERR;
faddr + = 4 ;
union {
unsigned char uc [ 4 ] ;
unsigned int ud ;
} tmp ;
#if 0
u32 len = ( size + 3 ) & ( ~ 3 ) ;
if ( len ) SpicUserProgramRtl8195A ( ( u8 * ) ptr , 1 , faddr , len ) ;
# else
u32 len = ( size + 3 ) > > 2 ;
uint8 * ps = ptr ;
while ( len - - ) {
tmp . uc [ 0 ] = * ps + + ;
tmp . uc [ 1 ] = * ps + + ;
tmp . uc [ 2 ] = * ps + + ;
tmp . uc [ 3 ] = * ps + + ;
_fwrite_word ( faddr , tmp . ud ) ; // if(flash_write(faddr, &tmp.ud, 4)) return FMEM_FLASH_ERR;
faddr + = 4 ;
}
# endif
return size ;
}
//=============================================================================
//- Сохранить объект в flash --------------------------------------------------
// Returns : false/true
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
bool FLASH_EEP_ATTR flash_write_cfg ( void * ptr , unsigned short id , unsigned short size )
2016-11-09 00:56:41 +00:00
{
if ( size > MAX_FOBJ_SIZE ) return false ;
bool retb = false ;
device_mutex_lock ( RT_DEV_LOCK_FLASH ) ;
// SPIC Init
flash_turnon ( ) ;
if ( fspic_isinit = = 0 ) flash_init ( & flashobj ) ;
if ( _flash_write_cfg ( ptr , id , size ) > = 0 ) {
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " saved ok \n " ) ;
# endif
retb = true ;
}
SpicDisableRtl8195A ( ) ;
device_mutex_unlock ( RT_DEV_LOCK_FLASH ) ;
return retb ;
}
//=============================================================================
//- Прочитать объект из flash -------------------------------------------------
// Параметры:
// prt - указатель, куда сохранить
// id - идентификатор искомого объекта
// maxsize - сколько байт сохранить максимум из найденного объекта, по ptr
// Returns:
// -3 - error
// -2 - flash rd/wr/clr error
// -1 - не найден
// 0..MAX_FOBJ_SIZE - ok, сохраненный размер объекта
//-----------------------------------------------------------------------------
2017-02-01 11:33:55 +00:00
signed short FLASH_EEP_ATTR flash_read_cfg ( void * ptr , unsigned short id , unsigned short maxsize )
2016-11-09 00:56:41 +00:00
{
2017-02-01 11:33:55 +00:00
signed short rets = FMEM_ERROR ;
2016-11-09 00:56:41 +00:00
if ( maxsize < = MAX_FOBJ_SIZE ) {
device_mutex_lock ( RT_DEV_LOCK_FLASH ) ;
fobj_head fobj ;
fobj . n . id = id ;
fobj . n . size = 0 ;
# if DEBUGSOO > 2
DBG_FEEP_INFO ( " read obj id: %04x[%d] \n " , id , maxsize ) ;
# endif
// SPIC Init
flash_turnon ( ) ;
if ( fspic_isinit = = 0 ) flash_init ( & flashobj ) ;
2017-02-01 11:33:55 +00:00
unsigned int faddr = get_addr_bscfg ( false ) ;
2016-11-09 00:56:41 +00:00
if ( faddr > = FMEM_ERROR_MAX ) {
faddr = get_addr_fobj ( faddr , & fobj , false ) ;
if ( faddr > = FMEM_ERROR_MAX ) {
#if 0
if ( maxsize ! = 0 & & ptr ! = NULL )
copy_align4_to_align1 ( ptr , SPI_FLASH_BASE + faddr + fobj_head_size , mMIN ( fobj . n . size , maxsize ) ) ;
# else
if ( maxsize ! = 0 & & ptr ! = NULL )
2017-02-01 11:33:55 +00:00
SpicUserReadRtl8195A ( mMIN ( fobj . n . size , maxsize ) , faddr + fobj_head_size , ptr , flashobj . SpicInitPara . Mode . BitMode ) ;
2016-11-09 00:56:41 +00:00
# endif
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " read ok, faddr: %p, size: %d \n " , faddr , fobj . n . size ) ;
# endif
rets = fobj . n . size ;
}
else {
# if DEBUGSOO > 3
DBG_FEEP_INFO ( " obj not found \n " ) ;
# endif
rets = - faddr - 1 ;
}
}
else rets = - faddr - 1 ;
SpicDisableRtl8195A ( ) ;
device_mutex_unlock ( RT_DEV_LOCK_FLASH ) ;
}
return rets ;
}
//=============================================================================