The B
flag's purpose depends on the programmer in use. The avrdude documentation doesn't tell the whole story. Fortunately the source is open, so we can peer beneath the covers.
Essentially avrdude collects the command line arguments, packs them in a struct, and asks the programmer to initialise itself. The USBasp's implementation of initialise ultimately calls set_sck_period
and passes it the bitclock setting. The bitclock setting, by this point, is the number you specified (3
) interpreted as microseconds and converted to Hertz. So roughly 333kHz.
Now set_sck_period
checks whether you're in TinyAVR mode or normal SPI mode. Assuming you're in SPI mode, it then finds the closest supported SCK frequency below the requested bitclock. For -B 3
, that's 187.5kHz. From there, your USBasp is told what's up. Interestingly, if no -B
flag is specified, then "AUTO" is set, which the USBasp interprets as 375kHz.
So why is 187.5kHz needed and 375kHz wont do? Could be a number of reasons such as borderline signal integrity that is helped by a lower clock speed. But I have noticed that with a ATmega328p at least, the CKDIV8
fuse comes programmed from the factory, which means the internal 8MHz oscillator produces a 1MHz system clock. Section 27.8 of the 328p datasheet indicates that for SPI programming, there must be at least four CPU clock cycles for each SCK period. At a 1MHz system clock, that probably means you need SCK to be no faster than 250kHz. Hence, 375kHz wont do, yet setting it to 333kHz succeeds because it's rounded down to 187.5kHz by the USBasp!