2003-08-13 Theodore A. Roth * ChangeLog: * doc/simulavr.texi: * src/avrcore.c: * src/device.c: Index: ChangeLog =================================================================== RCS file: /cvsroot/simulavr/simulavr/ChangeLog,v retrieving revision 1.154 diff -u -p -r1.154 ChangeLog --- ChangeLog 13 Aug 2003 01:32:42 -0000 1.154 +++ ChangeLog 13 Aug 2003 18:38:31 -0000 @@ -1,3 +1,10 @@ +2003-08-13 Theodore A. Roth + [Thanks to Hermann Kraus ] + + * doc/simulavr.texi: Fix 'target remote' note. + * src/avrcore.c: Wrap some line lines. + Document all functions via doxygen. + 2003-08-12 Theodore A. Roth * Makefile.am: Remove AUX_DIST and AUX_DIST_EXTRA vars. Index: doc/simulavr.texi =================================================================== RCS file: /cvsroot/simulavr/simulavr/doc/simulavr.texi,v retrieving revision 1.19 diff -u -p -r1.19 simulavr.texi --- doc/simulavr.texi 22 Feb 2003 23:00:31 -0000 1.19 +++ doc/simulavr.texi 13 Aug 2003 18:38:32 -0000 @@ -344,7 +344,7 @@ that the simulator has started and is re start a new one, which is not likely to be what you want to do. When specifying the remote target to connect to, it is sufficient to -write ``target remote :1212'' instead of ``target remote :1212''. +write ``target remote :1212'' instead of ``target remote localhost:1212''. Hitting @kbd{CTRL-c} in gdb can be used to interrupt the simulator while it is processing instructions and return control back to gdb. This is most Index: src/avrcore.c =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/avrcore.c,v retrieving revision 1.63 diff -u -p -r1.63 avrcore.c --- src/avrcore.c 20 Jun 2003 20:50:47 -0000 1.63 +++ src/avrcore.c 13 Aug 2003 18:38:32 -0000 @@ -4,7 +4,7 @@ **************************************************************************** * * simulavr - A simulator for the Atmel AVR family of microcontrollers. - * Copyright (C) 2001, 2002 Theodore A. Roth + * Copyright (C) 2001, 2002, 2003 Theodore A. Roth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -318,6 +318,10 @@ static IntVect *irq_get_head_vector( DLi * ***************************************************************************/ +/** \name AvrCore handling methods */ + +/address@hidden/ + /** \brief Allocate a new AvrCore object. */ AvrCore *avr_core_new( int flash_sz, int PC_sz, StackType stack_type, @@ -346,7 +350,8 @@ void avr_core_construct( AvrCore *core, core->sleep_mode = 0; /* each bit represents a sleep mode */ core->PC = 0; core->PC_size = PC_sz; - core->PC_max = flash_sz / 2; /* flash_sz is in bytes, need number of words here */ + core->PC_max = flash_sz / 2; /* flash_sz is in bytes, need number of + words here */ core->sreg = sreg_new(); core->flash = flash_new( flash_sz ); core->gpwr = gpwr_new(); @@ -454,83 +459,113 @@ void avr_core_attach_vdev( AvrCore *core mem_attach( core->mem, dev ); } -/** \brief FIXME: write me. */ +/** \brief Returns the \c VDevice with the name \a name. */ VDevice *avr_core_get_vdev_by_name( AvrCore *core, char *name ) { return mem_get_vdevice_by_name( core->mem, name ); } -/** \brief FIXME: write me. */ +/** \brief Returns the \c VDevice which handles the address \a addr. */ VDevice *avr_core_get_vdev_by_addr( AvrCore *core, int addr ) { return mem_get_vdevice_by_addr( core->mem, addr ); } -/** \brief FIXME: write me. */ +/** \brief Sets the device's state (running, stopped, breakpoint, sleep). */ void avr_core_set_state( AvrCore *core, StateType state ) { core->state = state; } -/** \brief FIXME: write me. */ +/** \brief Returns the device's state (running, stopped, breakpoint, sleep). */ int avr_core_get_state( AvrCore *core ) { return core->state; } -/** \brief FIXME: write me. */ + +/** \brief Sets the device to a sleep state. + * \param core Pointer to the core. + * \param sleep_mode The BITNUMBER of the sleepstate. + */ void avr_core_set_sleep_mode( AvrCore *core, int sleep_mode ) { core->state = STATE_SLEEP; core->sleep_mode = ((unsigned int)1 << sleep_mode); } -/** \brief FIXME: write me. */ +/** \brief Return the device's sleepmode. */ int avr_core_get_sleep_mode( AvrCore *core ) { return core->sleep_mode; } -/** - * \brief Program Memory Space Access Methods - */ +/address@hidden/ + +/** \name Program Memory Space Access Methods */ + +/address@hidden/ + +/** \brief Reads a word from flash memory. */ word avr_core_flash_read( AvrCore *core, int addr ) { return flash_read( core->flash, addr ); } -/** \brief FIXME: write me. */ +/** \brief Writes a word to flash memory. */ void avr_core_flash_write( AvrCore *core, int addr, word val ) { flash_write( core->flash, addr, val ); } -/** \brief FIXME: write me. */ +/** \brief Writes a byte to flash memory. + * + * This function writes the lower 8 bit of a flash word. + * Use avr_core_flash_write() write to write a full word, + * or avr_core_flash_write_hi8() to write the upper 8 bits. + */ void avr_core_flash_write_lo8( AvrCore *core, int addr, byte val ) { flash_write_lo8( core->flash, addr, val ); } -/** \brief FIXME: write me. */ +/** \brief Writes a byte to flash memory. + * + * This function writes the upper 8 bit of a flash word. + * Use avr_core_flash_write() write to write a full word, + * or avr_core_flash_write_lo8() to write the lower 8 bits. + */ void avr_core_flash_write_hi8( AvrCore *core, int addr, byte val ) { flash_write_hi8( core->flash, addr, val ); } -/** - * \brief Data Memory Space Access Methods - */ +/address@hidden/ + +/** \name Data Memory Space Access Methods */ + +/address@hidden/ + +/** \brief Reads a byte from memory. + * + * This accesses the \a register \a file and the \a SRAM. + */ byte avr_core_mem_read( AvrCore *core, int addr ) { return mem_read( core->mem, addr ); } -/** \brief FIXME: write me. */ +/** \brief Writes a byte to memory. + * + * This accesses the \a register \a file and the \a SRAM. + */ void avr_core_mem_write( AvrCore *core, int addr, byte val ) { mem_write( core->mem, addr, val ); } +/address@hidden/ + /** \name Status Register Access Methods */ /address@hidden/ @@ -586,26 +621,35 @@ void avr_core_rampz_set( AvrCore *core, /address@hidden/ /** - * \brief General Purpose Working Register Access Methods + * \Name General Purpose Working Register Access Methods */ + +/address@hidden/ + +/** \brief Returns a GPWR's(\a r0-r31) value. */ byte avr_core_gpwr_get ( AvrCore *core, int reg ) { return gpwr_get( core->gpwr, reg ); } -/** \brief FIXME: write me. */ +/** \brief Writes a GPWR's (\a r0-r31) value. */ void avr_core_gpwr_set ( AvrCore *core, int reg, byte val ) { gpwr_set( core->gpwr, reg, val ); } +/address@hidden/ + /** - * \brief Direct I/O Register Access Methods + * \name Direct I/O Register Access Methods * * IO Registers are mapped in memory directly after the 32 (0x20) * general registers. */ +/address@hidden/ + +/** \brief Displays all registers. */ void avr_core_io_display_names( AvrCore *core ) { int i; @@ -619,25 +663,37 @@ void avr_core_io_display_names( AvrCore } } -/** \brief FIXME: write me. */ +/** \brief Reads the value of a register. + * \param core Pointer to the core. + * \param reg The registers address. This address is counted above the + * beginning of the registers memory block (0x20). + */ byte avr_core_io_read( AvrCore *core, int reg ) { return avr_core_mem_read( core, reg + IO_REG_ADDR_BEGIN ); } -/** \brief FIXME: write me. */ +/** \brief Writes the value of a register. + * See avr_core_io_read() for a discussion of \a reg. */ void avr_core_io_write( AvrCore *core, int reg, byte val ) { avr_core_mem_write( core, reg + IO_REG_ADDR_BEGIN, val ); } -/** \brief Read an io register into val and put the name of the register into buf. */ - -void avr_core_io_fetch( AvrCore *core, int reg, byte *val, char *buf, int bufsiz ) +/** \brief Read an io register into val and put the name of the register into + * buf. */ +void avr_core_io_fetch( AvrCore *core, int reg, byte *val, char *buf, + int bufsiz ) { mem_io_fetch( core->mem, reg + IO_REG_ADDR_BEGIN, val, buf, bufsiz ); } +/address@hidden/ + +/** \name Stack Methods */ + +/address@hidden/ + /** \brief Pop 1-4 bytes off of the stack. * * See stack_pop() for more details. @@ -656,6 +712,12 @@ void avr_core_stack_push( AvrCore *core, stack_push( core->stack, bytes, val ); } +/address@hidden/ + +/** \name Program Counter Methods */ + +/address@hidden/ + /* Private Deal with PC reach-arounds. @@ -673,10 +735,12 @@ static void adjust_PC_to_max( AvrCore *c core->PC -= core->PC_max; } +/* FIXME: Aren't these functions better to be marked inline or macro? */ + /** \brief Returns the size of the Program Counter in bytes. * * Most devices have a 16-bit PC (2 bytes), but some larger ones - * (e.g. mega128), have a 22-bit PC (3 bytes). + * (e.g. mega256), have a 22-bit PC (3 bytes). */ sdword avr_core_PC_size( AvrCore *core ) { return core->PC_size; } @@ -716,13 +780,17 @@ void avr_core_PC_incr( AvrCore *core, in display_pc( core->PC ); } -/** - * \brief Methods for accessing CK and instruction Clocks. - */ +/address@hidden/ + +/** \name Methods for accessing CK and instruction Clocks */ + +/address@hidden/ + +/** \brief Get the current clock counter. */ qword avr_core_CK_get ( AvrCore *core ) { return core->CK; } -/** \brief FIXME: write me. */ -void avr_core_CK_incr( AvrCore *core ) +/** \brief Increment the clock counter. */ +void avr_core_CK_incr( AvrCore *core ) { core->CK++; @@ -730,40 +798,47 @@ void avr_core_CK_incr( AvrCore *core ) display_clock( core->CK ); } -/** \brief FIXME: write me. */ -int avr_core_inst_CKS_get( AvrCore *core ) { return core->inst_CKS; } +/** \brief Get the number of clock cycles remaining for the currently + * executing instruction. */ +int avr_core_inst_CKS_get( AvrCore *core ) { return core->inst_CKS; } + +/** \brief Set the number of clock cycles for the instruction being + * executed. */ +void avr_core_inst_CKS_set( AvrCore *core, int val ) { core->inst_CKS = val; } -/** \brief FIXME: write me. */ -void avr_core_inst_CKS_set( AvrCore *core, int val ) { core->inst_CKS = val; } +/** \name Interrupt Access Methods. */ -/** - * \brief Interrupt Access Methods. - */ +/address@hidden/ + +/** \brief Gets the first pending irq. */ IntVect *avr_core_irq_get_pending( AvrCore *core ) { - return irq_get_pending_vector( core->irq_pending, core->state, core->sleep_mode ); + return irq_get_pending_vector( core->irq_pending, core->state, + core->sleep_mode ); } -/** \brief FIXME: write me. */ +/** \brief Raises an irq by adding it's data to the irq_pending list. */ void avr_core_irq_raise( AvrCore *core, int irq ) { - core->irq_pending = irq_list_add( core->irq_pending, &core->irq_vtable[irq] ); + core->irq_pending = irq_list_add( core->irq_pending, + &core->irq_vtable[irq] ); } -/** \brief FIXME: write me. */ +/** \brief Calls the interrupt's callback to clear the flag. */ void avr_core_irq_clear( AvrCore *core, IntVect *irq ) { core->irq_pending = irq_list_delete( core->irq_pending, irq ); } - -/** \brief FIXME: write me. */ +/** \brief Removes all irqs from the irq_pending list. */ void avr_core_irq_clear_all( AvrCore *core ) { dlist_delete_all( core->irq_pending ); core->irq_pending = NULL; } +/address@hidden/ + /** \name Break point access methods. */ /address@hidden/ @@ -890,6 +965,10 @@ static int exec_next_instruction( AvrCor return result; } +/** \name Program control methods */ + +/address@hidden/ + /* * Private * @@ -902,6 +981,15 @@ static int exec_next_instruction( AvrCor * Reset vector is not controlled by the SREG(I) flag, thus if reset * interrupt has occurred, the device will be reset irregardless of state * of SREG(I). + * + * \note There are different ways of doing this: + * - In register.c wdtcr_intr_cb() we can directly reset the MCU without + * the use of irqs. This would require to make the callback an async + * callback and it would allow the speed improvments commented out below + * to be activated. + * - Keep it as an interrupt an waste CPU time. + * + * Ted, what do you think we should do? */ static void avr_core_check_interrupts( AvrCore *core ) @@ -973,9 +1061,8 @@ int avr_core_step( AvrCore *core ) core->inst_CKS--; } - /* - * FIXME: async cb's and interrupt checking might need to be put somewhere else. - */ + /* FIXME: async cb's and interrupt checking might need to be put + somewhere else. */ /* Execute the asynchronous callbacks */ avr_core_async_cb_exec( core ); @@ -1051,6 +1138,12 @@ void avr_core_reset( AvrCore *core ) mem_reset( core->mem ); } +/address@hidden/ + +/** \name Callback Handling Methods */ + +/address@hidden/ + /** * \brief For adding external read and write callback functions. * @@ -1110,7 +1203,8 @@ void avr_core_async_cb_add( AvrCore *cor void avr_core_clk_cb_exec( AvrCore *core ) { - core->clk_cb = callback_list_execute_all( core->clk_cb, avr_core_CK_get(core) ); + core->clk_cb = callback_list_execute_all( core->clk_cb, + avr_core_CK_get(core) ); } /** @@ -1118,9 +1212,12 @@ void avr_core_clk_cb_exec( AvrCore *core */ void avr_core_async_cb_exec( AvrCore *core ) { - core->async_cb = callback_list_execute_all( core->async_cb, get_program_time() ); + core->async_cb = callback_list_execute_all( core->async_cb, + get_program_time() ); } +/address@hidden/ + /** * \brief Dump the contents of the entire CPU core. * @@ -1145,9 +1242,7 @@ int avr_core_load_program( AvrCore *core return flash_load_from_file( core->flash, file, format ); } -/* - * Load a program from an input file. - */ +/** \brief Load a program from an input file. */ int avr_core_load_eeprom( AvrCore *core, char *file, int format ) { EEProm *ee = (EEProm *)mem_get_vdevice_by_name( core->mem, "EEProm" ); Index: src/device.c =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/device.c,v retrieving revision 1.9 diff -u -p -r1.9 device.c --- src/device.c 17 Apr 2002 20:47:58 -0000 1.9 +++ src/device.c 13 Aug 2003 18:38:32 -0000 @@ -50,7 +50,14 @@ #include "avrcore.h" +/** \file device.c + * \brief VDevice methods + * + * These functions are the base for all other devices + * mapped into the device space. + */ +/** \brief Create a new VDevice. */ VDevice *vdev_new( char *name, int base, int size, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_RegName reg_name ) @@ -64,6 +71,7 @@ VDevice *vdev_new( char *name, int base, return dev; } +/** \brief Constructor for a VDevice. */ void vdev_construct( VDevice *dev, char *name, int base, int size, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_RegName reg_name ) @@ -73,7 +81,8 @@ void vdev_construct( VDevice *dev, char class_construct( (AvrClass *)dev ); - dev->name = name; /* This should be a static string, so don't need to free */ + dev->name = name; /* This should be a static string, so don't + need to free */ dev->base = base; dev->size = size; @@ -83,6 +92,7 @@ void vdev_construct( VDevice *dev, char dev->reg_name = reg_name; } +/** \brief Destructor for a VDevice. */ void vdev_destroy( void *dev ) { if (dev == NULL) @@ -91,16 +101,28 @@ void vdev_destroy( void *dev ) class_destroy( dev ); } -/* c2 is really a string */ - +/** \brief Compare the names of 2 devices + * \param c1 The first device. + * \param c2 is a string and not an AvrClass object, because this function is + * called by dlist_lookup() which passes two AvrClass pointers. So the string + * is casted to an *AvrClass. + */ int vdev_name_cmp( AvrClass *c1, AvrClass *c2 ) { return strcmp( ((VDevice *)c1)->name, (char *)c2 ); } -/* When comparing an addr, c2 is really just a pointer to int and then - we see if d1->base <= addr < (d1->base+d1->size). */ - +/** \brief Checks if a address is in the device's address range + * \param c1 \c AvrClass to check. + * \param c2 The address to check. + * + * \return The different between the device's address bounds and \a c2 or if + * \a c2 is within the address range 0. + * + * \note When comparing an addr, c2 is really just a pointer (see + * vdev_name_cmp() for details) to int and then we see if d1->base <= addr < + * (d1->base+d1->size). + */ int vdev_addr_cmp( AvrClass *c1, AvrClass *c2 ) { VDevice *d1 = (VDevice *)c1; @@ -117,27 +139,42 @@ int vdev_addr_cmp( AvrClass *c1, AvrClas return 0; } +/** \brief Reads the device's value in the register at \a addr. */ byte vdev_read( VDevice *dev, int addr ) { return dev->read( dev, addr ); } +/** \brief Writes an value to the register at \a addr. */ void vdev_write( VDevice *dev, int addr, byte val ) { dev->write( dev, addr, val ); } +/** \brief Resets a device. */ void vdev_reset( VDevice *dev ) { dev->reset( dev ); } -/* set the core field */ -void vdev_set_core( VDevice *dev, AvrClass *core ) { dev->core = (AvrClass *)core; } +/** \brief Set the core field. */ +void vdev_set_core( VDevice *dev, AvrClass *core ) +{ dev->core = (AvrClass *)core; } + +/** \brief Get the core field. */ AvrClass *vdev_get_core( VDevice *dev ) { return dev->core; } +/** \brief Get the device's base address. */ int vdev_get_base( VDevice *dev ) { return dev->base; } + +/** \brief Set the device's size (the number of bytes of the address space it + * consumes). */ int vdev_get_size( VDevice *dev ) { return dev->size; } +/** \brief Get the device's name. */ char *vdev_get_name( VDevice *dev ) { return dev->name; } -char *vdev_get_reg_name( VDevice *dev, int addr ) { return dev->reg_name( dev, addr ); } + +/** \brief Get the name of a device's register name associated with the given + address. */ +char *vdev_get_reg_name( VDevice *dev, int addr ) +{ return dev->reg_name( dev, addr ); }