AVRDUDE failing to program a barebones atmega328p

I have made three sets of boards with atmega328p chips. Each set is 100~200 boards and they serve different purposes, so the functionality, connected chips, etc is all different between them.

These boards can be divided into two groups, ‘good’ and ‘bad’. Bad is on the order of ~5~10% of total boards.

On all boards, programming through AVRISP MKII ICSP works to load optiboot 8.0 with 38400 baud upload rate.

With ‘good’ boards, avrdude upload succeeds, sketch is loaded, and uart rx and tx are working.

On ‘bad’ boards, avrdude will fail, usually with
avrdude: initialization failed, rc=-1
stk500_getsync() not in sync

If I load the full sketch along with the bootloader with ICSP, UART i/o and sketch both work fine on ‘bad’ boards.

If I scope the reset pin of good or bad boards, DTR toggle holds reset low for 250us, so that shouldn’t be it.

Using 5v or 3.3v does not make a difference in the behavior.

I also tried Optiboot recompiled for slower upload rates (tried 38400 and 9600). This works on the working boards, but does not fix the ‘bad’ ones.

Of the boards, two sets were from a different pcb house, assembler, and part source, same issues. It looks like a design issue. In some instances, swapping the ATMEGA328 device between a ‘good’ and ‘bad’ board will cause the fault to follow the chip, sometimes stay with the board, and sometimes both boards are fixed. This makes me think that something is borderline out of spec.

The overall setup is very bare bones. Internal 8MHz oscillator, 3.3v power (LDO on one board, switching on the others), a few 1uF decoupling caps, 10k pullup + 1uF between reset and DTR. Series 100ohm on uart lines (setting to 0-ohm did not change behavior). Fuses are set to FD DC E2.


Better to post the schematics. It is hard to discuss without seeing the schematics. Are you talking about 500 boards in total? Did you test on prototype?

  1. "few 1uF decoupling caps" 0.1uF is enough and usual, 1uF can cause more problems than benefits
  2. "1uF between reset and DTR" ?; again; beter to go without
  3. "Series 100ohm on uart lines" is too small, 1k or 1k2 is better to improve USART behavior with impedance mismatch
    However, it doesn't explain why some of boards doesn't work. Normally, the 328P should be programmable with 115200 without any problem.

It turns out that the internal oscillator on some of the ATMEGAs varies enough to cause UART issues. Trying to upload at a slightly different speed (eg: 38000, different for each) instead of 38400 will successfully upload to these bad boards.

It could be that swapping components between boards had the effect of thermally cycling the die and causing the oscillator to change its value, sometimes closer to the spec.

A good solution might be to have Optiboot write OSCCAL, but there isn't much info on this.

I could also just sidestep the issue, program the remaining boards through ICSP and hope that they are close enough to the 8M spec for single-character UART to work between another similar board.

Any advice on the OSCCAL route?

I’ve been working with several different AVR parts configured with optiboot and minicore or mightycore for use on my own PC boards.

I learned that the internal 8MHz oscillator frequency does vary from one part to another. In addition the internal oscillator has a considerable amount of “frequency jitter.”

I have a very precise frequency counter. When using an AVR with an actual crystal (example: genuine Arduino UNO board) the clock is very stable. For example 15995.367 kHz. The counter reading only jumps around by about +/- 5 Hz.

But when using internal 8 MHz oscillator, the frequency counter might read 8008.935 kHz and then a few seconds later read 8006.158 kHz. So the frequency instability can be as high as +/- 1 kHz.
Also the frequency error is sometimes as large as +/- 4%. This is a large enough error to make serial programming unreliable at certain baud rates. And it varies from one device to another. I don’t think the “factory osccal” is as accurate as Atmel claims it to be.

I have been able to adjust OSCCAL to make my own code run within +/- 0.5% of proper speed when averaged over 60 seconds. But this doesn’t make optiboot work for serial programming because optiboot always uses the Atmel “factory oscillator calibration byte” which cannot be changed.

My fix for this is to do all my device programming with ICSP rather than serial programming. The precise clock frequency doesn’t matter with ICSP.

A lengthy search turned up a handful of avrdude experts who modified the boot loader to permit storing a user adjusted oscillator calibration into the boot flash area. Another technique mentioned is a boot loader modification which automatically fine tunes the baud rate for serial programming. I haven’t tried either of these myself yet.

After I acquire more experience using the 8 MHz internal oscillator I’ll start a new thread to share what I learn about this topic. The title will be something like “Serial AVR programming with 8MHz internal oscillator.”