/// <summary> /// Sync and Register Event Name/Value with External Device through EventSyncProtocol /// </summary> /// <param name="e">Event Name, NullorEmpty will Reset Sync Channel to inactive state without event register</param> /// <param name="et">Event Time, Non-NaN value will register in `Event` as well as `SyncEvent`</param> /// <param name="ev">Event Value, Non-Null value will register in new `CONDTESTPARAM` if event is a valid `CONDTESTPARAM`</param> protected virtual void SyncEvent(string e = null, double et = double.NaN, object ev = null) { var esp = ex.EventSyncProtocol; if (esp.SyncMethods == null || esp.SyncMethods.Count == 0) { Debug.LogWarning("No SyncMethod in EventSyncProtocol, Skip SyncEvent ..."); return; } bool addtosynclist = false; bool syncreset = string.IsNullOrEmpty(e); if (esp.nSyncChannel == 1 && esp.nSyncpEvent == 1) { syncvalue = !syncreset && !syncvalue; addtosynclist = !syncreset; for (var i = 0; i < esp.SyncMethods.Count; i++) { switch (esp.SyncMethods[i]) { case SyncMethod.Display: SetEnvActiveParam("Mark", syncvalue); break; case SyncMethod.GPIO: gpio?.BitOut(bit: Config.EventSyncCh, value: syncvalue); break; } } } if (addtosynclist && ex.CondTestAtState != CONDTESTATSTATE.NONE) { if (!double.IsNaN(et)) { condtestmanager.AddInList(CONDTESTPARAM.Event, e, et); } condtestmanager.AddInList(CONDTESTPARAM.SyncEvent, e); if (ev != null) { if (Enum.TryParse(e, out CONDTESTPARAM cte)) { condtestmanager.AddInList(cte, ev); } else { Debug.LogWarning($"Skip Adding Event Value, {e} is not a valid CONDTESTPARAM."); } } } }
void ThreadBitWave(int bit) { var timer = new Timer(); bool isbreakstarted; double start = 0; double breakstart = 0; Break: bitthreadevent[bit].WaitOne(); isbreakstarted = false; timer.Restart(); switch (bitwave[bit]) { case DigitalWaveType.PWM: timer.TimeoutMillisecond(bitlatency_ms[bit] + bitphase[bit] * (bithighdur_ms[bit] + bitlowdur_ms[bit])); while (true) { gpio.BitOut(bit, true); start = timer.ElapsedMillisecond; while ((timer.ElapsedMillisecond - start) < bithighdur_ms[bit]) { if (bitthreadbreak[bit]) { if (!isbreakstarted) { breakstart = timer.ElapsedMillisecond; isbreakstarted = true; } if (isbreakstarted && timer.ElapsedMillisecond - breakstart >= bitlatency_ms[bit]) { gpio.BitOut(bit, false); goto Break; } } } gpio.BitOut(bit, false); start = timer.ElapsedMillisecond; while ((timer.ElapsedMillisecond - start) < bitlowdur_ms[bit]) { if (bitthreadbreak[bit]) { if (!isbreakstarted) { breakstart = timer.ElapsedMillisecond; isbreakstarted = true; } if (isbreakstarted && timer.ElapsedMillisecond - breakstart >= bitlatency_ms[bit]) { goto Break; } } } } case DigitalWaveType.PoissonSpike: timer.TimeoutMillisecond(bitlatency_ms[bit] + bitphase[bit] / bitspikerate[bit]); var isid = new Exponential(bitspikerate[bit], rng); while (true) { var i = isid.Sample(); if (i > bitrefreshperiod_ms[bit]) { start = timer.ElapsedMillisecond; while ((timer.ElapsedMillisecond - start) < i) { if (bitthreadbreak[bit]) { if (!isbreakstarted) { breakstart = timer.ElapsedMillisecond; isbreakstarted = true; } if (isbreakstarted && timer.ElapsedMillisecond - breakstart >= bitlatency_ms[bit]) { goto Break; } } } gpio.BitOut(bit, true); start = timer.ElapsedMillisecond; while ((timer.ElapsedMillisecond - start) < bitspikewidth_ms[bit]) { if (bitthreadbreak[bit]) { if (!isbreakstarted) { breakstart = timer.ElapsedMillisecond; isbreakstarted = true; } if (isbreakstarted && timer.ElapsedMillisecond - breakstart >= bitlatency_ms[bit]) { gpio.BitOut(bit, false); goto Break; } } } gpio.BitOut(bit, false); } } } }