ARM仿真器_foxICE 设为首页   |   加入收藏夹   |   网站地图         
  站内搜索:
 
http://www.foxice.net
最新下载_foxICE
ARM7TDMI R3内核
ARM7EJS内核
ARM946E-S内核
ARM966E-S内核
ARM9TDMI内核
ARM940T内核
ARM指令集速查卡
ARM925T内核(TI925T)

更多 >> 

   首页>技术专栏>Nandflash专栏>Samsung公司512字节数据产生3字节ECC校验码、及用ECC码检查数据错误的软件代码

Samsung公司512字节数据产生3字节ECC校验码、及用ECC码检查数据错误的软件代码

    
高速程序代码下载速度200KBytes/S以上内置对于GDB Remote Serial Protocol协议支持FoxICE仿真器完美支持GDB 的 File IO扩展协议免费赠送Eclipse for ARM V 3.2.1集成开发环境支持Nand Flash( S3C2410/2440/2442可任选一种 )的烧写,支持超低电压的处理器调试, 目标范围为:0.65 ~ 5.5V
详细信息 >>

/***********************************************/
/* */
/* PROJECT : SAMSUNG ECC */
/* FILE : SAMSUNG_ECC.c */
/* PURPOSE : This file implements core ECC algorithms adopted */
/* Hamming Error Correction and Detection Algorithm */
/* */
/*---------------------------------------------*/
/* */
/* COPYRIGHT 2000-2004, SAMSUNG ELECTRONICS CO., LTD. */
/* ALL RIGHTS RESERVED */
/* */
/* Permission is hereby granted to licensees of Samsung Electronics */
/* Co., Ltd. products to use or abstract this computer program for the */
/* sole purpose of implementing a product based on Samsung */
/* Electronics Co., Ltd. products. No other rights to reproduce, use, */
/* or disseminate this computer program, whether in part or in whole, */
/* are granted. */
/* */
/* Samsung Electronics Co., Ltd. makes no representation or warranties */
/* with respect to the performance of this computer program, and */
/* specifically disclaims any responsibility for any damages, */
/* special or consequential, connected with the use of this program. */
/* */
/*---------------------------------------------------------------------------*/
/* */
/* REVISION HISTORY */
/* */
/* 13-NOV-2003 [Chang JongBaek] : first writing */
/* 03-MAR-2004 [ Kim YoungGon ] : Second writing */
/* 03-MAR-2004 [ Lee JaeBum ] : Third writing */
/*---------------------------------------------------------------------------*/
/* */
/* NOTES */
/* */
/* - Make ECC parity code of 512bytes(256words) and 3 bytes are represented */
/* And ECC compare & Correction code is also represented */
/* */
/*****************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "ecc.h"

#define XMODE 8

/*****************************************************************************/
/* Address Types */
/*****************************************************************************/

typedef unsigned char * address_t; /* address (pointer) */
typedef unsigned long address_value_t; /* address (for calculation) */

/*****************************************************************************/
/* Integer Types */
/*****************************************************************************/

typedef unsigned long uint32_t; /* unsigned 4 byte integer */
typedef signed long int32_t; /* signed 4 byte integer */
typedef unsigned short uint16_t; /* unsigned 2 byte integer */
typedef signed short int16_t; /* signed 2 byte integer */
typedef unsigned char uint8_t; /* unsigned 1 byte integer */
typedef signed char int8_t; /* signed 1 byte integer */

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;

