- Main Page
- Related Pages
- Files

# devsupp.c

Go to the documentation of this file.

    00001 /*
    00002  * $Id: devsupp.c,v 1.30 2008/01/06 21:34:16 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_xram_sz (DevSuppDefn *dev)
    00207 {
    00208     return dev->size.xram;
    00209 }
    00210
    00211 /*
    00212  * Device Definitions
    00213  */
    00214
    00215 #define IN_DEVSUPP_C
    00216
    00217 #include "defn/90s1200.h"
    00218 #include "defn/90s2313.h"
    00219 #include "defn/90s4414.h"
    00220 #include "defn/90s8515.h"
    00221
    00222 #include "defn/mega8.h"
    00223 #include "defn/mega16.h"
    00224 #include "defn/mega32.h"
    00225 #include "defn/mega103.h"
    00226 #include "defn/mega128.h"
    00227
    00228 #include "defn/43usb320.h"
    00229 #include "defn/43usb325.h"
    00230 #include "defn/43usb326.h"
    00231
    00232 #include "defn/43usb351.h"
    00233 #include "defn/43usb353.h"
    00234 #include "defn/43usb355.h"
    00235
    00236 #undef IN_DEVSUPP_C
    00237
    00238 /** \brief List of supported devices. */
    00239
    00240 static DevSuppDefn *devices_supported[] = {
    00241     &defn_at90s1200,
    00242     &defn_at90s2313,
    00243     &defn_at90s4414,
    00244     &defn_at90s8515,
    00245     &defn_atmega8,
    00246     &defn_atmega16,
    00247     &defn_atmega32,
    00248     &defn_atmega103,
    00249     &defn_atmega128,
    00250     &defn_at43usb351,
    00251     &defn_at43usb353,
    00252     &defn_at43usb355,
    00253     &defn_at43usb320,
    00254     &defn_at43usb325,
    00255     &defn_at43usb326,
    00256     NULL
    00257 };
    00258
    00259 /**
    00260  * \brief Look up a device name in support list.
    00261  *
    00262  * \returns An opaque pointer to DevSuppDefn or NULL if not found.
    00263  */
    00264
    00265 DevSuppDefn *
    00266 dev_supp_lookup_device (char *dev_name)
    00267 {
    00268     DevSuppDefn **dev = devices_supported;
    00269     int len;
    00270
    00271     while ((*dev))
    00272     {
    00273         len = strlen ((*dev)->name);
    00274
    00275         if (strncmp ((*dev)->name, dev_name, len) == 0)
    00276             return (*dev);
    00277
    00278         dev++;
    00279     }
    00280     return NULL;
    00281 }
    00282
    00283 /** \brief Print a list of supported devices to a file pointer. */
    00284
    00285 void
    00286 dev_supp_list_devices (FILE * fp)
    00287 {
    00288     DevSuppDefn **dev;
    00289
    00290     for (dev = devices_supported; (*dev); dev++)
    00291         fprintf (fp, "  %s\n", (*dev)->name);
    00292 }
    00293
    00294 void
    00295 dev_supp_attach_io_regs (AvrCore *core, DevSuppDefn *dev)
    00296 {
    00297     VDevice *vdev;
    00298     struct io_reg_defn *reg = dev->io_reg;
    00299
    00300     while (reg->name)
    00301     {
    00302         if (reg->ref_addr)
    00303         {
    00304             if (reg->ref_addr < 0x20)
    00305             {
    00306                 avr_error ("can't attach IO reg into general register space");
    00307             }
    00308
    00309             /* Get the referenced vdev. */
    00310
    00311             vdev = avr_core_get_vdev_by_addr (core, reg->ref_addr);
    00312             if (vdev == NULL)
    00313             {
    00314                 /* This means that the implementor of the vdev screwed up. */
    00315                 avr_error ("reference vdev hasn't been created yet");
    00316             }
    00317
    00318             vdev_add_addr (vdev, reg->addr, reg->name, reg->related,
    00319                            reg->data);
    00320
    00321             avr_core_attach_vdev (core, reg->addr, reg->name, vdev, reg->flags,
    00322                                   reg->reset_value, reg->rd_mask,
    00323                                   reg->wr_mask);
    00324
    00325             avr_message ("attach: IO Reg '%s' at 0x%04x: ref = 0x%04x\n",
    00326                          reg->name, reg->addr, reg->ref_addr);
    00327         }
    00328
    00329         else if (reg->vdev_create)
    00330         {
    00331             vdev = reg->vdev_create (reg->addr, reg->name, reg->related,
    00332                                      reg->data);
    00333             avr_core_attach_vdev (core, reg->addr, reg->name, vdev, reg->flags,
    00334                                   reg->reset_value, reg->rd_mask,
    00335                                   reg->wr_mask);
    00336
    00337             /* Attaching implicitly references the device so we need to unref
    00338                the newly created vdev since we're done with it here. */
    00339             class_unref ((AvrClass *)vdev);
    00340
    00341             avr_message ("attach: IO Reg '%s' at 0x%04x: created\n",
    00342                          reg->name, reg->addr);
    00343         }
    00344
    00345         else
    00346         {
    00347             avr_message ("TODO: attach IO Reg '%s' at 0x%04x\n", reg->name,
    00348                          reg->addr);
    00349
    00350             avr_core_set_addr_name (core, reg->addr, reg->name);
    00351         }
    00352
    00353         reg++;
    00354     }
    00355 }

Automatically generated by Doxygen 1.5.5 on 7 Nov 2008.