Add EV_CUSTOM event handler and tidy up E.setComparator

This commit is contained in:
Gordon Williams 2024-11-18 09:31:48 +00:00
parent 4c508935c6
commit 4a02875504
6 changed files with 55 additions and 26 deletions

View File

@ -378,9 +378,9 @@ for jsondata in jsondatas:
if not js.endswith("})"):
print(common.as_c_string(js)+"\n")
FATAL_ERROR("generate_js function doesn't end in })")
fnMatch = re.match(r"^\((function|\252)\(([^\)]*)\)", js);
if fnMatch:
fnKeyword, fnArgs = fnMatch.groups()
fnCode = js[len(fnKeyword)+len(fnArgs)+4:-2]
@ -388,7 +388,7 @@ for jsondata in jsondatas:
else:
print(common.as_c_string(js)+"\n")
FATAL_ERROR("generate_js function not in the correct format")
if hasThis(jsondata): statement = statement + ", parent"
else: statement = statement + ", NULL"
@ -743,25 +743,44 @@ for jsondata in jsondatas:
codeOut(" "+jsondata["generate"]+"();")
codeOut('}')
codeOut("/** When called with an Object, fields are added for each device that is used with estimated power usage in uA */")
codeOut('')
codeOut('')
codeOut("/** When called with an Object, fields are added for each device that is used with estimated power usage in uA (type:'powerusage' in JSON) */")
codeOut('void jswGetPowerUsage(JsVar *devices) {')
for jsondata in jsondatas:
if "type" in jsondata and jsondata["type"]=="powerusage":
codeOut(" "+jsondata["generate"]+"(devices);")
codeOut('}')
codeOut('')
codeOut('')
codeOut("/** Tasks to run when a character event is received */")
codeOut("/** Tasks to run when a character is received on a certain event channel. True if handled and shouldn't go to IRQ (type:'EV_SERIAL1/etc' in JSON) */")
codeOut('bool jswOnCharEvent(IOEventFlags channel, char charData) {')
codeOut(' NOT_USED(channel);')
codeOut(' NOT_USED(charData);')
for jsondata in jsondatas:
if "type" in jsondata and jsondata["type"].startswith("EV_"):
if "type" in jsondata and jsondata["type"]!="EV_CUSTOM" and jsondata["type"].startswith("EV_"):
codeOut(" if (channel=="+jsondata["type"]+") return "+jsondata["generate"]+"(charData);")
codeOut(' return false;')
codeOut('}')
codeOut("/** When we receive EV_CUSTOM, this is called so any library (eg Waveform) can hook onto it (type:'EV_CUSTOM' in JSON) */")
codeOut('void jswOnCustomEvent(IOEvent *event) {')
codeOut(' NOT_USED(event);')
for jsondata in jsondatas:
if "type" in jsondata and jsondata["type"]=="EV_CUSTOM":
codeOut(" "+jsondata["generate"]+"(event);")
codeOut('}')
codeOut('')
codeOut('')
codeOut('')
codeOut('')
codeOut("/** If we have a built-in module with the given name, return the module's contents - or 0 */")
codeOut('const char *jswGetBuiltInJSLibrary(const char *name) {')
codeOut(' NOT_USED(name);')
@ -826,7 +845,7 @@ if "USE_CALLFUNCTION_HACK" in board.defines:
# codeOut(' case '+argSpec+":")
argSpecs = []
# Ensure we force-add any entries we need
writeCallFunctionHackEntry(argSpecs, {'type': 'function', 'name': 'X', 'generate': 'X', 'params': []}) # jswrap_io
writeCallFunctionHackEntry(argSpecs, {'type': 'function', 'name': 'X', 'generate': 'X', 'params': []}) # jswrap_io
writeCallFunctionHackEntry(argSpecs, {'type': 'method', 'class': 'X', 'name': 'X', 'generate': 'X', 'params': [['1', 'JsVar', '']]}) # jswrap_promise
writeCallFunctionHackEntry(argSpecs, {'type': 'method', 'class': 'X', 'name': 'X', 'generate': 'X', 'params': [['1', 'JsVar', ''],['2', 'JsVar', '']]}) # jswrap_promise
writeCallFunctionHackEntry(argSpecs, {'type': 'method', 'class': 'X', 'name': 'X', 'generate': 'X', 'params': [['1', 'JsVar', ''],['2', 'JsVar', ''],['3', 'JsVar', '']]}) # jswrap_promise
@ -835,7 +854,7 @@ if "USE_CALLFUNCTION_HACK" in board.defines:
writeCallFunctionHackEntry(argSpecs, {'type': 'function', 'name': 'X', 'generate': 'X', 'params': [['1', 'float', ''],['1', 'float', '']], 'return': ['float','']}) # jswrap_banglejs + jswrap_arraybuffer
writeCallFunctionHackEntry(argSpecs, {'type': 'function', 'name': 'X', 'generate': 'X', 'params': [['1', 'int', ''],['1', 'int', '']], 'return': ['int','']}) # jswrap_arraybuffer
for jsondata in jsondatas:
if "generate" in jsondata:
if "generate" in jsondata:
writeCallFunctionHackEntry(argSpecs, jsondata)
#((uint32_t (*)(size_t,size_t,size_t,size_t))function)(argData[0],argData[1],argData[2],argData[3]);
codeOut(' default: jsExceptionHere(JSET_ERROR,"Unknown argspec %d",argumentSpecifier);')