/*****************************************************************************/
/* */
/* NAME */
/* make_ecc_512 */
/* DESCRIPTION */
/* This function generates 3 byte ECC for 512 byte data. */
/* (Software ECC) */
/* PARAMETERS */
/* ecc_buf the location where ECC should be stored */
/* data_buf given data */
/* RETURN VALUES */
/* none */
/* */
/*****************************************************************************/
#if (XMODE == 8)
void make_ecc_512(uint8_t * ecc_buf, uint8_t * data_buf)
#else
void make_ecc_512(uint16_t * ecc_buf, uint16_t * data_buf)
#endif
{

uint32_t i, ALIGN_FACTOR;
uint32_t tmp;
uint32_t uiparity = 0;
uint32_t parityCol, ecc = 0;
uint32_t parityCol4321 = 0, parityCol4343 = 0, parityCol4242 = 0, parityColTot = 0;
uint32_t *Data;
uint32_t Xorbit=0;

ALIGN_FACTOR = (uint32_t)data_buf % 4 ;
Data = (uint32_t *)(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;
}
}

#if (XMODE == 8)
tmp = (parityCol4321 >> 16) ^ parityCol4321;
tmp = (tmp << 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x200; // p128
#else
tmp = (parityCol4321 >> 16) ^ parityCol4321;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x80; // p128
#endif
#if (XMODE == 8)
tmp = (parityCol4343 >> 16) ^ parityCol4343;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x80; // p64
#else
tmp = (parityCol4343 >> 16) ^ parityCol4343;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x20; // p64
#endif
#if (XMODE == 8)
tmp = (parityCol4242 >> 16) ^ parityCol4242;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x20; // p32
#else
tmp = (parityCol4242 >> 16) ^ parityCol4242;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x08; // p32
#endif
#if (XMODE == 8)
tmp = parityColTot & 0xFFFF0000;
tmp = tmp >> 16;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x08; // p16
#else
tmp = parityColTot & 0xFFFF0000;
tmp = tmp >> 16;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x02; // p16
#endif
#if (XMODE == 8)
tmp = parityColTot & 0xFF00FF00;
tmp = (tmp >> 16) ^ tmp;
tmp = (tmp >> 8);
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x02; // p8
#else
tmp = parityColTot & 0xFF00FF00;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8);
tmp = (tmp << 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x800000; // p8
#endif
#if (XMODE == 8)
tmp = parityColTot & 0xF0F0F0F0 ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x800000; // p4
#else
tmp = parityColTot & 0xF0F0F0F0 ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x200000; // p4
#endif
#if (XMODE == 8)
tmp = parityColTot & 0xCCCCCCCC ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp >> 2);
ecc |= ((tmp << 1) ^ tmp) & 0x200000; // p2
#else
tmp = parityColTot & 0xCCCCCCCC ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x80000; // p2
#endif
#if (XMODE == 8)
tmp = parityColTot & 0xAAAAAAAA ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= (tmp & 0x80000); // p1
#else
tmp = parityColTot & 0xAAAAAAAA ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= (tmp & 0x20000); // p1
#endif
#if (XMODE == 8)
ecc |= (uiparity & 0x01) <<11;
ecc |= (uiparity & 0x02) <<12;
ecc |= (uiparity & 0x04) <<13;
ecc |= (uiparity & 0x08) <<14;
#else
ecc |= (uiparity & 0x01) <<9;
ecc |= (uiparity & 0x02) <<10;
ecc |= (uiparity & 0x04) <<11;
ecc |= (uiparity & 0x08) <<12;
#endif

if (Xorbit)
{
ecc |= (ecc ^ 0x00AAAAAA)>>1;
}
else
{
ecc |= (ecc >> 1);
}
#if (XMODE == 8)
ecc = ~ecc;
*(ecc_buf + 2) = (uint8_t) (ecc >> 16);
*(ecc_buf + 1) = (uint8_t) (ecc >> 8);
*(ecc_buf + 0) = (uint8_t) (ecc);
#else // X16
ecc = ( ~ecc ) | 0xFF000000;
*(ecc_buf + 1) = (uint16_t) (ecc >> 16);
*(ecc_buf + 0) = (uint16_t) (ecc);
#endif
}

