SP36 Pro troubleshooting adventure - anyone have driver details?

I've decided to try to troubleshoot my misbehaving SP36 Pro 5000K for the educational value. Here is what I know so far:

The switch LED works as expected when the light is off, when the light is in lockout, when the light is charging, when the light is fully charged (connected to charger), and when the light is on being driven by the 7135.

When the light is on and being driven by the FET, the switch LED behaves as follows:

  • The switch LED is on at full brightness at the low end of the FET range.
  • Approaching the top of the ramp, the switch LED dims rapidly as the brightness gets closer to top of ramp. In stepped mode, this issue appears on steps 6 and 7 (steps 1-5 work as expected).
  • With fully charged batteries, the switch LED will be off when near the top of ramp (i.e., step 6 or 7 in stepped mode).
  • As battery voltage drops, the switch LED gradually brightens (at first I incorrectly thought it was related to temperature but I've now isolated it to battery voltage). At approximately 3.9V and below, the switch LED behaves as expected, being bright over the full FET range.
  • When switching the light on with a high brightness memorized, the switch LED will light up brightly for about 1/10 of a second before exhibiting the voltage-dependent behavior described above.
  • Bizarre exception: the switch LED is always on at full brightness in turbo mode (really seems to be about steps 145-150 but that's hard to quantify, however I confirmed that it does light up to full brightness at step 149, so it's not related to direct drive). Now that I think about it, those modes close to the top are probably enough to sag battery voltage to below 3.9V, which would mean this isn't an exception after all.

The first thing I did was check the Anduril code (really FSM in this case) to see if anything could explain what I was seeing. I found this (code from unused ifdefs removed):

void indicator_led(uint8_t lvl) {
    switch (lvl) {
        case 0:  // indicator off
            DDRB &= 0xff ^ (1 << AUXLED_PIN);
            PORTB &= 0xff ^ (1 << AUXLED_PIN);
            break;
        case 1:  // indicator low
            DDRB &= 0xff ^ (1 << AUXLED_PIN);
            PORTB |= (1 << AUXLED_PIN);
            break;
        default:  // indicator high
            DDRB |= (1 << AUXLED_PIN);
            PORTB |= (1 << AUXLED_PIN);
            break;
    }
}
  • For the case where the LED is off, DDRB4 and PORTB4 are both low, yielding a tri-state input on PB4. I'm not sure why this isn't set to be a push/pull output driven low since I would think that would use less current.
  • For the case where the LED is on low, DDRB4 is low and PORTB4 is high, yielding an input with pull-up on PB4. I assume the LED is sourcing current from the pull-up resistor which I guess is a neat trick but I'm surprised to see it in production.
  • For the case where the LED is on high, DDRB4 and PORTB4 are both high, yielding an output voltage on PB4 equal to Vcc. Here I assume the LED is sourcing current from the port driver, but I'm not sure what else sits between the MCU and the LED.

The most important part of investigating the code was confirming that there's nothing in there that applies PWM to the switch LED and nothing that could explain the momentary bright flash before entering voltage-dependent behavior. Nor is there anything in the code that seems to be able to smoothly vary the brightness of the switch LED at all. So that leaves only the possibility of a hardware issue.

I invested in a pair of circlip pliers so I could open up the switch cover. I identified the 4 wires on the back of the switch PCB as charging LED (red), switch, indicator LED (green), and ground. Measuring the voltage on the indicator LED wire, I could see that the voltage dropped from about 2 V to about 0V as I approached top of ramp and then went back up to about 2 V when I activated turbo. Obviously measuring voltage across an LED isn't the most conclusive test but it leads me to believe that the current being sourced from the MCU is somehow affected as the emitter brightness increases.

I'm not confident that I can get the driver out without destroying the light and losing any ability to solve the mystery, so I'm wondering if anyone knows the details of how the switch LEDs are connected. I know they're controlled by the signal on PB4 (pin 3), but does that pin connect to a simple current-limiting resistor? A transistor? Something else? There's nothing but the LEDs on the switch PCB so the rest of the circuit has to be on the driver board itself.

Everything points to either a short on the board somewhere or a defect in the ATtiny85 itself, but it would be very interesting to figure out what the exact problem is.

Anduril is complex, but I know while flashlight is locked, you can 3 clicks to change switd led modes: Low-High-Blink-Off

The LED works normally when the light is off and when it is in lockout. It only malfunctions in the scenario mentioned above. Hopefully someone knows more about the circuit which might help to narrow down the exact cause.