/** * @brief * tear down logicalAddressToReservePhysical test * @return 1 if succesful, 0 otherwise */ error_t tearDown_logicalAddressToReservePhysicalTest(){ uint32_t i, j; // PRINT("\ntear down"); for(i=0; i< SEQ_N_SLOTS_COUNT; i++){ seg_map_ptr->seg_to_slot_map[i] = SEQ_NO_SLOT; } // delete segments for(i=0; i<SEQ_N_SLOTS_COUNT; i++){ /* erase eu's one by one from the segment */ j = i * SEQ_PAGES_PER_SLOT; for(; j< (i+1)* SEQ_PAGES_PER_SLOT; j+=NAND_PAGES_PER_ERASE_UNIT){ // if we encounter the first valid EU if(nandCheckEuStatus(j)){ /* erase it */ nandErase(j); } } } nandTerminate(); return 1; }
static void kill_block(NANDDriver *nandp, uint32_t block){ size_t i = 0; size_t page = 0; uint8_t op_status; /* This test requires good block.*/ osalDbgCheck(!nandIsBad(nandp, block)); while(true){ op_status = nandErase(&NAND, block); if (0 != (op_status & 1)){ if(!is_erased(nandp, block)) osalSysHalt("Block successfully killed"); } if(!is_erased(nandp, block)) osalSysHalt("Block block not erased, but erase operation report success"); for (page=0; page<nandp->config->pages_per_block; page++){ memset(nand_buf, 0, NAND_PAGE_SIZE); op_status = nandWritePageWhole(nandp, block, page, nand_buf, NAND_PAGE_SIZE); if (0 != (op_status & 1)){ nandReadPageWhole(nandp, block, page, nand_buf, NAND_PAGE_SIZE); for (i=0; i<NAND_PAGE_SIZE; i++){ if (nand_buf[i] != 0) osalSysHalt("Block successfully killed"); } } nandReadPageWhole(nandp, block, page, nand_buf, NAND_PAGE_SIZE); for (i=0; i<NAND_PAGE_SIZE; i++){ if (nand_buf[i] != 0) osalSysHalt("Page write failed, but write operation report success"); } } KillCycle++; } }
static void general_test (NANDDriver *nandp, size_t first, size_t last, size_t read_rounds){ size_t block, page, round; bool status; uint8_t op_status; uint32_t recc, wecc; red_led_on(); /* initialize time measurement units */ chTMObjectInit(&tmu_erase); chTMObjectInit(&tmu_write_data); chTMObjectInit(&tmu_write_spare); chTMObjectInit(&tmu_read_data); chTMObjectInit(&tmu_read_spare); /* perform basic checks */ for (block=first; block<last; block++){ if (!nandIsBad(nandp, block)){ if (!is_erased(nandp, block)){ op_status = nandErase(nandp, block); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ } } } /* write block with pattern, read it back and compare */ for (block=first; block<last; block++){ if (!nandIsBad(nandp, block)){ for (page=0; page<nandp->config->pages_per_block; page++){ pattern_fill(); chTMStartMeasurementX(&tmu_write_data); op_status = nandWritePageData(nandp, block, page, nand_buf, nandp->config->page_data_size, &wecc); chTMStopMeasurementX(&tmu_write_data); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ chTMStartMeasurementX(&tmu_write_spare); op_status = nandWritePageSpare(nandp, block, page, nand_buf + nandp->config->page_data_size, nandp->config->page_spare_size); chTMStopMeasurementX(&tmu_write_spare); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ /* read back and compare */ for (round=0; round<read_rounds; round++){ memset(nand_buf, 0, NAND_PAGE_SIZE); chTMStartMeasurementX(&tmu_read_data); nandReadPageData(nandp, block, page, nand_buf, nandp->config->page_data_size, &recc); chTMStopMeasurementX(&tmu_read_data); osalDbgCheck(0 == (recc ^ wecc)); /* ECC error detected */ chTMStartMeasurementX(&tmu_read_spare); nandReadPageSpare(nandp, block, page, nand_buf + nandp->config->page_data_size, nandp->config->page_spare_size); chTMStopMeasurementX(&tmu_read_spare); osalDbgCheck(0 == memcmp(ref_buf, nand_buf, NAND_PAGE_SIZE)); /* Read back failed */ } } /* make clean */ chTMStartMeasurementX(&tmu_erase); op_status = nandErase(nandp, block); chTMStopMeasurementX(&tmu_erase); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ status = is_erased(nandp, block); osalDbgCheck(true == status); /* blocks was not erased successfully */ }/* if (!nandIsBad(nandp, block)){ */ } red_led_off(); }
static void ecc_test(NANDDriver *nandp, uint32_t block){ uint32_t corrupted; uint32_t byte, bit; const uint32_t ecclen = 28; uint32_t ecc_ref, ecc_broken; uint8_t op_status; ecc_result_t ecc_result = ECC_NO_ERROR; /* This test requires good block.*/ osalDbgCheck(!nandIsBad(nandp, block)); if (!is_erased(nandp, block)) nandErase(&NAND, block); pattern_fill(); /*** Correctable errors ***/ op_status = nandWritePageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_ref); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ nandReadPageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_broken); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_NO_ERROR == ecc_result); /* unexpected error */ /**/ byte = 0; bit = 7; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 1, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 2047; bit = 0; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 2, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 1027; bit = 3; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 3, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /*** Uncorrectable error ***/ byte = 1027; invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); op_status = nandWritePageData(nandp, block, 4, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); ecc_result = parse_ecc(28, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_UNCORRECTABLE_ERROR == ecc_result); /* This error must be NOT correctable */ /*** make clean ***/ nandErase(&NAND, block); }