BlinkenArea - GitList
Repositories
Blog
Wiki
flaneth
Code
Commits
Branches
Tags
Search
Tree:
d48e86e
Branches
Tags
master
flaneth
firmware
eeprom.c
header fix
Stefan Schuermans
commited
d48e86e
at 2012-05-02 18:39:39
eeprom.c
Blame
History
Raw
/* flaneth - flash and ethernet Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project - http://www.blinkenarea.org/ */ #include <avr/interrupt.h> #include <avr/eeprom.h> #include "config.h" #include "debug.h" #include "eeprom.h" #include "macros.h" #include "rtl8019.h" // flags for what needs to be written to the EEPROM unsigned char EepromNeedWrite = 0x00; // (extern) // writing what where unsigned char EepromWriteFlags = 0; // some flags #define EepromWriteFlagActive 0x01 // if writing something to EEPROM #define EepromWriteFlagCheck 0x02 // if writing check byte to EEPROM unsigned char *pEepromWriteSrc; // pointer to source data unsigned short EepromWriteDestAddr; // destination address in EEPROM unsigned char EepromWriteCnt; // number of bytes still to write // memory layout of EEPROM // - every byte B is stored as B, ~B for data safety // - so everythings needs double space #define EEPROM_ADDR_MAC 0 #define EEPROM_ADDR_IP (EEPROM_ADDR_MAC + 2 * sizeof( ConfigMac )) #define EEPROM_ADDR_MASK (EEPROM_ADDR_IP + 2 * sizeof( ConfigIp )) #define EEPROM_ADDR_GW (EEPROM_ADDR_MASK + 2 * sizeof( ConfigMask )) #define EEPROM_ADDR_S8P_PORT (EEPROM_ADDR_GW + 2 * sizeof( ConfigGw )) #define EEPROM_ADDR_S8P_KEY (EEPROM_ADDR_S8P_PORT + 2 * sizeof( ConfigS8pPort )) #define EEPROM_ADDR_HTTP_PORT (EEPROM_ADDR_S8P_KEY + 2 * sizeof( ConfigS8pKey )) #define EEPROM_ADDR_DEF_OUT (EEPROM_ADDR_HTTP_PORT + 2 * sizeof( ConfigHttpPort )) #define EEPROM_ADDR_FreeFromHere (EEPROM_ADDR_DEF_OUT + 2 * sizeof( ConfigDefOut )) // get configuration from EEPROM - helper function // checks data in EEPROM // gets data from EEPROM // returns 0x00 if successful static inline unsigned char EepromGetConfigHelp(unsigned short SrcAddr, unsigned char *pDest, unsigned char Len) { unsigned char i, b; // check data in EEPROM EEAR = SrcAddr; for (i = 0; i < Len; i++) { // read byte bit_set(EECR, EERE); b = EEDR; EEAR++; // XOR in check byte bit_set(EECR, EERE); b ^= EEDR; EEAR++; // XOR result must be 0xFF if (b != 0xFF) return 0x01; // error } // read data from EEPROM EEAR = SrcAddr; for (; Len > 0; Len--) { // read byte bit_set(EECR, EERE); *(pDest++) = EEDR; EEAR += 2; // skip check byte } return 0x00; // success } // get configuration from EEPROM void EepromGetConfig(void) // (extern) { // get MAC if (EepromGetConfigHelp(EEPROM_ADDR_MAC, ConfigMac, sizeof(ConfigMac)) == 0x00) // re-initialize RTL8019 RtlReinit(); // get IP, subnet mask, gateway IP EepromGetConfigHelp(EEPROM_ADDR_IP, ConfigIp, sizeof(ConfigIp)); EepromGetConfigHelp(EEPROM_ADDR_MASK, ConfigMask, sizeof(ConfigMask)); EepromGetConfigHelp(EEPROM_ADDR_GW, ConfigGw, sizeof(ConfigGw)); // get port for S8P EepromGetConfigHelp(EEPROM_ADDR_S8P_PORT, (unsigned char *)&ConfigS8pPort, sizeof(ConfigS8pPort)); // get symmetric key for S8P EepromGetConfigHelp(EEPROM_ADDR_S8P_KEY, ConfigS8pKey, sizeof(ConfigS8pKey)); // get port for webserver EepromGetConfigHelp(EEPROM_ADDR_HTTP_PORT, (unsigned char *)&ConfigHttpPort, sizeof(ConfigHttpPort)); // get default output state EepromGetConfigHelp(EEPROM_ADDR_DEF_OUT, &ConfigDefOut, sizeof(ConfigDefOut)); } // task function to do the work - call from main loop void EepromTask(void) // (extern) { // not writing something to EEPROM if (!(EepromWriteFlags & EepromWriteFlagActive)) { // MAC needs to be written if (EepromNeedWrite & EepromNeedWriteMac) { EepromNeedWrite &= ~EepromNeedWriteMac; pEepromWriteSrc = ConfigMac; EepromWriteDestAddr = EEPROM_ADDR_MAC; EepromWriteCnt = sizeof(ConfigMac); EepromWriteFlags = EepromWriteFlagActive; } // IP needs to be written else if (EepromNeedWrite & EepromNeedWriteIp) { EepromNeedWrite &= ~EepromNeedWriteIp; pEepromWriteSrc = ConfigIp; EepromWriteDestAddr = EEPROM_ADDR_IP; EepromWriteCnt = sizeof(ConfigIp); EepromWriteFlags = EepromWriteFlagActive; } // subnet mask needs to be written else if (EepromNeedWrite & EepromNeedWriteMask) { EepromNeedWrite &= ~EepromNeedWriteMask; pEepromWriteSrc = ConfigMask; EepromWriteDestAddr = EEPROM_ADDR_MASK; EepromWriteCnt = sizeof(ConfigMask); EepromWriteFlags = EepromWriteFlagActive; } // gateway IP needs to be written else if (EepromNeedWrite & EepromNeedWriteGw) { EepromNeedWrite &= ~EepromNeedWriteGw; pEepromWriteSrc = ConfigGw; EepromWriteDestAddr = EEPROM_ADDR_GW; EepromWriteCnt = sizeof(ConfigGw); EepromWriteFlags = EepromWriteFlagActive; } // port for S8P needs to be written else if (EepromNeedWrite & EepromNeedWriteS8pPort) { EepromNeedWrite &= ~EepromNeedWriteS8pPort; pEepromWriteSrc = (unsigned char *)&ConfigS8pPort; EepromWriteDestAddr = EEPROM_ADDR_S8P_PORT; EepromWriteCnt = sizeof(ConfigS8pPort); EepromWriteFlags = EepromWriteFlagActive; } // symmetric key for S8P needs to be written else if (EepromNeedWrite & EepromNeedWriteS8pKey) { EepromNeedWrite &= ~EepromNeedWriteS8pKey; pEepromWriteSrc = ConfigS8pKey; EepromWriteDestAddr = EEPROM_ADDR_S8P_KEY; EepromWriteCnt = sizeof(ConfigS8pKey); EepromWriteFlags = EepromWriteFlagActive; } // port for webserver needs to be written else if (EepromNeedWrite & EepromNeedWriteHttpPort) { EepromNeedWrite &= ~EepromNeedWriteHttpPort; pEepromWriteSrc = (unsigned char *)&ConfigHttpPort; EepromWriteDestAddr = EEPROM_ADDR_HTTP_PORT; EepromWriteCnt = sizeof(ConfigHttpPort); EepromWriteFlags = EepromWriteFlagActive; } // if default output state needs to be written else if (EepromNeedWrite & EepromNeedWriteDefOut) { EepromNeedWrite &= ~EepromNeedWriteDefOut; pEepromWriteSrc = &ConfigDefOut; EepromWriteDestAddr = EEPROM_ADDR_DEF_OUT; EepromWriteCnt = sizeof(ConfigDefOut); EepromWriteFlags = EepromWriteFlagActive; } // nothing needs to be written else return; debug_eeprom_printf("write adr=0x%04X len=%u", EepromWriteDestAddr, EepromWriteCnt); } // EEPROM still busy if (bit_is_set(EECR, EEWE)) // try again later return; // disable interrupts cli(); // get address in EEPROM and data to write EEAR = EepromWriteDestAddr++; if (EepromWriteFlags & EepromWriteFlagCheck) // check byte { EEDR = ~*(pEepromWriteSrc++); // invert and advance source pointer EepromWriteCnt--; // count down number of bytes to write if (EepromWriteCnt <= 0) // finished EepromWriteFlags &= ~EepromWriteFlagActive; } else // not check byte EEDR = *pEepromWriteSrc; // use data byte as it is EepromWriteFlags ^= EepromWriteFlagCheck; // toggle check byte bit // initiate write to EEPROM bit_set(EECR, EEMWE); bit_set(EECR, EEWE); // enable interrupts sei(); }