Main Page

device.c
Go to the documentation of this file.
1 /*
2 * $Id: device.c,v 1.15 2004/01/30 07:09:56 troth Exp $
3 *
4 ****************************************************************************
5 *
6 * simulavr - A simulator for the Atmel AVR family of microcontrollers.
7 * Copyright (C) 2001, 2002, 2003, 2004 Theodore A. Roth
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 ****************************************************************************
24 */
25
26 #include <config.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "avrerror.h"
33 #include "avrmalloc.h"
34 #include "avrclass.h"
35 #include "utils.h"
36 #include "callback.h"
37 #include "op_names.h"
38
39 #include "storage.h"
40 #include "flash.h"
41
42 #include "vdevs.h"
43 #include "memory.h"
44 #include "stack.h"
45 #include "register.h"
46 #include "sram.h"
47 #include "eeprom.h"
48 #include "timers.h"
49 #include "ports.h"
50
51 #include "avrcore.h"
52
53 /** \file device.c
54 * \brief VDevice methods
55 *
56 * These functions are the base for all other devices
57 * mapped into the device space.
58 */
59
60 /** \brief Create a new VDevice. */
61 VDevice *
62 vdev_new (char *name, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset,
63 VDevFP_AddAddr add_addr)
64 {
65 VDevice *dev;
66
67 dev = avr_new0 (VDevice, 1);
68 vdev_construct (dev, rd, wr, reset, add_addr);
69 class_overload_destroy ((AvrClass *)dev, vdev_destroy);
70
71 return dev;
72 }
73
74 /** \brief Default AddAddr method.
75
76 This generate a warning that the should let the developer know that the
77 vdev needs to be updated. */
78
79 void
80 vdev_def_AddAddr (VDevice *dev, int addr, char *name, int related_addr,
81 void *data)
82 {
83 avr_warning ("Default AddAddr called [addr=0x%x; '%s']\n", addr, name);
84 }
85
86
87 /** \brief Constructor for a VDevice. */
88 void
89 vdev_construct (VDevice *dev, VDevFP_Read rd, VDevFP_Write wr,
90 VDevFP_Reset reset, VDevFP_AddAddr add_addr)
91 {
92 if (dev == NULL)
93 avr_error ("passed null ptr");
94
95 class_construct ((AvrClass *)dev);
96
97 dev->read = rd;
98 dev->write = wr;
99 dev->reset = reset;
100 dev->add_addr = add_addr;
101 }
102
103 /** \brief Destructor for a VDevice. */
104 void
105 vdev_destroy (void *dev)
106 {
107 if (dev == NULL)
108 return;
109
110 class_destroy (dev);
111 }
112
113 #if 0
114
115 /** \brief Compare the names of 2 devices
116 * \param c1 The first device.
117 * \param c2 is a string and not an AvrClass object, because this function is
118 * called by dlist_lookup() which passes two AvrClass pointers. So the string
119 * is casted to an *AvrClass.
120 */
121 int
122 vdev_name_cmp (AvrClass *c1, AvrClass *c2)
123 {
124 return strcmp (((VDevice *)c1)->name, (char *)c2);
125 }
126
127 #endif
128
129 #if 0
130 /** \brief Checks if a address is in the device's address range
131 * \param c1 \c AvrClass to check.
132 * \param c2 The address to check.
133 *
134 * \return The different between the device's address bounds and \a c2 or if
135 * \a c2 is within the address range 0.
136 *
137 * \note When comparing an addr, c2 is really just a pointer (see
138 * vdev_name_cmp() for details) to int and then we see if d1->base <= addr <
139 * (d1->base+d1->size).
140 */
141 int
142 vdev_addr_cmp (AvrClass *c1, AvrClass *c2)
143 {
144 VDevice *d1 = (VDevice *)c1;
145 int addr = *(int *)c2;
146
147 if (addr < d1->base)
148 return (addr - d1->base);
149
150 if (addr >= (d1->base + d1->size))
151 /* Add one to ensure we don't return zero. */
152 return (1 + addr - (d1->base + d1->size));
153
154 /* addr is in device's range */
155 return 0;
156 }
157 #endif
158
159 /** \brief Reads the device's value in the register at \a addr. */
160 uint8_t
161 vdev_read (VDevice *dev, int addr)
162 {
163 return dev->read (dev, addr);
164 }
165
166 /** \brief Writes an value to the register at \a addr. */
167 void
168 vdev_write (VDevice *dev, int addr, uint8_t val)
169 {
170 dev->write (dev, addr, val);
171 }
172
173 /** \brief Resets a device. */
174 void
175 vdev_reset (VDevice *dev)
176 {
177 dev->reset (dev);
178 }
179
180 /** \brief Set the core field. */
181 void
182 vdev_set_core (VDevice *dev, AvrClass *core)
183 {
184 dev->core = (AvrClass *)core;
185 }
186
187 /** \brief Get the core field. */
188 extern inline AvrClass *vdev_get_core (VDevice *dev);
189
190 /** \brief Inform the vdevice that it needs to handle another address.
191
192 This is primarily used when creating the core in dev_supp_create_core(). */
193
194 extern void
195 vdev_add_addr (VDevice *dev, int addr, char *name, int rel_addr, void *data)
196 {
197 if (dev->add_addr)
198 {
199 dev->add_addr (dev, addr, name, rel_addr, data);
200 }
201 else
202 {
203 avr_warning ("attempt to add addr to vdev with no add_addr() method: "
204 "%s [0x%04x]\n", name, addr);
205 }
206 }
207
208 #if 0
209 /** \brief Get the device's base address. */
210 int
211 vdev_get_base (VDevice *dev)
212 {
213 return dev->base;
214 }
215 #endif
216
217 #if 0
218 /** \brief Set the device's size (the number of bytes of the address space it
219 * consumes). */
220 int
221 vdev_get_size (VDevice *dev)
222 {
223 return dev->size;
224 }
225 #endif
226
227 #if 0
228 /** \brief Get the device's name. */
229 char *
230 vdev_get_name (VDevice *dev)
231 {
232 return dev->name;
233 }
234 #endif
vdev_add_addr
void vdev_add_addr(VDevice *dev, int addr, char *name, int rel_addr, void *data)
Inform the vdevice that it needs to handle another address.
Definition: device.c:195
vdev_def_AddAddr
void vdev_def_AddAddr(VDevice *dev, int addr, char *name, int related_addr, void *data)
Default AddAddr method.
Definition: device.c:80
vdev_destroy
void vdev_destroy(void *dev)
Destructor for a VDevice.
Definition: device.c:105
vdev_get_core
AvrClass * vdev_get_core(VDevice *dev)
Get the core field.
class_destroy
void class_destroy(void *klass)
Releases resources allocated by class&#39;s <klass>_new() function.
Definition: avrclass.c:78
avr_warning
#define avr_warning(fmt, args...)
Print a warning message to stderr.
Definition: avrerror.c:46
vdev_construct
void vdev_construct(VDevice *dev, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_AddAddr add_addr)
Constructor for a VDevice.
Definition: device.c:89
avr_error
#define avr_error(fmt, args...)
Print an error message to stderr and terminate program.
Definition: avrerror.c:50
vdev_new
VDevice * vdev_new(char *name, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_AddAddr add_addr)
Create a new VDevice.
Definition: device.c:62
vdev_read
uint8_t vdev_read(VDevice *dev, int addr)
Reads the device&#39;s value in the register at addr.
Definition: device.c:161
class_overload_destroy
void class_overload_destroy(AvrClass *klass, AvrClassFP_Destroy destroy)
Overload the default destroy method.
Definition: avrclass.c:92
class_construct
void class_construct(AvrClass *klass)
Initializes the AvrClass data structure.
Definition: avrclass.c:61
avr_new0
#define avr_new0(type, count)
Macro for allocating memory and initializing it to zero.
Definition: avrmalloc.c:67
vdev_set_core
void vdev_set_core(VDevice *dev, AvrClass *core)
Set the core field.
Definition: device.c:182
vdev_reset
void vdev_reset(VDevice *dev)
Resets a device.
Definition: device.c:175
vdev_write
void vdev_write(VDevice *dev, int addr, uint8_t val)
Writes an value to the register at addr.
Definition: device.c:168

Automatically generated by Doxygen 1.8.12 on Sun Apr 2 2017.