Main Page

- Main Page
- Related Pages
- Files

- File List
- Globals

# devsupp.c

Go to the documentation of this file.

    00001 /*
    00002  * $Id: devsupp.c,v 1.31 2008/03/19 22:39:01 joerg_wunsch 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 /**
    00027  * \file devsupp.c
    00028  * \brief Contains definitions for device types (i.e. at90s8515, at90s2313,
    00029  * etc.)
    00030  *
    00031  * This module is used to define the attributes for each device in the AVR
    00032  * family. A generic constructor is used to create a new AvrCore object with
    00033  * the proper ports, built-in peripherals, memory layout, registers, and
    00034  * interrupt vectors, etc.
    00035  */
    00036
    00037 #include <config.h>
    00038
    00039 #include <stdio.h>
    00040 #include <stdlib.h>
    00041 #include <string.h>
    00042
    00043 #include "avrerror.h"
    00044 #include "avrmalloc.h"
    00045 #include "avrclass.h"
    00046 #include "utils.h"
    00047 #include "callback.h"
    00048 #include "op_names.h"
    00049
    00050 #include "storage.h"
    00051 #include "flash.h"
    00052
    00053 #include "vdevs.h"
    00054 #include "memory.h"
    00055 #include "stack.h"
    00056 #include "register.h"
    00057 #include "sram.h"
    00058 #include "eeprom.h"
    00059 #include "timers.h"
    00060 #include "ports.h"
    00061 #include "spi.h"
    00062 #include "adc.h"
    00063 #include "usb.h"
    00064 #include "uart.h"
    00065
    00066 #include "avrcore.h"
    00067
    00068 #include "devsupp.h"
    00069
    00070 #ifndef DOXYGEN                 /* don't expose to doxygen */
    00071
    00072 /*
    00073  * Used to select which vector table the device uses.
    00074  * The value is an index into the global_vtable_list[] array
    00075  * defined in intvects.c.
    00076  */
    00077 enum _vector_table_select
    00078 {
    00079     VTAB_AT90S1200 = 0,
    00080     VTAB_AT90S2313,
    00081     VTAB_AT90S4414,
    00082     VTAB_ATMEGA8,
    00083     VTAB_ATMEGA16,
    00084     VTAB_ATMEGA32,
    00085     VTAB_ATMEGA103,
    00086     VTAB_ATMEGA128,
    00087     VTAB_AT43USB355,
    00088     VTAB_AT43USB320,
    00089     VTAB_AT43USB325,
    00090     VTAB_AT43USB326,
    00091 };
    00092
    00093 /* IO Register Definition.  */
    00094
    00095 struct io_reg_defn {
    00096     uint16_t addr;              /* The address of the register (in memory
    00097                                    space, not IO space). */
    00098     char *name;                 /* The register name as given by the
    00099                                    datasheet. */
    00100     uint16_t ref_addr;          /* Use the vdev reference at the given
    00101                                    address.  If not zero, use the same vdev
    00102                                    pointer at the given register address. The
    00103                                    vdev must have already been created at that
    00104                                    address.  Remember that address zero is
    00105                                    General Register 0 which is not an IO
    00106                                    register. This value should never be less
    00107                                    than 0x20. */
    00108     uint16_t related;           /* A related address. For example, if a device
    00109                                    has more than one timer, each timer has
    00110                                    it's own instance of the timer vdev, but
    00111                                    all timers need access to the TIMSK
    00112                                    register which should have the addr
    00113                                    specified here. There might be more than
    00114                                    one related address for a vdev, so this may
    00115                                    need to become an array. */
    00116     VDevCreate vdev_create;     /* The vdev creation function to be used to
    00117                                    create the vdev. Note that this should be a
    00118                                    wrapper around the vdev's new method. This
    00119                                    field is ignored if rel_addr is greater
    00120                                    than 0x1f. */
    00121     void *data;                 /* Optional data that may be needed by the
    00122                                    vdev. May be address specific too. */
    00123     int flags;                  /* Flags that can change the behaviour of the
    00124                                    value. (e.g. FL_SET_ON_RESET) */
    00125     uint8_t reset_value;        /* Initialize the register to this value after
    00126                                    reset. */
    00127
    00128     /* These should handle PORT width automagically. */
    00129
    00130     uint8_t rd_mask;            /* Mask of the readable bits in the
    00131                                    register. */
    00132     uint8_t wr_mask;            /* Mask of the writable bits in the
    00133                                    register. */
    00134 };
    00135
    00136 #define IO_REG_DEFN_TERMINATOR { .name = NULL, }
    00137
    00138 /* Structure for defining a supported device */
    00139
    00140 struct _DevSuppDefn
    00141 {
    00142     char *name;                 /* name of device type */
    00143
    00144     StackType stack_type;       /* STACK_HARDWARE or STACK_MEMORY */
    00145     int has_ext_io_reg;         /* does the device have extened IO registers */
    00146     int irq_vect_idx;           /* interrupt vector table index */
    00147
    00148     struct
    00149     {
    00150         int pc;                 /* width of program counter (usually 2, maybe
    00151                                    3) */
    00152         int stack;              /* depth of stack (only used by hardware
    00153                                    stack) */
    00154         int flash;              /* bytes of flash memory */
    00155         int sram;               /* bytes of sram memory */
    00156         int eeprom;             /* bytes of eeprom memory */
    00157         int xram;               /* bytes of external SRAM supported */
    00158     } size;
    00159
    00160     /* This _must_ be the last field of the structure since it is a variable
    00161        length array. (This is new in C99.) */
    00162
    00163     struct io_reg_defn io_reg[]; /* Definitions for for all the IO registers
    00164                                     the device provides. */
    00165 };
    00166
    00167 #endif /* DOXYGEN */
    00168
    00169 int
    00170 dev_supp_has_ext_io_reg (DevSuppDefn *dev)
    00171 {
    00172     return dev->has_ext_io_reg;
    00173 }
    00174
    00175 int
    00176 dev_supp_get_flash_sz (DevSuppDefn *dev)
    00177 {
    00178     return dev->size.flash;
    00179 }
    00180
    00181 int
    00182 dev_supp_get_PC_sz (DevSuppDefn *dev)
    00183 {
    00184     return dev->size.pc;
    00185 }
    00186
    00187 int
    00188 dev_supp_get_stack_sz (DevSuppDefn *dev)
    00189 {
    00190     return dev->size.stack;
    00191 }
    00192
    00193 int
    00194 dev_supp_get_vtab_idx (DevSuppDefn *dev)
    00195 {
    00196     return dev->irq_vect_idx;
    00197 }
    00198
    00199 int
    00200 dev_supp_get_sram_sz (DevSuppDefn *dev)
    00201 {
    00202     return dev->size.sram;
    00203 }
    00204
    00205 int
    00206 dev_supp_get_eeprom_sz (DevSuppDefn *dev)
    00207 {
    00208     return dev->size.eeprom;
    00209 }
    00210
    00211 int
    00212 dev_supp_get_xram_sz (DevSuppDefn *dev)
    00213 {
    00214     return dev->size.xram;
    00215 }
    00216
    00217 /*
    00218  * Device Definitions
    00219  */
    00220
    00221 #define IN_DEVSUPP_C
    00222
    00223 #include "defn/90s1200.h"
    00224 #include "defn/90s2313.h"
    00225 #include "defn/90s4414.h"
    00226 #include "defn/90s8515.h"
    00227
    00228 #include "defn/mega8.h"
    00229 #include "defn/mega16.h"
    00230 #include "defn/mega32.h"
    00231 #include "defn/mega103.h"
    00232 #include "defn/mega128.h"
    00233
    00234 #include "defn/43usb320.h"
    00235 #include "defn/43usb325.h"
    00236 #include "defn/43usb326.h"
    00237
    00238 #include "defn/43usb351.h"
    00239 #include "defn/43usb353.h"
    00240 #include "defn/43usb355.h"
    00241
    00242 #undef IN_DEVSUPP_C
    00243
    00244 /** \brief List of supported devices. */
    00245
    00246 static DevSuppDefn *devices_supported[] = {
    00247     &defn_at90s1200,
    00248     &defn_at90s2313,
    00249     &defn_at90s4414,
    00250     &defn_at90s8515,
    00251     &defn_atmega8,
    00252     &defn_atmega16,
    00253     &defn_atmega32,
    00254     &defn_atmega103,
    00255     &defn_atmega128,
    00256     &defn_at43usb351,
    00257     &defn_at43usb353,
    00258     &defn_at43usb355,
    00259     &defn_at43usb320,
    00260     &defn_at43usb325,
    00261     &defn_at43usb326,
    00262     NULL
    00263 };
    00264
    00265 /**
    00266  * \brief Look up a device name in support list.
    00267  *
    00268  * \returns An opaque pointer to DevSuppDefn or NULL if not found.
    00269  */
    00270
    00271 DevSuppDefn *
    00272 dev_supp_lookup_device (char *dev_name)
    00273 {
    00274     DevSuppDefn **dev = devices_supported;
    00275     int len;
    00276
    00277     while ((*dev))
    00278     {
    00279         len = strlen ((*dev)->name);
    00280
    00281         if (strncmp ((*dev)->name, dev_name, len) == 0)
    00282             return (*dev);
    00283
    00284         dev++;
    00285     }
    00286     return NULL;
    00287 }
    00288
    00289 /** \brief Print a list of supported devices to a file pointer. */
    00290
    00291 void
    00292 dev_supp_list_devices (FILE * fp)
    00293 {
    00294     DevSuppDefn **dev;
    00295
    00296     for (dev = devices_supported; (*dev); dev++)
    00297         fprintf (fp, "  %s\n", (*dev)->name);
    00298 }
    00299
    00300 void
    00301 dev_supp_attach_io_regs (AvrCore *core, DevSuppDefn *dev)
    00302 {
    00303     VDevice *vdev;
    00304     struct io_reg_defn *reg = dev->io_reg;
    00305
    00306     while (reg->name)
    00307     {
    00308         if (reg->ref_addr)
    00309         {
    00310             if (reg->ref_addr < 0x20)
    00311             {
    00312                 avr_error ("can't attach IO reg into general register space");
    00313             }
    00314
    00315             /* Get the referenced vdev. */
    00316
    00317             vdev = avr_core_get_vdev_by_addr (core, reg->ref_addr);
    00318             if (vdev == NULL)
    00319             {
    00320                 /* This means that the implementor of the vdev screwed up. */
    00321                 avr_error ("reference vdev hasn't been created yet");
    00322             }
    00323
    00324             vdev_add_addr (vdev, reg->addr, reg->name, reg->related,
    00325                            reg->data);
    00326
    00327             avr_core_attach_vdev (core, reg->addr, reg->name, vdev, reg->flags,
    00328                                   reg->reset_value, reg->rd_mask,
    00329                                   reg->wr_mask);
    00330
    00331             avr_message ("attach: IO Reg '%s' at 0x%04x: ref = 0x%04x\n",
    00332                          reg->name, reg->addr, reg->ref_addr);
    00333         }
    00334
    00335         else if (reg->vdev_create)
    00336         {
    00337             vdev = reg->vdev_create (reg->addr, reg->name, reg->related,
    00338                                      reg->data);
    00339             avr_core_attach_vdev (core, reg->addr, reg->name, vdev, reg->flags,
    00340                                   reg->reset_value, reg->rd_mask,
    00341                                   reg->wr_mask);
    00342
    00343             /* Attaching implicitly references the device so we need to unref
    00344                the newly created vdev since we're done with it here. */
    00345             class_unref ((AvrClass *)vdev);
    00346
    00347             avr_message ("attach: IO Reg '%s' at 0x%04x: created\n",
    00348                          reg->name, reg->addr);
    00349         }
    00350
    00351         else
    00352         {
    00353             avr_message ("TODO: attach IO Reg '%s' at 0x%04x\n", reg->name,
    00354                          reg->addr);
    00355
    00356             avr_core_set_addr_name (core, reg->addr, reg->name);
    00357         }
    00358
    00359         reg++;
    00360     }
    00361 }

Automatically generated by Doxygen 1.7.2 on Wed Feb 22 2012.