您现在的位置: 爱51代码网 >> 范文 >> 文章正文
K9k8G08U0A 裸机驱动复位不正常,一直检测不到RB拉低

 

/*
driver for K9K8G08U0A
use addr lines as ale cle r/b signels :
    ale--BA29
    cle--BA30
    r/b--PA15
    
    row 13bit --block       
        6bit  --page
        
    col   1bit  --spare
          2bit  --sector
          9bit  --offset(512byte)
    
    block0 info
    block 1~4096 data
    block 4097~8191 for replace bad block
    ecc save in spare area byte 1-3 (byte 0 is bad block mark)
    
    我们提供了
        虚拟块号写函数 nand_write_vblock :由vblock块的头开始写len长度(len<=64*2048)且该块将被整块覆盖
        虚拟块号读函数 nand_read_vblock :由vblock块的头开始读len长度(len<=64*2048)
        虚拟地址读函数 nand_read_vaddr :由虚拟地址vaddr(0~0x1FFFFFFF)读len长度(vaddr+len<=0x20000000)
        虚拟块号到虚拟地址转化函数 nand_vblocknum2vaddr :
        
        由于要写的块都要先擦除,所以仅提供了以虚拟块号为参数的写函数,而没有提供以虚拟地址为参数的写函数,
        为方便起见,提供了 虚拟块号到虚拟地址转化函数 和 虚拟地址到虚拟块号转化函数
        
    
*/
/*
09.6.30  检测busy管脚添加超时退出
*/
#pragma pack(1)
#include "vxWorks.h"
 
#define TIMEOUT_LOOP 99999  /*待测*/
 
#define DEBUG
#ifdef  DEBUG
#define DEBUG_READ     0x00000001
#define DEBUG_ERROR    0x00000002
#define DEBUG_PROGRAM  0x00000004
#define DEBUG_ERASE    0x00000008
#define DEBUG_ID       0x00000010
#define DEBUG_MAP      0x00000020
#define DEBUG_ECC      0x00000040
#define DEBUG_ADDR     0x00000080
#define DEBUG_BLKCHK   0x00000100
#define DEBUG_ALWAYS   0xffffffff
 
 
    LOCAL UINT32 debug = DEBUG_READ | DEBUG_BLKCHK | DEBUG_ERASE;
    #define DEBUG_PRINT(mask, string) \
                if ((debug & mask) || (mask == DEBUG_ALWAYS)) \
                printf string
#else
    #define DEBUG_PRINT(mask, string)
#endif
 
#define     NAND_CMD     0x50000002
#define     NAND_ADDR     0x50000004
#define        PAPAR        *((volatile UINT32*)0xf0010D06)
#define        PADIR        *((volatile UINT32*)0xf0010D02)
#define        PADAT        *((volatile UINT32*)0xf0010D10)
#define        PA15        0x00010000
typedef struct
{
    UCHAR checked;
    UCHAR badBlockTable[8192];
    union
    {
        UINT16 map_short[4096];
        UCHAR map_char[8192];
    }map;
    UCHAR bottomHaltInValid[4095];
}NAND_INFO;
LOCAL NAND_INFO nand_info;
typedef enum {
    ECC_NO_ERROR                = 0,        /* no error */
    ECC_CORRECTABLE_ERROR    = 1,        /* one bit data error */
    ECC_ECC_ERROR                = 2,        /* one bit ECC error */
    ECC_UNCORRECTABLE_ERROR    = 3        /* uncorrectable error */
} eccdiff_t;
LOCAL void make_ecc_512(unsigned char * ecc_buf, unsigned char * data_buf);
LOCAL eccdiff_t compare_ecc_512(unsigned char *iEccdata1, unsigned char *iEccdata2,
          unsigned char *pPagedata, long * pOffset, unsigned char * pCorrected);
LOCAL BOOL isBusy();
LOCAL void set_command(UCHAR cmd);
LOCAL void set_addr(UCHAR addr);
LOCAL UCHAR nand_read(void);
LOCAL void nand_write(UCHAR c);
 
