EEPROM with attiny814

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

I am building a project using Attiny814 for eeprom application. But due to insufficient data in application notes and datasheet, i couldn't read or write data in the EEPROM memory.

Can anyone help me out with EEPROM protocol and how to read and write data in EEPROM memories?

 

code: 

for EEPROM write:

 

NVMCTRL.DATA = 0x52;

NVMCTRL.ADDR = 0x1405;
NVMCTRL.CTRLA = 0x03;

 

for EEPROM read:

NVMCTRL.CTRLA = 0x04;

flag = NVMCTRL.DATA;

This topic has a solution.
Last Edited: Thu. Feb 14, 2019 - 11:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Which C compiler? Does it not already have inherent EEPROM support? avr-gcc (the compiler that comes with AS7) does:

 

https://www.nongnu.org/avr-libc/...

 

Not much point reinventing the wheel if it already comes with the compiler/C library.

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

You don't use the data and address registers directly. Just write normally to eeprom as if to normal memory, but keeping within the same eeprom page. These writes are directed to the NVMCTRL page buffer automagically.

When you are finished working with a page, you issue the write command to the NVMCTRL.

Wait until the write is complete, then move on to the next page.

 

To read the eeprom, just do a normal read to the eeprom address, that's the advantage of having a unified memory space.

 

edit: this is all explained in the datasheet, maybe not 100% clear, but clear enough.

edit2: what I don't get is why the data and address registers are exposed to the programmer, I don't see much (any?) use for them. They just cause confusion...

Last Edited: Wed. Feb 13, 2019 - 01:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Jeet_1997 wrote:
But due to insufficient data in application notes and datasheet, i couldn't read or write data in the EEPROM memory.

the Datasheet is lack of examples , however it has got comprehensive step by step descriptions in how to use peripherals and memory.

 

see : 9.3.2.4 Commands

To execute a command in the NVM:
1. Write the NVM command unlock to the Configuration Change Protection register in the CPU
(CPU.CCP).
2. Write the desired command value to the CMD bits in the Control A register (NVMCTRL.CTRLA)
within the next 4 instructions.

 

clawson wrote:
Not much point reinventing the wheel if it already comes with the compiler/C library.

+1

 

don't mess with EEPROM registers, leave it to compiler to do it for you.

Majid

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

Jeet_1997 wrote:
But due to insufficient data in application notes and datasheet

 

Well:

http://ww1.microchip.com/downloads/en/AppNotes/AN1983%20Writing%20to%20Flash%20and%20EEPROM%20on%20the%20tinyAVR%201-series%2040001983A.pdf

 

Regards

 

EDIT: and yes, its valid for attiny814

 

Last Edited: Wed. Feb 13, 2019 - 01:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Which C compiler? Does it not already have inherent EEPROM support? avr-gcc (the compiler that comes with AS7) does:

 

https://www.nongnu.org/avr-libc/...

 

Not much point reinventing the wheel if it already comes with the compiler/C library.

 

Clawson, I believe the question was a much more simple, more like basics of "reading/writing" thing, refer to this thread from the same OP:

 

https://www.avrfreaks.net/forum/i2c-attiny402

 

 

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

Ehh? He's talking about the EEPROM *inside* the AVR - not on an external bus/peripheral. How is I2C relevant here?

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

clawson wrote:

Ehh? He's talking about the EEPROM *inside* the AVR - not on an external bus/peripheral. How is I2C relevant here?

 

I was refering to the OP experience in AVR in general

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

But he was quoting very specific code making access to the NVM registers - hardly just a general "how do you do it?"

 

but like I say I'd try something like:

int main(void) {
	eeprom_update_word((uint16_t *)123, 456);
}

When I build that for tiny814 the code is:

	eeprom_update_word((uint16_t *)123, 456);
  4e:	68 ec       	ldi	r22, 0xC8	; 200
  50:	71 e0       	ldi	r23, 0x01	; 1
  52:	8b e7       	ldi	r24, 0x7B	; 123
  54:	90 e0       	ldi	r25, 0x00	; 0
  56:	05 d0       	rcall	.+10     	; 0x62 <eeprom_update_word>
00000062 <eeprom_update_word>:
  62:	01 96       	adiw	r24, 0x01	; 1
  64:	27 2f       	mov	r18, r23
  66:	02 d0       	rcall	.+4      	; 0x6c <eeprom_update_r18>
  68:	00 c0       	rjmp	.+0      	; 0x6a <eeprom_update_byte>

0000006a <eeprom_update_byte>:
  6a:	26 2f       	mov	r18, r22

0000006c <eeprom_update_r18>:
  6c:	1f d0       	rcall	.+62     	; 0xac <eeprom_mapen>
  6e:	00 80       	ld	r0, Z
  70:	02 16       	cp	r0, r18
  72:	11 f0       	breq	.+4      	; 0x78 <eeprom_update_r18+0xc>
  74:	04 d0       	rcall	.+8      	; 0x7e <eeprom_write_r18>
  76:	01 97       	sbiw	r24, 0x01	; 1
  78:	01 97       	sbiw	r24, 0x01	; 1
  7a:	08 95       	ret

