[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Simulavr-devel] Add example python script to simulate UART
From: |
Kevin O'Connor |
Subject: |
[Simulavr-devel] Add example python script to simulate UART |
Date: |
Fri, 15 Aug 2014 20:13:06 -0400 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
Hi,
I put together a python script that can read/write to UART pins in
simulavr and display the results. This is similar to the code in
src/ui/serial?x.cpp, but it is entirely contained in a single python
script (it doesn't require additional C code or TCL).
It took me a while to figure out how to do this, so I thought I would
send it to the list in case others need to implement similar
functionality. I'm sending it in the form of a patch to the existing
simple_serial example.
Cheers,
-Kevin
>From 61144e2da027d8d92e823687d705363a62b8f6d4 Mon Sep 17 00:00:00 2001
From: Kevin O'Connor <address@hidden>
Date: Fri, 15 Aug 2014 19:46:20 -0400
Subject: [PATCH] Update simple_serial example with python script to simulate
UART.
The current simple_serial example provides AVR C code that accesses
the hardware UART. However, it doesn't provide a mechanism for
displaying the serial data outside of simulavr. This patch adds a
simple python script that can run the binary, display data received
from the UART, and send data to the UART.
---
examples/simple_serial/Makefile.am | 2 +-
examples/simple_serial/README | 2 +-
examples/simple_serial/simple_serial.py | 99 +++++++++++++++++++++++++++++++++
3 files changed, 101 insertions(+), 2 deletions(-)
create mode 100644 examples/simple_serial/simple_serial.py
diff --git a/examples/simple_serial/Makefile.am
b/examples/simple_serial/Makefile.am
index bebf7a7..f5a3de2 100644
--- a/examples/simple_serial/Makefile.am
+++ b/examples/simple_serial/Makefile.am
@@ -21,7 +21,7 @@ CLEANFILES = $(EXAMPLE).hex $(EXAMPLE).elf $(AVR_OBJS)
do: $(EXAMPLE).elf
- ../../src/simulavr $(SIMULAVR_ARGS)
+ PYTHONPATH=../../src @PYTHON@ simple_serial.py $(AVR_CPU) $<
$(AVR_FREQUENCY)
program: $(EXAMPLE).hex
avrdude -c stk500v2 -b 115200 -p $(AVR_CPU) -P $(SERIAL_AVR) \
diff --git a/examples/simple_serial/README b/examples/simple_serial/README
index 9456914..d606d54 100644
--- a/examples/simple_serial/README
+++ b/examples/simple_serial/README
@@ -26,7 +26,7 @@ Building and running the example:
make
- - Run the example:
+ - Run the example (this requires python to be enabled):
make do
diff --git a/examples/simple_serial/simple_serial.py
b/examples/simple_serial/simple_serial.py
new file mode 100644
index 0000000..b1e738b
--- /dev/null
+++ b/examples/simple_serial/simple_serial.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# Script to interact with simulavr by simulating a serial port.
+import sys
+import pysimulavr
+
+SERIALBITS = 10 # 8N1 = 1 start, 8 data, 1 stop
+BAUD = 19200
+
+# Class to read serial data from AVR serial transmit pin.
+class SerialRxPin(pysimulavr.PySimulationMember, pysimulavr.Pin):
+ def __init__(self):
+ pysimulavr.Pin.__init__(self)
+ pysimulavr.PySimulationMember.__init__(self)
+ self.sc = pysimulavr.SystemClock.Instance()
+ self.delay = 10**9 / BAUD
+ self.current = 0
+ self.pos = -1
+ def SetInState(self, pin):
+ pysimulavr.Pin.SetInState(self, pin)
+ self.state = pin.outState
+ if self.pos < 0 and pin.outState == pin.LOW:
+ self.pos = 0
+ self.sc.Add(self)
+ def DoStep(self, trueHwStep):
+ ishigh = self.state == self.HIGH
+ self.current |= ishigh << self.pos
+ self.pos += 1
+ if not self.pos:
+ return int(self.delay * 1.5)
+ if self.pos >= SERIALBITS:
+ self.handleChar(chr((self.current >> 1) & 0xff))
+ self.pos = -1
+ self.current = 0
+ return -1
+ return self.delay
+ def handleChar(self, c):
+ sys.stdout.write(c)
+ sys.stdout.flush()
+
+# Class to send serial data to AVR serial receive pin.
+class SerialTxPin(pysimulavr.PySimulationMember, pysimulavr.Pin):
+ def __init__(self):
+ pysimulavr.Pin.__init__(self)
+ pysimulavr.PySimulationMember.__init__(self)
+ self.SetPin('H')
+ self.sc = pysimulavr.SystemClock.Instance()
+ self.delay = 10**9 / BAUD
+ self.current = 0
+ self.pos = 0
+ self.queue = ""
+ def DoStep(self, trueHwStep):
+ if not self.pos:
+ if not self.queue:
+ return -1
+ self.current = (ord(self.queue[0]) << 1) | 0x200
+ self.queue = self.queue[1:]
+ newstate = 'L'
+ if self.current & (1 << self.pos):
+ newstate = 'H'
+ self.SetPin(newstate)
+ self.pos += 1
+ if self.pos >= SERIALBITS:
+ self.pos = 0
+ return self.delay
+ def pushChars(self, c):
+ queueEmpty = not self.queue
+ self.queue += c
+ if queueEmpty:
+ self.sc.Add(self)
+
+def main():
+ proc, elffile, speed = sys.argv[1:]
+
+ # launch simulator
+ sc = pysimulavr.SystemClock.Instance()
+ dev = pysimulavr.AvrFactory.instance().makeDevice(proc)
+ dev.Load(elffile)
+ dev.SetClockFreq(10**9 / int(speed))
+ sc.Add(dev)
+
+ # Setup rx pin
+ rxpin = SerialRxPin()
+ net = pysimulavr.Net()
+ net.Add(rxpin)
+ net.Add(dev.GetPin("D1"))
+
+ # Setup tx pin
+ txpin = SerialTxPin()
+ net2 = pysimulavr.Net()
+ net2.Add(dev.GetPin("D0"))
+ net2.Add(txpin)
+
+ # Run loop
+ sc.RunTimeRange(200000)
+ txpin.pushChars("Sending data...")
+ sc.RunTimeRange(400000000)
+
+if __name__ == '__main__':
+ main()
--
1.9.3
- [Simulavr-devel] Add example python script to simulate UART,
Kevin O'Connor <=