? check.out
? patch2.diff
? patch3.diff
? patch4.diff
? patch5.diff
? simulavr/Makefile
? simulavr/Makefile.in
? simulavr/aclocal.m4
? simulavr/config.cache
? simulavr/config.log
? simulavr/config.status
? simulavr/configure
? simulavr/core_avr_dump.core
? simulavr/simulavr-disp.1
? simulavr/simulavr.1
? simulavr/simulavr.spec
? simulavr/config/install-sh
? simulavr/config/mdate-sh
? simulavr/config/missing
? simulavr/config/mkinstalldirs
? simulavr/doc/Makefile
? simulavr/doc/Makefile.in
? simulavr/doc/doxygen.config
? simulavr/doc/html
? simulavr/doc/internals
? simulavr/doc/internals_html
? simulavr/doc/simulavr.info
? simulavr/doc/stamp-vti
? simulavr/doc/version.texi
? simulavr/regress/Makefile
? simulavr/regress/Makefile.in
? simulavr/regress/regress.err
? simulavr/regress/regress.out
? simulavr/regress/regress.py
? simulavr/regress/sim.err
? simulavr/regress/sim.out
? simulavr/regress/modules/Makefile
? simulavr/regress/test_opcodes/Makefile
? simulavr/src/.avrclass.c.swp
? simulavr/src/.deps
? simulavr/src/Makefile
? simulavr/src/Makefile.in
? simulavr/src/aaa_regtodo
? simulavr/src/bitpos.c
? simulavr/src/bitpos.h
? simulavr/src/config-h.in
? simulavr/src/config.h
? simulavr/src/dtest
? simulavr/src/simulavr
? simulavr/src/stamp-h
? simulavr/src/stamp-h.in
? simulavr/src/timertest.dis
? simulavr/src/disp/Makefile
? simulavr/src/disp/Makefile.in
? simulavr/src/disp/disp
? simulavr/src/disp-vcd/.deps
? simulavr/src/disp-vcd/Makefile
? simulavr/src/disp-vcd/Makefile.in
? simulavr/src/disp-vcd/config_parser.c
? simulavr/src/disp-vcd/config_parser.h
? simulavr/src/disp-vcd/config_scanner.c
? simulavr/src/disp-vcd/simulavr-vcd
? simulavr/src/disp-vcd/test.vcd
? simulavr/test_asm/Makefile
? simulavr/test_asm/Makefile.in
? simulavr/test_asm/test_8515/Makefile
? simulavr/test_asm/test_8515/Makefile.in
? simulavr/test_asm/test_8515/test_blink
? simulavr/test_asm/test_8515/test_cntr
? simulavr/test_asm/test_8515/test_eeprom
? simulavr/test_asm/test_8515/test_port
? simulavr/test_asm/test_8515/test_stack
? simulavr/test_asm/test_8515/test_toie0
? simulavr/test_asm/test_8515/test_toie0_2
? simulavr/test_asm/test_8515/test_wdr
? simulavr/test_asm/test_8515/test_wdr2
? simulavr/test_c/.deps
? simulavr/test_c/Makefile
? simulavr/test_c/Makefile.in
Index: simulavr/ChangeLog
===================================================================
RCS file: /cvsroot/simulavr/simulavr/ChangeLog,v
retrieving revision 1.140
diff -u -r1.140 ChangeLog
--- simulavr/ChangeLog 6 Apr 2003 19:26:08 -0000 1.140
+++ simulavr/ChangeLog 7 Apr 2003 17:42:33 -0000
@@ -1,9 +1,28 @@
+2003-04-07 Hermann Kraus
+ * src/*.c: Added new include for "bitpos.h"
+ * src/bitpos.h: New file
+ * src/bitpos.c: New file
+ * src/timers.h:
+ * src/timers.c:
+ * src/eeprom.h:
+ * src/eeprom.c:
+ * src/register.h:
+ * src/register.c:
+ Support for variable bit positions (bitpos.c)
+ Some FIXMEs
+ * src/devsupp.c:
+ * src/intvects.h:
+ Moved the interrupt vector table names to intvects.h
+ * src/timers.h:
+ * src/timers.c:
+ Support for all 8 bit Timers/Counters
+
2003-04-06 Hermann Kraus
* src/devsupp.c:
* src/intvects.c:
Added support for the ATMega16 device
-
+
2003-04-04 Theodore A. Roth
* src/avrcore.c:
Index: simulavr/src/Makefile.am
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/Makefile.am,v
retrieving revision 1.18
diff -u -r1.18 Makefile.am
--- simulavr/src/Makefile.am 16 Nov 2002 23:33:26 -0000 1.18
+++ simulavr/src/Makefile.am 7 Apr 2003 17:42:35 -0000
@@ -44,6 +44,8 @@
avrerror.h \
avrmalloc.c \
avrmalloc.h \
+ bitpos.c \
+ bitpos.h \
callback.c \
callback.h \
decoder.c \
Index: simulavr/src/avrcore.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/avrcore.c,v
retrieving revision 1.62
diff -u -r1.62 avrcore.c
--- simulavr/src/avrcore.c 5 Apr 2003 06:44:34 -0000 1.62
+++ simulavr/src/avrcore.c 7 Apr 2003 17:42:39 -0000
@@ -44,6 +44,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/decoder.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/decoder.c,v
retrieving revision 1.30
diff -u -r1.30 decoder.c
--- simulavr/src/decoder.c 5 Apr 2003 06:44:34 -0000 1.30
+++ simulavr/src/decoder.c 7 Apr 2003 17:42:54 -0000
@@ -57,6 +57,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/device.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/device.c,v
retrieving revision 1.9
diff -u -r1.9 device.c
--- simulavr/src/device.c 17 Apr 2002 20:47:58 -0000 1.9
+++ simulavr/src/device.c 7 Apr 2003 17:42:55 -0000
@@ -39,6 +39,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/devsupp.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/devsupp.c,v
retrieving revision 1.9
diff -u -r1.9 devsupp.c
--- simulavr/src/devsupp.c 6 Apr 2003 19:26:08 -0000 1.9
+++ simulavr/src/devsupp.c 7 Apr 2003 17:42:57 -0000
@@ -49,6 +49,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
@@ -59,24 +60,7 @@
#include "ports.h"
#include "avrcore.h"
-
-#ifndef DOXYGEN /* don't expose to doxygen */
-
-/*
- * Used to select which vector table the device uses.
- * The value is an index into the global_vtable_list[] array
- * defined in intvects.c.
- */
-enum _vector_table_select {
- VTAB_AT90S1200 = 0,
- VTAB_AT90S2313,
- VTAB_AT90S4414,
- VTAB_ATMEGA16,
- VTAB_ATMEGA103,
- VTAB_ATMEGA128,
-};
-
-#endif
+#include "intvects.h"
/** \brief Structure for defining a supported device */
@@ -103,12 +87,11 @@
int eeprom; /* bytes of eeprom memory */
} size;
+ int bitpos_table_nr;
+
struct { /* io register function masks */
- byte eecr;
byte mcucr;
byte acsr;
- byte wdtcr;
- byte timsk;
} mask;
};
@@ -132,12 +115,10 @@
/* size.sram */ 0,
/* size.eeprom */ 64
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE),
/* mask.mcucr */ (mask_SE | mask_SM | mask_ISC01 | mask_ISC00),
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE0)
}
};
@@ -157,14 +138,12 @@
/* size.sram */ 128,
/* size.eeprom */ 128
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
- /* mask.mcucr */ (mask_SE | mask_SM |
+ /* mask.mcucr */ (mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
- /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
+ /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_TICIE1 | mask_TOIE0)
}
};
@@ -184,14 +163,12 @@
/* size.sram */ 256,
/* size.eeprom */ 256
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
- /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
+ /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
- /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
+ /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 | mask_TOIE0)
}
};
@@ -211,14 +188,12 @@
/* size.sram */ 512,
/* size.eeprom */ 512
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
- /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
+ /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
- /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
+ /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 | mask_TOIE0)
}
};
@@ -232,20 +207,18 @@
/* ports */ "a8b8c8d8",
{
- /* size.pc */ 2, /* 13 bits */
+ /* size.pc */ 2,
/* size.stack */ 0,
/* size.flash */ 16*1024,
/* size.sram */ 1*1024,
/* size.eeprom */ 512
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
/* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 | mask_TOIE0)
}
};
@@ -259,20 +232,18 @@
/* ports */ "a8b8c8d8",
{
- /* size.pc */ 2,
+ /* size.pc */ 3,
/* size.stack */ 0,
/* size.flash */ 128*1024,
/* size.sram */ 4*1024,
/* size.eeprom */ 4*1024
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
- /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
+ /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
- /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
+ /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 | mask_TOIE0)
}
};
@@ -292,14 +263,12 @@
/* size.sram */ 4*1024,
/* size.eeprom */ 4*1024
},
+ /* bitpos_table_nr */ BPT_ATMEGA16,
{
- /* mask.eecr */ (mask_EERE | mask_EEWE | mask_EEMWE),
- /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
+ /* mask.mcucr */ (mask_SRE | mask_SRW | mask_SE | mask_SM |
mask_ISC11 | mask_ISC10 | mask_ISC01 | mask_ISC00),
- /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
+ /* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
- /* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 | mask_TOIE0)
}
};
@@ -366,6 +335,7 @@
DevSuppDefn *dev = dev_supp_lookup_device( dev_name );
VDevice *vdev;
char *pp;
+ BitPos **bitpos_table;
if (dev)
{
@@ -378,8 +348,10 @@
dev->size.stack,
dev->irq_vect_idx );
+ bitpos_table=global_bitpos_device_tables[dev->bitpos_table_nr];
+
/* all devices have a timer/counter 0 */
- avr_core_attach_vdev( core, (VDevice *)timer0_new() );
+ avr_core_attach_vdev( core, (VDevice *)timer8_new( global_timer8_definitions[TD_TIMER0], bitpos_table[BPT_TCCR0]) );
/* Attach device specific vdevs */
@@ -391,7 +363,7 @@
if (dev->size.eeprom > 0)
{
- vdev = (VDevice *)eeprom_new( dev->size.eeprom, dev->mask.eecr );
+ vdev = (VDevice *)eeprom_new( dev->size.eeprom, bitpos_table[BPT_EECR] );
avr_core_attach_vdev( core, vdev );
}
@@ -407,15 +379,21 @@
avr_core_attach_vdev( core, vdev );
}
- if (dev->mask.wdtcr)
+ if (bitpos_table[BPT_WDTCR])
+ {
+ vdev = (VDevice *)wdtcr_new( bitpos_table[BPT_WDTCR] );
+ avr_core_attach_vdev( core, vdev );
+ }
+
+ if (bitpos_table[BPT_TIMSK])
{
- vdev = (VDevice *)wdtcr_new( dev->mask.wdtcr );
+ vdev = (VDevice *)timer_intr_new(bitpos_table[BPT_TIMSK] );
avr_core_attach_vdev( core, vdev );
}
- if (dev->mask.timsk)
+ if (bitpos_table[BPT_TCCR2])
{
- vdev = (VDevice *)timer_intr_new( dev->mask.timsk );
+ vdev = (VDevice *)timer8_new( global_timer8_definitions[TD_TIMER2], bitpos_table[BPT_TCCR2] );
avr_core_attach_vdev( core, vdev );
}
Index: simulavr/src/dtest.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/dtest.c,v
retrieving revision 1.5
diff -u -r1.5 dtest.c
--- simulavr/src/dtest.c 5 Sep 2002 06:41:08 -0000 1.5
+++ simulavr/src/dtest.c 7 Apr 2003 17:42:57 -0000
@@ -43,6 +43,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/eeprom.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/eeprom.c,v
retrieving revision 1.17
diff -u -r1.17 eeprom.c
--- simulavr/src/eeprom.c 1 Oct 2002 00:09:41 -0000 1.17
+++ simulavr/src/eeprom.c 7 Apr 2003 17:42:59 -0000
@@ -45,6 +45,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
@@ -68,18 +69,18 @@
static int eeprom_mwe_clr_cb ( qword time, AvrClass *data );
-EEProm *eeprom_new( int size, byte eecr_mask )
+EEProm *eeprom_new( int size, BitPos *bp_eecr )
{
EEProm *eeprom;
eeprom = avr_new( EEProm, 1 );
- eeprom_construct( eeprom, size, eecr_mask );
+ eeprom_construct( eeprom, size, bp_eecr );
class_overload_destroy( (AvrClass *)eeprom, eeprom_destroy );
return eeprom;
}
-void eeprom_construct( EEProm *eeprom, int size, byte eecr_mask )
+void eeprom_construct( EEProm *eeprom, int size, BitPos *bp_eecr )
{
char *name = "EEProm";
int i;
@@ -93,7 +94,7 @@
for ( i=0; istor, i, 0xff );
- eeprom->eecr_mask = eecr_mask;
+ eeprom->bp_eecr = bp_eecr;
eeprom_reg_reset( (VDevice *)eeprom );
@@ -136,7 +137,7 @@
{
EEProm *ee = (EEProm *)dev;
- if (ee->eecr & mask_EEWE)
+ if (ee->eecr & _BV(ee->bp_eecr[BP_EEWE].bit))
{
/*
* From the 8515 data sheet: The user should poll the EEWE bit before
@@ -166,6 +167,7 @@
ee->mwe_clr_cb = NULL;
ee->mwe_clk = 0;
+ /* FIXME: In the ATMega16 datasheet the default value of EEARx is undefined! */
ee->eecr = ee->eedr = ee->eearl = ee->eearh = 0;
}
@@ -187,51 +189,56 @@
CallBack *cb;
- switch (val & ee->eecr_mask) {
- case mask_EERE:
- /*
- * we never need to set EERE bit one,
- * just more data from eeprom array into eedr.
- */
- ee->eedr = storage_readb( ee->stor, addr );
- break;
-
- case mask_EEWE:
- if ( ((ee->eecr_mask & mask_EEMWE) == 0) /* device has no MWE function */
- || (ee->eecr & ee->eecr_mask & mask_EEMWE) ) /* or MWE bit is set */
- {
- ee->eecr |= mask_EEWE;
- ee->wr_op_clk = EEPROM_WR_OP_CLKS;
-
- /* start write operation */
- if (ee->wr_op_cb == NULL)
- {
- cb = callback_new( eeprom_wr_op_cb, (AvrClass *)ee );
- ee->wr_op_cb = cb;
- avr_core_async_cb_add( (AvrCore *)vdev_get_core((VDevice *)ee), cb );
- }
- }
- break;
-
- case mask_EEMWE:
- ee->eecr |= mask_EEMWE;
- ee->mwe_clk = EEPROM_MWE_CLKS;
+ /* READING */
+ if (val == _BV(ee->bp_eecr[BP_EERE].bit))
+ {
+ /*
+ * we never need to set EERE bit one,
+ * just more data from eeprom array into eedr.
+ */
+ ee->eedr = storage_readb( ee->stor, addr );
- if (ee->mwe_clr_cb == NULL)
- {
- cb = callback_new( eeprom_mwe_clr_cb, (AvrClass *)ee );
- ee->mwe_clr_cb = cb;
- avr_core_clk_cb_add( (AvrCore *)vdev_get_core((VDevice *)ee), cb );
- }
- break;
-
- case (mask_EEMWE | mask_EEWE):
- /* just call this function again, but without EEMWE set in val */
- eeprom_wr_eecr( ee, mask_EEWE );
- break;
+ }
+ /* TRYING TO WRITE */
+ else if (val & _BV(ee->bp_eecr[BP_EEWE].bit))
+ {
+ if ((ee->bp_eecr[BP_EEMWE].bit==0xff) /* device has no MWE function */
+ || (ee->eecr & _BV(ee->bp_eecr[BP_EEMWE].bit)) ) /* or MWE bit is set */
+ {
+ ee->eecr |= _BV(ee->bp_eecr[BP_EEWE].bit); /* Flaging that a write is in progress */
+ ee->wr_op_clk = EEPROM_WR_OP_CLKS;
+
+ /* start write operation */
+ if (ee->wr_op_cb == NULL)
+ {
+ cb = callback_new( eeprom_wr_op_cb, (AvrClass *)ee );
+ ee->wr_op_cb = cb;
+ avr_core_async_cb_add( (AvrCore *)vdev_get_core((VDevice *)ee), cb );
+ }
+ } else
+ {
+ avr_warning("EEPROM write failed because EEMWE bit was not set!");
+ }
+ }
+ /* SETTING THE EEMWE BIT */
+ else if (val & _BV(ee->bp_eecr[BP_EEMWE].bit))
+ {
+ ee->eecr |= _BV(ee->bp_eecr[BP_EEMWE].bit);
+ ee->mwe_clk = EEPROM_MWE_CLKS;
- default:
- avr_error( "Unknown eeprom control register write operation: 0x%02x", val );
+ if (ee->mwe_clr_cb == NULL)
+ {
+ cb = callback_new( eeprom_mwe_clr_cb, (AvrClass *)ee );
+ ee->mwe_clr_cb = cb;
+ avr_core_clk_cb_add( (AvrCore *)vdev_get_core((VDevice *)ee), cb );
+ }
+ } else
+ {
+ /*
+ * Note: [hnkraus] no user program should be able to crash simulavr!
+ * So I changed avr_error to avr_warning
+ */
+ avr_warning( "Unknown eeprom control register write operation: 0x%02x", val );
}
}
@@ -240,8 +247,11 @@
* depending on Vcc voltage. Since the get_program_time() function only has
* 10 ms resolution, we'll just simulate a timer with counting down from
* EEPROM_WR_OP_CLKS to zero. 2500 clocks would be 2.5 ms if simulator is
- * running at 1 MHz. I really don't think that this variation should be
+ * running at 1 MHz. I really don't think that this variation should be
* critical in most apps, but I'd wouldn't mind being proven wrong.
+ *
+ * FIXME: The number of cycles should depend on the clockspeed actually used.
+ * Add a new comandline option to specify it!
*/
static int eeprom_wr_op_cb( qword time, AvrClass *data )
{
@@ -269,7 +279,7 @@
storage_writeb( ee->stor, addr, ee->eedr );
/* Now it's ok to start another write operation */
- ee->eecr &= ~(mask_EEWE); /* clear the write enable bit */
+ ee->eecr &= ~_BV(ee->bp_eecr[BP_EEWE].bit); /* clear the write enable bit */
ee->wr_op_cb = NULL; /* remove callback */
return CB_RET_REMOVE;
@@ -289,7 +299,7 @@
return CB_RET_RETAIN;
}
- ee->eecr &= ~(mask_EEMWE); /* clear the EEMWE bit */
+ ee->eecr &= ~_BV(ee->bp_eecr[BP_EEMWE].bit); /* clear the EEMWE bit */
ee->mwe_clr_cb = NULL; /* remove callback */
return CB_RET_REMOVE;
@@ -334,7 +344,7 @@
default:
avr_warning( "Unsupported file format\n" );
}
-
+
return -1;
}
@@ -360,7 +370,7 @@
{
dup++;
} else {
- if (dup > 0)
+ if (dup > 0)
fprintf( f_core, " -- last line repeats --\n" );
fprintf( f_core, "%04x : %s\n", i-ndat, line );
dup = 0;
Index: simulavr/src/eeprom.h
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/eeprom.h,v
retrieving revision 1.3
diff -u -r1.3 eeprom.h
--- simulavr/src/eeprom.h 1 Oct 2002 00:09:41 -0000 1.3
+++ simulavr/src/eeprom.h 7 Apr 2003 17:43:00 -0000
@@ -32,18 +32,6 @@
*
\****************************************************************************/
-typedef enum {
- bit_EERE = 0, /* eeprom read enable strobe */
- bit_EEWE = 1, /* eeprom write enable strobe */
- bit_EEMWE = 2, /* eeprom master write enable strobe */
-} EECR_BITS;
-
-typedef enum {
- mask_EERE = 1 << bit_EERE,
- mask_EEWE = 1 << bit_EEWE,
- mask_EEMWE = 1 << bit_EEMWE,
-} EECR_MASKS;
-
enum _eeprom_constants {
EEPROM_BASE = 0x3c, /* base eeprom mem addr */
EEPROM_SIZE = 4, /* EECR, EEDR, EEARL, EEARH */
@@ -63,7 +51,7 @@
VDevice parent;
Storage *stor; /* storage for eeprom memory */
byte eecr; /* eeprom control register */
- byte eecr_mask; /* mask of bits available for device */
+ BitPos *bp_eecr; /* mask of bits available for device */
byte eedr; /* eeprom data register */
byte eearl; /* eeprom address register low byte */
byte eearh; /* eeprom address register high byte */
@@ -75,12 +63,12 @@
int mwe_clk; /* clock counter for hw clearing of MWE bit */
};
-extern EEProm *eeprom_new ( int size, byte eecr_mask );
-extern void eeprom_construct ( EEProm *eeprom, int size, byte eecr_mask );
+extern EEProm *eeprom_new ( int size, BitPos *bp_eecr );
+extern void eeprom_construct ( EEProm *eeprom, int size, BitPos *bp_eecr );
extern void eeprom_destroy ( void *eeprom );
extern int eeprom_get_size ( EEProm *eeprom );
-
+
extern int eeprom_load_from_file( EEProm *eeprom, char *file, int format );
extern void eeprom_dump_core ( EEProm *eeprom, FILE *f_core );
Index: simulavr/src/intvects.h
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/intvects.h,v
retrieving revision 1.3
diff -u -r1.3 intvects.h
--- simulavr/src/intvects.h 16 Jul 2002 06:34:58 -0000 1.3
+++ simulavr/src/intvects.h 7 Apr 2003 17:43:01 -0000
@@ -26,6 +26,25 @@
#ifndef SIM_INTVECTS_H
#define SIM_INTVECTS_H
+#ifndef DOXYGEN /* don't expose to doxygen */
+
+/*
+ * Used to select which vector table the device uses.
+ * The value is an index into the global_vtable_list[] array
+ * defined in intvects.c.
+ * [hnkraus]: Moved this here to keep everything about interrupts together
+ */
+enum _vector_table_select {
+ VTAB_AT90S1200 = 0,
+ VTAB_AT90S2313,
+ VTAB_AT90S4414,
+ VTAB_ATMEGA16,
+ VTAB_ATMEGA103,
+ VTAB_ATMEGA128,
+};
+
+#endif
+
enum _sleep_modes {
SLEEP_MODE_IDLE,
SLEEP_MODE_ADC_REDUX,
Index: simulavr/src/main.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/main.c,v
retrieving revision 1.29
diff -u -r1.29 main.c
--- simulavr/src/main.c 4 Mar 2003 21:54:32 -0000 1.29
+++ simulavr/src/main.c 7 Apr 2003 17:43:03 -0000
@@ -40,6 +40,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/memory.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/memory.c,v
retrieving revision 1.15
diff -u -r1.15 memory.c
--- simulavr/src/memory.c 17 Apr 2002 20:47:58 -0000 1.15
+++ simulavr/src/memory.c 7 Apr 2003 17:43:08 -0000
@@ -47,6 +47,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/ports.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/ports.c,v
retrieving revision 1.12
diff -u -r1.12 ports.c
--- simulavr/src/ports.c 16 Sep 2002 05:48:15 -0000 1.12
+++ simulavr/src/ports.c 7 Apr 2003 17:43:11 -0000
@@ -45,6 +45,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/register.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/register.c,v
retrieving revision 1.29
diff -u -r1.29 register.c
--- simulavr/src/register.c 16 Oct 2002 03:37:54 -0000 1.29
+++ simulavr/src/register.c 7 Apr 2003 17:43:13 -0000
@@ -38,6 +38,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
@@ -391,28 +392,28 @@
static int wdtcr_timer_cb ( qword time, AvrClass *data );
static int wdtcr_toe_clr_cb ( qword time, AvrClass *data );
-WDTCR *wdtcr_new( byte func_mask )
+WDTCR *wdtcr_new( BitPos *bp_wdtcr )
{
WDTCR *wdtcr;
wdtcr = avr_new( WDTCR, 1 );
- wdtcr_construct( wdtcr, func_mask );
+ wdtcr_construct( wdtcr, bp_wdtcr );
class_overload_destroy( (AvrClass *)wdtcr, wdtcr_destroy );
return wdtcr;
}
-void wdtcr_construct( WDTCR *wdtcr, byte func_mask )
+void wdtcr_construct( WDTCR *wdtcr, BitPos *bp_wdtcr )
{
char *name = "WDTCR";
if (wdtcr == NULL)
avr_error( "passed null ptr" );
- vdev_construct( (VDevice *)wdtcr, name, WDTCR_BASE, WDTCR_SIZE,
+ vdev_construct( (VDevice *)wdtcr, name, WDTCR_BASE, WDTCR_SIZE,
wdtcr_read, wdtcr_write, wdtcr_reset, wdtcr_reg_name );
- wdtcr->func_mask = func_mask;
+ wdtcr->bp_wdtcr = bp_wdtcr;
wdtcr_reset( (VDevice *)wdtcr );
}
@@ -443,14 +444,15 @@
static void wdtcr_set_bit( WDTCR *reg, int bit, int val )
{
- reg->wdtcr = set_bit_in_byte(reg->wdtcr, bit, val) & reg->func_mask;
+ reg->wdtcr = set_bit_in_byte(reg->wdtcr, bit, val) & bitpos_get_register_mask(reg->bp_wdtcr);
}
static byte wdtcr_read( VDevice *dev, int addr )
{
WDTCR *reg = (WDTCR *)dev;
-
- return (reg->wdtcr & reg->func_mask);
+ /* Note: We don't have to AND with the function mask here as it
+ is done in the write functions */
+ return reg->wdtcr;
}
/*
@@ -461,19 +463,19 @@
static void wdtcr_write( VDevice *dev, int addr, byte val )
{
WDTCR *reg = (WDTCR *)dev;
- byte wd_enabled = (reg->wdtcr & mask_WDE);
+ byte wd_enabled = (reg->wdtcr & _BV(reg->bp_wdtcr[BP_WDE].bit));
CallBack *cb;
- if (reg->func_mask & mask_WDTOE)
+ if (reg->bp_wdtcr[BP_WDTOE].bit<0xFF)
{ /* Device has WDTOE functionality */
- if ( (reg->wdtcr & mask_WDE) && !(reg->wdtcr & mask_WDTOE) )
+ if ( (reg->wdtcr & _BV(reg->bp_wdtcr[BP_WDE].bit)) && !(reg->wdtcr & _BV(reg->bp_wdtcr[BP_WDTOE].bit)) )
{ /* WDE can _NOT_ be cleared if WDTOE is zero */
- val |= mask_WDE;
+ val |= _BV(reg->bp_wdtcr[BP_WDE].bit);
}
-
- if ( val & mask_WDTOE )
+
+ if ( val & _BV(reg->bp_wdtcr[BP_WDTOE].bit) )
{ /* program has set WDTOE */
reg->toe_clk = TOE_CLKS;
@@ -487,9 +489,9 @@
}
}
- reg->wdtcr = (val & reg->func_mask);
+ reg->wdtcr = (val & bitpos_get_register_mask(reg->bp_wdtcr));
- if ( (wd_enabled == 0) && (val & mask_WDE) && (reg->timer_cb == NULL) )
+ if ( (wd_enabled == 0) && (val & _BV(reg->bp_wdtcr[BP_WDE].bit)) && (reg->timer_cb == NULL) )
{
/* install the WD timer callback */
cb = callback_new( wdtcr_timer_cb, (AvrClass *)reg );
@@ -497,7 +499,7 @@
avr_core_async_cb_add( (AvrCore *)vdev_get_core(dev), cb );
}
- if ( wd_enabled && ((val & mask_WDE) == 0) && (reg->timer_cb != NULL) )
+ if ( wd_enabled && ((val & _BV(reg->bp_wdtcr[BP_WDE].bit)) == 0) && (reg->timer_cb != NULL) )
{
/* tell callback to remove itself */
reg->timer_cb = NULL;
@@ -509,10 +511,14 @@
WDTCR *wdtcr = (WDTCR *)dev;
wdtcr->wdtcr = 0;
-
+
wdtcr->last_WDR = get_program_time(); /* FIXME: This might not be the right thing to do */
+ /* NOTE: [hnkraus] I think that is clearly the wrong thing to do!
+ A solution might be to use an clock callback and a new option to specify the
+ frequency the mcu is running at. This should be a function behaving more like
+ the real device */
wdtcr->timer_cb = NULL;
-
+
wdtcr->toe_clk = TOE_CLKS;
wdtcr->toe_cb = NULL;
}
@@ -535,7 +541,7 @@
return CB_RET_REMOVE;
time_diff = time - wdtcr->last_WDR;
- time_out = TIMEOUT_BASE * (1 << (wdtcr->wdtcr & mask_WDP));
+ time_out = TIMEOUT_BASE * (1 << (wdtcr->wdtcr & 0x03));
if (time_diff > time_out)
{
@@ -564,11 +570,11 @@
}
else
{
- wdtcr_set_bit( wdtcr, bit_WDTOE, 0 );
+ wdtcr_set_bit( wdtcr, wdtcr->bp_wdtcr[BP_WDTOE].bit, 0 );
wdtcr->toe_cb = NULL; /* So we know that cb is not installed */
return CB_RET_REMOVE;
}
-
+
return CB_RET_RETAIN;
}
Index: simulavr/src/register.h
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/register.h,v
retrieving revision 1.3
diff -u -r1.3 register.h
--- simulavr/src/register.h 16 Oct 2002 03:37:54 -0000 1.3
+++ simulavr/src/register.h 7 Apr 2003 17:43:15 -0000
@@ -207,24 +207,6 @@
*
\****************************************************************************/
-typedef enum {
- bit_WDP0 = 0, /* prescaler bit 0 */
- bit_WDP1 = 1, /* prescaler bit 1 */
- bit_WDP2 = 2, /* prescaler bit 2 */
- bit_WDE = 3, /* watchdog enable */
- bit_WDTOE = 4, /* turn-off enable */
-} WDTCR_BITS;
-
-typedef enum {
- mask_WDP0 = 1 << bit_WDP0,
- mask_WDP1 = 1 << bit_WDP1,
- mask_WDP2 = 1 << bit_WDP2,
- mask_WDE = 1 << bit_WDE,
- mask_WDTOE = 1 << bit_WDTOE,
-
- mask_WDP = (mask_WDP2 | mask_WDP1 | mask_WDP0),
-} WDTCR_MASKS;
-
enum _wdtcr_addr_info {
WDTCR_BASE = 0x41, /* wdtcr base mem addr */
WDTCR_SIZE = 1,
@@ -240,15 +222,15 @@
struct _WDTCR {
VDevice parent;
byte wdtcr;
- byte func_mask;
+ BitPos *bp_wdtcr;
qword last_WDR;
int toe_clk;
CallBack *timer_cb;
CallBack *toe_cb;
};
-extern WDTCR *wdtcr_new ( byte func_mask );
-extern void wdtcr_construct ( WDTCR *wdtcr, byte func_mask );
+extern WDTCR *wdtcr_new ( BitPos *bp_wdtcr );
+extern void wdtcr_construct ( WDTCR *wdtcr, BitPos *bp_wdtcr );
extern void wdtcr_destroy ( void *wdtcr );
extern void wdtcr_update ( WDTCR *wdtcr );
Index: simulavr/src/sram.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/sram.c,v
retrieving revision 1.7
diff -u -r1.7 sram.c
--- simulavr/src/sram.c 5 Sep 2002 06:41:08 -0000 1.7
+++ simulavr/src/sram.c 7 Apr 2003 17:43:15 -0000
@@ -38,6 +38,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/stack.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/stack.c,v
retrieving revision 1.11
diff -u -r1.11 stack.c
--- simulavr/src/stack.c 17 Apr 2002 20:47:58 -0000 1.11
+++ simulavr/src/stack.c 7 Apr 2003 17:43:17 -0000
@@ -47,6 +47,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
Index: simulavr/src/timers.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/timers.c,v
retrieving revision 1.7
diff -u -r1.7 timers.c
--- simulavr/src/timers.c 17 Apr 2002 20:47:58 -0000 1.7
+++ simulavr/src/timers.c 7 Apr 2003 17:43:19 -0000
@@ -27,7 +27,7 @@
* \file timers.c
* \brief Module to simulate the AVR's on-board timer/counters.
*
- * This currently only implements the timer/counter 0.
+ * This currently only implements the 8bit - timer/counters.
*/
#include
@@ -45,6 +45,7 @@
#include "storage.h"
#include "flash.h"
+#include "bitpos.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
@@ -58,9 +59,28 @@
#include "intvects.h"
+Timer8Definition global_timer8_definitions[] = {
+ {
+ /* timer_name */ "Timer0",
+ /* tcnt_name */ "TCNT0",
+ /* tccr_name */ "TCCR0",
+ /* base */ 0x52,
+ /* overflow_flag */ BP_TOV0,
+ /* output_compare_flag */ BP_OCF0,
+},
+{
+ /* timer_name */ "Timer2",
+ /* tcnt_name */ "TCNT2",
+ /* tccr_name */ "TCCR2",
+ /* base */ 0x44,
+ /* overflow_flag */ BP_TOV2,
+ /* output_compare_flag */ BP_OCF2,
+ }
+};
+
/******************************************************************************\
*
- * Timer/Counter 0
+ * Timer/Counter 0 and 2
*
\******************************************************************************/
@@ -72,12 +92,12 @@
/** \brief Allocate a new timer interrupt */
-TimerIntr_T *timer_intr_new( byte func_mask )
+TimerIntr_T *timer_intr_new( BitPos *bp_timsk)
{
TimerIntr_T *ti;
ti = avr_new( TimerIntr_T, 1 );
- timer_intr_construct( ti, func_mask );
+ timer_intr_construct( ti, bp_timsk );
class_overload_destroy( (AvrClass *)ti, timer_intr_destroy );
return ti;
@@ -85,7 +105,7 @@
/** \brief Constructor for timer interrupt object. */
-void timer_intr_construct( TimerIntr_T *ti, byte func_mask )
+void timer_intr_construct( TimerIntr_T *ti, BitPos *bp_timsk )
{
char *name = "TimerIntr";
@@ -95,7 +115,7 @@
vdev_construct( (VDevice *)ti, name, TIMER_INTR_BASE, TIMER_INTR_SIZE,
timer_intr_read, timer_intr_write, timer_intr_reset, timer_intr_reg_name );
- ti->func_mask = func_mask;
+ ti->bp_timsk = bp_timsk;
timer_intr_reset( (VDevice*)ti );
}
@@ -116,8 +136,8 @@
TimerIntr_T *ti = (TimerIntr_T *)dev;
switch ( addr - vdev_get_base(dev) ) {
- case TIMER_INTR_TIMSK_ADDR: return (ti->timsk & ti->func_mask);
- case TIMER_INTR_TIFR_ADDR: return (ti->tifr & ti->func_mask);
+ case TIMER_INTR_TIMSK_ADDR: return (ti->timsk & bitpos_get_register_mask(ti->bp_timsk));
+ case TIMER_INTR_TIFR_ADDR: return (ti->tifr & bitpos_get_register_mask(ti->bp_timsk));
default:
avr_error( "Bad address: 0x%04x", addr );
}
@@ -133,7 +153,7 @@
if (offset == TIMER_INTR_TIMSK_ADDR)
{
- ti->timsk = (val & ti->func_mask);
+ ti->timsk = (val & bitpos_get_register_mask(ti->bp_timsk));
if ( ti->timsk == 0 )
{
ti->intr_cb = NULL; /* no interrupt are enabled, remove the callback */
@@ -148,7 +168,7 @@
}
else if (offset == TIMER_INTR_TIFR_ADDR)
{
- ti->tifr = (val & ti->func_mask);
+ ti->tifr = (val & bitpos_get_register_mask(ti->bp_timsk));
}
else
{
@@ -181,7 +201,7 @@
static int timer_intr_cb( qword time, AvrClass *data )
{
TimerIntr_T *ti = (TimerIntr_T *)data;
- byte intrs = ti->timsk & ti->tifr & ti->func_mask;
+ byte intrs = ti->timsk & ti->tifr & bitpos_get_register_mask(ti->bp_timsk);
if ( ti->intr_cb == NULL )
return CB_RET_REMOVE;
@@ -193,31 +213,38 @@
* _BUT_ should it be done here? Might be a problem if there are
* many interrupts pending and then the user wants to clear one.
*/
-
- if (intrs & mask_TOV0)
+ /* Overflow flags */
+ if (intrs & _BV(ti->bp_timsk[BP_TOV0].bit))
{
avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER0_OVF );
- ti->tifr &= ~mask_TOV0;
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_TOV0].bit);
}
- else if ( intrs & mask_ICF1 )
+ else if ( intrs & _BV(ti->bp_timsk[BP_TOV1].bit))
{
- avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_CAPT );
- ti->tifr &= ~mask_ICF1;
+ avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_OVF );
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_TOV1].bit);
}
- else if ( intrs & mask_OCF1B )
+ else if ( intrs & _BV(ti->bp_timsk[BP_TOV2].bit))
{
- avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_COMPB );
- ti->tifr &= ~mask_OCF1B;
+ avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER2_OVF );
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_TOV2].bit);
}
- else if ( intrs & mask_OCF1A )
+ /* Output compare flags */
+ else if ( intrs & _BV(ti->bp_timsk[BP_OCF1A].bit))
{
avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_COMPA );
- ti->tifr &= ~mask_OCF1A;
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_OCF1A].bit);
}
- else if ( intrs & mask_TOV1 )
+ else if ( intrs & _BV(ti->bp_timsk[BP_OCF1B].bit))
{
- avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_OVF );
- ti->tifr &= ~mask_TOV1;
+ avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_COMPB );
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_OCF1B].bit);
+ }
+ /* Input capture flags */
+ else if ( intrs & _BV(ti->bp_timsk[BP_ICF1].bit))
+ {
+ avr_core_irq_raise( (AvrCore *)vdev_get_core((VDevice *)ti), IRQ_TIMER1_CAPT );
+ ti->tifr &= ~_BV(ti->bp_timsk[BP_ICF1].bit);
}
else
{
@@ -231,47 +258,48 @@
/******************************************************************************\
*
- * Timer/Counter 0
+ * Timer/Counter 0/2 (8 bit)
*
\******************************************************************************/
-static byte timer0_read ( VDevice *dev, int addr );
-static void timer0_write ( VDevice *dev, int addr, byte val );
-static void timer0_reset ( VDevice *dev );
-static char *timer0_reg_name ( VDevice *dev , int addr );
-static int timer0_clk_incr_cb( qword ck, AvrClass *data );
+static byte timer8_read ( VDevice *dev, int addr );
+static void timer8_write ( VDevice *dev, int addr, byte val );
+static void timer8_reset ( VDevice *dev );
+static char *timer8_reg_name ( VDevice *dev , int addr );
+static int timer8_clk_incr_cb( qword ck, AvrClass *data );
-/** \brief Allocate a new timer/counter 0. */
+/** \brief Allocate a new 8 bit timer/counter. */
-Timer0_T *timer0_new( void )
+Timer8_T *timer8_new( Timer8Definition timerdef, BitPos *bp_tccr )
{
- Timer0_T *timer;
+ Timer8_T *timer;
- timer = avr_new( Timer0_T, 1 );
- timer0_construct( timer );
- class_overload_destroy( (AvrClass *)timer, timer0_destroy );
+ timer = avr_new( Timer8_T, 1 );
+ timer8_construct( timer, timerdef, bp_tccr );
+ class_overload_destroy( (AvrClass *)timer, timer8_destroy );
return timer;
}
-/** \brief Constructor for timer/counter 0 object. */
+/** \brief Constructor for 8bit timer/counter object. */
-void timer0_construct( Timer0_T *timer )
+void timer8_construct( Timer8_T *timer, Timer8Definition timerdef, BitPos *bp_tccr )
{
- char *name = "Timer0";
-
if (timer == NULL)
avr_error( "passed null ptr" );
- vdev_construct( (VDevice *)timer, name, TIMER0_BASE, TIMER0_SIZE,
- timer0_read, timer0_write, timer0_reset, timer0_reg_name );
+ vdev_construct( (VDevice *)timer, timerdef.timer_name, timerdef.base, TIMER8_SIZE,
+ timer8_read, timer8_write, timer8_reset, timer8_reg_name );
+
+ timer->bp_tccr=bp_tccr;
+ timer->timerdef=timerdef;
- timer0_reset( (VDevice*)timer );
+ timer8_reset( (VDevice*)timer );
}
/** \brief Destructor for timer/counter 0 object. */
-void timer0_destroy( void *timer )
+void timer8_destroy( void *timer )
{
if (timer == NULL)
return;
@@ -279,42 +307,50 @@
vdev_destroy( timer );
}
-static byte timer0_read( VDevice *dev, int addr )
+static byte timer8_read( VDevice *dev, int addr )
{
- Timer0_T *timer = (Timer0_T *)dev;
+ Timer8_T *timer = (Timer8_T *)dev;
switch ( addr - vdev_get_base(dev) ) {
- case TIMER0_TCNT_ADDR: return timer->tcnt;
- case TIMER0_TCCR_ADDR: return timer->tccr;
+ case TCNT_ADDR: return timer->tcnt;
+ case TCCR_ADDR: return timer->tccr;
default:
avr_error( "Bad address: 0x%04x", addr );
}
return 0; /* will never get here */
}
-static void timer0_write( VDevice *dev, int addr, byte val )
+static void timer8_write( VDevice *dev, int addr, byte val )
{
- Timer0_T *timer = (Timer0_T *)dev;
+ Timer8_T *timer = (Timer8_T *)dev;
int offset = addr - vdev_get_base(dev);
+ int cs;
CallBack *cb;
- if ( offset == TIMER0_TCNT_ADDR )
+ if ( offset == TCNT_ADDR )
{
timer->tcnt = val;
}
- else if ( offset == TIMER0_TCCR_ADDR )
+ else if ( offset == TCCR_ADDR )
{
/*
* When the user writes toe TCCR, a callback is installed for either
* clock generated increments or externally generated increments. The
- * two incrememtor callback are mutally exclusive, only one or the
+ * two incrememtor callback are mutally exclusive, only one or the
* other can be installed at any given instant.
*/
/* timer 0 only has clock select function. */
- timer->tccr = val & mask_CS;
+ /* FIXME: [hnkraus] This is NOT true! on most devices t/c0 also has pwm and other functions
+ and these functions must be added! */
+ timer->tccr = val & bitpos_get_register_mask(timer->bp_tccr);
+
+ /* FIXME: [hnkraus] If any device has the CS bits not in a row we have to figure
+ out a new handling for this */
+
+ cs=((timer->tccr)>>timer->bp_tccr[BP_CS0].bit)&0x07;
- switch (timer->tccr) {
+ switch (cs) {
case CS_STOP:
/* stop either of the installed callbacks */
timer->clk_cb = timer->ext_cb = NULL;
@@ -346,11 +382,11 @@
/* remove external incrementor if installed */
if (timer->ext_cb)
timer->ext_cb = NULL;
-
+
/* install the clock incrementor callback (with flair!) */
if (timer->clk_cb == NULL)
{
- cb = callback_new( timer0_clk_incr_cb, (AvrClass *)timer );
+ cb = callback_new( timer8_clk_incr_cb, (AvrClass *)timer );
timer->clk_cb = cb;
avr_core_clk_cb_add( (AvrCore *)vdev_get_core((VDevice *)timer), cb );
}
@@ -361,9 +397,9 @@
}
}
-static void timer0_reset( VDevice *dev )
+static void timer8_reset( VDevice *dev )
{
- Timer0_T *timer = (Timer0_T *)dev;
+ Timer8_T *timer = (Timer8_T *)dev;
timer->clk_cb = NULL;
timer->ext_cb = NULL;
@@ -374,21 +410,24 @@
timer->divisor = 0;
}
-static char *timer0_reg_name( VDevice *dev , int addr )
+static char *timer8_reg_name( VDevice *dev , int addr )
{
+ Timer8_T *timer = (Timer8_T *)dev;
+
switch ( addr - vdev_get_base(dev) ) {
- case TIMER0_TCNT_ADDR: return "TCNT0";
- case TIMER0_TCCR_ADDR: return "TCCR0";
+ case TCNT_ADDR: return timer->timerdef.tcnt_name;
+ case TCCR_ADDR: return timer->timerdef.tccr_name;
default:
avr_error( "Bad address: 0x%04x", addr );
}
+
return NULL;
}
-static int timer0_clk_incr_cb( qword ck, AvrClass *data )
+static int timer8_clk_incr_cb( qword ck, AvrClass *data )
{
- Timer0_T *timer = (Timer0_T *)data;
+ Timer8_T *timer = (Timer8_T *)data;
byte last = timer->tcnt;
TimerIntr_T *ti;
@@ -401,6 +440,7 @@
if (timer->divisor <= 0)
avr_error( "Bad divisor value: %d", timer->divisor );
+ /* FIXME: This doesn't handle the prescaler mechanism correctly */
/* increment clock if ck is a mutliple of divisor */
timer->tcnt += ((ck % timer->divisor) == 0);
@@ -412,7 +452,8 @@
interpretation of the datasheets. See datasheet discussion of TIFR.
TRoth */
if ( (timer->tcnt == 0) && (timer->tcnt != last) )
- ti->tifr |= mask_TOV0;
-
+ ti->tifr |= _BV(ti->bp_timsk[timer->timerdef.overflow_flag].bit);
+
+ /* FIXME: Add output compare match */
return CB_RET_RETAIN;
}
Index: simulavr/src/timers.h
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/timers.h,v
retrieving revision 1.2
diff -u -r1.2 timers.h
--- simulavr/src/timers.h 18 Mar 2002 23:48:23 -0000 1.2
+++ simulavr/src/timers.h 7 Apr 2003 17:43:20 -0000
@@ -40,51 +40,18 @@
TIMER_INTR_TIMSK_ADDR = 1,
};
-typedef enum {
- bit_TOIE0 = 1, /* timer/counter0 overflow interrupt enable */
- bit_TICIE1 = 3, /* timer/counter1 input capture interrupt enable */
- bit_OCIE1B = 5, /* timer/counter1 output compare B match interrupt enable */
- bit_OCIE1A = 6, /* timer/counter1 output compare A match interrupt enable */
- bit_TOIE1 = 7, /* timer/counter1 overflow interrupt enable */
-} TIMSK_BITS;
-
-typedef enum {
- mask_TOIE0 = 1 << bit_TOIE0,
- mask_TICIE1 = 1 << bit_TICIE1,
- mask_OCIE1B = 1 << bit_OCIE1B,
- mask_OCIE1A = 1 << bit_OCIE1A,
- mask_TOIE1 = 1 << bit_TOIE1,
-} TIMSK_MASKS;
-
-typedef enum {
- bit_TOV0 = 1, /* timer/counter0 overflow flag */
- bit_ICF1 = 3, /* input capture flag 1 */
- bit_OCF1B = 5, /* output compare flag 1B */
- bit_OCF1A = 6, /* output compare flag 1A */
- bit_TOV1 = 7, /* timer/counter1 overflow flag */
-} TIFR_BITS;
-
-typedef enum {
- mask_TOV0 = 1 << bit_TOV0,
- mask_ICF1 = 1 << bit_ICF1,
- mask_OCF1B = 1 << bit_OCF1B,
- mask_OCF1A = 1 << bit_OCF1A,
- mask_TOV1 = 1 << bit_TOV1,
-} TIFR_MASKS;
-
typedef struct _TimerIntr_T TimerIntr_T;
-/* FIXME: will timsk and tifr always have the same func mask? */
struct _TimerIntr_T {
VDevice parent;
byte timsk; /* Timer/counter interrupt mask register */
byte tifr; /* Timer/counter interrupt flag register */
- byte func_mask; /* mask of available register functions */
CallBack *intr_cb; /* callback for checking and raising interrupts */
+ BitPos *bp_timsk; /* bit positions for timsk */
};
-extern TimerIntr_T *timer_intr_new ( byte func_mask );
-extern void timer_intr_construct ( TimerIntr_T *ti, byte func_mask );
+extern TimerIntr_T *timer_intr_new( BitPos *bp_timsk );
+extern void timer_intr_construct ( TimerIntr_T *ti, BitPos *bp_timsk );
extern void timer_intr_destroy ( void *ti );
/****************************************************************************\
@@ -93,26 +60,6 @@
*
\****************************************************************************/
-typedef enum {
- bit_CS0 = 0, /* timer/counter clock select bit 0*/
- bit_CS1 = 1,
- bit_CS2 = 2,
- bit_CTC = 3, /* clear timer/counter on compare match */
- bit_ICES = 6, /* input capture edge select */
- bit_ICNC = 7, /* input capture noise canceler (4 CKs) */
-} TCCR_BITS;
-
-typedef enum {
- mask_CS0 = 1 << bit_CS0,
- mask_CS1 = 1 << bit_CS1,
- mask_CS2 = 1 << bit_CS2,
- mask_CTC = 1 << bit_CTC,
- mask_ICES = 1 << bit_ICES,
- mask_ICNC = 1 << bit_ICNC,
-
- mask_CS = (mask_CS0 | mask_CS1 | mask_CS2),
-} TCCR_MASKS;
-
enum _cs_constants {
CS_STOP = 0x00, /* Stop, the Timer/Counter is stopped */
CS_CK = 0x01, /* CK */
@@ -120,37 +67,56 @@
CS_CK_64 = 0x03, /* CK/64 */
CS_CK_256 = 0x04, /* CK/256 */
CS_CK_1024 = 0x05, /* CK/1024 */
- CS_EXT_FALL = 0x06, /* External Pin Tn, falling edge */
- CS_EXT_RISE = 0x07, /* External Pin Tn, rising edge */
+ CS_EXT_FALL = 0x06, /* External Pin Tn, falling edge */
+ CS_EXT_RISE = 0x07, /* External Pin Tn, rising edge */
};
/****************************************************************************\
*
- * Timer0(VDevice) : Timer/Counter 0
+ * Timer0(VDevice) : Timer/Counter 0/2 (8bit)
*
\****************************************************************************/
-enum _timer0_constants {
- TIMER0_BASE = 0x52, /* base memory address */
- TIMER0_SIZE = 2, /* TCCR0 and TCNT0 */
+enum _timer8_definitions {
+ TD_TIMER0 = 0,
+ TD_TIMER2,
+};
+
+typedef struct _Timer8Definition Timer8Definition;
- TIMER0_TCNT_ADDR = 0, /* offset from base to TCNT Register */
- TIMER0_TCCR_ADDR = 1,
+struct _Timer8Definition {
+ char *timer_name;
+ char *tcnt_name;
+ char *tccr_name;
+ int base;
+ int overflow_flag;
+ int output_compare_flag;
};
-typedef struct _Timer0 Timer0_T;
+extern Timer8Definition global_timer8_definitions[];
+
+enum _timer8_constants {
+ TIMER8_SIZE = 2, /* TCCR0 and TCNT0 */
+ TCNT_ADDR = 0, /* offset from base to TCNT Register */
+ TCCR_ADDR = 1,
+};
+
+
+typedef struct _Timer8 Timer8_T;
-struct _Timer0 {
+struct _Timer8 {
VDevice parent;
byte tccr; /* control register */
byte tcnt; /* Timer/Counter up-counter register */
int divisor; /* clock divisor */
CallBack *clk_cb; /* incr timer tied to clock */
CallBack *ext_cb; /* incr timer tied to external event */
+ BitPos *bp_tccr; /* bitpositios for tccr */
+ Timer8Definition timerdef; /* Timer definition structure */
};
-extern Timer0_T *timer0_new ( void );
-extern void timer0_construct ( Timer0_T *timer );
-extern void timer0_destroy ( void *timer );
+extern Timer8_T *timer8_new ( Timer8Definition timerdef, BitPos *bp_tccr );
+extern void timer8_construct ( Timer8_T *timer, Timer8Definition timerdef, BitPos *bp_tccr );
+extern void timer8_destroy ( void *timer );
#endif /* SIM_TIMERS_H */