Created
February 9, 2015 22:40
-
-
Save monsonite/97730b0456762da20a98 to your computer and use it in GitHub Desktop.
A SIMPL Interpreter Hacked to run on the Papilio Duo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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 | |
[email protected] 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