0000007c <eeprom_write_byte>:
  7c:	26 2f       	mov	r18, r22

0000007e <eeprom_write_r18>:
  7e:	af 93       	push	r26
  80:	bf 93       	push	r27
  82:	e0 e0       	ldi	r30, 0x00	; 0
  84:	f0 e1       	ldi	r31, 0x10	; 16
  86:	32 81       	ldd	r19, Z+2	; 0x02
  88:	31 fd       	sbrc	r19, 1
  8a:	fd cf       	rjmp	.-6      	; 0x86 <eeprom_write_r18+0x8>
  8c:	dc 01       	movw	r26, r24
  8e:	a0 50       	subi	r26, 0x00	; 0
  90:	bc 4e       	sbci	r27, 0xEC	; 236
  92:	2c 93       	st	X, r18
  94:	2d e9       	ldi	r18, 0x9D	; 157
  96:	24 bf       	out	0x34, r18	; 52
  98:	23 e0       	ldi	r18, 0x03	; 3
  9a:	20 83       	st	Z, r18
  9c:	01 96       	adiw	r24, 0x01	; 1
  9e:	bf 91       	pop	r27
  a0:	af 91       	pop	r26
  a2:	08 95       	ret

000000a4 <eeprom_read_byte>:
  a4:	03 d0       	rcall	.+6      	; 0xac <eeprom_mapen>
  a6:	80 81       	ld	r24, Z
  a8:	99 27       	eor	r25, r25
  aa:	08 95       	ret

000000ac <eeprom_mapen>:
  ac:	fc 01       	movw	r30, r24
  ae:	e0 50       	subi	r30, 0x00	; 0
  b0:	fc 4e       	sbci	r31, 0xEC	; 236
  b2:	08 95       	ret

That does look like fairly normal "Xmega" handling of EEPROM as one might expect for tiny814

 

The header for tiny814 tells us:

#define NVMCTRL           (*(NVMCTRL_t *) 0x1000) /* Non-volatile Memory Controller */

using:

/* Non-volatile Memory Controller */
typedef struct NVMCTRL_struct
{
    register8_t CTRLA;  /* Control A */
    register8_t CTRLB;  /* Control B */
    register8_t STATUS;  /* Status */
    register8_t INTCTRL;  /* Interrupt Control */
    register8_t INTFLAGS;  /* Interrupt Flags */
    register8_t reserved_0x05;
    _WORDREGISTER(DATA);  /* Data */
    _WORDREGISTER(ADDR);  /* Address */
    register8_t reserved_0x0A;
    register8_t reserved_0x0B;
    register8_t reserved_0x0C;
    register8_t reserved_0x0D;
    register8_t reserved_0x0E;
    register8_t reserved_0x0F;
} NVMCTRL_t;

So I guess when the code is seen to do:

  82:	e0 e0       	ldi	r30, 0x00	; 0
  84:	f0 e1       	ldi	r31, 0x10	; 16
  86:	32 81       	ldd	r19, Z+2	; 0x02

then that, for example, is an access to NVMCTRL.STATUS etc (which is Z (0x1000) + 2 (= 0x1002))

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

Thank you for such a response.

I am a amateur in embedded coding but have tried few projects with attiny402 and have started with attiny814.

For my last thread i was able to use I2C for attiny402 and attiny814. Struggling for a bit longer time, i could successfully use attiny402 as an I2C master and as the registers are same in tiny1 series the same code can be used for attiny814 as well.

 

I am still facing issues regarding EEPROM memories read/write instructions.

Little more explanation in simple sense with 2-3 lines of code is required.

Last Edited: Thu. Feb 14, 2019 - 05:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello ,

I tried using atmel start non-volatile basic file. It had .C and .H file and using the same functions i could write a value to its EEPROM address but the value is not retained if i read the eeprom address after resetting the system. I am using 0x1414 memory address for storing the value.

write and read code:

FLASH_0_write_eeprom_byte((eeprom_adr_t) 0x1414, (uint8_t) 50);
 flag_2 = FLASH_0_read_eeprom_byte((eeprom_adr_t) 0x1414);

 

read code:

 flag_2 = FLASH_0_read_eeprom_byte((eeprom_adr_t) 0x1414);

 

 

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

Personally I wouldn't hard code memory locations. You do't do it with variables in RAM so why do it for data in EEPROM? Just use EEMEM and let the linker handle the allocation.

 

(the one argument for fixed layout is where one code will later be replaced by another but the EEPROM layout is retained and the 2nd code has to understand the layout and addresses of what the first created. If you are going to do this then collect all data in a struct then just fix the base address of the struct (probably to EEPROM 0x0000 in fact).

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

These functions you are using, are they the ones from this thread?

https://www.avrfreaks.net/forum/...