Main Page

- Main Page
- Related Pages
- Files

- File List
- Globals

# device.c

Go to the documentation of this file.

    00001 /*
    00002  * $Id: device.c,v 1.15 2004/01/30 07:09:56 troth Exp $
    00003  *
    00004  ****************************************************************************
    00005  *
    00006  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
    00007  * Copyright (C) 2001, 2002, 2003, 2004  Theodore A. Roth
    00008  *
    00009  * This program is free software; you can redistribute it and/or modify
    00010  * it under the terms of the GNU General Public License as published by
    00011  * the Free Software Foundation; either version 2 of the License, or
    00012  * (at your option) any later version.
    00013  *
    00014  * This program is distributed in the hope that it will be useful,
    00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00017  * GNU General Public License for more details.
    00018  *
    00019  * You should have received a copy of the GNU General Public License
    00020  * along with this program; if not, write to the Free Software
    00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00022  *
    00023  ****************************************************************************
    00024  */
    00025
    00026 #include <config.h>
    00027
    00028 #include <stdio.h>
    00029 #include <stdlib.h>
    00030 #include <string.h>
    00031
    00032 #include "avrerror.h"
    00033 #include "avrmalloc.h"
    00034 #include "avrclass.h"
    00035 #include "utils.h"
    00036 #include "callback.h"
    00037 #include "op_names.h"
    00038
    00039 #include "storage.h"
    00040 #include "flash.h"
    00041
    00042 #include "vdevs.h"
    00043 #include "memory.h"
    00044 #include "stack.h"
    00045 #include "register.h"
    00046 #include "sram.h"
    00047 #include "eeprom.h"
    00048 #include "timers.h"
    00049 #include "ports.h"
    00050
    00051 #include "avrcore.h"
    00052
    00053 /** \file device.c
    00054   * \brief VDevice methods
    00055   *
    00056   * These functions are the base for all other devices
    00057   * mapped into the device space.
    00058   */
    00059
    00060 /** \brief Create a new VDevice. */
    00061 VDevice *
    00062 vdev_new (char *name, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset,
    00063           VDevFP_AddAddr add_addr)
    00064 {
    00065     VDevice *dev;
    00066
    00067     dev = avr_new0 (VDevice, 1);
    00068     vdev_construct (dev, rd, wr, reset, add_addr);
    00069     class_overload_destroy ((AvrClass *)dev, vdev_destroy);
    00070
    00071     return dev;
    00072 }
    00073
    00074 /** \brief Default AddAddr method.
    00075
    00076     This generate a warning that the should let the developer know that the
    00077     vdev needs to be updated. */
    00078
    00079 void
    00080 vdev_def_AddAddr (VDevice *dev, int addr, char *name, int related_addr,
    00081                   void *data)
    00082 {
    00083     avr_warning ("Default AddAddr called [addr=0x%x; '%s']\n", addr, name);
    00084 }
    00085
    00086
    00087 /** \brief Constructor for a VDevice. */
    00088 void
    00089 vdev_construct (VDevice *dev, VDevFP_Read rd, VDevFP_Write wr,
    00090                 VDevFP_Reset reset, VDevFP_AddAddr add_addr)
    00091 {
    00092     if (dev == NULL)
    00093         avr_error ("passed null ptr");
    00094
    00095     class_construct ((AvrClass *)dev);
    00096
    00097     dev->read = rd;
    00098     dev->write = wr;
    00099     dev->reset = reset;
    00100     dev->add_addr = add_addr;
    00101 }
    00102
    00103 /** \brief Destructor for a VDevice. */
    00104 void
    00105 vdev_destroy (void *dev)
    00106 {
    00107     if (dev == NULL)
    00108         return;
    00109
    00110     class_destroy (dev);
    00111 }
    00112
    00113 #if 0
    00114
    00115 /** \brief Compare the names of 2 devices
    00116   * \param c1 The first device.
    00117   * \param c2 is a string and not an AvrClass object, because this function is
    00118   * called by dlist_lookup() which passes two AvrClass pointers. So the string
    00119   * is casted to an *AvrClass.
    00120   */
    00121 int
    00122 vdev_name_cmp (AvrClass *c1, AvrClass *c2)
    00123 {
    00124     return strcmp (((VDevice *)c1)->name, (char *)c2);
    00125 }
    00126
    00127 #endif
    00128
    00129 #if 0
    00130 /** \brief Checks if a address is in the device's address range
    00131   * \param c1 \c AvrClass to check.
    00132   * \param c2 The address to check.
    00133   *
    00134   * \return The different between the device's address bounds and \a c2 or if
    00135   * \a c2 is within the address range 0.
    00136   *
    00137   * \note When comparing an addr, c2 is really just a pointer (see
    00138   * vdev_name_cmp() for details) to int and then we see if d1->base <= addr <
    00139   * (d1->base+d1->size).
    00140   */
    00141 int
    00142 vdev_addr_cmp (AvrClass *c1, AvrClass *c2)
    00143 {
    00144     VDevice *d1 = (VDevice *)c1;
    00145     int addr = *(int *)c2;
    00146
    00147     if (addr < d1->base)
    00148         return (addr - d1->base);
    00149
    00150     if (addr >= (d1->base + d1->size))
    00151         /* Add one to ensure we don't return zero. */
    00152         return (1 + addr - (d1->base + d1->size));
    00153
    00154     /* addr is in device's range */
    00155     return 0;
    00156 }
    00157 #endif
    00158
    00159 /** \brief Reads the device's value in the register at \a addr. */
    00160 uint8_t
    00161 vdev_read (VDevice *dev, int addr)
    00162 {
    00163     return dev->read (dev, addr);
    00164 }
    00165
    00166 /** \brief Writes an value to the register at \a addr. */
    00167 void
    00168 vdev_write (VDevice *dev, int addr, uint8_t val)
    00169 {
    00170     dev->write (dev, addr, val);
    00171 }
    00172
    00173 /** \brief Resets a device. */
    00174 void
    00175 vdev_reset (VDevice *dev)
    00176 {
    00177     dev->reset (dev);
    00178 }
    00179
    00180 /** \brief Set the core field. */
    00181 void
    00182 vdev_set_core (VDevice *dev, AvrClass *core)
    00183 {
    00184     dev->core = (AvrClass *)core;
    00185 }
    00186
    00187 /** \brief Get the core field. */
    00188 extern inline AvrClass *vdev_get_core (VDevice *dev);
    00189
    00190 /** \brief Inform the vdevice that it needs to handle another address.
    00191
    00192     This is primarily used when creating the core in dev_supp_create_core(). */
    00193
    00194 extern void
    00195 vdev_add_addr (VDevice *dev, int addr, char *name, int rel_addr, void *data)
    00196 {
    00197     if (dev->add_addr)
    00198     {
    00199         dev->add_addr (dev, addr, name, rel_addr, data);
    00200     }
    00201     else
    00202     {
    00203         avr_warning ("attempt to add addr to vdev with no add_addr() method: "
    00204                      "%s [0x%04x]\n", name, addr);
    00205     }
    00206 }
    00207
    00208 #if 0
    00209 /** \brief Get the device's base address. */
    00210 int
    00211 vdev_get_base (VDevice *dev)
    00212 {
    00213     return dev->base;
    00214 }
    00215 #endif
    00216
    00217 #if 0
    00218 /** \brief Set the device's size (the number of bytes of the address space it
    00219  *  consumes). */
    00220 int
    00221 vdev_get_size (VDevice *dev)
    00222 {
    00223     return dev->size;
    00224 }
    00225 #endif
    00226
    00227 #if 0
    00228 /** \brief Get the device's name. */
    00229 char *
    00230 vdev_get_name (VDevice *dev)
    00231 {
    00232     return dev->name;
    00233 }
    00234 #endif

Automatically generated by Doxygen 1.7.2 on Wed Aug 15 2012.