Author Topic: [SAM] "EEPROM" dealings  (Read 3590 times)

0 Members and 1 Guest are viewing this topic.

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[SAM] "EEPROM" dealings
« on: December 22, 2021, 03:19:31 pm »
I've had a look at the sections of the SAMC datasheet that deal with the self writing capability. I gather this is probably the same as the SAMD series.

Am I right in that the datasheet's references to writing of the NVM (non volatile memory) apply also to the section dedicated to RWWEE  (EEPROM). I see there are some differences but in the two but they seem to not talk much about the RWWEE so I assume the general NVM procedures apply such as "27.6.4.3 NVM Write"

"27.6.5 NVM User Configuration" refers to selecting how many rows are to be EEPROM. one row is 256 bytes, this correlates with "Table 9-3. SAM C20/C21 RWW Section Parameters" that says the pages are 64 bytes as there are 4 pages to one row (27.6.2 Memory Organization).

Where I get confused is: "27.8.3 NVM Parameter" register. Here I can choose how many bytes are in a page. But pages are 64 bytes.... and there is a page write buffer that is limited to one page in that I have to read out 4 pages to erase the 4 page row before I write the one page buffer to a page. This makes the page buffer completely useless as I still have to act like I don't have it and buffer myself in RAM or another EEPROM location the entire row of 4 pages.

So as the page buffer is so limited how can I now go around deciding the page size?

If I understand correctly I have to write to the RWWEE space directly which will be caught by the buffer so I need to make sure I stay in the same page and then write it to memory when I am done. Further the writing into the buffer is done with another buffer that while visible to me serves no purpose I just need to make sure I stay inside it. So I have a buffer of a buffer, or I guess a 2 word/64 bit window into the buffer at a time. So I have to make sure I do not write data chunks that crosses the 8 byte window boundary or I go from writing in one 8 byte window to writing in another 8 byte window loosing the data that never got written properly......
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #1 on: December 22, 2021, 05:13:11 pm »
RWEE section is the same exact flash technology as the main flash array. It is just a separate plane that can be written while main array is available for code execution.

NVM Parameter is a read-only register with information about the device.

You have 256 byte rows, which is the minimum erase unit and then you have 64 byte pages (4 in each row), which are a minimum write unit. But pages also support partial writes, you can  always change 1->0, but not the other way around. Typical for flash devices. There is also a limit on maximum 8 writes to a row before a erase is needed, but it is not enforced anywhere in the device, writing more may make data less reliable, but I have not been able to observe that in practice under normal conditions.

Page buffer is not for you to temporarily store the data, it is for the flash controller to have all the data at the same time. If you want to update a few bytes in a row you have to buffer them anyway.

And none of the things about 8 byte boundaries are correct. You do need to fill and write one page (64 bytes) at a time.
« Last Edit: December 22, 2021, 05:25:05 pm by ataradov »
Alex
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #2 on: December 22, 2021, 08:29:43 pm »
You mean the detailed description in the datasheet about the page buffers buffer of 2 words is not true? Yes I understand that the page buffer is for the internal controller. Because of the indirect way it works, while I just write to the memory address space that implicitly sets the buffer up for a page. I am not actually writing to the memory until I use the write command (or the automatic write), so I have to make sure I do everything I want on that page and then write it.

Before I do anything I will have to copy out the entire row as I have to erase before writing.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #3 on: December 22, 2021, 08:47:36 pm »
The only place I see two words are mentioned is the internal organization of the page buffer, which consists of 64-bit words, but since you are writing one 32-bit word at a time, first half gets buffered until the second half arrives. All this is to say that you should always write the page buffer linearly and all 64 bytes (16 words). Do not write in random non-linear locations.

Otherwise the buffer is described as "The page buffer contains the same number of bytes as an NVM page."
Alex
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #4 on: December 23, 2021, 03:02:22 pm »
Right, so basically I will just buffer the 4 pages and then rewrite them one at a time from start to end once I am done.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #5 on: January 28, 2022, 09:41:17 am »
Right, I am in the thick of trying toe get it to work now.

Code: [Select]

#define d_eeprom_size 256ul // user EEPROM size in bytes
#define d_eeprom_word_size 4u // in bytes

