Success! Thermally regulated linear driver

Attiny13 hunh.. I thought you said you changed the chip to a 25. Anyway, it's not 1 in 255 even with even odds. You're missing my point. You're working with two bytes. One single bit will be the first to go. How long will it be in a state with only one bit wrong? How often will you click on during that time? Probably sometimes. You're relying on the fact that the first bit to go bad will be in the check byte and not the data byte. But there's 50% odds it will be the other way around. So that's 50% odds that at least sometimes when you click, you'll think the data is fine, but it isn't.

Well, yes… This thread is about using an attiny25 with noinit. But I’d wager that the other 99.999% of drivers currently in production that are using the noinit trick have an attiny13a on board.

And I think I get what you’re saying, it’s just a different approach than what I mentioned. Different isn’t always wrong. Your proposed method involves copying the fast presses counter to not one, but four separate bytes. First you check to make sure they’re all the same, then you can safely assume the data they contain can be used for a counter. Is that pretty close to what you’re describing?

Ok, I get your point about the 13. Yeah, I guess not many people are replacing 13's with 25's on nanjg. Anyway, yes that's it. And I agree it will take some significant bytes of code in the context of an attiny13. Even for the 25 version it was significant, but we've freed spaced and just not enabling one of the other methods (OTC or OTSM) now makes way more than enough space free to implement it without losing anything.

It’s definitely a good sounding method. Do you recall about how much space it takes up? For space-constrained applications, even doing that method with two bytes sounds far better than what Biscotti has.

I haven't actually implemented it yet. Just on my todo list.

I did work out that the check can look like if (a==b&c&d)

... but that's about as far as I got and actually while that looks tidy it probably doesn't optimize to much if any shorter than more verbose statements.

One trick I used to save some space is to declare a few key variables as global register variables. This avoids all the in LDS STS instructions for those data. If you do it too much (more than a few probably) it can result in more juggling instead of less though. I believe these are always noinit but I have no idea if they'd persist at all like ram variables.

As for two bytes, yeah, that's 1 in 2^8 so 255 for equal weighted bits. I started thinking this through with your idea first actually, then thought this other two byte trick, then figured, well, that makes it better but it will still be an actual problem so it needs 3 and might as well make it 4 (three would still hit someone someday). But three could be good for attiny13 if it will fit.

ah.. just realized that way of doing the check isn't as clever as it is cute. It's possible for that to pass with some not so hard to produce combinations of non-equal values, so it significantly weakens the check. Just have to do out long probably : if (a==b && b==c && c==d) Your claim of a weighted coin probably also weakens it.

I'm not quite sure what the main problem is, but if you're using an Attiny25, why not just use the EEPROM? This in conjunction with the RAM trick or an OTC would be very useful :)

Yes, eeprom can probably work too, but you still need a few bytes of noinit comparisson to reliably see the long press. Once you're setting a few bytes to the same value, might as well set them to the value that matters. If you need multiple sets of all bytes, like a clear and an increment, then maybe that starts to get a little more costly in terms of instructions, depending where it's done and if the variables are still in regeisters from the set when the clear is done(Ok, clear doesn't need the value but anyway some details may matter...) Of course a problem with any multi-byte thing is there can be interruption in the middle of it, but the odds on that are also pretty slim, and can be made slimmer with assembly programming, if one really wants.

Also eeprom is very slow (like multiple ms, which probably implies worse interruption concerns), and it has limited writes. Bistro adds wear leveling to anything written to on every single click (presently just the mode inex) to avoid writing to many times to a single byte. Maybe that's overkill, maybe not (100,000 writes max by spec), but you'd need more code if you want to do this to more variables as the wear leveling code isn't very general.

It's definitely option, and probably more than one way to skin this (including using attiny25's and OTSM) but each may have its own issues as gchart notes.

Very cool GC.
I can do the solder work but exactly as loneoceans posted above I need a translator most of the time.

BTW, I’ve got the multi-byte noinit stuff working just fine in the manner that Flintrock described. For proof of concept, I only used two bytes, but adding an extra one or two wouldn’t be a problem at all.