LOCAL UINT32 make_addr(UINT32 blocknum,UINT32 page,UINT32 sector,UINT32 offset,int flag);
LOCAL int set_data_addr(UINT32 addr,int flag);
 
int nand_erase(UINT32 blocknum);
LOCAL int nand_program_block(UCHAR* src,UINT32 blocknum,UINT32 len);
LOCAL int nand_program_sector(UCHAR* src,UINT32 blocknum,UINT32 page,UINT32 sector);
BOOL isChecked();
LOCAL void reset_nand();
LOCAL void initalBadBlockCheck();
LOCAL int read_id();
LOCAL int nand_read_sector(UCHAR* buf,UINT32 blocknum,UINT32 page,UINT32 sector);
LOCAL int load_info();
LOCAL int program_info();
LOCAL int nand_read_block0(UCHAR* buf,UINT32 len);
LOCAL int wait();
void nand_init();/*初始化*/
int nand_write_vblock(UINT32 vblocknum,UCHAR* buf,UINT32 len);/*vblocknum: 0~4095*//*虚拟块号写函数*/
int nand_read_vblock(UINT32 vblocknum,UCHAR* buf,UINT32 len);/*vblocknum: 0~4095*//*虚拟块号读函数*/
int nand_read_vaddr(UINT32 vaddr,UCHAR* buf,UINT32 len);/*vaddr : 0~0x1FFFFFFF*//*虚拟地址读函数*/
int nand_vblocknum2vaddr(UINT32 vblocknum,UINT32* pvaddr);/*虚拟块号到虚拟地址转化函数*/
int nand_vaddr2vblocknum(UINT32 vaddr,UINT32 * pvblock,UINT32 * poffset);/*虚拟地址到虚拟块号转化函数,poffset为块内偏移量*/
 
 
int nand_vblocknum2vaddr(UINT32 vblocknum,UINT32* pvaddr)
{
    
    if(vblocknum>4095)
    {
        printf("error : vblocknum>4095\n");
        return -1;
    }
    else
    {
        * pvaddr = (vblocknum<<17);
        return 0;
    }
        
}
int nand_vaddr2vblocknum(UINT32 vaddr,UINT32 * pvblock,UINT32 * poffset)
{
    
    if(vaddr>0x1FFFFFFF)
    {
        printf("error : vaddr>0x1FFFFFFF\n");
        return -1;
    }
    else
    {
        *pvblock = (vaddr & 0x1FFE0000)>>17;
        *poffset = (vaddr & 0x1FFFF);
        return 0;
    }
        
}
 
