34 #include <sys/types.h> 39 #include "avrmalloc.h" 61 static uint8_t eeprom_reg_read (VDevice *dev,
int addr);
62 static void eeprom_reg_write (VDevice *dev,
int addr, uint8_t val);
63 static void eeprom_reg_reset (VDevice *dev);
64 static void eeprom_wr_eecr (EEProm *ee, uint8_t val);
66 static int eeprom_wr_op_cb (uint64_t time, AvrClass *data);
67 static int eeprom_mwe_clr_cb (uint64_t time, AvrClass *data);
70 static VDevice *global_eeprom;
79 eeprom_create (
int addr,
char *name,
int rel_addr,
void *data)
81 if (rel_addr == 0 && addr != EECR_ADDR)
82 avr_error(
"Attempt to create EEPROM control register at unknown address: 0x%02x != 0x%02x",
89 eeprom_new (
int size, uint8_t eecr_mask)
93 if (global_eeprom != NULL)
94 avr_error(
"Global EEPROM does already exist");
97 eeprom_construct (eeprom, size, eecr_mask);
100 global_eeprom = (VDevice *)eeprom;
106 eeprom_construct (EEProm *eeprom,
int size, uint8_t eecr_mask)
113 eeprom->stor = storage_new (0 , size);
116 for (i = 0; i < size; i++)
117 storage_writeb (eeprom->stor, i, 0xff);
119 eeprom->eecr_mask = eecr_mask;
121 eeprom_reg_reset ((VDevice *)eeprom);
123 vdev_construct ((VDevice *)eeprom, eeprom_reg_read, eeprom_reg_write,
128 eeprom_destroy (
void *eeprom)
130 EEProm *_eeprom = (EEProm *)eeprom;
141 eeprom_get_size (EEProm *eeprom)
143 return storage_get_size (eeprom->stor);
147 eeprom_reg_read (VDevice *dev,
int addr)
149 EEProm *ee = (EEProm *)dev;
167 eeprom_reg_write (VDevice *dev,
int addr, uint8_t val)
169 EEProm *ee = (EEProm *)dev;
171 if (ee->eecr & mask_EEWE)
180 avr_error (
"Attempt to write to EEPROM I/O reg during write " 187 eeprom_wr_eecr (ee, val);
203 eeprom_reg_reset (VDevice *dev)
205 EEProm *ee = (EEProm *)dev;
210 ee->mwe_clr_cb = NULL;
213 ee->eecr = ee->eedr = ee->eearl = ee->eearh = 0;
217 eeprom_wr_eecr (EEProm *ee, uint8_t val)
219 int addr = (ee->eearh << 8) | ee->eearl;
223 switch (val & ee->eecr_mask)
230 ee->eedr = storage_readb (ee->stor, addr);
234 if (((ee->eecr_mask & mask_EEMWE) == 0)
236 || (ee->eecr & ee->eecr_mask & mask_EEMWE))
239 ee->eecr |= mask_EEWE;
240 ee->wr_op_clk = EEPROM_WR_OP_CLKS;
243 if (ee->wr_op_cb == NULL)
245 cb = callback_new (eeprom_wr_op_cb, (AvrClass *)ee);
254 ee->eecr |= mask_EEMWE;
255 ee->mwe_clk = EEPROM_MWE_CLKS;
257 if (ee->mwe_clr_cb == NULL)
259 cb = callback_new (eeprom_mwe_clr_cb, (AvrClass *)ee);
266 case (mask_EEMWE | mask_EEWE):
268 eeprom_wr_eecr (ee, mask_EEWE);
272 avr_error (
"Unknown eeprom control register write operation: " 286 eeprom_wr_op_cb (uint64_t time, AvrClass *data)
288 EEProm *ee = (EEProm *)data;
298 if (ee->wr_op_clk > 0)
302 return CB_RET_RETAIN;
306 addr = (ee->eearh << 8) | ee->eearl;
309 storage_writeb (ee->stor, addr, ee->eedr);
312 ee->eecr &= ~(mask_EEWE);
315 return CB_RET_REMOVE;
323 eeprom_mwe_clr_cb (uint64_t time, AvrClass *data)
325 EEProm *ee = (EEProm *)data;
330 return CB_RET_RETAIN;
333 ee->eecr &= ~(mask_EEMWE);
334 ee->mwe_clr_cb = NULL;
336 return CB_RET_REMOVE;
340 eeprom_load_from_bin_file (EEProm *eeprom,
char *file)
346 fd = open (file, O_RDONLY);
348 avr_error (
"Couldn't open binary eeprom image file: %s: %s", file,
351 while ((res = read (fd, &datum,
sizeof (datum))) != 0)
354 avr_error (
"Error reading binary eeprom image file: %s: %s", file,
357 storage_writeb (eeprom->stor, addr, datum);
370 eeprom_load_from_file (EEProm *eeprom,
char *file,
int format)
375 return eeprom_load_from_bin_file (eeprom, file);
386 eeprom_dump_core (EEProm *eeprom, FILE * f_core)
394 int size = storage_get_size (eeprom->stor);
396 fprintf (f_core,
"EEPROM Memory Dump:\n");
398 line[0] = last_line[0] =
'\0';
400 for (i = 0; i < size; i++)
402 if (((i % ndat) == 0) && strlen (line))
404 if (strncmp (line, last_line, 80) == 0)
411 fprintf (f_core,
" -- last line repeats --\n");
412 fprintf (f_core,
"%04x : %s\n", i - ndat, line);
415 strncpy (last_line, line, 80);
418 snprintf (buf, 80,
"%02x ", storage_readb (eeprom->stor, i));
419 strncat (line, buf, 80 - strlen(line) - 1);
423 fprintf (f_core,
" -- last line repeats --\n");
424 fprintf (f_core,
"%04x : %s\n", i - ndat, line);
426 fprintf (f_core,
"\n");
void avr_core_async_cb_add(AvrCore *core, CallBack *cb)
Add a new asynchronous callback to list.
void vdev_def_AddAddr(VDevice *dev, int addr, char *name, int related_addr, void *data)
Default AddAddr method.
void vdev_destroy(void *dev)
Destructor for a VDevice.
AvrClass * vdev_get_core(VDevice *dev)
Get the core field.
#define avr_warning(fmt, args...)
Print a warning message to stderr.
void class_unref(AvrClass *klass)
Decrements the reference count for the klass object.
void vdev_construct(VDevice *dev, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_AddAddr add_addr)
Constructor for a VDevice.
#define avr_error(fmt, args...)
Print an error message to stderr and terminate program.
void avr_core_clk_cb_add(AvrCore *core, CallBack *cb)
Add a new clock callback to list.
#define avr_new(type, count)
Macro for allocating memory.
void class_overload_destroy(AvrClass *klass, AvrClassFP_Destroy destroy)
Overload the default destroy method.
void display_eeprom(int addr, int len, uint8_t *vals)
Update a block of eeprom addresses in the display.