Merge branch 'master' into SMAQ3

This commit is contained in:
Gordon Williams 2020-09-17 09:44:46 +01:00
commit 8a6fdb237c
9 changed files with 73 additions and 25 deletions

View File

@ -45,6 +45,12 @@
Bangle.js: Peripheral polling now only fully wakes Bangle when an event requires JS processing (ref #1921)
Bangle.js: When not moved for 1 minute, slow down accelerometer poll interval from 80 to 800ms (fix #1921)
Ensure software SPI/I2C/Serial don't leak a variable when initialised
Fix delay in scheduling after initial setTimeout call (from 2v06 and later)
Espruino WiFi: Fix StorageFile on Espruino WiFi (use max storagefile size of 4k)
Espruino WiFi: Fix Storage compaction regression (introduced after 2v06 release)
Bangle.js: Fix backlight flicker regression if at part brightness (fix #1925)
Fix ArrayBuffer.sort with negative numbers (it's not just Array.sort!)
nRF52: Use the best available hardware timer for PWM taking frequency into account
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

@ -41,7 +41,7 @@ info = {
'DEFINES+=-DDUMP_IGNORE_VARIABLES=\'"g\\0"\'',
'DEFINES+=-DUSE_FONT_6X8 -DGRAPHICS_PALETTED_IMAGES',
'DEFINES+=-DNO_DUMP_HARDWARE_INITIALISATION', # don't dump hardware init - not used and saves 1k of flash
'DEFINES+=-DAPP_TIMER_OP_QUEUE_SIZE=3', # Bangle.js accelerometer poll handler needs something else in queue size
'DEFINES+=-DAPP_TIMER_OP_QUEUE_SIZE=5', # Bangle.js accelerometer poll handler needs something else in queue size
'DFU_PRIVATE_KEY=targets/nrf5x_dfu/dfu_private_key.pem',
'DFU_SETTINGS=--application-version 0xff --hw-version 52 --sd-req 0x8C',
'INCLUDE += -I$(ROOT)/libs/banglejs -I$(ROOT)/libs/misc',

View File

@ -318,12 +318,14 @@ typedef struct {
#define DEFAULT_LCD_POWER_TIMEOUT 0 // in msec - default for lcdPowerTimeout
#else
#define DEFAULT_LCD_POWER_TIMEOUT 30000 // in msec - default for lcdPowerTimeout
#define BACKLIGHT_PWM_INTERVAL 15 // in msec - 67Hz PWM
#endif
#define HRM_POLL_INTERVAL 20 // in msec
#define ACCEL_POLL_INTERVAL_MAX 4000 // in msec - DEFAULT_ACCEL_POLL_INTERVAL_MAX+TIMER_MAX must be <65535
#define BTN_LOAD_TIMEOUT 1500 // in msec - how long does the button have to be pressed for before we restart
#define TIMER_MAX 60000 // 60 sec - enough to fit in uint16_t without overflow if we add ACCEL_POLL_INTERVAL
#ifdef SMAQ3
IOEventFlags fakeBTN1Flags, fakeBTN2Flags, fakeBTN3Flags;
@ -346,8 +348,13 @@ JshI2CInfo i2cInternal;
bool i2cBusy;
/// How often should be poll for accelerometer/compass data?
volatile uint16_t pollInterval; // in ms
#ifndef EMSCRIPTEN
/// Nordic app timer to handle call of peripheralPollHandler
APP_TIMER_DEF(m_peripheral_poll_timer_id);
// Nordic app timer to handle backlight PWM
APP_TIMER_DEF(m_backlight_on_timer_id);
APP_TIMER_DEF(m_backlight_off_timer_id);
#endif
/// Timer used for power save (lowering the poll interval)
volatile uint16_t powerSaveTimer;
@ -522,9 +529,6 @@ char clipi8(int x) {
void jswrap_banglejs_setPollInterval_internal(uint16_t msec) {
pollInterval = (uint16_t)msec;
#ifndef EMSCRIPTEN
//JsSysTime t = jshGetTimeFromMilliseconds(pollInterval);
//jstStopExecuteFn(peripheralPollHandler, 0);
//jstExecuteFn(peripheralPollHandler, NULL, jshGetSystemTime()+t, t);
app_timer_stop(m_peripheral_poll_timer_id);
#if NRF_SD_BLE_API_VERSION<5
app_timer_start(m_peripheral_poll_timer_id, APP_TIMER_TICKS(pollInterval, APP_TIMER_PRESCALER), NULL);
@ -589,6 +593,7 @@ void peripheralPollHandler() {
}
if (i2cBusy) return;
i2cBusy = true;
unsigned char buf[7];
// check the magnetometer if we had it on
if (compassPowerOn) {
@ -742,6 +747,7 @@ void peripheralPollHandler() {
accIdleCount = 0; // it was inactive but not long enough to trigger a gesture
}
}
i2cBusy = false;
//jswrap_banglejs_ioWr(IOEXP_HRM,1); // debug using HRM LED
}
@ -792,6 +798,7 @@ void hrmPollHandler() {
void backlightOnHandler() {
if (i2cBusy) return;
jswrap_banglejs_ioWr(IOEXP_LCD_BACKLIGHT, 0); // backlight on
app_timer_start(m_backlight_off_timer_id, APP_TIMER_TICKS(BACKLIGHT_PWM_INTERVAL, APP_TIMER_PRESCALER) * lcdBrightness >> 8, NULL);
}
void backlightOffHandler() {
if (i2cBusy) return;
@ -944,18 +951,14 @@ void touchHandler(bool state, IOEventFlags flags) {
/// Turn just the backlight on or off (or adjust brightness)
static void jswrap_banglejs_setLCDPowerBacklight(bool isOn) {
#ifndef EMSCRIPTEN
jstStopExecuteFn(backlightOnHandler, 0);
jstStopExecuteFn(backlightOffHandler, 0);
app_timer_stop(m_backlight_on_timer_id);
app_timer_stop(m_backlight_off_timer_id);
if (isOn) { // wake
if (lcdBrightness>0) {
jswrap_banglejs_ioWr(IOEXP_LCD_BACKLIGHT, 0); // backlight on
if (lcdBrightness > 0) {
if (lcdBrightness < 255) { // only do PWM if brightness isn't full
JsSysTime now = jshGetSystemTime();
JsSysTime interval = jshGetTimeFromMilliseconds(10); // how often do we switch - 100Hz
JsSysTime ontime = interval*lcdBrightness/255; // how long to we stay on for?
jstExecuteFn(backlightOnHandler, NULL, now+interval, interval);
jstExecuteFn(backlightOffHandler, NULL, now+interval+ontime, interval);
}
app_timer_start(m_backlight_on_timer_id, APP_TIMER_TICKS(BACKLIGHT_PWM_INTERVAL, APP_TIMER_PRESCALER), NULL);
} else // full brightness
jswrap_banglejs_ioWr(IOEXP_LCD_BACKLIGHT, 0); // backlight on
} else { // lcdBrightness == 0
jswrap_banglejs_ioWr(IOEXP_LCD_BACKLIGHT, 1); // backlight off
}
@ -1793,9 +1796,7 @@ void jswrap_banglejs_init() {
jshEnableWatchDog(5); // 5 second watchdog
// This timer kicks the watchdog, and does some other stuff as well
pollInterval = DEFAULT_ACCEL_POLL_INTERVAL;
//JsSysTime t = jshGetTimeFromMilliseconds(pollInterval);
//jstExecuteFn(peripheralPollHandler, NULL, jshGetSystemTime()+t, t);
// requires APP_TIMER_OP_QUEUE_SIZE=3 in BOARD.py
// requires APP_TIMER_OP_QUEUE_SIZE=5 in BOARD.py
uint32_t err_code = app_timer_create(&m_peripheral_poll_timer_id,
APP_TIMER_MODE_REPEATED,
peripheralPollHandler);
@ -1805,6 +1806,15 @@ void jswrap_banglejs_init() {
#else
app_timer_start(m_peripheral_poll_timer_id, APP_TIMER_TICKS(pollInterval), NULL);
#endif
// Backlight PWM
err_code = app_timer_create(&m_backlight_on_timer_id,
APP_TIMER_MODE_REPEATED,
backlightOnHandler);
jsble_check_error(err_code);
err_code = app_timer_create(&m_backlight_off_timer_id,
APP_TIMER_MODE_SINGLE_SHOT,
backlightOffHandler);
jsble_check_error(err_code);
#endif
@ -1872,9 +1882,8 @@ void jswrap_banglejs_init() {
}*/
void jswrap_banglejs_kill() {
#ifndef EMSCRIPTEN
jstStopExecuteFn(backlightOnHandler, 0);
jstStopExecuteFn(backlightOffHandler, 0);
//jstStopExecuteFn(peripheralPollHandler, 0);
app_timer_stop(m_backlight_on_timer_id);
app_timer_stop(m_backlight_off_timer_id);
app_timer_stop(m_peripheral_poll_timer_id);
jstStopExecuteFn(hrmPollHandler, 0);
#endif

View File

@ -286,6 +286,7 @@ static void memcpy_circular(char *dst, uint32_t *dstIndex, uint32_t dstSize, cha
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);
if (nextFlashPage==0) nextFlashPage=JSF_END_ADDRESS;
// write any data between swapBufferTail and the end of the buffer
while (*swapBufferUsed) {
uint32_t s = *swapBufferUsed;
@ -307,6 +308,7 @@ static void jsfCompactWriteBuffer(uint32_t *writeAddress, uint32_t readAddress,
jshFlashWrite(&swapBuffer[*swapBufferTail], *writeAddress, s);
*writeAddress += s;
nextFlashPage = jsfGetAddressOfNextPage(*writeAddress);
if (nextFlashPage==0) nextFlashPage=JSF_END_ADDRESS;
*swapBufferTail = (*swapBufferTail+s) % swapBufferSize;
*swapBufferUsed -= s;
}
@ -374,7 +376,9 @@ static bool jsfCompactInternal(uint32_t startAddress, char *swapBuffer, uint32_t
bool jsfCompact() {
#ifndef SAVE_ON_FLASH
jsDebug(DBG_INFO,"Compacting\n");
uint32_t pageSize = jsfGetAddressOfNextPage(JSF_START_ADDRESS) - JSF_START_ADDRESS;
uint32_t pageAddr,pageSize;
if (!jshFlashGetPage(JSF_START_ADDRESS, &pageAddr, &pageSize))
return 0;
uint32_t maxRequired = pageSize + (uint32_t)sizeof(JsfFileHeader);
// TODO: We could skip forward pages if we think they are already fully compacted?

View File

@ -2077,7 +2077,7 @@ void jsiIdle() {
// Create the 'time' variable that will be passed to the user
JsVar *timePtr = jsvNewFromFloat(jshGetMillisecondsFromTime(jsiLastIdleTime+timerTime-delay)/1000);
// if it was a watch, set the last state up
jsvObjectSetChild(data, "state", jsvNewFromBool(timerState));
jsvObjectSetChildAndUnLock(data, "state", jsvNewFromBool(timerState));
// set up the lastTime variable of data to what was in the watch
jsvObjectSetChildAndUnLock(data, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0));
// set up the watches lastTime to this one

View File

@ -14,7 +14,9 @@
* ----------------------------------------------------------------------------
*/
#include "jswrap_arraybuffer.h"
#include "jswrap_array.h"
#include "jsparse.h"
#include "jsnative.h"
#include "jsinteractive.h"
/*JSON{
@ -631,7 +633,7 @@ Join all elements of this array together into one string, using 'separator' betw
"class" : "ArrayBufferView",
"name" : "sort",
"ifndef" : "SAVE_ON_FLASH",
"generate" : "jswrap_array_sort",
"generate" : "jswrap_arraybufferview_sort",
"params" : [
["var","JsVar","A function to use to compare array elements (or undefined)"]
],
@ -640,6 +642,30 @@ Join all elements of this array together into one string, using 'separator' betw
}
Do an in-place quicksort of the array
*/
static JsVarFloat _jswrap_arraybufferview_sort_float(JsVarFloat a, JsVarFloat b) {
return a-b;
}
static JsVarInt _jswrap_arraybufferview_sort_int(JsVarInt a, JsVarInt b) {
return a-b;
}
JsVar *jswrap_arraybufferview_sort(JsVar *array, JsVar *compareFn) {
if (!jsvIsArrayBuffer(array)) return 0;
bool isFloat = JSV_ARRAYBUFFER_IS_FLOAT(array->varData.arraybuffer.type);
if (compareFn)
return jswrap_array_sort(array, compareFn);
compareFn = isFloat ?
jsvNewNativeFunction(
(void (*)(void))_jswrap_arraybufferview_sort_float,
JSWAT_JSVARFLOAT|(JSWAT_JSVARFLOAT<<JSWAT_BITS)|(JSWAT_JSVARFLOAT<<(JSWAT_BITS*2))) :
jsvNewNativeFunction(
(void (*)(void))_jswrap_arraybufferview_sort_int,
JSWAT_INT32|(JSWAT_INT32<<JSWAT_BITS)|(JSWAT_INT32<<(JSWAT_BITS*2)));
JsVar *r = jswrap_array_sort(array, compareFn);
jsvUnLock(compareFn);
return r;
}
/*JSON{
"type" : "method",
"class" : "ArrayBufferView",

View File

@ -17,3 +17,4 @@ JsVar *jswrap_arraybuffer_constructor(JsVarInt byteLength);
JsVar *jswrap_typedarray_constructor(JsVarDataArrayBufferViewType type, JsVar *arr, JsVarInt byteOffset, JsVarInt length);
void jswrap_arraybufferview_set(JsVar *parent, JsVar *arr, int offset);
JsVar *jswrap_arraybufferview_map(JsVar *parent, JsVar *funcVar, JsVar *thisVar);
JsVar *jswrap_arraybufferview_sort(JsVar *array, JsVar *compareFn);

View File

@ -29,7 +29,7 @@
#define DBG(...)
#endif
const int STORAGEFILE_CHUNKSIZE = FLASH_PAGE_SIZE - sizeof(JsfFileHeader); // use 32 for testing
const int STORAGEFILE_CHUNKSIZE = (((FLASH_PAGE_SIZE<4096)?FLASH_PAGE_SIZE:4096) - sizeof(JsfFileHeader)); // use 32 for testing
/*JSON{
"type" : "library",

View File

@ -2,6 +2,8 @@ var a = [5,6,8,1,4,7,7,6,1].sort().toString();
var b = (new Uint8Array([1,1,4,5,6,6,7,7,8])).sort().toString();
var c = [5,6,8,1,4,7,7,6,1].sort(function(a,b) { return (a>b)?-1:((a<b)?1:0); }).toString();
var d = [ 0.933, 0.708, 0.256, 0.685, 0.657, 0.433, 0.272, 0.347, 0.376, 0.307 ].sort(function(a,b) { return a-b; }).toString();
var e = ([2,-1,0,-2,1]).sort().toString(); // go JS!
var f = (new Int8Array([2,-1,0,-2,1])).sort().toString();
result = "1,1,4,5,6,6,7,7,8"==a && "1,1,4,5,6,6,7,7,8"==b && "8,7,7,6,6,5,4,1,1"==c && "0.256,0.272,0.307,0.347,0.376,0.433,0.657,0.685,0.708,0.933"==d;
result = "1,1,4,5,6,6,7,7,8"==a && "1,1,4,5,6,6,7,7,8"==b && "8,7,7,6,6,5,4,1,1"==c && "0.256,0.272,0.307,0.347,0.376,0.433,0.657,0.685,0.708,0.933"==d && e=="-1,-2,0,1,2" && f=="-2,-1,0,1,2";