? 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 */