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.

Figure 3-54. EEPROM Data Memory

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’.

Figure 3-55. Page 1 of EEPROM Data Memory

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.

Figure 3-56. EEPROM Write Secure Procedure

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:

  1. Write EEPAGE in EECR (loading of temporary EEPROM buffer is enabled).
  2. Write the address bits needed to address bytes within a page into EEARL.
  3. Write data to EEDR.
  4. Repeat 2 and 3 above until the buffer is filled up or until all data is loaded.
  5. Write the remaining address bits for addressing the page into EEARH/EEARL.
    1. 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

    2. 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).

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:

  1. Write the start address to the EEARH and EEARL registers.
  2. Set burst read enable bit EEBRE in control register EECR2. This can also be done prior to writing the start address (step 1).
  3. 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.
  4. 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;

. . .