Merge pull request #2 from madcow/eeprom
Implement raw EEPROM read and write functionality
This commit is contained in:
2
Makefile
2
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
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "common/math.h"
|
||||
#include "common/types.h"
|
||||
#include "common/watchdog.h"
|
||||
#include "common/memory.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
@@ -16,6 +17,7 @@
|
||||
|
||||
void Info(const char *fmt, ...);
|
||||
void Error(const char *fmt, ...);
|
||||
void Print(const char *fmt, ...);
|
||||
|
||||
#include <util/delay.h>
|
||||
#define Sleep(ms) _delay_ms(ms)
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
|
||||
107
src/common/memory.c
Normal file
107
src/common/memory.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "common.h"
|
||||
|
||||
#include <util/atomic.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
// 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) {
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
15
src/common/memory.h
Normal file
15
src/common/memory.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef MAD_CORE_COMMON_MEMORY_H
|
||||
#define MAD_CORE_COMMON_MEMORY_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);
|
||||
void MEM_Dump(void);
|
||||
|
||||
#endif // MAD_CORE_COMMON_MEMORY_H
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user