|
7 | 7 | <script src="common.js" async type="text/javascript"></script> |
8 | 8 | <script> |
9 | 9 | var maxB=1,maxD=1,maxA=1,maxV=0,maxM=4000,maxPB=2048,maxL=1664,maxCO=5; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32 |
10 | | - var oMaxB=1; |
11 | 10 | var customStarts=false,startsDirty=[]; |
12 | 11 | function off(n) { gN(n).value = -1;} |
13 | 12 | // these functions correspond to C macros found in const.h |
|
43 | 42 | if (loc) d.Sf.action = getURL('/settings/leds'); |
44 | 43 | } |
45 | 44 | function bLimits(b,v,p,m,l,o=5,d=2,a=6) { |
46 | | - oMaxB = maxB = b; // maxB - max buses (can be changed if using ESP32 parallel I2S): 20 - ESP32, 14 - S3/S2, 6 - C3, 4 - 8266 |
47 | | - maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S): 17 - ESP32, 12 - S3/S2, 2 - C3, 3 - 8266 |
| 45 | + maxB = b; // maxB - max physical (analog + digital) buses: 32 - ESP32, 14 - S3/S2, 6 - C3, 4 - 8266 |
| 46 | + maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S): 16 - ESP32, 12 - S3/S2, 2 - C3, 3 - 8266 |
48 | 47 | maxA = a; // maxA - max analog channels: 16 - ESP32, 8 - S3/S2, 6 - C3, 5 - 8266 |
49 | 48 | maxV = v; // maxV - min virtual buses: 6 - ESP32/S3, 4 - S2/C3, 3 - ESP8266 (only used to distinguish S2/S3) |
50 | 49 | maxPB = p; // maxPB - max LEDs per bus |
51 | 50 | maxM = m; // maxM - max LED memory |
52 | 51 | maxL = l; // maxL - max LEDs (will serve to determine ESP >1664 == ESP32) |
53 | 52 | maxCO = o; // maxCO - max Color Order mappings |
54 | 53 | } |
| 54 | + function is8266() { return maxA == 5 && maxD == 3; } // NOTE: see const.h |
| 55 | + function is32() { return maxA == 16 && maxD == 16; } // NOTE: see const.h |
| 56 | + function isC3() { return maxA == 6 && maxD == 2; } // NOTE: see const.h |
| 57 | + function isS2() { return maxA == 8 && maxD == 12 && maxV == 4; } // NOTE: see const.h |
| 58 | + function isS3() { return maxA == 8 && maxD == 12 && maxV == 6; } // NOTE: see const.h |
55 | 59 | function pinsOK() { |
56 | 60 | var ok = true; |
57 | 61 | var nList = d.Sf.querySelectorAll("#mLC input[name^=L]"); |
|
212 | 216 | let busMA = 0; |
213 | 217 | let sLC = 0, sPC = 0, sDI = 0, maxLC = 0; |
214 | 218 | const abl = d.Sf.ABL.checked; |
215 | | - maxB = oMaxB; // TODO make sure we start with all possible buses |
216 | 219 | let setPinConfig = (n,t) => { |
217 | 220 | let p0d = "GPIO:"; |
218 | 221 | let p1d = ""; |
|
271 | 274 | gRGBW |= hasW(t); // RGBW checkbox |
272 | 275 | gId("co"+n).style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide color order for PWM |
273 | 276 | gId("dig"+n+"w").style.display = (isDig(t) && hasW(t)) ? "inline":"none"; // show swap channels dropdown |
274 | | - gId("dig"+n+"w").querySelector("[data-opt=CCT]").disabled = !hasCCT(t); // disable WW/CW swapping |
| 277 | + gId("dig"+n+"w").querySelector("[data-opt=CCT]").disabled = !hasCCT(t); // disable WW/CW swapping |
275 | 278 | if (!(isDig(t) && hasW(t))) d.Sf["WO"+n].value = 0; // reset swapping |
276 | 279 | gId("dig"+n+"c").style.display = (isAna(t)) ? "none":"inline"; // hide count for analog |
277 | 280 | gId("dig"+n+"r").style.display = (isVir(t)) ? "none":"inline"; // hide reversed for virtual |
|
289 | 292 | d.Sf.CR.checked = false; |
290 | 293 | } |
291 | 294 | // update start indexes, max values, calculate current, etc |
| 295 | + let sameType = 0; |
292 | 296 | var nList = d.Sf.querySelectorAll("#mLC input[name^=L]"); |
293 | 297 | nList.forEach((LC,i)=>{ |
294 | 298 | let nm = LC.name.substring(0,2); // field name |
295 | 299 | let n = LC.name.substring(2); // bus number |
296 | 300 | let t = parseInt(d.Sf["LT"+n].value); // LED type SELECT |
| 301 | + if (isDig(t)) { |
| 302 | + if (sameType == 0) sameType = t; // first bus type |
| 303 | + else if (sameType != t) sameType = -1; // different bus type |
| 304 | + } |
297 | 305 | // do we have a led count field |
298 | 306 | if (nm=="LC") { |
299 | 307 | let c = parseInt(LC.value,10); //get LED count |
|
351 | 359 | else LC.style.color = d.ro_gpio.some((e)=>e==parseInt(LC.value)) ? "orange" : "#fff"; |
352 | 360 | } |
353 | 361 | }); |
354 | | - const S2 = (oMaxB == 14) && (maxV == 4); |
355 | | - const S3 = (oMaxB == 14) && (maxV == 6); |
356 | | - if (oMaxB == 32 || S2 || S3) { // TODO: crude ESP32 & S2/S3 detection |
357 | | - if (maxLC > 300 || dC <= 2) { |
| 362 | + if (is32() || isS2() || isS3()) { |
| 363 | + if (maxLC > 600 || dC < 2 || sameType <= 0) { |
358 | 364 | d.Sf["PR"].checked = false; |
359 | 365 | gId("prl").classList.add("hide"); |
360 | 366 | } else |
361 | 367 | gId("prl").classList.remove("hide"); |
362 | | - // S2 supports mono I2S as well as parallel so we need to take that into account; S3 only supports parallel |
363 | | - maxD = (S2 || S3 ? 4 : 8) + (d.Sf["PR"].checked ? 8 : S2); // TODO: use bLimits() : 4/8RMT + (x1/x8 parallel) I2S1 |
364 | | - maxB = oMaxB - (d.Sf["PR"].checked ? 0 : 7 + S3); // S2 (maxV==4) does support mono I2S |
365 | | - } |
| 368 | + } else d.Sf["PR"].checked = false; |
366 | 369 | // distribute ABL current if not using PPL |
367 | 370 | enPPL(sDI); |
368 | 371 |
|
|
479 | 482 | if (type.t != undefined && type.t != "") { |
480 | 483 | opt.setAttribute('data-type', type.t); |
481 | 484 | } |
482 | | - sel.appendChild(opt); |
| 485 | + sel.appendChild(opt); |
483 | 486 | } |
484 | 487 | } |
485 | 488 | }); |
486 | 489 | enLA(d.Sf["LAsel"+s],s); // update LED mA |
487 | 490 | // disable inappropriate LED types |
488 | | - let sel = d.getElementsByName("LT"+s)[0] |
489 | | - if (i >= maxB || digitalB >= maxD) disable(sel,'option[data-type="D"]'); // NOTE: see isDig() |
490 | | - if (i >= maxB || twopinB >= 1) disable(sel,'option[data-type="2P"]'); // NOTE: see isD2P() |
| 491 | + let sel = d.getElementsByName("LT"+s)[0]; |
| 492 | + // 32 & S2 supports mono I2S as well as parallel so we need to take that into account; S3 only supports parallel |
| 493 | + let maxDB = maxD - (is32() || isS2() || isS3() ? (!d.Sf["PR"].checked)*8 - (!isS3()) : 0); // adjust max digital buses if parallel I2S is not used |
| 494 | + if (digitalB >= maxDB) disable(sel,'option[data-type="D"]'); // NOTE: see isDig() |
| 495 | + if (twopinB >= 2) disable(sel,'option[data-type="2P"]'); // NOTE: see isD2P() (we will only allow 2 2pin buses) |
491 | 496 | disable(sel,`option[data-type^="${'A'.repeat(maxA-analogB+1)}"]`); // NOTE: see isPWM() |
492 | 497 | sel.selectedIndex = sel.querySelector('option:not(:disabled)').index; |
493 | 498 | } |
|
586 | 591 | var cs = false; |
587 | 592 | for (var i=1; i < gEBCN("iST").length; i++) { |
588 | 593 | var s = chrID(i); |
589 | | - var p = chrID(i-1); // cover edge case 'A' previous char being '9' |
| 594 | + var p = chrID(i-1); // cover edge case 'A' previous char being '9' |
590 | 595 | var v = parseInt(gId("ls"+p).value) + parseInt(gN("LC"+p).value); |
591 | 596 | if (v != parseInt(gId("ls"+s).value)) {cs = true; startsDirty[i] = true;} |
592 | 597 | } |
|
617 | 622 |
|
618 | 623 | function receivedText(e) { |
619 | 624 | let lines = e.target.result; |
620 | | - let c = JSON.parse(lines); |
| 625 | + let c = JSON.parse(lines); |
621 | 626 | if (c.hw) { |
622 | 627 | if (c.hw.led) { |
623 | 628 | // remove all existing outputs |
|
0 commit comments