Flashlight Firmware Repository

I have yet to use Anduril at all outside of a quick test I did on my Q8. The firmware showed promise, I just have never had time to dig into the code. Usually takes me a week or 2 to get used to a new firmware code (even to the minor extent I understand the technical side) and have not had nearly that much free time lol.

As a discrete mode user I might as well suffer with what I have so far and live with the quirks. I won’t get used to the Narsil UI in 100 years. :smiley:
I don’t know if it’s a hardware or software problem, that’s what’s bugging me the most.

I’m running Anduril on my GT, and haven’t seen any issues on it. Which exact file did you flash to it? I could try to reproduce the issues using the same file.

I have also Andúril on my GT. But I don’t use it very often.

I flashed anduril.2018-09-30.BLF_GT.hex yesterday, but had anduril.2018-09-07.BLF_GT.hex on before. The thing is, I can’t really reproduce the problem. But doing a lot of clicky actions (as opposed to single clicks or holds) seem to increase the chance of failing.
A problem with the e-switch seems be unlikely, if the light works again after I disconnected and reconnected the batteries, right?

If the switch acts weird and it helps to loosen / tighten the batteries, it could be a bad connection to ground or something. I get that on the FW3A prototypes sometimes, especially after it has been knocked around. If I hit it sideways sometimes it seems to move the inner tube just enough to cause problems, so I have to loosen/tighten it to reset things. The firmware seems fine though, because even if I do it fast enough that the MCU doesn’t reboot, all the symptoms go away after re-seating the physical connections.

Anyway, I downloaded the 09-30 build and flashed it to my GT. I’ll keep an eye out for anything weird, but I ran through all the modes and so far it hasn’t done anything it’s not supposed to.

Whats updated from Anduril 9/7 to 9/30?
Thanks!

In detail, this is what changed:

https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/fsm/changes

I have been looking at the Anduril firmware for a project light I am working on. Got it to compile now I am trying to understand it so I can design the driver.

The big hangup I am having right now is the LVP. The drivers that do not use a voltage divider still seem to use a pin for ADC measurements in the firmware. Where / What is the setting to switch between a voltage divider and internal voltage sensing?

