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 <ke...@koconnor.net> 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 mailing list Simulavr-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/simulavr-devel