[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Simulavr-devel] ADC Patch
From: |
Keith Gudger |
Subject: |
[Simulavr-devel] ADC Patch |
Date: |
Thu, 13 Nov 2003 12:08:33 -0800 (PST) |
Ted:
Attached are the files needed to patch in the ADC. The adc.diff file
covers the changes to the devsupp.c file. Note that the atmega103 is the
only non-USB part in the list with an ADC. Also note that since the USB
parts have slightly different I/O addresses, the fact that a part supports
USB needs to get passed to the adc device creations. That is why the
usb.h file is attached.
Keith
? simulavr/devsupp.diff
? simulavr/src_old
? simulavr/src/config.h
? simulavr/src/sa_kg3.zip
Index: simulavr/src/devsupp.c
===================================================================
RCS file: /cvsroot/simulavr/simulavr/src/devsupp.c,v
retrieving revision 1.17
diff -u -r1.17 devsupp.c
--- simulavr/src/devsupp.c 13 Nov 2003 07:34:24 -0000 1.17
+++ simulavr/src/devsupp.c 13 Nov 2003 19:48:07 -0000
@@ -57,6 +57,8 @@
#include "eeprom.h"
#include "timers.h"
#include "ports.h"
+#include "adc.h"
+#include "usb.h"
#include "avrcore.h"
@@ -113,6 +115,8 @@
uint8_t acsr;
uint8_t wdtcr;
uint8_t timsk;
+ uint8_t adcsr;
+ uint8_t uier;
} mask;
};
@@ -142,7 +146,9 @@
/* mask.mcucr */ (mask_SE | mask_SM | mask_ISC01 | mask_ISC00),
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE | mask_ACIS1
| mask_ACIS0),
/* mask.wdtcr */ (mask_WDE | mask_WDP2 | mask_WDP1 | mask_WDP0),
- /* mask.timsk */ (mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -169,7 +175,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_TICIE1 | mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_TICIE1 | mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -196,7 +204,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -223,7 +233,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -249,7 +261,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -276,7 +290,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -303,7 +319,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ (mask_ADEN),
+ /* mask.uier */ 0
}
};
@@ -330,7 +348,9 @@
/* mask.acsr */ (mask_ACD | mask_ACO | mask_ACI | mask_ACIE |
mask_ACIC | mask_ACIS1 | mask_ACIS0),
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1 |
mask_WDP0),
- /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0)
+ /* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1 |
mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ 0
}
};
@@ -357,7 +377,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ (mask_ADEN),
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_FEP3)
}
};
@@ -384,7 +406,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ (mask_ADEN),
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_FEP3 |
mask_HEP0)
}
};
@@ -411,7 +435,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ (mask_ADEN),
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_FEP3 |
mask_HEP0)
}
};
@@ -438,7 +464,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_FEP3 |
mask_HEP0)
}
};
@@ -465,7 +493,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_HEP0)
}
};
@@ -492,7 +522,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_FEP3 |
mask_HEP0)
}
};
@@ -519,7 +551,9 @@
/* mask.wdtcr */ (mask_WDTOE | mask_WDE | mask_WDP2 | mask_WDP1
| mask_WDP0),
/* mask.timsk */ (mask_TOIE1 | mask_OCIE1A | mask_OCIE1B | mask_TICIE1
- | mask_TOIE0)
+ | mask_TOIE0),
+ /* mask.adcsr */ 0,
+ /* mask.uier */ (mask_FEP0 | mask_FEP1 | mask_FEP2 | mask_HEP0)
}
};
@@ -666,7 +700,15 @@
}
}
- /* Attach device port vdevs */
+ if (dev->mask.adcsr)
+ {
+ vdev = (VDevice *)adc_intr_new(dev->mask.uier);
+ avr_core_attach_vdev( core, vdev );
+ vdev = (VDevice *)adc_new(dev->mask.uier);
+ avr_core_attach_vdev( core, vdev );
+ }
+
+ /* Attach device port vdevs */
pp = dev->ports;
while (*pp)
/*
* $Id: adc.c,v 1.9 2003/11/07 22:22:34 kgudger Exp $
*
****************************************************************************
*
* simulavr - A simulator for the Atmel AVR family of microcontrollers.
* Copyright (C) 2001, 2002 Theodore A. Roth
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
****************************************************************************
*/
/**
* \file adc.c
* \brief Module to simulate the AVR's ADC module.
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "avrerror.h"
#include "avrmalloc.h"
#include "avrclass.h"
#include "utils.h"
#include "callback.h"
#include "op_names.h"
#include "storage.h"
#include "flash.h"
#include "vdevs.h"
#include "memory.h"
#include "stack.h"
#include "register.h"
#include "sram.h"
#include "eeprom.h"
#include "timers.h"
#include "ports.h"
#include "adc.h"
#include "avrcore.h"
#include "intvects.h"
/******************************************************************************\
*
* ADC Interrupts
*
\******************************************************************************/
static uint8_t adc_intr_read ( VDevice *dev, int addr );
static void adc_intr_write ( VDevice *dev, int addr, uint8_t val );
static void adc_intr_reset ( VDevice *dev );
static char *adc_intr_reg_name ( VDevice *dev , int addr );
static int adc_intr_cb( uint64_t time, AvrClass *data ) ;
static int adc_clk_incr_cb( uint64_t ck, AvrClass *data );
/** \brief Allocate a new ADC interrupt */
ADCIntr_T *adc_intr_new( uint8_t uier )
{
ADCIntr_T *adc;
adc = avr_new( ADCIntr_T, 1 );
adc_intr_construct( adc, uier );
class_overload_destroy( (AvrClass *)adc, adc_intr_destroy );
return adc;
}
/** \brief Constructor for adc interrupt object. */
void adc_intr_construct( ADCIntr_T *adc, uint8_t uier )
{
char *name = "ADCIntr";
if (adc == NULL)
avr_error( "passed null ptr" );
if ( uier )
vdev_construct( (VDevice *)adc, name, ADC_INTR_BASE_U, ADC_INTR_SIZE,
adc_intr_read, adc_intr_write, adc_intr_reset,
adc_intr_reg_name );
else
vdev_construct( (VDevice *)adc, name, ADC_INTR_BASE_A, ADC_INTR_SIZE,
adc_intr_read, adc_intr_write, adc_intr_reset,
adc_intr_reg_name );
adc_intr_reset( (VDevice*)adc );
}
/** \brief Destructor for adc interrupt object. */
void adc_intr_destroy( void *adc )
{
if (adc == NULL)
return;
vdev_destroy( adc );
}
static uint8_t adc_intr_read( VDevice *dev, int addr )
{
ADCIntr_T *adc = (ADCIntr_T *)dev;
switch ( addr - vdev_get_base(dev) ) {
case ADC_INTR_ADCSR_ADDR : return (adc->adcsr );
case ADC_INTR_ADMUX_ADDR : return (adc->admux );
default:
avr_error( "Bad address: 0x%04x", addr );
}
return 0; /* will never get here */
}
static void adc_intr_write( VDevice *dev, int addr, uint8_t val )
{
ADCIntr_T *adc = (ADCIntr_T *)dev;
CallBack *cb;
ADC_T *adc_d;
adc_d = (ADC_T *)avr_core_get_vdev_by_name( (AvrCore
*)vdev_get_core((VDevice *)adc),
"ADC" );
switch ( addr - vdev_get_base(dev) ) {
case ADC_INTR_ADCSR_ADDR :
if ( val & mask_ADIF ) /* clears interrupt flag */
adc->adcsr = val & ~mask_ADIF ;
else
adc->adcsr = val ;
if ( ( val & mask_ADSC ) && ( val & mask_ADEN ) )
{
if ( ( adc->intr_cb == NULL ) )
{
/* we need to install the intr_cb function */
cb = callback_new( adc_intr_cb, (AvrClass *)adc );
adc->intr_cb = cb;
avr_core_async_cb_add( (AvrCore *)vdev_get_core(dev), cb );
}
if ( ( adc_d->clk_cb == NULL ) )
{
/* we need to install the clk_cb function */
cb = callback_new( adc_clk_incr_cb, (AvrClass *)adc_d );
adc_d->clk_cb = cb;
avr_core_clk_cb_add( (AvrCore *)vdev_get_core(dev), cb );
}
adc_d->adc_count = 13 ;
switch ( (adc->adcsr) & (mask_ADPS0 | mask_ADPS1 | mask_ADPS2)
) {
case ADC_CK_0:
case ADC_CK_2:
adc_d->divisor = 2;
break;
case ADC_CK_4:
adc_d->divisor = 4;
break;
case ADC_CK_8:
adc_d->divisor = 8;
break;
case ADC_CK_16:
adc_d->divisor = 16;
break;
case ADC_CK_32:
adc_d->divisor = 32;
break;
case ADC_CK_64:
adc_d->divisor = 64;
break;
case ADC_CK_128:
adc_d->divisor = 128;
break;
default:
avr_error( "The impossible happened!" );
}
}
else
{
adc->intr_cb = NULL; /* no interrupt are enabled, remove the
callback */
}
break;
case ADC_INTR_ADMUX_ADDR : adc->admux = val ; break ;
default:
avr_error( "Bad address: 0x%04x", addr );
}
}
static void adc_intr_reset( VDevice *dev )
{
ADCIntr_T *adc = (ADCIntr_T *)dev;
adc->intr_cb = NULL;
adc->adcsr = 0;
adc->admux = 0 ;
}
static char *adc_intr_reg_name( VDevice *dev , int addr )
{
switch ( addr - vdev_get_base(dev) ) {
case ADC_INTR_ADCSR_ADDR : return ("ADSCR" );
case ADC_INTR_ADMUX_ADDR : return ("ADMUX" );
default:
avr_error( "Bad address: 0x%04x", addr );
}
return NULL; /* will never get here */
}
static int adc_intr_cb( uint64_t time, AvrClass *data )
{
ADCIntr_T *adc = (ADCIntr_T *)data;
if ( adc->intr_cb == NULL )
return CB_RET_REMOVE;
if ( ( adc->adcsr & mask_ADEN ) && ( adc->adcsr & mask_ADIE ) &&
( adc->adcsr & mask_ADIF )) /* an enabled interrupt occured */
{
AvrCore *core = (AvrCore *)vdev_get_core((VDevice *)adc);
avr_core_irq_raise( core, irq_vect_table_index(ADC) );
adc->adcsr &= ~mask_ADIF;
}
return CB_RET_RETAIN;
}
/******************************************************************************\
*
* ADC
*
\******************************************************************************/
static uint8_t adc_read ( VDevice *dev, int addr );
static void adc_write ( VDevice *dev, int addr, uint8_t val );
static void adc_reset ( VDevice *dev );
static char *adc_reg_name ( VDevice *dev , int addr );
/** \brief Allocate a new ADC structure. */
ADC_T *adc_new( uint8_t uier )
{
ADC_T *adc;
adc = avr_new( ADC_T, 1 );
adc_construct( adc, uier );
class_overload_destroy( (AvrClass *)adc, adc_destroy );
return adc;
}
/** \brief Constructor for ADC object. */
void adc_construct( ADC_T *adc, uint8_t uier )
{
char *name = "ADC";
if (adc == NULL)
avr_error( "passed null ptr" );
if ( uier )
vdev_construct( (VDevice *)adc, name, ADC_BASE_U, ADC_SIZE,
adc_read, adc_write, adc_reset, adc_reg_name );
else
vdev_construct( (VDevice *)adc, name, ADC_BASE_A, ADC_SIZE,
adc_read, adc_write, adc_reset, adc_reg_name );
adc_reset( (VDevice*)adc );
adc->u_divisor = uier ? 12 : 1 ;
}
/** \brief Destructor for ADC object. */
void adc_destroy( void *adc )
{
if (adc == NULL)
return;
vdev_destroy( adc );
}
static uint8_t adc_read( VDevice *dev, int addr )
{
ADC_T *adc = (ADC_T *)dev;
switch ( addr - vdev_get_base(dev) ) {
case ADC_ADCL_ADDR: return adc->adcl;
case ADC_ADCH_ADDR: return adc->adch;
default:
avr_error( "Bad address: 0x%04x", addr );
}
return 0; /* will never get here */
}
static void adc_write( VDevice *dev, int addr, uint8_t val )
{
avr_error( "Bad ADC write address: 0x%04x", addr );
}
static void adc_reset( VDevice *dev )
{
ADC_T *adc = (ADC_T *)dev;
adc->clk_cb = NULL;
adc->adcl = 0;
adc->adch = 0;
adc->adc_count = 0 ;
adc->adc_in = 0 ;
adc->divisor = 0;
}
static char *adc_reg_name( VDevice *dev , int addr )
{
switch ( addr - vdev_get_base(dev) ) {
case ADC_ADCL_ADDR: return "ADCL" ;
case ADC_ADCH_ADDR: return "ADCH" ;
default:
avr_error( "Bad address: 0x%04x", addr );
}
return NULL;
}
static int adc_clk_incr_cb( uint64_t ck, AvrClass *data )
{
ADC_T *adc = (ADC_T *)data;
uint8_t last = adc->adc_count;
ADCIntr_T *adc_ti;
adc_ti = (ADCIntr_T *)avr_core_get_vdev_by_name( (AvrCore
*)vdev_get_core((VDevice *)adc),
"ADCIntr" );
if (adc->clk_cb == NULL)
return CB_RET_REMOVE;
if (adc->divisor <= 0)
avr_error( "Bad divisor value: %d", adc->divisor );
/* decrement clock if ck is a multiple of divisor */
adc->adc_count -= ((ck % (adc->divisor * adc->u_divisor)) == 0);
/* */
if (adc->adc_count != last) /* we've changed the counter */
{
if ( adc->adc_count == 0 )
{
adc_ti->adcsr |= mask_ADIF;
adc_ti->adcsr &= ~mask_ADSC;
adc->adc_in = adc_port_rd( adc_ti->admux ) ;
adc->adcl = (adc->adc_in) & 0xff ; /* update adcl to what
we read */
adc->adch = ((adc->adc_in)>>8) & 0x03 ; /* update adch */
if ( adc_ti->adcsr & mask_ADFR ) /* free running mode */
adc->adc_count = 13 ;
else
{
adc->clk_cb = NULL;
return CB_RET_REMOVE;
}
}
}
return CB_RET_RETAIN;
}
uint16_t adc_port_rd( uint8_t mux )
{
int data;
char line[80];
while (1)
{
fprintf( stderr, "\nEnter data to read into the ADC for channel %d: ",
mux);
/* try to read in a line of input */
if ( fgets(line, sizeof(line), stdin) == NULL)
continue;
/* try to parse the line for a byte of data */
if ( sscanf(line, "%d\n", &data) != 1 )
continue;
break;
}
return (uint16_t)(data & 0x3ff);
}
void adc_port_wr( uint8_t val )
{
fprintf( stderr, "wrote 0x%02x to ADC\n", val );
}
/*
* $Id: adc.h,v 1.3 2003/11/07 20:58:28 kgudger Exp $
*
****************************************************************************
*
* simulavr - A simulator for the Atmel AVR family of microcontrollers.
* Copyright (C) 2001, 2002 Theodore A. Roth
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
****************************************************************************
*/
#ifndef ADC_H
#define ADC_H
/****************************************************************************\
*
* ADCInter_T(VDevice) : ADC Interrupt and Control Register
*
\****************************************************************************/
enum _adc_intr_constants {
ADC_INTR_BASE_A = 0x26, /* base address for vdev */
ADC_INTR_BASE_U = 0x27, /* base address for vdev */
ADC_INTR_SIZE = 2, /* SPCR, SPSR */
ADC_INTR_ADCSR_ADDR = 0,
ADC_INTR_ADMUX_ADDR = 1,
};
typedef enum {
bit_ADPS0 = 0, /* Clock Rate Select 0 */
bit_ADPS1 = 1, /* Clock Rate Select 1 */
bit_ADPS2 = 2, /* Clock Rate Select 1 */
bit_ADIE = 3, /* ADC Interrupt Enable */
bit_ADIF = 4, /* ADC Interrupt Flag */
bit_ADFR = 5, /* Free Run Select */
bit_ADSC = 6, /* ADC Start Conversion */
bit_ADEN = 7, /* ADC Enable */
} ADCSR_BITS;
typedef enum {
mask_ADPS0 = 1 << bit_ADPS0,
mask_ADPS1 = 1 << bit_ADPS1,
mask_ADPS2 = 1 << bit_ADPS2,
mask_ADIE = 1 << bit_ADIE,
mask_ADIF = 1 << bit_ADIF,
mask_ADFR = 1 << bit_ADFR,
mask_ADSC = 1 << bit_ADSC,
mask_ADEN = 1 << bit_ADEN,
} ADCSR_MASKS;
typedef enum {
bit_MUX0 = 0, /* MUX Channel Select Bit */
bit_MUX1 = 1, /* MUX Channel Select Bit */
bit_MUX2 = 2, /* MUX Channel Select Bit */
bit_MUX3 = 3, /* MUX Channel Select Bit */
} ADMUX_BITS;
typedef enum {
mask_MUX0 = 1 << bit_MUX0,
mask_MUX1 = 1 << bit_MUX1,
mask_MUX2 = 1 << bit_MUX2,
mask_MUX3 = 1 << bit_MUX3,
} ADMUX_MASKS;
typedef struct _ADCIntr_T ADCIntr_T;
struct _ADCIntr_T {
VDevice parent;
uint8_t adcsr; /* ADC Interrupt control and status register */
uint8_t admux; /* ADC Multiplexer Select register */
CallBack *intr_cb; /* callback for checking and raising interrupts
*/
};
extern ADCIntr_T *adc_intr_new ( uint8_t uier );
extern void adc_intr_construct ( ADCIntr_T *ti, uint8_t uier );
extern void adc_intr_destroy ( void *ti );
/****************************************************************************\
*
* General ADC bits and masks.
*
\****************************************************************************/
enum _adc_cs_constants {
ADC_CK_0 = 0x00, /* CK/2 */
ADC_CK_2 = 0x01, /* CK/2 */
ADC_CK_4 = 0x02, /* CK/4 */
ADC_CK_8 = 0x03, /* CK/8 */
ADC_CK_16 = 0x04, /* CK/16 */
ADC_CK_32 = 0x05, /* CK/32 */
ADC_CK_64 = 0x06, /* CK/64 */
ADC_CK_128 = 0x07, /* CK/128 */
};
/****************************************************************************\
*
* ADC(VDevice) : ADC
*
\****************************************************************************/
enum _adc_constants {
ADC_BASE_A = 0x24, /* base memory address */
ADC_BASE_U = 0x22, /* base memory address */
ADC_SIZE = 2, /* ADC Data Register Size = 2 bytes */
ADC_ADCL_ADDR = 0, /* offset from base to ADCL Register */
ADC_ADCH_ADDR = 1, /* offset from base to ADCH Register */
};
typedef struct _ADC ADC_T;
struct _ADC {
VDevice parent;
uint8_t adcl; /* data register */
uint8_t adch; /* data register */
uint16_t adc_count; /* 16 bit count register */
uint16_t adc_in; /* new data register */
uint16_t divisor; /* clock divisor */
uint8_t u_divisor; /* extra usb clock divisor */
CallBack *clk_cb; /* incr timer tied to clock */
};
extern ADC_T *adc_new ( uint8_t uier );
extern void adc_construct ( ADC_T *adc, uint8_t uier );
extern void adc_destroy ( void *adc );
extern void adc_intr_set_flag ( ADCIntr_T *ti );
extern void adc_intr_clear_flag ( ADCIntr_T *ti );
extern uint16_t adc_port_rd( uint8_t mux ) ;
extern void adc_port_wr( uint8_t val );
#endif
/*
* $Id: usb.h,v 1.3 2003/10/28 20:58:28 kgudger Exp $
*
****************************************************************************
*
* simulavr - A simulator for the Atmel AVR family of microcontrollers.
* Copyright (C) 2001, 2002 Theodore A. Roth
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
****************************************************************************
*/
#ifndef USB_H
#define USB_H
/****************************************************************************\
*
* USBInter_T(VDevice) : USB Interrupt Mask/Flag/Enable Registers
*
\****************************************************************************/
enum _usb_intr_constants {
USB_INTR_BASE = 0x1ff3, /* base address for vdev */
USB_INTR_SIZE = 11, /* UIER, unused, UIAR, UIMSK*/
USB_INTR_ENABLE_ADDR = 0,
USB_INTR_UNUSED_ADDR = 1,
USB_INTR_ACK_ADDR = 2,
USB_INTR_MASK_ADDR = 3,
USB_INTR_STATUS_ADDR = 4,
USB_INTR_SPRSMSK_ADDR = 5,
USB_INTR_SPRSIE_ADDR = 6,
USB_INTR_SPRSR_ADDR = 7,
USB_GLB_STATE_ADDR = 8,
USB_FRM_NUM_L_ADDR = 9,
USB_FRM_NUM_H_ADDR = 10,
};
typedef enum {
bit_FEP0 = 0, /* Function Endpoint 0 interrupt enable */
bit_FEP1 = 1, /* Function Endpoint 1 interrupt enable */
bit_FEP2 = 2, /* Function Endpoint 2 interrupt enable */
bit_HEP0 = 3, /* Hub Endpoint 0 interrupt enable */
bit_FEP3 = 4, /* Function Endpoint 3 interrupt enable */
} USBMSK_BITS;
typedef enum {
mask_FEP0 = 1 << bit_FEP0,
mask_FEP1 = 1 << bit_FEP1,
mask_FEP2 = 1 << bit_FEP2,
mask_HEP0 = 1 << bit_HEP0,
mask_FEP3 = 1 << bit_FEP3,
} USB_MASKS;
typedef enum {
bit_TX_COMPLETE = 0,
bit_RX_OUT_PACKET = 1,
bit_RX_SETUP = 2,
bit_STALL_SENT = 3,
bit_TX_PACKET_READY = 4,
bit_FORCE_STALL = 5,
bit_DATA_END = 6,
bit_DATA_DIR = 7,
} USBCSR_BITS;
typedef enum {
bit_TX_COMPLETE_ACK = 0,
bit_RX_OUT_PACKET_ACK = 1,
bit_RX_SETUP_ACK = 2,
bit_STALL_SENT_ACK = 3,
} USBCAR_BITS;
typedef enum {
TX_COMPLETE = 1 << bit_TX_COMPLETE,
RX_OUT_PACKET = 1 << bit_RX_OUT_PACKET,
RX_SETUP = 1 << bit_RX_SETUP,
STALL_SENT = 1 << bit_STALL_SENT,
TX_PACKET_READY = 1 << bit_TX_PACKET_READY,
FORCE_STALL = 1 << bit_FORCE_STALL,
DATA_END = 1 << bit_DATA_END,
DATA_DIR = 1 << bit_DATA_DIR,
} USBCSR_MASKS;
typedef struct _USBInter_T USBInter_T;
struct _USBInter_T {
VDevice parent;
uint8_t uier; /* USB interrupt enable (mask) register */
uint8_t uiar; /* USB interrupt ack register */
uint8_t uimsk; /* USB interrupt mask register */
uint8_t uisr; /* USB interrupt flag register */
uint8_t func_mask; /* mask of available register functions */
uint8_t sprsmsk;
uint8_t sprsie;
uint8_t sprsr;
uint8_t glb_state;
uint8_t frm_num_l;
uint8_t frm_num_h;
CallBack *intr_cb; /* callback for checking and raising interrupts
*/
};
extern USBInter_T *usb_intr_new ( uint8_t func_mask );
extern void usb_intr_construct ( USBInter_T *usb, uint8_t func_mask );
extern void usb_intr_destroy ( void *usb );
/****************************************************************************\
*
* USB(VDevice) : USB Structure
*
\****************************************************************************/
enum _usb_constants {
USB_BASE = 0x1fa0, /* base memory address */
USB_SIZE = 83, /* TCCR0 and TCNT0 */
USB_FCAR5_ADDR = 0, /* offset from base to FCAR Register */
USB_FCAR4_ADDR = 1,
USB_FCAR3_ADDR = 2,
USB_FCAR2_ADDR = 3,
USB_FCAR1_ADDR = 4,
USB_FCAR0_ADDR = 5,
USB_HCAR0_ADDR = 7,
USB_PSTATE1_ADDR = 8,
USB_PSTATE2_ADDR = 9,
USB_PSTATE3_ADDR = 0x0a,
USB_PSTATE4_ADDR = 0x0b,
USB_PSTATE5_ADDR = 0x0c,
USB_PSTATE6_ADDR = 0x0d,
USB_PSTATE7_ADDR = 0x0e,
USB_PSTATE8_ADDR = 0x0f,
USB_HPSCR1_ADDR = 0x10, /* 0x1fb0 */
USB_HPSCR2_ADDR = 0x11,
USB_HPSCR3_ADDR = 0x12,
USB_HPSCR4_ADDR = 0x13,
USB_HPSCR5_ADDR = 0x14,
USB_HPSCR6_ADDR = 0x15,
USB_HPSCR7_ADDR = 0x16,
USB_HPSCR8_ADDR = 0x17,
USB_HPSTAT1_ADDR = 0x18,
USB_HPSTAT2_ADDR = 0x19,
USB_HPSTAT3_ADDR = 0x1a,
USB_HPSTAT4_ADDR = 0x1b,
USB_HPSTAT5_ADDR = 0x1c,
USB_HPSTAT6_ADDR = 0x1d,
USB_HPSTAT7_ADDR = 0x1e,
USB_HPSTAT8_ADDR = 0x1f,
USB_HPCON_ADDR = 0x25,
USB_HSTR_ADDR = 0x27, /* 0X1FC7 */
USB_FBYTE_CNT5_ADDR = 0x28,
USB_FBYTE_CNT4_ADDR = 0x29,
USB_FBYTE_CNT3_ADDR = 0x2a,
USB_FBYTE_CNT2_ADDR = 0x2b,
USB_FBYTE_CNT1_ADDR = 0x2c,
USB_FBYTE_CNT0_ADDR = 0x2d,
USB_HBYTE_CNT0_ADDR = 0x2f,
USB_FDR5_ADDR = 0x30, /* 0x1fd0 */
USB_FDR4_ADDR = 0x31,
USB_FDR3_ADDR = 0x32,
USB_FDR2_ADDR = 0x33,
USB_FDR1_ADDR = 0x34,
USB_FDR0_ADDR = 0x35,
USB_HDR0_ADDR = 0x37,
USB_FCSR5_ADDR = 0x38,
USB_FCSR4_ADDR = 0x39,
USB_FCSR3_ADDR = 0x3a,
USB_FCSR2_ADDR = 0x3b,
USB_FCSR1_ADDR = 0x3c,
USB_FCSR0_ADDR = 0x3d,
USB_HCSR0_ADDR = 0x3f,
USB_FENDP5_CNTR_ADDR = 0x40, /* 0x1fe0 */
USB_FENDP4_CNTR_ADDR = 0x41,
USB_FENDP3_CNTR_ADDR = 0x42,
USB_FENDP2_CNTR_ADDR = 0x43,
USB_FENDP1_CNTR_ADDR = 0x44,
USB_FENDP0_CNTR_ADDR = 0x45,
USB_HENDP1_CNTR_ADDR = 0x46,
USB_HENDP0_CNTR_ADDR = 0x47,
USB_FADDR_ADDR = 0x4e, /* 0x1fee */
USB_HADDR_ADDR = 0x4f,
USB_ICSR_ADDR = 0x51, /* 0x1ff1 */
USB_UOVCER_ADDR = 0x52, /* 0x1ff2 */
};
typedef struct _USB USB_T;
struct _USB {
VDevice parent;
uint8_t uovcer; /* overcurrent register */
uint8_t haddr; /* Hub Address register */
uint8_t faddr; /* Function Address register */
uint8_t hstr ; /* Hub Status register */
uint8_t hpcon; /* Hub Port Control register */
uint8_t icsr; /* interrupt control sense register */
uint8_t fendp5_cntr; /* endpoint 5 control register */
uint8_t fendp4_cntr; /* endpoint 4 control register */
uint8_t fendp3_cntr; /* endpoint 3 control register */
uint8_t fendp2_cntr; /* endpoint 2 control register */
uint8_t fendp1_cntr; /* endpoint 1 control register */
uint8_t fendp0_cntr; /* endpoint 0 control register */
uint8_t hendp1_cntr; /* hub endpoint control register */
uint8_t hendp0_cntr; /* hub endpoint control register */
uint8_t fcsr5; /* endpoint 5 control & status register */
uint8_t fcsr4; /* endpoint 4 control & status register */
uint8_t fcsr3; /* endpoint 3 control & status register */
uint8_t fcsr2; /* endpoint 2 control & status register */
uint8_t fcsr1; /* endpoint 1 control & status register */
uint8_t fcsr0; /* endpoint 0 control & status register */
uint8_t hcsr0; /* hub endpoint control & status register */
uint8_t fcar5; /* endpoint 5 control & ack register */
uint8_t fcar4; /* endpoint 4 control & ack register */
uint8_t fcar3; /* endpoint 3 control & ack register */
uint8_t fcar2; /* endpoint 2 control & ack register */
uint8_t fcar1; /* endpoint 1 control & ack register */
uint8_t fcar0; /* endpoint 0 control & ack register */
uint8_t hcar0; /* hub endpoint control & ack register */
uint8_t hpstat1; /* hub port 1 status register */
uint8_t hpstat2; /* hub port 2 status register */
uint8_t hpstat3; /* hub port 3 status register */
uint8_t hpstat4; /* hub port 4 status register */
uint8_t hpstat5; /* hub port 5 status register */
uint8_t hpstat6; /* hub port 6 status register */
uint8_t hpstat7; /* hub port 7 status register */
uint8_t hpstat8; /* hub port 8 status register */
uint8_t pstate1; /* hub port 1 port state register */
uint8_t pstate2; /* hub port 2 port state register */
uint8_t pstate3; /* hub port 3 port state register */
uint8_t pstate4; /* hub port 4 port state register */
uint8_t pstate5; /* hub port 5 port state register */
uint8_t pstate6; /* hub port 6 port state register */
uint8_t pstate7; /* hub port 7 port state register */
uint8_t pstate8; /* hub port 8 port state register */
uint8_t hpscr1; /* hub port 1 status change register */
uint8_t hpscr2; /* hub port 2 status change register */
uint8_t hpscr3; /* hub port 3 status change register */
uint8_t hpscr4; /* hub port 4 status change register */
uint8_t hpscr5; /* hub port 5 status change register */
uint8_t hpscr6; /* hub port 6 status change register */
uint8_t hpscr7; /* hub port 7 status change register */
uint8_t hpscr8; /* hub port 8 status change register */
uint8_t fdr5; /* endpoint 5 data register */
uint8_t fdr4; /* endpoint 4 data register */
uint8_t fdr3; /* endpoint 3 data register */
uint8_t fdr2; /* endpoint 2 data register */
uint8_t fdr1; /* endpoint 1 data register */
uint8_t fdr0; /* endpoint 0 data register */
uint8_t hdr0; /* hub endpoint data register */
uint8_t fbyte_cnt5; /* byte count register */
uint8_t fbyte_cnt4; /* byte count register */
uint8_t fbyte_cnt3; /* byte count register */
uint8_t fbyte_cnt2; /* byte count register */
uint8_t fbyte_cnt1; /* byte count register */
uint8_t fbyte_cnt0; /* byte count register */
uint8_t hbyte_cnt0; /* byte count register */
};
extern USB_T *usb_new ( void );
extern void usb_construct ( USB_T *usb );
extern void usb_destroy ( void *usb );
extern void usb_intr_set_flag ( USB_T *usb, uint8_t bitnr );
extern void usb_intr_clear_flag ( USB_T *usb, uint8_t bitnr );
#endif /* USB_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Simulavr-devel] ADC Patch,
Keith Gudger <=