Read/Write from ATtiny1616 EEPROM

1.2k views Asked by At

Using the ATting1616 within avr-gcc I am trying to read and write to the EEPROM.

The ATtiny1616 uses NVMCTRL - Nonvolatile Memory Controller for byte level read/writes. I am using NVMCTRL to read/write blocks from the EEPROM, but it is not working correctly.

Here is an example to demonstrate what I am trying to so.

Lets say that I was to save two different values within the EEPROM and then read back each ones value.

uint16_t eeprom_address1 = 0x01;//!< Address one for first saved value
uint16_t eeprom_address2 = 0x32;//!< Address two for second saved value

char save_one = "12345"; //!< Test value to save, one
char save_two = "testing";//!< Test value to save, two


FLASH_0_write_eeprom_block(eeprom_address1,save_one,7); //!< Save first value to address 1
FLASH_0_write_eeprom_block(eeprom_address2,save_two,7); //!< Save second value to address 2


char test_data[7] = {0}; //!< Just some empty array to put chars into

FLASH_0_read_eeprom_block(eeprom_address1,test_data,7); //!< Read eeprom from address, to address+ 7, and store back into test_data

Here are the read/write functions:

#  define EEPROM_START     (0x1400)//!< is located in header file
/**
 * \brief Read a block from eeprom
 *
 * \param[in] eeprom_adr The byte-address in eeprom to read from
 * \param[in] data Buffer to place read data into
 *
 * \return Nothing
 */
void FLASH_0_read_eeprom_block(eeprom_adr_t eeprom_adr, uint8_t *data, size_t size)
{

    // Read operation will be stalled by hardware if any write is in progress

    memcpy(data, (uint8_t *)(EEPROM_START + eeprom_adr), size);
}

/**
 * \brief Write a block to eeprom
 *
 * \param[in] eeprom_adr The byte-address in eeprom to write to
 * \param[in] data The buffer to write
 *
 * \return Status of write operation
 */
nvmctrl_status_t FLASH_0_write_eeprom_block(eeprom_adr_t eeprom_adr, uint8_t *data, size_t size)
{

    uint8_t *write = (uint8_t *)(EEPROM_START + eeprom_adr);

    /* Wait for completion of previous write */
    while (NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm)
        ;

    /* Clear page buffer */
    ccp_write_spm((void *)&NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEBUFCLR_gc);

    do {
        /* Write byte to page buffer */
        *write++ = *data++;
        size--;
        // If we have filled an entire page or written last byte to a partially filled page
        if ((((uintptr_t)write % EEPROM_PAGE_SIZE) == 0) || (size == 0)) {
            /* Erase written part of page and program with desired value(s) */
            ccp_write_spm((void *)&NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
        }
    } while (size != 0);

    return NVM_OK;
}

The value that is turned if test_data[7] is printed will be "testing". When looking at the memory in debug mode I am able to see that the value is always being written to the first memory location in the data EEPROM.[0x1400] In this case starting at memory x1400 the value of "testing" starts.

There seems to be something fundamental that I have failed to understand with reading and write to the EEPROM. Any guidance would be greatly appreciated.

0

There are 0 answers