Merge branch 'master' into SMAQ3

This commit is contained in:
Gordon Williams 2020-07-14 15:10:24 +01:00
commit c14f207c83
31 changed files with 354 additions and 272 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@
*.srec
*.bin
*.pyc
/*.bin.unpadded
/*.zip
/gen/*
/.vagrant/*

View File

@ -8,6 +8,13 @@
WIZNet: add setHostname(), geHostname(), getStatus()
Fix XON not sent after reset() (fix #1872)
Remove USBSERIAL enum for non-USB devices
Shrink new vector font sizes to allow multi-line use (fix #1873)
Stop Object.setPrototypeOf overwriting Object.prototype sometimes (fix #1875)
Arrow functions now always overwrite `this` (fix #1878)
Implement Streaming Storage compaction to allow compact with less RAM (fix #1598,#1707,#1828)
jslTokenAsString now works for 'of'
Speed up Array.prototype.join (fix #1660)
Allow 'in' to be used with typed arrays (fix #1534)
2v06 : Allow `"ram"` keyword at the top of a function to allow it to be pretokenised and loaded to RAM
Don't store line numbers for pretokenised functions

View File

@ -1084,7 +1084,7 @@ void jswrap_banglejs_setLCDTimeout(JsVarFloat timeout) {
"name" : "setPollInterval",
"generate" : "jswrap_banglejs_setPollInterval",
"params" : [
["interval","float","Polling interval in milliseconds"]
["interval","float","Polling interval in milliseconds (Default is 80ms - 12.5Hz to match accelerometer)"]
],
"ifdef" : "BANGLEJS"
}
@ -2136,22 +2136,32 @@ void jswrap_banglejs_accelWr(JsVarInt reg, JsVarInt data) {
"name" : "accelRd",
"generate" : "jswrap_banglejs_accelRd",
"params" : [
["reg","int",""]
["reg","int",""],
["cnt","int","If specified, `accelRd` returns and array of the given length (max 128). If not (or 0) it returns a number"]
],
"return" : ["int",""],
"return" : ["JsVar",""],
"ifdef" : "BANGLEJS"
}
Reads a register from the KX023 Accelerometer
**Note:** On Espruino 2v06 and before this function only returns a number (`cnt` is ignored).
*/
int jswrap_banglejs_accelRd(JsVarInt reg) {
JsVar *jswrap_banglejs_accelRd(JsVarInt reg, JsVarInt cnt) {
#ifndef EMSCRIPTEN
unsigned char buf[1];
if (cnt<0) cnt=0;
unsigned char buf[128];
if (cnt>sizeof(buf)) cnt=sizeof(buf);
buf[0] = (unsigned char)reg;
i2cBusy = true;
jsi2cWrite(ACCEL_I2C, ACCEL_ADDR, 1, buf, true);
jsi2cRead(ACCEL_I2C, ACCEL_ADDR, 1, buf, true);
jsi2cRead(ACCEL_I2C, ACCEL_ADDR, cnt, buf, true);
i2cBusy = false;
return buf[0];
if (cnt) {
JsVar *ab = jsvNewArrayBufferWithData(cnt, buf);
JsVar *d = jswrap_typedarray_constructor(ARRAYBUFFERVIEW_UINT8, ab,0,0);
jsvUnLock(ab);
return d;
} else return jsvNewFromInteger(buf[0]);
#else
return 0;
#endif

View File

@ -34,7 +34,7 @@ JsVar *jswrap_banglejs_getAccel();
JsVar *jswrap_banglejs_dbg();
void jswrap_banglejs_accelWr(JsVarInt reg, JsVarInt data);
int jswrap_banglejs_accelRd(JsVarInt reg);
JsVar *jswrap_banglejs_accelRd(JsVarInt reg, JsVarInt cnt);
void jswrap_banglejs_compassWr(JsVarInt reg, JsVarInt data);
void jswrap_banglejs_ioWr(JsVarInt mask, bool on);
JsVar *jswrap_banglejs_project(JsVar *latlong);

View File

@ -366,7 +366,7 @@ Called with discovered characteristics when discovery is finished
"type" : "event",
"class" : "NRF",
"name" : "NFCon",
"ifdef" : "NRF52"
"#if" : "defined(NRF52) && defined(USE_NFC)"
}
Called when an NFC field is detected
*/
@ -374,7 +374,7 @@ Called when an NFC field is detected
"type" : "event",
"class" : "NRF",
"name" : "NFCoff",
"ifdef" : "NRF52"
"#if" : "defined(NRF52) && defined(USE_NFC)"
}
Called when an NFC field is no longer detected
*/
@ -385,7 +385,7 @@ Called when an NFC field is no longer detected
"params" : [
["arr","JsVar","An ArrayBuffer containign the received data"]
],
"ifdef" : "NRF52"
"#if" : "defined(NRF52) && defined(USE_NFC)"
}
When NFC is started with `NRF.nfcStart`, this is fired
when NFC data is received. It doesn't get called if
@ -2010,7 +2010,7 @@ void jswrap_ble_setLowPowerConnection(bool lowPower) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcURL",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_URL",
"params" : [
["url","JsVar","The URL string to expose on NFC, or `undefined` to disable NFC"]
@ -2088,7 +2088,7 @@ void jswrap_nfc_URL(JsVar *url) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcPair",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_pair",
"params" : [
["key","JsVar","16 byte out of band key"]
@ -2149,7 +2149,7 @@ void jswrap_nfc_pair(JsVar *key) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcAndroidApp",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_androidApp",
"params" : [
["app","JsVar","The unique identifier of the given Android App"]
@ -2208,7 +2208,7 @@ void jswrap_nfc_androidApp(JsVar *appName) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcRaw",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_raw",
"params" : [
["payload","JsVar","The NFC NDEF message to deliver to the reader"]
@ -2270,7 +2270,7 @@ void jswrap_nfc_raw(JsVar *payload) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcStart",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_start",
"params" : [
["payload","JsVar","Optional 7 byte UID"]
@ -2339,7 +2339,7 @@ JsVar *jswrap_nfc_start(JsVar *payload) {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcStop",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_stop",
"params" : [ ]
}
@ -2363,7 +2363,7 @@ void jswrap_nfc_stop() {
"type" : "staticmethod",
"class" : "NRF",
"name" : "nfcSend",
"ifdef" : "NRF52",
"#if" : "defined(NRF52) && defined(USE_NFC)",
"generate" : "jswrap_nfc_send",
"params" : [
["payload","JsVar","Optional tx data"]

View File

@ -42,7 +42,6 @@ DSTATUS disk_initialize (
{
if (drv != 0)
return STA_NODISK;
//jsDebug("Flash Disk Init %d",drv);
return RES_OK;
}
@ -76,7 +75,7 @@ DRESULT disk_read (
uint16_t size = (uint16_t)(count * FS_SECTOR_SIZE);
uint32_t addr = sector * FS_SECTOR_SIZE + fs_flash_base;
jsDebug("Flash disk_read sector: %d, buff: mem: %d buff: %d len: %d", sector, addr, buff, size);
jsDebug(DBG_INFO,"Flash disk_read sector: %d, buff: mem: %d buff: %d len: %d", sector, addr, buff, size);
jshFlashRead( buff, addr, size);
return RES_OK;
}
@ -98,7 +97,7 @@ DRESULT disk_write (
uint16_t size = (uint16_t)(count * FS_SECTOR_SIZE);
uint32_t addr = sector * FS_SECTOR_SIZE + fs_flash_base;
jsDebug("Flash disk_write sector: %d, buff: mem: %d buff: %d len: %d", sector, addr, buff, size);
jsDebug(DBG_INFO,"Flash disk_write sector: %d, buff: mem: %d buff: %d len: %d", sector, addr, buff, size);
jshFlashErasePage(addr);
jshFlashWrite( (void *)buff, addr,size);
@ -123,7 +122,7 @@ DRESULT disk_ioctl (
switch (ctrl) {
case CTRL_SYNC : /// Make sure that no pending write process
res = RES_OK;
jsDebug("Flash disk_ioctl CTRL_SYNC");
jsDebug(DBG_INFO,"Flash disk_ioctl CTRL_SYNC");
break;
case GET_SECTOR_COUNT : // Get number of sectors on the disk (DWORD)

View File

@ -31,13 +31,3 @@
#define FS_FLASH_BASE 0x300000;
uint8_t flashFatFsInit( uint32_t addr, uint16_t sectors );
/*
#ifndef RELEASE
#define jsDebug(fmt,...) jsWarn(fmt,##__VA_ARGS__)
#else
#define jsDebug(fmt,...)
#endif
#endif
*/
#define jsDebug(fmt,...)

View File

@ -649,7 +649,7 @@ int jswrap_E_flashFatFS(JsVar* options) {
if (init) {
if ( format ) {
uint8_t res = f_mount(&jsfsFAT, "", 0);
jsDebug("Formatting Flash");
jsDebug(DBG_INFO,"Formatting Flash");
res = f_mkfs("", 1, 0); // Super Floppy format, using all space (not partition table)
if (res != FR_OK) {
jsExceptionHere(JSET_INTERNALERROR, "Flash Formatting error:",res);

View File

@ -18,8 +18,8 @@
const uint8_t vfFirstChar = 33;
const uint8_t vfLastChar = 255;
#define VF_CHAR_WIDTH 13
#define VF_SCALE 12
#define VF_OFFSET_Y (-3)
#define VF_SCALE 16
#define VF_OFFSET_Y (-2)
#define VF_CHAR_SPACING 1
static const uint8_t vfPolyVerts[] IN_FLASH_MEMORY = {
169,171,197,195,

View File

@ -42,12 +42,6 @@
#define UNUSED(x) (void)(x)
#ifndef RELEASE
#define jsDebug(format, ...) jsWarn(format, ## __VA_ARGS__)
#else
#define jsDebug(format, ...) do { } while(0)
#endif
static void sendWifiCompletionCB(
JsVar **g_jsCallback, //!< Pointer to the global callback variable
char *reason //!< NULL if successful, error string otherwise
@ -233,7 +227,7 @@ static char *wifiReasonToString(uint8_t reason) {
case WIFI_REASON_UNSUPP_RSN_IE_VERSION:
return "REASON_UNSUPP_RSN_IE_VERSION";
}
jsDebug( "wifiReasonToString: Unknown reason %d", reason);
jsDebug(DBG_INFO, "wifiReasonToString: Unknown reason %d", reason);
return "Unknown reason";
} // End of wifiReasonToString
@ -413,7 +407,7 @@ static JsVar *getWifiModule() {
static int s_retry_num = 0;
static char *wifiGetEvent(uint32_t event) {
jsDebug( "wifiGetEvent: Got event: %d", event);
jsDebug(DBG_INFO,"wifiGetEvent: Got event: %d", event);
switch(event) {
case SYSTEM_EVENT_AP_PROBEREQRECVED:
return "#onprobe_recv";
@ -442,7 +436,7 @@ switch(event) {
case SYSTEM_EVENT_WIFI_READY:
break;
}
jsDebug( "Unhandled wifi event type: %d", event);
jsDebug(DBG_INFO, "Unhandled wifi event type: %d", event);
return NULL;
} // End of wifiGetEvent
@ -488,12 +482,12 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
* * bssid
* * reason
*/
jsDebug("Wifi: Event(%d):SYSTEM_EVENT_%s\n",event->event_id,wifiEventToString(event->event_id));
jsDebug(DBG_INFO,"Wifi: Event(%d):SYSTEM_EVENT_%s\n",event->event_id,wifiEventToString(event->event_id));
if (event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
if (--s_retry_num > 0 ) {
esp_wifi_connect();
jsDebug("retry to AP connect");
jsDebug(DBG_INFO,"retry to AP connect");
return;
}
g_isStaConnected = false; // Flag as disconnected
@ -578,7 +572,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
jsvObjectSetChildAndUnLock(jsDetails, "netmask", jsvNewFromString(temp));
sprintf(temp, IPSTR, IP2STR(&event->event_info.got_ip.ip_info.gw));
jsvObjectSetChildAndUnLock(jsDetails, "gw", jsvNewFromString(temp));
jsDebug("Wifi: About to emit connect!");
jsDebug(DBG_INFO, "Wifi: About to emit connect!");
sendWifiEvent(event->event_id, jsDetails);
// start mDNS
const char * hostname;
@ -642,7 +636,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
sendWifiCompletionCB(&g_jsAPStartedCallback, NULL);
return ESP_OK;
}
jsDebug("Wifi: event_handler -> NOT HANDLED EVENT: %d", event->event_id );
jsDebug(DBG_INFO, "Wifi: event_handler -> NOT HANDLED EVENT: %d", event->event_id );
return ESP_OK;
} // End of event_handler
@ -658,7 +652,7 @@ void esp32_wifi_init() {
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
jsDebug("esp32_wifi_init complete");
jsDebug(DBG_INFO, "esp32_wifi_init complete");
} // End of esp32_wifi_init
@ -674,7 +668,7 @@ static void sendWifiCompletionCB(
JsVar **g_jsCallback, //!< Pointer to the global callback variable
char *reason //!< NULL if successful, error string otherwise
) {
jsDebug("sendWifiCompletionCB");
jsDebug(DBG_INFO, "sendWifiCompletionCB");
// Check that we have a callback function.
if (!jsvIsFunction(*g_jsCallback)){
return; // we have not got a function pointer: nothing to do
@ -699,7 +693,7 @@ static void sendWifiCompletionCB(
* Perform a soft initialization of ESP32 networking.
*/
void jswrap_esp32_wifi_soft_init() {
jsDebug("jswrap_esp32_wifi_soft_init()");
jsDebug(DBG_INFO, "jswrap_esp32_wifi_soft_init()");
JsNetwork net;
networkCreate(&net, JSNETWORKTYPE_ESP32); // Set the network type to be ESP32
networkState = NETWORKSTATE_ONLINE; // Set the global state of the networking to be online
@ -724,7 +718,7 @@ void jswrap_wifi_disconnect(JsVar *jsCallback) {
g_jsDisconnectCallback = jsvLockAgainSafe(jsCallback);
// Call the ESP-IDF to disconnect us from the access point.
jsDebug("Disconnecting.....");
jsDebug(DBG_INFO, "Disconnecting.....");
// turn off auto-connect
esp_wifi_set_auto_connect(false);
s_retry_num = 0; // flag so we don't attempt to reconnect
@ -758,7 +752,7 @@ void jswrap_wifi_stopAP(JsVar *jsCallback) {
}
err = esp_wifi_set_mode(mode);
if (err != ESP_OK) {
jsDebug("jswrap_wifi_stopAP: esp_wifi_set_mode rc=%d(%s)", err,wifiErrorToString(err));
jsDebug(DBG_INFO, "jswrap_wifi_stopAP: esp_wifi_set_mode rc=%d(%s)", err,wifiErrorToString(err));
}
if (jsvIsFunction(jsCallback)) {
@ -772,7 +766,7 @@ void jswrap_wifi_connect(
JsVar *jsCallback
) {
jsDebug("jswrap_wifi_connect: entry");
jsDebug(DBG_INFO, "jswrap_wifi_connect: entry");
// Check that the ssid value isn't obviously in error.
if (!jsvIsString(jsSsid)) {
@ -821,7 +815,7 @@ jsDebug("jswrap_wifi_connect: entry");
}
jsvUnLock(jsPassword);
} // End of we had options
jsDebug("jswrap_wifi_connect: SSID, password, Callback done");
jsDebug(DBG_INFO, "jswrap_wifi_connect: SSID, password, Callback done");
// At this point, we have the ssid in "ssid" and the password in "password".
// Perform an esp_wifi_set_mode
@ -851,7 +845,7 @@ jsDebug("jswrap_wifi_connect: entry");
jsError( "jswrap_wifi_connect: esp_wifi_set_mode: %d(%s), mode=%d", err,wifiErrorToString(err), mode);
return;
}
jsDebug("jswrap_wifi_connect: esi_wifi_set_mode done");
jsDebug(DBG_INFO, "jswrap_wifi_connect: esi_wifi_set_mode done");
// Perform a an esp_wifi_set_config
wifi_config_t staConfig;
@ -861,17 +855,17 @@ jsDebug("jswrap_wifi_connect: entry");
memcpy(staConfig.sta.password, password, sizeof(staConfig.sta.password));
staConfig.sta.bssid_set = false;
esp_wifi_set_auto_connect(true);
jsDebug("jswrap_wifi_connect: esp_wifi_set_autoconnect done");
jsDebug(DBG_INFO, "jswrap_wifi_connect: esp_wifi_set_autoconnect done");
err = esp_wifi_set_config(ESP_IF_WIFI_STA, &staConfig);
if (err != ESP_OK) {
jsError( "jswrap_wifi_connect: esp_wifi_set_config: %d(%s)", err,wifiErrorToString(err));
return;
}
jsDebug("jswrap_wifi_connect: esp_wifi_set_config done");
jsDebug(DBG_INFO, "jswrap_wifi_connect: esp_wifi_set_config done");
// Perform an esp_wifi_start
jsDebug("jswrap_wifi_connect: esp_wifi_start %s",ssid);
jsDebug(DBG_INFO, "jswrap_wifi_connect: esp_wifi_start %s",ssid);
err = esp_wifi_start();
if (err != ESP_OK) {
jsError( "jswrap_wifi_connect: esp_wifi_start: %d(%s)", err,wifiErrorToString(err));
@ -1307,7 +1301,7 @@ JsVar *jswrap_wifi_getAPDetails(JsVar *jsCallback) {
} // End of jswrap_wifi_getAPDetails
void jswrap_wifi_save(JsVar *what) {
jsDebug("Wifi.save");
jsDebug(DBG_INFO, "Wifi.save");
JsVar *o = jsvNewObject();
if (!o) return;
@ -1315,7 +1309,7 @@ void jswrap_wifi_save(JsVar *what) {
JsVar *name = jsvNewFromString(WIFI_CONFIG_STORAGE_NAME);
jswrap_storage_erase(name);
jsvUnLock(name);
jsDebug("Wifi.save(clear)");
jsDebug(DBG_INFO, "Wifi.save(clear)");
return;
}
@ -1353,16 +1347,16 @@ void jswrap_wifi_save(JsVar *what) {
jswrap_storage_write(name,o,0,0);
jsvUnLock2(name,o);
jsDebug("Wifi.save: write completed");
jsDebug(DBG_INFO, "Wifi.save: write completed");
}
void jswrap_wifi_restore(void) {
jsDebug("jswrap_wifi_restore");
jsDebug(DBG_INFO, "jswrap_wifi_restore");
JsVar *name = jsvNewFromString(WIFI_CONFIG_STORAGE_NAME);
JsVar *o = jswrap_storage_readJSON(name, true);
if (!o) { // no data
jsDebug("jswrap_wifi_restore: No data - Starting default AP");
jsDebug(DBG_INFO, "jswrap_wifi_restore: No data - Starting default AP");
esp_wifi_start();
jsvUnLock2(name,o);
return;
@ -1458,7 +1452,7 @@ void jswrap_wifi_restore(void) {
return;
}
} else {
jsDebug( "Wifi: Both STA AND APSTA are off");
jsDebug(DBG_INFO, "Wifi: Both STA AND APSTA are off");
}
} // End of jswrap_wifi_restore
@ -1533,7 +1527,7 @@ void jswrap_wifi_setHostname(
) {
char hostname[256];
jsvGetString(jsHostname, hostname, sizeof(hostname));
jsDebug("Wifi.setHostname: %s\n", hostname);
jsDebug(DBG_INFO, "Wifi.setHostname: %s\n", hostname);
tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA,hostname);
// now update mDNS

View File

@ -202,6 +202,9 @@ JsVar *jswrap_ethernet_getIP(JsVar *wlanObj, JsVar *callback) {
networkPutAddressAsString(data, "ip", &gWIZNETINFO.ip[0], 4, 10, '.');
networkPutAddressAsString(data, "subnet", &gWIZNETINFO.sn[0], 4, 10, '.');
networkPutAddressAsString(data, "gateway", &gWIZNETINFO.gw[0], 4, 10, '.');
if ( !gWIZNETINFO.gw[0] ) {
gWIZNETINFO.dns[0] = gWIZNETINFO.dns[1] = gWIZNETINFO.dns[2] = gWIZNETINFO.dns[3] = 0;
}
networkPutAddressAsString(data, "dns", &gWIZNETINFO.dns[0], 4, 10, '.');
networkPutAddressAsString(data, "mac", &gWIZNETINFO.mac[0], 6, 16, ':');

View File

@ -148,3 +148,4 @@ LDFLAGS+= -L$(ESP_APP_TEMPLATE_PATH)/build/components/bt/bluedroid/api \
-L$(ESP_APP_TEMPLATE_PATH)/build/components/bt/bluedroid/bta
endif
FLASH_BAUD ?= 921600 # The flash baud rate

View File

@ -31,7 +31,7 @@ flash: $(PROJ_NAME).bin
python $(ESP_IDF_PATH)/components/esptool_py/esptool/esptool.py \
--chip esp32 \
--port ${COMPORT} \
--baud 921600 \
--baud $(FLASH_BAUD) \
write_flash \
-z \
--flash_mode "dio" \
@ -43,6 +43,6 @@ flash: $(PROJ_NAME).bin
erase_flash:
python $(ESP_IDF_PATH)/components/esptool_py/esptool/esptool.py \
--chip esp32 \
--port ${COMPORT}\
--baud 921600 \
--port ${COMPORT} \
--baud $(FLASH_BAUD) \
erase_flash

View File

@ -441,8 +441,8 @@ var vector_font_c = `/*
const uint8_t vfFirstChar = ${firstChar};
const uint8_t vfLastChar = ${lastChar};
#define VF_CHAR_WIDTH ${charWidth}
#define VF_SCALE 12
#define VF_OFFSET_Y (-3)
#define VF_SCALE 16
#define VF_OFFSET_Y (-2)
#define VF_CHAR_SPACING 1
static const uint8_t vfPolyVerts[] IN_FLASH_MEMORY = {
${uniquePolys.map(p => p.join(",")).join(",\n ")}

View File

@ -421,6 +421,8 @@ def get_ifdef_description(d):
if d=="USE_FLASHFS": return "devices with filesystem in Flash support enabled (ESP32 only)"
if d=="USE_TERMINAL": return "devices with VT100 terminal emulation enabled (Pixl.js only)"
if d=="USE_TELNET": return "devices with Telnet enabled (Linux, ESP8266 and ESP32)"
if d=="USE_WIZNET": return "builds with support for WIZnet Ethernet modules built in"
if d=="USE_NFC": return "NFC (Puck.js, Pixl.js, MDBT42Q)"
print("WARNING: Unknown ifdef '"+d+"' in common.get_ifdef_description")
return d

View File

@ -21,12 +21,6 @@
#define SAVED_CODE_BOOTCODE ".bootcde" // bootcode that doesn't run after reset
#define SAVED_CODE_VARIMAGE ".varimg" // Image of all JsVars written to flash
#ifdef DEBUG
#define DBG(...) jsiConsolePrintf("[Flash] "__VA_ARGS__)
#else
#define DBG(...)
#endif
#define JSF_START_ADDRESS FLASH_SAVED_CODE_START
#define JSF_END_ADDRESS (FLASH_SAVED_CODE_START+FLASH_SAVED_CODE_LENGTH)
@ -146,13 +140,13 @@ static bool jsfEraseFrom(uint32_t startAddr) {
/// Erase the entire contents of the memory store
bool jsfEraseAll() {
DBG("EraseAll\n");
jsDebug(DBG_INFO,"EraseAll\n");
return jsfEraseFrom(JSF_START_ADDRESS);
}
/// When a file is found in memory, erase it (by setting first bytes of name to 0). addr=ptr to data, NOT header
static void jsfEraseFileInternal(uint32_t addr, JsfFileHeader *header) {
DBG("EraseFile 0x%08x\n", addr);
jsDebug(DBG_INFO,"EraseFile 0x%08x\n", addr);
addr -= (uint32_t)sizeof(JsfFileHeader);
addr += (uint32_t)((char*)&header->name.firstChars - (char*)header);
@ -280,93 +274,138 @@ static uint32_t jsfGetAllocatedSpace(uint32_t addr, bool allPages, uint32_t *unc
return allocated;
}
// Copy one memory buffer to another *circular buffer*
static void memcpy_circular(char *dst, uint32_t *dstIndex, uint32_t dstSize, char *src, size_t len) {
while (len--) {
dst[*dstIndex] = *(src++);
*dstIndex = (*dstIndex+1) % dstSize;
}
}
static void jsfCompactWriteBuffer(uint32_t *writeAddress, uint32_t readAddress, char *swapBuffer, uint32_t swapBufferSize, uint32_t *swapBufferUsed, uint32_t *swapBufferTail) {
uint32_t nextFlashPage = jsfGetAddressOfNextPage(*writeAddress);
// write any data between swapBufferTail and the end of the buffer
while (*swapBufferUsed) {
uint32_t s = *swapBufferUsed;
// don't read past end - it's circular
if (s+*swapBufferTail > swapBufferSize)
s = swapBufferSize - *swapBufferTail;
// don't write into a new page
if (s+*writeAddress > nextFlashPage)
s = nextFlashPage-*writeAddress;
if (readAddress < nextFlashPage) {
jsDebug(DBG_INFO,"compact> skip write (0x%08x) as we're still reading from the page (0x%08x)\n", &writeAddress, readAddress);
return;
}
jsDebug(DBG_INFO,"compact> write %d from buf[%d] => 0x%08x\n", s, *swapBufferTail, *writeAddress);
if (!jsfIsErased(*writeAddress, s)) {
jshFlashErasePage(*writeAddress);
}
assert(jsfIsErased(*writeAddress, s));
jshFlashWrite(&swapBuffer[*swapBufferTail], *writeAddress, s);
*writeAddress += s;
nextFlashPage = jsfGetAddressOfNextPage(*writeAddress);
*swapBufferTail = (*swapBufferTail+s) % swapBufferSize;
*swapBufferUsed -= s;
}
}
/* Try and compact saved data so it'll fit in Flash again.
* TO RUN THIS, 'ALLOCATED' MUST BE CORRECT, AND THERE MUST BE ENOUGH STACK FREE
*/
static bool jsfCompactInternal(uint32_t startAddress, uint32_t allocated) {
DBG("Compacting from 0x%08x\n", startAddress);
if (allocated>0) {
// allocated = amount of RAM needed to compact all pages
// All our allocated data will fit in RAM - awesome!
// Allocate RAM
char *swapBuffer = alloca(allocated);
char *swapBufferPtr = swapBuffer;
// Copy all data to swap
DBG("Compacting - copy data to swap\n");
JsfFileHeader header;
memset(&header,0,sizeof(JsfFileHeader));
uint32_t addr = startAddress;
if (jsfGetFileHeader(addr, &header, true)) do {
if (header.name.firstChars != 0) { // if not replaced
memcpy(swapBufferPtr, &header, sizeof(JsfFileHeader));
swapBufferPtr += sizeof(JsfFileHeader);
uint32_t alignedSize = jsfAlignAddress(jsfGetFileSize(&header));
jshFlashRead(swapBufferPtr, addr+(uint32_t)sizeof(JsfFileHeader), alignedSize);
memset(&swapBufferPtr[jsfGetFileSize(&header)], 0xFF, alignedSize-jsfGetFileSize(&header));
swapBufferPtr += alignedSize;
}
} while (jsfGetNextFileHeader(&addr, &header, GNFH_GET_ALL));
// Erase everything
DBG("Compacting - erasing pages\n");
jsfEraseFrom(startAddress);
// Copy data back
DBG("Compacting - copy data from swap\n");
char *swapBufferEnd = swapBufferPtr;
swapBufferPtr = swapBuffer;
while (swapBufferPtr < swapBufferEnd) {
memcpy(&header, swapBufferPtr, sizeof(JsfFileHeader));
swapBufferPtr += sizeof(JsfFileHeader);
JsfFileHeader newHeader;
uint32_t newFile = jsfCreateFile(header.name, jsfGetFileSize(&header), jsfGetFileFlags(&header), &newHeader);
static bool jsfCompactInternal(uint32_t startAddress, char *swapBuffer, uint32_t swapBufferSize) {
uint32_t writeAddress = startAddress;
jsDebug(DBG_INFO,"Compacting from 0x%08x (%d byte buffer)\n", startAddress, swapBufferSize);
uint32_t swapBufferHead = 0;
uint32_t swapBufferTail = 0;
uint32_t swapBufferUsed = 0;
JsfFileHeader header;
memset(&header,0,sizeof(JsfFileHeader));
uint32_t addr = startAddress;
if (jsfGetFileHeader(addr, &header, true)) do {
if (header.name.firstChars != 0) { // if not replaced
jsDebug(DBG_INFO,"compact> copying file at 0x%08x\n", addr);
// Copy the file into the circular buffer, one bit at a time.
// Write the header
memcpy_circular(swapBuffer, &swapBufferHead, swapBufferSize, (char*)&header, sizeof(JsfFileHeader));
swapBufferUsed += (uint32_t)sizeof(JsfFileHeader);
// Write the contents
uint32_t alignedSize = jsfAlignAddress(jsfGetFileSize(&header));
if (newFile) jshFlashWrite(swapBufferPtr, newFile, alignedSize);
swapBufferPtr += alignedSize;
uint32_t alignedPtr = addr+(uint32_t)sizeof(JsfFileHeader);
jsfCompactWriteBuffer(&writeAddress, alignedPtr, swapBuffer, swapBufferSize, &swapBufferUsed, &swapBufferTail);
while (alignedSize) {
// How much space do we have available in our swapBuffer
uint32_t s = swapBufferSize-swapBufferUsed;
if (s > swapBufferSize-swapBufferHead)
s = swapBufferSize-swapBufferHead;
if ((swapBufferTail>swapBufferHead) && (s > (swapBufferTail-swapBufferHead)))
s = swapBufferTail-swapBufferHead;
if (s==0) {
jsDebug(DBG_INFO,"compact> error - no space left!\n");
return false;
}
if (s>alignedSize) s=alignedSize;
jsDebug(DBG_INFO,"compact> read %d from 0x%08x => buf[%d]\n", s, alignedPtr, swapBufferHead);
jshFlashRead(&swapBuffer[swapBufferHead], alignedPtr, s);
alignedSize -= s;
alignedPtr += s;
swapBufferUsed += s;
swapBufferHead = (swapBufferHead+s) % swapBufferSize;
// Is the buffer big enough to write?
jsfCompactWriteBuffer(&writeAddress, alignedPtr, swapBuffer, swapBufferSize, &swapBufferUsed, &swapBufferTail);
}
}
} else {
DBG("Compacting - no data, just erasing page\n");
jsfEraseFrom(startAddress);
}
DBG("Compaction Complete\n");
} while (jsfGetNextFileHeader(&addr, &header, GNFH_GET_ALL));
jsDebug(DBG_INFO,"compact> finished reading...\n");
// try and write the remaining
jsfCompactWriteBuffer(&writeAddress, JSF_END_ADDRESS, swapBuffer, swapBufferSize, &swapBufferUsed, &swapBufferTail);
// Finished - erase remaining
jsDebug(DBG_INFO,"compact> almost there - erase remaining pages\n");
writeAddress = jsfGetAddressOfNextPage(writeAddress-1);
jsfEraseFrom(writeAddress);
jsDebug(DBG_INFO,"Compaction Complete\n");
return true;
}
// Try and compact saved data so it'll fit in Flash again
bool jsfCompact() {
DBG("Compacting\n");
uint32_t addr = JSF_START_ADDRESS;
jsDebug(DBG_INFO,"Compacting\n");
uint32_t pageSize = jsfGetAddressOfNextPage(JSF_START_ADDRESS) - JSF_START_ADDRESS;
uint32_t maxRequired = pageSize + (uint32_t)sizeof(JsfFileHeader);
// TODO: We could skip forward pages if we think they are already fully compacted?
/* Try and compact the whole area first, but if that
* fails, keep skipping forward pages until we have
* enough RAM free that it's ok. */
while (addr) {
uint32_t uncompacted = 0;
uint32_t allocated = jsfGetAllocatedSpace(addr, true, &uncompacted);
if (!uncompacted) {
DBG("Already fully compacted\n");
return true;
}
if (allocated+1024 < jsuGetFreeStack()) {
DBG("Compacting - all data fits in RAM for 0x%08x (%d bytes)\n", addr, allocated);
return jsfCompactInternal(addr, allocated);
} else {
DBG("Compacting - Not enough memory for 0x%08x (%d bytes)\n", addr, allocated);
}
// move to the next available page and try from there
addr = jsfGetAddressOfNextStartPage(addr);
uint32_t uncompacted = 0;
uint32_t allocated = jsfGetAllocatedSpace(JSF_START_ADDRESS, true, &uncompacted);
if (!uncompacted) {
jsDebug(DBG_INFO,"Already fully compacted\n");
return true;
}
DBG("Compacting - not enough memory to compact anything\n");
/* TODO: we should try and compact pages at the start as well.
* Currently we just skip pages from the front until we have
* enough RAM. By doing both we could work either side of a
* massive saved code area. */
uint32_t swapBufferSize = allocated;
if (swapBufferSize > maxRequired) swapBufferSize=maxRequired;
// See if we have enough memory...
if (swapBufferSize+256 < jsuGetFreeStack()) {
jsDebug(DBG_INFO,"Enough stack for %d byte buffer\n", swapBufferSize);
char *swapBuffer = alloca(swapBufferSize);
return jsfCompactInternal(JSF_START_ADDRESS, swapBuffer, swapBufferSize);
} else {
jsDebug(DBG_INFO,"Not enough stack for (%d bytes)\n", swapBufferSize);
JsVar *buf = jsvNewFlatStringOfLength(swapBufferSize);
if (buf) {
jsDebug(DBG_INFO,"Allocated data in JsVars\n");
char *swapBuffer = jsvGetFlatStringPointer(buf);
bool r = jsfCompactInternal(JSF_START_ADDRESS, swapBuffer, swapBufferSize);
jsvUnLock(buf);
return r;
}
}
jsDebug(DBG_INFO,"Not enough memory to compact anything\n");
return false;
}
/// Create a new 'file' in the memory store - DOES NOT remove existing files with same name. Return the address of data start, or 0 on error
static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flags, JsfFileHeader *returnedHeader) {
DBG("CreateFile (%d bytes)\n", size);
jsDebug(DBG_INFO,"CreateFile (%d bytes)\n", size);
uint32_t requiredSize = jsfAlignAddress(size)+(uint32_t)sizeof(JsfFileHeader);
bool compacted = false;
uint32_t addr = 0;
@ -392,12 +431,12 @@ static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flag
if (!compacted) {
compacted = true;
if (!jsfCompact()) {
DBG("CreateFile - Compact failed\n");
jsDebug(DBG_INFO,"CreateFile - Compact failed\n");
return 0;
}
addr = JSF_START_ADDRESS; // addr->startAddr = restart
} else {
DBG("CreateFile - Not enough space\n");
jsDebug(DBG_INFO,"CreateFile - Not enough space\n");
return 0;
}
}
@ -412,16 +451,16 @@ static uint32_t jsfCreateFile(JsfFileName name, uint32_t size, JsfFileFlags flag
(spaceAvailable > (size + nextPage - addr)) && // there is space
(requiredSize < 512) && // it's not too big. We should always try and put big files as near the start as possible. See note in jsfCompact
!jsfGetFileHeader(nextPage, &header, false)) { // the next page is free
DBG("CreateFile straddles page boundary, pushed to next page (0x%08x -> 0x%08x)\n", addr, nextPage);
jsDebug(DBG_INFO,"CreateFile straddles page boundary, pushed to next page (0x%08x -> 0x%08x)\n", addr, nextPage);
addr = nextPage;
}
// write out the header
DBG("CreateFile new 0x%08x\n", addr+(uint32_t)sizeof(JsfFileHeader));
jsDebug(DBG_INFO,"CreateFile new 0x%08x\n", addr+(uint32_t)sizeof(JsfFileHeader));
header.size = size | (flags<<24);
header.name = name;
DBG("CreateFile write header\n");
jsDebug(DBG_INFO,"CreateFile write header\n");
jshFlashWrite(&header,addr,(uint32_t)sizeof(JsfFileHeader));
DBG("CreateFile written header\n");
jsDebug(DBG_INFO,"CreateFile written header\n");
if (returnedHeader) *returnedHeader = header;
return addr+(uint32_t)sizeof(JsfFileHeader);
}
@ -573,14 +612,14 @@ bool jsfWriteFile(JsfFileName name, JsVar *data, JsfFileFlags flags, JsVarInt of
flags==jsfGetFileFlags(&header) &&
dLen==size && // setting all in one go
jsfIsEqual(addr, (unsigned char*)dPtr, (uint32_t)dLen)) {
DBG("jsfWriteFile files Equal\n");
jsDebug(DBG_INFO,"jsfWriteFile files Equal\n");
return true;
}
if (addr) { // file exists, remove it!
DBG("jsfWriteFile remove existing file\n");
jsDebug(DBG_INFO,"jsfWriteFile remove existing file\n");
jsfEraseFileInternal(addr, &header);
}
DBG("jsfWriteFile create file\n");
jsDebug(DBG_INFO,"jsfWriteFile create file\n");
addr = jsfCreateFile(name, (uint32_t)size, flags, &header);
}
if (!addr) {
@ -596,9 +635,9 @@ bool jsfWriteFile(JsfFileName name, JsVar *data, JsfFileFlags flags, JsVarInt of
jsExceptionHere(JSET_ERROR, "File already written with different data");
return false;
}
DBG("jsfWriteFile write contents\n");
jsDebug(DBG_INFO,"jsfWriteFile write contents\n");
jshFlashWriteAligned(dPtr, addr, (uint32_t)dLen);
DBG("jsfWriteFile written contents\n");
jsDebug(DBG_INFO,"jsfWriteFile written contents\n");
return true;
}

View File

@ -754,7 +754,7 @@ void jslTokenAsString(int token, char *str, size_t len) {
case LEX_UNFINISHED_COMMENT : strcpy(str, "UNFINISHED COMMENT"); return;
case 255 : strcpy(str, "[ERASED]"); return;
}
if (token>=_LEX_OPERATOR_START && token<_LEX_R_LIST_END) {
if (token>=_LEX_OPERATOR_START && token<=_LEX_R_LIST_END) {
const char tokenNames[] =
/* LEX_EQUAL : */ "==\0"
/* LEX_TYPEEQUAL : */ "===\0"

View File

@ -1444,9 +1444,7 @@ NO_INLINE JsVar *jspeArrowFunction(JsVar *funcVar, JsVar *a) {
bool expressionOnly = lex->tk!='{';
jspeFunctionDefinitionInternal(funcVar, expressionOnly);
if (execInfo.thisVar) {
jsvObjectSetChild(funcVar, JSPARSE_FUNCTION_THIS_NAME, execInfo.thisVar);
}
jsvObjectSetChild(funcVar, JSPARSE_FUNCTION_THIS_NAME, execInfo.thisVar);
return funcVar;
}
@ -1878,8 +1876,14 @@ NO_INLINE JsVar *__jspeBinaryExpression(JsVar *a, unsigned int lastPrecedence) {
char nameBuf[JSLEX_MAX_TOKEN_LENGTH];
if (jsvGetString(av, nameBuf, sizeof(nameBuf)) < sizeof(nameBuf))
varFound = jswBinarySearch(syms, bv, nameBuf);
bool found = varFound!=0;
jsvUnLock2(a, varFound);
a = jsvNewFromBool(varFound!=0);
if (!found && jsvIsArrayBuffer(bv)) {
JsVarFloat f = jsvGetFloat(av); // if not a number this will be NaN, f==floor(f) fails
if (f==floor(f) && f>=0 && f<jsvGetArrayBufferLength(bv))
found = true;
}
a = jsvNewFromBool(found);
} else { // not built-in, just assume we can't do it
jsExceptionHere(JSET_ERROR, "Cannot use 'in' operator to search a %t", bv);
jsvUnLock(a);

View File

@ -400,6 +400,22 @@ typedef enum {
void jsAssertFail(const char *file, int line, const char *expr);
#define DBG_INFO 0
#define DBG_VERBOSE 1
/*
#if defined(DEBUG) || __FILE__ == DEBUG_FILE
#define jsDebug(dbg_type, format, ...) jsiConsolePrintf("[" __FILE__ "]:" format, ## __VA_ARGS__)
#else
#define jsDebug(dbg_type, format, ...) do { } while(0)
#endif
*/
#if (defined DEBUG ) || ( defined __FILE__ == DEBUG_FILE)
#define jsDebug(dbg_type, format, ...) jsiConsolePrintf("[" __FILE__ "]:" format, ## __VA_ARGS__)
#else
#define jsDebug(dbg_type, format, ...) do { } while(0)
#endif
#ifndef USE_FLASH_MEMORY
// Normal functions thet place format string in ram
void jsExceptionHere(JsExceptionType type, const char *fmt, ...);

View File

@ -3266,23 +3266,26 @@ void jsvArrayAddUnique(JsVar *arr, JsVar *v) {
JsVar *jsvArrayJoin(JsVar *arr, JsVar *filler) {
JsVar *str = jsvNewFromEmptyString();
if (!str) return 0; // out of memory
assert(!filler || jsvIsString(filler));
JsvIterator it;
jsvIteratorNew(&it, arr, JSIF_EVERY_ARRAY_ELEMENT);
JsvStringIterator itdst;
jsvStringIteratorNew(&itdst, str, 0);
bool first = true;
while (!jspIsInterrupted() && jsvIteratorHasElement(&it)) {
JsVar *key = jsvIteratorGetKey(&it);
if (jsvIsInt(key)) {
// add the filler
if (filler && !first)
jsvAppendStringVarComplete(str, filler);
jsvStringIteratorAppendString(&itdst, filler, 0);
first = false;
// add the value
JsVar *value = jsvIteratorGetValue(&it);
if (value && !jsvIsNull(value)) {
JsVar *valueStr = jsvAsString(value);
if (valueStr) { // could be out of memory
jsvAppendStringVarComplete(str, valueStr);
jsvStringIteratorAppendString(&itdst, valueStr, 0);
jsvUnLock(valueStr);
}
}
@ -3292,6 +3295,7 @@ JsVar *jsvArrayJoin(JsVar *arr, JsVar *filler) {
jsvIteratorNext(&it);
}
jsvIteratorFree(&it);
jsvStringIteratorFree(&itdst);
return str;
}

View File

@ -556,7 +556,7 @@ Set the prototype of the given object - this is like writing
`object.__proto__ = prototype` but is the 'proper' ES6 way of doing it
*/
JsVar *jswrap_object_setPrototypeOf(JsVar *object, JsVar *proto) {
JsVar *v = (jsvIsFunction(object)||jsvIsObject(object)) ? jspGetNamedField(object, "__proto__", true) : 0;
JsVar *v = (jsvIsFunction(object)||jsvIsObject(object)) ? jsvFindChildFromString(object, "__proto__", true) : 0;
if (!jsvIsName(v)) {
jsExceptionHere(JSET_TYPEERROR, "Can't extend %t\n", v);
} else {

View File

@ -41,7 +41,10 @@ void jsble_init(){
esp_err_t ret;
if(ESP32_Get_NVS_Status(ESP_NETWORK_BLE)){
ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
if(ret) {jsWarn("mem release failed:%x\n",ret); return;}
if(ret) {
jsExceptionHere(JSET_ERROR,"mem release failed:%x\n",ret);
return;
}
if(initController()) return;
if(initBluedroid()) return;
@ -51,7 +54,7 @@ void jsble_init(){
}
else{
ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
jsWarn("Bluetooth is disabled per ESP32.enableBLE(false)\n");
jsWarn("Bluetooth is disabled per ESP32.enableBLE(false)\n");
}
}
/** Completely deinitialise the BLE stack */
@ -96,7 +99,9 @@ uint32_t jsble_advertising_start(){
void jsble_advertising_stop(){
esp_err_t status;
status = bluetooth_gap_startAdvertizing(false);
if(status) jsWarn("error in stop advertising:0X%x\n",status);
if(status){
jsExceptionHere(JSET_ERROR,"error in stop advertising:0X%x",status);
}
}
/** Is BLE connected to any device at all? */
bool jsble_has_connection(){
@ -130,7 +135,9 @@ bool jsble_check_error(uint32_t err_code){
}
/// Scanning for advertisign packets
uint32_t jsble_set_scanning(bool enabled, bool activeScan){
if (activeScan) jsWarn("active scan not implemented\n");
if (activeScan) {
jsWarn("active scan not implemented\n");
}
bluetooth_gap_setScan(enabled);
return 0;
}

View File

@ -154,11 +154,6 @@ void jshInit() {
if (JSHPINSTATE_I2C != 13 || JSHPINSTATE_GPIO_IN_PULLDOWN != 6 || JSHPINSTATE_MASK != 15) {
jsError("JshPinState #defines have changed, please update pinStateToString()");
}
/*
jsWarn( "JSHPINSTATE_I2C %d\n",JSHPINSTATE_I2C );
jsWarn( "JSHPINSTATE_GPIO_IN_PULLDOWN %d\n",JSHPINSTATE_GPIO_IN_PULLDOWN );
jsWarn( "JSHPINSTATE_MASK %d\n",JSHPINSTATE_MASK );
*/
gpio_isr_register(gpio_intr_handler,NULL,0,NULL); //changed to automatic assign of interrupt
// Initialize something for each of the possible pins.
jshPinDefaultPullup();

View File

@ -40,19 +40,19 @@ static esp_err_t checkError( char * caller, esp_err_t ret ) {
switch(ret) {
case ESP_OK: break;
case ESP_ERR_INVALID_ARG: {
jsError( "%s:, Parameter error\n", caller );
jsExceptionHere(JSET_ERROR, "%s:, Parameter error\n", caller );
break;
}
case ESP_FAIL: {
jsError( "%s:, slave doesn't ACK the transfer.\n", caller );
jsExceptionHere(JSET_ERROR, "%s: slave doesn't ACK the transfer", caller);
break;
}
case ESP_ERR_TIMEOUT: {
jsError( "%s:, Operation timeout because the bus is busy.\n", caller );
jsExceptionHere(JSET_ERROR, "%s:, Operation timeout because the bus is busy", caller );
break;
}
default: {
jsError( "%s:, unknown error code %d, \n", caller, ret );
jsExceptionHere(JSET_ERROR, "%s:, unknown error code %d", caller, ret );
break;
}
}
@ -83,7 +83,7 @@ int getI2cFromDevice( IOEventFlags device ) {
void jshI2CSetup(IOEventFlags device, JshI2CInfo *info) {
int i2c_master_port = getI2cFromDevice(device);
if (i2c_master_port == -1) {
jsError("Only I2C1 and I2C2 supported");
jsExceptionHere(JSET_ERROR,"Only I2C1 and I2C2 supported");
return;
}
if(jshIsDeviceInitialised(device)){
@ -110,13 +110,13 @@ void jshI2CSetup(IOEventFlags device, JshI2CInfo *info) {
conf.master.clk_speed = info->bitrate;
esp_err_t err=i2c_param_config(i2c_master_port, &conf);
if ( err == ESP_ERR_INVALID_ARG ) {
jsError("jshI2CSetup: Invalid arguments");
jsExceptionHere(JSET_ERROR,"jshI2CSetup: Invalid arguments");
return;
}
err=i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);
if ( err == ESP_OK ) {
jsWarn("jshI2CSetup: driver installed, sda: %d scl: %d freq: %d, \n", sda, scl, info->bitrate);
jshSetDeviceInitialised(device, true);
jsDebug(DBG_INFO, "jshI2CSetup: driver installed, sda: %d scl: %d freq: %d, \n", sda, scl, info->bitrate);
jshSetDeviceInitialised(device, true);
} else {
checkError("jshI2CSetup",err);
}
@ -129,7 +129,7 @@ void jshI2CWrite(IOEventFlags device,
bool sendStop) {
int i2c_master_port = getI2cFromDevice(device);
if (i2c_master_port == -1) {
jsError("Only I2C1 and I2C2 supported");
jsExceptionHere(JSET_ERROR,"Only I2C1 and I2C2 supported");
return;
}
esp_err_t ret;
@ -153,8 +153,8 @@ void jshI2CRead(IOEventFlags device,
}
int i2c_master_port = getI2cFromDevice(device);
if (i2c_master_port == -1) {
jsError("Only I2C1 and I2C2 supported");
return;
jsExceptionHere(JSET_ERROR,"Only I2C1 and I2C2 supported");
return;
}
esp_err_t ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();

View File

@ -124,8 +124,8 @@ void jshSPISetup(
.flags=flags
};
if(SPIChannels[channelPnt].spi){
SPIChannelReset(channelPnt);
jsWarn("spi was already in use, removed old assignment");
SPIChannelReset(channelPnt);
jsDebug(DBG_INFO, "spi was already in use, removed old assignment");
}
esp_err_t ret=spi_bus_initialize(SPIChannels[channelPnt].HOST, &buscfg, 1);
assert(ret==ESP_OK);
@ -150,25 +150,23 @@ int jshSPISend(
// Send 8 bits of data taken from "data" over the selected spi and store the returned
// data for subsequent retrieval.
//spiTransferBits(_spi[which_spi], (uint32_t)data, &g_lastSPIRead, 8);
esp_err_t ret;
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8; //Command is 8 bits
t.tx_buffer=&data; //The data is the cmd itself
// https://esp-idf.readthedocs.io/en/latest/api/spi_master.html#type-definitions
// should this be a switch or always read?
t.flags=SPI_TRANS_USE_RXDATA;
t.flags=SPI_TRANS_USE_RXDATA;
ret=spi_device_transmit(SPIChannels[channelPnt].spi, &t); //Transmit - blocks until result - need to change this?
assert(ret == ESP_OK);
SPIChannels[channelPnt].g_lastSPIRead=t.rx_data[0];
assert(ret == ESP_OK);
SPIChannels[channelPnt].g_lastSPIRead=t.rx_data[0];
} else {
SPIChannels[channelPnt].g_lastSPIRead = (uint32_t)-1;
}
return (int)retData;
}
/**
* Send 16 bit data through the given SPI device.
*/

View File

@ -38,12 +38,6 @@
#define FAKE_FLASH_BLOCKSIZE FLASH_PAGE_SIZE
#define FAKE_FLASH_BLOCKS (FLASH_TOTAL/FLASH_PAGE_SIZE)
#ifdef DEBUG
#define FAKE_FLASH_DBG(...) jsiConsolePrintf(__VA_ARGS__)
#else
#define FAKE_FLASH_DBG(...)
#endif
#ifndef FLASH_64BITS_ALIGNMENT
#define FLASH_UNITARY_WRITE_SIZE 4
#else
@ -883,7 +877,7 @@ static FILE *jshFlashOpenFile(bool dontCreate) {
return f;
}
void jshFlashErasePage(uint32_t addr) {
FAKE_FLASH_DBG("FlashErasePage 0x%08x\n", addr);
jsDebug(DBG_VERBOSE,"FlashErasePage 0x%08x\n", addr);
FILE *f = jshFlashOpenFile(true);
if (!f) return; // if no file and we're erasing, we don't have to do anything
uint32_t startAddr, pageSize;
@ -898,7 +892,7 @@ void jshFlashErasePage(uint32_t addr) {
fclose(f);
}
void jshFlashRead(void *buf, uint32_t addr, uint32_t len) {
FAKE_FLASH_DBG("FlashRead 0x%08x %d\n", addr,len);
jsDebug(DBG_VERBOSE,"FlashRead 0x%08x %d\n", addr,len);
//assert(!(addr&(FLASH_UNITARY_WRITE_SIZE-1))); // sanity checks here to mirror real hardware
//assert(!(len&(FLASH_UNITARY_WRITE_SIZE-1))); // sanity checks here to mirror real hardware
if (addr<FLASH_START || addr>=FLASH_START+FLASH_TOTAL) {
@ -918,7 +912,7 @@ void jshFlashRead(void *buf, uint32_t addr, uint32_t len) {
fclose(f);
}
void jshFlashWrite(void *buf, uint32_t addr, uint32_t len) {
FAKE_FLASH_DBG("FlashWrite 0x%08x %d\n", addr,len);
jsDebug(DBG_VERBOSE,"FlashWrite 0x%08x %d\n", addr,len);
uint32_t i;
#ifndef SPIFLASH_BASE // for debug
assert(!(addr&(FLASH_UNITARY_WRITE_SIZE-1))); // sanity checks here to mirror real hardware

View File

@ -1,9 +1,12 @@
global.value = 34;
var obj = {
value : 42,
a : function() {
return x=>this.value+x;
}
return x => this.value+x;
},
b : x => this.value+x
};
var r = obj.a()(8);
result = r === 50;
var r2 = obj.b(8);
result = r === 50 && r2===42;

View File

@ -176,38 +176,38 @@ g.setFont("Vector",32);
g.setColor(1);
g.drawString("X");
SHOULD_BE(`
######...............#####......
.#####..............######......
..#####.............#####.......
..######...........#####........
...#####..........######........
....#####.........#####.........
....######.......#####..........
.....#####......######..........
......#####.....#####...........
......######...#####............
.......#####..######............
........#####.#####.............
........##########..............
.........#########..............
..........#######...............
..........######................
..........######................
..........#######...............
.........#########..............
........##########..............
........#####.#####.............
.......#####..######............
......######...#####............
......#####.....#####...........
.....#####......######..........
....######.......#####..........
....#####.........#####.........
...#####..........######........
..######...........#####........
..#####.............#####.......
.#####..............######......
######...............#####......`);
................................
................................
####............####............
.####..........####.............
..####........####..............
..####........####..............
...####......####...............
....####....####................
....####....####................
.....####..####.................
......########..................
......########..................
.......######...................
........####....................
........####....................
.......######...................
......########..................
......########..................
.....####..####.................
....####....####................
....####....####................
...####......####...............
..####........####..............
..####........####..............
.####..........####.............
####............####............
................................
................................
................................
................................
................................
................................`);
g.clear();
g.setColor(1);

View File

@ -1,3 +1,10 @@
/* We actually expect fillPoly to be different to drawPoly now. In order to
be useful for rendering more complex shapes like fonts, fillPoly needs to render
from low X,Y *up to but not including the highest pixels*.
Despite seeming odd, it's actually extremely common behaviour
*/
var g = Graphics.createArrayBuffer(100,64,8);
g.dump = _=>{
var s = "";
@ -84,15 +91,15 @@ SHOULD_BE(`
........###.......####................###....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........###.......####................###....###.......###....#...........#....###.......###........
........##.........##..................##....##.........##....#...#####...#....##..#####..##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#...#####...#....##..#####..##........
........###.......####................###....###.......###....#...........#....###.......###........
........###......#####...............####....###......####....#...........#....###......####........
........##........###.................###....##........###....#...####....#....##..####..###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#...........#....##........###........
........#################################....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........####.....######..............####....#############....#...........#....#############........
@ -106,15 +113,15 @@ SHOULD_BE(`
........####.....######..............####....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........####.....######..............####....###.......###....#...........#....###.......###........
........###.......####................###....##.........##....#...#####...#....##..#####..##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........##.........##..................##....##.........##....#..#######..#....##.#######.##........
........###.......####................###....##.........##....#...#####...#....##..#####..##........
........####.....######..............####....###.......###....#...........#....###.......###........
........####....#######.............#####....###......####....#...........#....###......####........
........###......#####...............####....##........###....#...####....#....##..####..###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........##........###.................###....##........###....#..######...#....##.######.###........
........###......#####...............####....##........###....#...........#....##........###........
........#################################....#############....#...........#....#############........
........#################################....#############....#...........#....#############........
........#################################....#############....#############....#############........
....................................................................................................

View File

@ -36,21 +36,21 @@ g.setFontVector(15);
g.drawString("4");
SHOULD_BE(`
................
.......##.......
......###.......
.....####.......
....#####.......
....#####.......
...######.......
..###.###.......
..###.###.......
.###..###.......
.##########.....
###########.....
###########.....
......###.......
......###.......
......###.......`);
....###.........
....###.........
...####.........
..##.##.........
.##..##.........
.##..##.........
#######.........
#######.........
.....##.........
.....##.........
.....##.........
................
................
................
................`);
g.clear();

View File

@ -0,0 +1,8 @@
// https://github.com/espruino/Espruino/issues/1875
let base = {foo: 42};
let child = {};
Object.setPrototypeOf(child, base);
print(child.__proto__ == Object.prototype);
print(Object.prototype);
result = (child.__proto__ != Object.prototype) && JSON.stringify(Object.prototype)=="{}";