Crescendo clicky firmware by TK

What MCU is the version you flashed written for? And what MCU is in the driver? There is a version that is written for attiny13a and a different version that is for the attiny25. But I would think if the wrong version was flashed then there should have been an error. ??? I like that firmware.

Do you have trouble with loosing the memory setting—- I’m constantly having to re-enable memory

I have mainly flashed it to the attiny13a series MCU. That version does not support memory.

The version for the attiny 25 is complete with memory. When I have flashed the 25 version to the attiny25 it has worked properly.

Depending on your skills it is possible to swap the MCU’s, they are the same size. That is best done with a hot air workstation.


I'm setting ATTINY == 85 and that's indeed the MCU on the driver. What that does is this (attiny.h):

#elif (ATTINY == 85)

// TODO: Use 6.4 MHz instead of 8 MHz?

#define F_CPU 8000000UL

#define EEPSIZE 512

#define V_REF REFS1

#define BOGOMIPS (F_CPU/4000)

// (1 << V_REF) | (0 << ADLAR) | (VCC_CHANNEL)

#define ADMUX_VCC 0b00001100

// (1 << V_REF) | (0 << ADLAR) | (THERM_CHANNEL)

#define ADMUX_THERM 0b10001111

#define DELAY_ZERO_TIME 1020


But to be honest I have no clue what any of that means.

Might have something to do with how the FW does off-time memory. See this thread for some discussion and reference to more discussion.

In my case double tap did not work due linker optimization dropping ".noinit" variables. Solved it by adding "used" attribute, so declarations looks like this:
uint8_t fast_presses __attribute__ ((section (".noinit"))) __attribute__((used));
uint8_t long_press __attribute__ ((section (".noinit"))) __attribute__((used));
uint8_t mode_idx __attribute__ ((section (".noinit"))) __attribute__((used));
uint8_t ramp_level __attribute__ ((section (".noinit"))) __attribute__((used));
int8_t ramp_dir __attribute__ ((section (".noinit"))) __attribute__((used));
uint8_t next_mode_num __attribute__ ((section (".noinit"))) __attribute__((used));

I finally had some time to read up on this and try out a few things. Unfortunately I had no luck, it’s as before - single tap works, double tap doesn’t, triple tap works.
I also played with CAP_SHORT to make sure I’m not just too clumsy, but that didn’t help either.

Could this be a fuse settings issue somehow? I have E:FF, H:DE, L:E2.

Have you tried #comment-1834332 ?

Try building with -Wl,-Map=app.map in LDFLAGS and verify .noinit section in map file.

It should look like this, more or less:

.noinit 0x0000000000800071 0x6 crescendo.o
0x0000000000800071 next_mode_num
0x0000000000800072 ramp_dir
0x0000000000800073 ramp_level
0x0000000000800074 mode_idx
0x0000000000800075 long_press
0x0000000000800076 fast_presses
[!provide] PROVIDE (__noinit_end, .)
0x0000000000800077 _end = .
[!provide] PROVIDE (__heap_start, .)

if it's shorter then there's your problem cause. You can either disable optimization (-fwhole_program/-flto) or hint the linker to keep them even if it thinks it would be better to drop them and use registers instead (or do something to prevent resetting MCU every time you press the button)

I have tried that, yes. This is going far beyond what I understand (I've never dealt with C much) but here's the relevant block I got as per your suggestion:

.noinit 0x000000000080006b 0x6 crescendo.o
0x000000000080006b next_mode_num
0x000000000080006c ramp_dir
0x000000000080006d ramp_level
0x000000000080006e mode_idx
0x000000000080006f long_press
0x0000000000800070 fast_presses
[!provide] PROVIDE (__noinit_end = .)
0x0000000000800071 _end = .
[!provide] PROVIDE (__heap_start = .)

It looks pretty similar to me?

Yeah, looks good to me.
I’m out of ideas, I’m affraid :frowning:

No worries, thanks for your help empeka!

One last bump as this is really getting to me. I’ve now tried the fuses of Bistro for TA, using different OTC components including the one from a Mtn Electronics driver where everything is working just fine, and I’ve even tried a different switch. I’m really out of ideas. Unless there’s a bug in the firmware itself that prevents the ramping down I fail to see how I can be so bad at building drivers :frowning:

Have you tried using a different MCU, like a attiny 25 or something?

Is it possible to change the floor level of the output. I mean, I think my driver doesn't seem to be reaching moon as it did before. More of a 'low' level. I transferred the Mtn 20mm driver from an S21A to a L2.

Edit: Nevermind. The reflector is so efficient that it looks brighter. Perfectly good for a thrower.

This is awesome. :smiley: :+1:

I flashed this onto two drivers that were buggy.
original 3/5 convoy driver works perfect.
the red biscotti has audio ringing as the mode goes higher. Is that coming from the mcu?

Also is this compatible with DELs DDM FET+1 drivers? OSH Park ~

I’m a big fan

I believe it should work on any driver meant for use with a clicky switch and with an attiny13a or an attiny25; two different versions are available. I have Crescendo working on both.

I ran into the same issue trying to get Crescendo to work on an H17Fx driver, where most things seemed to work except for double tapping from steady, which seemed to do nothing. I added in some blinks at various points to debug the situation and long story short, I'm pretty sure gcc was straight up removing the line that sets the next mode to ramp mode in the if (fast_presses == 1) block. This was further evidenced by the fact that compiling with optimizations disabled seemed to make it work.

To hack around this, I just made all .noinit variables also volatile and used (as suggested above). Seems to have fixed the issue

Edit: I also seem to have to have made mode_override, mode, and first_loop all volatile as well. As I add back in the low voltage protection and thermal regulation, it might be the case that basically all of these variables need to be volatile to avoid issues... which makes me thing that something is probably wrong :facepalm:

Pretty cool wjs3!

Welcome to BLF!

It's good to have you here, wjs3!