Read/Write from ATtiny1616 EEPROM
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 0x1400 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.
avr avr-gcc eeprom non-volatile
add a comment |
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 0x1400 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.
avr avr-gcc eeprom non-volatile
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03
add a comment |
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 0x1400 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.
avr avr-gcc eeprom non-volatile
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 0x1400 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.
avr avr-gcc eeprom non-volatile
avr avr-gcc eeprom non-volatile
edited Nov 19 '18 at 11:03
ReAl
6081216
6081216
asked Nov 12 '18 at 19:05
KaimbelicKaimbelic
32
32
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03
add a comment |
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268544%2fread-write-from-attiny1616-eeprom%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268544%2fread-write-from-attiny1616-eeprom%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Where are the EEPROM read/write function coming from and how are those implemented? Are you sure you do not have to provide an address starting from 0x1400 (like uint16_t eeprom_address1 = 0x1400)?
– Rev1.0
Nov 13 '18 at 7:56
The EEPROM functions are defined by atmel. I have edited the original to reflect those. The functions say they take in an address, and add it to the start position. I assume that if I says 0x01 that it would be 0x1401 in function.
– Kaimbelic
Nov 13 '18 at 15:47
Hmm I can't see anything obvious wrong with your code. How did you "print" the test_data contents? Maybe just your output is the problem.
– Rev1.0
Nov 14 '18 at 9:03