Giter VIP home page Giter VIP logo

Comments (14)

dlbeer avatar dlbeer commented on August 16, 2024 1

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

I should also note that the lines of the output that start with "NAND Flash Read/Program" are emitted from the nand.c functions such as dhara_nand_read, etc so that I can track the sectors/pages that the map layer is reading/writing.

from dhara.

dlbeer avatar dlbeer commented on August 16, 2024

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

I added a debug statement at the beginning and end of my dhara_nand_is_bad function to ensure it was returning 0.

/* Is the given block bad? */
int dhara_nand_is_bad(const struct dhara_nand *n, dhara_block_t b)
{
	debug_print("NAND Flash - Checking to see if block %lu is bad...\n", b);
	FLASH_PageSpareSection spareData = { 0xFF };
	// Need to just read the last 64 bytes of the sector 0 of the first page of the block
	uint16_t pageAddr = b * (1 << n->log2_ppb);
	if(!FLASH_ReadPageData(&Flash, pageAddr))
		return 1;
	
	while (FLASH_IsBusy(&Flash));
	
	if (!FLASH_Read(&Flash, FACTORY_BAD_BLOCK_OFFSET, (uint8_t*)&spareData, BAD_BLOCK_DATA_LEN))
		return 1;
	
	// Should have valid data regarding block status
	uint8_t isBadBlock = (spareData.FactoryBadBlockMarker != FLASH_BLOCK_OK || spareData.UserBadBlockMarker != FLASH_BLOCK_OK);

	debug_print("NAND Flash - is Block %lu bad? %i\n", b, isBadBlock);

	return isBadBlock; 
}

/* Mark bad the given block (or attempt to). No return value is
 * required, because there's nothing that can be done in response.
 */
void dhara_nand_mark_bad(const struct dhara_nand *n, dhara_block_t b)
{
	debug_print("NAND Flash - Attempting to mark Block %lu as bad!\n", b);
	// the 2048th Bit (0 indexed) is the factory bad block marker.
	// We want to mark the 2049th byte as a 0x01
	uint8_t userBadBlockMarker = FLASH_BLOCK_USER_FAIL;
	// Need to just read the page into the buffer so we can set just the OOB bad block marker byte to 0x01
	if(!FLASH_ReadPageData(&Flash, b << n->log2_ppb))
		return;
	
	while (FLASH_IsBusy(&Flash)) ;
	
	if (!FLASH_WritePageRandom(&Flash, FACTORY_BAD_BLOCK_OFFSET + 1, &userBadBlockMarker, sizeof(userBadBlockMarker)))
		return;
	
	while (FLASH_IsBusy(&Flash)) ;
	
	if (!FLASH_ProgramExecute(&Flash, b << n->log2_ppb))
		return;
	__ASM("nop");
	// Success but return is void
}

Here is that new output:

================ NAND Erase ================
================ Block Device Init (Dhara FTL) ================
Dhara FTL - Map Init
FTL - Map Init Complete. Resuming...
NAND Flash - Checking to see if block 0 is bad...
NAND Flash - is Block 0 bad? 0
NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 1 is bad...
NAND Flash - is Block 1 bad? 0
NAND Flash Read - Sector: 259 - Page/SubSector: 64/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 2 is bad...
NAND Flash - is Block 2 bad? 0
NAND Flash Read - Sector: 515 - Page/SubSector: 128/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 3 is bad...
NAND Flash - is Block 3 bad? 0
NAND Flash Read - Sector: 771 - Page/SubSector: 192/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 4 is bad...
NAND Flash - is Block 4 bad? 0
NAND Flash Read - Sector: 1027 - Page/SubSector: 256/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 5 is bad...
NAND Flash - is Block 5 bad? 0
NAND Flash Read - Sector: 1283 - Page/SubSector: 320/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 6 is bad...
NAND Flash - is Block 6 bad? 0
NAND Flash Read - Sector: 1539 - Page/SubSector: 384/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 7 is bad...
NAND Flash - is Block 7 bad? 0
NAND Flash Read - Sector: 1795 - Page/SubSector: 448/3 - Offset: 0 - Length: 512
Map Initialized. Could not find existing journal. head = 0
Error initializing journal: Too many bad blocks
Map Capacity: 152628
Initial Sync...
Map Count: 0

