From d868ab508fa5ae6acda0d040db2f8c678a54a44f Mon Sep 17 00:00:00 2001 From: David Johnson-Davies Date: Tue, 18 May 2021 09:11:24 +0100 Subject: [PATCH] Version 3.6c - 18th May 2021 Fixes #48. Adds support for Raspberry Pi Pico. --- ulisp-arm.ino | 121 ++++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 52 deletions(-) diff --git a/ulisp-arm.ino b/ulisp-arm.ino index 8880b68..b954c9c 100644 --- a/ulisp-arm.ino +++ b/ulisp-arm.ino @@ -1,5 +1,5 @@ -/* uLisp ARM Version 3.6b - www.ulisp.com - David Johnson-Davies - www.technoblogy.com - 5th May 2021 +/* uLisp ARM Version 3.6c - www.ulisp.com + David Johnson-Davies - www.technoblogy.com - 18th May 2021 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 #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 #error "Board not supported!" #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, #elif defined(CPU_MAX32620) 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 USERFUNCTIONS, ENDFUNCTIONS }; @@ -486,6 +495,13 @@ object *stream (uint8_t streamtype, uint8_t address) { return ptr; } +object *newstring () { + object *ptr = myalloc(); + ptr->type = STRING; + ptr->chars = 0; + return ptr; +} + // Garbage collection 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 error(SAVEIMAGE, invalidarg, arg); if (!file) error2(SAVEIMAGE, PSTR("problem saving to SD card")); - SDWriteInt(file, (uintptr_t)arg); - SDWriteInt(file, imagesize); - SDWriteInt(file, (uintptr_t)GlobalEnv); - SDWriteInt(file, (uintptr_t)GCStack); + SDWrite32(file, (uintptr_t)arg); + SDWrite32(file, imagesize); + SDWrite32(file, (uintptr_t)GlobalEnv); + SDWrite32(file, (uintptr_t)GCStack); #if SYMBOLTABLESIZE > BUFFERSIZE - SDWriteInt(file, (uintptr_t)SymbolTop); + SDWrite32(file, (uintptr_t)SymbolTop); int SymbolUsed = SymbolTop - SymbolTable; for (int i=0; i BUFFERSIZE - SymbolTop = (char *)SDReadInt(file); + SymbolTop = (char *)SDRead32(file); int SymbolUsed = SymbolTop - SymbolTable; for (int i=0; itype = STRING; - GlobalString = NULL; + object *string = newstring(); + GlobalString = string; GlobalStringIndex = 0; return string; } -void buildstring (uint8_t ch, int *chars, object **head) { +void buildstring (uint8_t ch, object *string, int *chars) { static object* tail; static uint8_t shift; if (*chars == 0) { shift = (sizeof(int)-1)*8; *chars = ch<car = cell; + if (cdr(string) == NULL) cdr(string) = cell; else tail->car = cell; cell->car = NULL; cell->chars = *chars; tail = cell; @@ -1349,18 +1364,15 @@ void buildstring (uint8_t ch, int *chars, object **head) { } object *readstring (uint8_t delim, gfun_t gfun) { - object *obj = myalloc(); - obj->type = STRING; + object *obj = newstring(); int ch = gfun(); if (ch == -1) return nil; - object *head = NULL; int chars = 0; while ((ch != delim) && (ch != -1)) { if (ch == '\\') ch = gfun(); - buildstring(ch, &chars, &head); + buildstring(ch, obj, &chars); ch = gfun(); } - obj->cdr = head; return obj; } @@ -1402,7 +1414,7 @@ int gstr () { } void pstr (char c) { - buildstring(c, &GlobalStringIndex, &GlobalString); + buildstring(c, GlobalString, &GlobalStringIndex); } // Lookup variable in environment @@ -1798,6 +1810,8 @@ void checkanalogread (int pin) { if (!((pin>=14 && pin<=27))) error(ANALOGREAD, invalidpin, number(pin)); #elif defined(ARDUINO_TEENSY41) 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 } @@ -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)); #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)); +#elif defined(ARDUINO_RASPBERRY_PI_PICO) + if (!(pin>=0 && pin<=29)) error(ANALOGWRITE, invalidpin, number(pin)); #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}; 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; if (prescaler<0 || prescaler>8) error(NOTE, PSTR("octave out of range"), number(prescaler)); tone(pin, scale[note%12]>>prescaler); @@ -1854,7 +1870,7 @@ void playnote (int pin, int note, int octave) { } void nonote (int pin) { -#if defined(ARDUINO_NRF52840_CLUE) +#if defined(ARDUINO_NRF52840_CLUE) || defined(ARDUINO_RASPBERRY_PI_PICO) noTone(pin); #endif } @@ -2398,10 +2414,10 @@ object *sp_withoutputtostring (object *args, object *env) { object *pair = cons(var, stream(STRINGSTREAM, 0)); push(pair,env); object *string = startstring(WITHOUTPUTTOSTRING); + push(string, GCStack); object *forms = cdr(args); eval(tf_progn(forms,env), env); - string->cdr = GlobalString; - GlobalString = NULL; + pop(GCStack); return string; } @@ -3702,8 +3718,7 @@ object *fn_stringfn (object *args, object *env) { object *arg = first(args); int type = arg->type; if (type == STRING) return arg; - object *obj = myalloc(); - obj->type = STRING; + object *obj = newstring(); if (type == CHARACTER) { object *cell = myalloc(); cell->car = NULL; @@ -3713,14 +3728,12 @@ object *fn_stringfn (object *args, object *env) { } else if (type == SYMBOL) { char *s = symbolname(arg->name); char ch = *s++; - object *head = NULL; int chars = 0; while (ch) { if (ch == '\\') ch = *s++; - buildstring(ch, &chars, &head); + buildstring(ch, arg, &chars); ch = *s++; } - obj->cdr = head; } else error(STRINGFN, PSTR("can't convert to string"), arg); return obj; } @@ -3730,9 +3743,7 @@ object *fn_concatenate (object *args, object *env) { object *arg = first(args); if (arg->name != STRINGFN) error2(CONCATENATE, PSTR("only supports strings")); args = cdr(args); - object *result = myalloc(); - result->type = STRING; - object *head = NULL; + object *result = newstring(); int chars = 0; while (args != NULL) { object *obj = first(args); @@ -3742,14 +3753,13 @@ object *fn_concatenate (object *args, object *env) { int quad = obj->chars; while (quad != 0) { char ch = quad>>((sizeof(int)-1)*8) & 0xFF; - buildstring(ch, &chars, &head); + buildstring(ch, result, &chars); quad = quad<<8; } obj = car(obj); } args = cdr(args); } - result->cdr = head; return result; } @@ -3762,16 +3772,13 @@ object *fn_subseq (object *args, object *env) { int end; args = cddr(args); if (args != NULL) end = checkinteger(SUBSEQ, car(args)); else end = stringlength(arg); - object *result = myalloc(); - result->type = STRING; - object *head = NULL; + object *result = newstring(); int chars = 0; for (int i=start; icdr = head; return result; } @@ -3789,7 +3796,6 @@ object *fn_princtostring (object *args, object *env) { object *arg = first(args); object *obj = startstring(PRINCTOSTRING); prin1object(arg, pstr); - obj->cdr = GlobalString; return obj; } @@ -3798,7 +3804,6 @@ object *fn_prin1tostring (object *args, object *env) { object *arg = first(args); object *obj = startstring(PRIN1TOSTRING); printobject(arg, pstr); - obj->cdr = GlobalString; return obj; } @@ -4080,7 +4085,7 @@ object *fn_analogread (object *args, object *env) { object *fn_analogreference (object *args, object *env) { (void) env; 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")); #else analogReference((eAnalogReference)checkkeyword(ANALOGREFERENCE, arg)); @@ -4298,7 +4303,7 @@ object *fn_format (object *args, object *env) { } n++; } - if (output == nil) { obj->cdr = GlobalString; return obj; } + if (output == nil) return obj; else return nil; } @@ -4827,6 +4832,12 @@ const char string217[] PROGMEM = ":output"; const char string218[] PROGMEM = ":default"; const char string219[] PROGMEM = ":external"; 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 // Insert your own function names here @@ -5125,6 +5136,12 @@ const tbl_entry_t lookup_table[] PROGMEM = { { string218, (fn_ptr_type)DEFAULT, ANALOGREFERENCE }, { string219, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE }, { 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 // Insert your own table entries here @@ -5881,7 +5898,7 @@ void setup () { initenv(); initsleep(); initgfx(); - pfstring(PSTR("uLisp 3.6 "), pserial); pln(pserial); + pfstring(PSTR("uLisp 3.7 "), pserial); pln(pserial); } // Read/Evaluate/Print loop