ATtiny1614: EEPROM read/write in C

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

can somebody please explain how I can read and write bytes to the EEPROM on an ATtiny1614? I've started to read the datasheet but after a few levels of abstraction, I had to switch to scan mode. Then the chapter ended with no actual clue on how to solve this task. It's really hard to understand that theoretical and abstract text without ever seeing a piece of the final C code. The authors obviously know what they're talking about but they completely fail to teach.

 

The web has nothing to offer, everybody's still talking about the older generation MCUs. I did find an application note though that indicates the the 1-series controllers do things differently. Again, without code. Not solution-oriented.

 

So an example of the final code would be very helpful. Maybe I can then understand the datasheet. I'm only interested in EEPROM, not Flash access.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's 2 Application Notes mentioning "EEPROM" listed on the Product Page - do they help ?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AN_2540 is outdated (from 2004). It does not apply to the product it's listed under, as per AN1983.

 

AN1983 is the one I already found. It does not help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does the Arduino core for this part do ? https://github.com/SpenceKonde/m...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you saying < avr/eeprom.h > does not work then? (I'm assuming avr-gcc)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now that's a lot of additional questions. I only have one. And if somebody has ever done EEPROM access on a 1-series device with C code, I'd be interested in snippets of it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Go on.   Codevision handles EEPROM natively.   GCC has avr/eeprom.h.   Arduino has EEPROM functions...

 

I don't have a Tiny1614 but I do have Tiny817,  Mega4809 or Xmega.

 

You don't need any libraries.   The datasheet explains the registers.   You can write your own C code.

 

I suggest that you try the compiler supported methods first.   Then you have something to compare with when you do your EEPROM square wheel development.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks like the EEPROM in the tiny1614 is located in data memory at address 0x1400 and goes to 0x14ff. 

From here on I'm guessing.  Never used a Tiny1614.

write EEPROM address, data (8 bits 0--7???), and command  to the non-volatile memory controller set of registers.    

NVMCTRL.ADDR = address; // EE addr 0-255 plus 0x1400????

NVMCTRL.DATA = value;  bits 15-8 == 0 ?????

NVMCTRL.CTRLA = 0x01 // Write Page   EEPROM page size == 255 ???  all unchanged EE locations unwritten????

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will answer on the assumption that you use gcc. If not, ignore it.
 

Test code.
The result of writing and reading is stored in the variable result.
You can also see that it is written to 0x1400.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some datasheet info to look at-

 

Table 6.1 EEPROM properties
256 bytes, 32 bytes/page, 8 pages, address 0x1400

9.3.2.4 Commands

9.3.2.4.3 Erase-Write Operation

 

Will assume eeprom only which is easiest. You have a page buffer which acts similar to previous avr, except loading the data into the buffer simply requires writing the data to the memory address of interest. If you want to write the first byte in eeprom, then just write the data to address 0x1400. You just wrote to the page buffer, not eeprom. Now when you are done loading all your bytes in a single page you can proceed to getting the page buffer bytes written to eeprom (will assume the easier route of doing a byte at a time). Now all you need to do is tell the nvmctrl peripheral what to do via a command, and since the nvmctrl register is protected you need to 'unlock' the ability to write the command. For eeprom, once the command is done your cpu will continue executing instructions. The eeprom will only update the bytes you had written to the page buffer, in contrast to the flash writing. Easy as pie.

 

You can write your own code if you want, or use the code provided as shown in previous post. The EEMEM macro places the eeprom var in the .eeprom section, and its main purpose is to get the eeprom initial data into the hex file so the programmer programs the eeprom with its initial data. Having the .eeprom vma address as 0 is not a great thing for these avr0/1, as it requires adjusting the vma address from 0 based to 0x1400 based, but you have to get into the linker script to change things. I assume you are not at that point so you just go with what is required.

 

#include <avr/io.h>
#include <avr/eeprom.h>

 

//these eemem (vma) addresses are 0 based
EEMEM uint8_t a = 0x99;

 

//assuming simple byte read/write only

 

uint8_t ee_read(uint8_t* addr){ //can read without anything special, just need to adjust address
    return *(volatile uint8_t*)(EEPROM_START+addr);
}

 

void ee_write(uint8_t* addr, uint8_t data){
    if( ee_read(addr) == data ) return; //same?, no need to write
    while( NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm ); //wait while ee busy
    *(volatile uint8_t*)(EEPROM_START+addr) = data; //write byte to page buffer
    CCP = CCP_SPM_gc; //unlock spm
    NVMCTRL.CTRLA = NVMCTRL_CMD_PAGEERASEWRITE_gc; //ERWP command, erase and write
}

 

int main(void) {

 

    ee_write( &a, ee_read(&a) + 1 );

 

    for(;;){}

}
 

 

With a slight linker script mod (get the vma address to 0x1400, the lma address still using the eeprom memory section so gets into the hex file as before), the reads would need no special treatment-

 

void ee_write(uint8_t* addr, uint8_t data){
    if( *addr == data ) return; //same?, no need to write
    while( NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm ); //wait while ee busy
    *addr = data; //write byte to page buffer
    CCP = CCP_SPM_gc; //unlock spm
    NVMCTRL.CTRLA = NVMCTRL_CMD_PAGEERASEWRITE_gc; //ERWP command, erase and write
}

 

int main(void) {

 

    ee_write(&a, a + 1);

    SREG = a;

    ...

Last Edited: Thu. Mar 19, 2020 - 03:36 AM