View File

@ -68,8 +68,9 @@ if "check_output" not in dir( subprocess ):
# // hwinit = function to run on Hardware Initialisation (called once at boot time, after jshInit, before jsvInit/etc)
# // init = function to run on Initialisation (eg boot/load/reset/after save/etc)
# // kill = function to run on Deinitialisation (eg before save/reset/etc)
# // EV_xxx = Something to be called with a character in an IRQ when it is received (eg. EV_SERIAL1)
# // powerusage = fn(JsVar*) called with an object, and should insert fields for deviec names and estimated power usage in uA
# // EV_CUSTOM = Called whenever an event of type EV_CUSTOM is received (jswOnCustomEvent(event))
# // EV_xxx = Something to be called with a character in an IRQ when it is received (eg. EV_SERIAL1) (jswOnCharEvent)
# // powerusage = fn(JsVar*) called with an object, and should insert fields for deviec names and estimated power usage in uA (jswGetPowerUsage)
# "class" : "Double", "name" : "doubleToIntBits",
# "needs_parentName":true, // optional - if for a method, this makes the first 2 args parent+parentName (not just parent)
# "generate_full|generate|wrap" : "*(JsVarInt*)&x", // if generate=false, it'll only be used for docs

View File

@ -2154,19 +2154,7 @@ void jsiIdle() {
jsvUnLock(usartClass);
#endif
} else if (eventType == EV_CUSTOM) {
// TODO: maybe we should handle this with jswrapper.c?
#if defined(NRF52_SERIES) && !defined(SAVE_ON_FLASH)
// see jshSetComparator / E.setComparator
int type = event.data.time & EVC_TYPE_MASK;
if (type == EVC_LPCOMP) {
JsVar *arg = jsvNewFromInteger((event.data.time & EVC_DATA_LPCOMP_UP) ? 1 : -1);
jsiExecuteEventCallbackOn("E",JS_EVENT_PREFIX"comparator",1,&arg);
jsvUnLock(arg);
}
#endif
#ifdef NRF52_SERIES
jsiConsolePrintf("EV_CUSTOM %d\n", event.data.time);
#endif
jswOnCustomEvent(&event);
#ifdef BLUETOOTH
} else if ((eventType == EV_BLUETOOTH_PENDING) || (eventType == EV_BLUETOOTH_PENDING_DATA)) {
maxEvents -= jsble_exec_pending(&event);

View File

@ -684,6 +684,9 @@ void jswrap_espruino_kickWatchdog() {
jshKickWatchDog();
}
/*JSON{
"type" : "event",
"#if" : "defined(NRF52) && !defined(SAVE_ON_FLASH)",
@ -695,6 +698,20 @@ void jswrap_espruino_kickWatchdog() {
}
Called when a bit rises or falls above a set level. See `E.setComparator` for setup.
*/
/*JSON{
"type" : "EV_CUSTOM",
"#if" : "defined(NRF52) && !defined(SAVE_ON_FLASH)",
"generate" : "jswrap_espruino_setComparator_eventHandler"
}
*/
void jswrap_espruino_setComparator_eventHandler(IOEvent *event) {
// see jshSetComparator / E.setComparator
if ((event->data.time & EVC_TYPE_MASK) == EVC_LPCOMP) {
JsVar *arg = jsvNewFromInteger((event->data.time & EVC_DATA_LPCOMP_UP) ? 1 : -1);
jsiExecuteEventCallbackOn("E",JS_EVENT_PREFIX"comparator",1,&arg);
jsvUnLock(arg);
}
}
/*JSON{
"type" : "staticmethod",
"#if" : "defined(NRF52) && !defined(SAVE_ON_FLASH)",

View File

@ -30,6 +30,7 @@ void jswrap_espruino_FFT(JsVar *arrReal, JsVar *arrImag, bool inverse);
void jswrap_espruino_enableWatchdog(JsVarFloat time, JsVar *isAuto);
void jswrap_espruino_kickWatchdog();
void jswrap_espruino_setComparator_eventHandler(IOEvent *event);
void jswrap_espruino_setComparator(Pin pin, JsVarFloat level);
/// Return an array of errors based on the current flags
JsVar *jswrap_espruino_getErrorFlagArray(JsErrorFlags flags);

View File

@ -149,12 +149,15 @@ void jswInit();
/** Tasks to run on Deinitialisation */
void jswKill();
/** When called with an Object, fields are added for each device that is used with estimated power usage in uA */
/** When called with an Object, fields are added for each device that is used with estimated power usage in uA (type:'powerusage' in JSON) */
void jswGetPowerUsage(JsVar *devices);
/** Tasks to run when a character is received on a certain event channel. True if handled and shouldn't go to IRQ */
/** Tasks to run when a character is received on a certain event channel. True if handled and shouldn't go to IRQ (type:'EV_SERIAL1/etc' in JSON) */
bool jswOnCharEvent(IOEventFlags channel, char charData);
/** When we receive EV_CUSTOM, this is called so any library (eg Waveform) can hook onto it (type:'EV_CUSTOM' in JSON) */
void jswOnCustomEvent(IOEvent *event);
/** If we get this in 'require', do we have the object for this
inside the interpreter already? If so, return the native function
pointer of the object's constructor */