#define d_eeprom_row_size ( FLASH_USER_PAGE_SIZE * 4u )
#define d_eeprom_words ( d_eeprom_size / d_eeprom_word_size )
#define d_eeprom_rows ( d_eeprom_size / d_eeprom_row_size )

void read_eeprom_nvv()
{
uint8_t wordcounter = 0 ;

while ( wordcounter < d_eeprom_words )
{
if ( REG_NVMCTRL_INTFLAG & 0x01 )
{
nvv.eeprom[wordcounter] = register32( FLASH_USER_PAGE_ADDR + wordcounter * d_eeprom_word_size ) ;
wordcounter ++ ;
}
}
}


If I make d_eeprom_word_size  2 after 2 consecutive reads the chip crashes from what I can tell. I say this because I have a display updating routine running in the background on a 100µs interrupt. it takes 2 clycles to complete a command to the display.
If I put a character into my display buffer array it never appears on the screen as before the 2 cycles have occurred the thing has totally crashed it would seem.

If I use a word size of 4 bytes it works, I get some gibberish read out onto the display that supposedly came from the EEPROM, as the EEPROM was presumably erased when the chip was programmed it has obviously not actually read the EEPROM an this is simply the contents of the RAM occupied by what should be the EEPROM copied into variables.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #6 on: January 28, 2022, 03:28:21 pm »
OK so I have grown up slightly and am now using pointer-y magic:

Code: [Select]

#define d_eeprom_size 256ul // user EEPROM size in bytes
#define d_eeprom_word_size 4u // in bytes

#define d_eeprom_row_size ( FLASH_USER_PAGE_SIZE * 4u )
#define d_eeprom_words ( d_eeprom_size / d_eeprom_word_size )
#define d_eeprom_rows ( d_eeprom_size / d_eeprom_row_size )

void read_eeprom_nvv()
{
uint16_t wordcounter = 0 ;
uint32_t *p_flashaddress = ( uint32_t * ) FLASH_USER_PAGE_ADDR ;

while ( wordcounter < d_eeprom_words )
{
if (wordcounter ==  16 ) pinclr(PB11); // debug code

nvv.eeprom[wordcounter] = *p_flashaddress ;
p_flashaddress += 4 ;
wordcounter ++ ;
}

}


So one row is 256 bytes, I am reading in units of 32 bit words, so 64 cycles to be made.
The 16th cycle completes (wordcounter at 15).
This would be the end of the first 64 byte page of 16 4 byte words (page 0).
As soon as I try to read the 17th word which is the first 4 bytes of page 1 the micro crashes as the pin is never turned off.

 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #7 on: January 28, 2022, 03:38:33 pm »
So back to my original version that works - well it gets gone through and out the other side.
Code: [Select]
#define register32(x) ( *(volatile uint32_t * )( x ) )

#define d_eeprom_size 256ul // user EEPROM size in bytes
#define d_eeprom_word_size 4u // in bytes

#define d_eeprom_row_size ( FLASH_USER_PAGE_SIZE * 4u ) //
#define d_eeprom_words ( d_eeprom_size / d_eeprom_word_size )
#define d_eeprom_rows ( d_eeprom_size / d_eeprom_row_size )


void read_eeprom_nvv()
{
uint16_t wordcounter = 0 ;

while ( wordcounter < d_eeprom_words )
{
if (wordcounter ==  63u ) pinclr(PB11);
nvv.eeprom[wordcounter] = register32( FLASH_USER_PAGE_ADDR + wordcounter * d_eeprom_word_size ) ;
wordcounter ++ ;
}
}
« Last Edit: January 28, 2022, 03:43:29 pm by Simon »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #8 on: January 28, 2022, 05:22:57 pm »
You are using pointers wrong: "p_flashaddress += 4"  // This will increment the pointer by 16 bytes. Pointers are incremented in units of the pointed data type.
Alex
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #9 on: January 28, 2022, 05:44:46 pm »
right, makes sense, maybe stick to my tried and tested method of wrapping it in a define and calculating it like a function instead of being clever.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #10 on: January 28, 2022, 10:02:21 pm »
I suppose the first pointer version fixed will run faster as the address pointer is incremented rather than being calculated in a more long winded way.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #11 on: January 28, 2022, 10:29:08 pm »
Or you can do something like this and get readable code:
Code: [Select]
void read_eeprom_nvv()
{
volatile uint32_t *flash = (volatile uint32_t * ) FLASH_USER_PAGE_ADDR ;

for (int i = 0; i < d_eeprom_words; i++)
nvv.eeprom[i] = flash[i];
}
Alex
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 5599
  • Country: fi