LOCAL void make_ecc_512(unsigned char * ecc_buf, unsigned char * data_buf)
{
    
    unsigned long    i, ALIGN_FACTOR;
    unsigned long    tmp;
    unsigned long    uiparity = 0;
    unsigned long    parityCol, ecc = 0;
    unsigned long    parityCol4321 = 0, parityCol4343 = 0, parityCol4242 = 0, parityColTot = 0;
    unsigned long    *Data;
    unsigned long    Xorbit=0;
 
    ALIGN_FACTOR = (unsigned long)data_buf % 4 ;
    Data = (unsigned long *)(data_buf + ALIGN_FACTOR);
 
    for( i = 0; i < 16; i++)
    {
        parityCol = *Data++;
        tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp; parityCol4242 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4321 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp; parityCol4321 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp; parityCol4321 ^= tmp;
        tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp; parityCol4343 ^= tmp; parityCol4321 ^= tmp;
 
        parityColTot ^= parityCol;
 
        tmp = (parityCol >> 16) ^ parityCol;
        tmp = (tmp >> 8) ^ tmp;
        tmp = (tmp >> 4) ^ tmp;
        tmp = ((tmp >> 2) ^ tmp) & 0x03;
        if ((tmp == 0x01) || (tmp == 0x02))
        {
            uiparity ^= i;
            Xorbit ^= 0x01;
        }
    }
 
    tmp = (parityCol4321 >> 16) ^ parityCol4321;
    tmp = (tmp << 8) ^ tmp;
    tmp = (tmp >> 4) ^ tmp;
    tmp = (tmp >> 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x200;  
 
    tmp = (parityCol4343 >> 16) ^ parityCol4343;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp << 4) ^ tmp;
    tmp = (tmp << 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x80;  
 
    tmp = (parityCol4242 >> 16) ^ parityCol4242;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp << 4) ^ tmp;
    tmp = (tmp >> 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x20;  
 
 
    tmp = parityColTot & 0xFFFF0000;
    tmp = tmp >> 16;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp >> 4) ^ tmp;
    tmp = (tmp << 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x08;  
 
    tmp = parityColTot & 0xFF00FF00;
    tmp = (tmp >> 16) ^ tmp;
    tmp = (tmp >> 8);
    tmp = (tmp >> 4) ^ tmp;
    tmp = (tmp >> 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x02;  
 
    tmp = parityColTot & 0xF0F0F0F0 ;
    tmp = (tmp << 16) ^ tmp;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp << 2) ^ tmp;
    ecc |= ((tmp << 1) ^ tmp) & 0x800000;  
 
    tmp = parityColTot & 0xCCCCCCCC ;
    tmp = (tmp << 16) ^ tmp;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp << 4) ^ tmp;
    tmp = (tmp >> 2);
    ecc |= ((tmp << 1) ^ tmp) & 0x200000;  
 
    tmp = parityColTot & 0xAAAAAAAA ;
    tmp = (tmp << 16) ^ tmp;
    tmp = (tmp >> 8) ^ tmp;
    tmp = (tmp >> 4) ^ tmp;
    tmp = (tmp << 2) ^ tmp;
    ecc |= (tmp & 0x80000);  
 
    ecc |= (uiparity & 0x01) <<11;  
    ecc |= (uiparity & 0x02) <<12;  
    ecc |= (uiparity & 0x04) <<13;
    ecc |= (uiparity & 0x08) <<14;
 
    if (Xorbit)
    {
        ecc |= (ecc ^ 0x00AAAAAA)>>1;
    }
    else
    {
        ecc |= (ecc >> 1);
    }
 
    ecc = ~ecc;
    *(ecc_buf + 2) = (unsigned char) (ecc >> 16);
    *(ecc_buf + 1) = (unsigned char) (ecc >> 8);
    *(ecc_buf + 0) = (unsigned char) (ecc);
}
 
