Flashlight Firmware Repository

Okay, that's done. There's now a flash-tinyNN.sh script and a flash-tinyNN-fuses.sh script for each supported MCU, and people should generally use the one without fuses by default. This reduces the risk of bricking the MCU.

I also cleaned up some other stuff while I was at it, and added some generic wrappers for building and flashing.

Indeed, that's a crappy thing to lose. I ended up swapping the XP-L HI board out of my green D4S too, because the green one was a prototype where the parts don't fit right. Like, the tube is too short for most 26650 cells, and the button retaining ring isn't installed, and some edges are sharp, so it's not really usable for normal flashlight purposes.

I'd rather have a green model instead of a black one, but Hank sent what he sent.

I think you may be missing a -u in there, but otherwise it looks right. Here's what I have: flash-tiny85.sh

#/bin/sh
FIRMWARE=$1
avrdude -c usbasp -p t85 -u -Uflash:w:$FIRMWARE

flash-tiny85-fuses.sh

#/bin/sh
# 8 MHz, 64ms boot delay, enable flashing
# (everything else disabled)
# Use low fuse 0xD2 for 4ms startup delay,
#           or 0xE2 for 64ms (useful on a twisty light)
avrdude -c usbasp -p t85 -u -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m

http://www.engbedded.com/cgi-bin/fcx.cgi?P_PREV=ATtiny85&P=ATtiny85&M_LOW_0x3F=0x22&M_HIGH_0x07=0x07&M_HIGH_0x20=0x00&B_SPIEN=P&B_SUT0=P&B_CKSEL3=P&B_CKSEL2=P&B_CKSEL0=P&V_LOW=E2&V_HIGH=DF&V_EXTENDED=FF&O_HEX=Apply+values

Iā€™ll have to check out the change log in bzr.

From what Iā€™ve read from the help file, the lowercase u turns off safe mode so you can flash fuse bits but is not needed in the firmware flash commands.

Itā€™s worked without issue on my q8 with the clip. The d4s just seems to like to give me a hard time.

If you have a minute, can you review my thoughts on the voltage calculations?

The ifdef / undef stuff mostly depends on the order things are defined in. For example, the compile error you ran into is because the cfg files used to be included later in the source, but got moved up, and I didnā€™t update the ramp length define to account for this.

In general though, Iā€™d avoid changing the ramp length much, since Anduril makes a bunch of assumptions about its proportions. Like, the thermal regulation response would be way off if the ramp were half as long or twice as long.

Also, I wouldnā€™t recommend copying a ramp from Narsil, because the differences are more than just length.

This is why it doesnā€™t work very well to copy a ramp from Narsil.

Anduril underclocks the MCU on the lowest few levels to reduce power. So moon on Narsil uses about 5 mA, while moon in Anduril uses about 1.7 mA. Three times as much runtime just by slowing down the MCU. However, this also means the ramp needs a different shape, and you have to be especially careful about the PWM levels at the exact point where the clock speed changes.

Because integer math. Itā€™s a bad idea to use floating-point numbers except when absolutely necessary, especially on tiny AVR chips since they physically donā€™t have that functionality.

No, it wonā€™t just ignore extra data.

It really sounds like you need to calculate a new ramp with the bin/level_calc.py tool.

The cfg~~.h files are mostly meant for UI options, not hardware options. The hardware correction factor should be in a hwdef-.h file. So thatā€™s why it works that way, and why defining it in a cfg~~*.h file doesnā€™t work.

But in general, Iā€™ve been meaning to redo the config system again. Itā€™s way better than it was, but itā€™s still clunky. So Iā€™ll probably rearrange this stuff again to make it cleaner.

Until then, you might want to just edit the hwdef files. I donā€™t currently have a clean way to define correction values per individual driver, like this D4S needs a value of 4 while that D4S needs a value of 7. But hopefully after reorganizing things, itā€™ll be more amenable to freeform config changes.

Ah, Iā€™ve been assuming that safe mode was basically a dry run mode where it doesnā€™t actually flash anything. So maybe the other -u isnā€™t necessary.

Thanks for the info.

Ok, so I guess I will just revert to editing the defines in the anduril file, not a big deal, I will just keep copies of the whole thing for each light like I used to.

Thanks for the info on the ramp smoothness, that does explain some oddities in the low power ranges I was seeing.

Yeah, I know how to make a new ramp, the issue I run into is that I generally have to manually edit the ramp to get it as smooth as I want in the low ranges and in the channel switch over points so creating a whole new ramp becomes a real pain when I just need minor changes to max power output. Not something I need a lot but some lights just canā€™t handle 100% power.

You can still edit the ramp manually. Something Iā€™ve done a few times is to calculate the ramp in segments, then only change one or two segments. That way I can have, for example, the FW3A ramp for the 1x7135 channel, but also use some other new ramp for the rest.

About the per-light configuration, it would be really helpful to hear about what doesnā€™t work, so I can fix it. Like, Iā€™m fixing the voltage fudge factor thing now. The hwdef files will check for that first instead of assuming they own it.

Editing the Ramp in segments is an idea, although generally I need to edit the end of 1 ramp and the start of the next to get it smooth. But I suppose I could just cut the ramp after those edits, that might work.

Since I really donā€™t know what I am doing with the code, what I am wanting is to have ALL the defines that can possibly be used or needed inside the config file. I never know what I might need to tweak and would like to have them all in one place to make editing easy as not understanding the code can make it difficult to find the correct define and then get it working later.

It sounds like it will be hit or miss getting defines to work in the config file so rather then making you have to re-work stuff for my very niche use case, I figured it would be easier to just use the main anduril file instead.

