//------------------------------------------------------------------------------ /// Writes the data and/or spare area of a nandflash page, after calculating an /// ECC for the data area and storing it in the spare. If no data buffer is /// provided, the ECC is read from the existing page spare. If no spare buffer /// is provided, the spare area is still written with the ECC information /// calculated on the data buffer. /// Returns 0 if successful; otherwise returns an error code. /// \param ecc Pointer to an EccNandFlash instance. /// \param block Number of the block to write in. /// \param page Number of the page to write inside the given block. /// \param data Data area buffer, can be 0. /// \param spare Spare area buffer, can be 0. //------------------------------------------------------------------------------ unsigned char EccNandFlash_WritePage( const struct EccNandFlash *ecc, unsigned short block, unsigned short page, void *data, void *spare) { unsigned char error; unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc)); unsigned short pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc)); unsigned char hamming[NandCommon_MAXSPAREECCBYTES]; ASSERT(data || spare, "EccNandFlash_WritePage: At least one area must be written\n\r"); TRACE_DEBUG("EccNandFlash_WritePage(B#%d:P#%d)\n\r", block, page); // Compute ECC on the new data, if provided // If not provided, hamming code set to 0xFFFF.. to keep existing bytes memset(hamming, 0xFF, NandCommon_MAXSPAREECCBYTES); if (data) { // Compute hamming code on data Hamming_Compute256x(data, pageDataSize, hamming); } // Store code in spare buffer (if no buffer provided, use a temp. one) if (!spare) { spare = tmpSpare; memset(spare, 0xFF, pageSpareSize); } NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hamming); // Perform write operation error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) { TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; } return 0; }
//------------------------------------------------------------------------------ /// Writes the data and/or spare area of a nandflash page, after calculating an /// ECC for the data area and storing it in the spare. If no data buffer is /// provided, the ECC is read from the existing page spare. If no spare buffer /// is provided, the spare area is still written with the ECC information /// calculated on the data buffer. /// Returns 0 if successful; otherwise returns an error code. /// \param ecc Pointer to an EccNandFlash instance. /// \param block Number of the block to write in. /// \param page Number of the page to write inside the given block. /// \param data Data area buffer, can be 0. /// \param spare Spare area buffer, can be 0. //------------------------------------------------------------------------------ unsigned char EccNandFlash_WritePage( struct EccNandFlash *ecc, unsigned short block, unsigned short page, void *data, void *spare) { unsigned char error; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc)); unsigned short pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc)); unsigned char *pSpareBuffer = RawNandFlash_GetSpareBuffer(RAW(ecc)); ASSERT(data || spare, "EccNandFlash_WritePage: At least one area must be written\n\r"); TRACE_DEBUG("EccNandFlash_WritePage(B#%d:P#%d)\n\r", block, page); #ifndef HARDWARE_ECC // Compute ECC on the new data, if provided // If not provided, hamming code set to 0xFFFF.. to keep existing bytes memset(ecc->hamming, 0xFF, NandCommon_MAXSPAREECCBYTES); if (data) { // Compute hamming code on data Hamming_Compute256x(data, pageDataSize, ecc->hamming); } // Store code in spare buffer (if no buffer provided, use a temp. one) if (!spare) { spare = pSpareBuffer; memset(spare, 0xFF, pageSpareSize); } NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, ecc->hamming); // Perform write operation error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) goto error; #else // Store code in spare buffer (if no buffer provided, use a temp. one) if (!spare) { spare = pSpareBuffer; memset(spare, 0xFF, pageSpareSize); } // Perform write operation error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) goto error; HSMC4_GetEccParity(pageDataSize, hsiao, NandFlashModel_GetDataBusWidth(MODEL(ecc))); // Perform write operation NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hsiao); error = RawNandFlash_WritePage(RAW(ecc), block, page, 0, spare); if (error) goto error; #endif RawNandFlash_ReleaseSpareBuffer(RAW(ecc)); return 0; error: RawNandFlash_ReleaseSpareBuffer(RAW(ecc)); TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; }
/** * \brief Writes the data and/or spare area of a nandflash page, after calculating an * ECC for the data area and storing it in the spare. If no data buffer is * provided, the ECC is read from the existing page spare. If no spare buffer * is provided, the spare area is still written with the ECC information * calculated on the data buffer. * \param ecc Pointer to an EccNandFlash instance. * \param block Number of block to read from. * \param page Number of page to read inside given block. * \param data Data area buffer. * \param spare Spare area buffer. * \return 0 if successful; otherwise returns an error code. */ unsigned char EccNandFlash_WritePage( const struct EccNandFlash *ecc, unsigned short block, unsigned short page, void *data, void *spare) { unsigned char error; unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc)); unsigned short pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc)); #ifndef HARDWARE_ECC unsigned char hamming[NandCommon_MAXSPAREECCBYTES]; #else unsigned char hsiao[NandCommon_MAXSPAREECCBYTES]; #endif assert( (data != NULL) || (spare != NULL) ) ; // TRACE_DEBUG( "EccNandFlash_WritePage: At least one area must be written\n\r" ) ; TRACE_DEBUG("EccNandFlash_WritePage(B#%d:P#%d)\n\r", block, page); #ifndef HARDWARE_ECC /* Compute ECC on the new data, if provided */ /* If not provided, hamming code set to 0xFFFF.. to keep existing bytes */ memset(hamming, 0xFF, NandCommon_MAXSPAREECCBYTES); if (data) { /* Compute hamming code on data */ Hamming_Compute256x(data, pageDataSize, hamming); } /* Store code in spare buffer (if no buffer provided, use a temp. one) */ if (!spare) { spare = tmpSpare; memset(spare, 0xFF, pageSpareSize); } NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hamming); /* Perform write operation */ error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) { TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; } #else /* Store code in spare buffer (if no buffer provided, use a temp. one) */ if (!spare) { spare = tmpSpare; memset(spare, 0xFF, pageSpareSize); } /* Perform write operation */ error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare); if (error) { TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; } HSMC4_GetEccParity(pageDataSize, hsiao, NandFlashModel_GetDataBusWidth(MODEL(ecc))); /* Perform write operation */ NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hsiao); error = RawNandFlash_WritePage(RAW(ecc), block, page, 0, spare); if (error) { TRACE_ERROR("EccNandFlash_WritePage: Failed to write page\n\r"); return error; } #endif return 0; }