/****************************************************************************
* NAME     compare_ecc_512 
* DESCRIPTION
*        This function compares two ECCs and indicates if there is an error.
* PARAMETERS    
*        ecc_data1        one ECC to be compared
*        ecc_data2        the other ECC to be compared
*        page_data        content of data page 
*        offset            where the error occurred
*        corrected        correct data
* RETURN VALUES
*        Upon successful completion, compare_ecc returns SSR_SUCCESS.
*      Otherwise, corresponding error code is returned.
****/
LOCAL eccdiff_t compare_ecc_512(unsigned char *iEccdata1, unsigned char *iEccdata2,
          unsigned char *pPagedata, long* pOffset, unsigned char* pCorrected)
{
 
    unsigned long  iCompecc = 0, iEccsum = 0;
    unsigned long  iFindbyte   = 0;
    unsigned long  iIndex;
    unsigned long  nT1 = 0, nT2 =0;
 
    unsigned char   iNewvalue;
    unsigned char   iFindbit    = 0;
 
    unsigned char   *pEcc1 = (unsigned char *)iEccdata1;
    unsigned char   *pEcc2 = (unsigned char *)iEccdata2;
 
    for ( iIndex = 0; iIndex <2; iIndex++)
    {
        nT1 ^= (((*pEcc1) >> iIndex) & 0x01);
        nT2 ^= (((*pEcc2) >> iIndex) & 0x01);
    }
 
    for (iIndex = 0; iIndex < 3; iIndex++)
        iCompecc |= ((~(*pEcc1++) ^ ~(*pEcc2++)) << iIndex * 8);
    
    for(iIndex = 0; iIndex < 24; iIndex++)
        iEccsum += ((iCompecc >> iIndex) & 0x01);
 
    switch (iEccsum)
    {
        case 0 :
            DEBUG_PRINT(DEBUG_ECC, ("RESULT : no error\n"));
            return ECC_NO_ERROR;
 
        case 1 :
            DEBUG_PRINT(DEBUG_ECC,("RESULT : ECC code 1 bit fail\n"));
            return ECC_ECC_ERROR;
 
        case 12 :
            if (nT1 != nT2)
            {
                iFindbyte = ((iCompecc >> 17 & 1) << 8) + ((iCompecc >> 15 & 1) << 7) + ((iCompecc >> 13 & 1) << 6)
                    + ((iCompecc >> 11 & 1) << 5) + ((iCompecc >> 9 & 1) << 4) + ((iCompecc >> 7 & 1) << 3)
                    + ((iCompecc >> 5 & 1) << 2) + ((iCompecc >> 3 & 1) << 1) + (iCompecc >> 1 & 1);
                iFindbit =  (unsigned char)(((iCompecc >> 23 & 1) << 2) + ((iCompecc >> 21 & 1) << 1) + (iCompecc >> 19 & 1));
                iNewvalue = (unsigned char)(pPagedata[iFindbyte] ^ (1 << iFindbit));
 
                DEBUG_PRINT(DEBUG_ECC,("iCompecc = %d\n",iCompecc));
                DEBUG_PRINT(DEBUG_ECC,("RESULT : one bit error\r\n"));
                DEBUG_PRINT(DEBUG_ECC,("byte = %d, bit = %d\r\n", iFindbyte, iFindbit));
                DEBUG_PRINT(DEBUG_ECC,("corrupted = %x, corrected = %x\r\n", pPagedata[iFindbyte], iNewvalue));
 
                if (pOffset != NULL)     *pOffset = iFindbyte;
 
                if (pCorrected != NULL)     *pCorrected = iNewvalue;
            
                return ECC_CORRECTABLE_ERROR;
            }
            else
                return ECC_UNCORRECTABLE_ERROR;
 
        default :
            DEBUG_PRINT(DEBUG_ECC,("RESULT : unrecoverable error\n"));
            return ECC_UNCORRECTABLE_ERROR;
    }  
}

上一页  [1] [2] [3] [4] 下一页

  • 上一篇文章:

  • 下一篇文章: 没有了
  • 最新文章 热点文章 相关文章
    Hadoop2.2.0在eclipse控制台没有
    maven如何加自定义的包
    redhat 2.6 (santigo 5.6) vsftp
    shell如何实现自动填写操作执行下
    linux shell 文件配置sh:color:
    shell script语法一定要加path吗
    SecureCRT如何访问虚拟机vmWare中
    C#如何读取WINDOWS的放大系数
    cximge的图如何存入数据库并提取
    DBGRID控件显示查询结果文本类型
    Hadoop2.2.0在eclipse控制台没有
    maven如何加自定义的包
    redhat 2.6 (santigo 5.6) vsftp
    shell如何实现自动填写操作执行下
    linux shell 文件配置sh:color:
    shell script语法一定要加path吗
    SecureCRT如何访问虚拟机vmWare中
    C#如何读取WINDOWS的放大系数
    cximge的图如何存入数据库并提取
    DBGRID控件显示查询结果文本类型
    VS2013+WDK8.1如何配置
    W5300 UDP 接收不到数据
    找不到mach/gpio.h
    STC12C5A60S2可以设计4路pwm
    write_data_ds1302’missing
    USB HID 读写STM32数据失败
    don't know how to make
    clean sysgen时出现的error 
    430单片机和GSM模块相连接时
    wince下如何使用webclient类
     



    设为首页 | 加入收藏 | 网站地图 | 友情链接 |