Right now the only error I know about is the ramp length but I have also not really tried anything else.

I just fixed a lot of that.

Regardless, it probably helps to explain the structure a bit more:

  • The cfg-*.h files only apply to one specific interface, Anduril *. Other FSM-based programs have their own unique configurations. So the cfg files are mostly about configuring the interface, or the application.
  • The hwdef-*.h files apply to all firmwares, so they focus on the hardware-specific features and the things which are universal for all programs which run on that hardware. It isnā€™t really even limited to FSM; the hwdef files can be used by other stuff too, like Bistro.

* ā€¦ and RampingIOS V3, since itā€™s a direct derivative and is intentionally compatible.

Getting Anduril to support a new light usually requires both ā€” a hardware definition and an interface configuration. So itā€™s currently two files per new light. But I just made some changes to make it more amenable to doing only one file. This makes it a lot easier to express things like ā€œthis is just like Brand X, except that Function Y is differentā€.

Putting the product-specific stuff in the main Anduril file instead of a header file mostly just means one or both of the following:

  • Patches might get rejected for not being clean.
  • Extra work on the part of whoever translates the changes into the proper form.

Adding a new light shouldnā€™t break the build for any other lights, and generally shouldnā€™t change the md5sum of any other builds. It can add new features which didnā€™t exist in FSM or Anduril before, like another aux LED or tint ramping or another switch, but only if it doesnā€™t break anything else.

Itā€™s definitely more complex than older projects, so it can be weird at first. Instead of one file containing everything, itā€™s several independent components linked together. There are four layers:

  1. The hardware definition (hwdef-*.h)
  2. The UI toolkit (FSM)
  3. The application (Anduril)
  4. The applicationā€™s config (cfg-*.h)

Adding support for a new light typically touches the top-most and bottom-most layers, but usually doesnā€™t touch either of the middle layers.

I think I have started to get the hang of the hwdef and cfg files. Once you figure that out I really like this setup, which is why I wanted to add all the defines to the cfg file to make it easy to adjust things.

I have found myself having to do all sorts of strange things to get things working like I want in the past (such as the slightly longer ramp in Narsil in order to get it smooth, the extra length are values I had to add to smooth the channel change over).

Past this is where I am still stumbling around, I figured out that the Anduril.c file seems to have all the defines I am interested in so that is the only other file I have really messed with. Now I have been trying to find all the possible settings and defines that I can adjust and move them into the cfg file so they are ready. I plan to make an all-inclusive cfg ā€œbase fileā€ that I can copy/paste for future drivers and remove any settings that are not needed after finishing the driver.

The only other complicated bit is having to add in the new hwdef and cfg files to the attiny and anduril files but I can live with it now that I figured it out.

Just to be clear, I really like Anduril from a coding perspective, I just simply donā€™t have the skills to truly understand it so the learning curve has been steep. I really like the direction you are taking though.

The only UI comment on Anduril I have is the double click delay that prevents anything from happening until it sees if you are double clicking I assume. I understand why you did it this way It just makes the light feel ā€œlaggyā€ and for some reason bothers me.

The flash of dark before turbo when you double click Narsil is not perfect either but I think I prefer it personally. The light just feels snappier but then I get annoyed by delays like this quite easily and I know it.

Would it be a simple change to make it like Narsil where it gives instant response to the first click and then does the double click action if a second click is detected?

If not Is it possible to lesson the double click length to reduce the delay easily as a possible compromise?

So, this is direct from the AVRDUDE manual:

So if we KNOW that the fuses were set correctly, not setting -u while flashing firmware could potentially be more dangerous as the USBASP will be double checking the fuses and attempting to reflash them if they ā€œchangeā€ for any reason (bad connection, or an actual issue that changed them during the FW flashing process.)

Im also curious to see the changes you are working on FSM. Ive been able to decipher some of it and what comes from where, but something similar to Texas Aceā€™s idea would be nice for future UI overhauls.

I also didnt see anything in the bzr changes besides the flashing script changes. Were the other changes you were working on committed or are they still being worked on?

I am going the toykeeper readme route. I have sudo apt-get install gcc-avr avr-libc binutils-avr

but I am getting a fatal error No such file or directory

< avr/interrupt.h >

edit I also just noticed that this doesnā€™t show up unless I add a space after the < sign.

<avr/interrupt.h> nothing shows up if its in < >

Did you run ALL of the apt-get commands?

From the readme:

Off hand I dont know exactly what that is referencing, but with the Linux subsystem for Windows running Ubuntu, the build scripts should work out of the box if your pathing is correct.

Ran it. Then again. Says I have it and its newest.

What command are you trying to run?

Also, did you by chance do an apt-get update prior to the install? I believe thats one thing extra that I needed to do.

Im assuming youre trying to compile Anduril. If you look in the build-85.sh script, there are quite a few more flags, options and variables that go into it. When I run that command, I get an error about an include for spaghetti-monster.h

It might be easier to just run the build-all.sh script inside of the Anduril folder to create the hexes. If you want to specify which targets you write to, you can ā€œnano build-all.shā€ and remove the lines for the drivers you will never build.

I have mine set to build for the Q8, and 3 different Emisars I have.

I followed TKā€™s setup directions and it went very smoothly on mint 19.

I then followed her suggestions to copy the whole repository to the local machine and running the build script worked perfect first try. I have only had issues I caused since.

From my
understanding the avr interrupt should be something I already have from the readme files

Let me clarify this:

#include <avr/interrupt.h> works
#include < avr/interrupt.h > does not?