Re: [SAM] "EEPROM" dealings
« Reply #12 on: January 29, 2022, 07:39:55 am »
The whole appeal of ARM is that everything is memory mapped in single address space so standard C language works without any tricks, special instructions or special accessor macros. Therefore, just write normal C, it's easiest to read. Avoid NIHilims patterns like the register32 macro.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #13 on: January 29, 2022, 08:14:23 am »
Or you can do something like this and get readable code:
Code: [Select]
void read_eeprom_nvv()
{
volatile uint32_t *flash = (volatile uint32_t * ) FLASH_USER_PAGE_ADDR ;

for (int i = 0; i < d_eeprom_words; i++)
nvv.eeprom[i] = flash[i];
}

Yes that is much more elegant. It looks like the pointer properties of arrays are used, I didn't think you could do that without a compiler complaint. I mean the whole goal was to treat a memory space like an array.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 5599
  • Country: fi
Re: [SAM] "EEPROM" dealings
« Reply #14 on: January 29, 2022, 11:41:24 am »
Almost every project in existence, even the simplest (ignoring hello worlds), use the [] indexing of pointer.

Typically like this:
Code: [Select]
int process_data(int* buffer, size_t len)
{
    for(size_t i = 0; i < len; i++)
    {
        ... buffer[i] ...
    }
}

[] indexing works because compiler knows the type and therefore the size of each array element.

This is all in C standard and one of the earliest and most fundamental features of the language, pretty much defining what C is.

You can always use pointer arithmetic, too, and remember that even just pointer + and - operations take the size of the type into account, too: meaning, +1 on the pointer does the same as indexing [1], even if the type is larger than 1 byte.

But [] indexing is more readable to most, use it whenever possible.
« Last Edit: January 29, 2022, 11:44:19 am by Siwastaja »
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #15 on: January 29, 2022, 02:11:23 pm »
what I mean is a pointer variable is created, but it is then used with an index like an array. I understand arrays, I use them all the time especially when I want to use to math to determine with variable I want.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #16 on: January 31, 2022, 08:42:23 am »
If I erase the EEPROM then read it the result should be  11111111111111111....... ?
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #17 on: January 31, 2022, 09:29:44 am »
The NVM Address bit field in the Address register (ADDR.ADDR) uses 16-bit addressing

So are they saying that the address locations go in 2 bytes rather than 1? I am going in circles clearly not addressing the right location and this is getting silly. The datasheet is so cryptic when with the same amount of words they could have said much more.
« Last Edit: January 31, 2022, 09:39:12 am by Simon »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #18 on: January 31, 2022, 05:08:48 pm »
ADDR register should contain the offset of a 16-bit word, so ADDR must be written the value of a physical address / 2. In your case physical address is FLASH_USER_PAGE_ADDR.

You only need ADDR for writes, so it does not matter, as you write entire pages anyway most of the time.

This is trivial to test and debug. Just specify whatever address, do the programming, read the device contents using a debugger and see where it was written.
Alex
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #19 on: January 31, 2022, 07:37:55 pm »
i worked it all out in the end, I was using the wrong address for the eeprom, there are two diagrams of memory, one showing eeprom and one RWW section. Totally confusing. Not very well explained but I worked it out and my hunch that given the diagrams the address of the first page moves down as you increase space.

That section of the datasheet is truly awful, the only worse stuff I have read for comprehension was my uni modules that were simply put not written in English as most of us understand.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 5599
  • Country: fi
Re: [SAM] "EEPROM" dealings
« Reply #20 on: January 31, 2022, 07:56:18 pm »
They indeed seem to have overcomplicated it a bit. And I think the marketing idea to call flash "eeprom" is a huge mistake, it only causes confusion because it's actual lying, EEPROM is EEPROM, it's a distinct technology, which the chip doesn't have. (I know they somewhere call it "eeprom emulation", but some other places just "eeprom". Huge waste of time. Especially since they don't do any eeprom emulation, you have to do it yourself. Which they offer appnotes for, just like every manufacturer.)

