SAME54 rewrite flash without erasing

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, 

 

In the SAMD21 datasheet it says: 

Note that on this flash technology, a max number of 8 consecutive write is allowed per row. Once this number is reached, a row erase is mandatory.

So I understand that with the samd21 I can rewrite a row multiple times. 

 

But I couldn't find any info on this same topic for the SAME54.

Does anyone know if this is also the case?

I have done some tests:

I try to rewrite every byte 8 times (switch 1 bit from a 1 to a 0 every time), and that for an entire block.

for (i = 0; i < page_size; i++) {
		src_data[i] = 0xFF;
	}

	int32_t ret = flash_write(&FLASH_0, 0x8C000, src_data, page_size);
	if (ret != ERR_NONE)
	{
		return ret;
	}
	
	uint8_t values[] = {0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00};
	uint16_t j = 3;
	for (i = 0; i < page_size; i++)
	{
		
		gpio_toggle_pin_level(LED0);
		
		for (j = 0; j < 8; j++)
		{	
			hri_wdt_write_CLEAR_reg(WDT, WDT_CLEAR_CLEAR_KEY);
			src_data[i] = values[j];
			//src_data[i+1] = values[j];
			//src_data[i+2] = values[j];
			//src_data[i+3] = values[j];
			flash_append(&FLASH_0, 0x8C000, src_data, page_size);
			ret = flash_read(&FLASH_0, 0x8C000, chk_data, page_size);
			if (ret != ERR_NONE)
			{
				volatile int k = 0;
				return ret;
			}
			uint16_t k;
			for (k = 0; k < page_size; k++)
			{
				if(chk_data[k] != src_data[k])
				{
					volatile int l = 0;
					return -32; // data niet hetzelfde
				}
			}
		}
	}

This code fails when i and j are both 0x02. That means that 18 writes were succesfull. But it doesn't fail in byte 3, bit 3. It fails because the first byte is suddenly different.

 

 

But when I swap the 2 for loops, it fails after only 6 writes

for (i = 0; i < page_size; i++) {
		src_data[i] = 0xFF;
	}

	int32_t ret = flash_write(&FLASH_0, 0x8C000, src_data, page_size);
	if (ret != ERR_NONE)
	{
		return ret;
	}
	
	uint8_t values[] = {0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00};
	uint16_t j = 3;
	for (j = 0; j < 8; j++)
	{
		
		gpio_toggle_pin_level(LED0);
		
		for (i = 0; i < page_size; i++)
		{	
			hri_wdt_write_CLEAR_reg(WDT, WDT_CLEAR_CLEAR_KEY);
			src_data[i] = values[j];
			//src_data[i+1] = values[j];
			//src_data[i+2] = values[j];
			//src_data[i+3] = values[j];
			flash_append(&FLASH_0, 0x8C000, src_data, page_size);
			ret = flash_read(&FLASH_0, 0x8C000, chk_data, page_size);
			if (ret != ERR_NONE)
			{
				volatile int k = 0;
				return ret;
			}
			uint16_t k;
			for (k = 0; k < page_size; k++)
			{
				if(chk_data[k] != src_data[k])
				{
					volatile int l = 0;
					return -32; // data niet hetzelfde
				}
			}
		}
	}

 

 

After these test I read that writes happen in 32 bits. So I changed the code to write every fourth byte 8 times. And this one succeeds:

for (i = 0; i < page_size; i+=4)
	{
		
		gpio_toggle_pin_level(LED0);
		
		for (j = 0; j < 8; j++)
		{	
			hri_wdt_write_CLEAR_reg(WDT, WDT_CLEAR_CLEAR_KEY);
			src_data[i] = values[j];
			//src_data[i+1] = values[j];
			//src_data[i+2] = values[j];
			//src_data[i+3] = values[j];
			flash_append(&FLASH_0, 0x8C000, src_data, page_size);
			ret = flash_read(&FLASH_0, 0x8C000, chk_data, page_size);
			if (ret != ERR_NONE)
			{
				volatile int k = 0;
				return ret;
			}
			uint16_t k;
			for (k = 0; k < page_size; k++)
			{
				if(chk_data[k] != src_data[k])
				{
					volatile int l = 0;
					return -32; // data niet hetzelfde
				}
			}
		}
	}

 

But now for the "weird" part: when I change both for loops again (so instead of writing every fourth byte 8 times, i write 8 times every other byte)

And this fails when it has written any byte 1 time, and starts with the first one again

for (j = 0; j < 8; j++)
	{
		
		gpio_toggle_pin_level(LED0);
		
		for (i = 0; i < page_size; i+=4)
		{	
			hri_wdt_write_CLEAR_reg(WDT, WDT_CLEAR_CLEAR_KEY);
			src_data[i] = values[j];
			//src_data[i+1] = values[j];
			//src_data[i+2] = values[j];
			//src_data[i+3] = values[j];
			flash_append(&FLASH_0, 0x8C000, src_data, page_size);
			ret = flash_read(&FLASH_0, 0x8C000, chk_data, page_size);
			if (ret != ERR_NONE)
			{
				volatile int k = 0;
				return ret;
			}
			uint16_t k;
			for (k = 0; k < page_size; k++)
			{
				if(chk_data[k] != src_data[k])
				{
					volatile int l = 0;
					return -32; // data niet hetzelfde
				}
			}
		}
	}

 

Anyone any idea on why this is? I can't find anything in the datasheet/ online.