I need to remember to check and see how much extra space that takes up. I’ll report back later.

And yes, there’s all sorts of ways to address this. But I’d like to see it work on the typical nanjg drivers that are so prevalent… no OTC mods or anything necessary. Especially with the several reports of Biscotti acting funny due to the current noinit implementation, this should solve that.

But I got my 47uF tantalum caps and low leakage diodes now and will put together an OTSM build with bistro, of course not nanjg or attiny13.

Cool, yeah, the cap related comment was not aimed at this case.

Ok, I’ve done some initial fast_presses redundancy size testing. I can’t say these are the most optimized, but it should be pretty good. The code can be found here. I’m open to suggestions… looking at you, Flintrock :wink: You’ll notice I was also testing out your variable-length mode groups, FR. With the current mode groups set up, it was adding about 14 bytes. But if I wanted groups longer than 4, I bet I’d see efficiency over making all the groups longer.

No redundancy: 984 bytes (control program)
Using 2 bytes: 1010 bytes (+26 bytes from control)
Using 3 bytes: 1028 bytes (+44 bytes from control)
Using 4 bytes: 1044 bytes (+60 bytes from control)

cool, 60 bytes sounds reasonable to me. I was hoping for 50, but that was kind of just my guess. Yes the variable mode-group length has a little buy-in price. I haven't looked yet, will soon, so not sure how this translates to the tiny13 firmware, but the next biggest savings was probably all the array looping of the menu variable operations, save, restore, and toggle. The easiest savings were probably

a) going through every function and trying with and without inline as the compiler doesn't optimize this as well as you expect even though it's only supposed to be a hint, and it's not always as obvious as it seems which way is best.

b) Changing some key variables to register variables. (and it matters which register is used).

really it would be great if we could figure out how to include the attiny13 software as a subset of bistro(already setup that way in principle, but in practice may be hard now to get a small enough configuration). I might look at it. Then these changes don't need to be maintained in two places. But it's good this way too. It's not like it's a huge program.

Yeah, I just went thru the inline / no-inline exercise on every function. Can be a good amount of savings there. Now that I’ve refreshed myself on inline functions, I’m using them more to make the code easier to read. It had been about 12 years (college days) since I last used C for much.

I’ll have to take another look thru your code. I’m not real familiar with the register variables

One thing I was shocked about is how much space can be saved by using local variables instead of globals when hitting it frequently. Like in count_modes(), swapping out solid_modes for a local variable when iterating thru.

So bistro-HD seems to compile for attiny13 just fine and I guess the nanjg layout that I essentially copied over from previous bistro, should work. I see that there are some things missing for making it a true BLFA6 replacement, example timed turbo (attiny25 doesn't need it of course, so the opposite of your issue), and star configuration. I don't know if I'll get around to adding that or not, but I'm making a separated config file for a BLFA6_EMU build. Partially I wanted to start breaking out config files like this anyway, because it seems it will be useful for other various builds. I'm not sure how the size of bistro-nanjg13 compares to BLFA6 because the options are setup exactly comparably yet, but it's at least possible to get something working in under 1K.

deleted, momentarily confused. I saw OTC in blfa6 and forgot that you said you modified it specifically for not using that.

Local variables can be allocated on a stack frame, and then probably aren't really better than globals that need to be fetched from the RAM "heap". However, in my testing the compiler is pretty decent at keeping locals entirely in registers until you have too many of them. Then if they really are temp variables, there's no loading and saving them, so that saves some instructions.

This is the same reason why changing a global to a global register vairable can help. However, it reduces registers available for local use, so it can hurt too.

Looking at the A6 firmware now. Ok, I see, with so few modes and so few options, optimization is an entirely different story. It's just so simple and efficient to sort of hard code everything there as done. Probably many of my optimization ideas don't apply, and also the idea of including BLFA6 as a config option in bistro kind of looks hopeless. It's probably too much overhead to produce a relatively much simpler driver in so little space, which I guess is why TK didn't do it too.