"Sketch uses 23032 bytes (71%) of program storage space. Maximum is 32256 bytes. Global variables use 1342 bytes (65%) of dynamic memory, leaving 706 bytes for local variables. Maximum is 2048 bytes."

I have "verify code after upload" disabled. With this enabled, it takes an additional 20 sec to upload for a total of 56 sec.

Using Sparkfun's avr programmer with USBtinyISP, win 10, arduino ide, minicore library. Code is utilizing several libraries from Mozzi. External 16mhz crystal. Have set fuse bits on the chip to use the external clock using the following command: "avrdude -c usbtiny-p m328p -U lfuse:w:0xFF:m"

Seems like it should be faster if truly uploading at 115200 bits / sec. But maybe I'm missing something in how this works.

Thanks !!


ISP programmers typically default to low ISP clock rates. Often something like 10khz, sometimes slower, probably to just work by default with very slowly clocked AVR chips. The ISP clock rate must be about one eigth that of the AVR's clock. For example, by defaulting to a low rate like 10Khz, the programmer will successfully communicate with an AVR clocked at 125KHz with some margin. Around 4 KHz would work with a 32.768 KHz watch crystal.

Look in avrdude documentation for the -B option. Note uppercase 'B', this is the option for changing the ISP speed, not lowercase -b which is for the PC to programmer (or bootloader) baud rate. Not all programmers support -B, but many do.


Well, I dug around the USBtinyISP code and in avrdude and it looks like the default value for -B is 10. So 10uS. The way this value is used in the USBtinyISP code is for high or low period, rather than total clock period. So it's about 20uS per bit, or 50kHz. If that's your rate, then the plain clocking of the SPI data only accounts for about 3.7 seconds. So that does cast doubt on this idea.

But, it still may be worth double checking that it is operating with the value 10 and not something larger. Just to put this in perspective: the maximum -B value is apparently 250, which would result in 2kHz ISP clock rate and about a minute and a half to clock out your roughly 23 KByte.

More findings: Per byte SPI overhead

Each byte of the flash pages is being delivered into the ISP interface by way of 4-byte long SPI commands. The firmware for the programmer has the following code in it for writing a page in its spi/main.c file where you can see it calling spi( cmd, res, 4 ) :

extern  void    usb_out ( byte_t* data, byte_t len )
    byte_t  i;
    uint_t  usec;
    byte_t  r;

    for ( i = 0; i < len; i++ )
        cmd[3] = data[i];
        cmd[0] ^= 0x60; // turn write into read
        for ( usec = 0; usec < timeout; usec += 32 * sck_period )
        {   // when timeout > 0, poll until byte is written
          spi( cmd, res, 4 );
            r = res[3];
            if  ( r == cmd[3] && r != poll1 && r != poll2 )

This code is used to deliver data to the flash page buffer during ISP programming.

You can see a comment in avrdude's code explaining that each byte becomes a 4-byte SPI transaction as an aid to explaining their calculation for a communications timeout with the programmer. The following is in avrdude's usbtiny.c file for the usbtiny_paged_write function.

if (usb_out(pgm,
            function,       // Flash or EEPROM
            delay,          // How much to wait between each byte
            addr,           // Address in memory
            m->buf + addr,  // Pointer to data
            chunk,          // Number of bytes to write
            32 * PDATA(pgm)->sck_period + delay  // each byte gets turned into a
                                 // 4-byte SPI cmd  usb_out() multiplies
                                 // this per byte. Then add the cmd-delay
            ) < 0) {
  return -1;

To be clear, these two functions have the same name but are in fact two different functions; the former running in the programmer the later is running in avrdude.

So there is in fact substantial SPI transaction overhead in just delivering data into the page buffer. Beyond that there's a second USB and SPI transaction to commit the page buffer to flash.

  • Great info, thank you. I looked into my output and found: "avrdude: Using SCK period of 10 usec" So it appears to be set to the default of 10uS. – cody blanchard Nov 26 '20 at 5:23
  • I went into the avrdude.conf file and changed the "default_bitclock" value to 1. Code now uploads in 10 seconds and executes fine on the chip. This is a 66% improvement but still seems like it ought to upload faster based on the math. – cody blanchard Nov 26 '20 at 5:32
  • Or.... maybe this is about right. If we're estimating about 3.5 seconds of spi data and the bitclock is set to pause for 2uS for each bit ... if each bit took about 1uS to write wouldn't that approximately triple the total time it takes? Although I have no idea how much time it actually is taking to write one bit... – cody blanchard Nov 26 '20 at 5:52
  • @codyblanchard, see expanded findings. The "the plain clocking of the SPI data" probably should have been written to say "of the program data". What I was trying to do (and probably failing at) was being conservative in saying rough 3.7 seconds for the irreducible (barring compression) SPI timing associated with program data itself. Beyond what I've just mentioned in the update, I'm sure there are more delays. Though they'll probably be diminishing returns. – timemage Nov 26 '20 at 13:38

I have a description of the uploading process which, if you extrapolate out from the 1082 bytes being uploaded in about 0.15 seconds (plus some overhead) should mean that you would get 23032 bytes uploaded in 23032 / 1082 * 0.15 seconds, namely about 3 seconds, including verification.

The fact that you are not achieving that would suggest (as Gil mentioned in their answer) that there is a problem with your PC actually sending data that fast down the USB port.

If you were to hook up a logic analyzer and watch what actually arrives, then you might find that there are bigger gaps between bytes (or batches of bytes) than you would expect.


It sounds like the bandwidth is limited. I have no idea how much delay the ISP is adding but it has to add some. The best would be via the USB at 115200 baud or faster if you can get it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.