Version 3.6b - 5th May 2021

Adds save-image to flash on ATSAMD21.
This commit is contained in:
David Johnson-Davies 2021-05-05 09:47:15 +01:00 committed by GitHub
parent 358a44e7ba
commit b4aa4f6630
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 215 additions and 132 deletions

View File

@ -1,5 +1,5 @@
/* uLisp ARM Version 3.6 - www.ulisp.com /* uLisp ARM Version 3.6b - www.ulisp.com
David Johnson-Davies - www.technoblogy.com - 4th April 2021 David Johnson-Davies - www.technoblogy.com - 5th May 2021
Licensed under the MIT license: https://opensource.org/licenses/MIT Licensed under the MIT license: https://opensource.org/licenses/MIT
*/ */
@ -57,25 +57,29 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#define RAMFUNC __attribute__ ((section (".ramfunctions"))) #define RAMFUNC __attribute__ ((section (".ramfunctions")))
#define MEMBANK #define MEMBANK
#if defined(ARDUINO_ITSYBITSY_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) #if defined(ARDUINO_GEMMA_M0) || defined(ARDUINO_SEEED_XIAO_M0)
#define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */
#define DATAFLASHSIZE 2048000 /* 2 MBytes */ #define EEPROMFLASH
#define FLASHSIZE 32768 /* Bytes */
#define SYMBOLTABLESIZE 512 /* Bytes */
#define CODESIZE 128 /* Bytes */
#define STACKDIFF 320
#define CPU_ATSAMD21
#elif defined(ARDUINO_ITSYBITSY_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS)
#define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */
#define DATAFLASH
#define FLASHSIZE 2048000 /* 2 MBytes */
#define SYMBOLTABLESIZE 512 /* Bytes */ #define SYMBOLTABLESIZE 512 /* Bytes */
#define CODESIZE 128 /* Bytes */ #define CODESIZE 128 /* Bytes */
#define SDCARD_SS_PIN 4 #define SDCARD_SS_PIN 4
#define STACKDIFF 320 #define STACKDIFF 320
#define CPU_ATSAMD21 #define CPU_ATSAMD21
#elif defined(ARDUINO_GEMMA_M0)
#define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */
#define SYMBOLTABLESIZE 512 /* Bytes */
#define CODESIZE 128 /* Bytes */
#define STACKDIFF 320
#define CPU_ATSAMD21
#elif defined(ARDUINO_METRO_M4) || defined(ARDUINO_ITSYBITSY_M4) || defined(ARDUINO_FEATHER_M4) || defined(ARDUINO_PYBADGE_M4) || defined(ARDUINO_PYGAMER_M4) #elif defined(ARDUINO_METRO_M4) || defined(ARDUINO_ITSYBITSY_M4) || defined(ARDUINO_FEATHER_M4) || defined(ARDUINO_PYBADGE_M4) || defined(ARDUINO_PYGAMER_M4)
#define WORKSPACESIZE (20480-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (20480-SDSIZE) /* Objects (8*bytes) */
#define DATAFLASHSIZE 2048000 /* 2 MBytes */ #define DATAFLASH
#define FLASHSIZE 2048000 /* 2 MBytes */
#define SYMBOLTABLESIZE 1024 /* Bytes */ #define SYMBOLTABLESIZE 1024 /* Bytes */
#define CODESIZE 256 /* Bytes */ #define CODESIZE 256 /* Bytes */
#define SDCARD_SS_PIN 10 #define SDCARD_SS_PIN 10
@ -84,7 +88,8 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#elif defined(ARDUINO_GRAND_CENTRAL_M4) #elif defined(ARDUINO_GRAND_CENTRAL_M4)
#define WORKSPACESIZE (28672-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (28672-SDSIZE) /* Objects (8*bytes) */
#define DATAFLASHSIZE 8192000 /* 8 MBytes */ #define DATAFLASH
#define FLASHSIZE 8192000 /* 8 MBytes */
#define SYMBOLTABLESIZE 1024 /* Bytes */ #define SYMBOLTABLESIZE 1024 /* Bytes */
#define CODESIZE 256 /* Bytes */ #define CODESIZE 256 /* Bytes */
#define STACKDIFF 400 #define STACKDIFF 400
@ -92,6 +97,8 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#elif defined(ARDUINO_SAMD_MKRZERO) #elif defined(ARDUINO_SAMD_MKRZERO)
#define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */
#define EEPROMFLASH
#define FLASHSIZE 32768 /* Bytes */
#define SYMBOLTABLESIZE 512 /* Bytes */ #define SYMBOLTABLESIZE 512 /* Bytes */
#define CODESIZE 128 /* Bytes */ #define CODESIZE 128 /* Bytes */
#define STACKDIFF 840 #define STACKDIFF 840
@ -99,6 +106,8 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#elif defined(ARDUINO_SAMD_ZERO) /* Put this last, otherwise overrides the Adafruit boards */ #elif defined(ARDUINO_SAMD_ZERO) /* Put this last, otherwise overrides the Adafruit boards */
#define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (2816-SDSIZE) /* Objects (8*bytes) */
#define EEPROMFLASH
#define FLASHSIZE 32768 /* Bytes */
#define SYMBOLTABLESIZE 512 /* Bytes */ #define SYMBOLTABLESIZE 512 /* Bytes */
#define CODESIZE 128 /* Bytes */ #define CODESIZE 128 /* Bytes */
#define SDCARD_SS_PIN 10 #define SDCARD_SS_PIN 10
@ -135,7 +144,8 @@ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RS
#elif defined(ARDUINO_NRF52840_ITSYBITSY) || defined(ARDUINO_NRF52840_CLUE) #elif defined(ARDUINO_NRF52840_ITSYBITSY) || defined(ARDUINO_NRF52840_CLUE)
#define WORKSPACESIZE (20992-SDSIZE) /* Objects (8*bytes) */ #define WORKSPACESIZE (20992-SDSIZE) /* Objects (8*bytes) */
#define DATAFLASHSIZE 2048000 /* 2 MBytes */ #define DATAFLASH
#define FLASHSIZE 2048000 /* 2 MBytes */
#define SYMBOLTABLESIZE 1024 /* Bytes */ #define SYMBOLTABLESIZE 1024 /* Bytes */
#define CODESIZE 256 /* Bytes */ #define CODESIZE 256 /* Bytes */
#define STACKDIFF 1200 #define STACKDIFF 1200
@ -260,7 +270,6 @@ typedef struct {
typedef int (*gfun_t)(); typedef int (*gfun_t)();
typedef void (*pfun_t)(char); typedef void (*pfun_t)(char);
typedef int PinMode;
enum function { NIL, TEE, NOTHING, OPTIONAL, INITIALELEMENT, ELEMENTTYPE, BIT, AMPREST, LAMBDA, LET, enum function { NIL, TEE, NOTHING, OPTIONAL, INITIALELEMENT, ELEMENTTYPE, BIT, AMPREST, LAMBDA, LET,
LETSTAR, CLOSURE, SPECIAL_FORMS, QUOTE, OR, DEFUN, DEFVAR, SETQ, LOOP, RETURN, PUSH, POP, INCF, DECF, LETSTAR, CLOSURE, SPECIAL_FORMS, QUOTE, OR, DEFUN, DEFVAR, SETQ, LOOP, RETURN, PUSH, POP, INCF, DECF,
@ -600,11 +609,17 @@ char *MakeFilename (object *arg) {
// Save-image and load-image // Save-image and load-image
#if defined(sdcardsupport) #if defined(sdcardsupport)
void SDWriteInt (File file, int data) { void SDWrite32 (File file, int data) {
file.write(data & 0xFF); file.write(data>>8 & 0xFF); file.write(data & 0xFF); file.write(data>>8 & 0xFF);
file.write(data>>16 & 0xFF); file.write(data>>24 & 0xFF); file.write(data>>16 & 0xFF); file.write(data>>24 & 0xFF);
} }
#elif defined(DATAFLASHSIZE)
int SDRead32 (File file) {
uintptr_t b0 = file.read(); uintptr_t b1 = file.read();
uintptr_t b2 = file.read(); uintptr_t b3 = file.read();
return b0 | b1<<8 | b2<<16 | b3<<24;
}
#elif defined(DATAFLASH)
// Winbond DataFlash support for Adafruit M4 Express boards // Winbond DataFlash support for Adafruit M4 Express boards
#define PAGEPROG 0x02 #define PAGEPROG 0x02
#define READSTATUS 0x05 #define READSTATUS 0x05
@ -620,68 +635,19 @@ const int sck = 38, ssel = 39, mosi = 37, miso = 36;
const int sck = PIN_QSPI_SCK, ssel = PIN_QSPI_CS, mosi = PIN_QSPI_IO0, miso = PIN_QSPI_IO1; const int sck = PIN_QSPI_SCK, ssel = PIN_QSPI_CS, mosi = PIN_QSPI_IO0, miso = PIN_QSPI_IO1;
#endif #endif
boolean FlashSetup () { void FlashBusy () {
uint8_t manID, devID; digitalWrite(ssel, 0);
digitalWrite(ssel, HIGH); pinMode(ssel, OUTPUT); FlashWrite(READSTATUS);
pinMode(sck, OUTPUT); while (FlashReadByte() & 1 != 0);
pinMode(mosi, OUTPUT); digitalWrite(ssel, 1);
pinMode(miso, INPUT);
digitalWrite(sck, LOW); digitalWrite(mosi, HIGH);
digitalWrite(ssel, LOW);
FlashWrite(READID);
for(uint8_t i=0; i<4; i++) manID = FlashRead();
devID = FlashRead();
digitalWrite(ssel, HIGH);
return (devID == 0x14 || devID == 0x15 || devID == 0x16); // Found correct device
} }
inline void FlashWrite (uint8_t data) { inline void FlashWrite (uint8_t data) {
shiftOut(mosi, sck, MSBFIRST, data); shiftOut(mosi, sck, MSBFIRST, data);
} }
void FlashBusy () {
digitalWrite(ssel, 0);
FlashWrite(READSTATUS);
while (FlashRead() & 1 != 0);
digitalWrite(ssel, 1);
}
void FlashWriteEnable () {
digitalWrite(ssel, 0);
FlashWrite(WRITEENABLE);
digitalWrite(ssel, 1);
}
void FlashBeginRead () {
FlashBusy();
digitalWrite(ssel, 0);
FlashWrite(READDATA);
FlashWrite(0); FlashWrite(0); FlashWrite(0);
}
inline uint8_t FlashRead () {
int data;
return shiftIn(miso, sck, MSBFIRST);
}
inline void FlashEndRead(void) {
digitalWrite(ssel, 1);
}
void FlashBeginWrite (int blocks) {
// Erase 64K
for (int b=0; b<blocks; b++) {
FlashWriteEnable();
digitalWrite(ssel, 0);
FlashWrite(BLOCK64K);
FlashWrite(b); FlashWrite(0); FlashWrite(0);
digitalWrite(ssel, 1);
FlashBusy();
}
}
inline uint8_t FlashReadByte () { inline uint8_t FlashReadByte () {
return FlashRead(); return shiftIn(miso, sck, MSBFIRST);
} }
void FlashWriteByte (uint32_t *addr, uint8_t data) { void FlashWriteByte (uint32_t *addr, uint8_t data) {
@ -700,14 +666,127 @@ void FlashWriteByte (uint32_t *addr, uint8_t data) {
(*addr)++; (*addr)++;
} }
inline void FlashEndWrite (void) { void FlashWriteEnable () {
digitalWrite(ssel, 0);
FlashWrite(WRITEENABLE);
digitalWrite(ssel, 1);
}
boolean FlashCheck () {
uint8_t manID, devID;
digitalWrite(ssel, HIGH); pinMode(ssel, OUTPUT);
pinMode(sck, OUTPUT);
pinMode(mosi, OUTPUT);
pinMode(miso, INPUT);
digitalWrite(sck, LOW); digitalWrite(mosi, HIGH);
digitalWrite(ssel, LOW);
FlashWrite(READID);
for(uint8_t i=0; i<4; i++) manID = FlashReadByte();
devID = FlashReadByte();
digitalWrite(ssel, HIGH);
return (devID == 0x14 || devID == 0x15 || devID == 0x16); // true = found correct device
}
void FlashBeginWrite (uint32_t *addr, uint32_t bytes) {
(void) addr;
uint32_t blocks = (bytes+65535)/65536;
// Erase 64K
for (int b=0; b<blocks; b++) {
FlashWriteEnable();
digitalWrite(ssel, 0);
FlashWrite(BLOCK64K);
FlashWrite(b); FlashWrite(0); FlashWrite(0);
digitalWrite(ssel, 1);
FlashBusy();
}
}
void FlashWrite32 (uint32_t *addr, uint32_t data) {
FlashWriteByte(addr, data & 0xFF); FlashWriteByte(addr, data>>8 & 0xFF);
FlashWriteByte(addr, data>>16 & 0xFF); FlashWriteByte(addr, data>>24 & 0xFF);
}
inline void FlashEndWrite (uint32_t *addr) {
(void) addr;
digitalWrite(ssel, 1); digitalWrite(ssel, 1);
FlashBusy(); FlashBusy();
} }
void FlashWriteInt (uint32_t *addr, int data) { void FlashBeginRead (uint32_t *addr) {
FlashWriteByte(addr, data & 0xFF); FlashWriteByte(addr, data>>8 & 0xFF); (void) addr;
FlashWriteByte(addr, data>>16 & 0xFF); FlashWriteByte(addr, data>>24 & 0xFF); FlashBusy();
digitalWrite(ssel, 0);
FlashWrite(READDATA);
FlashWrite(0); FlashWrite(0); FlashWrite(0);
}
uint32_t FlashRead32 (uint32_t *addr) {
(void) addr;
uint8_t b0 = FlashReadByte(); uint8_t b1 = FlashReadByte();
uint8_t b2 = FlashReadByte(); uint8_t b3 = FlashReadByte();
return b0 | b1<<8 | b2<<16 | b3<<24;
}
inline void FlashEndRead(uint32_t *addr) {
(void) addr;
digitalWrite(ssel, 1);
}
#elif defined(EEPROMFLASH)
// For ATSAMD21
__attribute__((__aligned__(256))) static const uint8_t flash_store[FLASHSIZE] = { };
void row_erase (const volatile void *addr) {
NVMCTRL->ADDR.reg = ((uint32_t)addr) / 2;
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER;
while (!NVMCTRL->INTFLAG.bit.READY);
}
void page_clear () {
// Execute "PBC" Page Buffer Clear
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
while (NVMCTRL->INTFLAG.bit.READY == 0);
}
void page_write () {
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
while (NVMCTRL->INTFLAG.bit.READY == 0);
}
boolean FlashCheck() {
return true;
}
void FlashBeginWrite(uint32_t *addr, uint32_t bytes) {
(void) bytes;
*addr = (uint32_t)flash_store;
// Disable automatic page write
NVMCTRL->CTRLB.bit.MANW = 1;
}
void FlashWrite32 (uint32_t *addr, uint32_t data) {
if (((*addr) & 0xFF) == 0) row_erase((const volatile void *)(*addr));
if (((*addr) & 0x3F) == 0) page_clear();
*(volatile uint32_t *)(*addr) = data;
(*addr) = (*addr) + 4;
if (((*addr) & 0x3F) == 0) page_write();
}
void FlashEndWrite (uint32_t *addr) {
if (((*addr) & 0x3F) != 0) page_write();
}
void FlashBeginRead(uint32_t *addr) {
*addr = (uint32_t)flash_store;
}
uint32_t FlashRead32 (uint32_t *addr) {
uint32_t data = *(volatile const uint32_t *)(*addr);
(*addr) = (*addr) + 4;
return data;
}
void FlashEndRead (uint32_t *addr) {
} }
#endif #endif
@ -739,31 +818,39 @@ int saveimage (object *arg) {
} }
file.close(); file.close();
return imagesize; return imagesize;
#elif defined(DATAFLASHSIZE) #elif defined(DATAFLASH) || defined(EEPROMFLASH)
unsigned int imagesize = compactimage(&arg); unsigned int imagesize = compactimage(&arg);
if (!(arg == NULL || listp(arg))) error(SAVEIMAGE, invalidarg, arg); if (!(arg == NULL || listp(arg))) error(SAVEIMAGE, invalidarg, arg);
if (!FlashSetup()) error2(SAVEIMAGE, PSTR("no DataFlash found.")); if (!FlashCheck()) error2(SAVEIMAGE, PSTR("flash not available"));
// Save to DataFlash // Save to flash
int SymbolUsed = SymbolTop - SymbolTable; uint32_t SymbolUsed = SymbolTop - SymbolTable;
int bytesneeded = 20 + SymbolUsed + CODESIZE + imagesize*8; uint32_t bytesneeded = 20 + SymbolUsed + CODESIZE + imagesize*8;
if (bytesneeded > DATAFLASHSIZE) error(SAVEIMAGE, PSTR("image too large"), number(imagesize)); if (bytesneeded > FLASHSIZE) error(SAVEIMAGE, PSTR("image too large"), number(imagesize));
uint32_t addr = 0; uint32_t addr;
FlashBeginWrite((bytesneeded+65535)/65536); FlashBeginWrite(&addr, bytesneeded);
FlashWriteInt(&addr, (uintptr_t)arg); FlashWrite32(&addr, (uintptr_t)arg);
FlashWriteInt(&addr, imagesize); FlashWrite32(&addr, imagesize);
FlashWriteInt(&addr, (uintptr_t)GlobalEnv); FlashWrite32(&addr, (uintptr_t)GlobalEnv);
FlashWriteInt(&addr, (uintptr_t)GCStack); FlashWrite32(&addr, (uintptr_t)GCStack);
#if SYMBOLTABLESIZE > BUFFERSIZE #if SYMBOLTABLESIZE > BUFFERSIZE
FlashWriteInt(&addr, (uintptr_t)SymbolTop); FlashWrite32(&addr, (uintptr_t)SymbolTop);
for (int i=0; i<SymbolUsed; i++) FlashWriteByte(&addr, SymbolTable[i]); for (int i=0; i<(SymbolUsed+3)/4; i=i+4) {
union { uint32_t u32; uint8_t u8[4]; };
u8[0] = SymbolTable[i]; u8[1] = SymbolTable[i+1]; u8[2] = SymbolTable[i+2]; u8[3] = SymbolTable[i+3];
FlashWrite32(&addr, u32);
}
#endif #endif
for (int i=0; i<CODESIZE; i++) FlashWriteByte(&addr, MyCode[i]); for (int i=0; i<CODESIZE; i=i+4) {
union { uint32_t u32; uint8_t u8[4]; };
u8[0] = MyCode[i]; u8[1] = MyCode[i+1]; u8[2] = MyCode[i+2]; u8[3] = MyCode[i+3];
FlashWrite32(&addr, u32);
}
for (unsigned int i=0; i<imagesize; i++) { for (unsigned int i=0; i<imagesize; i++) {
object *obj = &Workspace[i]; object *obj = &Workspace[i];
FlashWriteInt(&addr, (uintptr_t)car(obj)); FlashWrite32(&addr, (uintptr_t)car(obj));
FlashWriteInt(&addr, (uintptr_t)cdr(obj)); FlashWrite32(&addr, (uintptr_t)cdr(obj));
} }
FlashEndWrite(); FlashEndWrite(&addr);
return imagesize; return imagesize;
#else #else
(void) arg; (void) arg;
@ -772,20 +859,6 @@ int saveimage (object *arg) {
#endif #endif
} }
#if defined(sdcardsupport)
int SDReadInt (File file) {
uintptr_t b0 = file.read(); uintptr_t b1 = file.read();
uintptr_t b2 = file.read(); uintptr_t b3 = file.read();
return b0 | b1<<8 | b2<<16 | b3<<24;
}
#elif defined(DATAFLASHSIZE)
int FlashReadInt () {
uint8_t b0 = FlashReadByte(); uint8_t b1 = FlashReadByte();
uint8_t b2 = FlashReadByte(); uint8_t b3 = FlashReadByte();
return b0 | b1<<8 | b2<<16 | b3<<24;
}
#endif
int loadimage (object *arg) { int loadimage (object *arg) {
#if defined(sdcardsupport) #if defined(sdcardsupport)
SD.begin(SDCARD_SS_PIN); SD.begin(SDCARD_SS_PIN);
@ -812,27 +885,36 @@ int loadimage (object *arg) {
file.close(); file.close();
gc(NULL, NULL); gc(NULL, NULL);
return imagesize; return imagesize;
#elif defined(DATAFLASHSIZE) #elif defined(DATAFLASH) || defined(EEPROMFLASH)
if (!FlashSetup()) error2(LOADIMAGE, PSTR("no DataFlash found.")); if (!FlashCheck()) error2(LOADIMAGE, PSTR("flash not available"));
FlashBeginRead(); uint32_t addr;
FlashReadInt(); // Skip eval address FlashBeginRead(&addr);
unsigned int imagesize = FlashReadInt(); FlashRead32(&addr); // Skip eval address
uint32_t imagesize = FlashRead32(&addr);
if (imagesize == 0 || imagesize == 0xFFFFFFFF) error2(LOADIMAGE, PSTR("no saved image")); if (imagesize == 0 || imagesize == 0xFFFFFFFF) error2(LOADIMAGE, PSTR("no saved image"));
GlobalEnv = (object *)FlashReadInt(); GlobalEnv = (object *)FlashRead32(&addr);
GCStack = (object *)FlashReadInt(); GCStack = (object *)FlashRead32(&addr);
#if SYMBOLTABLESIZE > BUFFERSIZE #if SYMBOLTABLESIZE > BUFFERSIZE
SymbolTop = (char *)FlashReadInt(); SymbolTop = (char *)FlashRead32(&addr);
int SymbolUsed = SymbolTop - SymbolTable; int SymbolUsed = SymbolTop - SymbolTable;
for (int i=0; i<SymbolUsed; i++) SymbolTable[i] = FlashReadByte(); for (int i=0; i<(SymbolUsed+3)/4; i=i+4) {
#endif union { uint32_t u32; uint8_t u8[4]; };
for (int i=0; i<CODESIZE; i++) MyCode[i] = FlashReadByte(); u32 = FlashRead32(&addr);
for (unsigned int i=0; i<imagesize; i++) { SymbolTable[i] = u8[0]; SymbolTable[i+1] = u8[1]; SymbolTable[i+2] = u8[2]; SymbolTable[i+3] = u8[3];
object *obj = &Workspace[i];
car(obj) = (object *)FlashReadInt();
cdr(obj) = (object *)FlashReadInt();
} }
#endif
for (int i=0; i<CODESIZE; i=i+4) {
union { uint32_t u32; uint8_t u8[4]; };
u32 = FlashRead32(&addr);
MyCode[i] = u8[0]; MyCode[i+1] = u8[1]; MyCode[i+2] = u8[2]; MyCode[i+3] = u8[3];
}
for (uint32_t i=0; i<imagesize; i++) {
object *obj = &Workspace[i];
car(obj) = (object *)FlashRead32(&addr);
cdr(obj) = (object *)FlashRead32(&addr);
}
FlashEndRead(&addr);
gc(NULL, NULL); gc(NULL, NULL);
FlashEndRead();
return imagesize; return imagesize;
#else #else
(void) arg; (void) arg;
@ -852,11 +934,12 @@ void autorunimage () {
loadimage(NULL); loadimage(NULL);
apply(0, autorun, NULL, NULL); apply(0, autorun, NULL, NULL);
} }
#elif defined(DATAFLASHSIZE) #elif defined(DATAFLASH) || defined(EEPROMFLASH)
if (!FlashSetup()) error2(0, PSTR("no DataFlash found.")); if (!FlashCheck()) error2(0, PSTR("flash not available"));
FlashBeginRead(); uint32_t addr;
object *autorun = (object *)FlashReadInt(); FlashBeginRead(&addr);
FlashEndRead(); object *autorun = (object *)FlashRead32(&addr);
FlashEndRead(&addr);
if (autorun != NULL && (unsigned int)autorun != 0xFFFFFFFF) { if (autorun != NULL && (unsigned int)autorun != 0xFFFFFFFF) {
loadimage(nil); loadimage(nil);
apply(0, autorun, NULL, NULL); apply(0, autorun, NULL, NULL);
@ -3950,9 +4033,9 @@ object *fn_cls (object *args, object *env) {
object *fn_pinmode (object *args, object *env) { object *fn_pinmode (object *args, object *env) {
(void) env; (void) env;
int pin = checkinteger(PINMODE, first(args)); int pin = checkinteger(PINMODE, first(args));
PinMode pm = INPUT; int pm = INPUT;
object *arg = second(args); object *arg = second(args);
if (keywordp(arg)) pm = (PinMode)checkkeyword(PINMODE, arg); if (keywordp(arg)) pm = checkkeyword(PINMODE, arg);
else if (integerp(arg)) { else if (integerp(arg)) {
int mode = arg->integer; int mode = arg->integer;
if (mode == 1) pm = OUTPUT; else if (mode == 2) pm = INPUT_PULLUP; if (mode == 1) pm = OUTPUT; else if (mode == 2) pm = INPUT_PULLUP;