Fundamentally, the key concepts in flash are:
* Erase turns bits to '1'
* By writing, those can be only turned to '0'
* Erasing is SLOW
* Erasing affects large part at once, this is called erase granularity. The term for smallest erasable unit varies, I like "page".
* There might be some limitation on write granularity, too. The term for smallest writable unit varies, too. I like "word".

MCU flash usually comes with multiple pages (I mean: erasable units) so that you don't need to erase the firmware if you want to just update settings.

Some implementations have fairly small page size which is handy, you can update smaller sections of settings / calibration / whatever. Sometimes pages are of different sizes; it makes sense, it's enough to have a bunch of small pages for non-volatile storage of data, but the firmware itself can go into a larger page no problems.

Rest is just trying to make sense with the terminology choices and how these fundamental basics are represented in the manuals. I prefer shorter over longer. Surprisingly, ST seems to do better job here. The best I have seen: Nordic Semiconductor, as usual, their register-level datasheets are excellent (same can't be said about SDKs and example code). Fine erase granularity, very simple register interface with no BS, and short datasheet that explains exactly what is necessary, and no more.
« Last Edit: January 31, 2022, 07:58:06 pm by Siwastaja »
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #21 on: January 31, 2022, 08:00:15 pm »
Things like the address register, they use the term "section" this is a very generic word and it's definition is further back, you have to be really determined to piece together all the snippets. To the NVMC a section is a very defined thing, their wording could have been much clearer with a restatement of the casually given definition further up.

The problem is that these data sheets are written by those that know the chip and take their knowledge for granted which means they pass very little on in the datasheet.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #22 on: January 31, 2022, 11:57:23 pm »
There will always be a way to misunderstand the datasheet, any of them. I have never seen a "golden" datasheet that is an example of clarity that nobody ever got confused about.

Also, use reference code to see how it does things. This usually clarifies it readily.

EEPROM here is always used in conjunction with emulation. There are two things that are implemented towards that goal - RWEE section, which is separate from the main flash array and does not block reads from the main flash array when written. And then you have ability to reserve some part of the main flash array via fuses, and it will affect device behaviour, but ultimately it will remain the same flash array.

« Last Edit: February 01, 2022, 12:00:03 am by ataradov »
Alex
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 16818
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAM] "EEPROM" dealings
« Reply #23 on: February 01, 2022, 08:03:06 am »
I searched for reference code an eventually found some, but really I feel that having to copy how someone else did it means that the datasheet is not serving it's purpose and skips vital detail in writing good code. Anything in the way of app notes from microchip/atmel just talked about the libraries they offer and I'm not even going to try and work out how to invoke those, as soon as I go near supplied code I find that it's and infinite rabbit hole of one bit of code referencing another and soon I am spending time trying to understand the code rather than the peripheral.

So it sounds like there are 2 "EEPROM" memories? what is the RWEE section? that is the one I was trying to use at one point. In the end I had to guess that what I was aiming for was the address of the rows working down from the top of the address space of the main flash "section".
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8877
  • Country: us
    • Personal site
Re: [SAM] "EEPROM" dealings
« Reply #24 on: February 01, 2022, 08:10:17 am »
The documentation was pretty clear to me. I had no issues interpreting it. And where it is not clear, it is usually easy enough to setup and experiment and see what  happens.

There is EEPROM section in the main flash, which size you can setup using User Row setting. The only thing that this size affects on a hardware level is how CRC calculation works. Mostly it is useless, and you can just allocate however much you feel for data storage.

Then there is a completely separate chunk of flash called RWEE. This can be written while code is executing from the main flash array. As far as writing goes, it works mostly like the regular flash, but it uses different commands for erase and write.

Keep in mind that ADDR specifies an offset into the respective flash memory (main flash or RWEE), and not an absolute address. So, to write the first page of the RWEE memory you need to specify address 0. And which memory is written depends on the command used.
« Last Edit: February 01, 2022, 08:13:19 am by ataradov »
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf