Util Timer now runs independently of system time. More accurate on nRF52 (fix #2125)

Also remove (mostly) duplicated jshPinPulse
This commit is contained in:
Gordon Williams 2022-03-03 16:43:00 +00:00
parent ad3eb1094d
commit 8861b27954
21 changed files with 98 additions and 198 deletions

View File

@ -33,6 +33,7 @@
Bangle.js1: Add 'back' option to E.showScroller and Bangle.setUI
Bangle.js1: setUI button handlers now work on falling edge
Bangle.js: Add setUI custom 'swipe' handler
Util Timer now runs independently of system time. More accurate on nRF52 (fix #2125)
2v12 : nRF52840: Flow control XOFF is now sent at only 3/8th full - delays in BLE mean we can sometimes fill our 1k input buffer otherwise
__FILE__ is now set correctly for apps (fixes 2v11 regression)

View File

@ -1674,7 +1674,7 @@ static void jswrap_banglejs_setLCDPowerBacklight(bool isOn) {
#elif defined(ESPR_BACKLIGHT_FADE)
if (!lcdFadeHandlerActive) {
JsSysTime t = jshGetTimeFromMilliseconds(10);
jstExecuteFn(backlightFadeHandler, NULL, t, t);
jstExecuteFn(backlightFadeHandler, NULL, t, t, NULL);
lcdFadeHandlerActive = true;
backlightFadeHandler();
}
@ -4403,7 +4403,7 @@ JsVar *jswrap_banglejs_beep(int time, int freq) {
#endif
}
}
jstExecuteFn(jswrap_banglejs_beep_callback, NULL, jshGetTimeFromMilliseconds(time), 0);
jstExecuteFn(jswrap_banglejs_beep_callback, NULL, jshGetTimeFromMilliseconds(time), 0, NULL);
return jsvLockAgain(promiseBeep);
}
@ -4446,7 +4446,7 @@ JsVar *jswrap_banglejs_buzz(int time, JsVarFloat amt) {
if (!promiseBuzz) return 0;
buzzAmt = (unsigned char)(amt*255);
if (jstExecuteFn(jswrap_banglejs_buzz_callback, NULL, jshGetTimeFromMilliseconds(time), 0)) {
if (jstExecuteFn(jswrap_banglejs_buzz_callback, NULL, jshGetTimeFromMilliseconds(time), 0, NULL)) {
// task schedule succeeded - start buzz
if (bangleFlags & JSBF_ENABLE_BUZZ) {
_jswrap_banglejs_setVibration();

View File

@ -257,7 +257,7 @@ void jswrap_microbit_show_raw(uint32_t newState) {
if ((newState!=0) && (microbitLEDState==0)) {
// we want to display something but we don't have an interval
JsSysTime period = jshGetTimeFromMilliseconds(MB_LED_UPDATE_MS);
jstExecuteFn(jswrap_microbit_display_callback, 0, period, (uint32_t)period);
jstExecuteFn(jswrap_microbit_display_callback, 0, period, (uint32_t)period, NULL);
// and also set pins to outputs
nrf_gpio_cfg_output(MB_LED_COL1);
nrf_gpio_cfg_output(MB_LED_COL2);

View File

@ -60,7 +60,7 @@ void hrm_timer() {
static void hrm_sensor_timer_start() {
JsSysTime t = jshGetTimeFromMilliseconds(hrmPollInterval);
jstExecuteFn(hrm_timer, NULL, t, t);
jstExecuteFn(hrm_timer, NULL, t, t, NULL);
}
static void hrm_sensor_timer_stop() {

View File

@ -30,7 +30,7 @@ void hrm_timer() {
static void hrm_sensor_timer_start() {
JsSysTime t = jshGetTimeFromMilliseconds(hrmPollInterval);
jstExecuteFn(hrm_timer, NULL, t, t);
jstExecuteFn(hrm_timer, NULL, t, t, NULL);
}
static void hrm_sensor_timer_stop() {

View File

@ -1109,6 +1109,7 @@ void jswrap_puck_IR(JsVar *data, Pin cathode, Pin anode) {
_jswrap_puck_IR_pin = cathode;
}
JsSysTime time = 0;
uint32_t timerOffset = jstGetUtilTimerOffset();
bool hasPulses = false;
JsvIterator it;
@ -1116,11 +1117,11 @@ void jswrap_puck_IR(JsVar *data, Pin cathode, Pin anode) {
while (jsvIteratorHasElement(&it)) {
JsVarFloat pulseTime = jsvIteratorGetFloatValue(&it);
if (twoPin) {
if (hasPulses) jstPinOutputAtTime(time, &anode, 1, pulsePolarity);
if (hasPulses) jstPinOutputAtTime(time, &timerOffset, &anode, 1, pulsePolarity);
else jshPinSetState(anode, JSHPINSTATE_GPIO_OUT);
} else {
if (pulsePolarity) jstExecuteFn(_jswrap_puck_IR_on, NULL, time, 0);
else jstExecuteFn(_jswrap_puck_IR_off, NULL, time, 0);
if (pulsePolarity) jstExecuteFn(_jswrap_puck_IR_on, NULL, time, 0, &timerOffset);
else jstExecuteFn(_jswrap_puck_IR_off, NULL, time, 0, &timerOffset);
}
hasPulses = true;
time += jshGetTimeFromMilliseconds(pulseTime);
@ -1132,9 +1133,9 @@ void jswrap_puck_IR(JsVar *data, Pin cathode, Pin anode) {
if (hasPulses) {
if (twoPin) {
uint32_t d = cathode | anode<<8;
jstExecuteFn(_jswrap_puck_IR_done, (void*)d, time, 0);
jstExecuteFn(_jswrap_puck_IR_done, (void*)d, time, 0, &timerOffset);
} else {
jstExecuteFn(_jswrap_puck_IR_off, NULL, time, 0);
jstExecuteFn(_jswrap_puck_IR_off, NULL, time, 0, &timerOffset);
}
}
}

View File

@ -58,6 +58,7 @@ TriggerStruct mainTrigger = { (Pin)-1/*pin*/};
void trigOnTimingPulse(TriggerStruct *data, JsSysTime pulseTime) {
JsSysTime currentTime = jshGetSystemTime();
uint32_t timerOffset = jstGetUtilTimerOffset();
int timeDiff = (int)(pulseTime - data->lastTime);
if (timeDiff < 0) {
data->errors |= TRIGERR_WRONG_TIME;
@ -166,10 +167,10 @@ void trigOnTimingPulse(TriggerStruct *data, JsSysTime pulseTime) {
//jsiConsolePrint("Trigger already passed\n");
}
if (!jstPinOutputAtTime(trigTime, trig->pins, TRIGGERPOINT_TRIGGERS_COUNT, 0xFF))
if (!jstPinOutputAtTime(trigTime, &timerOffset, trig->pins, TRIGGERPOINT_TRIGGERS_COUNT, 0xFF))
data->errors |= TRIGERR_TIMER_FULL;
if (trig->pulseLength>0) {
if (!jstPinOutputAtTime(trigTime+trig->pulseLength, trig->pins, TRIGGERPOINT_TRIGGERS_COUNT, 0))
if (!jstPinOutputAtTime(trigTime+trig->pulseLength, &timerOffset, trig->pins, TRIGGERPOINT_TRIGGERS_COUNT, 0))
data->errors |= TRIGERR_TIMER_FULL;
}
// trigger fired, so update it

View File

@ -198,8 +198,6 @@ typedef enum {
/// Output an analog value on a pin - either via DAC, hardware PWM, or software PWM
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags); // if freq<=0, the default is used
/// Pulse a pin for a certain time, but via IRQs, not JS: `digitalWrite(pin,value);setTimeout("digitalWrite(pin,!value)", time*1000);`
void jshPinPulse(Pin pin, bool value, JsVarFloat time);
/// Can the given pin be watched? it may not be possible because of conflicts
bool jshCanWatch(Pin pin);
/// start watching pin - return the EXTI (IRQ number flag) associated with it

View File

@ -47,6 +47,7 @@ void jsserialSoftwareFunc(
bitCnt += 1;
// Get ready to send
uint32_t timerOffset = jstGetUtilTimerOffset();
JsSysTime bitTime = jshGetTimeFromMilliseconds(1000.0 / inf->baudRate);
JsSysTime time;
UtilTimerTask task;
@ -70,19 +71,19 @@ void jsserialSoftwareFunc(
} else {
// state changed!
time += bitTime*outCount;
jstPinOutputAtTime(time, &inf->pinTX, 1, bit);
jstPinOutputAtTime(time, &timerOffset, &inf->pinTX, 1, bit);
outState = bit;
outCount = 1;
}*/
// hacky - but seems like we may have some timing problems otherwise
jstPinOutputAtTime(time, &inf->pinTX, 1, bit);
jstPinOutputAtTime(time, &timerOffset, &inf->pinTX, 1, bit);
//jsiConsolePrintf("-> %d\n",bit);
time += bitTime;
}
// And finish off by raising...
time += bitTime*outCount;
//jsiConsolePrintf("-> 1 (final)\n");
jstPinOutputAtTime(time, &inf->pinTX, 1, 1);
jstPinOutputAtTime(time, &timerOffset, &inf->pinTX, 1, 1);
// we do this even if we are high, because we want to ensure that the next char is properly spaced
// Ideally we'd be able to store the last bit time when sending so we could just go straight on from it
}

View File

@ -31,6 +31,8 @@ unsigned int utilTimerData;
uint16_t utilTimerReload0H, utilTimerReload0L, utilTimerReload1H, utilTimerReload1L;
/// When we rescheduled the timer, how far in the future were we meant to get called (in system time)?
int utilTimerPeriod;
/// Incremented with utilTimerPeriod - used when we're adding multiple items and we want them all relative to each other
volatile int utilTimerOffset;
#ifndef SAVE_ON_FLASH
@ -95,6 +97,7 @@ void jstUtilTimerInterruptHandler() {
utilTimerTasks[t].time -= utilTimerPeriod;
t = (t+1) & (UTILTIMERTASK_TASKS-1);
}
utilTimerOffset += utilTimerPeriod;
// Check timers and execute any timers that are due
while (utilTimerTasksTail!=utilTimerTasksHead && utilTimerTasks[utilTimerTasksTail].time <= 0) {
UtilTimerTask *task = &utilTimerTasks[utilTimerTasksTail];
@ -212,6 +215,11 @@ void jstUtilTimerWaitEmpty() {
WAIT_UNTIL(!jstUtilTimerIsRunning(), "Utility Timer");
}
/// Get the current timer offset - supply this when adding >1 timer task to ensure they are all executed at the same time relative to each other
uint32_t jstGetUtilTimerOffset() {
return utilTimerOffset;
}
/// Is the timer full - can it accept any other signals?
static bool utilTimerIsFull() {
unsigned char nextHead = (utilTimerTasksHead+1) & (UTILTIMERTASK_TASKS-1);
@ -226,12 +234,20 @@ void jstRestartUtilTimer() {
jshUtilTimerStart(utilTimerPeriod);
}
// Queue a task up to be executed when a timer fires... return false on failure
bool utilTimerInsertTask(UtilTimerTask *task) {
/** Queue a task up to be executed when a timer fires... return false on failure.
* task.time is the delay at which to execute the task. If timerOffset!==NULL then
* task.time is relative to the time at which timerOffset=jstGetUtilTimerOffset().
* This allows pulse trains/etc to be scheduled in sync.
*/
bool utilTimerInsertTask(UtilTimerTask *task, uint32_t *timerOffset) {
// check if queue is full or not
if (utilTimerIsFull()) return false;
if (!utilTimerInIRQ) jshInterruptOff();
// See above - keep times in sync
if (timerOffset)
task->time += (int)*timerOffset - (int)utilTimerOffset;
// find out where to insert
unsigned char insertPos = utilTimerTasksTail;
while (insertPos != utilTimerTasksHead && utilTimerTasks[insertPos].time < task->time)
@ -355,7 +371,7 @@ bool jstGetLastBufferTimerTask(JsVar *var, UtilTimerTask *task) {
}
#endif
bool jstPinOutputAtTime(JsSysTime time, Pin *pins, int pinCount, uint8_t value) {
bool jstPinOutputAtTime(JsSysTime time, uint32_t *timerOffset, Pin *pins, int pinCount, uint8_t value) {
assert(pinCount<=UTILTIMERTASK_PIN_COUNT);
UtilTimerTask task;
task.time = (int)time;
@ -367,7 +383,7 @@ bool jstPinOutputAtTime(JsSysTime time, Pin *pins, int pinCount, uint8_t value)
task.data.set.value = value;
WAIT_UNTIL(!utilTimerIsFull(), "Utility Timer");
return utilTimerInsertTask(&task);
return utilTimerInsertTask(&task, timerOffset);
}
// Do software PWM on the given pin, using the timer IRQs
@ -444,15 +460,18 @@ bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin) {
// first task is to turn on
jshPinSetValue(pin, 1);
uint32_t timerOffset = jstGetUtilTimerOffset();
// now start the 2 PWM tasks
WAIT_UNTIL(!utilTimerIsFull(), "Utility Timer");
if (!utilTimerInsertTask(&taskon)) return false;
if (!utilTimerInsertTask(&taskon, &timerOffset)) return false;
WAIT_UNTIL(!utilTimerIsFull(), "Utility Timer");
return utilTimerInsertTask(&taskoff);
return utilTimerInsertTask(&taskoff, &timerOffset);
}
/// Execute the given function repeatedly after the given time period. If period=0, don't repeat. True on success or false on failure to schedule
bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, uint32_t period) {
/** Execute the given function repeatedly after the given time period. If period=0, don't repeat. True on success or false on failure to schedule
* See utilTimerInsertTask for notes on timerOffset
*/
bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, uint32_t period, uint32_t *timerOffset) {
UtilTimerTask task;
task.time = (int)startTime;
task.repeatInterval = period;
@ -461,7 +480,7 @@ bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, u
task.data.execute.userdata = userdata;
WAIT_UNTIL(!utilTimerIsFull(), "Utility Timer");
return utilTimerInsertTask(&task);
return utilTimerInsertTask(&task, timerOffset);
}
/// Stop executing the given function
@ -475,7 +494,7 @@ bool jstStopExecuteFn(UtilTimerTaskExecFn fn, void *userdata) {
/// Set the utility timer so we're woken up in whatever time period
bool jstSetWakeUp(JsSysTime period) {
UtilTimerTask task;
task.time = (int)(jshGetSystemTime() + period);
task.time = (int)period;
task.repeatInterval = 0;
task.type = UET_WAKEUP;
@ -497,7 +516,7 @@ bool jstSetWakeUp(JsSysTime period) {
return true;
}
bool ok = utilTimerInsertTask(&task);
bool ok = utilTimerInsertTask(&task, NULL);
// We wait until the timer is out of the reload event, because the reload event itself would wake us up
return ok;
}
@ -528,7 +547,7 @@ bool jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, JsVar *curre
if (!jshIsPinValid(pin)) return false;
UtilTimerTask task;
task.repeatInterval = (unsigned int)period;
task.time = (int)(startTime + period);
task.time = (int)(startTime-jshGetSystemTime() + period);
task.type = type;
if (UET_IS_BUFFER_WRITE_EVENT(type)) {
task.data.buffer.pinFunction = jshGetCurrentPinFunction(pin);
@ -552,7 +571,7 @@ bool jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, JsVar *curre
}
jstUtilTimerSetupBuffer(&task);
return utilTimerInsertTask(&task);
return utilTimerInsertTask(&task, NULL);
}
@ -569,6 +588,7 @@ void jstReset() {
jshUtilTimerDisable();
utilTimerOn = false;
utilTimerTasksTail = utilTimerTasksHead = 0;
utilTimerOffset = 0;
utilTimerPeriod = 0;
}

View File

@ -103,20 +103,27 @@ void jstUtilTimerWaitEmpty();
/// Return true if the utility timer is running
bool jstUtilTimerIsRunning();
/// Get the current timer offset - supply this when adding >1 timer task to ensure they are all executed at the same time relative to each other
uint32_t jstGetUtilTimerOffset();
/// Return true if a timer task for the given pin exists (and set 'task' to it)
bool jstGetLastPinTimerTask(Pin pin, UtilTimerTask *task);
/// Return true if a timer task for the given variable exists (and set 'task' to it)
bool jstGetLastBufferTimerTask(JsVar *var, UtilTimerTask *task);
/// returns false if timer queue was full... Changes the state of one or more pins at a certain time (using a timer)
bool jstPinOutputAtTime(JsSysTime time, Pin *pins, int pinCount, uint8_t value);
/** returns false if timer queue was full... Changes the state of one or more pins at a certain time in the future (using a timer)
* See utilTimerInsertTask for notes on timerOffset
*/
bool jstPinOutputAtTime(JsSysTime time, uint32_t *timerOffset, Pin *pins, int pinCount, uint8_t value);
// Do software PWM on the given pin, using the timer IRQs
bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin);
/// Execute the given function repeatedly after the given time period. If period=0, don't repeat. True on success or false on failure to schedule
bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, uint32_t period);
/** Execute the given function repeatedly after the given time period. If period=0, don't repeat. True on success or false on failure to schedule
* See utilTimerInsertTask for notes on timerOffset
*/
bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, uint32_t period, uint32_t *timerOffset);
/// Stop executing the given function
bool jstStopExecuteFn(UtilTimerTaskExecFn fn, void *userdata);
@ -149,8 +156,12 @@ void jstDumpUtilityTimers();
need to be called by anything outside jstimer.c */
void jstRestartUtilTimer();
// Queue a task up to be executed when a timer fires... return false on failure
bool utilTimerInsertTask(UtilTimerTask *task);
/** Queue a task up to be executed when a timer fires... return false on failure.
* task.time is the delay at which to execute the task. If timerOffset!==NULL then
* task.time is relative to the time at which timerOffset=jstGetUtilTimerOffset().
* This allows pulse trains/etc to be scheduled in sync.
*/
bool utilTimerInsertTask(UtilTimerTask *task, uint32_t *timerOffset);
/// Remove the task that that 'checkCallback' returns true for. Returns false if none found
bool utilTimerRemoveTask(bool (checkCallback)(UtilTimerTask *task, void* data), void *checkCallbackData);

View File

@ -17,6 +17,7 @@
#include "jsvar.h"
#include "jswrap_arraybuffer.h" // for jswrap_io_peek
#include "jswrapper.h" // for JSWAT_VOID
#include "jstimer.h" // for digitalPulse
#ifdef ESP32
#include "freertos/FreeRTOS.h"
@ -218,21 +219,38 @@ eg. `digitalPulse(A0,1,5);` pulses A0 high for 5ms. `digitalPulse(A0,1,[5,2,4]);
digitalPulse is for SHORT pulses that need to be very accurate. If you're doing anything over a few milliseconds, use setTimeout instead.
*/
void jswrap_io_digitalPulse(Pin pin, bool value, JsVar *times) {
if (!jshIsPinValid(pin)) {
jsExceptionHere(JSET_ERROR, "Invalid pin!");
return;
}
// check for currently running timer tasks
UtilTimerTask task;
uint32_t timerOffset = jstGetUtilTimerOffset();
bool hasTimer = jstGetLastPinTimerTask(pin, &task);
if (!hasTimer) task.time = 0;
// now start either one or a series of pulses
if (jsvIsNumeric(times)) {
JsVarFloat time = jsvGetFloat(times);
if (time<0 || isnan(time)) {
JsVarFloat pulseTime = jsvGetFloat(times);
if (pulseTime<0 || isnan(pulseTime)) {
jsExceptionHere(JSET_ERROR, "Pulse Time given for digitalPulse is less than 0, or not a number");
} else {
jshPinPulse(pin, value, time);
}
} else if (pulseTime>0) {
if (!hasTimer) jshPinOutput(pin, value);
task.time += jshGetTimeFromMilliseconds(pulseTime);
jstPinOutputAtTime(task.time, &timerOffset, &pin, 1, !value);
} else jstUtilTimerWaitEmpty(); // time==0
} else if (jsvIsIterable(times)) {
// iterable, so output a square wave
if (!hasTimer) jshPinOutput(pin, value);
JsvIterator it;
jsvIteratorNew(&it, times, JSIF_EVERY_ARRAY_ELEMENT);
while (jsvIteratorHasElement(&it)) {
JsVarFloat time = jsvIteratorGetFloatValue(&it);
if (time>=0 && !isnan(time))
jshPinPulse(pin, value, time);
JsVarFloat pulseTime = jsvIteratorGetFloatValue(&it);
if (!isnan(pulseTime)) {
if (pulseTime>0) {
task.time += jshGetTimeFromMilliseconds(pulseTime);
jstPinOutputAtTime(task.time, &timerOffset, &pin, 1, !value);
}
}
value = !value;
jsvIteratorNext(&it);
}

View File

@ -135,7 +135,7 @@ Sets the output state of the pin to the parameter given at the specified time.
void jswrap_pin_writeAtTime(JsVar *parent, bool value, JsVarFloat time) {
Pin pin = jshGetPinFromVar(parent);
JsSysTime sTime = jshGetTimeFromMilliseconds(time*1000) - jshGetSystemTime();
jstPinOutputAtTime(sTime, &pin, 1, value);
jstPinOutputAtTime(sTime, NULL, &pin, 1, value);
}

View File

@ -147,9 +147,6 @@ JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, Js
return JSH_NOTHING;
}
void jshPinPulse(Pin pin, bool value, JsVarFloat time) {
}
bool jshCanWatch(Pin pin) {
return true;
}

View File

@ -86,7 +86,7 @@ void startNotifTimer(){
inNotif = true;
JsSysTime period = jshGetTimeFromMilliseconds(10);
JsSysTime time = jshGetSystemTime();
jstExecuteFn(notifTimerCB, NULL, time + period, period);
jstExecuteFn(notifTimerCB, NULL, time + period, period, NULL);
}
void gatts_sendNotification(int c){
notifBuffer[notifBufferPnt] = (uint8_t)c;

View File

@ -436,42 +436,6 @@ bool CALLED_FROM_INTERRUPT jshGetWatchedPinState(IOEventFlags eventFlag) { // ca
}
/**
* Set the value of the pin to be the value supplied and then wait for
* a given period and set the pin value again to be the opposite.
*/
void jshPinPulse(
Pin pin, //!< The pin to be pulsed.
bool pulsePolarity, //!< The value to be pulsed into the pin.
JsVarFloat pulseTime //!< The duration in milliseconds to hold the pin.
) {
// ESP32 specific version, replaced by Espruino Style version from nrf52
//int duration = (int)pulseTime * 1000; //from millisecs to microsecs
//sendPulse(pin, pulsePolarity, duration);
// ---- 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);
}
}
/**
* Determine whether the pin can be watchable.
* \return Returns true if the pin is watchable.

View File

@ -673,37 +673,6 @@ bool CALLED_FROM_INTERRUPT jshGetWatchedPinState(IOEventFlags eventFlag) { // ca
}
/**
* Set the value of the pin to be the value supplied and then wait for
* a given period and set the pin value again to be the opposite.
*/
void jshPinPulse(
Pin pin, //!< The pin to be pulsed.
bool pulsePolarity, //!< The value to be pulsed into the pin.
JsVarFloat pulseTime //!< The duration in milliseconds to hold the pin.
) {
if (!jshIsPinValid(pin)) {
jsExceptionHere(JSET_ERROR, "Invalid pin!");
return;
}
if (pulseTime <= 0) {
// just wait for everything to complete [??? what does this mean ???]
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);
}
}
/**
* Determine whether the pin can be watchable.
* \return Returns true if the pin is wathchable.

View File

@ -579,15 +579,6 @@ JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, Js
return JSH_NOTHING;
}
void jshPinPulse(Pin pin, bool value, JsVarFloat time) {
if (jshIsPinValid(pin)) {
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
jshPinSetValue(pin, value);
jshDelayMicroseconds(time*1000000);
jshPinSetValue(pin, !value);
} else jsError("Invalid pin!");
}
bool jshCanWatch(Pin pin) {
if (jshIsPinValid(pin)) {
IOEventFlags exti = getNewEVEXTI();

View File

@ -1569,30 +1569,6 @@ void jshSetOutputValue(JshPinFunction func, int value) {
#endif
}
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 = 0;
}
// Now set the end of the pulse to happen on a timer
jstPinOutputAtTime(task.time + jshGetTimeFromMilliseconds(pulseTime), &pin, 1, !pulsePolarity);
}
}
static IOEventFlags jshGetEventFlagsForWatchedPin(nrf_drv_gpiote_pin_t pin) {
for (int i=0;i<EXTI_COUNT;i++)
if (pin == extiToPin[i])

View File

@ -2762,29 +2762,6 @@ void jshUtilTimerStart(JsSysTime period) {
}
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);
}
}
JshPinFunction jshGetCurrentPinFunction(Pin pin) {
// FIXME: This isn't actually right - we need to look at the hardware or store this info somewhere.
if (jshIsPinValid(pin)) {

View File

@ -1481,31 +1481,6 @@ JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, Js
return 0;
}
/// Pulse a pin for a certain time, but via IRQs, not JS: `digitalWrite(pin,value);setTimeout("digitalWrite(pin,!value)", time*1000);`
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);
}
}
/// Can the given pin be watched? it may not be possible because of conflicts
bool jshCanWatch(Pin pin){
if (jshIsPinValid(pin)) {