Merge remote-tracking branch 'origin/montana-black-shield' into merge-probe

* origin/montana-black-shield:
  docs(bulb-map): Montana-Black-Shield (f960) ergaenzt
  chore(tools): qconnex-Migrationswerkzeug und HA-Integration ins Repo
  feat(station): Montana-Black-Produkt-ID -> Ziel ledshield_rgb
  feat(board): ledshield_rgb — Montana Black RGB-LED-Shield (analoge RGB-Streifen)
  build: tools/podman.sh — docker.sh-Pendant für podman (gleiches Image, gleicher Mount)
  Überträgt lokale Änderungen (nl_crc8 unsigned-shift, docker.sh cd -P) in neuen Top-Level-Tree und entfernt altes ninlight-w600/
  Initial commit
This commit is contained in:
Michael Sauer
2026-09-26 17:18:27 +02:00
38 changed files with 1260 additions and 26 deletions
+8
View File
@@ -31,6 +31,14 @@ const nl_board_t nl_boards[] = {
* PB16=WW, PB15=CW - verify on a series bulb. */
{"g95_cw", "Klyqa G95 Vintage CW/WW", NL_DRV_PWM, false, 2000, 5000, 600,
{NONE, NONE, NONE, CH(1, NL_PB(13)), CH(3, NL_PB(15))}, NO_SM},
/* Montana Black LED Shield (Klyqa LED-Strippen-Steuergeraet,
product_id @qcx.montana.black.ledshield.rgb): analog RGB-Streifen an
lowseitigen MOSFETs, kein CW/WW-Zweig. PIN-Kanaele und 800 Hz aus der
Original-Firmware (fw-w600 qcl_build_config_lamp.h, HARDWARE_MOBL_LED_SHIELD);
dort invertiert init mit invertiertem Duty, effektive Wirkung wie hier
active-high. ct_min == ct_max markiert "weiss = RGB-Kombination". */
{"ledshield_rgb", "Montana Black RGB LED Shield", NL_DRV_PWM, true, 4000, 4000, 800,
{CH(1, NL_PB(13)), CH(2, NL_PB(16)), CH(3, NL_PB(15)), NONE, NONE}, NO_SM},
};
const size_t nl_boards_count = sizeof(nl_boards) / sizeof(nl_boards[0]);
+5
View File
@@ -62,6 +62,11 @@ void nl_visual_to_channels(const nl_visual_t *v, uint16_t ct_min, uint16_t ct_ma
/* keep the lowest brightness step visible */
if (!out[NL_CH_R] && !out[NL_CH_G] && !out[NL_CH_B] && lin[maxi] > 0)
out[NL_CH_R + maxi] = 1;
} else if (ct_min == ct_max) {
/* RGB-only board (ledshield_rgb): no white channels wired, ct range
* collapsed to a point. White shows as an equal RGB mix. */
uint8_t w = to8(level);
out[NL_CH_R] = out[NL_CH_G] = out[NL_CH_B] = w ? w : 1;
} else {
uint32_t cw = level * nl_ct_cw_fraction(v->ct, ct_min, ct_max) / 65535u;
uint32_t ww = level - cw;
+1 -1
View File
@@ -19,7 +19,7 @@ uint8_t nl_crc8(const void *data, size_t len)
while (len--) {
crc ^= *p++;
for (int k = 0; k < 8; k++)
crc = (uint8_t)((crc & 0x80u) ? (crc << 1) ^ 0x07u : (crc << 1));
crc = (uint8_t)((crc & 0x80u) ? (int)(((unsigned)crc << 1) ^ 0x07u) : (int)((unsigned)crc << 1));
}
return crc;
}