Hi,
I extended the python interface so that you can simulate ADC inputs.
Can you please review the attached commit?
Can I get commit rights or do you prefer to push it yourself?

Some questions for the review:

I think the output of "Pin::operator char" was inconsistent with
"Pin::operator=", so i swapped "A" and "a" there. Is this ok? Or should
the swap be done in "Pin::operator="? Or was the inconsistency
deliberate?

Is it ok to extend Pin? Or should the python interface use AdcAnalogPin
in some way?
I think it's better to use Pin because the property of a pin to be an
analog input can change during run time in the real microcontroller,
too.

AREF initialization:
        aref.SetAnalog(INT_MAX)
Is this as intended?

Sebastian
commit 27e6bbd4fe0102fcaff78e2302e95045ef32a463
Author: Sebastian <sebast...@svetz.(none)>
Date:   Wed Jun 30 23:51:24 2010 +0200

    Extended python interface: SetAnalog

diff --git a/examples/python/Makefile.am b/examples/python/Makefile.am
index 15a4e64..349e262 100644
--- a/examples/python/Makefile.am
+++ b/examples/python/Makefile.am
@@ -57,7 +57,17 @@ $(EXAMPLE5B): multicore.c
 example5: $(EXAMPLE5A) $(EXAMPLE5B)
        PYTHONPATH=../../src @PYTHON@ multicore.py
 
-run_example: example1 example2 example3 example4 example5
+# example6: ADC with atmega16
+EXAMPLE6 = adc.elf
+EX6_CFLAGS = -g -O2 -mmcu=atmega16
+
+$(EXAMPLE6): adc.c
+       $(AVR_GCC) $(EX6_CFLAGS) -o $@ $<
+
+example6: $(EXAMPLE6)
+       PYTHONPATH=../../src @PYTHON@ adc.py atmega16:$<
+
+run_example: example1 example2 example3 example4 example5 example6
 
 else
 
@@ -74,13 +84,13 @@ run_example:
 endif
 
 
-EXTRA_DIST = example.c example.py example_pin.py example_io.c example_io.py \
-             ex_utils.py ex_pinout.py ex_pinout.c multicore.c multicore.py
+EXTRA_DIST = example.c example.py example_pin.py example_io.c adc.c \
+             example_io.py ex_utils.py ex_pinout.py ex_pinout.c multicore.c 
multicore.py adc.py
 
-examples_DATA = $(EXAMPLE1) $(EXAMPLE3) $(EXAMPLE4) $(EXAMPLE5A) $(EXAMPLE5B) \
+examples_DATA = $(EXAMPLE1) $(EXAMPLE3) $(EXAMPLE4) $(EXAMPLE5A) $(EXAMPLE5B) 
$(EXAMPLE6) \
                 $(EXTRA_DIST) README Makefile
 
-CLEANFILES = $(EXAMPLE1) $(EXAMPLE3) $(EXAMPLE4) $(EXAMPLE5A) $(EXAMPLE5B) \
+CLEANFILES = $(EXAMPLE1) $(EXAMPLE3) $(EXAMPLE4) $(EXAMPLE5A) $(EXAMPLE5B) 
$(EXAMPLE6) \
              ex_utils.pyc ex_pinout.vcd
 
 example: run_example
