Monday, December 14, 2015

So Many Ways to Skin a Cat......




SIMPL code can do this to an otherwise blank screen
Background

I have recently been experimenting with the J1b Forth processor,  running on a Papilio Duo board - a low cost FPGA development board from Gadget Factory.

The J1b has a cycle time of 12.5nS and can conduct an empty Forth DO LOOP in just 100nS. This is seriously quick  - an major asset for such a simple processor.

The only problem I have, is that the J1b is programmed in Forth, on top of it's own assembly language - and neither of these really appeal for quick experimentation.  

Forth is a tremendously powerful language - but you have to practice hard to keep your brain up to speed with it - so this is why I am a proponent of a novel cut down version of Forth - essentially a minimal Forth-Like interpreted language, which I call SIMPL.

From Arduino to ZPUino - and everything between

As I find coding in Forth a bit hard on the brain - I have got interested in other minimal interactive languages - which are ideal for testing out new hardware.

SIMPL was inspired by Ward Cunningham's Txtzyme Interpreter - from 2013 - which is written in C and programmable into various dev boards like Arduino and Teensy.

Txtzyme is a very small text interpreter, where single characters are interpreted as function calls. These are used to invoke the various "hardware helper" functions - that are part of Arduino - such as digitalWrite, analogRead, millis, delay etc.  

Txtzyme only has 13 functions in it's basic form - but the beauty of it is that it forms a minimum framework which is easily extended. Also because it has been written in C (all be it Arduino dialect) it is easily ported to virtually any other microcontroller. The core of Txtzyme uses only about 1300 bytes of program space on an ATmega328.

Txtzyme is a minimalist interpreter, which allows immediate and interactive control of the hardware - from a few serial commands. Txtzyme is Forth-like in it's behaviour, and uses a stack to process commands.

In the last 2 years I have added extra functionality to it, and tried it out on a number of resource limited processors - from the Arduino to custom soft-cores - such as the ZPUino - which runs on the Papilio Duo dev board.

I have added integer maths, and the ability to handle 32 bit numbers.

In the Spring of 2013, I extended Txtzye to allow new user subroutines to be defined, and a means to store these user routines in RAM.  I called the resulting program SIMPL - which is an acronym for Serial Interpreted Minimal Programming Language.

SIMPL has been developed specifically to make interaction with new processor hardware both fun and easy.

Commands take the form of a lowercase letter - usually preceded by a number. Unlike Forth whitespace is rarely used at all - and the space character has a special function of pushing a second numerical parameter onto the stack  - to give two operands for arithmetic etc.

Here are some of the basic commands

d   Allocate a digital pin for input or output
h   Set the allocated port pin high
l    Set the allocated port pin low
m  A millisecond delay
p   print out the value on the top of the stack
u   A microsecond delay
s   Sample the analogue input pin
t   Print out a time stamp in microseconds - useful for timing operations
{   Start a loop of instructions
}   End a loop of instructions
_   Text Identifier for print out   eg. _Hello World_

Then we have arithmetic and logical operators

+  Add the top 2 items on the stack
-   Subtract
*   Multiply
/   Divide

&  Bitwise AND
|   Bitwise OR
~  Invert
^  Bitwise XOR

To light a LED on Digital 13:    13dh     

13d just allocates an output pin  - in this case Digital 13

To flash a LED 10 times:   13d10{h100ml500m}

h is the comand to set the allocated pin high, and l to set it low.

100m is a 100mS delay.

Extending the Language

SIMPL can be extended with "colon definitions"  These start with a colon : and are given a capital letter as their function name - so only 26 new definitions are permitted

For Example, to acknowledge a command by printing ok:   

:O_ok_  

Any text included between the _ _ is printed to the terminal.

So concatenating these commands 

13d10{h100ml500m}O    - flash an LED, on digital 13, 10 times and acknowledge with ok when finished

The size of this program is just 18 bytes plus a carriage return. That makes it small enough to be send as a packet over a wireless link.

You can then give this function another name - like "F" - for flash-LED

:F13d10{h100ml500m}O

Timing

SIMPL has the native ability to be able to time-stamp your code.  For example, if you wanted to generate a million cycles of square wave via an output port:

t1000000{hl}tO

t effectively prints out the microsecond count at the time it is called - so the above example provides a start time and an end time for a million cycle output

The response from this command sequence is 

13569162
17507533

OK

So subtracting the numbers - we can calculate that 1 million output pin toggle cycles was executed in 3.938371 seconds - so a frequency of  253.9kHz. This is approximate because it includes the printout time (11520 characters per second) and the overhead of setting up the loop.

With these few short examples - we can see that SIMPL is very extensible.

Graphics

SIMPL is easily extended to allow any coded function to be called from the terminal. 

I programmed in the ZPUino soft core onto the Papilio Duo, with a modified a version of SIMPL -so that I could take full advantage of the Adafruit GFX library - and output graphics to an 800 x 600 pixel VGA screen.

I have included a SIMPL primitive "g" which wll plot a single pixel at y,x. 

Primitive "a" sets the 16 bit colour value.

To plot a Line we define a new word L   :L 800{kg}   This draws a line 800 pixels long

To fill a field - we define a word F   :F600{kL} which draws 600 consecutive lines  - thus filling the screen

(in each case, k is the decrementing loop variable).

So to combine these into a repetitive screen clear routing  we define a new word S

:SaF   -   clear the screen with colour, a

Finally we set this up in a loop that cycles through all the possible values of a

65535S

At about 5 seconds for a screen wipe - this could take a few hours  (91 hours!)









No comments: