/*JSON{ "type" : "idle", "generate" : "jswrap_wice_idle" }*/ bool jswrap_wice_idle() { #ifdef GATEWAY sendSerial(); if (restartWifiAt != 0 && restartWifiAt < jshGetSystemTime()) { blink(PIN_GRN, 2000); disableWifi(); blink(PIN_RED, 4000); enableWifi(); restartWifiAt = 0; startTime = jshGetSystemTime() + jshGetTimeFromMilliseconds(5000); } #else //NODE if (hasConnection && hasConnection == needConnection){ blink(PIN_BLUE, 20); blink(PIN_BLUE, 20); needConnection = false; disableDASH(); doTimeout = true; //start timing out again } if (doTimeout && transmittingData && !jshHasTransmitData()) { transmittingData = false; delay(20); //DO NOT BLOCK disableDASH(); } #endif return false; }
/*JSON{ "type" : "staticmethod", "class" : "process", "name" : "memory", "generate" : "jswrap_process_memory", "return" : ["JsVar","Information about memory usage"] } Run a Garbage Collection pass, and return an object containing information on memory usage. * `free` : Memory that is available to be used (in blocks) * `usage` : Memory that has been used (in blocks) * `total` : Total memory (in blocks) * `history` : Memory used for command history - that is freed if memory is low. Note that this is INCLUDED in the figure for 'free' * `gc` : Memory freed during the GC pass * `gctime` : Time taken for GC pass (in milliseconds) * `stackEndAddress` : (on ARM) the address (that can be used with peek/poke/etc) of the END of the stack. The stack grows down, so unless you do a lot of recursion the bytes above this can be used. * `flash_start` : (on ARM) the address of the start of flash memory (usually `0x8000000`) * `flash_binary_end` : (on ARM) the address in flash memory of the end of Espruino's firmware. * `flash_code_start` : (on ARM) the address in flash memory of pages that store any code that you save with `save()`. * `flash_length` : (on ARM) the amount of flash memory this firmware was built for (in bytes). **Note:** Some STM32 chips actually have more memory than is advertised. Memory units are specified in 'blocks', which are around 16 bytes each (depending on your device). See http://www.espruino.com/Performance for more information. **Note:** To find free areas of flash memory, see `require('Flash').getFree()` */ JsVar *jswrap_process_memory() { JsSysTime time1 = jshGetSystemTime(); int gc = jsvGarbageCollect(); JsSysTime time2 = jshGetSystemTime(); JsVar *obj = jsvNewObject(); if (obj) { unsigned int history = 0; JsVar *historyVar = jsvObjectGetChild(execInfo.hiddenRoot, JSI_HISTORY_NAME, 0); if (historyVar) { history = (unsigned int)jsvCountJsVarsUsed(historyVar); // vars used to store history jsvUnLock(historyVar); } unsigned int usage = jsvGetMemoryUsage() - history; unsigned int total = jsvGetMemoryTotal(); jsvObjectSetChildAndUnLock(obj, "free", jsvNewFromInteger((JsVarInt)(total-usage))); jsvObjectSetChildAndUnLock(obj, "usage", jsvNewFromInteger((JsVarInt)usage)); jsvObjectSetChildAndUnLock(obj, "total", jsvNewFromInteger((JsVarInt)total)); jsvObjectSetChildAndUnLock(obj, "history", jsvNewFromInteger((JsVarInt)history)); jsvObjectSetChildAndUnLock(obj, "gc", jsvNewFromInteger((JsVarInt)gc)); jsvObjectSetChildAndUnLock(obj, "gctime", jsvNewFromFloat(jshGetMillisecondsFromTime(time2-time1))); #ifdef ARM extern uint32_t LINKER_END_VAR; // end of ram used (variables) - should be 'void', but 'int' avoids warnings extern uint32_t LINKER_ETEXT_VAR; // end of flash text (binary) section - should be 'void', but 'int' avoids warnings jsvObjectSetChildAndUnLock(obj, "stackEndAddress", jsvNewFromInteger((JsVarInt)(unsigned int)&LINKER_END_VAR)); jsvObjectSetChildAndUnLock(obj, "flash_start", jsvNewFromInteger((JsVarInt)FLASH_START)); jsvObjectSetChildAndUnLock(obj, "flash_binary_end", jsvNewFromInteger((JsVarInt)(unsigned int)&LINKER_ETEXT_VAR)); jsvObjectSetChildAndUnLock(obj, "flash_code_start", jsvNewFromInteger((JsVarInt)FLASH_SAVED_CODE_START)); jsvObjectSetChildAndUnLock(obj, "flash_length", jsvNewFromInteger((JsVarInt)FLASH_TOTAL)); #endif } return obj; }
/*JSON{ "type" : "function", "name" : "setTimeout", "generate" : "jswrap_interface_setTimeout", "params" : [ ["function","JsVar","A Function or String to be executed"], ["timeout","float","The time until the function will be executed"], ["args","JsVarArray","Optional arguments to pass to the function when executed"] ], "return" : ["JsVar","An ID that can be passed to clearTimeout"] } Call the function (or evaluate the string) specified ONCE after the timeout in milliseconds. For instance: ``` setTimeout(function () { console.log("Hello World"); }, 1000); // or setTimeout('console.log("Hello World");', 1000); // both print 'Hello World' after a second ``` You can also specify extra arguments that will be sent to the function when it is executed. For example: ``` setTimeout(function (a,b) { console.log(a+" "+b); }, 1000, "Hello", "World"); // prints 'Hello World' after 1 second ``` If you want to stop the function from being called, pass the number that was returned by `setTimeout` into the `clearInterval` function. **Note:** If `setDeepSleep(true)` has been called and the interval is greater than 5 seconds, Espruino may execute the interval up to 1 second late. This is because Espruino can only wake from deep sleep every second - and waking early would cause Espruino to waste power while it waited for the correct time. */ JsVar *_jswrap_interface_setTimeoutOrInterval(JsVar *func, JsVarFloat interval, JsVar *args, bool isTimeout) { // NOTE: The 5 sec delay mentioned in the description is handled by jshSleep JsVar *itemIndex = 0; if (!jsvIsFunction(func) && !jsvIsString(func)) { jsExceptionHere(JSET_ERROR, "Function or String not supplied!"); } else { // Create a new timer JsVar *timerPtr = jsvNewWithFlags(JSV_OBJECT); if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL; JsSysTime intervalInt = jshGetTimeFromMilliseconds(interval); jsvObjectSetChildAndUnLock(timerPtr, "time", jsvNewFromLongInteger((jshGetSystemTime() - jsiLastIdleTime) + intervalInt)); if (!isTimeout) { jsvObjectSetChildAndUnLock(timerPtr, "interval", jsvNewFromLongInteger(intervalInt)); } jsvObjectSetChild(timerPtr, "callback", func); // intentionally no unlock if (jsvGetArrayLength(args)) jsvObjectSetChild(timerPtr, "args", args); // intentionally no unlock // Add to array itemIndex = jsvNewFromInteger(jsiTimerAdd(timerPtr)); jsvUnLock(timerPtr); jsiTimersChanged(); // mark timers as changed } return itemIndex; }
void jshInputThread() { while (isInitialised) { bool shortSleep = false; /* Handle the delayed Ctrl-C -> interrupt behaviour (see description by EXEC_CTRL_C's definition) */ if (execInfo.execute & EXEC_CTRL_C_WAIT) execInfo.execute = (execInfo.execute & ~EXEC_CTRL_C_WAIT) | EXEC_INTERRUPTED; if (execInfo.execute & EXEC_CTRL_C) execInfo.execute = (execInfo.execute & ~EXEC_CTRL_C) | EXEC_CTRL_C_WAIT; // Read from the console while (kbhit()) { int ch = getch(); if (ch<0) break; jshPushIOCharEvent(EV_USBSERIAL, (char)ch); } // Read from any open devices - if we have space if (jshGetEventsUsed() < IOBUFFERMASK/2) { int i; for (i=0;i<=EV_DEVICE_MAX;i++) { if (ioDevices[i]) { char buf[32]; // read can return -1 (EAGAIN) because O_NONBLOCK is set int bytes = (int)read(ioDevices[i], buf, sizeof(buf)); if (bytes>0) { //int j; for (j=0;j<bytes;j++) printf("]] '%c'\r\n", buf[j]); jshPushIOCharEvents(i, buf, (unsigned int)bytes); shortSleep = true; } } } } // Write any data we have IOEventFlags device = jshGetDeviceToTransmit(); while (device != EV_NONE) { char ch = (char)jshGetCharToTransmit(device); //printf("[[ '%c'\r\n", ch); if (ioDevices[device]) { write(ioDevices[device], &ch, 1); shortSleep = true; } device = jshGetDeviceToTransmit(); } #ifdef SYSFS_GPIO_DIR Pin pin; for (pin=0;pin<JSH_PIN_COUNT;pin++) if (gpioShouldWatch[pin]) { shortSleep = true; bool state = jshPinGetValue(pin); if (state != gpioLastState[pin]) { jshPushIOEvent(pinToEVEXTI(pin) | (state?EV_EXTI_IS_HIGH:0), jshGetSystemTime()); gpioLastState[pin] = state; } } #endif usleep(shortSleep ? 1000 : 50000); } }
void sendSerial() { JsSysTime endTime = startTime + jshGetTimeFromMilliseconds(5000); JsSysTime time = jshGetSystemTime(); if (!connected && (startTime != 0 && time > endTime)) { startTime = 0; //disable sending doSendSerial(); } }
/* ********************************************************************************************************* * CHECK TIMEOUT * * Description: This function checks the timeout of DHCP in each state. * Arguments : None. * Returns : None. * Note : ********************************************************************************************************* */ void check_Timeout(uint8_t s, wiz_NetInfo *pWIZNETINFO) { uint8_t i, d_addr[4]; if (retry_count < MAX_DHCP_RETRY) { if (next_time < jshGetSystemTime()) { next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count++; switch ( dhcp_state ) { case STATE_DHCP_DISCOVER : // jsiConsolePrintf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n"); send_DHCP_DISCOVER(s, pWIZNETINFO); break; case STATE_DHCP_REQUEST : // jsiConsolePrintf("<<timeout>> state : STATE_DHCP_REQUEST\r\n"); for (i = 0; i < 4; i++) d_addr[i] = 0xff; send_DHCP_REQUEST(s, Cip, d_addr, pWIZNETINFO); break; case STATE_DHCP_REREQUEST : // jsiConsolePrintf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n"); for (i = 0; i < 4; i++) d_addr[i] = DHCP_SIP[i]; send_DHCP_REQUEST(s, (*pWIZNETINFO).ip, d_addr, pWIZNETINFO); break; default : break; } } } else { next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count = 0; DHCP_timeout = 1; /* open a socket in IP RAW mode for DHCP */ socket(s, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); send_DHCP_DISCOVER(s, pWIZNETINFO); dhcp_state = STATE_DHCP_DISCOVER; } }
/// destroys the given socket void net_wiznet_closesocket(JsNetwork *net, int sckt) { NOT_USED(net); // try and close gracefully disconnect((uint8_t)sckt); JsSysTime timeout = jshGetSystemTime()+jshGetTimeFromMilliseconds(1000); uint8_t status; while ((status=getSn_SR((uint8_t)sckt)) != SOCK_CLOSED && jshGetSystemTime()<timeout) ; // if that didn't work, force it if (status != SOCK_CLOSED) closesocket((uint8_t)sckt); // Wiznet is a bit strange in that it uses the same socket for server and client if (sckt & WIZNET_SERVER_CLIENT) { // so it's just closed, but put it into 'listen' mode again sckt = socket((uint8_t)sckt, Sn_MR_TCP, wiznetSocketPorts[sckt&7], SF_IO_NONBLOCK); listen((uint8_t)sckt); // Be sure to mark it as not a client socket any more wiznetSocketAsServerClient = wiznetSocketAsServerClient & (unsigned char)~(1<<(sckt&7)); } }
static void jswrap_waveform_start(JsVar *waveform, Pin pin, JsVarFloat freq, JsVar *options, bool isWriting) { bool running = jsvGetBoolAndUnLock(jsvObjectGetChild(waveform, "running", 0)); if (running) { jsExceptionHere(JSET_ERROR, "Waveform is already running"); return; } if (!jshIsPinValid(pin)) { jsExceptionHere(JSET_ERROR, "Invalid pin"); return; } if (!isfinite(freq) || freq<0.001) { jsExceptionHere(JSET_ERROR, "Frequency must be above 0.001Hz"); return; } JsSysTime startTime = jshGetSystemTime(); bool repeat = false; if (jsvIsObject(options)) { JsVarFloat t = jsvGetFloatAndUnLock(jsvObjectGetChild(options, "time", 0)); if (isfinite(t) && t>0) startTime = jshGetTimeFromMilliseconds(t*1000); repeat = jsvGetBoolAndUnLock(jsvObjectGetChild(options, "repeat", 0)); } else if (!jsvIsUndefined(options)) { jsExceptionHere(JSET_ERROR, "Expecting options to be undefined or an Object, not %t", options); } bool is16Bit = false; JsVar *buffer = jswrap_waveform_getBuffer(waveform,0, &is16Bit); JsVar *buffer2 = jswrap_waveform_getBuffer(waveform,1,0); UtilTimerEventType eventType; if (is16Bit) { eventType = isWriting ? UET_WRITE_SHORT : UET_READ_SHORT; } else { eventType = isWriting ? UET_WRITE_BYTE : UET_READ_BYTE; } // And finally set it up if (!jstStartSignal(startTime, jshGetTimeFromMilliseconds(1000.0 / freq), pin, buffer, repeat?(buffer2?buffer2:buffer):0, eventType)) jsWarn("Unable to schedule a timer"); jsvUnLock(buffer); jsvUnLock(buffer2); jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(true))); jsvUnLock(jsvObjectSetChild(waveform, "freq", jsvNewFromFloat(freq))); // Add to our list of active waveforms JsVar *waveforms = jsvObjectGetChild(execInfo.hiddenRoot, JSI_WAVEFORM_NAME, JSV_ARRAY); if (waveforms) { jsvArrayPush(waveforms, waveform); jsvUnLock(waveforms); } }
/* ********************************************************************************************************* * Get an IP from the DHCP server. * * Description: * Arguments : None. * Returns : None. * Note : ********************************************************************************************************* */ uint8_t getIP_DHCPS(uint8_t s, wiz_NetInfo *pWIZNETINFO) { uint8_t tmpip[4]; DHCP_XID = 0x12345678; setSHAR((*pWIZNETINFO).mac); // SRC IP tmpip[0] = 0; tmpip[1] = 0; tmpip[2] = 0; tmpip[3] = 0; setSIPR(tmpip); setGAR(tmpip); setSUBR(tmpip); //sysinit(tx_mem_conf, rx_mem_conf); socket(s, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); // Create UDP socket for network configuration //socket(SOCK_CONFIG, Sn_MR_UDP, REMOTE_CLIENT_PORT, 0x00); send_DHCP_DISCOVER(s, pWIZNETINFO); dhcp_state = STATE_DHCP_DISCOVER; DHCP_timeout = 0; next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count = 0; while (dhcp_state != STATE_DHCP_LEASED) { //************* // Add James Kim for IWatchDog #ifdef _IWDG /* Reload IWDG counter */ IWDG_ReloadCounter(); #endif // //************** //if (Recv_ConfigMsg() == MSG_SETTING_REQ) return(2); if (DHCP_timeout == 1 || jspIsInterrupted()) { jsiConsolePrintf("> => DHCP Timeout occurred\r\n"); return(0); } check_DHCP_state(s, pWIZNETINFO); } return 1; }
/*JSON{ "type" : "staticmethod", "class" : "Trig", "name" : "setup", "generate" : "jswrap_trig_setup", "params" : [ ["pin","pin","The pin to use for triggering"], ["options","JsVar","Additional options as an object. defaults are: ```{teethTotal:60,teethMissing:2,minRPM:30,keyPosition:0}```"] ] } Initialise the trigger class */ void jswrap_trig_setup(Pin pin, JsVar *options) { if (!jshIsPinValid(pin)) { jsError("Invalid pin supplied as an argument to Trig.setup"); return; } TriggerStruct *trig = &mainTrigger; // static info trig->teethMissing = 2; trig->teethTotal = 60; trig->keyPosition = 0; JsVarFloat minRPM = 30; if (jsvIsObject(options)) { JsVar *v; v = jsvObjectGetChild(options, "teethMissing", 0); if (!jsvIsUndefined(v)) trig->teethMissing = (unsigned char)jsvGetInteger(v); jsvUnLock(v); v = jsvObjectGetChild(options, "teethTotal", 0); if (!jsvIsUndefined(v)) trig->teethTotal = (unsigned char)jsvGetInteger(v); jsvUnLock(v); v = jsvObjectGetChild(options, "minRPM", 0); if (!jsvIsUndefined(v)) minRPM = jsvGetFloat(v); jsvUnLock(v); v = jsvObjectGetChild(options, "keyPosition", 0); if (!jsvIsUndefined(v)) trig->keyPosition = jsvGetFloat(v); jsvUnLock(v); } trig->maxTooth = (unsigned int)jshGetTimeFromMilliseconds(60000 / (JsVarFloat)(trig->teethTotal * minRPM)); // semi-static info int i; for (i=0;i<TRIGGER_TRIGGERS_COUNT;i++) { trig->triggers[i].tooth = TRIGGERPOINT_TOOTH_DISABLE; trig->triggers[i].newTooth = TRIGGERPOINT_TOOTH_DISABLE; } // dynamic info trig->lastTime = jshGetSystemTime(); trig->avrTrigger = (unsigned int)jshGetTimeFromMilliseconds(10); // average time for a trigger pulse trig->avrTooth = (unsigned int)jshGetTimeFromMilliseconds(10); // average time for a tooth trig->currTooth = 0; trig->teethSinceStart = 0; trig->wrongTriggerTeeth = 0; // finally set up the watch! if (jshIsPinValid(trig->sensorPin)) jshPinWatch(trig->sensorPin, false); trig->sensorPin = pin; jshPinWatch(trig->sensorPin, true); }
/** * \brief Perform the main loop processing. * This is where work is performed * as often as possible. */ static void mainLoop() { if (suspendMainLoopFlag == true) { return; } jsiLoop(); #ifdef EPS8266_BOARD_HEARTBEAT if (system_get_time() - lastTime > 1000 * 1000 * 5) { lastTime = system_get_time(); os_printf("tick: %d\n", jshGetSystemTime()); } #endif // Setup for another callback queueTaskMainLoop(); }
void jshIdle() { while (kbhit()) { jshPushIOCharEvent(EV_USBSERIAL, (char)getch()); } #ifdef SYSFS_GPIO_DIR Pin pin; for (pin=0;pin<JSH_PIN_COUNT;pin++) if (gpioShouldWatch[pin]) { bool state = jshPinGetValue(pin); if (state != gpioLastState[pin]) { jshPushIOEvent(pinToEVEXTI(pin) | (state?EV_EXTI_IS_HIGH:0), jshGetSystemTime()); gpioLastState[pin] = state; } } #endif }
/** * Perform the main loop processing. * This is where work is performed * as often as possible. */ static void mainLoop() { if (suspendMainLoopFlag == true) { return; } jsiLoop(); #ifdef EPS8266_BOARD_HEARTBEAT if (system_get_time() - lastTime > 1000 * 1000 * 5) { lastTime = system_get_time(); os_printf("tick: %u, heap: %u\n", (uint32)(jshGetSystemTime()), system_get_free_heap_size()); } #endif // Setup for another callback //queueTaskMainLoop(); suspendMainLoop(0); // HACK to get around SDK 1.4 bug }
/*JSON{ "type" : "function", "name" : "changeInterval", "generate" : "jswrap_interface_changeInterval", "params" : [ ["id","JsVar","The id returned by a previous call to setInterval"], ["time","float","The new time period in ms"] ] } Change the Interval on a callback created with setInterval, for example: ```var id = setInterval(function () { print('foo'); }, 1000); // every second``` ```changeInterval(id, 1500); // now runs every 1.5 seconds``` This takes effect the next time the callback is called (so it is not immediate). */ void jswrap_interface_changeInterval(JsVar *idVar, JsVarFloat interval) { JsVar *timerArrayPtr = jsvLock(timerArray); if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL; JsVar *timerName = jsvIsBasic(idVar) ? jsvFindChildFromVar(timerArrayPtr, idVar, false) : 0; if (timerName) { JsVar *timer = jsvSkipNameAndUnLock(timerName); JsVar *v; JsVarInt intervalInt = (JsVarInt)jshGetTimeFromMilliseconds(interval); v = jsvNewFromInteger(intervalInt); jsvUnLock2(jsvSetNamedChild(timer, v, "interval"), v); v = jsvNewFromInteger((JsVarInt)(jshGetSystemTime()-jsiLastIdleTime) + intervalInt); jsvUnLock3(jsvSetNamedChild(timer, v, "time"), v, timer); // timerName already unlocked jsiTimersChanged(); // mark timers as changed } else { jsExceptionHere(JSET_ERROR, "Unknown Interval"); } jsvUnLock(timerArrayPtr); }
void trigOnTimingPulse(TriggerStruct *data, JsSysTime pulseTime) { JsSysTime currentTime = jshGetSystemTime(); int timeDiff = (int)(pulseTime - data->lastTime); if (timeDiff < 0) { data->errors |= TRIGERR_WRONG_TIME; timeDiff = 0; // jsiConsolePrintf("0x%Lx 0x%Lx 0x%Lx\n",data->lastTime2, data->lastTime, pulseTime); pulseTime = data->lastTime + data->avrTrigger; // just make it up and hope! } data->lastTime2 = data->lastTime; data->lastTime = pulseTime; unsigned char teeth = (unsigned char)((((timeDiff<<1) / data->avrTrigger) + 1) >> 1); // round to find out # of teeth if (teeth<1) { data->errors |= TRIGERR_SHORT_TOOTH; teeth=1; } // running average if (data->teethSinceStart<16) data->avrTrigger = (data->avrTrigger + timeDiff) >> 1; else
/*JSON{ "type":"function", "name" : "changeInterval", "description" : ["Change the Interval on a callback created with setInterval, for example:", "```var id = setInterval(function () { print('foo'); }, 1000); // every second```", "```changeInterval(id, 1500); // now runs every 1.5 seconds```", "This takes effect the text time the callback is called (so it is not immediate)."], "generate" : "jswrap_interface_changeInterval", "params" : [ [ "id", "JsVar", "The id returned by a previous call to setInterval"], [ "time","float","The new time period in ms" ] ] }*/ void jswrap_interface_changeInterval(JsVar *idVar, JsVarFloat interval) { JsVar *timerArrayPtr = jsvLock(timerArray); if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL; JsVar *timerName = jsvIsBasic(idVar) ? jsvFindChildFromVar(timerArrayPtr, idVar, false) : 0; if (timerName) { JsVar *timer = jsvSkipNameAndUnLock(timerName); JsVar *v; v = jsvNewFromInteger(jshGetTimeFromMilliseconds(interval)); jsvUnLock(jsvSetNamedChild(timer, v, "interval")); jsvUnLock(v); v = jsvNewFromInteger(jshGetSystemTime() + jshGetTimeFromMilliseconds(interval)); jsvUnLock(jsvSetNamedChild(timer, v, "time")); jsvUnLock(v); jsvUnLock(timer); // timerName already unlocked } else { jsError("Unknown Interval"); } jsvUnLock(timerArrayPtr); }
/*JSON{ "type":"function", "name" : "setTimeout", "description" : ["Call the function specified ONCE after the timeout in milliseconds.", "The function that is being called may also take an argument, which is an object containing a field called 'time' (the time in seconds at which the timer happened)", "for example: ```setTimeout(function (e) { print(e.time); }, 1000);```", "This can also be removed using clearTimeout", "**Note:** If `setDeepSleep(true)` has been called and the interval is greater than 5 seconds, Espruino may execute the interval up to 1 second late. This is because Espruino can only wake from deep sleep every second - and waking early would cause Espruino to waste power while it waited for the correct time." ], "generate" : "jswrap_interface_setTimeout", "params" : [ [ "function", "JsVar", "A Function or String to be executed"], [ "timeout", "float", "The time until the function will be executed" ] ], "return" : ["JsVar", "An ID that can be passed to clearTimeout"] }*/ JsVar *_jswrap_interface_setTimeoutOrInterval(JsVar *func, JsVarFloat interval, bool isTimeout) { // NOTE: The 5 sec delay mentioned in the description is handled by jshSleep JsVar *itemIndex = 0; if (!jsvIsFunction(func) && !jsvIsString(func)) { jsError("Function or String not supplied!"); } else { // Create a new timer JsVar *timerPtr = jsvNewWithFlags(JSV_OBJECT); if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL; JsVarInt intervalInt = jshGetTimeFromMilliseconds(interval); jsvUnLock(jsvObjectSetChild(timerPtr, "time", jsvNewFromInteger(jshGetSystemTime() + intervalInt))); jsvUnLock(jsvObjectSetChild(timerPtr, "interval", jsvNewFromInteger(intervalInt))); if (!isTimeout) jsvUnLock(jsvObjectSetChild(timerPtr, "recur", jsvNewFromBool(true))); jsvObjectSetChild(timerPtr, "callback", func); // intentionally no unlock // Add to array itemIndex = jsvNewFromInteger(jsiTimerAdd(timerPtr)); jsvUnLock(timerPtr); } return itemIndex; }
void jshPinPulse(Pin pin, bool pulsePolarity, JsVarFloat pulseTime) { // ---- USE TIMER FOR PULSE if (!jshIsPinValid(pin)) { jsExceptionHere(JSET_ERROR, "Invalid pin!"); return; } if (pulseTime<=0) { // just wait for everything to complete jstUtilTimerWaitEmpty(); return; } else { // find out if we already had a timer scheduled UtilTimerTask task; if (!jstGetLastPinTimerTask(pin, &task)) { // no timer - just start the pulse now! jshPinOutput(pin, pulsePolarity); task.time = jshGetSystemTime(); } // Now set the end of the pulse to happen on a timer jstPinOutputAtTime(task.time + jshGetTimeFromMilliseconds(pulseTime), &pin, 1, !pulsePolarity); } }
/*JSON{ "type" : "init", "generate" : "jswrap_wice_init" }*/ void jswrap_wice_init() { jspCallNamedFunction(execInfo.root, "USB.setConsole", 0, 0); jspEvaluate("USB.setConsole();"); #ifdef WICE_DEBUG WDEBUGLN("USB is console"); #endif /*JsVar *mode = jsvNewFromString("output"); jswrap_io_pinMode(jshGetPinFromString(PIN_DASH7_XTAL_EN), mode); jswrap_io_pinMode(jshGetPinFromString(PIN_DASH7_RST), mode); jsvUnLock(mode);*/ enableDASH(); // Set up the DASH7 USART how we want it JshUSARTInfo inf; jshUSARTInitInfo(&inf); inf.baudRate = 115200; inf.pinRX = jshGetPinFromString(PIN_DASH7_RX); inf.pinTX = jshGetPinFromString(PIN_DASH7_TX); jshUSARTSetup(EV_SERIAL1, &inf); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL1_DASH7, false); jswrap_object_addEventListener(serial, "data", dash7Callback, JSWAT_VOID | (JSWAT_JSVAR<<(JSWAT_BITS))); jsvUnLock(serial); startTime = jshGetSystemTime(); wice_msg_init(&wifiMessage, wifiMessageBuffer, 2048); wice_msg_init(&dash7Message, dash7MessageBuffer, 256); options = jspEvaluate("x = {\"repeat\": \"true\", \"edge\": \"rising\", \"debounce\":\"50\"}"); Pin btn = jshGetPinFromString("B10"); JsVar *btnmode = jsvNewFromString("input"); jswrap_io_pinMode(btn, btnmode); jsvUnLock(btnmode); #ifdef GATEWAY WDEBUGLN("GATEWAY"); blink(PIN_GRN, 50); /// opendrain and digitalwrite 1 will 'opencircuit it' /// http://www.espruino.com/Reference#l__global_pinMode JsVar *opendrain = jsvNewFromString("opendrain"); WDEBUGSTRVAR(opendrain); jswrap_io_pinMode(jshGetPinFromString(PIN_ESP_GPIO_0), opendrain); jswrap_io_pinMode(jshGetPinFromString(PIN_ESP_GPIO_2), opendrain); jshPinOutput(jshGetPinFromString(PIN_ESP_GPIO_0), 1); jshPinOutput(jshGetPinFromString(PIN_ESP_GPIO_2), 1); jsvUnLock(opendrain); /// must opendrain gpio0/2 because of boot modes /// https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process enableWifi(); // Set up the Wifi USART how we want it JshUSARTInfo inf4; jshUSARTInitInfo(&inf4); inf4.baudRate = 115200; inf4.pinRX = jshGetPinFromString(PIN_ESP_RX); inf4.pinTX = jshGetPinFromString(PIN_ESP_TX); jshUSARTSetup(EV_SERIAL4, &inf4); /// make button restart wifi for gateway JsVar *restartWifi_fn = jsvNewNativeFunction(restartWifi, JSWAT_VOID); btnEvent = jswrap_interface_setWatch(restartWifi_fn, btn, options); jsvUnLock(restartWifi_fn); /// configure wifi usart callback JsVar *wifiSerial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false); jswrap_object_addEventListener(wifiSerial, "data", wifiCallback, JSWAT_VOID | (JSWAT_JSVAR<<(JSWAT_BITS))); jsvUnLock(wifiSerial); doSendSerial(); #else WDEBUGLN("NODE"); blink(PIN_BLUE, 50); /// make button a forced measurement for nodes JsVar *doMeasurementAndWaitForResponse_fn = jsvNewNativeFunction(doMeasurementAndWaitForResponse, JSWAT_VOID); btnEvent = jswrap_interface_setWatch(doMeasurementAndWaitForResponse_fn, btn, options); jsvUnLock(doMeasurementAndWaitForResponse_fn); /// set up main interval callback for nodes JsVar *doMeasurement_fn = jsvNewNativeFunction(doMeasurement, JSWAT_VOID); currentInterval = jswrap_interface_setInterval(doMeasurement_fn, INTERVAL, 0); jsvUnLock(doMeasurement_fn); /// prepare the I2C bus for talking with the Si7050 temp sensor JsVar *s = jspEvaluate("I2C1.setup({scl:B8, sda:B9, bitrate:50000});"); jsvUnLock(s); disableDASH(); jswrap_interface_setDeepSleep(true); //do deep sleep [TODO can we wake on press?] #endif }
/*JSON{ "type" : "staticmethod", "class" : "Date", "name" : "now", "generate" : "jswrap_date_now", "return" : ["float",""] } Get the number of milliseconds elapsed since 1970 (or on embedded platforms, since startup) */ JsVarFloat jswrap_date_now() { // Not quite sure why we need this, but (JsVarFloat)jshGetSystemTime() / (JsVarFloat)jshGetTimeFromMilliseconds(1) in inaccurate on STM32 return ((JsVarFloat)jshGetSystemTime() / (JsVarFloat)jshGetTimeFromMilliseconds(1000)) * 1000; }
/*JSON{ "type" : "staticmethod", "class" : "Trig", "name" : "getRPM", "generate" : "jswrap_trig_getRPM", "return" : ["float","The current RPM of the trigger wheel"] } Get the RPM of the trigger wheel */ JsVarFloat jswrap_trig_getRPM() { TriggerStruct *trig = &mainTrigger; if (jshGetSystemTime() > (trig->lastTime + trig->maxTooth)) return 0; return jshGetTimeFromMilliseconds(60000) / (JsVarFloat)(trig->avrTooth * trig->teethTotal); }
void wice_msg_start(WiceMessage *msg){ if (!msg->hasStarted){ msg->startTime = (JsVarFloat)jshGetSystemTime() / (JsVarFloat)jshGetTimeFromMilliseconds(1000); msg->hasStarted = true; } }
bool wice_msg_isTimeout(WiceMessage *msg){ JsVarFloat current = (JsVarFloat)jshGetSystemTime() / (JsVarFloat)jshGetTimeFromMilliseconds(1000); return (current > (msg->startTime + 20)); }
unsigned char * hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) { unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; JsSysTime timeout = jshGetSystemTime() + jshGetTimeFromMilliseconds(10000); // blocking for 10 seconds (!!!) cc3000_irq_disable(); while (!jspIsInterrupted()) { if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams,0 ,*(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } if (pRetParams) // GW: just in case. It'll probably still crash though :( memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; cc3000_spi_resume(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { cc3000_irq_enable(); return NULL; } } else cc3000_check_irq_pin(); if (jshGetSystemTime() > timeout) { jspSetInterrupted(true); jsError("Timeout in CC3000 driver (%d)", tSLInformation.usRxEventOpcode); break; } } cc3000_irq_enable(); return NULL; }
/* ********************************************************************************************************* * CHECK DHCP STATE * * Description: This function checks the state of DHCP. * Arguments : None. * Returns : None. * Note : ********************************************************************************************************* */ void check_DHCP_state(uint8_t s, wiz_NetInfo *pWIZNETINFO) { uint16_t len, i; uint8_t type, flag; uint8_t d_addr[4]; type = 0; if ((len = getSn_RX_RSR(s)) > 0) { type = parseDHCPMSG(s, len, pWIZNETINFO); } switch ( dhcp_state ) { case STATE_DHCP_DISCOVER : if (type == DHCP_OFFER) { jsiConsolePrintf("> Receive DHCP_OFFER\r\n"); for (i = 0; i < 4; i++) d_addr[i] = 0xff; send_DHCP_REQUEST(s, Cip, d_addr, pWIZNETINFO); dhcp_state = STATE_DHCP_REQUEST; } else check_Timeout(s, pWIZNETINFO); break; case STATE_DHCP_REQUEST : if (type == DHCP_ACK) { jsiConsolePrintf("> Receive DHCP_ACK\r\n"); if (check_leasedIP(s, pWIZNETINFO)) { //iinchip_init() - WIZnet chip reset & Delay (10ms); //Set_network(); ctlwizchip(CW_RESET_WIZCHIP, 0); ctlnetwork(CN_SET_NETINFO, (void*)&(*pWIZNETINFO)); /* for (i = 0; i < 12; i++) { //EEP_Write(EEP_LIP+i, *(uint8_t *)((*pWIZNETINFO).ip+i)); } */ next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count = 0; dhcp_state = STATE_DHCP_LEASED; } else { next_time = jshGetSystemTime() + DHCP_WAIT_TIME1; retry_count = 0; //dhcp_state = STATE_DHCP_DISCOVER; dhcp_state = STATE_DHCP_LEASED; jsiConsolePrintf("> => Recceived IP is invalid\r\n"); //iinchip_init(); //Set_Default(); //Set_network(); //ctlwizchip(CW_RESET_WIZCHIP, 0); //set_default_netinfo(); //ctlnetwork(CN_SET_NETINFO, (void*)&(*pWIZNETINFO)); } } else if (type == DHCP_NAK) { jsiConsolePrintf("> Receive DHCP_NACK\r\n"); next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count = 0; dhcp_state = STATE_DHCP_DISCOVER; } else check_Timeout(s, pWIZNETINFO); break; case STATE_DHCP_LEASED : if ((lease_time.lVal != 0xffffffff) && ((lease_time.lVal/2) < jshGetSystemTime())) { jsiConsolePrintf("> Renewal IP address \r\n"); type = 0; for (i = 0; i < 4; i++) OLD_SIP[i] = (*pWIZNETINFO).ip[i]; for (i = 0; i < 4; i++) d_addr[i] = DHCP_SIP[i]; DHCP_XID++; send_DHCP_REQUEST(s, (*pWIZNETINFO).ip, d_addr, pWIZNETINFO); dhcp_state = STATE_DHCP_REREQUEST; next_time = jshGetSystemTime() + DHCP_WAIT_TIME; } break; case STATE_DHCP_REREQUEST : if (type == DHCP_ACK) { retry_count = 0; flag = 0; for (i = 0; i < 4; i++) { if (OLD_SIP[i] != (*pWIZNETINFO).ip[i]) { flag = 1; break; } } // change to new IP address if (flag) { //iinchip_init(); //Set_network(); ctlwizchip(CW_RESET_WIZCHIP, 0); ctlnetwork(CN_SET_NETINFO, (void*)&(*pWIZNETINFO)); } next_time = jshGetSystemTime() + DHCP_WAIT_TIME; dhcp_state = STATE_DHCP_LEASED; } else if (type == DHCP_NAK) { next_time = jshGetSystemTime() + DHCP_WAIT_TIME; retry_count = 0; dhcp_state = STATE_DHCP_DISCOVER; // jsiConsolePrintf("state : STATE_DHCP_DISCOVER\r\n"); } else check_Timeout(s, pWIZNETINFO); break; case STATE_DHCP_RELEASE : break; default : break; } }