I performed a dhara_nand_mark_bad(&BlockDevice.nand, 0); to see if the bad block detection would then detect that block and skip it and I had the following results:

================ NAND Erase ================
NAND Flash - Attempting to mark Block 0 as bad!
================ Block Device Init (Dhara FTL) ================
Dhara FTL - Map Init
FTL - Map Init Complete. Resuming...
NAND Flash - Checking to see if block 0 is bad...
NAND Flash - is Block 0 bad? 1
NAND Flash - Checking to see if block 1 is bad...
NAND Flash - is Block 1 bad? 0
NAND Flash Read - Sector: 259 - Page/SubSector: 64/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 2 is bad...
NAND Flash - is Block 2 bad? 0
NAND Flash Read - Sector: 515 - Page/SubSector: 128/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 3 is bad...
NAND Flash - is Block 3 bad? 0
NAND Flash Read - Sector: 771 - Page/SubSector: 192/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 4 is bad...
NAND Flash - is Block 4 bad? 0
NAND Flash Read - Sector: 1027 - Page/SubSector: 256/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 5 is bad...
NAND Flash - is Block 5 bad? 0
NAND Flash Read - Sector: 1283 - Page/SubSector: 320/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 6 is bad...
NAND Flash - is Block 6 bad? 0
NAND Flash Read - Sector: 1539 - Page/SubSector: 384/3 - Offset: 0 - Length: 512
NAND Flash - Checking to see if block 7 is bad...
NAND Flash - is Block 7 bad? 0
NAND Flash Read - Sector: 1795 - Page/SubSector: 448/3 - Offset: 0 - Length: 512
Map Initialized. Could not find existing journal. head = 0
Error initializing journal: Too many bad blocks
Map Capacity: 152628
Initial Sync...
Map Count: 0

You can see where when I have block 0 marked as bad, the resume routine skips checking sectors inside that block. Does that prove my is_bad function is working as intended?

Should the dhara_map_resume write initialization data if it doesn't find a journal and it finds a good block? Or should it only occur on a subsequent sync operation?

Thanks again for helping me on this!

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

It looks like in the journal_resume (which map_resume) calls, is this code.

	/* Find the first checkpoint-containing block */
	if (find_checkblock(j, 0, &first, err) < 0) {
		reset_journal(j);
		return -1;
	}

It appears that if it can't find a checkblock, then clear the journal vars and return -1.

For the find_checkblock function:

/* Find the first checkpoint-containing block. If a block contains any
 * checkpoints at all, then it must contain one in the first checkpoint
 * location -- otherwise, we would have considered the block eraseable.
 */
static int find_checkblock(struct dhara_journal *j,
			   dhara_block_t blk, dhara_block_t *where,
			   dhara_error_t *err)
{
	int i;

	for (i = 0; (blk < j->nand->num_blocks) && (i < DHARA_MAX_RETRIES); i++) {
		const dhara_page_t p = (blk << j->nand->log2_ppb) | ((1 << j->log2_ppc) - 1);
		if (!(dhara_nand_is_bad(j->nand, blk) || dhara_nand_read(j->nand, p, 0, 1 << j->nand->log2_page_size, j->page_buf, err)) 
			&& hdr_has_magic(j->page_buf)) 
		{
			*where = blk;
			return 0;
		}

		blk++;
	}

	dhara_set_error(err, DHARA_E_TOO_BAD);
	return -1;
}