Setting: ADMUX_VCC in tk-attiny.h, with a mix of the hardware-definitions (hwdef-BLF_GT.h vs hwdef-Emisar_D4.h, #define USE_VOLTAGE_DIVIDER)

Where it's done: fsm-adc.c

In fsm-adc.c, it switches between reading the temperature and VCC values.

Thanks, keep in mind I know just enough about C code to get my self in trouble and fully admit it.

So best I can understand, if the” #define VOLTAGE_PIN” is set to PB2 (maybe it ignores the pin completely when using the internal ref?) and “#define USE_VOLTAGE_DIVIDER” is not set, then it defaults to the internal voltage reference and there is nothing else I need to do.

If “#define USE_VOLTAGE_DIVIDER” is set then it uses an external voltage divider?

So basically adding or removing the “#define USE_VOLTAGE_DIVIDER” is all I need to do to switch between these options?

What about pin 7? What does it need to be connected to if using the internal voltage? Can it be used as an indicator LED output? Can I set the voltage sensing (internal or external) to another pin?

That seems to be the case, if you set USE_VOLTAGE_DIVIDER, it uses ADMUX_VOLTAGE_DIVIDER for measurements, otherwise it uses ADMUX_VCC

It also sets up the pins (DIR0) differently if it is used.

You're free to use pin 7 for anything else you desire if you use internal VCC measurement.

Yes you can use it as an indicator LED, please see my Texas Avenger 21mm Skilhunt H03 config for reference.

This config may have a problem with space as I have some other tweaks in my fork.

Removing #define TICK_DURING_STANDBY frees up enough space so it fits onto the 8KB of flash.

hwdef-H03-TA.h

/* TA 21mm H03 driver layout
 * ----
 * Reset   -|1 8|- VCC
 * eswitch -|2 7|- indicator led
 * FET     -|3 6|- 7x7135
 * GND     -|4 5|- 1x7135
 * ----
 */

#define PWM_CHANNELS 3

#define SWITCH_PIN PB3 // pin 2
#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt

#define PWM1_PIN PB0 // pin 5, 1x7135 PWM
#define PWM1_LVL OCR0A // OCR0A is the output compare register for PB0
#define PWM2_PIN PB1 // pin 6, 7x7135 PWM
#define PWM2_LVL OCR0B // OCR0B is the output compare register for PB1
#define PWM3_PIN PB4 // pin 3, FET PWM
#define PWM3_LVL OCR1B // OCR1B is the output compare register for PB4

#define AUXLED_PIN PB2 // pin 7, indicator led

#define ADC_PRSCL 0x06 // clk/64
// average drop across diode on this hardware
#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V

#define TEMP_CHANNEL 0b00001111

#define FAST 0xA3 // fast PWM both channels
#define PHASE 0xA1 // phase-correct PWM both channels

cfg-h03-ta.h

// TA 21mm H03 config options for Anduril

// the button lights up
#define USE_INDICATOR_LED
// the aux LEDs are behind the main LEDs
#ifdef USE_INDICATOR_LED_WHILE_RAMPING
#undef USE_INDICATOR_LED_WHILE_RAMPING
#endif
// enable blinking indicator LED while off
#define TICK_DURING_STANDBY

#ifdef RAMP_LENGTH
#undef RAMP_LENGTH
#endif

// …/…/bin/level_calc.py 1 65 7135 1 0.8 150
// … mixed with this:
// …/…/…/bin/level_calc.py 3 150 7135 1 0.33 150 7135 1 1 850 FET 1 10 1500
#define RAMP_LENGTH 150
#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255
#define MAX_1x7135 65
#define MAX_Nx7135 130
#define HALFSPEED_LEVEL 14
#define QUARTERSPEED_LEVEL 5

// stop panicking at about 3A or ~1100 lm, this light is a hotrod
#define THERM_FASTER_LEVEL MAX_Nx7135
// optional, makes initial turbo step-down faster so first peak isn't as hot
#define THERM_HARD_TURBO_DROP

Internal? No. Thats - as the name implies - internal. If you want to set it to another external pin, you would need to update the registers used in the hwdef-*.h file:

#define USE_VOLTAGE_DIVIDER // use a voltage divider on pin 7, not VCC
#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
#define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2
// 1.1V reference, left-adjust, ADC1/PB2
//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
// 1.1V reference, no left-adjust, ADC1/PB2
#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL)
#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
#define ADC_PRSCL 0x06 // clk/64

ok, I think I am getting it now. Seeing a defined pin for the internal reference really threw me for a loop.

So if it is using the internal reference then it is also ignoring the pin defined for the voltage divider and I am free to use it for something else.

I wounder why the pin 7 is defined at all for those drivers? Seems like it would be commented out completely?

Thanks for taking the time to explain it.

My best guess: copy&paste as you can see the comment in hwdef-Emisar_D4.h

// (FIXME: remove?  not used?)
#define VOLTAGE_PIN PB2     // pin 7, voltage ADC

Thanks for answering all that over the past few posts. :slight_smile:

The API for voltage measurement is, um, not ideal. It’s not really designed so much as just kludged together over time. I’ll probably want to rewrite it when I add support for a new MCU architecture, but I don’t know when that will be. Writing all these abstraction layers takes a while, and the hardware abstraction parts aren’t anywhere near as mature as the UI abstraction parts.

So for the moment, it’s a bit of a mess.

Great, at least I can switch pin 7 to AUXled duty, using pin 3 would of been more difficult. So this is all I should have to do to setup the drive with FET + 1x 7135 + AUX led.

Having PB2 defined twice will not matter correct? Or should I comment out the ADC section entirely?

Sorry, this driver is kind of a last minute addition to a light Neal asked me for that is already in the works and I will not have time for a second prototype I am sure, so I need to get the hardware right the first time and preferably the firmware as well.

As I start to learn my way around Anduril I can see the advantages it brings to the table, although I am sure I will have more questions before I am comfortable with it. Took me 6 months to get comfortable with Bistro and then Narsil but I am getting better each time.

Thanks again for the help.

EDIT: Are the fuses the same as Bistro?

This is what I use now:

lfuse:w:0xd2:m
hfuse:w:0xde:m
efuse:w:0xff:m

Referring to PB2 from more than one place shouldn’t cause issues, as long as only one part tries to use it. The voltage pin thing isn’t used unless it also has the USE_VOLTAGE_DIVIDER thing enabled.

The recommended fuse values are always in bin/flash-85.sh.

There is some debate about whether BOD should be enabled, but it doesn’t appear to matter much in practice.

For what kind of light does Neal need a last-minute Anduril driver? Should I trust that people will follow the license requirements this time?

I was looking at the flash scripts and noticed that the fuses are different for the tiny25 and tiny85, I used to use the same settings for both, has that changed?

Tiny85 -
lfuse:w:0xe2:m
hfuse:w:0xdf:m
efuse:w:0xff:m

Tiny25 -
lfuse:w:0xd2:m
hfuse:w:0xdf:m
efuse:w:0xff:m

I am not sure that I am supposed to say anything about the light at this point, not sure what the status on it is, I was not really involved with it until a week ago and then only as a “hey, we need a better driver, can you make one? Oh and I would like to use Anduril” type thing lol.

I am not even sure who is making it come to think of it. Heck, I am not even sure about what the light is, I only know it needs a 17mm driver and to support a fair amount of power.

On my end, I always keep all the source files, and credit those needed on the silk screen (unless they remove it, like one manufacture did). So I try to do everything I can to maintain the license, just not always in the most timely fashion.

If you ever have questions or issues with the driver or firmware for a light I worked on, please let me know and I will get you whatever you need. It might be “messy” but I am happy to send it your way. Although I am getting better at keeping things a little more organized as I work now.

The low fuse value of D2 vs E2 selects a startup time of 64 ms or 4 ms. This is how long the MCU waits for power to stabilize before starting to run code. In general it doesn’t matter, as either one should be enough. But it used 4 ms on tiny25 since those are mostly clicky-switch lights where a fast response is important… and 64 ms on tiny85 since those are mostly e-switch lights where boot-up usually means the user is screwing the parts together.

Anyway, the license doesn’t care about whether someone’s name is inscribed onto the PCB. It’s about making sure that anyone who distributes the product also makes the source code available under the same license. Usually this means putting a note in the manual and/or product page stating that the product uses free software, with a link pointing to the code. Putting a conspicuous notice somewhere with the copyright and licensing info is mostly just a means to an end. Attribution isn’t the goal, but because of how copyright law works it’s kind of a necessary prerequisite.

I finally merged FSM into trunk again today. It included several bug fixes and other updates since the last merge.

  • Added support for Fireflies lights.
  • Tweaked thermal settings for a few lights.
  • Fixed a bug with one very specific click sequence causing a MCU hang.
  • Fixed a bug where changing the ramp style could sometimes jump to the wrong brightness.
  • Added a moon timing hint on hold-from-off.
  • Fixed a timing inconsistency on hold-from-off; stepped ramp took too long to start ramping up.
  • Added manuals for RampingIOS V2 and V3.
  • Added a ramp shape parameter to level_calc.py.
  • Added initial support for a second set of aux LEDs, but it simply copies the behavior of the first set.
  • Fixed a bug where thermal regulation could go up from the requested level after double-click-from-off.

The only UI change people would likely notice from this update is the moon timing hint.