4 IO module that simulates the AVR EEProm
6 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
8 This file is part of simavr.
10 simavr is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 simavr is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with simavr. If not, see <http://www.gnu.org/licenses/>.
27 #include "avr_eeprom.h"
29 static void avr_eeprom_run(avr_t * avr, avr_io_t * port)
31 avr_eeprom_t * p = (avr_eeprom_t *)port;
32 //printf("%s\n", __FUNCTION__);
33 if (p->eempe_clear_timer) {
34 p->eempe_clear_timer--;
35 if (p->eempe_clear_timer == 0) {
36 avr_regbit_clear(avr, p->eempe);
39 if (p->ready_raise_timer) {
40 p->ready_raise_timer--;
41 if (p->ready_raise_timer == 0) {
42 avr_raise_interupt(avr, &p->ready);
47 static void avr_eeprom_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
49 avr_eeprom_t * p = (avr_eeprom_t *)param;
50 uint8_t eempe = avr_regbit_get(avr, p->eempe);
52 avr_core_watch_write(avr, addr, v);
54 if (!eempe && avr_regbit_get(avr, p->eempe)) {
55 p->eempe_clear_timer = 4; // auto clear, later
58 if (eempe && avr_regbit_get(avr, p->eepe)) { // write operation
59 uint16_t addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
60 printf("eeprom write %04x <- %02x\n", addr, avr->data[p->r_eedr]);
61 p->eeprom[addr] = avr->data[p->r_eedr];
62 // automaticaly clears that bit (?)
63 p->eempe_clear_timer = 0;
64 avr_regbit_clear(avr, p->eempe);
66 p->ready_raise_timer = 1024; // make a avr_milliseconds_to_cycle(...) 3.4ms here
68 if (avr_regbit_get(avr, p->eere)) { // read operation
69 uint16_t addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
70 avr->data[p->r_eedr] = p->eeprom[addr];
71 printf("eeprom read %04x : %02x\n", addr, p->eeprom[addr]);
75 avr_regbit_clear(avr, p->eepe);
76 avr_regbit_clear(avr, p->eere);
79 static int avr_eeprom_ioctl(avr_t * avr, avr_io_t * port, uint32_t ctl, void * io_param)
81 avr_eeprom_t * p = (avr_eeprom_t *)port;
85 case AVR_IOCTL_EEPROM_SET: {
86 avr_eeprom_desc_t * desc = (avr_eeprom_desc_t*)io_param;
87 if (!desc || !desc->size || !desc->ee || (desc->offset + desc->size) >= p->size) {
88 printf("%s: AVR_IOCTL_EEPROM_SET Invalid argument\n",
92 memcpy(p->eeprom + desc->offset, desc->ee, desc->size);
93 printf("%s: AVR_IOCTL_EEPROM_SET Loaded %d at offset %d\n",
94 __FUNCTION__, desc->size, desc->offset);
101 static avr_io_t _io = {
103 .run = avr_eeprom_run,
104 .ioctl = avr_eeprom_ioctl,
107 void avr_eeprom_init(avr_t * avr, avr_eeprom_t * p)
110 printf("%s init (%d bytes) EEL/H:%02x/%02x EED=%02x EEC=%02x\n",
111 __FUNCTION__, p->size, p->r_eearl, p->r_eearh, p->r_eedr, p->r_eecr);
113 p->eeprom = malloc(p->size);
114 memset(p->eeprom, 0xff, p->size);
116 avr_register_io(avr, &p->io);
117 avr_register_vector(avr, &p->ready);
119 avr_register_io_write(avr, p->r_eecr, avr_eeprom_write, p);