Main Page | File List | Globals | Related Pages

device.c

Go to the documentation of this file.
00001 /* 00002 * $Id: device.c,v 1.14 2003/12/02 08:25:00 troth Exp $ 00003 * 00004 **************************************************************************** 00005 * 00006 * simulavr - A simulator for the Atmel AVR family of microcontrollers. 00007 * Copyright (C) 2001, 2002, 2003 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, int base, int size, VDevFP_Read rd, VDevFP_Write wr, 00063 VDevFP_Reset reset, VDevFP_RegName reg_name) 00064 { 00065 VDevice *dev; 00066 00067 dev = avr_new (VDevice, 1); 00068 vdev_construct (dev, name, base, size, rd, wr, reset, reg_name); 00069 class_overload_destroy ((AvrClass *)dev, vdev_destroy); 00070 00071 return dev; 00072 } 00073 00074 /** \brief Constructor for a VDevice. */ 00075 void 00076 vdev_construct (VDevice *dev, char *name, int base, int size, VDevFP_Read rd, 00077 VDevFP_Write wr, VDevFP_Reset reset, VDevFP_RegName reg_name) 00078 { 00079 if (dev == NULL) 00080 avr_error ("passed null ptr"); 00081 00082 class_construct ((AvrClass *)dev); 00083 00084 dev->name = name; /* This should be a static string, so don't 00085 need to free */ 00086 dev->base = base; 00087 dev->size = size; 00088 00089 dev->read = rd; 00090 dev->write = wr; 00091 dev->reset = reset; 00092 dev->reg_name = reg_name; 00093 } 00094 00095 /** \brief Destructor for a VDevice. */ 00096 void 00097 vdev_destroy (void *dev) 00098 { 00099 if (dev == NULL) 00100 return; 00101 00102 class_destroy (dev); 00103 } 00104 00105 /** \brief Compare the names of 2 devices 00106 * \param c1 The first device. 00107 * \param c2 is a string and not an AvrClass object, because this function is 00108 * called by dlist_lookup() which passes two AvrClass pointers. So the string 00109 * is casted to an *AvrClass. 00110 */ 00111 int 00112 vdev_name_cmp (AvrClass *c1, AvrClass *c2) 00113 { 00114 return strcmp (((VDevice *)c1)->name, (char *)c2); 00115 } 00116 00117 /** \brief Checks if a address is in the device's address range 00118 * \param c1 \c AvrClass to check. 00119 * \param c2 The address to check. 00120 * 00121 * \return The different between the device's address bounds and \a c2 or if 00122 * \a c2 is within the address range 0. 00123 * 00124 * \note When comparing an addr, c2 is really just a pointer (see 00125 * vdev_name_cmp() for details) to int and then we see if d1->base <= addr < 00126 * (d1->base+d1->size). 00127 */ 00128 int 00129 vdev_addr_cmp (AvrClass *c1, AvrClass *c2) 00130 { 00131 VDevice *d1 = (VDevice *)c1; 00132 int addr = *(int *)c2; 00133 00134 if (addr < d1->base) 00135 return (addr - d1->base); 00136 00137 if (addr >= (d1->base + d1->size)) 00138 /* Add one to ensure we don't return zero. */ 00139 return (1 + addr - (d1->base + d1->size)); 00140 00141 /* addr is in device's range */ 00142 return 0; 00143 } 00144 00145 /** \brief Reads the device's value in the register at \a addr. */ 00146 uint8_t 00147 vdev_read (VDevice *dev, int addr) 00148 { 00149 return dev->read (dev, addr); 00150 } 00151 00152 /** \brief Writes an value to the register at \a addr. */ 00153 void 00154 vdev_write (VDevice *dev, int addr, uint8_t val) 00155 { 00156 dev->write (dev, addr, val); 00157 } 00158 00159 /** \brief Resets a device. */ 00160 void 00161 vdev_reset (VDevice *dev) 00162 { 00163 dev->reset (dev); 00164 } 00165 00166 /** \brief Set the core field. */ 00167 void 00168 vdev_set_core (VDevice *dev, AvrClass *core) 00169 { 00170 dev->core = (AvrClass *)core; 00171 } 00172 00173 /** \brief Get the core field. */ 00174 extern inline AvrClass *vdev_get_core (VDevice *dev); 00175 00176 /** \brief Get the device's base address. */ 00177 int 00178 vdev_get_base (VDevice *dev) 00179 { 00180 return dev->base; 00181 } 00182 00183 /** \brief Set the device's size (the number of bytes of the address space it 00184 * consumes). */ 00185 int 00186 vdev_get_size (VDevice *dev) 00187 { 00188 return dev->size; 00189 } 00190 00191 /** \brief Get the device's name. */ 00192 char * 00193 vdev_get_name (VDevice *dev) 00194 { 00195 return dev->name; 00196 } 00197 00198 /** \brief Get the name of a device's register name associated with the given 00199 address. */ 00200 char * 00201 vdev_get_reg_name (VDevice *dev, int addr) 00202 { 00203 return dev->reg_name (dev, addr); 00204 }

Automatically generated by Doxygen 1.3.8 on 11 Aug 2004.