From 2cb677445d048dad30742514196cc36982f4cd80 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Fri, 20 Sep 2024 15:31:45 +0200 Subject: [PATCH 1/4] Define basic EEPROM data structures and functions --- src/common.h | 1 + src/common/eeprom.c | 17 +++++++++++++++++ src/common/eeprom.h | 14 ++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 src/common/eeprom.c create mode 100644 src/common/eeprom.h diff --git a/src/common.h b/src/common.h index f1d0c78..ae5ad53 100644 --- a/src/common.h +++ b/src/common.h @@ -4,6 +4,7 @@ #include "common/math.h" #include "common/types.h" #include "common/watchdog.h" +#include "common/eeprom.h" #include #include diff --git a/src/common/eeprom.c b/src/common/eeprom.c new file mode 100644 index 0000000..a250306 --- /dev/null +++ b/src/common/eeprom.c @@ -0,0 +1,17 @@ +#include "common.h" + +// TODO: Implement EEPROM storage with wear leveling + +int MEM_Read(mem_data_t *out) +{ + UNUSED(out); + + return 0; +} + +int MEM_Write(mem_data_t *in) +{ + UNUSED(in); + + return 0; +} diff --git a/src/common/eeprom.h b/src/common/eeprom.h new file mode 100644 index 0000000..4b6eeb8 --- /dev/null +++ b/src/common/eeprom.h @@ -0,0 +1,14 @@ +#ifndef MAD_CORE_COMMON_EEPROM_H +#define MAD_CORE_COMMON_EEPROM_H + +typedef struct mem_data_s mem_data_t; + +struct mem_data_s { + byte sentinel; // Data marker bit + word value[2]; // Values to be written +}; + +int MEM_Read(mem_data_t *out); +int MEM_Write(mem_data_t *in); + +#endif // MAD_CORE_COMMON_EEPROM_H From 171e827ab5a9fabd9645484cb6f6266a8cb6602a Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Fri, 20 Sep 2024 15:56:39 +0200 Subject: [PATCH 2/4] Burn EESAVE fuse to preserve EEPROM on chip erase --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f0ebac8..35b82c1 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,7 @@ flash: $(TARGET) $(Q) $(AVD) -l $(LOGFILE) \ -c $(ASP) -p $(ARCH) \ -U lfuse:w:0xff:m \ - -U hfuse:w:0x99:m \ + -U hfuse:w:0x91:m \ -U flash:w:$(TARGET) .PHONY: clean From 29b0ace897eb1c5186c8711c51dccda484f63101 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Fri, 20 Sep 2024 16:56:29 +0200 Subject: [PATCH 3/4] Implement raw EEPROM read and write functionality --- src/common.h | 2 +- src/common/eeprom.c | 17 ------ src/common/memory.c | 89 +++++++++++++++++++++++++++++++ src/common/{eeprom.h => memory.h} | 6 +-- 4 files changed, 93 insertions(+), 21 deletions(-) delete mode 100644 src/common/eeprom.c create mode 100644 src/common/memory.c rename src/common/{eeprom.h => memory.h} (67%) diff --git a/src/common.h b/src/common.h index ae5ad53..d075862 100644 --- a/src/common.h +++ b/src/common.h @@ -4,7 +4,7 @@ #include "common/math.h" #include "common/types.h" #include "common/watchdog.h" -#include "common/eeprom.h" +#include "common/memory.h" #include #include diff --git a/src/common/eeprom.c b/src/common/eeprom.c deleted file mode 100644 index a250306..0000000 --- a/src/common/eeprom.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "common.h" - -// TODO: Implement EEPROM storage with wear leveling - -int MEM_Read(mem_data_t *out) -{ - UNUSED(out); - - return 0; -} - -int MEM_Write(mem_data_t *in) -{ - UNUSED(in); - - return 0; -} diff --git a/src/common/memory.c b/src/common/memory.c new file mode 100644 index 0000000..1c3113f --- /dev/null +++ b/src/common/memory.c @@ -0,0 +1,89 @@ +#include "common.h" + +#include + +static int WriteRaw(word addr, byte data); +static byte ReadRaw(word addr); + +int MEM_Read(mem_data_t *out) +{ + // TODO + UNUSED(out); + UNUSED(ReadRaw); + return 0; +} + +int MEM_Write(mem_data_t *in) +{ + // TODO + UNUSED(in); + UNUSED(WriteRaw); + return 0; +} + +static int WriteRaw(word addr, byte data) +{ + // The EEMWE bit determines whether setting EEWE to + // one causes the EEPROM to be written. When EEMWE + // is set, setting EEWE within four clock cycles + // will write data to the EEPROM at the selected + // address. + + // If EEMWE is zero, setting EEWE will have no + // effect. When EEMWE has been written to one by + // software, hardware clears the bit to zero after + // four clock cycles. + + // Caution: An interrupt between the last two steps + // will make the write cycle fail, since the EEPROM + // Master Write Enable will time-out. + + // If an interrupt routine accessing the EEPROM is + // interrupting another EEPROM Access, the EEAR or + // EEDR reGister will be modified, causing the + // interrupted EEPROM Access to fail. + + // It is recommended to have the Global Interrupt + // Flag cleared during all the steps to avoid these + // problems. + + // Wait until ready + while (EECR & BIT(EEWE)); + + // No interrupts during EEPROM write + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + EEAR = addr; + EEDR = data; + + // Write to address + EECR |= BIT(EEMWE); + EECR |= BIT(EEWE); + } + + return 0; +} + +static byte ReadRaw(word addr) +{ + // Wait until ready + while (EECR & BIT(EEWE)); + + EEAR = addr; + + // The EEPROM Read Enable Signal EERE is the read + // strobe to the EEPROM. When the correct address + // is set up in the EEAR Register, the EERE bit + // must be written to a logic one to trigger the + // EEPROM read. + + // Read from address + EECR |= BIT(EERE); + + // The EEPROM read access takes one instruction, + // and the requested data is available immediately. + // When the EEPROM is read, the CPU is halted for + // four cycles before the next instruction is + // executed. + + return EEDR; +} diff --git a/src/common/eeprom.h b/src/common/memory.h similarity index 67% rename from src/common/eeprom.h rename to src/common/memory.h index 4b6eeb8..a06151b 100644 --- a/src/common/eeprom.h +++ b/src/common/memory.h @@ -1,5 +1,5 @@ -#ifndef MAD_CORE_COMMON_EEPROM_H -#define MAD_CORE_COMMON_EEPROM_H +#ifndef MAD_CORE_COMMON_MEMORY_H +#define MAD_CORE_COMMON_MEMORY_H typedef struct mem_data_s mem_data_t; @@ -11,4 +11,4 @@ struct mem_data_s { int MEM_Read(mem_data_t *out); int MEM_Write(mem_data_t *in); -#endif // MAD_CORE_COMMON_EEPROM_H +#endif // MAD_CORE_COMMON_MEMORY_H From 190ecea8559521eaa373287abd42f13a71a6e0d9 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Fri, 20 Sep 2024 18:03:34 +0200 Subject: [PATCH 4/4] Dump EEPROM to ensure low level memory access is working correctly --- src/common.h | 1 + src/common/common.c | 38 +++++++++++++++++++++++++++++++++----- src/common/memory.c | 18 ++++++++++++++++++ src/common/memory.h | 5 +++-- src/main.c | 4 ++-- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/common.h b/src/common.h index d075862..18412db 100644 --- a/src/common.h +++ b/src/common.h @@ -17,6 +17,7 @@ void Info(const char *fmt, ...); void Error(const char *fmt, ...); +void Print(const char *fmt, ...); #include #define Sleep(ms) _delay_ms(ms) diff --git a/src/common/common.c b/src/common/common.c index 9107a60..cafc163 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -10,16 +10,44 @@ static void Puts(const char *str) } } +static void PrintArgs(const char *fmt, va_list ap) +{ + char msg[256]; + + vsnprintf(msg, sizeof(msg), fmt, ap); + + Puts(msg); +} + +void Print(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + PrintArgs(fmt, ap); + va_end(ap); +} + void Info(const char *fmt, ...) { va_list ap; - char msg[256]; va_start(ap, fmt); - vsnprintf(msg, sizeof(msg), fmt, ap); + Puts("[CORE] "); + PrintArgs(fmt, ap); + Puts("\r\n"); + va_end(ap); +} + +void Error(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + Puts("[CORE] Error: "); + PrintArgs(fmt, ap); + Puts("\r\n"); va_end(ap); - Puts("[CORE] "); - Puts(msg); - Puts("\r\n"); + // XXX: Force reset? } diff --git a/src/common/memory.c b/src/common/memory.c index 1c3113f..0f38a3d 100644 --- a/src/common/memory.c +++ b/src/common/memory.c @@ -21,6 +21,15 @@ int MEM_Write(mem_data_t *in) return 0; } +void MEM_Dump(void) +{ + // byte rom[1024]; + // Info("Dumping EEPROM memory:"); + // for (int i = 0; i < 1024; i++) { + // rom[i] = ReadRaw(i); + // } +} + static int WriteRaw(word addr, byte data) { // The EEMWE bit determines whether setting EEWE to @@ -52,6 +61,15 @@ static int WriteRaw(word addr, byte data) // No interrupts during EEPROM write ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + + // The EEPROM Address Registers – EEARH and + // EEARL – specify the EEPROM address in the + // 1024bytes EEPROM space. The EEPROM data + // bytes are addressed linearly between 0 + // and 1023. The initial value of EEAR is + // undefined. A proper value must be written + // before the EEPROM may be accessed. + EEAR = addr; EEDR = data; diff --git a/src/common/memory.h b/src/common/memory.h index a06151b..6eed367 100644 --- a/src/common/memory.h +++ b/src/common/memory.h @@ -8,7 +8,8 @@ struct mem_data_s { word value[2]; // Values to be written }; -int MEM_Read(mem_data_t *out); -int MEM_Write(mem_data_t *in); +int MEM_Read(mem_data_t *out); +int MEM_Write(mem_data_t *in); +void MEM_Dump(void); #endif // MAD_CORE_COMMON_MEMORY_H diff --git a/src/main.c b/src/main.c index 7e0f655..b753c70 100644 --- a/src/main.c +++ b/src/main.c @@ -75,7 +75,7 @@ static int Init(void) PWM_Init(); MOS_Enable(MOS03); // Lights - MOS_Enable(MOS01); // Peltier + //MOS_Enable(MOS01); // Peltier // MOS_Disable(MOS02); // Heating // Only FAN01 and FAN02 are receiving the correct @@ -88,7 +88,7 @@ static int Init(void) // complicated so it might be worth it to switch to // something like an ATmega328PB. - PWM_SetValue(FAN01, 20); // Fan Peltier Hot side + PWM_SetValue(FAN01, 50); // Fan Peltier Hot side PWM_SetValue(FAN02, 50); // Fan Peltier Cold Side // PWM_SetValue(FAN03, 20); // Fan Heating