[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Simulavr-devel] SPI Device Support?
From: |
Joel Sherrill |
Subject: |
Re: [Simulavr-devel] SPI Device Support? |
Date: |
Wed, 18 Mar 2009 15:39:30 -0500 |
User-agent: |
Thunderbird 2.0.0.19 (X11/20090105) |
Michael N. Moran wrote:
Joel Sherrill wrote:
Michael N. Moran wrote:
Joel Sherrill wrote:
And that brings up the next question.. Since I
have to simulate a TI ADS1258 SPI analog, does
anyone have any suggestions on how to hook a
simulated device on the SPI bus?
I submitted patches some years ago that are
still Open.
This patch contains some example code and
"stimulator" classes for stimulating the SPI
port using file I/O. The check.tcl file in
the examples/mnm directory shows how it is
all put together.
<https://savannah.nongnu.org/patch/?4599>
Note that it requires some previous
(still open) patches.
The last patch (still Open0 that I submitted
is here:
<https://savannah.nongnu.org/patch/?4629>
I hope this helps.
OK. I have downloaded them and will
clean them up against the head. Once I
get it building, I will post a new diff with
both merged if that's OK with you.
I'm speechless ;) Of course its OK with me.
I thought so. It thrills me since I needed
SPI and analog support for my "real work"
Attached is a patch against the current CVS head.
It builds and seems to get close to running your
application. I think the failure is related to
some parts of the patch which I think are missing.
+ The .6 patch modifies atmega48.cpp which
does not exist in CVS.
+ The .4 patch added this to main.cpp but I didn't
see any code to set or use the flags:
Index: src/main.cpp
===================================================================
RCS file: /sources/simulavr/simulavrxx/src/main.cpp,v
retrieving revision 1.23
diff -u -r1.23 main.cpp
--- src/main.cpp 13 Mar 2009 20:43:34 -0000 1.23
+++ src/main.cpp 18 Mar 2009 19:53:00 -0000
@@ -94,6 +94,10 @@
string tracefilename("unknown");
int global_gdbserver_port = 1212;
int global_gdb_debug = 0;
+ bool use_spi_source=false;
+ bool use_spi_sink=false;
+ const char* pinmon = 0;
+
bool globalWaitForGdbConnection=true; //please wait for gdb connection
int userinterface_flag=0;
unsigned long long fcpu=4000000;
I want you to test it.
It may take a while, but I'll make it happen.
:)
Thanks Joel
--
Joel Sherrill, Ph.D. Director of Research & Development
address@hidden On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
? 4-rej
? examples/spi/Makefile.notauto
Index: configure.ac
===================================================================
RCS file: /sources/simulavr/simulavrxx/configure.ac,v
retrieving revision 1.44
diff -u -r1.44 configure.ac
--- configure.ac 16 Mar 2009 17:50:36 -0000 1.44
+++ configure.ac 18 Mar 2009 20:37:42 -0000
@@ -120,6 +120,9 @@
[examples/atmel_key/checkdebug.tcl],
[chmod +x examples/atmel_key/checkdebug.tcl])
AC_CONFIG_FILES(
+ [examples/spi/check.tcl],
+ [chmod +x examples/spi/check.tcl])
+ AC_CONFIG_FILES(
[examples/stdiodemo/checkdebug.tcl],
[chmod +x examples/stdiodemo/checkdebug.tcl])
else
@@ -140,7 +143,8 @@
regress/Makefile regress/modules/Makefile regress/test_opcodes/Makefile \
regress/avrtest/Makefile \
examples/Makefile examples/anacomp/Makefile examples/atmel_key/Makefile \
- examples/simple_ex1/Makefile examples/stdiodemo/Makefile \
+ examples/simple_ex1/Makefile examples/spi/Makefile \
+ examples/stdiodemo/Makefile \
])
AC_OUTPUT
Index: examples/Makefile.am
===================================================================
RCS file: /sources/simulavr/simulavrxx/examples/Makefile.am,v
retrieving revision 1.9
diff -u -r1.9 Makefile.am
--- examples/Makefile.am 16 Mar 2009 20:30:45 -0000 1.9
+++ examples/Makefile.am 18 Mar 2009 20:37:42 -0000
@@ -5,7 +5,7 @@
SUBDIRS = simple_ex1 anacomp atmel_key
if USE_TCL
-SUBDIRS += anacomp stdiodemo
+SUBDIRS += anacomp spi stdiodemo
endif
noinst_DATA = kbd.xbm
Index: examples/spi/.cvsignore
===================================================================
RCS file: examples/spi/.cvsignore
diff -N examples/spi/.cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/.cvsignore 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,4 @@
+Makefile
+Makefile.in
+check.tcl
+spi.elf
Index: examples/spi/Makefile.am
===================================================================
RCS file: examples/spi/Makefile.am
diff -N examples/spi/Makefile.am
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/Makefile.am 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,32 @@
+#
+# $Id: Makefile.am,v 1.12 2009/03/11 21:35:49 joelsherrill Exp $
+#
+
address@hidden@
+
+noinst_DATA = spi.elf
+
+CLEANFILES = spi.elf main.o trace
+
+EXTRA_DIST = main.cpp spidata anadata
+
+all-local: $(objdir)/spidata $(objdir)/anadata
+
+$(objdir)/spidata: $(srcdir)/spidata
+ test -r spidata || cp $(srcdir)/spidata spidata
+
+$(objdir)/anadata: $(srcdir)/anadata
+ test -r anadata || cp $(srcdir)/anadata anadata
+
+do: spi.elf
+ $(TCL_WISH) check.tcl
+
+# WAR: should detect avr-toolset first!
+
+main.o : $(srcdir)/main.cpp
+ $(AVR_GCC) -g -O2 -mmcu=atmega128 -c -o $@ $<
+
+spi.elf : main.o
+ $(AVR_GCC) -mmcu=atmega128 -o $@ $<
+
+SUBDIRS =
Index: examples/spi/README
===================================================================
RCS file: examples/spi/README
diff -N examples/spi/README
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/README 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,92 @@
+#
+# $Id$
+#
+
+Demonstrates the following Stimulation classes:
+
+ o SpiSink - monitors the /SS, SCLK and MISO pins and prints
+ each byte to stdout.
+
+ o SpiSource - drives the /SS, SCLK and MOSI pins with data from
+ the spidata file.
+
+ o PinMonitor - monitors Port A Bit 0 and prints changes in its
+ binary status to stdout.
+
+ o AdcPin - Stimulates Port F Bit 0 with the values contained
+ in the anadata file.
+
+The AVR program alternately (every other byte) echoes the byte received
+on the SPI or the ADCH value read from a recenet A/D converter, to the SPI.
+
+The spidata file contains an HDLC encoded stream of *mostly* flags
+that was used in my project at work. (We're running a form of
+PPP/HDLC over SPI.)
+
+The format of the spidata file consists of comments (lines
+that start with a '#') and data lines. Each data line consists
+of 3 values.
+
+o First Value - the value (0 or non-zero)of /SS
+o Second Value - the value (0 or non-zero) of SCLK
+o Third Value - the value (0 or non-zero) of MOSI
+
+When the SpiSource program stimulator reaches the end-of-file,
+it rewinds and repeats ad-nauseum.
+
+The anadata file contains analog data that that is read by the
+AdcPin class and written to the Port F Bit 0 analog input of
+the ATMega128.
+
+The format of the anadata file consists of comments (lines
+that start with a '#' character) and analog input lines.
+Each input line consists of 2 values separated by whitespace.
+
+o First Value - number of nano-seconds before the next value
+ is read and applied to the analog input.
+o Second Value - signed integer "analogValue" to be applied
+ to the analog input.
+
+To try it:
+
+Step 1:
+ Configure and build the simulavr (simulavr.so in particular)
+
+Step 2:
+ Build the AVR test program in this directory.
+ $ make
+
+Step 3:
+ Run the test TCL script from this directory.
+ $ check.tcl
+
+Step 4:
+ Marvel at the stdio activity.
+
+Step 5:
+ Try modifying the spidata file and see the results.
+
+
+What you'll see on stdout:
+
+Note: Comments added on the right.
+
+spisink: /SS asserted ; SPI /SS goes LOW (printed by SpiSink)
+spisink: 0x00 ; 0x00 byte received on MISO from AVR
(printed by SpiSink)
+PORTA0: ASSERT ; Port A Bit 0 set low by AVR (printed
by PinMonitor)
+spisink: 0x00 ; Analog Data from AVR on SPI MISO
+spisink: 0x02 ; echoed HDLC Data from AVR on SPI MISO
+spisink: 0x99 ; Analog data from AVR on SPI MISO
+spisink: 0xD3 ; echoed HDLC data from AVR on SPI MISO
+spisink: 0x66 ; Analog data from AVR on SPI MISO
+spisink: 0x7E ; echoed HDLC data from AVR on SPI MISO
+spisink: 0x33 ; Analog data from AVR on SPI MISO
+spisink: 0x7E ; echoed HDLC data from AVR on SPI MISO
+...
+...
+spisink: 0x7E ; echoed HDLC data from AVR on SPI MISO
+spisink: 0x04 ; Analog data from AVR on SPI MISO
+spisink: /SS negated ; SPI /SS goes HIGH (printed by SpiSink)
+spisink: /SS asserted ; SPI /SS goes LOW (printed by SpiSink)
+spisink: 0x7E ; echoed HDLC data
+
Index: examples/spi/anadata
===================================================================
RCS file: examples/spi/anadata
diff -N examples/spi/anadata
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/anadata 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,32 @@
+#
+# This is an analog pin data file. Each must be either a comment
+# or an analog entry with the format:
+#
+# <delayInNanoseconds> <signed analog integer value>
+#
+# The delay is the amount of time before the following line
+# is read and executed.
+#
+3333333 5000000
+3333333 4000000
+3333333 3000000
+3333333 2000000
+3333333 1000000
+3333333 900000
+3333333 800000
+3333333 700000
+3333333 600000
+3333333 500000
+3333333 400000
+3333333 300000
+3333333 200000
+3333333 100000
+3333333 90000
+3333333 80000
+3333333 70000
+3333333 60000
+3333333 50000
+3333333 40000
+3333333 30000
+3333333 20000
+3333333 10000
Index: examples/spi/check.tcl.in
===================================================================
RCS file: examples/spi/check.tcl.in
diff -N examples/spi/check.tcl.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/check.tcl.in 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,84 @@
+#! @TCL_WISH@
+#
+# $Id: check.tcl.in,v 1.6 2009/03/06 11:28:20 zfrdh Exp $
+#
+
+set traceFile trace
+
+#load the avr-simulator package
+load @top_builddir@/src/.libs/libsimulavr.so
+
+puts "simulavr loaded"
+
+#create new device
+set dev1 [new_AvrDevice_atmega128]
+
+#load elf file to the device
+AvrDevice_Load $dev1 "./spi.elf"
+
+#set the clock cycle time [ns]
+# 1000000000ns/1000000MHz == 1000ns
+AvrDevice_SetClockFreq $dev1 1000
+
+#systemclock must know that this device will be stepped from application
+set sc [GetSystemClock]
+$sc Add $dev1
+
+# MNM
+set netB0 [new_Net]
+set netB1 [new_Net]
+set netB2 [new_Net]
+set netB3 [new_Net]
+
+[AvrDevice_GetPin $dev1 "B0"] SetOutState $Pin_PULLUP
+
+$netB0 Add [AvrDevice_GetPin $dev1 "B0"]
+$netB1 Add [AvrDevice_GetPin $dev1 "B1"]
+$netB2 Add [AvrDevice_GetPin $dev1 "B2"]
+$netB3 Add [AvrDevice_GetPin $dev1 "B3"]
+
+SpiSource spiSource "spidata" $netB0 $netB1 $netB2
+SpiSink spiSink $netB0 $netB1 $netB3
+set pinMonPinNameStr "A0"
+set pinMonPinDescStr "PORTA0"
+set pinMonPinHighStr "NEGATE"
+set pinMonPinLowStr "ASSERT"
+
+# This line did not work since the string "constants" are
+# apparently de-allocated after the constructor, and the
+# PinMonitor class keeps the pointers, not a copy to
+# the strings!
+#PinMonitor pinmon $dev1 "A0" "PORTA0" "NEGATE" "ASSERT"
+
+# This works because the variables do not get de-allocated.
+PinMonitor pinmon $dev1 $pinMonPinNameStr $pinMonPinDescStr $pinMonPinHighStr
$pinMonPinLowStr
+
+set netF0 [new_Net]
+set netAref [new_Net]
+
+$netF0 Add [AvrDevice_GetPin $dev1 "F0"]
+
+AdcPin adcPinSource "anadata" $netF0
+
+$netAref Add [AvrDevice_GetPin $dev1 "AREF"]
+
+set aRef [new_AdcAnalogPin]
+
+$aRef SetOutState $Pin_ANALOG
+
+$netAref Add $aRef
+
+$aRef setAnalogValue 5000000
+
+$sc Add spiSource
+$sc Add spiSink
+$sc Add adcPinSource
+
+GdbServer gdb1 $dev1 1212 0 0
+$sc Add gdb1
+
+# nice -n 19 xterm -e "avr-gdb $objfile -x gdbinit"
+
+#now run simulation
+$sc Endless
+exit
Index: examples/spi/main.cpp
===================================================================
RCS file: examples/spi/main.cpp
diff -N examples/spi/main.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/main.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,107 @@
+/*
+ * Demonstrate the use of the SpiSource, SpiSink, and PinMonitor.
+ *
+ * $Id$
+ */
+
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <avr/signal.h>
+#include <stdint.h>
+
+uint8_t txData;
+volatile uint8_t rxData;
+
+static void startADC()
+{
+ ADCSRA = ( (1<<ADEN) // ADC Enabled
+ | (1<<ADSC) // Start Conversion NOW
+ | (0<<ADFR) // Auto Trigger Disabled
+ | (1<<ADIF) // Interrupt Flag
Acknowledge
+ | (1<<ADIE) // Interrupt enabled
+ | (0<<ADPS2) // Prescaler should get
between 50KHz-200KHz for max resolution
+ | (1<<ADPS1) // System Clock = 1MHz
+ | (1<<ADPS0) //
Prescaler = 1MHz/100KHz = ~10 thus = 8 : 1MHz/8 = 120KHz
+ ) ;
+}
+
+static void assertPA0(){
+ // asserted is LOW
+ PORTA &= ~(1<<PA0);
+ }
+
+static void negatePA0(){
+ // negated is HIG
+ PORTA |= (1<<PA0);
+ }
+
+uint8_t count;
+uint8_t adcData;
+
+SIGNAL(SIG_ADC)
+{
+ adcData = ADCH;
+ startADC();
+}
+
+SIGNAL(SIG_SPI)
+{
+ rxData = SPDR;
+ if(count % 2){
+ SPDR = rxData;
+ }
+ else {
+ SPDR = adcData;
+ }
+
+ if(count == 0){
+ assertPA0();
+ }
+
+ if(count == 128){
+ negatePA0();
+ }
+ ++count;
+}
+
+int main(int argc,char *argv[]){
+ ADMUX = (0<<REFS1) // Use Vcc as ADC reference
+ | (1<<REFS0) // Use Vcc as ADC
reference
+ | (1<<ADLAR) // Left justify result
(percentage FS)
+ | (0<<MUX4) // Always zero for our
application
+ | (0<<MUX3)
+ | (0<<MUX2)
+ | (0<<MUX1)
+ | (0<<MUX0)
+ ;
+
+ DDRB &= ~( (1<<PB0) // /SS PortB pin 0 as input
+ | (1<<PB1) // SCK PortB pin 1 as
input for slave
+ | (1<<PB2) // MOSI PortB pin 2 as
input for slave
+ );
+ DDRB |= (1<<PB3); // MISO PortB pin 2 as output
for slave
+ PORTA |= (1<<PA0); // Negate "interrupt"
+ DDRA |= (1<<PA0); // "Interrupt" output
+
+ SPCR = (1<<SPIE) // interrupt enable
+ | (1<<SPE) // SPI enable
+ | (0<<DORD) // MSB first
+ | (0<<MSTR) // Slave Mode
+ | (1<<CPOL) // Clock HIGH when idle
+ | (0<<CPHA) // Sample on leading
edge
+ | (0<<SPR1) // Slave has no affect
+ | (0<<SPR0) // Slave has no affect
+ ;
+
+ startADC();
+
+ sei();
+
+ for(;;);
+
+ return 0;
+}
+
+
+
+
Index: examples/spi/spidata
===================================================================
RCS file: examples/spi/spidata
diff -N examples/spi/spidata
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/spi/spidata 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,623 @@
+1 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+#
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+0 1 0
+0 0 0
+0 1 0
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 1
+0 0 1
+0 1 1
+0 1 0
+0 0 0
+0 1 0
+#
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
+1 1 1
Index: src/Makefile.am
===================================================================
RCS file: /sources/simulavr/simulavrxx/src/Makefile.am,v
retrieving revision 1.31
diff -u -r1.31 Makefile.am
--- src/Makefile.am 16 Mar 2009 17:56:23 -0000 1.31
+++ src/Makefile.am 18 Mar 2009 20:37:42 -0000
@@ -27,15 +27,16 @@
noinst_LTLIBRARIES=libsim.la
libsim_la_SOURCES = \
- application.cpp at4433.cpp at8515.cpp atmega128.cpp avrdevice.cpp \
- avrerror.cpp avrfactory.cpp avrmalloc.cpp decoder.cpp decoder_trace.cpp \
- flash.cpp gdbserver.cpp hardware.cpp helper.cpp hwacomp.cpp hwad.cpp \
- hweeprom.cpp hwextirq.cpp hwmegaextirq.cpp hwmegatimer.cpp \
- hwmegatimer0123irq.cpp hwport.cpp hwspi.cpp hwsreg.cpp hwstack.cpp \
- hwtimer.cpp hwtimer01irq.cpp hwuart.cpp hwwado.cpp ioregs.cpp irqsystem.cpp \
- keyboard.cpp lcd.cpp memory.cpp mysocket.cpp net.cpp pin.cpp pinatport.cpp \
- printable.cpp rwmem.cpp scope.cpp serialrx.cpp serialtx.cpp systemclock.cpp \
- trace.cpp ui.cpp
+ adcpin.cpp application.cpp at4433.cpp at8515.cpp atmega128.cpp \
+ avrdevice.cpp avrerror.cpp avrfactory.cpp avrmalloc.cpp decoder.cpp \
+ decoder_trace.cpp flash.cpp gdbserver.cpp hardware.cpp helper.cpp \
+ hwacomp.cpp hwad.cpp hweeprom.cpp hwextirq.cpp hwmegaextirq.cpp \
+ hwmegatimer.cpp hwmegatimer0123irq.cpp hwpinchange.cpp hwport.cpp hwspi.cpp \
+ hwsreg.cpp hwstack.cpp hwtimer.cpp hwtimer01irq.cpp hwuart.cpp \
+ hwwado.cpp ioregs.cpp irqsystem.cpp keyboard.cpp lcd.cpp memory.cpp \
+ mysocket.cpp net.cpp pin.cpp pinatport.cpp pinmon.cpp printable.cpp \
+ rwmem.cpp scope.cpp serialrx.cpp serialtx.cpp spisrc.cpp spisink.cpp \
+ systemclock.cpp trace.cpp ui.cpp
nodist_libsimulavr_la_SOURCES = $(TCL_WRAP_SRC)
libsimulavr_la_LDFLAGS = -version-info 0:0:0
@@ -43,18 +44,18 @@
$(AVR_LIBBFD_LIB) $(AVR_LIBIBERTY_LIB)
pkginclude_HEADERS = \
- application.h at4433.h at8515.h atmega128.h avrdevice.h \
+ adcpin.h application.h at4433.h at8515.h atmega128.h avrdevice.h \
avrdevice_impl.h avrerror.h avrfactory.h avrmalloc.h breakpoint.h \
config_deprecated.h decoder.h externaltype.h flash.h \
funktor.h gdb.h global.h hardware.h helper.h hwacomp.h \
hwad.h hweeprom.h hwextirq.h hwmegaextirq.h hwmegatimer.h \
- hwmegatimer0123irq.h hwport.h hwspi.h hwsreg.h hwstack.h \
+ hwmegatimer0123irq.h hwpinchange.h hwport.h hwspi.h hwsreg.h hwstack.h \
hwtimer.h hwtimer01irq.h hwuart.h hwwado.h ioregs.h \
irqsystem.h keyboard.h keynumber_to_scancode.dat lcd.h \
- memory.h mysocket.h net.h pin.h pinatport.h pinnotify.h \
- printable.h rwmem.h scope.h serialrx.h serialtx.h \
- simulationmember.h systemclock.h systemclocktypes.h trace.h \
- types.h ui.h xcode_to_keynumber.dat
+ memory.h mysocket.h net.h pin.h pinatport.h pinnotify.h pinmon.h \
+ printable.h rwmem.h scope.h serialrx.h serialtx.h simulationmember.h \
+ spisrc.h spisink.h systemclock.h systemclocktypes.h trace.h types.h \
+ ui.h xcode_to_keynumber.dat
simulavr_SOURCES = main.cpp $(COMMON_SRC)
Index: src/adcpin.cpp
===================================================================
RCS file: src/adcpin.cpp
diff -N src/adcpin.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/adcpin.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,51 @@
+#include <iostream>
+#include "adcpin.h"
+
+AdcPin::AdcPin( const char* fileName,
+ Net& pinNet
+ ) throw():
+ _analogPin(),
+ _anaFile(fileName)
+ {
+ _analogPin.SetOutState(Pin::ANALOG);
+ pinNet.Add(&_analogPin);
+
+ if(!_anaFile){
+ cerr << "Cannot open Analog input file \"" << fileName
<< "\"." << endl;
+ exit(1);
+ }
+ }
+
+char* readNextLine(std::ifstream& f,char* buffer,unsigned
len,SystemClockOffset *timeToNextStepIn_ns){
+ for(unsigned i=0;i<2;++i){
+ while(f.getline(buffer, len)){
+ // Skip comment lines
+ if(buffer[0] == '#') continue;
+ return buffer;
+ }
+ f.clear();
+ f.seekg (0, ios::beg);
+ }
+ return 0;
+ }
+
+int AdcPin::Step(bool &trueHwStep, SystemClockOffset *timeToNextStepIn_ns){
+ if(!_anaFile) return 0;
+
+ char lineBuffer[1024];
+
+
if(!readNextLine(_anaFile,lineBuffer,sizeof(lineBuffer),timeToNextStepIn_ns)){
+ _anaFile.close();
+ }
+
+ char* p = lineBuffer;
+ unsigned long delayInNs = strtoul(p, &p, 0);
+ int analogValue = (int)strtol(p, &p, 0);
+
+ _analogPin.setAnalogValue(analogValue);
+
+ *timeToNextStepIn_ns = delayInNs;
+
+ return 0;
+ }
+
Index: src/adcpin.h
===================================================================
RCS file: src/adcpin.h
diff -N src/adcpin.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/adcpin.h 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,40 @@
+#ifndef _adcpinh_
+#define _adcpinh_
+#include <fstream>
+#include "avrdevice.h"
+
+// This class allows the analog simulator access
+// to the analogValue field of the pin and causes
+// the Net to update (CalcNet). Note there is
+// no dependency on the UserInterface class.
+class AdcAnalogPin : public Pin {
+ public:
+ // Set the analog value and propagte through Net.
+ inline void setAnalogValue(int value) throw(){
+ analogValue = value;
+ connectedTo->CalcNet();
+ }
+ };
+
+// The purpose of this class is to stimulate a pin
+// with an analog pattern specified by a file.
+// The file will contain an "analog sample value" on
+// each line, along with a duration in nano-seconds
+// that must elapse before the value is changed.
+class AdcPin : public SimulationMember {
+ private:
+ AdcAnalogPin _analogPin; // Output to AVR
+
+ // The analog input file.
+ std::ifstream _anaFile;
+
+ public:
+ AdcPin( const char* fileName,
+ Net& pinNet
+ ) throw();
+
+ private: // SimulationMember
+ int Step(bool &trueHwStep, SystemClockOffset
*timeToNextStepIn_ns=0);
+ };
+
+#endif
Index: src/hwpinchange.cpp
===================================================================
RCS file: src/hwpinchange.cpp
diff -N src/hwpinchange.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/hwpinchange.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,273 @@
+#include <iostream>
+#include "hwpinchange.h"
+#include "irqsystem.h"
+#include "trace.h"
+
+HWPcir::HWPcir( AvrDevice* avr,
+ HWIrqSystem& irqSystem,
+ unsigned vector0,
+ unsigned vector1,
+ unsigned vector2,
+ unsigned vector3,
+ unsigned vector4,
+ unsigned vector5,
+ unsigned vector6,
+ unsigned vector7
+ ) throw():
+ Hardware(avr),
+ _pcifr(0),
+ _pcicr(0),
+ _irqSystem(irqSystem),
+ _vector0(vector0),
+ _vector1(vector1),
+ _vector2(vector2),
+ _vector3(vector3),
+ _vector4(vector4),
+ _vector5(vector5),
+ _vector6(vector6),
+ _vector7(vector7)
+ {
+ }
+
+bool HWPcir::getPcifr(unsigned pcifrBit) throw(){
+ return _pcifr & (1<<pcifrBit);
+ }
+
+unsigned HWPcir::convertBitToVector(unsigned bit) const throw(){
+ unsigned vector = ~0;
+ switch(bit){
+ case 0:
+ vector = _vector0;
+ break;
+ case 1:
+ vector = _vector1;
+ break;
+ case 2:
+ vector = _vector2;
+ break;
+ case 3:
+ vector = _vector3;
+ break;
+ case 4:
+ vector = _vector4;
+ break;
+ case 5:
+ vector = _vector5;
+ break;
+ case 6:
+ vector = _vector6;
+ break;
+ case 7:
+ vector = _vector7;
+ break;
+ default:
+ cerr << "HWPcir: invalid PCIFR bit specified.." << endl;
+ break;
+ };
+ return vector;
+ }
+
+void HWPcir::setPcifr(unsigned pcifrBit) throw(){
+ if(_pcifr & (1<<pcifrBit)){
+ // Already set/pending
+ return;
+ }
+ // At this point we have a *new* pin-change interrupt.
+ _pcifr |= (1<<pcifrBit);
+
+ unsigned vector = convertBitToVector(pcifrBit);
+
+ if(vector == (unsigned)~0){
+ cerr << "HWPcir: Attempt to set invalid pin-change interrupt."
<< endl;
+ return;
+ }
+
+ if(_pcicr & (1<<pcifrBit)){
+ _irqSystem.SetIrqFlag(this,vector);
+ }
+ }
+
+void HWPcir::setPcifrMask(unsigned char val) throw(){
+ // Only XOR bits that are set/pending
+ val &= _pcifr;
+
+ // Clear the appropriate pending interrupts
+ _pcifr ^= val;
+
+ for(unsigned i=0;i<8;++i){
+ if(val & (1<<i)){
+ // We're trying to clear an interrupt
+ // An interrupt is pending
+ if(_pcicr & (1<<i)){
+ // The interrupt is enabled and pending,
+ // so tell the interrupt system
+ unsigned vector = convertBitToVector(i);
+ _irqSystem.ClearIrqFlag(vector);
+ }
+ }
+ }
+
+ // Clear the bits in the register
+ _pcifr ^= val;
+ }
+
+unsigned char HWPcir::getPcifrMask() const throw(){
+ return _pcifr;
+ }
+
+void HWPcir::setPcicrMask(unsigned char val) throw(){
+ unsigned char pcicrChanges = _pcicr ^ val;
+ for(unsigned i=0;i<8;++i){
+ if(pcicrChanges & (1<<i)){
+ // Bit changed
+ if(val & (1<<i)){
+ // Bit is being enabled
+ if(_pcifr & (1<<i)){
+ // Change interrupt pending
+ unsigned vector = convertBitToVector(i);
+ _irqSystem.SetIrqFlag(this,vector);
+ }
+ }
+ else {
+ // Bit is being disabled
+ if(val & (1<<i)){
+ // Change interrupt pending
+ unsigned vector = convertBitToVector(i);
+ _irqSystem.ClearIrqFlag(vector);
+ }
+ }
+ }
+ }
+ _pcicr = val;
+ }
+
+unsigned char HWPcir::getPcicrMask() const throw(){
+ return _pcicr;
+ }
+
+
+void HWPcir::Reset(){
+ _pcicr = 0;
+ _pcifr = 0;
+ }
+
+void HWPcir::ClearIrqFlag(unsigned int vector){
+ if(vector == _vector0){
+ _pcifr &= ~(1<<0);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector1){
+ _pcifr &= ~(1<<1);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector2){
+ _pcifr &= ~(1<<2);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector3){
+ _pcifr &= ~(1<<3);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector4){
+ _pcifr &= ~(1<<4);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector5){
+ _pcifr &= ~(1<<5);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector6){
+ _pcifr &= ~(1<<6);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ if(vector == _vector7){
+ _pcifr &= ~(1<<7);
+ _irqSystem.ClearIrqFlag(vector);
+ return;
+ }
+ cerr << "HWPcir: Attempt to clear non-existent irq vector";
+ }
+
+HWPcmsk::HWPcmsk( HWPcifrApi& pcifrApi,
+ unsigned pcifrBit
+ ) throw():
+ _pcifrApi(pcifrApi),
+ _pcmsk(0),
+ _pcifrBit(pcifrBit)
+ {
+ }
+
+void HWPcmsk::setPcmskMask(unsigned char val) throw(){
+ _pcmsk = val;
+ }
+
+unsigned char HWPcmsk::getPcmskMask() const throw(){
+ return _pcmsk;
+ }
+
+void HWPcmsk::pinChanged(unsigned bit) throw(){
+ if(_pcmsk & (1<<bit)){
+ _pcifrApi.setPcifr(_pcifrBit);
+ }
+ }
+
+PinChange::PinChange( Pin& pin,
+ HWPcmskPinApi&
pcmskPinApi,
+ unsigned
pcmskBit
+ ) throw():
+ _pin(pin),
+ _pcmskPinApi(pcmskPinApi),
+ _pcmskBit(pcmskBit),
+ _prevState(true)
+ {
+ pin.RegisterCallback(this);
+ }
+
+void PinChange::PinStateHasChanged(Pin* pin){
+ bool currentState = (bool)*pin;
+ if(currentState == _prevState){
+ return;
+ }
+
+ _prevState = currentState;
+
+ _pcmskPinApi.pinChanged(_pcmskBit);
+ }
+
+unsigned char RWPcicr::operator=(unsigned char val){
+ if (core->trace_on) trioaccess("PCICR",val);
+ _pcirMaskApi.setPcicrMask(val);
+ return val;
+ }
+
+RWPcicr::operator unsigned char() const{
+ return _pcirMaskApi.getPcicrMask();
+ }
+
+unsigned char RWPcifr::operator=(unsigned char val){
+ if (core->trace_on) trioaccess("PCIFR",val);
+ _pcirMaskApi.setPcifrMask(val);
+ return val;
+ }
+
+RWPcifr::operator unsigned char() const{
+ return _pcirMaskApi.getPcifrMask();
+ }
+
+unsigned char RWPcmsk::operator=(unsigned char val){
+ if (core->trace_on) trioaccess("PCMSK",val);
+ _pcmskApi.setPcmskMask(val);
+ return val;
+ }
+
+RWPcmsk::operator unsigned char() const{
+ return _pcmskApi.getPcmskMask();
+ }
+
Index: src/hwpinchange.h
===================================================================
RCS file: src/hwpinchange.h
diff -N src/hwpinchange.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/hwpinchange.h 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,174 @@
+#ifndef _hwpinchangeh_
+#define _hwpinchangeh_
+#include "avrdevice.h"
+#include "pin.h"
+#include "pinnotify.h"
+#include "net.h"
+#include "rwmem.h"
+#include "hardware.h"
+
+class HWPcifrApi {
+ public:
+ virtual ~HWPcifrApi(){}
+ virtual bool getPcifr(unsigned bit) throw()=0;
+ virtual void setPcifr(unsigned bit) throw()=0;
+
+ };
+
+class HWPcicrApi {
+ public:
+ virtual ~HWPcicrApi(){}
+ virtual bool getPcicr(unsigned bit) throw()=0;
+ virtual void setPcicr(unsigned bit) throw()=0;
+
+ };
+
+class HWPcmskApi {
+ public:
+ virtual ~HWPcmskApi(){}
+ virtual void setPcmskMask(unsigned char val)
throw()=0;
+ virtual unsigned char getPcmskMask() const throw()=0;
+
+// virtual bool getPcmsk(unsigned bit) throw()=0;
+// virtual void setPcmsk(unsigned bit) throw()=0;
+
+ };
+
+class HWPcmskPinApi {
+ public:
+ virtual ~HWPcmskPinApi(){}
+ virtual void pinChanged(unsigned bit) throw()=0;
+ };
+
+class HWPcirMaskApi {
+ public: // HWPcirMaskApi
+ virtual void setPcifrMask(unsigned char val)
throw()=0;
+ virtual unsigned char getPcifrMask() const throw()=0;
+
+ virtual void setPcicrMask(unsigned char val)
throw()=0;
+ virtual unsigned char getPcicrMask() const throw()=0;
+ };
+
+class HWPcir : public HWPcifrApi , public HWPcirMaskApi , public Hardware {
+ private:
+ unsigned char _pcifr;
+ unsigned char _pcicr;
+ HWIrqSystem& _irqSystem;
+
+ const unsigned _vector0;
+ const unsigned _vector1;
+ const unsigned _vector2;
+ const unsigned _vector3;
+ const unsigned _vector4;
+ const unsigned _vector5;
+ const unsigned _vector6;
+ const unsigned _vector7;
+
+ public:
+ // Unimplemented vectors are set
+ // to a value of all ones (i.e. ~0).
+ HWPcir( AvrDevice* avr,
+ HWIrqSystem& irqSystem,
+ unsigned vector0 = ~0,
+ unsigned vector1 = ~0,
+ unsigned vector2 = ~0,
+ unsigned vector3 = ~0,
+ unsigned vector4 = ~0,
+ unsigned vector5 = ~0,
+ unsigned vector6 = ~0,
+ unsigned vector7 = ~0
+ ) throw();
+
+ private:
+ unsigned convertBitToVector(unsigned bit) const throw();
+
+ public: // HWPcifrApi
+ bool getPcifr(unsigned pcifrBit) throw();
+ void setPcifr(unsigned pcifrBit) throw();
+
+ public: // HWPcirMaskApi
+ void setPcifrMask(unsigned char val) throw();
+ unsigned char getPcifrMask() const throw();
+
+ void setPcicrMask(unsigned char val) throw();
+ unsigned char getPcicrMask() const throw();
+
+ private: // Hardware
+ void Reset();
+ void ClearIrqFlag(unsigned int vector);
+
+
+ };
+
+class HWPcmsk : public HWPcmskApi , public HWPcmskPinApi {
+ private:
+ HWPcifrApi& _pcifrApi;
+ unsigned char _pcmsk;
+ const unsigned _pcifrBit;
+
+ public:
+ // constructor
+ HWPcmsk( HWPcifrApi& pcifrApi,
+ unsigned pcifrBit
+ ) throw();
+
+ public: // HWPcmskApi
+ void setPcmskMask(unsigned char val) throw();
+ unsigned char getPcmskMask() const throw();
+
+ public: // HWPcmskPinApi
+ void pinChanged(unsigned bit) throw();
+ };
+
+// This class monitors a single pin for changes
+// an reports an interrupt if the pin chages.
+class PinChange : public HasPinNotifyFunction {
+ private:
+ Pin& _pin;
+ HWPcmskPinApi& _pcmskPinApi;
+ const unsigned _pcmskBit;
+
+ // Previous state of pin since change callback doesn't *really*
+ // mean "change"!
+ bool _prevState;
+
+ public:
+ PinChange( Pin& pin,
+ HWPcmskPinApi& pcmskPinApi,
+ unsigned pcmskBit
+ ) throw();
+
+ private: // HasPinNotifyFunction
+ void PinStateHasChanged(Pin*);
+ };
+
+class RWPcicr : public RWMemoryMembers {
+ private:
+ HWPcirMaskApi& _pcirMaskApi;
+ public:
+ RWPcicr(AvrDevice *c, HWPcirMaskApi& pcirMaskApi):
RWMemoryMembers(c), _pcirMaskApi(pcirMaskApi) {}
+ virtual unsigned char operator=(unsigned char);
+ virtual operator unsigned char() const;
+ };
+
+class RWPcifr : public RWMemoryMembers {
+ private:
+ HWPcirMaskApi& _pcirMaskApi;
+
+ public:
+ RWPcifr(AvrDevice *c, HWPcirMaskApi& pcirMaskApi ):
RWMemoryMembers(c), _pcirMaskApi(pcirMaskApi) {}
+ virtual unsigned char operator=(unsigned char);
+ virtual operator unsigned char() const;
+ };
+
+class RWPcmsk : public RWMemoryMembers {
+ private:
+ HWPcmskApi& _pcmskApi;
+
+ public:
+ RWPcmsk(AvrDevice *c, HWPcmskApi& pcmskApi ):
RWMemoryMembers(c), _pcmskApi(pcmskApi) {}
+ virtual unsigned char operator=(unsigned char);
+ virtual operator unsigned char() const;
+ };
+
+#endif
Index: src/main.cpp
===================================================================
RCS file: /sources/simulavr/simulavrxx/src/main.cpp,v
retrieving revision 1.23
diff -u -r1.23 main.cpp
--- src/main.cpp 13 Mar 2009 20:43:34 -0000 1.23
+++ src/main.cpp 18 Mar 2009 20:37:42 -0000
@@ -94,6 +94,10 @@
string tracefilename("unknown");
int global_gdbserver_port = 1212;
int global_gdb_debug = 0;
+ bool use_spi_source=false;
+ bool use_spi_sink=false;
+ const char* pinmon = 0;
+
bool globalWaitForGdbConnection=true; //please wait for gdb connection
int userinterface_flag=0;
unsigned long long fcpu=4000000;
Index: src/pinmon.cpp
===================================================================
RCS file: src/pinmon.cpp
diff -N src/pinmon.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/pinmon.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,35 @@
+#include <iostream>
+#include "pinmon.h"
+
+PinMonitor::PinMonitor( AvrDevice& avr,
+ const char* pinNameStr, //
AVR pin name. (e.g. "B1","C2", etc.)
+ const char* pinDescStr,
+ const char* pinHighStr,
+ const char* pinLowStr
+ ) throw():
+ _prevState(true)
+ {
+ Pin* pin = avr.GetPin(pinNameStr);
+ pin->RegisterCallback(this);
+ _pinDescStr = pinDescStr?pinDescStr:pinNameStr;
+ _pinHighStr = pinHighStr?pinHighStr:"HIGH";
+ _pinLowStr = pinLowStr?pinLowStr:"LOW";
+ }
+
+void PinMonitor::PinStateHasChanged(Pin* pin){
+ const char* stateStr;
+ if((bool)*pin == _prevState){
+ return;
+ }
+ if((bool)*pin){
+ stateStr = _pinHighStr;
+ _prevState = true;
+ }
+ else {
+ stateStr = _pinLowStr;
+ _prevState = false;
+ }
+
+ cout << _pinDescStr << ": " << stateStr << endl;
+ }
+
Index: src/pinmon.h
===================================================================
RCS file: src/pinmon.h
diff -N src/pinmon.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/pinmon.h 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,32 @@
+#ifndef _pinmonh_
+#define _pinmonh_
+#include "avrdevice.h"
+#include "pin.h"
+#include "pinnotify.h"
+#include "net.h"
+
+// This class monitors a single pin and prints
+// changes in the pin state to stdout.
+class PinMonitor : public HasPinNotifyFunction {
+ private:
+ // This string printed as a prefix on stdout with each pin
change.
+ const char* _pinDescStr;
+ // String printed when the pin is HIGH.
+ const char* _pinHighStr;
+ // String printed when the pin is LOW.
+ const char* _pinLowStr;
+ // Previous state of pin since change callback doesn't *really*
+ // mean "change"!
+ bool _prevState;
+ public:
+ PinMonitor( AvrDevice& avr,
+ const char* pinNameStr, // AVR pin
name. (e.g. "B1","C2", etc.)
+ const char* pinDescStr = 0,
+ const char* pinHighStr = 0,
+ const char* pinLowStr = 0
+ ) throw();
+ private: // HasPinNotifyFunction
+ void PinStateHasChanged(Pin*);
+ };
+
+#endif
Index: src/simulavr.i
===================================================================
RCS file: /sources/simulavr/simulavrxx/src/simulavr.i,v
retrieving revision 1.8
diff -u -r1.8 simulavr.i
--- src/simulavr.i 16 Mar 2009 17:56:23 -0000 1.8
+++ src/simulavr.i 18 Mar 2009 20:37:42 -0000
@@ -17,6 +17,10 @@
#include "lcd.h"
#include "serialrx.h"
#include "serialtx.h"
+#include "spisrc.h"
+#include "spisink.h"
+#include "adcpin.h"
+#include "pinmon.h"
#include "scope.h"
SystemClock &GetSystemClock() { return SystemClock::Instance(); }
@@ -41,6 +45,10 @@
%include "lcd.h"
%include "serialrx.h"
%include "serialtx.h"
+%include "spisrc.h"
+%include "spisink.h"
+%include "adcpin.h"
+%include "pinmon.h"
%include "scope.h"
Index: src/spisink.cpp
===================================================================
RCS file: src/spisink.cpp
diff -N src/spisink.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/spisink.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,127 @@
+#include <iostream>
+#include "spisink.h"
+
+SpiSink::SpiSink( Net& ssNet,
+ Net& sclkNet,
+ Net& misoNet,
+ bool clockIsIdleHigh,
+ bool clockSampleOnLeadingEdge
+ ) throw():
+ _ss(),
+ _sclk(),
+ _miso(),
+ _state(0),
+ _sr(0),
+ _clockIsIdleHigh(clockIsIdleHigh),
+ _clockSampleOnLeadingEdge(clockSampleOnLeadingEdge),
+ _prevClkState(clockIsIdleHigh),
+ _prevSS(true)
+ {
+ _ss.SetOutState(Pin::PULLUP);
+ ssNet.Add(&_ss);
+
+ _sclk.SetOutState(Pin::PULLUP);
+ sclkNet.Add(&_sclk);
+
+ _miso.SetOutState(Pin::PULLUP);
+ misoNet.Add(&_miso);
+ }
+
+int SpiSink::Step(bool &trueHwStep, SystemClockOffset *timeToNextStepIn_ns){
+ *timeToNextStepIn_ns = 1000; // Once every microsecond
+ bool sample = false;
+
+ if(!_ss){
+ if(_prevClkState != (bool)_sclk){
+ _prevClkState = (bool)_sclk;
+ if(_clockIsIdleHigh){
+ // Clock is HIGH when idle
+ if(_clockSampleOnLeadingEdge){
+ // Sample on leading edge
+ sample = ((bool)_sclk)?false:true;
+ }
+ else {
+ // Sample on trailing edge
+ sample = ((bool)_sclk)?true:false;
+ }
+ }
+ else {
+ // Clock is LOW when idle
+ if(_clockSampleOnLeadingEdge){
+ // Sample on leading edge
+ sample = ((bool)_sclk)?true:false;
+ }
+ else {
+ // Sample on trailing edge
+ sample = ((bool)_sclk)?false:true;
+ }
+ }
+ }
+ }
+ else {
+ _sr = 0;
+ _state = 0;
+ }
+
+ for(;;){
+ switch(_state){
+ case 0: // Waiting for /SS
+ if(!_ss){
+ _state = 1;
+ continue;
+ }
+ break;
+ case 1: // First sample
+ case 2: // Second sample
+ case 3: // Third sample
+ case 4: // Fourth sample
+ case 5: // Fifth sample
+ case 6: // Sixth sample
+ case 7: // Seventh sample
+ if(sample){
+ _sr <<= 1;
+ if(_miso){
+ _sr |= 0x01;
+ }
+ ++_state;
+ }
+ break;
+ case 8: // First sample
+ if(sample){
+ _sr <<= 1;
+ if(_miso){
+ _sr |= 0x01;
+ }
+ _state = 1;
+
+ streamsize streamWidth =
cout.width();
+ ios_base::fmtflags saved =
cout.flags();
+
cout.setf(ios_base::hex,ios_base::basefield);
+ cout.setf(ios_base::uppercase);
+ cout.setf(ios_base::right);
+ cout << "spisink: 0x";
+ cout.width(2);
+ cout.fill('0');
+ cout << (unsigned long)_sr;
+ cout << endl;
+ cout.width(streamWidth);
+ cout.flags(saved);
+ }
+ break;
+ }
+ break;
+ }
+
+ if((bool)_ss != _prevSS){
+ if(_ss){
+ cout << "spisink: /SS negated" << endl;
+ }
+ else {
+ cout << "spisink: /SS asserted" << endl;
+ }
+ _prevSS = _ss;
+ }
+
+ return 0;
+ }
+
Index: src/spisink.h
===================================================================
RCS file: src/spisink.h
diff -N src/spisink.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/spisink.h 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,29 @@
+#ifndef _spisinkh_
+#define _spisinkh_
+#include "avrdevice.h"
+
+// This class monitors the /SS, SCLK, and MISO pin of the AVR and
+// prints the results one byte at a time to stdout.
+class SpiSink : public SimulationMember {
+ private:
+ Pin _ss; // Output to AVR
+ Pin _sclk; // Output to AVR
+ Pin _miso; // Output to AVR
+ unsigned _state;
+ unsigned char _sr;
+ bool _clockIsIdleHigh;
+ bool _clockSampleOnLeadingEdge;
+ bool _prevClkState;
+ bool _prevSS;
+ public:
+ SpiSink( Net& ssNet,
+ Net& sclkNet,
+ Net& misoNet,
+ bool clockIsIdleHigh = true,
+ bool
clockSampleOnLeadingEdge = true
+ ) throw();
+ private: // SimulationMember
+ int Step(bool &trueHwStep, SystemClockOffset
*timeToNextStepIn_ns=0);
+ };
+
+#endif
Index: src/spisrc.cpp
===================================================================
RCS file: src/spisrc.cpp
diff -N src/spisrc.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/spisrc.cpp 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,63 @@
+#include <iostream>
+#include "spisrc.h"
+
+SpiSource::SpiSource( const char* fileName,
+ Net& ssNet,
+ Net& sclkNet,
+ Net& mosiNet
+ ) throw():
+ _ss(),
+ _sclk(),
+ _mosi(),
+ _spiFile(fileName)
+ {
+ _ss.SetOutState(Pin::HIGH);
+ ssNet.Add(&_ss);
+
+ _sclk.SetOutState(Pin::HIGH);
+ sclkNet.Add(&_sclk);
+
+ _mosi.SetOutState(Pin::HIGH);
+ mosiNet.Add(&_mosi);
+
+ if(!_spiFile){
+ cerr << "Cannot open SPI Source input file " <<
fileName << endl;
+ exit(1);
+ }
+ }
+
+static char* readNextLine(std::ifstream& f,char* buffer,unsigned
len,SystemClockOffset *timeToNextStepIn_ns){
+ *timeToNextStepIn_ns = 100000; // Once every 100 microseconds
+ for(unsigned i=0;i<2;++i){
+ while(f.getline(buffer, len)){
+ if(buffer[0] == '#') continue;
+ return buffer;
+ }
+ *timeToNextStepIn_ns = 1000000; // Once every 100
microseconds
+ f.clear();
+ f.seekg (0, ios::beg);
+ }
+ return 0;
+ }
+
+int SpiSource::Step(bool &trueHwStep, SystemClockOffset
*timeToNextStepIn_ns){
+ if(!_spiFile) return 0;
+
+ char lineBuffer[1024];
+
+
if(!readNextLine(_spiFile,lineBuffer,sizeof(lineBuffer),timeToNextStepIn_ns)){
+ _spiFile.close();
+ return 0;
+ }
+
+ char* p = lineBuffer;
+ unsigned long ss = strtoul(p, &p, 0);
+ unsigned long sclk = strtoul(p, &p, 0);
+ unsigned long output = strtoul(p, &p, 0);
+
+ _ss = (ss)?'H':'L';
+ _sclk = (sclk)?'H':'L';
+ _mosi = (output)?'H':'L';
+ return 0;
+ }
+
Index: src/spisrc.h
===================================================================
RCS file: src/spisrc.h
diff -N src/spisrc.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/spisrc.h 18 Mar 2009 20:37:42 -0000
@@ -0,0 +1,23 @@
+#ifndef _spisrch_
+#define _spisrch_
+#include <fstream>
+#include "avrdevice.h"
+
+class SpiSource : public SimulationMember {
+ private:
+ Pin _ss; // Output to AVR
+ Pin _sclk; // Output to AVR
+ Pin _mosi; // Output to AVR
+ std::ifstream _spiFile;
+ public:
+ SpiSource( const char* fileName,
+ Net& ssNet,
+ Net& sclkNet,
+ Net& mosiNet
+ ) throw();
+ private: // SimulationMember
+ int Step(bool &trueHwStep, SystemClockOffset
*timeToNextStepIn_ns=0);
+ };
+
+
+#endif