📄 llayer.c
字号:
#ifndef _LLAYER_C_
#define _LLAYER_C_
/****************************************************************************
*
* Copyright (c) 2005 by HCC Embedded
*
* This software is copyrighted by and is the sole property of
* HCC. All rights, title, ownership, or other interests
* in the software remain the property of HCC. This
* software may only be used in accordance with the corresponding
* license agreement. Any unauthorized use, duplication, transmission,
* distribution, or disclosure of this software is expressly forbidden.
*
* This Copyright notice may not be removed or modified without prior
* written consent of HCC.
*
* HCC reserves the right to modify this software without notice.
*
* HCC Embedded
* Budapest 1132
* Victor Hugo Utca 11-15
* Hungary
*
* Tel: +36 (1) 450 1302
* Fax: +36 (1) 450 1303
* http: www.hcc-embedded.com
* email: info@hcc-embedded.com
*
***************************************************************************/
#include "llayer.h"
#include "prgmacro.h"
#include "mdebug.h"
#include "string.h"
static unsigned char gl_data [MAX_SIZE*MLAYER_SETS];
static unsigned long gl_wear[MAX_BLOCK*MLAYER_SETS];
static int onceinit=0;
/****************************************************************************
*
* ll_init
*
* low level init function, this is called from mlayer lowinit function once
*
* RETURNS
*
* 0 - if successfuly
* other if any error
*
***************************************************************************/
unsigned char ll_init() {
if (!onceinit) {
memset(gl_data,0xff,sizeof(gl_data));
onceinit=1;
}
return 0;
}
/****************************************************************************
*
* ll_getwear
*
* subfunction for windows, displaying wear information
*
* INPUTS
*
* RETURNS
*
***************************************************************************/
void ll_getwear(unsigned short blk, unsigned long *dest) {
unsigned long pos=blk;
pos*=MAX_BLOCK_SIZE;
*dest=GET_SPARE_AREA(&gl_data[pos])->wear;
}
/****************************************************************************
*
* ll_erase
*
* erase a block
*
* INPUTS
*
* pba - physical block address
*
* RETURNS
*
* LL_OK - if successfuly
* LL_ERROR - if any error
*
***************************************************************************/
unsigned char ll_erase(t_ba pba) {
unsigned long pos=pba;
DEBPR2("ll_erase pba %d, %04x\n",pba,pba);
if (pba>=MAX_BLOCK*MLAYER_SETS) return LL_ERROR;
pos*=MAX_BLOCK_SIZE;
memset(gl_data+pos,0xff,MAX_BLOCK_SIZE);
cnt_increase(CNT_TERASES);
return LL_OK;
}
/****************************************************************************
*
* ll_write
*
* write a page
*
* INPUTS
*
* pba - physical block address
* ppo - physical page offset
* buffer - page data to be written (data+spare)
*
* RETURNS
*
* LL_OK - if successfuly
* LL_ERROR - if any error
*
***************************************************************************/
unsigned char ll_write(t_ba pba,t_po ppo, unsigned char *buffer) {
unsigned long page=ppo;
unsigned long pos=pba;
unsigned char *dest=gl_data;
long a;
DEBPR3("ll_write pba %d, %04x ppo %d\n",pba,pba,ppo);
if (pba>=MAX_BLOCK*MLAYER_SETS) return LL_ERROR;
if (ppo>=MAX_PAGE_PER_BLOCK) return LL_ERROR;
pos*=MAX_BLOCK_SIZE;
page*=MAX_PAGE_SIZE;
dest+=(pos+page);
if (!ppo) {
unsigned long newwear=GET_SPARE_AREA(buffer)->wear;
if (gl_wear[pba]+1!=newwear) {
a=10;
}
gl_wear[pba]=newwear;
}
for (a=0; a<MAX_PAGE_SIZE; a++) {
char ch=*dest;
char ch2=*buffer++;
*dest++=(unsigned char)(ch&ch2);
}
return LL_OK;
}
/****************************************************************************
*
* ll_writedouble
*
* write a page from 2 buffers
*
* INPUTS
*
* pba - physical block address
* ppo - physical page offset
* buffer - 1st half of page data to be written
* buffer - 2nd half of page data + spare data to be written
*
* RETURNS
*
* LL_OK - if successfuly
* LL_ERROR - if any error
*
***************************************************************************/
unsigned char ll_writedouble(t_ba pba,t_po ppo, unsigned char *buffer0,unsigned char *buffer1) {
unsigned long page=ppo;
unsigned long pos=pba;
unsigned char *dest=gl_data;
long a;
DEBPR3("ll_writedouble pba %d, %04x ppo %d\n",pba,pba,ppo);
if (pba>=MAX_BLOCK*MLAYER_SETS) return LL_ERROR;
if (ppo>=MAX_PAGE_PER_BLOCK) return LL_ERROR;
pos*=MAX_BLOCK_SIZE;
page*=MAX_PAGE_SIZE;
dest+=(pos+page);
for (a=0; a<MAX_DATA_SIZE/2; a++) {
char ch=*dest;
char ch2=*buffer0++;
*dest++=(unsigned char)(ch&ch2);
}
for (; a<MAX_PAGE_SIZE; a++) {
char ch=*dest;
char ch2=*buffer1++;
*dest++=(unsigned char)(ch&ch2);
}
if (!ppo) {
unsigned long newwear=GET_SPARE_AREA((gl_data+pos+page))->wear;
if (gl_wear[pba]+1!=newwear) {
a=10;
}
gl_wear[pba]=newwear;
}
return LL_OK;
}
/****************************************************************************
*
* ll_read
*
* read a page
*
* INPUTS
*
* pba - physical block address
* ppo - physical page offset
* buffer - page data pointer where to store data (data+spare)
*
* RETURNS
*
* LL_OK - if successfuly
* LL_ERASED - if page is empty
* LL_ERROR - if any error
*
***************************************************************************/
unsigned char ll_read(t_ba pba,t_po ppo, unsigned char *buffer) {
unsigned long page=ppo;
unsigned long pos=pba;
unsigned char *sou=gl_data;
long a;
DEBPR3("ll_read pba %d, %04x ppo %d\n",pba,pba,ppo);
if (pba>=MAX_BLOCK*MLAYER_SETS) return LL_ERROR;
if (ppo>=MAX_PAGE_PER_BLOCK) return LL_ERROR;
pos*=MAX_BLOCK_SIZE;
page*=MAX_PAGE_SIZE;
sou+=(pos+page);
memcpy (buffer,sou,MAX_PAGE_SIZE);
for (a=0; a<MAX_PAGE_SIZE; a++) {
if (*buffer++!=0xff) return LL_OK; //not empty
}
return LL_ERASED;
}
/****************************************************************************
*
* end of llayer.c
*
***************************************************************************/
#endif //_LLAYER_C_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -