Flashlight Firmware Repository

I haven't followed everything going on here, will try to catch up. Looks pretty awesome though. I guess this noinit stuff is pretty critical for the ramping. Anyway, I did put "safe presses" into bistro HD, and it's configurable how many bytes to use, not that it helps the ramping build directly.

I also merged the new space savings gains of HD into biscotti. Basically actually HD has configurations to build all previous versions, or very very close approximations to them at lest (menu order might be different in some cases, and probably not quite as stable yet). The space savings for biscotti means that the safe presses fits in, and as well I fit in turbo timeout and bump-up(had to rework the bump-up since bistro is different than BLFA6), and there's room to spare, can also fit in firstboot and moon_mode for instance. I know the last version was pretty bad. I've done quite a bit more testing and bug checking on this version, although not on these new features yet. Actually I haven't checked the biscotti build itself at all yet, but it comes from the same code as the TA tripple build so the basic features are likely to work. that's the good thing this way, fix or improve something in one place, in most cases it should be fixed in all. Of course you could see as that as I added bugs to all, lol; the space savings and Vcc required a bunch of changes, but they're getting smoothed out.

I'm still hoping to get a full solution to this OTSM thing to solve this worry about heat changing tap length. I've at least got some ideas to play with again, which is better than where I was.

I need to catch up tooā€¦ Iā€™m way behind on the tiny25/45/85 thread, and way behind on bistro HD development. At the very least, I should get the code into the repository.

Instead Iā€™ve been distracted by a random whim to make a ramping UI, and then procrastinating about adding the few remaining things it needs before a stable release. But maybe it doesnā€™t need thermal regulation. I donā€™t know about anyone else, but I always turn that off anyway. Does anyone really use it or is it mostly just checkbox compliance?

Personally Iā€™ve never used temp control. Love your work tk. Thanks.

I finally added a thing for that today. Just uncomment the ā€œSTOP_AT_TOPā€ option to get the behavior you described. Youā€™ll probably also want to comment out the ā€œBLINK_AT_TOPā€ bit, since you were trying to avoid sudden changes in light level.

You're not too behind, and don't bother getting it in just quite yet. I just got a version up this weekend that isn't completely bug riddled (at least the "baseline" Avenger configuration actually works), but since then I solved the OTSM problems (not exactly a bug, as much as just learning how make it work) and that version still isn't up. I'll get it there shortly. It seems others can't edit the repository? For now I'm making updates pretty regularly anyway. Since this isn't just one build but a platform for configuring builds I don't know if it will ever be "final". I'm pretty sure if eswitch goes anywhere it's going to get some UI tweaks.

The OTSM stuff may be able to translate over to this ramping driver though if there are issues with OTC timing (well there are always at least some issues with OTC timing). It sounds like gchart got this ramping firmware setup with a good version of our noinit redundancy already. I have a different implementation in bistro, haven't compared but it's a pretty straight forward thing and we both came out to about the same byte count, so I doubt there's much difference there. There have been quite a few comments about capacitor problems on TA thread so hopefully this will put an end to all that, at least on attiny25/45 drivers. With the next update I'll post build-up instructions for use with the version one TA drivers.

Hi Toykeeper, I tried Crescendo on a Nanjg tiny13. I absolutely love it, thank you so much! I canā€™t wait to try the tiny25 FET+1 version with all the party strobes; they are tons of fun.

My vote would be for 2 separate versions: 1 for Nanjg tiny13 and 1 for tiny25 FET+1. Would it be possible to also do one for a tiny13 FET+1 (A6 driver) also?

I donā€™t personally need thermal regulation.

As far as temperature control, I don't have enough experience with different lights to say. On my bistro light, I'm using something like an S2 with a FET that's probably not so great that doesn't pull much over 2A anyway. The insides aren't that great at it will thermal throttle a little, which seems kind of nice, but actually it's only kind of warm anyway. Sure seems like there a bunch of lights out there where it would be useful/safer to have than not have. On my quad, I'd think thermal control would be very useful, but it's has no firmware at all. I don't know though, maybe the turbo timeout of BLFA6 is about as useful? I did rework that to work in bistro. Since bistro doesn't have fixed mode orders or placement, bumping the mode_idx down and up like BLFA6 wouldn't work. Instead kept the mode_idx fixed, bumped the level down, and disabled mode advance on next click so it boots back into TURBO pre-timeout. Same effect, different way to get there. This is now included in the biscotti-HD build. Completely untested though. A similar way might work on crescendo. Freeze some types of mode changes for next click, adjust level down after timeout.

I just remembered to add TripleDown support (FET+N+1). So, thatā€™s working now too. Just pick it as a driver layout at the top of the file, and uncomment or define a 3-channel ramp table.

It works on both tiny13 and tiny25, regardless of whether the driver has 1, 2, or 3 power channels. A BLF-A6 driver is one of the items Iā€™ve been testing on. The main restriction is that tiny13 may need some things disabled in order to make room. I tried to make it easy to turn features on and off so you can tweak each build as needed, particularly if youā€™re trying to make it fit on tiny13.

Iā€™m wary of publishing compiled versions though, because itā€™s practically guaranteed to not have the right calibration for most drivers. It needs moon and voltage values configured differently for different hardware, and may also need ramps recalculated based on how many lumens the light can make. So, itā€™s more of a ā€œplug in a few numbers and compileā€ sort of thing.

Okay, Iā€™ll wait a bit. I still have a few hundred posts to catch up on though.

LOL, software is almost never ā€œfinalā€. :slight_smile:

Thatā€™s one of the last things I need to try again before merging it into the stable branch. I havenā€™t seen it misbehave at all in a week of frequent use, and couldnā€™t even get a robot to measure a difference between noinit redundancy techniques (including ā€œnoneā€)ā€¦ but I still feel like it should be a little more careful than it is now.

Iā€™ve been kind of avoiding thermal regulation because itā€™s a pain to implement and testā€¦ but Iā€™ve also been kind of avoiding turbo timeouts on bistro-based code. Different reason though. Turbo ā€œbumpā€ was kind of a dirty hack in blf-a6, and ā€œbumpā€ in bistro (and derivatives) seems even dirtier. Not to say that my code is generally immaculate or anything, because itā€™s not even closeā€¦ but when I know in advance that something is going to be messy I tend to procrastinate about it.

I donā€™t think youā€™ll see any improvements by testing repeatedly on the same driver or two. From the (potentially incorrect) way that I understand it, itā€™s MCU dependant. Iā€™ve read that each byte decays about the same way each time. So you could get an MCU where the byte that is being used by the noinit variable decays to 15 everytime, which in original Biscotti, would launch you straight into config mode. It doesnā€™t have to 15 either. Anything less than that just gets you into config quicker than intended.

Assuming at 70% likelihood that a bit will decay to 1, I figure that 1 in 514 drivers will have their fast_presses byte decay to exactly 15. If you ship out thousands of drivers, youā€™re bound to get a couple of them. If youā€™re flashing a handful, pretty unlikely.

In order to test if the redundancy was effective, youā€™d need to flash a ton of drivers and make sure none of them exhibited the behavior mentioned above.

Hopefully the documentation will capture the most important bits.

Oh, wrote the next bit before I read gcharts post so this basically just says what he said:

As for the robot and redunancy. What I've seen and aparently from conversation with gchart others have seen similar, is that RAM tends to always reset to the same value. I only tested this over the course of a few hours with one single byte of ram. It always reset to the same value, but it was a random value, and I guessed, and it sounds like gchart confirms, this value isn't fixed, it's just a characteristic of that particular byte. So maybe you can test that byte forever and always be fine. Maybe not maybe on a different day or different temperature it too will hit a different value, I don't know. But it always settled to the same value for me, and so long as it's not a value you consider valid, then it's fine every time. The problem is what about some other byte in some other light, or a different byte in the same light if the software changes? Probably one out of somewhere between 20 to 255 light, depending on the test requirements and the probability of ones and zeros (aparently not 50/50), will have issues. That's not so small. Just by the math and the evidence we might have about bit probabilities, you need 3 bytes to get that up out of the one in a couple hundred range, or worse maybe, and into the low thousands range instead.

Yeah, for causal modding, it's all fine. For selling on gearbest, I don't know, seems like an issue. Of course there are so many issues with any GB BG or whatever lights that it's probably hard to tell. Anyway, the implementation in HD is centered around the SAFE_PRESSES defines. I'm sure gcharts (actually the original, or the first to be finished and working at least) implementation is great too. They both do the same thing basically the same way, just different variable names probably.