In specific:
if (!(dhara_nand_is_bad(j->nand, blk) || dhara_nand_read(j->nand, p, 0, 1 << j->nand->log2_page_size, j->page_buf, err))

Am I mistaken in that it even though this function can return an error of DHARA_E_TOO_BAD, one of the failing reasons could be that perhaps it's just missing the Magic ('Dha') and not that the block is bad on a completely erased flash array?

from dhara.

dlbeer avatar dlbeer commented on August 16, 2024

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

I thought you might want to see that so I had already programmed in a #define USE_SIM flag so that everything would switch to using a simulated nand flash array.

Below is the "mapTest" that is called from the Task:

int performMapTest(void)
{
	const size_t page_size = 1 << sim_nand.log2_page_size;
	uint8_t page_buf[page_size];
	struct dhara_map map;
	int i;

	sim_reset();
	//sim_inject_bad(10);
	//sim_inject_timebombs(30, 20);

	debug_print("Map init\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
	debug_print("  capacity: %lu\n", dhara_map_capacity(&map));
	debug_print("  sector count: %d\n", NUM_SECTORS);
	debug_print("\n");

	debug_print("Sync...\n");
	dhara_map_sync(&map, NULL);
	debug_print("Resume...\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);

	printf("Writing sectors...\n");
	shuffle(0);
	for (i = 0; i < NUM_SECTORS; i++) {
		const dhara_sector_t s = sector_list[i];

		mt_write(&map, s, s);
		mt_check(&map);
	}

	debug_print("Sync...\n");
	dhara_map_sync(&map, NULL);
	debug_print("Resume...\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
	debug_print("  capacity: %lu\n", dhara_map_capacity(&map));
	debug_print("  use count: %lu\n", dhara_map_size(&map));
	debug_print("\n");

	debug_print("Read back...\n");
	shuffle(1);
	for (i = 0; i < NUM_SECTORS; i++) {
		const dhara_sector_t s = sector_list[i];

		mt_assert(&map, s, s);
	}

	debug_print("Rewrite/trim half...\n");
	shuffle(2);
	for (i = 0; i < NUM_SECTORS; i += 2) {
		const dhara_sector_t s0 = sector_list[i];
		const dhara_sector_t s1 = sector_list[i + 1];

		mt_write(&map, s0, ~s0);
		mt_check(&map);
		mt_trim(&map, s1);
		mt_check(&map);
	}

	debug_print("Sync...\n");
	dhara_map_sync(&map, NULL);
	debug_print("Resume...\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
	debug_print("  capacity: %lu\n", dhara_map_capacity(&map));
	debug_print("  use count: %lu\n", dhara_map_size(&map));
	debug_print("\n");

	debug_print("Read back...\n");
	for (i = 0; i < NUM_SECTORS; i += 2) {
		const dhara_sector_t s0 = sector_list[i];
		const dhara_sector_t s1 = sector_list[i + 1];

		mt_assert(&map, s0, ~s0);
		mt_assert_blank(&map, s1);
	}

	debug_print("\n");
	sim_dump();
	return 0;
}

This is the output:

Map init
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
  capacity: 36
  sector count: 2

Sync...
Resume...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
Writing sectors...
SIM Flash Prog - Page: 0
SIM Flash Prog - Page: 1
Successful map write to Sector 1.
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Prog - Page: 2
SIM Flash Prog - Page: 3
Successful map write to Sector 0.
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
Sync...
Resume...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 121 - Offset: 0 - Length: 256
SIM Flash Read - Page: 129 - Offset: 0 - Length: 256
SIM Flash Read - Page: 137 - Offset: 0 - Length: 256
SIM Flash Read - Page: 145 - Offset: 0 - Length: 256
SIM Flash Read - Page: 153 - Offset: 0 - Length: 256
SIM Flash Read - Page: 161 - Offset: 0 - Length: 256
SIM Flash Read - Page: 169 - Offset: 0 - Length: 256
SIM Flash Read - Page: 177 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 89 - Offset: 0 - Length: 256
SIM Flash Read - Page: 97 - Offset: 0 - Length: 256
SIM Flash Read - Page: 105 - Offset: 0 - Length: 256
SIM Flash Read - Page: 113 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 3 - Offset: 0 - Length: 256
  capacity: 36
  use count: 2

Read back...
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Read - Page: 0 - Offset: 0 - Length: 256
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 2 - Offset: 0 - Length: 256
Rewrite/trim half...
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Prog - Page: 4
SIM Flash Prog - Page: 5
Successful map write to Sector 1.
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 4 - Offset: 0 - Length: 256
SIM Flash Prog - Page: 6
SIM Flash Prog - Page: 7
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
Sync...
Resume...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 121 - Offset: 0 - Length: 256
SIM Flash Read - Page: 129 - Offset: 0 - Length: 256
SIM Flash Read - Page: 137 - Offset: 0 - Length: 256
SIM Flash Read - Page: 145 - Offset: 0 - Length: 256
SIM Flash Read - Page: 153 - Offset: 0 - Length: 256
SIM Flash Read - Page: 161 - Offset: 0 - Length: 256
SIM Flash Read - Page: 169 - Offset: 0 - Length: 256
SIM Flash Read - Page: 177 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 89 - Offset: 0 - Length: 256
SIM Flash Read - Page: 97 - Offset: 0 - Length: 256
SIM Flash Read - Page: 105 - Offset: 0 - Length: 256
SIM Flash Read - Page: 113 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 7 - Offset: 0 - Length: 256
  capacity: 36
  use count: 1

Read back...
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
SIM Flash Read - Page: 6 - Offset: 0 - Length: 256
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132

NAND operation counts:
    is_bad:         101
    mark_bad        0
    erase:          1
    erase failures: 0
    is_erased:      10
    prog:           8
    prog failures:  0
    read:           117
    read (bytes):   28588

Block status:
    ::::::::::::::::::::::::::::::::

This does look like it initializes ok. I was curious if you thought these different values would affect the outcome of the test in anyway?

Sim
#define LOG2_PAGE_SIZE 8 // 256 #define LOG2_PAGES_PER_BLOCK 3 // 8

Real NAND Flash (using 512b sub-sectors of the 2kb pages)
#define LOG2_SECTOR_SIZE 9 // 512 #define LOG2_SECTORS_PER_BLOCK 8 // 256

This CPU has 192kB of RAM and around 105kB is already in use so I was limited in how big of a sim array I could create although I suppose I could create a dedicated test project although I'd like to avoid that if possible as I don't feel anything else in the system is contributing to this as all other threads had a
for (;;) osDelay(1000); at the start to disable them.

I'm sure this has to be something on my end but I've spent the better part of a week on this one particular issue so I felt it was a good idea to reach out.
I did study the other closed issues thoroughly before posting this.

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

I wanted to test my initialization code to see if it'd print out the same "TOO MANY BAD BLOCKS" on the sim array and it does.

#ifdef SIM_USE_ALTERNATE_INIT
	debug_print("Dhara FTL - Map Init\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	debug_print("FTL - Map Init Complete. Resuming...\n");
	dhara_error_t resume_err = DHARA_E_NONE;
	uint8_t map_initialized = dhara_map_resume(&map, &resume_err);
	if (map_initialized)
	{
		debug_print("Map Initialized. Could not find existing journal. head = %lu\n", map.journal.head);
		if (resume_err != DHARA_E_NONE)
		{
			debug_print("\tError initializing journal: %s\n", dhara_strerror(resume_err));
		}
	}
	else
	{
		debug_print("Journal Resumed. head = %lu\n", map.journal.head);
	}
	debug_print("Map Capacity: %lu\n", dhara_map_capacity(&map));	
	
	debug_print("Initial Sync...\n");
	dhara_error_t sync_err = DHARA_E_NONE;	
	dhara_map_sync(&map, &sync_err);
	if (sync_err != DHARA_E_NONE)
	{
		debug_print("Error syncing map: %s\n", dhara_strerror(resume_err));
	}
	debug_print("Map Count: %lu\n", map.count);
#else
	debug_print("Map init\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
	debug_print("  capacity: %lu\n", dhara_map_capacity(&map));
	debug_print("  sector count: %d\n", NUM_SECTORS);
	debug_print("\n");

	debug_print("Sync...\n");
	dhara_map_sync(&map, NULL);
	debug_print("Resume...\n");
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
#endif

Produces the following:

Dhara FTL - Map Init
FTL - Map Init Complete. Resuming...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
Map Initialized. Could not find existing journal. head = 0
        Error initializing journal: Too many bad blocks
Map Capacity: 36
Initial Sync...
Map Count: 0
Writing sectors...
SIM Flash Prog - Page: 0
SIM Flash Prog - Page: 1
Successful map write to Sector 1.
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Prog - Page: 2
SIM Flash Prog - Page: 3
Successful map write to Sector 0.
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
Sync...
Resume...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 121 - Offset: 0 - Length: 256
SIM Flash Read - Page: 129 - Offset: 0 - Length: 256
SIM Flash Read - Page: 137 - Offset: 0 - Length: 256
SIM Flash Read - Page: 145 - Offset: 0 - Length: 256
SIM Flash Read - Page: 153 - Offset: 0 - Length: 256
SIM Flash Read - Page: 161 - Offset: 0 - Length: 256
SIM Flash Read - Page: 169 - Offset: 0 - Length: 256
SIM Flash Read - Page: 177 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 89 - Offset: 0 - Length: 256
SIM Flash Read - Page: 97 - Offset: 0 - Length: 256
SIM Flash Read - Page: 105 - Offset: 0 - Length: 256
SIM Flash Read - Page: 113 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 3 - Offset: 0 - Length: 256
  capacity: 36
  use count: 2

Read back...
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Read - Page: 0 - Offset: 0 - Length: 256
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 2 - Offset: 0 - Length: 256
Rewrite/trim half...
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
SIM Flash Prog - Page: 4
SIM Flash Prog - Page: 5
Successful map write to Sector 1.
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
SIM Flash Read - Page: 4 - Offset: 0 - Length: 256
SIM Flash Prog - Page: 6
SIM Flash Prog - Page: 7
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
Sync...
Resume...
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 121 - Offset: 0 - Length: 256
SIM Flash Read - Page: 129 - Offset: 0 - Length: 256
SIM Flash Read - Page: 137 - Offset: 0 - Length: 256
SIM Flash Read - Page: 145 - Offset: 0 - Length: 256
SIM Flash Read - Page: 153 - Offset: 0 - Length: 256
SIM Flash Read - Page: 161 - Offset: 0 - Length: 256
SIM Flash Read - Page: 169 - Offset: 0 - Length: 256
SIM Flash Read - Page: 177 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 89 - Offset: 0 - Length: 256
SIM Flash Read - Page: 97 - Offset: 0 - Length: 256
SIM Flash Read - Page: 105 - Offset: 0 - Length: 256
SIM Flash Read - Page: 113 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 73 - Offset: 0 - Length: 256
SIM Flash Read - Page: 81 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
SIM Flash Read - Page: 65 - Offset: 0 - Length: 256
SIM Flash Read - Page: 7 - Offset: 0 - Length: 256
  capacity: 36
  use count: 1

Read back...
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
SIM Flash Read - Page: 6 - Offset: 0 - Length: 256
SIM Flash Read - Page: 7 - Offset: 20 - Length: 132

NAND operation counts:
    is_bad:         93
    mark_bad        0
    erase:          1
    erase failures: 0
    is_erased:      10
    prog:           8
    prog failures:  0
    read:           109
    read (bytes):   26540

Block status:
    ::::::::::::::::::::::::::::::::

It would appear that error is possible when the "array" is empty and does not indicate a fatal error?

from dhara.

dlbeer avatar dlbeer commented on August 16, 2024

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

When I included the map_test.c in my project, I can pass the sim array test.
I simply put it's main into a function that I could call from my FreeRTOS thread, other than that, it's the same as the test.

I am still working on adapting my code to be able to use the Sim array to replicate.

If the Sim array can write/read to the map and throw no asserts on the read value being different than the written value, Do you have any other ideas on where in my nand.c function or in my Flash Driver the problem could reside?

I'm still working on adapting my main code to use the sim array to attempt to replicate the problem via that method.

Sorry for the delay in response, was on holiday for July 4th.

from dhara.

dlbeer avatar dlbeer commented on August 16, 2024

from dhara.

chrisreedtech avatar chrisreedtech commented on August 16, 2024

First let me say I deeply appreciate your time on helping me work through this.

Here is the output of the simulated array test but using the same "main" code that is used on the real array. As you can see the simulated array does not have the same issues but there is one minor difference in mapping behavior, noted below.

================ Block Device Init (Dhara FTL) ================
Dhara FTL - Map Init
FTL - Map Init Complete. Resuming...
        SIM Flash Read - Page: 1 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 9 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 17 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 25 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 33 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 41 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 49 - Offset: 0 - Length: 256
        SIM Flash Read - Page: 57 - Offset: 0 - Length: 256
Map Initialized. Could not find existing journal. head = 0
        Error initializing journal: Too many bad blocks
Map Capacity: 36
Initial Sync...
Map Count: 0
================ Write Operation ================
Attempting map write to sector 0...
        SIM Flash Prog - Page: 0
        SIM Flash Prog - Page: 1
Successful map write to sector 0.
Attempting map write to sector 1...
        SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
        SIM Flash Prog - Page: 2
        SIM Flash Prog - Page: 3
Successful map write to sector 1.
Attempting map write to sector 2...
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
        SIM Flash Prog - Page: 4
        SIM Flash Prog - Page: 5
Successful map write to sector 2.
Attempting map write to sector 3...
        SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
        SIM Flash Prog - Page: 6
        SIM Flash Prog - Page: 7
Successful map write to sector 3.
================ Sector Scan ================
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
Logical sector 0 mapped to physical sector 0
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
Logical sector 1 mapped to physical sector 2
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
Logical sector 2 mapped to physical sector 4
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
Logical sector 3 mapped to physical sector 6
================ Sync Operation ================
Syncing sectors to storage...
BlockDeviceAPI: Sync Started
Successful sync. Map Count: 4
================ Sector Scan ================
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
Logical sector 0 mapped to physical sector 0
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
Logical sector 1 mapped to physical sector 2
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
Logical sector 2 mapped to physical sector 4
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
Logical sector 3 mapped to physical sector 6
================ Read Operation ================
Loading Sector 0 from FTL...
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 1 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 0 - Offset: 0 - Length: 256
Successful Read of sector 0.
  Sector Magic Validated.
    Sector contents validated!
Loading Sector 1 from FTL...
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 3 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 2 - Offset: 0 - Length: 256
Successful Read of sector 1.
  Sector Magic Validated.
    Sector contents validated!
Loading Sector 2 from FTL...
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 5 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 4 - Offset: 0 - Length: 256
Successful Read of sector 2.
  Sector Magic Validated.
    Sector contents validated!
Loading Sector 3 from FTL...
        SIM Flash Read - Page: 7 - Offset: 20 - Length: 132
        SIM Flash Read - Page: 6 - Offset: 0 - Length: 256
Successful Read of sector 3.
  Sector Magic Validated.
    Sector contents validated!

In this test, I changed all my setup/writing/reading code to use pointers to the nand/map structures so that I could easily change them from real flash array (map/nand struct) to the simulated array (sim.c/h).

The prior "simulation" I ran was just a slightly modified map_test from the repo. This new test is using the same code just with the backing array / driver code changed.

The values I'm using for the simulated array are as follows:

#define SIM_LOG2_PAGE_SIZE		9 // 512
#define SIM_LOG2_PAGES_PER_BLOCK	3 // 4
#define SIM_NUM_BLOCKS		32

The values for the real flash array are:

#define NUM_BLOCKS		1024
#define LOG2_SECTOR_SIZE		9 // 512
#define LOG2_SECTORS_PER_BLOCK	8 // 256

This sim setup is using 169kb of my 192kb of RAM so unfortunately I can't make it any larger.

One difference I'm seeing is in how often a checkblock is written.

It looks like with the simulated array, it writes a checkblock (dhara magic + page meta * page count per checkblock) after every written sector.

On the real array it does 3 user pages for every checkblock/page. I checked the debugger and the log2_ppc value is calculated to be 1 on the simulated array. When using my real flash array, log2_ppc is calculated to be 2. So a 2 for the sim versus a 4 for the real.

I will paste the output of the program using the real array. The only change is a single
#define USE_SIM which exchanges the pointers and includes the sim code instead of the hardware nand flash driver.

As a reminder, the write operation writes a "page/sector" to the map that contains a custom defined Magic value of 0xBABEFACE as the first 4 bytes then followed by a single byte that is the intended sector number so when that sector is read back, it can check to see if the same sector requested is the one returned.

================ NAND Setup ================
FLASH Reset successful. Reading JEDEC ID..
Retrieved JEDEC ID of Flash chip. Manufacturer ID: 0xEF - DeviceID: 0xAA21
Read NAND Protection Register.
WP Pin Enabled Successfully. Disabling Hardware Write Protect...
        Hardware Write Protect disabled.
================ NAND Erase ================
================ Block Device Init (Dhara FTL) ================
Dhara FTL - Map Init
FTL - Map Init Complete. Resuming...
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 259 - Page/SubSector: 64/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 515 - Page/SubSector: 128/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 771 - Page/SubSector: 192/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 1027 - Page/SubSector: 256/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 1283 - Page/SubSector: 320/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 1539 - Page/SubSector: 384/3 - Offset: 0 - Length: 512
        NAND Flash Read - Sector: 1795 - Page/SubSector: 448/3 - Offset: 0 - Length: 512
Map Initialized. Could not find existing journal. head = 0
        Error initializing journal: Too many bad blocks
Map Capacity: 152628
Initial Sync...
Map Count: 0
================ Write Operation ================
Attempting map write to sector 0...
        NAND Flash Program - Sector: 0 - Page/SubSector: 0/0)
Successful map write to sector 0.
Attempting map write to sector 1...
        NAND Flash Program - Sector: 1 - Page/SubSector: 0/1)
Successful map write to sector 1.
Attempting map write to sector 2...
        NAND Flash Program - Sector: 2 - Page/SubSector: 0/2)
        NAND Flash Program - Sector: 3 - Page/SubSector: 0/3)
Successful map write to sector 2.
Attempting map write to sector 3...
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Program - Sector: 4 - Page/SubSector: 1/0)
Successful map write to sector 3.
================ Sector Scan ================
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
Logical sector 0 mapped to physical sector 2
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
Logical sector 1 mapped to physical sector 0
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
Logical sector 2 mapped to physical sector 0
Logical sector 3 mapped to physical sector 4
================ Sync Operation ================
Syncing sectors to storage...
BlockDeviceAPI: Sync Started
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 152 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 284 - Length: 132
        NAND Flash Program - Sector: 7 - Page/SubSector: 1/3)
Successful sync. Map Count: 3
================ Sector Scan ================
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
Logical sector 0 mapped to physical sector 6
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
Logical sector 1 mapped to physical sector 0
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
Logical sector 2 mapped to physical sector 0
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
Logical sector 3 mapped to physical sector 0
================ Read Operation ================
Loading Sector 0 from FTL...
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 6 - Page/SubSector: 1/2 - Offset: 0 - Length: 512
Successful Read of sector 0.
  Sector magic is wrong! Didn't attempt [4] validation.
Loading Sector 1 from FTL...
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 0 - Page/SubSector: 0/0 - Offset: 0 - Length: 512
Successful Read of sector 1.
  Sector Magic Validated.
    Sector contents are wrong! Value of [4]: 0x00 (0)
Loading Sector 2 from FTL...
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 0 - Page/SubSector: 0/0 - Offset: 0 - Length: 512
Successful Read of sector 2.
  Sector Magic Validated.
    Sector contents are wrong! Value of [4]: 0x00 (0)
Loading Sector 3 from FTL...
        NAND Flash Read - Sector: 7 - Page/SubSector: 1/3 - Offset: 284 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 3 - Page/SubSector: 0/3 - Offset: 20 - Length: 132
        NAND Flash Read - Sector: 0 - Page/SubSector: 0/0 - Offset: 0 - Length: 512
Successful Read of sector 3.
  Sector Magic Validated.
    Sector contents are wrong! Value of [4]: 0x00 (0)

from dhara.

dlbeer avatar dlbeer commented on August 16, 2024

from dhara.

brunoeagle avatar brunoeagle commented on August 16, 2024

@chrisreedio ,

I'm using the same flash with an STM32 as well. Same LOG2 configs as you.
I'm still testing everything, but I think I haven't had the same issue as you. I'm able to resume, write and read without any problems, never entered in na bad block mark or other error from dhara.

In your nand implementation, specialy the functions that receive the a 'dhara_page_t' parameter, are you shifting out the 2 least signifcant on the flash's ReadPage command, and putting those 2 bits as an offset for the flash's ReadBuffer command?

I'm doing this because the minimum number of bytes to the flash's buffer on the ReadPage command is 2048(+64), and the page configured for dhara is 512bytes:

My dhara_nand_is_free implementarion for example:

int dhara_nand_is_free(const struct dhara_nand *n, dhara_page_t p) {
	const uint16_t pageToRead = p >> LOG2_SECTOR_PER_PAGE;	// 4 sectors per page
	const uint16_t offset = ( p & ( dhara_page_t )3 ) * PAGE_SIZE;	
	uint16_t i, j;
	w25n01g_ReadPage( pageToRead );
	while( w25n01g_Busy() );
	if( w25n01g_ECCFail() ) {
		w25n01g_error();
	}
	for( i = offset; i < ( offset + PAGE_SIZE ); i += sizeof( w25n01gBuffer ) ) {
		w25n01g_ReadData( i, w25n01gBuffer, sizeof( w25n01gBuffer ) );
		for( j = 0; j < sizeof( w25n01gBuffer ); j++ ) {
			if( w25n01gBuffer[ j ] != 0xFF )
				return 0;
		}
	}
	return 1;
}

@dlbeer , does that makes any sense to you?

from dhara.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.