3.10.3.3 EEPROM Data Memory
The configuration of the transceiver can be stored in the EEPROM data memory. During normal operation, the AVR, DSP and RF front end registers as well as the settings which are located in the SRAM are automatically loaded with this configuration.
The EEPROM address range 0x0280 to 0x03FF (384 bytes) is reserved for customer applications. A modification of the EEPROM content is only allowed during IDLEMode.
The EEPROM data memory contains two pages:
- 1024 bytes of firmware and user data EEPROM memory in which single bytes are read/write accessible. This page holds the configuration data. For further details, see EEPROM Configuration. It is subdivided into 64 pages with 16 bytes per page. 512 bytes are divided into 4 sections that can be locked separately. This can be used to secure encryption keys.
- 128 bytes of factory programmed configuration data that is write-protected for the user. Programming is done by the IC manufacturer during production test.
The CPU – EEPROM access is described below, specifying the EEPROM address registers (EEARH, EEARL), the EEPROM data register (EEDR) and the EEPROM control registers (EECR, EECR2).
For a detailed description of the SPI and serial data downloading to the EEPROM, see Memory Programming.
EEPROM Read/Write Access
The EEPROM access registers are located in the I/O space.
In order to prevent unintentional EEPROM writes, a specific write procedure must be followed. Refer to the description of the EEPROM control register (EECR) for details.
When the EEPROM is read in non-burst mode, the CPU is stopped for two clock cycles before the next instruction is executed. When the EEPROM is read in burst mode, the CPU is stopped for two clock cycles during load operation of the first byte. Following bytes can be read without wait states if the IN EEDR instruction is followed by a minimum of one other instruction. When the EEPROM is written, the CPU is stopped for two clock cycles before the next instruction is executed.
The EEPROM memory page 2 is only readable by the microcontroller.
The EEPROM memory page 1 is readable and programmable by the microcontroller. An EEPROM
read/write operation of a part of the memory can be blocked with additional
four control bits (EEAP0, EEAP1, EEAP2, EEAP3) located in the EEPR register.
The protected part of the EEPROM data memory has four selectable areas (AP0,
AP1, AP2 and AP3) with a size of 128 bytes each as shown in the following
figure. A read access of addresses located in protected areas always returns
‘0
’.
Write EEPROM (Secure Write Procedure)
To increase data security while writing the EEPROM, a “secure write procedure” is implemented in the firmware. The internal 10 byte-wide tmpAryApp buffer in the SRAM is used for data buffering during this procedure.
First the external MCU writes the data into the tmpAryApp buffer using the SPI command “Write SRAM Register”. The user has to take care that the data block begins with a 2-byte address (high byte first), followed by a 1-byte data block length indicator in the range of 1 to 7. Optionally, the external MCU might read out and verify the content of the tmpAryApp buffer using the SPI command “Read SRAM Register”. Finally, the SPI command “Trigger EEPROM Secure Write” starts writing the buffer content into the EEPROM. For more details about the usage of the SPI commands, refer to SPI Command Reference.
EEPROM Error Correction
The EEPROM memory uses hamming coding for error detection and correction. It is possible to correct one out of eight bits with the used code. The error detection and correction is performed automatically by hardware before putting the data on the data bus.
The following code examples show one assembly and one C function for writing to the EEPROM. The examples assume that interrupts are controlled (e.g., by disabling interrupts globally) so that no interrupts occur during execution of these functions. The examples also assume that no Flash boot loader is present in the software. If such code is present, the EEPROM write function must also wait for any ongoing SPM command to finish.
Assembly Code Example |
EEPROM_write: ; Wait for completion of previous write sbic EECR,EEWE rjmp EEPROM_write ; Set up address (r18:r17) in address register out EEARH, r18 out EEARL, r17 ; Write data (r16) to Data Register out EEDR,r16 ; Write logical ‘1’ to EEMWE sbi EECR,EEMWE ; Start eeprom write by setting EEWE sbi EECR,EEWE ret |
C Code Example |
void EEPROM_write(unsigned int uiAddress, unsigned char ucData) { /* Wait for completion of previous write */ while(EECR & (1<<EEWE)) ; /* Set up address and Data Registers */ EEAR = uiAddress; EEDR = ucData; /* Write logical ‘1’ to EEMWE */ EECR |= (1<<EEMWE); /* Start eeprom write by setting EEWE */ EECR |= (1<<EEWE); } |
The next code examples show assembly and C functions for reading the EEPROM. The examples assume that interrupts are controlled so that no interrupts occur during execution of these functions.
Assembly Code Example |
EEPROM_read: ; Wait for completion of previous write sbic EECR,EEWE rjmp EEPROM_read ; Set up address (r18:r17) in address register out EEARH, r18 out EEARL, r17 ; Start eeprom read by writing EERE sbi EECR,EERE ; Read data from Data Register in r16,EEDR ret |
C Code Example |
unsigned char EEPROM_read(unsigned int uiAddress) { /* Wait for completion of previous write */ while(EECR & (1<<EEWE)) ; /* Set up address register */ EEAR = uiAddress; /* Start eeprom read by writing EERE */ EECR |= (1<<EERE); /* Return data from Data Register */ return EEDR; } |
Programming Multiple Bytes in One Atomic Operation
It is possible to write multiple bytes into the EEPROM. Before initiating programming
(erase/write), the data to be written has to be loaded into the temporary
EEPROM page buffer. Writing EEPAGE to ‘1
’ enables a load
operation.
When the EEPAGE bit is written to ‘1
’, the temporary EEPROM page buffer is ready
for loading. To load data into the temporary EEPROM page buffer, the address
and data must be written into EEARL and EEDR, respectively. Note that the
data is loaded when EEDR is updated. For this reason, the address must be
written before the data. This operation is repeated until the temporary
EEPROM page buffer is filled up or until all data to be written are loaded.
The number of bytes loaded must not exceed the temporary EEPROM page size
before performing a program operation. Note that it is not possible to write
more than one time to each byte in the temporary EEPROM page buffer before
executing a program operation. If the same byte is written multiple times,
the content in the temporary EEPROM page is bitwise AND between the written
data (i.e., if 0xaa and 0x55 is loaded to the same byte, the result is
0x00).
The temporary EEPROM buffer is ready for new data after the program operation has completed. Alternatively, the temporary EEPROM buffer is flushed and ready for new data by writing EEPE (within four cycles after EEMPE is written) if the EEPM bits are 0b11. When the temporary EEPROM buffer is flushed, the EEPAGE bit is cleared. Loading data into the temporary EEPROM buffer takes three CPU clock cycles. If EEDR is written while EEPAGE is set, the CPU is stopped to ensure that the operation takes three cycles.
The order the different bits and registers are accessed is:
- Write EEPAGE in EECR (loading of temporary EEPROM buffer is enabled).
- Write the address bits needed to address bytes within a page into EEARL.
- Write data to EEDR.
- Repeat 2 and 3 above until the buffer is filled up or until all data is loaded.
- Write the remaining address bits for addressing the page into EEARH/EEARL.
- Select which programming mode must be executed
(EEPM bits). Write the EEPE bit in EECR (within four
cycles after EEMPE has been written) to start a
program operation. The temporary EEPROM page buffer
auto-erases after program operation is
completed.
OR
- If an error situation occurs and the loading needs to be terminated by software: Write EEPM to 0b11 and trigger flushing by writing EEPE (within four cycles after EEMPE is written).
- Select which programming mode must be executed
(EEPM bits). Write the EEPE bit in EECR (within four
cycles after EEMPE has been written) to start a
program operation. The temporary EEPROM page buffer
auto-erases after program operation is
completed.
Read Multiple Bytes with Burst Read Access
Reading several bytes from consecutive addresses of the EEPROM by software is supported by hardware as burst read access.
If the EEPROM burst read access is enabled by setting the EEBRE in EECR2, the EEPROM address (registers EEARH and EEARL) is incremented automatically after each read access of EEDR. The content of this new address is automatically read and stored in EEDR until the next read access.
The address register can be modified during the burst read access.
The burst read access requires the following sequence of instructions for accessing the EEPROM configuration registers:
- Write the start address to the EEARH and EEARL registers.
- Set burst read enable bit EEBRE in control register EECR2. This can also be done prior to writing the start address (step 1).
- Read fetched data from EEDR. The address pointer in EEARH/EEARL is incremented and data stored at this new address is fetched in the next cycle.
- Repeat step 3 for all addresses to be read.
If necessary, clear EEBRE in control register EECR2.
The following code examples show assembly and C functions for reading the EEPROM in burst read mode. The examples assume that interrupts are controlled so that no interrupts occur during execution of these functions.
Assembly Code Example |
EEPROM_burst_read: ; Wait for completion of previous write sbic EECR,EEWE rjmp EEPROM_burst_read ; Set up address (r18:r17) in address register out EEARH, r18 out EEARL, r17 ; Enable burst read sbi EECR2,EEBRE ; Read data from Data Register, address is automatically incremented in r16,EEDR st Z+, r16 ; e.g. store to SRAM or other instruction ; repeat previous in/st commands as often as necessary, ; if read is finished return ret |
C Code Example |
unsigned char EEPROM_enable_burst_read(unsigned int uiAddress) { /* Wait for completion of previous write */ while(EECR & (1<<EEWE)); /* Set up address register */ EEAR = uiAddress; /* Enable burst read EECR2 |= (1<<EEBRE); } . . . /* Enable burst read EEPROM_enable_burst_read(0x00); /* Read first value from EEPROM to SRAM variable tmp1 = EEDR; /* Read second value from EEPROM to SRAM variable tmp2 = EEDR; . . . |