I'm using avr-g++ (4.9.2) on Linux on a ATtiny40 and am convinced there is something fundamentally wrong with either the support for ATtiny40 ICs in this compiler version, the specific IC I am using, or the ATtiny40 in general.
Is anybody using a similar configuration with a ATtiny40 with a non-trivial build reliably?
I've previously been using an ATtiny84A with a cross-platform codebase (ARM and AVR) and it's been working fine.
I've had no end of problems trying to port it to an ATtiny40. Certain images when flashed appear to not start at all, and others work fine, with seemingly small changes determining whether it will work or not:
- Switching between -Os and -O.
- Calling the exact same function one more time than usual. For example a bit-bang SPI-style send called ten times works fine, but eleven times fails.
- The number of exported symbols in a certain file going beyond a certain number (eg. I can include functions A and C, A and B, B and C, but not A, B, and C- even if I never call them).
- I don't believe it's related to stack size but can't be sure. My program RAM usage is obscenely low (<16 bytes) so I don't think so.
- It isn't program size. I've had 3K programs work, and 512b programs fail.
- I've tried all-in-once style builds versus the usual linked ones. Doesn't seem to make it worse or better, but can break a working program, or make a broken one work.
- Bits of code that follow different paths to the same result can have different outcomes.
- The same program flashed multiple times tends to either work or not, ie. it almost always works, or always fails. It generally isn't random, but seems to be based off the particular image that I have built.
I haven't been able to get a stable tracewrites working (this is the bit of code giving me hassle), and I can't guarantee whether setting an output on a pin is even going to work in any build, which is making it hard to diagnose.
I can't put together a minimal example that breaks it, but have generated many examples using the existing codebase that will break/fix with a trivial change that should make no difference (eg. toggling pins that were just toggled previously). I realise this means I can't eliminate potential fault in the existing codebase, but I have run into problems with so many changes in unrelated areas that should have done nothing that caused the image to fail to work that this is unlikely to be the sole cause. This is especially true with the same code running fine on an ARM and an ATtiny84A with no hassle.
It is really starting to look like an IC fault or the compiler is simply not capable of building reliably for the IC. The former seems possible as the behaviour is consistent with parts of the flash being faulty. The latter seems possible as it seems certain combinations of code, rather than the nature of the code itself, determines whether a working build will run. I'd like to figure out which is the case.
So... is anyone else having luck with this combination? Is the ATtiny40 just awful, is the compiler support incomplete, or is my specific IC bad? Am I the only one trying to work with it with avr-gcC? Please let me know if you've had better luck than I, and how your setup compares to mine.
Just a note for anyone considering using an ATtiny40:
- It uses TPI, which is just awful to work with. I had no idea TPI even existed. What a way to learn.
- No serial programming.
- No self-programming. Don't be fooled by the mention of "Self programming" in the datasheet. All that section says is that it is unsupported.
- It is seriously picky about programming voltage. I've had repeated failures with flashing using 5V through a Schottky, that were solved by removing the Schottky.
- avrdude with linuxgpio doesn't support TPI.
- not even the latest version, hand-built.
- there are some non-merged patches (davidm) out there that apparently supports it
- they don't apply to the latest version.
- when fixed, they don't actually work.
- almost nobody seems to be using them. Searching for common error messages yields almost no results.
- no luck even when using dedicated Pi pins and detached from the whole prototype.
- even with the suggested resistor (which, let's be honest, is obviously a hack).
- I was forced to revert to using a generic AVRASP, which with some struggling re voltage, could be made to work.
- No EEPROM. It's one of the few chips with *none*.
- You can probably forget about in-system programming with the need for dedicated hardware and the voltage pickiness, unless you happen to be running at 5V already.
And before someone suggests the 1634: That is an excellent suggestion. I almost went with it instead. Knowing what I do now, I would choose it over the 40. I really, really wish that I'd gotten one instead or at the same time as the 40. I only really need about 1K flash, so the 1634 seemed like overkill, but it's all down to the peripherals and hardware functionality.