|
268 | 268 | } |
269 | 269 |
|
270 | 270 | // enable/disable LED fields |
| 271 | + updateTypeDropdowns(); // restrict bus types in dropdowns to max allowed digital/analog buses |
271 | 272 | let dC = 0; // count of digital buses (for parallel I2S) |
272 | 273 | let LTs = d.Sf.querySelectorAll("#mLC select[name^=LT]"); |
273 | 274 | LTs.forEach((s,i)=>{ |
274 | | - if (i < LTs.length-1) s.disabled = true; // prevent changing type (as we can't update options) |
275 | 275 | // is the field a LED type? |
276 | 276 | var n = s.name.substring(2,3); // bus number (0-Z) |
277 | 277 | var t = parseInt(s.value); |
|
448 | 448 | { |
449 | 449 | var o = gEBCN("iST"); |
450 | 450 | var i = o.length; |
451 | | - let disable = (sel,opt) => { sel.querySelectorAll(opt).forEach((o)=>{o.disabled=true;}); } |
452 | 451 |
|
453 | 452 | var f = gId("mLC"); |
454 | | - let digitalB = 0, analogB = 0, twopinB = 0, virtB = 0; |
455 | | - f.querySelectorAll("select[name^=LT]").forEach((s)=>{ |
456 | | - let t = s.value; |
457 | | - if (isDig(t) && !isD2P(t)) digitalB++; |
458 | | - if (isD2P(t)) twopinB++; |
459 | | - if (isPWM(t)) analogB += numPins(t); // each GPIO is assigned to a channel |
460 | | - if (isVir(t)) virtB++; |
461 | | - }); |
462 | 453 |
|
463 | 454 | if ((n==1 && i>=36) || (n==-1 && i==0)) return; // used to be i>=maxB+maxV when virtual buses were limited (now :"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
464 | 455 | var s = chrID(i); |
|
468 | 459 | var cn = `<div class="iST"> |
469 | 460 | <hr class="sml"> |
470 | 461 | ${i+1}: |
471 | | -<select name="LT${s}" onchange="UI(true)"></select><br> |
| 462 | +<select name="LT${s}" onchange="updateTypeDropdowns();UI(true)"></select><br> |
472 | 463 | <div id="abl${s}"> |
473 | 464 | mA/LED: <select name="LAsel${s}" onchange="enLA(this,'${s}');UI();"> |
474 | 465 | <option value="55" selected>55mA (typ. 5V WS281x)</option> |
|
523 | 514 | } |
524 | 515 | }); |
525 | 516 | enLA(d.Sf["LAsel"+s],s); // update LED mA |
526 | | - // disable inappropriate LED types |
| 517 | + // temporarily set to virtual (network) type to avoid "same type" exception during dropdown update |
527 | 518 | let sel = d.getElementsByName("LT"+s)[0]; |
528 | | - // 32 & S2 supports mono I2S as well as parallel so we need to take that into account; S3 only supports parallel |
529 | | - let maxDB = maxD - (is32() || isS2() || isS3() ? (!d.Sf["PR"].checked)*8 - (!isS3()) : 0); // adjust max digital buses if parallel I2S is not used |
530 | | - if (digitalB >= maxDB) disable(sel,'option[data-type="D"]'); // NOTE: see isDig() |
531 | | - if (twopinB >= 2) disable(sel,'option[data-type="2P"]'); // NOTE: see isD2P() (we will only allow 2 2pin buses) |
532 | | - disable(sel,`option[data-type^="${'A'.repeat(maxA-analogB+1)}"]`); // NOTE: see isPWM() |
| 519 | + sel.value = sel.querySelector('option[data-type="N"]').value; |
| 520 | + updateTypeDropdowns(); // update valid bus options including this new one |
533 | 521 | sel.selectedIndex = sel.querySelector('option:not(:disabled)').index; |
| 522 | + updateTypeDropdowns(); // update again for the newly selected type |
534 | 523 | } |
535 | 524 | if (n==-1) { |
536 | 525 | o[--i].remove();--i; |
537 | | - o[i].querySelector("[name^=LT]").disabled = false; |
538 | 526 | } |
539 | 527 |
|
540 | 528 | gId("+").style.display = (i<35) ? "inline":"none"; // was maxB+maxV-1 when virtual buses were limited (now :"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
|
829 | 817 | } |
830 | 818 | return opt; |
831 | 819 | } |
| 820 | + // dynamically enforce bus type availability based on current usage |
| 821 | + function updateTypeDropdowns() { |
| 822 | + let LTs = d.Sf.querySelectorAll("#mLC select[name^=LT]"); |
| 823 | + let digitalB = 0, analogB = 0, twopinB = 0, virtB = 0; |
| 824 | + // count currently used buses |
| 825 | + LTs.forEach(sel => { |
| 826 | + let t = parseInt(sel.value); |
| 827 | + if (isDig(t) && !isD2P(t)) digitalB++; |
| 828 | + if (isPWM(t)) analogB += numPins(t); |
| 829 | + if (isD2P(t)) twopinB++; |
| 830 | + if (isVir(t)) virtB++; |
| 831 | + }); |
| 832 | + // enable/disable type options according to limits in dropdowns |
| 833 | + LTs.forEach(sel => { |
| 834 | + const curType = parseInt(sel.value); |
| 835 | + const disable = (q) => sel.querySelectorAll(q).forEach(o => o.disabled = true); |
| 836 | + const enable = (q) => sel.querySelectorAll(q).forEach(o => o.disabled = false); |
| 837 | + enable('option'); // reset all first |
| 838 | + // max digital buses: ESP32 & S2 support mono I2S as well as parallel so we need to take that into account; S3 only supports parallel |
| 839 | + // supported outputs using parallel I2S/mono I2S: S2: 12/5, S3: 12/4, ESP32: 16/9 |
| 840 | + let maxDB = maxD - ((is32() || isS2() || isS3()) ? (!d.Sf["PR"].checked) * 8 - (!isS3()) : 0); // adjust max digital buses if parallel I2S is not used |
| 841 | + // disallow adding more of a type that has reached its limit but allow changing the current type |
| 842 | + if (digitalB >= maxDB && !(isDig(curType) && !isD2P(curType))) disable('option[data-type="D"]'); |
| 843 | + if (twopinB >= 2 && !isD2P(curType)) disable('option[data-type="2P"]'); |
| 844 | + // Disable PWM types that need more pins than available (accounting for current type's pins if PWM) |
| 845 | + disable(`option[data-type^="${'A'.repeat(maxA - analogB + (isPWM(curType)?numPins(curType):0) + 1)}"]`); |
| 846 | + }); |
| 847 | + } |
832 | 848 | </script> |
833 | 849 | <style>@import url("style.css");</style> |
834 | 850 | </head> |
|
0 commit comments