One-shot PLU init. Idempotent: a second call rewrites the same registers.
| 232 | |
| 233 | // One-shot PLU init. Idempotent: a second call rewrites the same registers. |
| 234 | static void initPluGraph() FL_NOEXCEPT { |
| 235 | // Step 1: enable peripheral clock BEFORE any register write |
| 236 | // (ARM Cortex-M0+ silently drops writes to unpowered peripherals). |
| 237 | enablePluClock(); |
| 238 | |
| 239 | // Step 2: wire LUT0 inputs - only IN2 matters. |
| 240 | writeLutInputMux(0, 0, kMuxPluIn0); // ignored |
| 241 | writeLutInputMux(0, 1, kMuxPluIn1); // ignored |
| 242 | writeLutInputMux(0, 2, kMuxPluIn2); // CNT1 |
| 243 | writeLutInputMux(0, 3, kMuxPluIn0); |
| 244 | writeLutInputMux(0, 4, kMuxPluIn0); |
| 245 | writeLutTruth(0, kLut0Truth_T0H); |
| 246 | |
| 247 | // Step 3: wire LUT1 inputs - IN1, IN2 matter. |
| 248 | writeLutInputMux(1, 0, kMuxPluIn0); // ignored |
| 249 | writeLutInputMux(1, 1, kMuxPluIn1); // CNT0 |
| 250 | writeLutInputMux(1, 2, kMuxPluIn2); // CNT1 |
| 251 | writeLutInputMux(1, 3, kMuxPluIn0); |
| 252 | writeLutInputMux(1, 4, kMuxPluIn0); |
| 253 | writeLutTruth(1, kLut1Truth_T1H); |
| 254 | |
| 255 | // Step 4: wire LUT2 (bit mux) - IN0=DATA, IN1=LUT0_out, IN2=LUT1_out. |
| 256 | writeLutInputMux(2, 0, kMuxPluIn0); // DATA |
| 257 | writeLutInputMux(2, 1, muxLutOutput(0)); // LUT0 out |
| 258 | writeLutInputMux(2, 2, muxLutOutput(1)); // LUT1 out |
| 259 | writeLutInputMux(2, 3, kMuxPluIn0); |
| 260 | writeLutInputMux(2, 4, kMuxPluIn0); |
| 261 | writeLutTruth(2, kLut2Truth_BitMux); |
| 262 | |
| 263 | // Step 5: route LUT2 to PLU_OUT0. |
| 264 | writeOutputMux(0, 2); |
| 265 | |
| 266 | // Step 6: PLU is purely combinational + a wake-int block we don't use. |
| 267 | // Disable any latent wake-interrupt config (UM11065 §12.6.4). |
| 268 | *reg32(kPluBase, kOffWakeIntCtrl) = 0; |
| 269 | |
| 270 | // Step 7 (deferred): bring up the timing-counter source feeding PLU_IN1 / |
| 271 | // PLU_IN2. On LPC804 this is most naturally an SCT-generated Gray-coded |
| 272 | // pair (counter rolls every WS2812 bit period). The exact SCT config is |
| 273 | // pin-routing dependent and intentionally left for board-level glue. |
| 274 | // TODO(2841): provide a default SCT-based timing source in a follow-up |
| 275 | // commit; for now the integrator must call their own init_timing_source() |
| 276 | // before FastLED.show(). |
| 277 | } |
| 278 | |
| 279 | } // namespace lpc_plu_detail |
| 280 |
no test coverage detected