Oh, I tried drivers which acted a little odd sometimes during manual tests, but with a robot involved they either worked every time or acted like I was doing long presses. I think itā€™s because my automated setup canā€™t get the timing precise enough to consistently hit right on the timing boundary.

Iā€™ve never actually seen one in person which decays to a bad state, but Iā€™ve occasionally managed to catch one in a half-decayed stateā€¦ and thatā€™s when it did random things. Hard to do on purpose though, since the time window seems to be 10ms or less. That narrow partially-decayed window is what I was trying to test.

A strict check would duplicate every noinit var, check that theyā€™re all the same, and reset everything if any checks fail. However, thatā€™s a bit larger than Iā€™m hoping for. I suspect that simply checking ~16 bits for all-zeroes will be good enough to avoid 99.99% of the potential issues. Actually, going by that 70% chance estimate, 8 bits would achieve 99.99% while 16 bits would be like 99.999999. Assuming the 70 estimate is correct and there are no other factors.

Yeah, so I had to add a save variable that's used as one-time short-click lockout. I guess that's a little "dirty". Come to think of it, it probably should have wear leveling. It's not quite as bad the regular mode_idx variable probably, but still would be better to add it to wear leveling. Could do it like you did wear leveling in BLFA6 for mulitple toggles. That would work well. Adds a few more bytes more pre-processor work, more dirtiness though. I guess it could be noinit since it's only for short presses(maybe doesn't needed a decay check at all). How long is noinit reliable for on standard builds? On an OTSM build I found RAM lasted half an hour or maybe even much more.

I didn't find basic thermal regulation in bistro to be "dirty" though. It seems good to me. It got more challenging with Vcc reads though because it required an ADC reference shift back and forth in the loop which required changing the wait sequence a little for stabilization. A really nice way to do this would be to make all the ADC work asynchronous, but that's a bunch of work.

On a light which actually uses the OTC, like BLF-A6 or Bistro, noinit lasts a lot longer. I tried to use it to detect short presses instead of relying on a temperature-sensitive OTC, but with the OTC charged up I found that the SRAM didnā€™t decay at all until well after it would have been useful.

Basically, the OTC method and SRAM decay method are mutually exclusive on existing driver designs because a charged OTC prevents the SRAM from decaying.

A 4 byte check is running around 40 bytes of code. I'm not sure in crescendo, in bistro, a comparison failure is not a full reset, it just implies a long click, so that could be a rest, or whatever depending on the UI (or memory setting or whatever). Of course for any situation where you've already gauranteed a short click, maybe no test is needed. Short click, so you know the data is still good. It's if you don't have OTC that you're stuck.

Right, well I guess without OTC by definition I'm checking ram decay to define a short click. It's just weather the 5th byte was the first to decay or not, never mind, been down that arguement, not good enough. Either need EEPROM then or more redundancy checks, or somehow overload use of the fast_presses variable.

Ok, overloading fast presses wins. I think that's a good idea. It's already setup so when there's an OTC there's no redundancy because it's ignored on med/long presses then anyway. So fast_presses==NO_NEXTMODE can be the next mode lockout, probably better than the eeprom save I have now. Oh yeah, I'm pretty sure another reason this isn't in biscotti is there's just no room left. But now there is.

Overloading fast_presses is what allowed problems in the first place. Using a separate byte (or 2, or 4) to detect long presses appears to be an effective solution.

uint8_t long_press __attribute__ ((section (".noinit")));
...
if (long_press) {
  // reset all noinit vars
} else {
  // assume all noinit vars are intact
}
long_press = 0;

To increase reliability, simply define it as uint16_t or uint32_t. The chance of error, using an estimated 70% chance of each bit decaying to ā€œ1ā€, is:

  • 4 bits: 1 in 123 (overloading fast_presses)
  • 8 bits: 1 in 15,241
  • 16 bits: 1 in 232,305,731
  • 32 bits: 1 in 53 quadrillion

Soā€¦ I suspect that 16 bits is enough. It doesnā€™t even cost much extra ROM space.

Oh, youā€™re talking about drivers which use an OTC. The problem I ran into doesnā€™t happen on those. :slight_smile:

Both.. HD is a preprocessor festival! Yeah, for OTC redundancy is disabled. If not OTC or OTSM caps are defined redundancy is enabled and used to determine click length, so yeah, it's all there already. In either case using a magic value of fast_presses will work.