diff --git a/examples/python/adc.c b/examples/python/adc.c
new file mode 100644
index 0000000..e717dc0
--- /dev/null
+++ b/examples/python/adc.c
@@ -0,0 +1,42 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+volatile uint32_t dummy = 0;
+volatile uint32_t conversions = 0;
+
+volatile uint16_t adc_value = 5555;
+ISR(ADC_vect)
+{
+    if((ADCSRA & (1 << ADSC)) == 0)
+    {
+        ++conversions;
+        adc_value = ADC;
+        ADCSRA |= /* ADC Control and Status Register A */
+            (1 << ADSC); /* ADC Start Conversion */
+    }
+}
+
+int main(void)
+{
+    /* I'm not sure if this is necessary. I think, program startup is
+     * considered to be handling of the reset interrupt.
+     * So Interrupts will be disabled at program startup.
+     * just to be on the safe side: */
+    cli();
+
+    ADCSRA = /* ADC Control and Status Register A */
+          (1 << ADEN) /* ADC Enable */
+        | (1 << ADSC) /* ADC Start Conversion */
+        | (1 << ADIE) /* ADC Interrupt Enable */
+        | (1<< ADPS2) /* ADPS2...ADPS0 ADC Prescaler Select Bits = 1 0 0, Bei 
1MHz, Faktor 16 = 62,5kHz, 16us */
+        ;
+    ADMUX = /* ADC Multiplexer Select Register */
+        /* REFS1...REFS0 (ReferenceSelection Bits) = 0 --> Externes AREF */    
    
+        (0 << MUX2) | (0 << MUX1) | (0 << MUX0); /* MUX4...MUX0 = channel*/
+
+    sei();
+    while(1)
+    {
+        ++dummy;
+    }
+}
diff --git a/examples/python/adc.py b/examples/python/adc.py
new file mode 100644
index 0000000..aa187e0
--- /dev/null
+++ b/examples/python/adc.py
@@ -0,0 +1,51 @@
+# Python Script
+from sys import argv
+from os.path import splitext, basename
+
+import pysimulavr
+from ex_utils import SimulavrAdapter
+
+class XPin(pysimulavr.Pin):
+  
+  def __init__(self, dev, name, state = None):
+    pysimulavr.Pin.__init__(self)
+    self.dev=dev
+    self.name = name
+    devpin = dev.GetPin(name)
+    if state is not None: self.SetPin(state)
+    # hold the connecting net here, it have not be destroyed, if we leave this 
method
+    self.__net = pysimulavr.Net()
+    self.__net.Add(self)
+    self.__net.Add(devpin)
+
+if __name__ == "__main__":
+
+  proc, elffile = argv[1].split(":")
+  
+  sim = SimulavrAdapter()
+  sim.dmanSingleDeviceApplication()
+  dev = sim.loadDevice(proc, elffile)
+  print "value 'adc_value'=%d" % sim.getWordByName(dev, "adc_value")
+  
+  a0 = XPin(dev, "A0", 'a')
+  A0 = dev.GetPin("A0")
+  aref = XPin(dev, "AREF", 'a')
+  
+  INT_MAX = 2**31 - 1
+  aref.SetAnalog(INT_MAX)
+  # hwad.cpp: adSample= (int)((float)adSample/(float)adref*INT_MAX);
+  
+  sim.dmanStart()
+  print "simulation start: (t=%dns)" % sim.getCurrentTime()
+  a0.SetAnalog(123)
+  #a0.SetAnalog(int(0.1 * 2**31))
+  sim.doRun(sim.getCurrentTime() + 500000)
+  print "simulation end: (t=%dns)" % sim.getCurrentTime()  
+  print "conversions: %d" % sim.getWordByName(dev, "conversions")
+  
+  print "adc_value=%d" % sim.getWordByName(dev, "adc_value")
+  
+  sim.dmanStop()
+  del dev
+  
+# EOF
diff --git a/src/pin.cpp b/src/pin.cpp
index 3bef6e4..76b599c 100644
--- a/src/pin.cpp
+++ b/src/pin.cpp
@@ -172,8 +172,8 @@ Pin::operator char() const {
         case TRISTATE: return 't';
         case PULLDOWN: return 'l';
         case LOW: return 'L';
-        case ANALOG: return 'A';
-        case ANALOG_SHORTED: return 'a';
+        case ANALOG: return 'a';
+        case ANALOG_SHORTED: return 'A';
     }
     return 'S'; //only default, should never be reached
 }
@@ -241,6 +241,15 @@ Pin& Pin::operator= (char c) {
     return *this;
 }
 
+Pin& Pin::setAnalog(int value) {
+    //outState = ANALOG;
+    analogValue = value;
+
+    CalcPin();
+
+    return *this;
+}
+
 Pin Pin::operator+= (const Pin& p) {
     *this = *this + p;
     return *this;
diff --git a/src/pin.h b/src/pin.h
index 6f27af8..f361d25 100644
--- a/src/pin.h
+++ b/src/pin.h
@@ -95,6 +95,7 @@ class Pin {
         virtual void UnRegisterNet(Net *n); //!< deletes Net instance 
registration for pin
         virtual Pin GetPin(void) { return *this;} //!< "cast method" to get 
back a Pin instance
         int GetAnalog(void) const; //!< Returns analog input value of pin
+        Pin& setAnalog(int value);  //!< Sets the pin to an analog value
         void RegisterCallback(HasPinNotifyFunction *); //!< register a 
listener for input value change
         //! Update input values from output values
         /*! If there is no connection to other pins, then it will reflect the 
own
diff --git a/src/python/pysimulavr.i b/src/python/pysimulavr.i
index d668563..488f792 100644
--- a/src/python/pysimulavr.i
+++ b/src/python/pysimulavr.i
@@ -108,6 +108,9 @@ namespace std {
   void SetPin(const char c) {
     *$self = c;
   }
+  void SetAnalog(int value) {
+    $self->setAnalog(value);
+  }
 }
 
 %include "net.h"
_______________________________________________
Simulavr-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/simulavr-devel

Reply via email to