/** * \brief Write the data and/or spare area of a NAND Flash 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 nand_flash_ecc 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 return the error code. */ uint32_t nand_flash_ecc_write_page(const struct nand_flash_ecc *ecc, uint16_t block, uint16_t page, uint8_t *data, uint8_t *spare) { uint32_t error; uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(ecc)); uint8_t hamming_code[NAND_COMMON_MAX_SPARE_ECC_BYTES]; uint8_t spare_buffer[NAND_COMMON_MAX_PAGE_SPARE_SIZE]; /** * Compute ECC on the new data, if provided. If not provided, hamming * code set to 0xFFFF.. to keep existing bytes. */ memset(hamming_code, 0xFF, NAND_COMMON_MAX_SPARE_ECC_BYTES); if (data) { /* Compute hamming code on data */ hamming_compute_256x(data, page_data_size, hamming_code); } /* if no buffer provided, use a temp one */ if (!spare) { spare = spare_buffer; } memset(spare, 0xFF, NAND_COMMON_MAX_PAGE_SPARE_SIZE); nand_flash_spare_scheme_write_ecc(nand_flash_model_get_scheme(MODEL(ecc)), spare, hamming_code); /* Perform write operation */ error = nand_flash_raw_write_page(RAW(ecc), block, page, data, spare); if (error) { return error; } return 0; }
int main(void) { uint16_t block, page; uint32_t i; uint32_t error = 0; /* Initialize the SAM3 system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("-- NAND Flash Raw Example --\n\r"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); memset(&nf_raw, 0, sizeof(nf_raw)); if (nand_flash_raw_initialize(&nf_raw, 0, cmd_address, addr_address, data_address)) { printf("-E- Device Unknown\n\r"); return 0; } printf("-I- NAND Flash driver initialized\n\r"); /* Get device parameters */ mem_size = nand_flash_model_get_device_size_in_bytes(&nf_raw.model); block_size = nand_flash_model_get_block_size_in_bytes(&nf_raw.model); num_block = nand_flash_model_get_device_size_in_blocks(&nf_raw.model); page_size = nand_flash_model_get_page_data_size(&nf_raw.model); pages_per_block = nand_flash_model_get_block_size_in_pages(&nf_raw.model); printf("-I- Size of the whole device in bytes : 0x%x \n\r", mem_size); printf("-I- Size in bytes of one single block of a device : 0x%x \n\r", block_size); printf("-I- Number of blocks in the entire device : 0x%x \n\r", num_block); printf("-I- Size of the data area of a page in bytes : 0x%x \n\r", page_size); printf("-I- Number of pages in the entire device : 0x%x \n\r", pages_per_block); /* Erase all block and use the last good block for read/write test */ for (i = 0; i < num_block; i++) { error = nand_flash_raw_erase_block(&nf_raw, i); if (error == NAND_COMMON_ERROR_BADBLOCK) { printf("-E- Block %u is BAD block. \n\r", i); } else { block = i; } } /* Prepare a page size buffer in SRAM. */ printf("-I- Preparing a buffer in SRAM ...\n\r"); for (i = 0; i < page_size; i++) { write_buffer[i] = i & 0xFF; } /* Reset read buffer. */ memset(read_buffer, 0, sizeof(read_buffer)); /* Select a page. */ page = 0; /* Write a page to the NAND Flash. */ printf("-I- Write the buffer in page %d of block %d without ECC.\n\r", page, block); error = nand_flash_raw_write_page(&nf_raw, block, page, write_buffer, 0); if (error) { printf("-E- Cannot write page %d of block %d.\n\r", page, block); return error; } /* Read the page from the NAND Flash. */ printf("-I- Read page %d of block %d without ECC.\n\r", page, block); nand_flash_raw_read_page(&nf_raw, block, page, read_buffer, 0); /* Test if the read buffer is the same as SRAM buffer */ error = memcmp(read_buffer, write_buffer, sizeof(write_buffer)); if (error) { printf("-I- Read data is different from write data.\n\r"); printf("-I- Need ECC module when handle this page.\n\r"); return 0; } printf("-I- Read data matches write data.\n\r"); printf("-I- Test passed.\n\r"); while (1) { /* Do nothing */ } }