Version 3.6c - 18th May 2021

Fixes #48. Adds support for Raspberry Pi Pico.
This commit is contained in:
David Johnson-Davies 2021-05-18 09:11:24 +01:00 committed by GitHub
parent b4aa4f6630
commit d868ab508f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 69 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/* uLisp ARM Version 3.6b - www.ulisp.com /* uLisp ARM Version 3.6c - www.ulisp.com
David Johnson-Davies - www.technoblogy.com - 5th May 2021 David Johnson-Davies - www.technoblogy.com - 18th May 2021
Licensed under the MIT license: https://opensource.org/licenses/MIT Licensed under the MIT license: https://opensource.org/licenses/MIT
*/ */
@ -179,6 +179,13 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#undef MEMBANK #undef MEMBANK
#define MEMBANK DMAMEM #define MEMBANK DMAMEM
#elif defined(ARDUINO_RASPBERRY_PI_PICO) /* NANO_RP2040_CONNECT */
#define WORKSPACESIZE (15360-SDSIZE) /* Objects (8*bytes) */
#define SYMBOLTABLESIZE 1024 /* Bytes */
#define CODESIZE 256 /* Bytes */
#define STACKDIFF 320
#define CPU_RP2040
#else #else
#error "Board not supported!" #error "Board not supported!"
#endif #endif
@ -310,6 +317,8 @@ K_INPUT, K_INPUT_PULLUP, K_INPUT_PULLDOWN, K_OUTPUT, K_AR_DEFAULT, K_AR_INTERNAL
K_INPUT, K_INPUT_PULLUP, K_INPUT_PULLDOWN, K_OUTPUT, K_OUTPUT_OPENDRAIN, K_INPUT, K_INPUT_PULLUP, K_INPUT_PULLDOWN, K_OUTPUT, K_OUTPUT_OPENDRAIN,
#elif defined(CPU_MAX32620) #elif defined(CPU_MAX32620)
K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_EXTERNAL, K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_EXTERNAL,
#elif defined(CPU_RP2040)
K_INPUT, K_INPUT_PULLUP, K_INPUT_PULLDOWN, K_OUTPUT,
#endif #endif
USERFUNCTIONS, ENDFUNCTIONS }; USERFUNCTIONS, ENDFUNCTIONS };
@ -486,6 +495,13 @@ object *stream (uint8_t streamtype, uint8_t address) {
return ptr; return ptr;
} }
object *newstring () {
object *ptr = myalloc();
ptr->type = STRING;
ptr->chars = 0;
return ptr;
}
// Garbage collection // Garbage collection
void markobject (object *obj) { void markobject (object *obj) {
@ -801,20 +817,20 @@ int saveimage (object *arg) {
} else if (arg == NULL || listp(arg)) file = SD.open("ULISP.IMG", O_RDWR | O_CREAT | O_TRUNC); } else if (arg == NULL || listp(arg)) file = SD.open("ULISP.IMG", O_RDWR | O_CREAT | O_TRUNC);
else error(SAVEIMAGE, invalidarg, arg); else error(SAVEIMAGE, invalidarg, arg);
if (!file) error2(SAVEIMAGE, PSTR("problem saving to SD card")); if (!file) error2(SAVEIMAGE, PSTR("problem saving to SD card"));
SDWriteInt(file, (uintptr_t)arg); SDWrite32(file, (uintptr_t)arg);
SDWriteInt(file, imagesize); SDWrite32(file, imagesize);
SDWriteInt(file, (uintptr_t)GlobalEnv); SDWrite32(file, (uintptr_t)GlobalEnv);
SDWriteInt(file, (uintptr_t)GCStack); SDWrite32(file, (uintptr_t)GCStack);
#if SYMBOLTABLESIZE > BUFFERSIZE #if SYMBOLTABLESIZE > BUFFERSIZE
SDWriteInt(file, (uintptr_t)SymbolTop); SDWrite32(file, (uintptr_t)SymbolTop);
int SymbolUsed = SymbolTop - SymbolTable; int SymbolUsed = SymbolTop - SymbolTable;
for (int i=0; i<SymbolUsed; i++) file.write(SymbolTable[i]); for (int i=0; i<SymbolUsed; i++) file.write(SymbolTable[i]);
#endif #endif
for (int i=0; i<CODESIZE; i++) file.write(MyCode[i]); for (int i=0; i<CODESIZE; i++) file.write(MyCode[i]);
for (unsigned int i=0; i<imagesize; i++) { for (unsigned int i=0; i<imagesize; i++) {
object *obj = &Workspace[i]; object *obj = &Workspace[i];
SDWriteInt(file, (uintptr_t)car(obj)); SDWrite32(file, (uintptr_t)car(obj));
SDWriteInt(file, (uintptr_t)cdr(obj)); SDWrite32(file, (uintptr_t)cdr(obj));
} }
file.close(); file.close();
return imagesize; return imagesize;
@ -867,20 +883,20 @@ int loadimage (object *arg) {
else if (arg == NULL) file = SD.open("/ULISP.IMG"); else if (arg == NULL) file = SD.open("/ULISP.IMG");
else error(LOADIMAGE, PSTR("illegal argument"), arg); else error(LOADIMAGE, PSTR("illegal argument"), arg);
if (!file) error2(LOADIMAGE, PSTR("problem loading from SD card")); if (!file) error2(LOADIMAGE, PSTR("problem loading from SD card"));
SDReadInt(file); SDRead32(file);
unsigned int imagesize = SDReadInt(file); unsigned int imagesize = SDRead32(file);
GlobalEnv = (object *)SDReadInt(file); GlobalEnv = (object *)SDRead32(file);
GCStack = (object *)SDReadInt(file); GCStack = (object *)SDRead32(file);
#if SYMBOLTABLESIZE > BUFFERSIZE #if SYMBOLTABLESIZE > BUFFERSIZE
SymbolTop = (char *)SDReadInt(file); SymbolTop = (char *)SDRead32(file);
int SymbolUsed = SymbolTop - SymbolTable; int SymbolUsed = SymbolTop - SymbolTable;
for (int i=0; i<SymbolUsed; i++) SymbolTable[i] = file.read(); for (int i=0; i<SymbolUsed; i++) SymbolTable[i] = file.read();
#endif #endif
for (int i=0; i<CODESIZE; i++) MyCode[i] = file.read(); for (int i=0; i<CODESIZE; i++) MyCode[i] = file.read();
for (unsigned int i=0; i<imagesize; i++) { for (unsigned int i=0; i<imagesize; i++) {
object *obj = &Workspace[i]; object *obj = &Workspace[i];
car(obj) = (object *)SDReadInt(file); car(obj) = (object *)SDRead32(file);
cdr(obj) = (object *)SDReadInt(file); cdr(obj) = (object *)SDRead32(file);
} }
file.close(); file.close();
gc(NULL, NULL); gc(NULL, NULL);
@ -928,7 +944,7 @@ void autorunimage () {
SD.begin(SDCARD_SS_PIN); SD.begin(SDCARD_SS_PIN);
File file = SD.open("ULISP.IMG"); File file = SD.open("ULISP.IMG");
if (!file) error2(0, PSTR("problem autorunning from SD card")); if (!file) error2(0, PSTR("problem autorunning from SD card"));
object *autorun = (object *)SDReadInt(file); object *autorun = (object *)SDRead32(file);
file.close(); file.close();
if (autorun != NULL) { if (autorun != NULL) {
loadimage(NULL); loadimage(NULL);
@ -1322,21 +1338,20 @@ void indent (uint8_t spaces, char ch, pfun_t pfun) {
} }
object *startstring (symbol_t name) { object *startstring (symbol_t name) {
object *string = myalloc(); object *string = newstring();
string->type = STRING; GlobalString = string;
GlobalString = NULL;
GlobalStringIndex = 0; GlobalStringIndex = 0;
return string; return string;
} }
void buildstring (uint8_t ch, int *chars, object **head) { void buildstring (uint8_t ch, object *string, int *chars) {
static object* tail; static object* tail;
static uint8_t shift; static uint8_t shift;
if (*chars == 0) { if (*chars == 0) {
shift = (sizeof(int)-1)*8; shift = (sizeof(int)-1)*8;
*chars = ch<<shift; *chars = ch<<shift;
object *cell = myalloc(); object *cell = myalloc();
if (*head == NULL) *head = cell; else tail->car = cell; if (cdr(string) == NULL) cdr(string) = cell; else tail->car = cell;
cell->car = NULL; cell->car = NULL;
cell->chars = *chars; cell->chars = *chars;
tail = cell; tail = cell;
@ -1349,18 +1364,15 @@ void buildstring (uint8_t ch, int *chars, object **head) {
} }
object *readstring (uint8_t delim, gfun_t gfun) { object *readstring (uint8_t delim, gfun_t gfun) {
object *obj = myalloc(); object *obj = newstring();
obj->type = STRING;
int ch = gfun(); int ch = gfun();
if (ch == -1) return nil; if (ch == -1) return nil;
object *head = NULL;
int chars = 0; int chars = 0;
while ((ch != delim) && (ch != -1)) { while ((ch != delim) && (ch != -1)) {
if (ch == '\\') ch = gfun(); if (ch == '\\') ch = gfun();
buildstring(ch, &chars, &head); buildstring(ch, obj, &chars);
ch = gfun(); ch = gfun();
} }
obj->cdr = head;
return obj; return obj;
} }
@ -1402,7 +1414,7 @@ int gstr () {
} }
void pstr (char c) { void pstr (char c) {
buildstring(c, &GlobalStringIndex, &GlobalString); buildstring(c, GlobalString, &GlobalStringIndex);
} }
// Lookup variable in environment // Lookup variable in environment
@ -1798,6 +1810,8 @@ void checkanalogread (int pin) {
if (!((pin>=14 && pin<=27))) error(ANALOGREAD, invalidpin, number(pin)); if (!((pin>=14 && pin<=27))) error(ANALOGREAD, invalidpin, number(pin));
#elif defined(ARDUINO_TEENSY41) #elif defined(ARDUINO_TEENSY41)
if (!((pin>=14 && pin<=27) || (pin>=38 && pin<=41))) error(ANALOGREAD, invalidpin, number(pin)); if (!((pin>=14 && pin<=27) || (pin>=38 && pin<=41))) error(ANALOGREAD, invalidpin, number(pin));
#elif defined(ARDUINO_RASPBERRY_PI_PICO)
if (!(pin>=26 && pin<=29)) error(ANALOGREAD, invalidpin, number(pin));
#endif #endif
} }
@ -1838,6 +1852,8 @@ void checkanalogwrite (int pin) {
if (!((pin>=0 && pin<=15) || (pin>=18 && pin<=19) || (pin>=22 && pin<=25) || (pin>=28 && pin<=29) || (pin>=33 && pin<=39))) error(ANALOGWRITE, invalidpin, number(pin)); if (!((pin>=0 && pin<=15) || (pin>=18 && pin<=19) || (pin>=22 && pin<=25) || (pin>=28 && pin<=29) || (pin>=33 && pin<=39))) error(ANALOGWRITE, invalidpin, number(pin));
#elif defined(ARDUINO_TEENSY41) #elif defined(ARDUINO_TEENSY41)
if (!((pin>=0 && pin<=15) || (pin>=18 && pin<=19) || (pin>=22 && pin<=25) || (pin>=28 && pin<=29) || pin==33 || (pin>=36 && pin<=37))) error(ANALOGWRITE, invalidpin, number(pin)); if (!((pin>=0 && pin<=15) || (pin>=18 && pin<=19) || (pin>=22 && pin<=25) || (pin>=28 && pin<=29) || pin==33 || (pin>=36 && pin<=37))) error(ANALOGWRITE, invalidpin, number(pin));
#elif defined(ARDUINO_RASPBERRY_PI_PICO)
if (!(pin>=0 && pin<=29)) error(ANALOGWRITE, invalidpin, number(pin));
#endif #endif
} }
@ -1846,7 +1862,7 @@ void checkanalogwrite (int pin) {
const int scale[] PROGMEM = {4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902}; const int scale[] PROGMEM = {4186,4435,4699,4978,5274,5588,5920,6272,6645,7040,7459,7902};
void playnote (int pin, int note, int octave) { void playnote (int pin, int note, int octave) {
#if defined(ARDUINO_NRF52840_CLUE) #if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_RASPBERRY_PI_PICO)
int prescaler = 8 - octave - note/12; int prescaler = 8 - octave - note/12;
if (prescaler<0 || prescaler>8) error(NOTE, PSTR("octave out of range"), number(prescaler)); if (prescaler<0 || prescaler>8) error(NOTE, PSTR("octave out of range"), number(prescaler));
tone(pin, scale[note%12]>>prescaler); tone(pin, scale[note%12]>>prescaler);
@ -1854,7 +1870,7 @@ void playnote (int pin, int note, int octave) {
} }
void nonote (int pin) { void nonote (int pin) {
#if defined(ARDUINO_NRF52840_CLUE) #if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_RASPBERRY_PI_PICO)
noTone(pin); noTone(pin);
#endif #endif
} }
@ -2398,10 +2414,10 @@ object *sp_withoutputtostring (object *args, object *env) {
object *pair = cons(var, stream(STRINGSTREAM, 0)); object *pair = cons(var, stream(STRINGSTREAM, 0));
push(pair,env); push(pair,env);
object *string = startstring(WITHOUTPUTTOSTRING); object *string = startstring(WITHOUTPUTTOSTRING);
push(string, GCStack);
object *forms = cdr(args); object *forms = cdr(args);
eval(tf_progn(forms,env), env); eval(tf_progn(forms,env), env);
string->cdr = GlobalString; pop(GCStack);
GlobalString = NULL;
return string; return string;
} }
@ -3702,8 +3718,7 @@ object *fn_stringfn (object *args, object *env) {
object *arg = first(args); object *arg = first(args);
int type = arg->type; int type = arg->type;
if (type == STRING) return arg; if (type == STRING) return arg;
object *obj = myalloc(); object *obj = newstring();
obj->type = STRING;
if (type == CHARACTER) { if (type == CHARACTER) {
object *cell = myalloc(); object *cell = myalloc();
cell->car = NULL; cell->car = NULL;
@ -3713,14 +3728,12 @@ object *fn_stringfn (object *args, object *env) {
} else if (type == SYMBOL) { } else if (type == SYMBOL) {
char *s = symbolname(arg->name); char *s = symbolname(arg->name);
char ch = *s++; char ch = *s++;
object *head = NULL;
int chars = 0; int chars = 0;
while (ch) { while (ch) {
if (ch == '\\') ch = *s++; if (ch == '\\') ch = *s++;
buildstring(ch, &chars, &head); buildstring(ch, arg, &chars);
ch = *s++; ch = *s++;
} }
obj->cdr = head;
} else error(STRINGFN, PSTR("can't convert to string"), arg); } else error(STRINGFN, PSTR("can't convert to string"), arg);
return obj; return obj;
} }
@ -3730,9 +3743,7 @@ object *fn_concatenate (object *args, object *env) {
object *arg = first(args); object *arg = first(args);
if (arg->name != STRINGFN) error2(CONCATENATE, PSTR("only supports strings")); if (arg->name != STRINGFN) error2(CONCATENATE, PSTR("only supports strings"));
args = cdr(args); args = cdr(args);
object *result = myalloc(); object *result = newstring();
result->type = STRING;
object *head = NULL;
int chars = 0; int chars = 0;
while (args != NULL) { while (args != NULL) {
object *obj = first(args); object *obj = first(args);
@ -3742,14 +3753,13 @@ object *fn_concatenate (object *args, object *env) {
int quad = obj->chars; int quad = obj->chars;
while (quad != 0) { while (quad != 0) {
char ch = quad>>((sizeof(int)-1)*8) & 0xFF; char ch = quad>>((sizeof(int)-1)*8) & 0xFF;
buildstring(ch, &chars, &head); buildstring(ch, result, &chars);
quad = quad<<8; quad = quad<<8;
} }
obj = car(obj); obj = car(obj);
} }
args = cdr(args); args = cdr(args);
} }
result->cdr = head;
return result; return result;
} }
@ -3762,16 +3772,13 @@ object *fn_subseq (object *args, object *env) {
int end; int end;
args = cddr(args); args = cddr(args);
if (args != NULL) end = checkinteger(SUBSEQ, car(args)); else end = stringlength(arg); if (args != NULL) end = checkinteger(SUBSEQ, car(args)); else end = stringlength(arg);
object *result = myalloc(); object *result = newstring();
result->type = STRING;
object *head = NULL;
int chars = 0; int chars = 0;
for (int i=start; i<end; i++) { for (int i=start; i<end; i++) {
char ch = nthchar(arg, i); char ch = nthchar(arg, i);
if (ch == 0) error2(SUBSEQ, PSTR("index out of range")); if (ch == 0) error2(SUBSEQ, PSTR("index out of range"));
buildstring(ch, &chars, &head); buildstring(ch, result, &chars);
} }
result->cdr = head;
return result; return result;
} }
@ -3789,7 +3796,6 @@ object *fn_princtostring (object *args, object *env) {
object *arg = first(args); object *arg = first(args);
object *obj = startstring(PRINCTOSTRING); object *obj = startstring(PRINCTOSTRING);
prin1object(arg, pstr); prin1object(arg, pstr);
obj->cdr = GlobalString;
return obj; return obj;
} }
@ -3798,7 +3804,6 @@ object *fn_prin1tostring (object *args, object *env) {
object *arg = first(args); object *arg = first(args);
object *obj = startstring(PRIN1TOSTRING); object *obj = startstring(PRIN1TOSTRING);
printobject(arg, pstr); printobject(arg, pstr);
obj->cdr = GlobalString;
return obj; return obj;
} }
@ -4080,7 +4085,7 @@ object *fn_analogread (object *args, object *env) {
object *fn_analogreference (object *args, object *env) { object *fn_analogreference (object *args, object *env) {
(void) env; (void) env;
object *arg = first(args); object *arg = first(args);
#if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(MAX32620) #if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(MAX32620) || defined(ARDUINO_RASPBERRY_PI_PICO)
error2(ANALOGREFERENCE, PSTR("not supported")); error2(ANALOGREFERENCE, PSTR("not supported"));
#else #else
analogReference((eAnalogReference)checkkeyword(ANALOGREFERENCE, arg)); analogReference((eAnalogReference)checkkeyword(ANALOGREFERENCE, arg));
@ -4298,7 +4303,7 @@ object *fn_format (object *args, object *env) {
} }
n++; n++;
} }
if (output == nil) { obj->cdr = GlobalString; return obj; } if (output == nil) return obj;
else return nil; else return nil;
} }
@ -4827,6 +4832,12 @@ const char string217[] PROGMEM = ":output";
const char string218[] PROGMEM = ":default"; const char string218[] PROGMEM = ":default";
const char string219[] PROGMEM = ":external"; const char string219[] PROGMEM = ":external";
const char string220[] PROGMEM = ""; const char string220[] PROGMEM = "";
#elif defined(CPU_RP2040)
const char string215[] PROGMEM = ":input";
const char string216[] PROGMEM = ":input-pullup";
const char string217[] PROGMEM = ":input-pulldown";
const char string218[] PROGMEM = ":output";
const char string219[] PROGMEM = "";
#endif #endif
// Insert your own function names here // Insert your own function names here
@ -5125,6 +5136,12 @@ const tbl_entry_t lookup_table[] PROGMEM = {
{ string218, (fn_ptr_type)DEFAULT, ANALOGREFERENCE }, { string218, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
{ string219, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE }, { string219, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
{ string220, NULL, 0x00 }, { string220, NULL, 0x00 },
#elif defined(CPU_RP2040)
{ string215, (fn_ptr_type)INPUT, PINMODE },
{ string216, (fn_ptr_type)INPUT_PULLUP, PINMODE },
{ string217, (fn_ptr_type)INPUT_PULLDOWN, PINMODE },
{ string218, (fn_ptr_type)OUTPUT, PINMODE },
{ string219, NULL, 0x00 },
#endif #endif
// Insert your own table entries here // Insert your own table entries here
@ -5881,7 +5898,7 @@ void setup () {
initenv(); initenv();
initsleep(); initsleep();
initgfx(); initgfx();
pfstring(PSTR("uLisp 3.6 "), pserial); pln(pserial); pfstring(PSTR("uLisp 3.7 "), pserial); pln(pserial);
} }
// Read/Evaluate/Print loop // Read/Evaluate/Print loop