From 54b4fac7a1a87dc21c6e26b69513897c20605fa5 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Wed, 30 Dec 2015 20:01:07 -0800 Subject: [PATCH] More cleanup --- src/util.h | 33 +-- src/xmega/xmega_eeprom.c | 526 +++++++++++++-------------------------- 2 files changed, 191 insertions(+), 368 deletions(-) diff --git a/src/util.h b/src/util.h index 7fa2a80..295d1d7 100644 --- a/src/util.h +++ b/src/util.h @@ -24,6 +24,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + /* util.c/.h contains a dog's breakfast of supporting functions that are * not specific to tinyg: including: * @@ -35,10 +36,7 @@ #ifndef UTIL_H_ONCE #define UTIL_H_ONCE -/****** Global Scope Variables and Functions ******/ - -//*** vector utilities *** - +// Vector utilities extern float vector[AXES]; // vector of axes for passing to subroutines #define clear_vector(a) (memset(a,0,sizeof(a))) @@ -49,28 +47,24 @@ uint8_t vector_equal(const float a[], const float b[]); float *set_vector(float x, float y, float z, float a, float b, float c); float *set_vector_by_axis(float value, uint8_t axis); -//*** math utilities *** - +// Math utilities float min3(float x1, float x2, float x3); float min4(float x1, float x2, float x3, float x4); float max3(float x1, float x2, float x3); float max4(float x1, float x2, float x3, float x4); -//float std_dev(float a[], uint8_t n, float *mean); -//*** string utilities *** +// String utilities uint8_t isnumber(char_t c); char_t *escape_string(char_t *dst, char_t *src); char_t *pstr2str(const char *pgm_string); char_t fntoa(char_t *str, float n, uint8_t precision); uint16_t compute_checksum(char_t const *string, const uint16_t length); -//*** other utilities *** - +// Other utilities uint32_t SysTickTimer_getValue(); -//**** Math Support ***** - +// Math support #ifndef square #define square(x) ((x)*(x)) /* UNSAFE */ #endif @@ -95,15 +89,14 @@ uint32_t SysTickTimer_getValue(); #endif #ifndef EPSILON -#define EPSILON ((float)0.00001) // allowable rounding error for floats -//#define EPSILON ((float)0.000001) // allowable rounding error for floats +#define EPSILON ((float)0.00001) // allowable rounding error for floats #endif #ifndef fp_EQ -#define fp_EQ(a,b) (fabs(a-b) < EPSILON) // requires math.h to be included in each file used +#define fp_EQ(a,b) (fabs(a - b) < EPSILON) // requires math.h to be included in each file used #endif #ifndef fp_NE -#define fp_NE(a,b) (fabs(a-b) > EPSILON) // requires math.h to be included in each file used +#define fp_NE(a,b) (fabs(a - b) > EPSILON) // requires math.h to be included in each file used #endif #ifndef fp_ZERO #define fp_ZERO(a) (fabs(a) < EPSILON) // requires math.h to be included in each file used @@ -112,17 +105,17 @@ uint32_t SysTickTimer_getValue(); #define fp_NOT_ZERO(a) (fabs(a) > EPSILON) // requires math.h to be included in each file used #endif #ifndef fp_FALSE -#define fp_FALSE(a) (a < EPSILON) // float is interpreted as FALSE (equals zero) +#define fp_FALSE(a) (a < EPSILON) // float is interpreted as FALSE (equals zero) #endif #ifndef fp_TRUE -#define fp_TRUE(a) (a > EPSILON) // float is interpreted as TRUE (not equal to zero) +#define fp_TRUE(a) (a > EPSILON) // float is interpreted as TRUE (not equal to zero) #endif // Constants #define MAX_LONG (2147483647) #define MAX_ULONG (4294967295) #define MM_PER_INCH (25.4) -#define INCHES_PER_MM (1/25.4) +#define INCHES_PER_MM (1 / 25.4) #define MICROSECONDS_PER_MINUTE ((float)60000000) #define uSec(a) ((float)(a * MICROSECONDS_PER_MINUTE)) @@ -131,4 +124,4 @@ uint32_t SysTickTimer_getValue(); #define M_SQRT3 (1.73205080756888) #endif -#endif // End of include guard: UTIL_H_ONCE +#endif // UTIL_H_ONCE diff --git a/src/xmega/xmega_eeprom.c b/src/xmega/xmega_eeprom.c index 726fc60..2fa151a 100644 --- a/src/xmega/xmega_eeprom.c +++ b/src/xmega/xmega_eeprom.c @@ -87,139 +87,69 @@ #include #include #include -#include "../tinyg.h" // only used to define __UNIT_TEST_EEPROM. can be removed. +#include "../tinyg.h" // only used to define __UNIT_TEST_EEPROM. can be removed. #ifdef __UNIT_TEST_EEPROM #include -#include // precursor for xio.h -#include // for memset() #include -#include "xio.h" // all device includes are nested here +#include // for memset() +#include #endif #define __USE_AVR1008_EEPROM // use the AVR1008 workaround code -#define ARBITRARY_MAX_LENGTH 80 // string max for NNVM write - -/**** Inline assembly to support NVM operations ****/ - -static inline void NVM_EXEC() -{ - void *z = (void *)&NVM_CTRLA; - - __asm__ volatile("out %[ccp], %[ioreg]" "\n\t" - "st z, %[cmdex]" - : - : [ccp] "I" (_SFR_IO_ADDR(CCP)), - [ioreg] "d" (CCP_IOREG_gc), - [cmdex] "r" (NVM_CMDEX_bm), - [z] "z" (z) - ); -} +#define ARBITRARY_MAX_LENGTH 80 // string max for NNVM write + -/**** AVR1008 fixes ****/ +// Inline assembly to support NVM operations +static inline void NVM_EXEC() { + void *z = (void *)&NVM_CTRLA; + + __asm__ volatile("out %[ccp], %[ioreg]" "\n\t" + "st z, %[cmdex]" + : + : [ccp] "I" (_SFR_IO_ADDR(CCP)), + [ioreg] "d" (CCP_IOREG_gc), + [cmdex] "r" (NVM_CMDEX_bm), + [z] "z" (z) + ); +} #ifdef __USE_AVR1008_EEPROM -//Interrupt handler for for EEPROM write "done" interrupt -ISR(NVM_EE_vect) -{ - NVM.INTCTRL = (NVM.INTCTRL & ~NVM_EELVL_gm); // Disable EEPROM interrupt +// Interrupt handler for for EEPROM write "done" interrupt +ISR(NVM_EE_vect) { + NVM.INTCTRL = (NVM.INTCTRL & ~NVM_EELVL_gm); // Disable EEPROM interrupt } -// Wrapper for NVM_EXEC that executes the workaround code -static inline void NVM_EXEC_WRAPPER() -{ - uint8_t sleepCtr = SLEEP.CTRL; // Save the Sleep register +// Wrapper for NVM_EXEC that executes the workaround code +static inline void NVM_EXEC_WRAPPER() { + uint8_t sleepCtr = SLEEP.CTRL; // Save the Sleep register // Set sleep mode to IDLE - SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP.CTRL) | SLEEP_SMODE_IDLE_gc; - uint8_t statusStore = PMIC.STATUS; // Save the PMIC Status... - uint8_t pmicStore = PMIC.CTRL; //...and control registers + SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP.CTRL) | SLEEP_SMODE_IDLE_gc; + uint8_t statusStore = PMIC.STATUS; // Save the PMIC Status... + uint8_t pmicStore = PMIC.CTRL; //...and control registers // Enable only hi interrupts - PMIC.CTRL = (PMIC.CTRL & ~(PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm)) | PMIC_HILVLEN_bm; - uint8_t globalInt = SREG; // Save SREG for later use - sei(); // Enable global interrupts - SLEEP.CTRL |= SLEEP_SEN_bm; // Set sleep enabled - uint8_t eepromintStore = NVM.INTCTRL; // Save eeprom int settings - NVM_EXEC(); // exec EEPROM command - NVM.INTCTRL = NVM_EELVL0_bm | NVM_EELVL1_bm;// Enable EEPROM int - sleep_cpu(); // Sleep before 2.5uS passed - SLEEP.CTRL = sleepCtr; // Restore sleep settings - PMIC.STATUS = statusStore; // Restore PMIC status... - PMIC.CTRL = pmicStore; //...and control registers - NVM.INTCTRL = eepromintStore; // Restore EEPROM int settings - SREG = globalInt; // Restore global int settings + PMIC.CTRL = (PMIC.CTRL & ~(PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm)) | PMIC_HILVLEN_bm; + uint8_t globalInt = SREG; // Save SREG for later use + sei(); // Enable global interrupts + SLEEP.CTRL |= SLEEP_SEN_bm; // Set sleep enabled + uint8_t eepromintStore = NVM.INTCTRL; // Save eeprom int settings + NVM_EXEC(); // exec EEPROM command + NVM.INTCTRL = NVM_EELVL0_bm | NVM_EELVL1_bm;// Enable EEPROM int + sleep_cpu(); // Sleep before 2.5uS passed + SLEEP.CTRL = sleepCtr; // Restore sleep settings + PMIC.STATUS = statusStore; // Restore PMIC status... + PMIC.CTRL = pmicStore; //...and control registers + NVM.INTCTRL = eepromintStore; // Restore EEPROM int settings + SREG = globalInt; // Restore global int settings } #else #define NVM_EXEC_WRAPPER NVM_EXEC #endif // __USE_AVR1008_EEPROM -/************************************************************************* - ****** Functions added for TinyG **************************************** - *************************************************************************/ - -/* - * Non Non-Volatile Memory RAM array & - * functions to substitute for EEPROM for testing. - */ - -#ifdef __NNVM -char nnvm[NNVM_SIZE]; // not non-volatile memory - emulate xmega192 or 256 has 4096 - -void NNVM_WriteString(const uint16_t address, const char *buf, const uint8_t unused); -void NNVM_ReadString(const uint16_t address, char *buf, const uint8_t size); -void NNVM_WriteBytes(const uint16_t address, const int8_t *buf, const uint16_t size); -void NNVM_ReadBytes(const uint16_t address, int8_t *buf, const uint16_t size); - -void NNVM_WriteString(const uint16_t address, const char *buf, const uint8_t unused) -{ - uint16_t j = address; // NNVM pointer - - for (uint16_t i = 0; i < ARBITRARY_MAX_LENGTH; i++) { - nnvm[j++] = buf[i]; - if (!buf[i]) { - return; - } - } -} - -void NNVM_ReadString(const uint16_t address, char *buf, const uint8_t size) -{ - uint16_t j = address; // NNVM pointer - - for (uint16_t i = 0; i < size; i++) { - buf[i] = nnvm[j++]; - if (!buf[i]) { - return; - } - } -} - -void NNVM_WriteBytes(const uint16_t address, const int8_t *buf, const uint16_t size) -{ - uint16_t j = address; // NNVM pointer - - for (uint16_t i = 0; i < size; i++) { - nnvm[j++] = buf[i]; - } - return; -} - -void NNVM_ReadBytes(const uint16_t address, int8_t *buf, const uint16_t size) -{ - uint16_t j = address; // NNVM pointer - - for (uint16_t i = 0; i < size; i++) { - buf[i] = nnvm[j++]; - } - return; -} - - -#endif // __NNVM - /* * EEPROM_WriteString() - write string to EEPROM; may span multiple pages * @@ -259,79 +189,17 @@ void NNVM_ReadBytes(const uint16_t address, int8_t *buf, const uint16_t size) * as single page operations. */ -uint16_t EEPROM_WriteString(const uint16_t address, const char *buf, const uint8_t terminate) -{ -#ifdef __NNVM - NNVM_WriteString(address, buf, true); - return address; -#else - uint16_t addr = address; // local copy - uint8_t i = 0; // index into string - - EEPROM_DisableMapping(); - while (buf[i]) { - EEPROM_WriteByte(addr++, buf[i++]); - } - if (terminate) { - EEPROM_WriteByte(addr++, 0); - } - return addr; // return next address in EEPROM -#endif //__NNVM -} +uint16_t EEPROM_WriteString(const uint16_t address, const char *buf, const uint8_t terminate) { + uint16_t addr = address; // local copy + uint8_t i = 0; // index into string -/* //+++ this is broken and will need to be fixed to work with NNVM -#ifdef __TEST_EEPROM_WRITE - uint8_t testbuffer[32]; // fake out the page buffer -#endif // __TEST_EEPROM_WRITE - -uint16_t EEPROM_WriteString(const uint16_t address, const char *string, const uint8_t terminate) -{ - uint8_t i = 0; // index into string - uint16_t curaddr; // starting addr of string remaining to write - uint16_t endaddr; // ending address, adjusted for termination - uint16_t strnlen; // remaining unwritten string len (zero based) - uint8_t curpage; // current page number (0 - 127) - uint8_t endpage; // ending page number (0 - 127) - uint8_t byteidx; // index into page - uint8_t byteend; // ending byte number in page - - // initialize variables - EEPROM_DisableMapping(); - curaddr = address; - strnlen = strlen(buf) + terminate - 1; // terminate will be 1 or 0 - endaddr = address + strnlen; - curpage = (curaddr >> 5) & 0x7F; // mask it just to be safe - endpage = (endaddr >> 5) & 0x7F; // mask it just to be safe - - while (curpage <= endpage) { - // initialize addresses and variables for this write page - byteidx = curaddr & EEPROM_BYTE_ADDR_MASK_gm; - byteend = min((byteidx + strnlen), EEPROM_PAGESIZE-1); - strnlen = strnlen - (byteend - byteidx) - 1;// chars left in string - curaddr = curaddr + (byteend - byteidx) + 1;// bump current address - NVM.ADDR1 = curpage++; // set upper addr bytes - NVM.ADDR2 = 0x00; - - // load page buffer w/string contents and optional 0 termination - EEPROM_FlushBuffer(); // ensure no unintentional data is written - NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; // Page Load command - while (byteidx <= byteend) { -#ifdef __NNVM - NVM.ADDR0 = byteidx; - testbuffer[byteidx++] = buf[i++]; -#else - // use EEPROM (the real code) - NVM.ADDR0 = byteidx++; // set buffer location for data - NVM.DATA0 = buf[i++]; // writing DATA0 triggers write to buffer -#endif - } - // run EEPROM Atomic Write (Erase&Write) command. - NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc; // load command - NVM_EXEC_WRAPPER(); //write protection signature and execute cmd - } - return curaddr; + EEPROM_DisableMapping(); + while (buf[i]) EEPROM_WriteByte(addr++, buf[i++]); + if (terminate) EEPROM_WriteByte(addr++, 0); + + return addr; // return next address in EEPROM } -*/ + /* * EEPROM_ReadString() - read string from EEPROM; may span multiple pages @@ -345,37 +213,29 @@ uint16_t EEPROM_WriteString(const uint16_t address, const char *string, const ui * size cutoff string and terminate at this length * return next address past string termination */ +uint16_t EEPROM_ReadString(const uint16_t address, char *buf, const uint16_t size) { + uint16_t addr = address; // local copy + uint16_t i = 0; // index into strings -uint16_t EEPROM_ReadString(const uint16_t address, char *buf, const uint16_t size) -{ -#ifdef __NNVM - NNVM_ReadString(address, buf, size); - return(address + sizeof(buf)); -#else - uint16_t addr = address; // local copy - uint16_t i = 0; // index into strings - - EEPROM_DisableMapping(); - - for (i = 0; i < size; i++) { - NVM.ADDR0 = addr & 0xFF; // set read address - NVM.ADDR1 = (addr++ >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - - EEPROM_WaitForNVM(); // Wait until NVM is not busy - NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command - NVM_EXEC(); - if (!(buf[i] = NVM.DATA0)) { - break; - } - } - if (i == size) { // null terinate the buffer overflow case - buf[i] = 0; - } - return addr; -#endif //__NNVM + EEPROM_DisableMapping(); + + for (i = 0; i < size; i++) { + NVM.ADDR0 = addr & 0xFF; // set read address + NVM.ADDR1 = (addr++ >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + + EEPROM_WaitForNVM(); // Wait until NVM is not busy + NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command + NVM_EXEC(); + if (!(buf[i] = NVM.DATA0)) break; + } + + if (i == size) buf[i] = 0; // null terinate the buffer overflow case + + return addr; } + /* * EEPROM_WriteBytes() - write N bytes to EEPROM; may span multiple pages * @@ -386,24 +246,17 @@ uint16_t EEPROM_ReadString(const uint16_t address, char *buf, const uint16_t siz * * Returns address past the write */ +uint16_t EEPROM_WriteBytes(const uint16_t address, const int8_t *buf, const uint16_t size) { + uint16_t addr = address; // local copy -uint16_t EEPROM_WriteBytes(const uint16_t address, const int8_t *buf, const uint16_t size) -{ -#ifdef __NNVM - NNVM_WriteBytes(address, buf, size); - return(address + size); -#else - uint16_t i; - uint16_t addr = address; // local copy - - EEPROM_DisableMapping(); - for (i=0; i> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - - EEPROM_WaitForNVM(); // Wait until NVM is not busy - NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command - NVM_EXEC(); - buf[i] = NVM.DATA0; - } - return addr; -#endif //__NNVM -} + EEPROM_DisableMapping(); + + for (uint16_t i = 0; i < size; i++) { + NVM.ADDR0 = addr & 0xFF; // set read address + NVM.ADDR1 = (addr++ >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + + EEPROM_WaitForNVM(); // Wait until NVM is not busy + NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command + NVM_EXEC(); + buf[i] = NVM.DATA0; + } -/************************************************************************* - ****** Functions from Atmel eeprom_driver.c w/some changes ************** - *************************************************************************/ + return addr; +} -// Look for NVM_EXEC_WRAPPER in places. /* * EEPROM_WaitForNVM() - Wait for any NVM access to finish @@ -451,12 +292,11 @@ uint16_t EEPROM_ReadBytes(const uint16_t address, int8_t *buf, const uint16_t si * any previous operations are finished yet, like an EEPROM write. */ -void EEPROM_WaitForNVM( void ) -{ - do { - } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm); +void EEPROM_WaitForNVM() { + while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm); } + /* * EEPROM_FlushBuffer() - Flush temporary EEPROM page buffer. * @@ -466,16 +306,16 @@ void EEPROM_WaitForNVM( void ) * * Note: The EEPROM write operations will automatically flush the buffer for you */ +void EEPROM_FlushBuffer() { + EEPROM_WaitForNVM(); // Wait until NVM is not busy -void EEPROM_FlushBuffer( void ) -{ - EEPROM_WaitForNVM(); // Wait until NVM is not busy - if ((NVM.STATUS & NVM_EELOAD_bm) != 0) { // Flush page buffer if necessary - NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc; - NVM_EXEC(); - } + if ((NVM.STATUS & NVM_EELOAD_bm) != 0) { // Flush page buffer if necessary + NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc; + NVM_EXEC(); + } } + /* * EEPROM_WriteByte() - write one byte to EEPROM using IO mapping * EEPROM_WriteByteByPage() - write one byte using page addressing (MACRO) @@ -491,20 +331,19 @@ void EEPROM_FlushBuffer( void ) * Note: DO NOT USE THIS FUNCTION IF YOU CAN AVOID IT AS ENDURANCE SUCKS * Use EEPROM_WriteString(), or write a new routine for binary blocks. */ - -void EEPROM_WriteByte(uint16_t address, uint8_t value) -{ - EEPROM_DisableMapping(); // *** SAFETY *** - EEPROM_FlushBuffer(); // prevent unintentional write - NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;// load page_load command - NVM.ADDR0 = address & 0xFF; // set buffer addresses - NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - NVM.DATA0 = value; // load write data - triggers EEPROM page buffer load - NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;// Atomic Write (Erase&Write) - NVM_EXEC_WRAPPER(); // Load command, write protection signature & exec command +void EEPROM_WriteByte(uint16_t address, uint8_t value) { + EEPROM_DisableMapping(); // *** SAFETY *** + EEPROM_FlushBuffer(); // prevent unintentional write + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;// load page_load command + NVM.ADDR0 = address & 0xFF; // set buffer addresses + NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + NVM.DATA0 = value; // load write data - triggers EEPROM page buffer load + NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;// Atomic Write (Erase&Write) + NVM_EXEC_WRAPPER(); // Load command, write protection signature & exec command } + /* * EEPROM_ReadByte() - Read one byte from EEPROM using IO mapping. * EEPROM_ReadChar() - Read one char from EEPROM using IO mapping. @@ -518,19 +357,19 @@ void EEPROM_WriteByte(uint16_t address, uint8_t value) * address EEPROM address, between 0 and EEPROM_SIZE * returns byte value read from EEPROM. */ - -uint8_t EEPROM_ReadByte(uint16_t address) -{ - EEPROM_DisableMapping(); // *** SAFETY *** - EEPROM_WaitForNVM(); // Wait until NVM is not busy - NVM.ADDR0 = address & 0xFF; // set read address - NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command - NVM_EXEC(); - return NVM.DATA0; +uint8_t EEPROM_ReadByte(uint16_t address) { + EEPROM_DisableMapping(); // *** SAFETY *** + EEPROM_WaitForNVM(); // Wait until NVM is not busy + NVM.ADDR0 = address & 0xFF; // set read address + NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + NVM.CMD = NVM_CMD_READ_EEPROM_gc; // issue EEPROM Read command + NVM_EXEC(); + + return NVM.DATA0; } + /* * EEPROM_LoadByte() - Load single byte into temporary page buffer. * @@ -547,18 +386,17 @@ uint8_t EEPROM_ReadByte(uint16_t address) * byteAddr EEPROM Byte address, between 0 and EEPROM_PAGESIZE. * value Byte value to write to buffer. */ - -void EEPROM_LoadByte(uint8_t byteAddr, uint8_t value) -{ - EEPROM_DisableMapping(); // +++ SAFETY - EEPROM_WaitForNVM(); // wait until NVM is not busy - NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; // prepare NVM command - NVM.ADDR0 = byteAddr & EEPROM_ADDR1_MASK_gm;// set address - NVM.ADDR1 = 0x00; - NVM.ADDR2 = 0x00; - NVM.DATA0 = value; // Set data, which triggers loading EEPROM page buffer +void EEPROM_LoadByte(uint8_t byteAddr, uint8_t value) { + EEPROM_DisableMapping(); // +++ SAFETY + EEPROM_WaitForNVM(); // wait until NVM is not busy + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; // prepare NVM command + NVM.ADDR0 = byteAddr & EEPROM_ADDR1_MASK_gm;// set address + NVM.ADDR1 = 0x00; + NVM.ADDR2 = 0x00; + NVM.DATA0 = value; // Set data, which triggers loading EEPROM page buffer } + /* * EEPROM_LoadPage() - Load entire page into temporary EEPROM page buffer. * @@ -574,22 +412,21 @@ void EEPROM_LoadByte(uint8_t byteAddr, uint8_t value) * * values Pointer to SRAM buffer containing an entire page. */ - -void EEPROM_LoadPage( const uint8_t * values ) -{ - EEPROM_DisableMapping(); // +++ SAFETY - EEPROM_WaitForNVM(); // wait until NVM not busy - NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; - NVM.ADDR1 = 0x00; // set upper addr's to zero - NVM.ADDR2 = 0x00; - - for (uint8_t i = 0; i < EEPROM_PAGESIZE; ++i) { // load multiple bytes - NVM.ADDR0 = i; - NVM.DATA0 = *values; - ++values; - } +void EEPROM_LoadPage(const uint8_t * values) { + EEPROM_DisableMapping(); // +++ SAFETY + EEPROM_WaitForNVM(); // wait until NVM not busy + NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc; + NVM.ADDR1 = 0x00; // set upper addr's to zero + NVM.ADDR2 = 0x00; + + for (uint8_t i = 0; i < EEPROM_PAGESIZE; ++i) { // load multiple bytes + NVM.ADDR0 = i; + NVM.DATA0 = *values; + ++values; + } } + /* * EEPROM_AtomicWritePage() - Write already loaded page into EEPROM. * @@ -602,18 +439,17 @@ void EEPROM_LoadPage( const uint8_t * values ) * * pageAddr EEPROM Page address between 0 and EEPROM_SIZE/EEPROM_PAGESIZE */ - -inline void EEPROM_AtomicWritePage(uint8_t pageAddr) -{ - EEPROM_WaitForNVM(); // wait until NVM not busy - uint16_t address = (uint16_t)(pageAddr*EEPROM_PAGESIZE); - NVM.ADDR0 = address & 0xFF; // set addresses - NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc; // erase & write page command - NVM_EXEC(); +inline void EEPROM_AtomicWritePage(uint8_t pageAddr) { + EEPROM_WaitForNVM(); // wait until NVM not busy + uint16_t address = (uint16_t)(pageAddr * EEPROM_PAGESIZE); + NVM.ADDR0 = address & 0xFF; // set addresses + NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc; // erase & write page command + NVM_EXEC(); } + /* * EEPROM_ErasePage() - Erase EEPROM page. * @@ -621,18 +457,17 @@ inline void EEPROM_AtomicWritePage(uint8_t pageAddr) * * pageAddr EEPROM Page address between 0 and EEPROM_SIZE/EEPROM_PAGESIZE */ - -inline void EEPROM_ErasePage( uint8_t pageAddr ) -{ - EEPROM_WaitForNVM(); // wait until NVM not busy - uint16_t address = (uint16_t)(pageAddr*EEPROM_PAGESIZE); - NVM.ADDR0 = address & 0xFF; // set addresses - NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - NVM.CMD = NVM_CMD_ERASE_EEPROM_PAGE_gc; // erase page command - NVM_EXEC_WRAPPER(); +inline void EEPROM_ErasePage(uint8_t pageAddr) { + EEPROM_WaitForNVM(); // wait until NVM not busy + uint16_t address = (uint16_t)(pageAddr * EEPROM_PAGESIZE); + NVM.ADDR0 = address & 0xFF; // set addresses + NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + NVM.CMD = NVM_CMD_ERASE_EEPROM_PAGE_gc; // erase page command + NVM_EXEC_WRAPPER(); } + /* * EEPROM_SplitWritePage() - Write (without erasing) EEPROM page. * @@ -642,26 +477,21 @@ inline void EEPROM_ErasePage( uint8_t pageAddr ) * * pageAddr EEPROM Page address between 0 and EEPROM_SIZE/EEPROM_PAGESIZE */ - -inline void EEPROM_SplitWritePage( uint8_t pageAddr ) -{ - EEPROM_WaitForNVM(); // wait until NVM not busy - uint16_t address = (uint16_t)(pageAddr*EEPROM_PAGESIZE); - NVM.ADDR0 = address & 0xFF; // set addresses - NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; - NVM.ADDR2 = 0x00; - NVM.CMD = NVM_CMD_WRITE_EEPROM_PAGE_gc; // split write command - NVM_EXEC_WRAPPER(); +inline void EEPROM_SplitWritePage(uint8_t pageAddr) { + EEPROM_WaitForNVM(); // wait until NVM not busy + uint16_t address = (uint16_t)(pageAddr * EEPROM_PAGESIZE); + NVM.ADDR0 = address & 0xFF; // set addresses + NVM.ADDR1 = (address >> 8) & EEPROM_ADDR1_MASK_gm; + NVM.ADDR2 = 0x00; + NVM.CMD = NVM_CMD_WRITE_EEPROM_PAGE_gc; // split write command + NVM_EXEC_WRAPPER(); } -/* - * EEPROM_EraseAll() - Erase entire EEPROM memory to 0xFF - */ -inline void EEPROM_EraseAll( void ) -{ - EEPROM_WaitForNVM(); // wait until NVM not busy - NVM.CMD = NVM_CMD_ERASE_EEPROM_gc; // erase all command - NVM_EXEC_WRAPPER(); +/// EEPROM_EraseAll() - Erase entire EEPROM memory to 0xFF +inline void EEPROM_EraseAll() { + EEPROM_WaitForNVM(); // wait until NVM not busy + NVM.CMD = NVM_CMD_ERASE_EEPROM_gc; // erase all command + NVM_EXEC_WRAPPER(); } -- 2.27.0