Skip to content

Instantly share code, notes, and snippets.

@monsonite
Created February 9, 2015 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monsonite/97730b0456762da20a98 to your computer and use it in GitHub Desktop.
Save monsonite/97730b0456762da20a98 to your computer and use it in GitHub Desktop.
A SIMPL Interpreter Hacked to run on the Papilio Duo
/*
This is a very quick hack to run SIMPL on a Papilio Duo using the LogicStart shield for some LEDs
The SIMPL Interpreter is between lines 356 and 548
ken.boak@gmail.com 9th Feb 2015
SIMPL described from May 2013 on my Blog
http://sustburbia.blogspot.co.uk/2013/05/txtzyme-minimal-interpreter-and.html
Gadget Factory
LogicStart MegaWing Example
Related library documentation:
http://papilio.cc/index.php?n=Papilio.VGA
created 2014
by Alvaro Lopes and Jack Gassett
http://www.gadgetfactory.net
This example code is in the public domain.
*/
#define circuit LogicStart_Shield
#define FREQ 17000 //Freq for all players
#define LS_JOY_RIGHT 10
#define LS_JOY_LEFT 13
#define LS_JOY_DOWN 12
#define LS_JOY_UP 11
#include "HQVGA.h"
#include <SevenSegHW.h>
#include "SPI.h"
#include <SD.h>
#include "SmallFS.h"
#include "modplayer.h"
#include "ramFS.h"
#include "cbuffer.h"
#include <Timer.h>
MODPLAYER modplayer;
SEVENSEGHW sevenseg;
int ledPins[] = {
48, 50, 52, 5, 6, 7, 8, 9 }; // an array of pin numbers to which LEDs are attached
int ledCount = 8; // the number of pins (i.e. the length of the array)
int switchPins[] = {
0, 1, 2, 3, 4, 42, 44, 46 }; // an array of pin numbers to which Buttons are attached
int switchCount = 8; // the number of pins (i.e. the length of the array)
int buttonState = 0; // variable for reading the pushbutton status
int thisPin;
int ledState = LOW;
unsigned adcvalue = 5;
int cnt = 0;
int extcnt = 0;
int mode = 0;
unsigned channel=0;
int timeout=0;
// ---------------------------------------------------------------------------------------------
// Here are the defines for SIMPL
#define bufRead(addr) (*(unsigned char *)(addr))
#define bufWrite(addr, b) (*(unsigned char *)(addr) = (b))
unsigned char bite;
unsigned int x = 0;
unsigned int y = 0;
int len = 48;
// Define the I?O pins to be used with the shift registers
int sinPin = 5; // Serial input pin from 74HC165
int sclkPin = 6; // Clock pin to 74HC165
int loadPin = 7; // parallel load pin of 74HC165
int latchPin = 8; //Pin connected to ST_CP of 74HC595
int dataPin = 9; //Pin connected to DS of 74HC595
int clockPin = 10; //Pin connected to SH_CP of 74HC595
char array[26][48] = { // Define a 26 x 64 array for the colon definitions
{"6d75{1o708u0o708u}"},
{"9rP8rP12rP4rP6rP2rP3rP1rP"}, // A backward step on a stepper motor
{"6d91{1o585u0o585u}"},
{"6d100{1o532u0o532u}"},
{"6d110{1o484u0o484u}"},
{"1rP3rP2rP6rP4rP12rP8rP9rP"}, // A forward step on a stepper motor
{"6d133{1o484u0o484u}"},
{"_Hello World, and welcome to SIMPL_"},
{"5{ABC}"},
{" "},
{" "},
{" "},
{" "},
{" "},
{" "},
{"1m"}, // Time delay to see stepper motor action
{" "},
{"512{F}0r "},
{"512{B}0r "},
{" "},
};
int d = 5;
char name;
char* parray;
char buf[64];
char* addr;
//-------------------------------------------------------------------------------------------------
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(d,OUTPUT);
pinMode(loadPin, OUTPUT); // Set up the pins needed for the shift registers
pinMode(sclkPin, OUTPUT);
pinMode(sinPin, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
digitalWrite(sclkPin,HIGH); // initialise the clock HIGH
// myservo.attach(4); // attaches the servo on pin 9 to the servo object
// delay(2000);
Serial.println("Type H for Welcome or ? for Help");
parray = &array[0][0]; // parray is the pointer to the first element
//Start SmallFS
if (SmallFS.begin()<0) {
Serial.println("No SmalLFS found.");
}
else{
Serial.println("SmallFS Started.");
}
/*
//Set what wishbone slot the audio passthrough device is connected to.
modplayer.setup(5);
modplayer.loadFile("music.mod");
modplayer.play(true);
//Setup timer for YM and mod players, this generates an interrupt at 17000hz
Timers.begin();
int r = Timers.periodicHz(17000, (bool(*)(void*))timer, 0, 1);
if (r<0) {
Serial.println("Fatal error!");
}
//Setup VGA Hello World
VGA.begin(VGAWISHBONESLOT(9),CHARMAPWISHBONESLOT(10));
VGA.clear();
VGA.setBackgroundColor(BLACK);
VGA.setColor(RED);
VGA.printtext(35,10,"Hello World");
VGA.printtext(15,30, "Hello World RED");
VGA.setColor(GREEN);
VGA.printtext(15,40, "Hello World GREEN");
VGA.setColor(BLUE);
VGA.printtext(15,50, "Hello World BLUE");
VGA.setColor(YELLOW);
VGA.printtext(15,60, "Hello World YELLOW");
VGA.setColor(PURPLE);
VGA.printtext(15,70, "Hello World PURPLE");
VGA.setColor(CYAN);
VGA.printtext(15,80, "Hello World CYAN");
VGA.setColor(WHITE);
VGA.printtext(15,90, "Hello World WHITE");
VGA.setBackgroundColor(WHITE);
VGA.setColor(BLACK);
VGA.printtext(15,100, "Hello World BLACK");
sevenseg.begin(11);
sevenseg.setBrightness(8);
sevenseg.setHexValue(0x8888);
// initialize the LED pins as an output:
for (int thisPin = 0; thisPin < ledCount; thisPin++) {
pinMode(ledPins[thisPin], OUTPUT);
digitalWrite(ledPins[thisPin], LOW);
}
// initialize the switch pins as an input:
for (int thisPin = 0; thisPin < ledCount; thisPin++) {
pinMode(switchPins[thisPin], INPUT);
}
*/
}
bool timer(void)
{
//Interrupt runs at 17KHz
modplayer.zpu_interrupt();
return true;
}
static void up()
{
sevenseg.custom(0,0);
sevenseg.custom(0,1);
sevenseg.custom(SEGB|SEGC|SEGD|SEGE|SEGF,2);
sevenseg.custom(SEGA|SEGB|SEGE|SEGF|SEGG,3);
}
static void down()
{
sevenseg.custom(SEGA|SEGB|SEGC|SEGD,0);
sevenseg.custom(SEGA|SEGB|SEGC|SEGD|SEGE|SEGF,1);
sevenseg.custom(SEGB|SEGC|SEGD|SEGE|SEGF|SEGG,2);
sevenseg.custom(SEGA|SEGB|SEGC|SEGE|SEGF,3);
}
static void right()
{
sevenseg.custom(SEGA|SEGB|SEGC|SEGE|SEGG,0);
sevenseg.custom(SEGA|SEGC|SEGD|SEGE|SEGF,1);
sevenseg.custom(SEGB|SEGC|SEGE|SEGF|SEGG,2);
sevenseg.custom(SEGD|SEGE|SEGF|SEGG,3);
}
static void left()
{
sevenseg.custom(SEGD|SEGE|SEGF,0);
sevenseg.custom(SEGA|SEGD|SEGE|SEGF|SEGG,1);
sevenseg.custom(SEGA|SEGE|SEGF|SEGG,2);
sevenseg.custom(SEGD|SEGE|SEGF|SEGG,3);
}
void loop() {
/*
// put your main code here, to run repeatedly:
if (modplayer.getPlaying() == 1)
modplayer.audiofill();
//Handle LED's and Switches
for (int thisPin = 0; thisPin < switchCount; thisPin++) {
// read the state of the pushbutton value:
buttonState = digitalRead(switchPins[thisPin]);
// check if the switch is on.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPins[thisPin], HIGH);
}
else {
// toggle LED:
digitalWrite(ledPins[thisPin], LOW);
}
}
//Handle joystick and reading SPI ADC
if ((extcnt & 0x17) == 0) {
if (timeout==0) {
if (digitalRead(LS_JOY_UP)) {
//Serial.println("Up");
up();
} else if (digitalRead(LS_JOY_DOWN)) {
//Serial.println("Down");
down();
} else if (digitalRead(LS_JOY_LEFT)) {
//Serial.println("Left");
left();
} else if (digitalRead(LS_JOY_RIGHT)) {
//Serial.println("Right");
right();
}
else {
sevenseg.setHexValue(0x8888);
}
}
cnt++;
}
extcnt++;
if (timeout!=0)
timeout--;
*/
//}
//void loop() // The SIMPL interpreter is just the following 3 functions executed within a loop
// {
txtRead(buf, 64); // Get the next character from the buffer
txtChk(buf); // check if it is a colon definition
txtEval(buf); // Evaluate the character and execute the code associated with it
}
void txtRead (char *p, byte n) {
byte i = 0;
while (i < (n-1)) {
while (!Serial.available());
char ch = Serial.read();
if (ch == '\r' || ch == '\n') break;
if (ch >= ' ' && ch <= '~') {
*p++ = ch;
i++;
}
}
*p = 0;
}
void txtChk (char *buf) { // Check if the text starts with a colon and if so store in temp[]
if (*buf == ':') {
char ch;
int i =0;
while ((ch = *buf++)){
if (ch == ':') {
Serial.println(*buf); // get the name from the first character
name = *buf ;
buf++;
}
bufWrite((parray + (len*(name-65) +i)),*buf);
i++;
}
}
}
void txtEval (char *buf) {
unsigned int k = 0;
char *loop;
char ch;
while ((ch = *buf++)) {
switch (ch) {
case '0': // Ennumerate it to a variable x if the characters are digits
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
x = ch - '0';
while (*buf >= '0' && *buf <= '9') {
x = x*10 + (*buf++ - '0');
}
break;
case 'p': // Print out the value of x
Serial.println(x);
break;
case '=': // more familiar for maths
Serial.println(x);
break;
case 'd':
d = x;
break;
case 'A': // Point the interpreter to the array containing the words
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
name = ch - 65;
addr = parray + (len*name);
txtEval(addr);
break;
case 'y':
y = x;
case '!': // store
y = x;
break;
case '@': // fetch
x = y;
break;
case '+': // Add
x = x+y;
break;
case '-': // Subtract
x = y-x;
break;
case '*': // Multiply
x = x*y;
break;
case '/': // Divide
x = y/x;
break;
case '?': // Print out all the RAM
parray = &array[0][0]; // reset parray to the pointer to the first element
for (int j = 0; j<26; j++) {
Serial.write(j+65); // print the caps word name
Serial.write(20); // space
for (int i=0; i<len; i++) {
bite = bufRead( parray + (j *len )+i); // read the array
Serial.write(bite); // print the character to the serial port
}
Serial.println();
}
for(int i = 0; i <11; i++) { // Print 12 free lines so it looks better on Arduino serial screen
Serial.println();
}
break;
case 'i':
x = digitalRead(d);
break;
case 'o':
digitalWrite(d, x%2);
break;
case 'm':
delay(x);
break;
case 'u':
delayMicroseconds(x);
break;
case '{':
k = x;
loop = buf;
while ((ch = *buf++) && ch != '}') {
}
case '}':
if (k) {
k--;
buf = loop;
}
break;
case 'k':
x = k;
break;
case '_':
while ((ch = *buf++) && ch != '_') {
Serial.print(ch);
}
Serial.println();
break;
case 's':
// x = analogRead(x);
// myservo.write(x); // sets the servo position according to the scaled value
break;
case 'q': // Send an 8 bit byte to the shift register using shiftOut
// PORTB &= ~_BV(0);
// shiftOut(dataPin, clockPin, MSBFIRST, x); // shift out the bits:
// PORTB |= _BV(0);
break;
case 'r': // Send an 16 bit byte to the shift register using shiftOut
// PORTB &= ~_BV(0);
// shiftOut(dataPin, clockPin, MSBFIRST, x>>8); // shift out the high bits:
// shiftOut(dataPin, clockPin, MSBFIRST, x); // shift out the low bits:
// PORTB |= _BV(0);
break;
case 't': // test the inputs from 74HC165 shift registers
// Read incoming word from 74HC165
digitalWrite(loadPin, LOW);
digitalWrite(loadPin, HIGH);
// x = shiftIn(sinPin, sclkPin, MSBFIRST);
digitalWrite(sclkPin,HIGH);
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment