From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- peripherals/hsmc4/hsmc.dir | 37 +++ peripherals/hsmc4/hsmc4.c | 247 +++++++++++++++ peripherals/hsmc4/hsmc4.h | 73 +++++ peripherals/hsmc4/hsmc4_ecc.c | 703 ++++++++++++++++++++++++++++++++++++++++++ peripherals/hsmc4/hsmc4_ecc.h | 85 +++++ 5 files changed, 1145 insertions(+) create mode 100644 peripherals/hsmc4/hsmc.dir create mode 100644 peripherals/hsmc4/hsmc4.c create mode 100644 peripherals/hsmc4/hsmc4.h create mode 100644 peripherals/hsmc4/hsmc4_ecc.c create mode 100644 peripherals/hsmc4/hsmc4_ecc.h (limited to 'peripherals/hsmc4') diff --git a/peripherals/hsmc4/hsmc.dir b/peripherals/hsmc4/hsmc.dir new file mode 100644 index 0000000..9ec8bb4 --- /dev/null +++ b/peripherals/hsmc4/hsmc.dir @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \dir +/// +/// !!!Purpose +/// +/// Contains the peripheral Static Memory Controller (HSMC4). +//------------------------------------------------------------------------------ + diff --git a/peripherals/hsmc4/hsmc4.c b/peripherals/hsmc4/hsmc4.c new file mode 100644 index 0000000..350da99 --- /dev/null +++ b/peripherals/hsmc4/hsmc4.c @@ -0,0 +1,247 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "hsmc4.h" + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ +/// Store value of current read only HSMC4_CTRL register. +static unsigned int hsmc4Ctrl; + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller has terminated the command. +/// read mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_CommandDone(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_CMDDONE) == AT91C_HSMC4_CMDDONE); +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/// Sets the mode of the HSMC4 to one of the following values: +/// - AT91C_HSMC4_PAGESIZE +/// - AT91C_HSMC4_WSPARE +/// - AT91C_HSMC4_RSPARE +/// - AT91C_HSMC4_EDGECTRL +/// - AT91C_HSMC4_RBEDGE +/// - AT91C_HSMC4_DTOCYC +/// - AT91C_HSMC4_DTOMUL +/// \param mode mode. +//------------------------------------------------------------------------------ +void HSMC4_SetMode(unsigned int mode) +{ + AT91C_BASE_HSMC4->HSMC4_CFG = mode; +} + +//----------------------------------------------------------------------------- +/// Reset the HSMC4 Nand flash controll host. +//----------------------------------------------------------------------------- +void HSMC4_ResetNfc(void) +{ + //Disable all the HSMC4 interrupts + AT91C_BASE_HSMC4 -> HSMC4_IDR = 0xFFFFFFFF; + AT91C_BASE_HSMC4 -> HSMC4_CTRL = 0; + hsmc4Ctrl = 0; +} + +//----------------------------------------------------------------------------- +/// Enable NAND flsah controller host through the APB interface. +//----------------------------------------------------------------------------- +void HSMC4_EnableNfc(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_NFCEN; + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; +} + +//----------------------------------------------------------------------------- +/// Acticated and perform a data transfer between the Host and a Nand Flash. +//----------------------------------------------------------------------------- +void HSMC4_EnableNfcHost(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_HOSTEN; + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; +} + +//----------------------------------------------------------------------------- +/// Enable host transfer data from the internal SRAM to the memory device. +//----------------------------------------------------------------------------- +void HSMC4_EnableHostTransfer(void) +{ + hsmc4Ctrl |= AT91C_HSMC4_HOSTWR; + // The HOSTWR field can be modified if the host controller is not busy. + while((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); + AT91C_BASE_HSMC4->HSMC4_CTRL = hsmc4Ctrl; + while((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); +} + +//----------------------------------------------------------------------------- +/// Enables the host main controller reads both main and spare area in read mode. +//----------------------------------------------------------------------------- +void HSMC4_EnableSpareRead(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG |= AT91C_HSMC4_RSPARE; +} + +//----------------------------------------------------------------------------- +/// The host main controller skips spare area in read mode. +//----------------------------------------------------------------------------- +void HSMC4_DisableSpareRead(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG &= 0xFFFFFDFF; +} + +//----------------------------------------------------------------------------- +/// Enables the host main controller writes both main and spare area in write +/// mode. +//----------------------------------------------------------------------------- +void HSMC4_EnableSpareWrite(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG |= AT91C_HSMC4_WSPARE; +} + +//----------------------------------------------------------------------------- +/// The host main controller skips spare area in write mode. +//----------------------------------------------------------------------------- +void HSMC4_DisableSpareWrite(void) +{ + AT91C_BASE_HSMC4->HSMC4_CFG &= 0xFFFFFEFF; +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller reads both main and spare area in +/// read mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isSpareRead(void) +{ + return (((AT91C_BASE_HSMC4->HSMC4_CFG) >> 9) & 0x1); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller writes both main and spare area in +/// write mode. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isSpareWrite(void) +{ + return (((AT91C_BASE_HSMC4->HSMC4_CFG) >> 8) & 0x1); +} + + +//----------------------------------------------------------------------------- +/// Returns 1 if the host main controller has terminated the data transmission. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_TransferComplete(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_XFRDONE) == AT91C_HSMC4_XFRDONE); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if edge has been detected on the Ready/Busy line. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isReadyBusy(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_RBEDGE0) == AT91C_HSMC4_RBEDGE0); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the Controller is activated and accesses the memory device. +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isNfcBusy(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_HOSTBUSY) == AT91C_HSMC4_HOSTBUSY); +} + +//----------------------------------------------------------------------------- +/// Returns 1 if the ecc is ready +/// otherwise returns 0. +//----------------------------------------------------------------------------- +unsigned char HSMC4_isEccReady(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_SR & AT91C_HSMC4_ECCRDY) == AT91C_HSMC4_ECCRDY); +} + +//----------------------------------------------------------------------------- +/// Returns the current status register of the HSMC4 peripheral. This +/// resets the internal value of the status register, so further read may yield +/// different values. +//----------------------------------------------------------------------------- +unsigned int HSMC4_GetStatus(void) +{ + return AT91C_BASE_HSMC4->HSMC4_SR; +} + +//------------------------------------------------------------------------------ +// HOST command functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Returns 1 if the host controller is busy. +/// otherwise returns 0. +//------------------------------------------------------------------------------ +unsigned char HSMC4_isHostBusy(void) +{ + return (((*((volatile unsigned int *) (CMD_BASE_ADDR + AT91C_HSMC4_HOSTCMD))) & 0x8000000) == 0x8000000); +} + +//------------------------------------------------------------------------------ +/// Uses the HOST nandflash conntroller to send a command to the NFC +/// \param cmd command to send. +/// \param addressCycle address cycle when command access id decoded. +/// \param cycle0 address at first cycle. +//------------------------------------------------------------------------------ +void HSMC4_SendCommand (unsigned int cmd, unsigned int addressCycle, unsigned int cycle0) +{ + volatile unsigned int *pCommandAddress; + // Wait until host controller is not busy. + while(HSMC4_isHostBusy()); + // Send the command plus the ADDR_CYCLE + pCommandAddress = (volatile unsigned int *) (cmd + CMD_BASE_ADDR); + AT91C_BASE_HSMC4->HSMC4_ADDR = cycle0; + *pCommandAddress = addressCycle; + while( !HSMC4_CommandDone()); +} + + diff --git a/peripherals/hsmc4/hsmc4.h b/peripherals/hsmc4/hsmc4.h new file mode 100644 index 0000000..47e19bb --- /dev/null +++ b/peripherals/hsmc4/hsmc4.h @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef HSMC4_H +#define HSMC4_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ +#define NFC_SRAM_BASE_ADDRESS 0x20100000 + +#ifndef BOARD_NF_COMMAND_ADDR + #define CMD_BASE_ADDR 0x60000000 +#else + #define CMD_BASE_ADDR BOARD_NF_COMMAND_ADDR +#endif + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +extern void HSMC4_SendCommand (unsigned int cmd, unsigned int addressCycle, unsigned int cycle0); +extern unsigned char HSMC4_isHostBusy(void); +extern unsigned char HSMC4_TransferComplete(void); +extern unsigned char HSMC4_isReadyBusy(void); +extern unsigned char HSMC4_isNfcBusy(void); +extern unsigned char HSMC4_isEccReady(void); +extern void HSMC4_SetMode(unsigned int mode); +extern void HSMC4_ResetNfc(void); +extern void HSMC4_EnableNfc(void); +extern void HSMC4_EnableNfcHost(void); + +extern void HSMC4_EnableSpareRead(void); +extern void HSMC4_DisableSpareRead(void); +extern void HSMC4_EnableSpareWrite(void); +extern void HSMC4_DisableSpareWrite(void); +extern unsigned char HSMC4_isSpareRead(void); +extern unsigned char HSMC4_isSpareWrite(void); +extern unsigned int HSMC4_GetStatus(void); + +#endif //#ifndef HSMC4_H + diff --git a/peripherals/hsmc4/hsmc4_ecc.c b/peripherals/hsmc4/hsmc4_ecc.c new file mode 100644 index 0000000..e27655f --- /dev/null +++ b/peripherals/hsmc4/hsmc4_ecc.c @@ -0,0 +1,703 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include "hsmc4.h" +#include "hsmc4_ecc.h" +#include +#include + +//------------------------------------------------------------------------------ +// Internal function +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/// Counts and return the number of bits set to '1' in the given byte. +/// \param byte Byte to count. +//------------------------------------------------------------------------------ +static unsigned char CountBitsInByte(unsigned char byte) +{ + unsigned char count = 0; + while (byte > 0) { + + if (byte & 1) { + + count++; + } + byte >>= 1; + } + + return count; +} +//------------------------------------------------------------------------------ +/// Counts and return the number of bits set to '1' in the given hsiao code. +/// \param code Hsizo code. +//------------------------------------------------------------------------------ +static unsigned char CountBitsInCode(unsigned char *code) +{ + return CountBitsInByte(code[0]) + + CountBitsInByte(code[1]) + + CountBitsInByte(code[2]); +} + +//------------------------------------------------------------------------------ +/// Get all ECC parity and Nparity value. +//------------------------------------------------------------------------------ +void HSMC4_EccGetValue(unsigned int *ecc) +{ + ecc[0] = AT91C_BASE_HSMC4->HSMC4_ECCPR0; + ecc[1] = AT91C_BASE_HSMC4->HSMC4_ECCPR1; + ecc[2] = AT91C_BASE_HSMC4->HSMC4_ECCPR2; + ecc[3] = AT91C_BASE_HSMC4->HSMC4_ECCPR3; + ecc[4] = AT91C_BASE_HSMC4->HSMC4_ECCPR4; + ecc[5] = AT91C_BASE_HSMC4->HSMC4_ECCPR5; + ecc[6] = AT91C_BASE_HSMC4->HSMC4_ECCPR6; + ecc[7] = AT91C_BASE_HSMC4->HSMC4_ECCPR7; + ecc[8] = AT91C_BASE_HSMC4->HSMC4_ECCPR8; + ecc[9] = AT91C_BASE_HSMC4->HSMC4_ECCPR9; + ecc[10] = AT91C_BASE_HSMC4->HSMC4_ECCPR10; + ecc[11] = AT91C_BASE_HSMC4->HSMC4_ECCPR11; + ecc[12] = AT91C_BASE_HSMC4->HSMC4_ECCPR12; + ecc[13] = AT91C_BASE_HSMC4->HSMC4_ECCPR13; + ecc[14] = AT91C_BASE_HSMC4->HSMC4_ECCPR14; + ecc[15] = AT91C_BASE_HSMC4->HSMC4_Eccpr15; +#ifdef DUMP_ECC_PARITY + TRACE_INFO("Ecc parity(0-7) %x, %x, %x, %x, %x, %x, %x, %x \n\r",ecc[0],ecc[1],ecc[2],ecc[3],ecc[4],ecc[5],ecc[6],ecc[7]); + TRACE_INFO("Ecc parity(8-15) %x, %x, %x, %x, %x, %x, %x, %x \n\r",ecc[8],ecc[9],ecc[10],ecc[11],ecc[12],ecc[13],ecc[14],ecc[15]); +#endif +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/// Configures ECC mode in HSMC4 peripheral as specified. +/// \param type Type of correction. +/// \param pageSize Page size of NAND flash device. +//------------------------------------------------------------------------------ +void HSMC4_EccConfigure(unsigned int type, unsigned int pageSize) +{ + // Software Reset ECC. + AT91C_BASE_HSMC4->HSMC4_ECCCR = (0x1 << 1) ; + AT91C_BASE_HSMC4->HSMC4_ECCCMD = type | pageSize; +} + +//------------------------------------------------------------------------------ +/// Returns type of ECC correction setting. +//------------------------------------------------------------------------------ +unsigned int HSMC4_GetEccCorrectoinType(void) +{ + return ((AT91C_BASE_HSMC4->HSMC4_ECCCMD)& AT91C_ECC_TYPCORRECT); +} + +//------------------------------------------------------------------------------ +/// Returns ECC status by giving ecc number +/// \param eccNumber ecc parity number from 0 to 15. +//------------------------------------------------------------------------------ +unsigned char HSMC4_GetEccStatus(unsigned char eccNumber) +{ + unsigned int status; + if (eccNumber < 8){ + status = AT91C_BASE_HSMC4->HSMC4_ECCSR1; + } + else { + status = AT91C_BASE_HSMC4->HSMC4_ECCSR2; + eccNumber -=8; + } + return ((status >> (eccNumber * 4)) & 0x07); +} +//------------------------------------------------------------------------------ +/// Verifies 4-bytes hsiao codes for a data block whose size is a page Size +/// word. Page words block is verified between the given HSIAO code +/// generated by hardware and original HSIAO codes store has been previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +//------------------------------------------------------------------------------ +static unsigned char HSMC4_VerifyPageOf8bitHsiao( + unsigned char *data, + const unsigned char *originalCode, + const unsigned char *verifyCode) +{ + unsigned char correctionCode[4]; + unsigned char bitCount; + // Xor both codes together + correctionCode[0] = verifyCode[0] ^ originalCode[0]; + correctionCode[1] = verifyCode[1] ^ originalCode[1]; + correctionCode[2] = verifyCode[2] ^ originalCode[2]; + correctionCode[3] = verifyCode[3] ^ originalCode[3]; + TRACE_DEBUG("Correction code = %02X %02X %02X %02X\n\r", + correctionCode[0], correctionCode[1], correctionCode[2], correctionCode[3]); + // If all bytes are 0, there is no error + if ((correctionCode[0] == 0) + && (correctionCode[1] == 0) + && (correctionCode[2] == 0) + && (correctionCode[3] == 0)) { + + return 0; + } + // If there is a single bit error, there are 15 bits set to 1 + bitCount = CountBitsInByte(correctionCode[0]) + + CountBitsInByte(correctionCode[1]) + + CountBitsInByte(correctionCode[2]) + + CountBitsInByte(correctionCode[3]); + if (bitCount == 15) { + // Get byte and bit indexes + unsigned short byte = (correctionCode[0] & 0xf0) >> 4; + byte |= (correctionCode[1] & 0xff) << 4; + unsigned char bit = correctionCode[0] & 0x0f; + // Correct bit + TRACE_INFO("Correcting byte #%d at bit %d\n\r", byte, bit); + data[byte] ^= (1 << bit); + + return Hsiao_ERROR_SINGLEBIT; + } + + // Check if ECC has been corrupted + if (bitCount == 1) { + return Hsiao_ERROR_ECC; + } + // Otherwise, this is a multi-bit error + else { + return Hsiao_ERROR_MULTIPLEBITS; + } +} + +//------------------------------------------------------------------------------ +/// Verifies 3-bytes hsiao codes for a data block whose size is multiple of +/// 256 bytes. Each 256-bytes block is verified between the given HSIAO code +/// generated by hardware and original HSIAO codes store has been previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param size Size of the data in words. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +//------------------------------------------------------------------------------ +static unsigned char HSMC4_Verify256x8bitHsiao( + unsigned char *data, + unsigned int size, + const unsigned char *originalCode, + const unsigned char *verifyCode) +{ + unsigned char correctionCode[3]; + unsigned int position = 0; + unsigned char byte; + unsigned char bit; + unsigned char error = 0; + + TRACE_DEBUG("HSMC4_Verify512x8bitHsiao()\n\r"); + while (position < size) { + // Xor both codes together + correctionCode[0] = verifyCode[0] ^ originalCode[0]; + correctionCode[1] = verifyCode[1] ^ originalCode[1]; + correctionCode[2] = verifyCode[2] ^ originalCode[2]; + TRACE_DEBUG("Correction code = %02X %02X %02X\n\r", + correctionCode[0], correctionCode[1], correctionCode[2]); + + // If all bytes are 0, there is no error + if ( correctionCode[0] || correctionCode[1] || correctionCode[2]) { + // If there is a single bit error, there are 11 bits set to 1 + if (CountBitsInCode(correctionCode) == 11) { + // Get byte and bit indexes + byte = (correctionCode[0] & 0xf8) >> 3; + byte |= (correctionCode[1] & 0x07) << 5; + bit = correctionCode[0] & 0x07; + // Correct bit + TRACE_INFO("Correcting byte #%d at bit %d\n\r", (position + byte), bit); + data[byte] ^= (1 << bit); + error = Hsiao_ERROR_SINGLEBIT; + } + // Check if ECC has been corrupted + else if (CountBitsInCode(correctionCode) == 1) { + return Hsiao_ERROR_ECC; + } + else { + // Otherwise, this is a multi-bit error + return Hsiao_ERROR_MULTIPLEBITS; + } + } + data += 256; + originalCode += 3; + verifyCode += 3; + position += 256; + } + return error; +} + +//------------------------------------------------------------------------------ +/// Verifies 3-bytes hsiao codes for a data block whose size is multiple of +/// 512 bytes. Each 512-bytes block is verified between the given HSIAO code +/// generated by hardware and original HSIAO codes store has been previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param size Size of the data in words. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +//------------------------------------------------------------------------------ +static unsigned char HSMC4_Verify512x8bitHsiao( + unsigned char *data, + unsigned int size, + const unsigned char *originalCode, + const unsigned char *verifyCode) +{ + unsigned char correctionCode[3]; + unsigned int position = 0; + unsigned short byte; + unsigned char bit; + unsigned char error = 0; + + TRACE_DEBUG("HSMC4_Verify512x8bitHsiao()\n\r"); + while (position < size) { + // Xor both codes together + correctionCode[0] = verifyCode[0] ^ originalCode[0]; + correctionCode[1] = verifyCode[1] ^ originalCode[1]; + correctionCode[2] = verifyCode[2] ^ originalCode[2]; + TRACE_DEBUG("Correction code = %02X %02X %02X\n\r", + correctionCode[0], correctionCode[1], correctionCode[2]); + + // If all bytes are 0, there is no error + if ( correctionCode[0] || correctionCode[1] || correctionCode[2]) { + // If there is a single bit error, there are 11 bits set to 1 + if (CountBitsInCode(correctionCode) == 12) { + // Get byte and bit indexes + byte = (correctionCode[0] & 0xf8) >> 3; + byte |= (correctionCode[1] & 0x0f) << 5; + bit = correctionCode[0] & 0x07; + // Correct bit + TRACE_INFO("Correcting byte #%d at bit %d\n\r", (position + byte), bit); + data[byte] ^= (1 << bit); + error = Hsiao_ERROR_SINGLEBIT; + } + // Check if ECC has been corrupted + else if (CountBitsInCode(correctionCode) == 1) { + return Hsiao_ERROR_ECC; + } + else { + // Otherwise, this is a multi-bit error + return Hsiao_ERROR_MULTIPLEBITS; + } + } + data += 512; + originalCode += 3; + verifyCode += 3; + position += 512; + } + return error; +} + +//------------------------------------------------------------------------------ +/// Verifies 4-bytes hsiao codes for a data block whose size is a page Size +/// word. Page words block is verified between the given HSIAO code +/// generated by hardware and original HSIAO codes store has been previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +//------------------------------------------------------------------------------ +static unsigned char HSMC4_VerifyPageOf16bitHsiao( + unsigned short *data, + const unsigned char *originalCode, + const unsigned char *verifyCode) +{ + unsigned char correctionCode[4]; + unsigned char bitCount; + // Xor both codes together + correctionCode[0] = verifyCode[0] ^ originalCode[0]; + correctionCode[1] = verifyCode[1] ^ originalCode[1]; + correctionCode[2] = verifyCode[2] ^ originalCode[2]; + correctionCode[3] = verifyCode[3] ^ originalCode[3]; + TRACE_DEBUG("Correction code = %02X %02X %02X %02X\n\r", + correctionCode[0], correctionCode[1], correctionCode[2], correctionCode[3]); + // If all bytes are 0, there is no error + if ((correctionCode[0] == 0) + && (correctionCode[1] == 0) + && (correctionCode[2] == 0) + && (correctionCode[3] == 0)) { + + return 0; + } + // If there is a single bit error, there are 11 bits set to 1 + bitCount = CountBitsInByte(correctionCode[0]) + + CountBitsInByte(correctionCode[1]) + + CountBitsInByte(correctionCode[2]) + + CountBitsInByte(correctionCode[3]); + printf("bitCount = %d \n\r",bitCount); + if (bitCount == 12) { + // Get byte and bit indexes + unsigned char word = (correctionCode[0] & 0xf0) >> 4; + word |= (correctionCode[1] & 0xff) << 4; + unsigned char bit = correctionCode[0] & 0x0f; + // Correct bit + TRACE_INFO("Correcting word #%d at bit %d\n\r", word, bit); + data[word] ^= (1 << bit); + + return Hsiao_ERROR_SINGLEBIT; + } + + // Check if ECC has been corrupted + if (bitCount == 1) { + return Hsiao_ERROR_ECC; + } + // Otherwise, this is a multi-bit error + else { + return Hsiao_ERROR_MULTIPLEBITS; + } +} + +//------------------------------------------------------------------------------ +/// Verifies 3-bytes hsiao codes for a data block whose size is multiple of +/// 256 word.Each 256-words block is verified between the given HSIAO code +/// generated by hardware and original HSIAO codes store has been previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param size Size of the data in words. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +//------------------------------------------------------------------------------ +static unsigned char HSMC4_Verify256x16bitHsiao( + unsigned short *data, + unsigned int size, + const unsigned char *originalCode, + const unsigned char *verifyCode + ) +{ + unsigned char correctionCode[3]; + unsigned int position = 0; + unsigned char word; + unsigned char bit; + unsigned char error = 0; + + TRACE_DEBUG("HSMC4_Verify512x8bitHsiao()\n\r"); + while (position < size) { + // Xor both codes together + correctionCode[0] = verifyCode[0] ^ originalCode[0]; + correctionCode[1] = verifyCode[1] ^ originalCode[1]; + correctionCode[2] = verifyCode[2] ^ originalCode[2]; + TRACE_DEBUG("Correction code = %02X %02X %02X\n\r", + correctionCode[0], correctionCode[1], correctionCode[2]); + + // If all bytes are 0, there is no error + if ( correctionCode[0] || correctionCode[1] || correctionCode[2]) { + // If there is a single bit error, there are 11 bits set to 1 + if (CountBitsInCode(correctionCode) == 12) { + // Get word and bit indexes + word = (correctionCode[0] & 0xf0) >> 4; + word |= (correctionCode[1] & 0x0f) << 4; + bit = correctionCode[0] & 0x0f; + // Correct bit + TRACE_INFO("Correcting word #%d at bit %d\n\r", (position + word), bit); + data[word] ^= (1 << bit); + error = Hsiao_ERROR_SINGLEBIT; + } + // Check if ECC has been corrupted + else if (CountBitsInCode(correctionCode) == 1) { + return Hsiao_ERROR_ECC; + } + else { + // Otherwise, this is a multi-bit error + return Hsiao_ERROR_MULTIPLEBITS; + } + } + data += 256; + originalCode += 3; + verifyCode += 3; + position += 256; + } + return error; +} + +//------------------------------------------------------------------------------ +/// Verifies hsiao codes for a data block. The block is verified between the given +/// HSIAO code generated by hardware and original HSIAO codes store has been +/// previously stored. +/// Returns 0 if the data is correct, Hsiao_ERROR_SINGLEBIT if one or more +/// block(s) have had a single bit corrected, or either Hsiao_ERROR_ECC +/// or Hsiao_ERROR_MULTIPLEBITS. +/// \param data Data buffer to verify. +/// \param size Size of the data in words. +/// \param originalCode Original codes. +/// \param verifyCode codes to be verified. +/// \param dataPath 8bit/16bit data path. +//------------------------------------------------------------------------------ +unsigned char HSMC4_VerifyHsiao( + unsigned char *data, + unsigned int size, + const unsigned char *originalCode, + const unsigned char *verifyCode, + unsigned char dataPath) +{ + unsigned char correctionType; + unsigned char error = 0; + correctionType = HSMC4_GetEccCorrectoinType(); + // For 16-bit data path + if (dataPath == 16) { + switch (correctionType){ + case AT91C_ECC_TYPCORRECT_ONE_PER_PAGE: + error = HSMC4_VerifyPageOf16bitHsiao((unsigned short*)data, originalCode, verifyCode); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_256_BYTES: + error= HSMC4_Verify256x16bitHsiao((unsigned short*)data, size / 2, originalCode, verifyCode); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_512_BYTES: + TRACE_WARNING("16-bit 512 per page correction not yet implement! \n\r"); + break; + } + } + // For 8-bit data path + else { + switch (correctionType){ + case AT91C_ECC_TYPCORRECT_ONE_PER_PAGE: + error = HSMC4_VerifyPageOf8bitHsiao(data, originalCode, verifyCode); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_256_BYTES: + error = HSMC4_Verify256x8bitHsiao(data, size, originalCode, verifyCode); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_512_BYTES: + error = HSMC4_Verify512x8bitHsiao(data, size, originalCode, verifyCode); + break; + } + } + return error; +} + +//------------------------------------------------------------------------------ +/// Get 32-bit ECC code for 16-bit data path NAND flash. +/// 32-bit ECC is generated in order to perform one bit correction +/// for a page in page 512/1024/2048/4096 for 16-bit words +/// \param size Data size in bytes. +/// \param code Codes buffer. +//------------------------------------------------------------------------------ +void HSMC4_Get24bitPerPageEcc(unsigned int pageDataSize, unsigned char *code) +{ + unsigned int eccParity; + unsigned int eccNparity; + unsigned int ecc[16]; + // Get Parity value. + HSMC4_EccGetValue(ecc); + + // ---- P16384'P8192'P4096'P2048' P1024'P512'P256' --- 4th. Ecc Byte to store + /// P128' P64' P32' P16' P8' P4' P2' P1' --- 3rd. Ecc Byte to store + // ---- P16384 P8192 P4096 P2048 P1024 P512 P256 --- 2nd. Ecc Byte to store + // P128 P64 P32 P16 P8 P4 P2 P1 --- 1st. Ecc Byte to store + + // Invert codes (linux compatibility) + eccParity = ~(ecc[0]); + eccNparity = ~(ecc[1]); + TRACE_DEBUG("ecc Parity is 0x%08x, ecc Nparity is 0x%08x \n\r", eccParity, eccNparity); + code[0] = eccParity & 0xff; + code[1] = (eccParity >> 8 )& 0xff; + code[2] = eccNparity & 0xff; + code[3] = (eccNparity >> 8 )& 0xff; +} + +//------------------------------------------------------------------------------ +/// Get 24-bit ECC code for 8-bit data path NAND flash. +/// 24-bit ECC is generated in order to perform one bit correction +/// for 256 byte in page 512/1024/2048/4096 for 8-bit words +/// \param size Data size in bytes. +/// \param code Codes buffer. +//------------------------------------------------------------------------------ +void HSMC4_Get24bitPer256Ecc(unsigned int pageDataSize, unsigned char *code) +{ + unsigned char i; + unsigned char numEcc; + unsigned int eccParity; + unsigned int ecc[16]; + HSMC4_EccGetValue(ecc); + numEcc = pageDataSize / 256; + + // P2048' P1024' P512' P256' P128' P64' P32' P16' --- 3rd. Ecc Byte to store + // P8' P4' P2' P1' P2048 P1024 P512 P256 --- 2nd. Ecc Byte to store + // P128 P64 P32 P16 P8 P4 P2 P1 --- 1st. Ecc Byte to store + for (i = 0; i < numEcc; i++) { + // Get Parity and NParity value. + eccParity = ecc[i]; + // Invert codes (linux compatibility) + eccParity = ~eccParity; + TRACE_DEBUG("ecc Parity%d is 0x%08x \n\r", i, eccParity); + code[i * 3] = eccParity & 0xff; + code[i * 3 + 1] = (eccParity >> 8) & 0xff; + code[i * 3 + 2] = (eccParity >> 16) & 0xff; + } +} + +//------------------------------------------------------------------------------ +/// Get 24-bit ECC code for 8-bit data path NAND flash. +/// 24-bit ECC is generated in order to perform one bit correction +/// for 512 byte in page 512/1024/2048/4096 for 8-bit words +/// \param size Data size in bytes. +/// \param code Codes buffer. +//------------------------------------------------------------------------------ +void HSMC4_Get24bitPer512Ecc(unsigned int pageDataSize, unsigned char *code) +{ + unsigned char i; + unsigned char numEcc; + unsigned int eccParity; + unsigned int ecc[16]; + HSMC4_EccGetValue(ecc); + numEcc = pageDataSize / 512; + + // P2048' P1024' P512' P256' P128' P64' P32' P16' --- 3rd. Ecc Byte to store + // P8' P4' P2' P1' P2048 P1024 P512 P256 --- 2nd. Ecc Byte to store + // P128 P64 P32 P16 P8 P4 P2 P1 --- 1st. Ecc Byte to store + for (i = 0; i < numEcc; i++) { + // Get Parity and NParity value. + eccParity = ecc[i]; + // Invert codes (linux compatibility) + eccParity = ~eccParity; + TRACE_DEBUG("ecc Parity%d is 0x%08x \n\r", i, eccParity); + code[i * 3] = eccParity & 0xff; + code[i * 3 + 1] = (eccParity >> 8) & 0xff; + code[i * 3 + 2] = (eccParity >> 16) & 0xff; + } +} + +//------------------------------------------------------------------------------ +/// Get 32-bit ECC code for 16-bit data path NAND flash. +/// 32-bit ECC is generated in order to perform one bit correction +/// for 256 word in page 512/1024/2048/4096 for 16-bit words +/// \param size Data size in bytes. +/// \param code Codes buffer. +//------------------------------------------------------------------------------ +void HSMC4_Get32bitPer256Ecc(unsigned int pageDataSize, unsigned char *code) +{ + unsigned char i; + unsigned char numEcc; + unsigned int eccParity; + unsigned int eccNparity; + unsigned int ecc[16]; + HSMC4_EccGetValue(ecc); + numEcc = pageDataSize / 256; + + // P2048' P1024' P512' P256' P128' P64' P32' P16' --- 3rd. Ecc Byte to store + // P8' P4' P2' P1' P2048 P1024 P512 P256 --- 2nd. Ecc Byte to store + // P128 P64 P32 P16 P8 P4 P2 P1 --- 1st. Ecc Byte to store + for (i = 0; i < numEcc; i+= 2) { + // Get Parity value. + eccParity = ecc[i]; + // Invert codes (linux compatibility) + eccParity = ~eccParity; + // Get NParity value. + eccNparity = ecc[i + 1]; + eccNparity = ~eccNparity; + TRACE_DEBUG("ecc Parity%d is 0x%08x, ecc Nparity%d is 0x%08x \n\r", i, eccParity, i, eccNparity); + code[i * 3] = eccParity & 0xff; + code[i * 3 + 1] = ((eccParity >> 8) & 0x0f ) | ((eccNparity & 0x0f) << 4); + code[i * 3 + 2] = (eccNparity >> 4) & 0xff; + + code[(i + 1) * 3] = (eccParity >> 16) & 0xff; + code[(i + 1) * 3 + 1] = ((eccParity >> 24) & 0x0f ) | (((eccNparity >> 16)& 0x0f) << 4); + code[(i + 1) * 3 + 2] = (eccNparity >> 20) & 0xff; + + } +} + +//------------------------------------------------------------------------------ +/// Get 32-bit ECC code for 16-bit data path NAND flash. +/// 32-bit ECC is generated in order to perform one bit correction +/// for a page in page 512/1024/2048/4096 for 16-bit words +/// \param size Data size in bytes. +/// \param code Codes buffer. +//------------------------------------------------------------------------------ +void HSMC4_Get32bitPerPageEcc(unsigned int pageDataSize, unsigned char *code) +{ + unsigned int eccParity; + unsigned int eccNparity; + unsigned int ecc[16]; + // Get Parity value. + HSMC4_EccGetValue(ecc); + + // ---- P16384'P8192'P4096'P2048' P1024'P512'P256' --- 4th. Ecc Byte to store + /// P128' P64' P32' P16' P8' P4' P2' P1' --- 3rd. Ecc Byte to store + // ---- P16384 P8192 P4096 P2048 P1024 P512 P256 --- 2nd. Ecc Byte to store + // P128 P64 P32 P16 P8 P4 P2 P1 --- 1st. Ecc Byte to store + + // Invert codes (linux compatibility) + eccParity = ~(ecc[0]); + eccNparity = ~(ecc[1]); + TRACE_DEBUG("ecc Parity%d is 0x%08x, ecc Nparity%d is 0x%08x \n\r", eccParity, eccNparity); + code[0] = eccParity & 0xff; + code[1] = (eccParity >> 8 )& 0xff; + code[2] = eccNparity & 0xff; + code[3] = (eccNparity >> 8 )& 0xff; +} + +//------------------------------------------------------------------------------ +/// Get ECC code for 8bit/16-bit data path NAND flash by giving data path. +/// 24-bit or 32-bit ECC is generated in order to perform one bit correction +/// for a page in page 512/1024/2048/4096. +/// \param size Data size in bytes. +/// \param code Codes buffer. +/// \param dataPath 8bit/16bit data path. +//------------------------------------------------------------------------------ +void HSMC4_GetEccParity(unsigned int pageDataSize, unsigned char *code, unsigned char dataPath) +{ + unsigned char correctionType; + correctionType = HSMC4_GetEccCorrectoinType(); + // For 16-bit data path + if (dataPath == 16) { + switch (correctionType){ + case AT91C_ECC_TYPCORRECT_ONE_PER_PAGE: + HSMC4_Get32bitPerPageEcc(pageDataSize, code); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_256_BYTES: + HSMC4_Get32bitPer256Ecc(pageDataSize, code); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_512_BYTES: + TRACE_WARNING("16 bit 512 byte correct not yet implement! \n\r"); + break; + } + } + // For 8-bit data path + else { + switch (correctionType){ + case AT91C_ECC_TYPCORRECT_ONE_PER_PAGE: + HSMC4_Get24bitPerPageEcc(pageDataSize, code); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_256_BYTES: + HSMC4_Get24bitPer256Ecc(pageDataSize, code); + break; + case AT91C_ECC_TYPCORRECT_ONE_EVERY_512_BYTES: + HSMC4_Get24bitPer512Ecc(pageDataSize, code); + break; + } + } +} \ No newline at end of file diff --git a/peripherals/hsmc4/hsmc4_ecc.h b/peripherals/hsmc4/hsmc4_ecc.h new file mode 100644 index 0000000..8ddcc87 --- /dev/null +++ b/peripherals/hsmc4/hsmc4_ecc.h @@ -0,0 +1,85 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef HSMC4_ECC_H +#define HSMC4_ECC_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Hsiao Code Errors" +/// These are the possible errors when trying to verify a block of data encoded +/// using a Hsiao code: +/// +/// !Errors: +/// - Hsiao_ERROR_SINGLEBIT +/// - Hsiao_ERROR_ECC +/// - Hsiao_ERROR_MULTIPLEBITS + +/// A single bit was incorrect but has been recovered. +#define Hsiao_ERROR_SINGLEBIT 1 + +/// The original code has been corrupted. +#define Hsiao_ERROR_ECC 2 + +/// Multiple bits are incorrect in the data and they cannot be corrected. +#define Hsiao_ERROR_MULTIPLEBITS 3 + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void HSMC4_EccConfigure(unsigned int type, unsigned int pageSize); + +extern unsigned int HSMC4_GetEccCorrectoinType(void); + +extern void HSMC4_EccGetValue(unsigned int *ecc); + +extern void HSMC4_GetEccParity( + unsigned int pageDataSize, + unsigned char *code, + unsigned char dataPath); + +extern unsigned char HSMC4_VerifyHsiao( + unsigned char *data, + unsigned int size, + const unsigned char *originalCode, + const unsigned char *verifyCode, + unsigned char dataPath); + +#endif //#ifndef HSMC4_ECC_H + -- cgit v1.2.3