/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#if (XMODE == 8)
eccdiff_t compare_ecc_512(uint8_t *iEccdata1, uint8_t *iEccdata2,
uint8_t *pPagedata, int32_t pOffset, uint8_t pCorrected)
#else // X16
eccdiff_t compare_ecc_512(uint16_t *iEccdata1, uint16_t *iEccdata2,
uint16_t *pPagedata, int32_t pOffset, uint16_t pCorrected)
#endif
{

uint32_t iCompecc = 0, iEccsum = 0;
uint32_t iFindbyte = 0;
uint32_t iIndex;
uint32_t nT1 = 0, nT2 =0;

#if (XMODE == 8)
uint8_t iNewvalue;
uint8_t iFindbit = 0;

uint8_t *pEcc1 = (uint8_t *)iEccdata1;
uint8_t *pEcc2 = (uint8_t *)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);
}

#else // X16
uint16_t iNewvalue;
uint16_t iFindbit = 0;

uint16_t *pEcc1 = (uint16_t *)iEccdata1;
uint16_t *pEcc2 = (uint16_t *)iEccdata2;

for ( iIndex = 0; iIndex <2; iIndex++)
{
nT1 ^= (((*pEcc1) >> iIndex) & 0x01);
nT2 ^= (((*pEcc2) >> iIndex) & 0x01);
}

for (iIndex = 0; iIndex < 2; iIndex++) // 2 word of ECC data
iCompecc |= (((~*pEcc1++) ^ (~*pEcc2++)) << iIndex * 16);

for(iIndex = 0; iIndex < 24; iIndex++) {
iEccsum += ((iCompecc >> iIndex) & 0x01);
}
#endif

switch (iEccsum) {
case 0 :
printf("RESULT : no error\n");
return ECC_NO_ERROR;

case 1 :
printf("RESULT : ECC code 1 bit fail\n");
return ECC_ECC_ERROR;

case 12 :
if (nT1 != nT2)
{
#if (XMODE == 8)
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 = (uint8_t)(((iCompecc >> 23 & 1) << 2) + ((iCompecc >> 21 & 1) << 1) + (iCompecc >> 19 & 1));
iNewvalue = (uint8_t)(pPagedata[iFindbyte] ^ (1 << iFindbit));
#else // CASE_X16
iFindbyte = ((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 = (uint16_t)(((iCompecc >> 23 & 1) << 3) + ((iCompecc >> 21 & 1) << 2) + ((iCompecc >> 19 & 1) << 1)
+ (iCompecc >> 17 & 1) );
iNewvalue = (uint16_t)(pPagedata[iFindbyte] ^ (1 << iFindbit));
#endif
printf("iCompecc = %d\n",iCompecc);
printf("RESULT : one bit error\r\n");
printf("byte = %d, bit = %d\r\n", iFindbyte, iFindbit);
printf("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 :
printf("RESULT : unrecoverable error\n");
return ECC_UNCORRECTABLE_ERROR;
}
}

相关文档
U-Boot在44B0X开发板上的移植以及代码分析
U-boot移植日记(s3c44b0)
S3C44B0\U-Boot的启动流程及移植
U-Boot在S3C2410上的移植
uboot在ARM s3c2410上移植过程
VxWorks 的bootrom 到u-boot 的移植心得
嵌入式系统中U-Boot基本特点及其移植方法
ecc_algorithm_for_web_256w
ecc_algorithm_for_web_512b
NAND Flash ECC Algorithm(Error Checking & Correction)
下载说明:
  1. 未经本站明确许可,任何网站不得非法盗链及抄袭本站资源!
 

首页 | 产品介绍 | 技术支持 | 下载中心 | 技术专栏 | 公司简介 | 联系我们
电话:86-755-82798083   82796301   传真:86-755-82799007    Email:sales@foxice.net   sales6@foxice.net
在线咨询:QQ:346466907   MSN:sales6@foxice.net   ini3000@msn.com Skype: Call me!

© 2006 深圳市伽罗华科技开发有限公司 版权所有
联系电话
0755-82798083
0755-82796301
服务时间
8:30-18:00
周一至周五
在线咨询
有事您Q我!!
有事您Q我!!
常见问题解答