IDE downloading question

I've been trying to understand the downloading protocol that the IDE uses to
talk to the bootloader. In the bootloader source, there are statements like
the following for transmitting a block of data bytes:

	/* Write memory, length is big endian and is in bytes  */
	else if(ch=='d') {
	    length.byte[1] = getch();
	    length.byte[0] = getch();
	    flags.eeprom = 0;
	    if (getch() == 'E') flags.eeprom = 1;
	    for (w=0;w<length.word;w++) {
		buff[w] = getch();	     // Store data in buffer, 
can't keep up with serial data stream whilst programming pages
	    }

I notice that buff[] size = 256 bytes. How can I find out how many bytes the IDE
actually sends over in each block? IE, the values of
length.byte[1] = getch();
length.byte[0] = getch();

As suggested earlier, you could look at the stk500 protocol.

You could also look at the source code for avrdude to see an implementation.

Abandon all hope

Well I've just wasted 3 days trying to find out one simple thing = how many
bytes are in the data blocks the IDE downloader sends over to the bootloader
in each packet when burning a sketch in Flash, but the answer appears to be
buried under level upon level of obfuscation. Doesn't anybody know this ????

  1. I've looked at the STK500 communications protocol in appnote AVR068, but
    clearly the bootloader doesn't actually use it.

  2. anaysis of the source code of 2 bootloaders indicates, at best, they
    use mainly the STK500 #defines, such as STK_SET_PARAMETER, but not the
    actual packet protocol.

  3. I've also looked at the source code for avrdude, but that's just about
    indecipherable, AFAIAC. From the best I can tell, avrdude must load in
    some config files that actually tell it what to do for different AVR
    chips, and then this info is probably in some kind of coded format.

  4. I also wrote a sketch to run on a 2nd Arduino chip that captures the
    RS232 comms from the IDE to the bootloader [simple IDE "Blink" example
    was captured below], but cannot really rationalize the data captured
    with what the bootloader seems to expect to be receiving, so ????

The capture sketch simply dumps the incoming data into a char buffer, and
I should think the Arduino should be fast enough to receive at 57600
without dropping characters.

Plus, I can't even see in the bootloader code where it expects a 0x84 and
answers with a 'K', on startup.

I'm stumped.

In following, a '.' was inserted in the buffer every 10-msec, printable
chars are shown as 1-column ASCII, eg '@' or 'R', and nonprintable as
their Hex value, eg 84 = 0x84 and F4 = 0xF4.

Buffer Dump ... RX line
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  . 84  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  . 84  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  . 84  . 00 F4  .  . 90 FF  . 20 00 00 00 FC 0F 08
 00 00 80  .  . 01  H 86 FF  . 80  .  . A1  .  . 83 F4 F4  .
 83 FC F4  .  . 83 F4 F4  . 81 FC F4  .  . 00 80  . 04  ( 02
 02  X  .  @ EB  @ E9  @ EB  @ E8  @ EB  @ E9  @ E8  @ EB  @ <-- '@' = set_parameter
 E9  @ E8  @ E8  @ E8  @ EB  @ E9  @  h  @ E9  @ E9  @ E8  @
 EB  @ EB  @ E9  @ E9  @ E9  @ E9 00 00 80 A0 E0 00 00 80 C0
 E0 00  . 00 80  .  . 00 F4  . 05  ( 85 01 A0 01 01 01  !  ! <-- '!!!' = monitor cmds
  !  ! 8C 8C 8C 94  R  .  1 10 12 10 00 02 04 00 01 00 00 94 <-- 'R' = chip_erase
 02 00 00 00  @ BC  o B1 F7 C1  q AC 8C  , 08  H 88 84  R C0 <-- 'q' = read_data
 8C 0C  H CA 84  ` 03 0E 03  @ 08 80  .  . 10 F4  .  . 04  (
 8A 84 03 0A E4 C7 0C  l A8  @ 8C  l  I  ` C7 0C  l A9  @ A4 <-- '`' = prog_flash
 C2  .  X 80  4 9E 9E  ' 01  f 9D AF AF BD BD  ! 01 08 00 14
 C0 15  @  $ 00  1  0 97 CE A6 84 FE 89  0 90 09  ( 01  ( 00 <-- '@' = set_parameter
 FF  .  . 80 F4  .  . 05  (  , 01  , 01 08 00 08 00 15 C0 14
 00  1  3 A1 01  ( 00  , 00  , 8C F4 B5 B5  t  t  4 8D D2  ! <-- 't' = read_page
 A1 01  . E0 0E 08 00 0A 00  + C0 15  P  a 01 E7 C1 90  &  & <-- 'P' = enter_progmode,
							     <-- 'a' = prog_data
 DE E2 E8 E0 E5  %  &  ' C6 FF  .  . 00 F4  .  . 04  (  j  5
 BD 1D A1 0F F0 CD 08 05 80 04 C0 14 C0 15 D0  n  @  G 0E 8B
  3 BD EE  v 1D  O CF 09  1  5  j  5 BF  = A1  i 0D FB 01 F1
  8  0  . 00 C0 C0 83 80 00 00 20 02 06 89 89 C8 88 F4  .  .
 00 80  . 04  (  D  r  .  b C4  r  b 04 AF 8C 08  D CC 8C  " <-- 'r' = read_fuse
 08 89  ( 08  D C4 8C 08  D 89  s 08 88  ( EC 8C 08  D C4  c
 08 88  ( 08 89  ( 08  D 84 84 C3 20 04  ^  L  l 90 0D  @  4
  . E3  @  .  . 08 F4  . 04  ( 09 AA C4  8  m  8 CC  1 95 B2
  5  .  H 88  J 94 BE E1 AF 0E 0A E8  *  ?  \  N  l 90 B0 FB
 05 08  ) 0D 80  4 18 F2 05 8D C0 A8 EC  W  : 85 86  B C6 A4
 C0 A1  i F9  i 8C  D 8C  .  . 00  @  .  . 05  ( 01 08 08 FD
 08 85 CB  ( 08 00 89  } 08 7F  r  b C4 FD 08 C5  ~ A6 9E EC
 FE  =  o  C  .  t B9 95 A3 0A 08 AA 00 09  u D5  / AF AD 0D
 1D 03 02 0C  l 08 80  b 97 01 B7 89  .  . 00 81  .  . 05 20
 C3  .  . 00 F4  . 04  ( F4  .  .  . 00 F4  . 05  ( F4  .  .
  . 80 F4  . 04  ( F4  .  .  . 80 F4  .  . 05  ( F4  .  . 00
 F4  .  . 07  ( F4  .  .  . 00 F4  . 04  ( F4  .  .  . 08 F4
  .  . 04  ( F4  .  . 20 F4  .  . 05  ( F4  .  .  . 00 81  .
 04  ! F4  .  .  @  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .


Buffer Dump ... TX line
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  K  .  .  .  .  .  .  .  .  .  .  . <-- 'K' = 0x4B
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  K
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  K  . 1B FA  . 1B FA  .  .  K
  .  .  K  .  K  .  .  k  ' FF  . 0B FA  .  . 0B FA  .  . 0B
 FA  . 0B FA  .  .  K  .  . FB  . FA  .  .  K  .  . FB  . FA
  .  K  .  .  . FB FA  .  .  K  .  .  . FB FA  .  .  K  .  .
  . FB FA  .  .  K  .  . FB  . FA  .  K  .  .  . FB  . FA  .
  K  .  .  . FB FA  .  .  K  .  . FB FA  .  K  .  .  + 9B  (
 EB  ( EB  ( EB  ( EB  ( EB  ( EB  ( EB  ( EB  ( EB  ( EB  (
 EB  ( EB  ( EB  ( EB  ( EB  (  K  ( EB  ( EB  ( EB  ( EB  (
  . EB  ( EB  ( EB  ( EB  ( EB 08 08  (  8 08 08 08  8 08 18
 08 08  H  .  K  .  . 1B  ( 18  (  )  )  ) 09 08 08 18 08 08
 00 00 00 00 84  B  a  (  H 08 08  B 84 00  B  . 08 08 08 95
 ED 8E 7F  =  1  \ 8C EC 0C  <  : 0A  Z F6 C5  \ 1C  | 1A  Z
 E6  i 1E  i 94  ! FA  .  .  K  .  ; 9C  ,  k C4  a  L  , 8B
  8 8C  ,  .  k C4  a  L  , 8B 08  ' C6 A0 84  /  ' A7  $ E5
 D2 D2  Z  z  z  B  e  Z  F 95 A4 9D A4 85 8C E3 EB E3 CC 0A
 98 02 1B EB  a  a  X 19  Z  F FF  .  .  K  .  . 0B 0A  Z  F
 85 A4 8D 84 85 A4 8D 8C E3 EB  a  a  Z 8C 0A  Z 00 9D BD 9D
 BD 9D 9D A7 A0  )  o A3 FC  n  X 18  Z 8C 85 A4 8D D4  X E2
 04 B4 BC BD  .  : 9C  ' CA 20 E3 EB  1 FA  .  K  .  . 0B A8
 E1 EB F1 FB 1B D0  n  X 18  Z 8C 85 A4 8D D4  X E2 04 B4 BC
 BD  : 9C  ' CA 20 E3 EB  1  8  . BD EB F1 FB  Y  #  _ 8C 1E
  N 8C CC 8C F7 10 EB 9E 9F F7 20  + 88  y  y FA  .  .  K  .
 1B  ,  ^  < DE  < AD 8E 18 C4  b 8E 0A 18 88 18  . 18 C4  b
 8E 18 C4  b 8E 18 89 18 9C 8E 18 C4  z  s 18 89 18 18 88 18
 18 C4  B 88 18  J 86 20 1C 8C 94 B7 94 C5  < FA  .  .  K  .
  +  . 85  A  < 8E  =  q  0  m  u 00  /  + 85  a  T  / EF  n
  Y 18  Y  / F1 00 1C F8 B7 94 C5 94 B7 B4 C5  <  [  )  0 0C
 01  !  . 0A 1F 1A 0E  Z 8B  I E5 D2  .  . DA  O  .  K  .  .
  + 0C 85  5 0C 85 19  B 8A  y 95  , 19 C4 A5 95 0C A5 19  b
  ; AC BC  5  0  m E7  n 1D F4  !  o 09  Y  . 8C A5 9E  w 7F
 A5  k  i  ! CC  , 0B 08  s  i 08 DF  K  .  .  K  . FB C1  .
  .  K  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

blocksize = 4;

from hardware/tools/avrdude.conf, under m328p
EDIT: That's for EEPROM. For flash:

	blocksize	= 128;
	readsize	= 256;

Did you see this?
http://www.atmel.com/Images/doc2591.pdf

This page says that the arduino bootloader implements stk500 about halfway down:
http://www.sparkfun.com/tutorials/142
You've said that it's clear it doesn't, but you haven't said why. It doesn't implement everything, but the protocol for what it does implement do work.

You could also try asking on the avrfreaks forum.

Why do you want to know this?

oric_dan(333):
I notice that buff[] size = 256 bytes. How can I find out how many bytes the IDE
actually sends over in each block? IE, the values of

  length.byte[1] = getch();

length.byte[0] = getch();

The simplest thing would be to go into verbose mode, then you see the bytes that are being sent. Like this:

avrdude: Version 5.11, compiled on Sep  2 2011 at 18:52:52
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino_1.0.1.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/nick/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/tty.usbmodemfa1421
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: Send: 0 [30]   [20] 
avrdude: Send: 0 [30]   [20] 
avrdude: Send: 0 [30]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
avrdude: Send: A [41] . [80]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [03] 
avrdude: Recv: . [10] 

...

avrdude: Recv: . [14] 
avrdude: Recv: . [00] 
avrdude: Recv: . [10] 
avrdude: reading input file "/var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build6634746716421938216.tmp/Blink.cpp.hex"
avrdude: writing flash (1084 bytes):

Writing | avrdude: Send: U [55] . [00] . [00]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: Send: d [64] . [00] . [80] F [46] . [0c] . [94] a [61] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] . [9d] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [0c] . [94] ~ [7e] . [00] . [00] . [00] . [00] . [00] $ [24] . [00] ' [27] . [00] * [2a] . [00] . [00] . [00] . [00] . [00] % [25] . [00] ( [28] . [00] + [2b] . [00] . [00] . [00] . [00] . [00]   [20] 

...

avrdude: Recv: . [10] 
######avrdude: Send: U [55] . [00] . [02]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: Send: t [74] . [00] < [3c] F [46]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [f8] . [94] f [66] # [23] ! [21] . [f4] . [8c] . [91] . [90] . [95] . [89] # [23] . [02] . [c0] . [8c] . [91] . [89] + [2b] . [8c] . [93] / [2f] . [bf] . [08] . [95] . [cf] . [93] . [df] . [93] . [0e] . [94] > [3e] . [01] . [0e] . [94] . [97] . [00] . [c0] . [e0] . [d0] . [e0] . [0e] . [94] . [80] . [00]   [20] . [97] . [e1] . [f3] . [0e] . [94] . [00] . [00] . [f9] . [cf] . [f8] . [94] . [ff] . [cf] . [0d] . [00] 
avrdude: Recv: . [10] 
### | 100% 0.14s

avrdude: verifying ...
avrdude: 1084 bytes of flash verified
avrdude: Send: Q [51]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 

avrdude done.  Thank you.

Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack


flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff

Great, thanks, Nick. It helps to know where to look!
Although I'm a little surprised the value is so big = 128, see next post.

hardware/tools/avrdude.conf

Did you see this?
http://www.atmel.com/Images/doc2591.pdf

Thanks, I figured it was in some config file somewheres.

That pdf file is the AVR068 appnote I mentioned last time.

Why do you want to know this?

I have some XBee modules and want to experiment with wireless downloading.

NOTE - I have read the various tutorials on this from Adafruit, Sparkfun, etc,
but they only say how to setup XBee for their own particular breakout boards,
and NOT what the protocol actually is.

The problem is that XBees have a limited size holding buffer, so there can potentially
be a problem if the transmit block sizes are too long. I realize the guys mentioned
are able to do it, but I want to understand what's really going on.

This page says that the arduino bootloader implements stk500 about halfway down:
Notes on the STK500 Serial Bootloader - SparkFun Electronics
You've said that it's clear it doesn't, but you haven't said why. It doesn't implement everything, but the protocol for what it does implement do work.

As I mentioned, from looking at the actual bootloader code. I edited out the setup
code, but the forever loop clearly doesn't look for STK500 packet headers, only
for the individual codes, eg STK_GET_PARAMETER, etc.

BOOTLOADER:

/* main program starts here */
int main(void) {
  uint8_t ch;

----- setup stuff edited out --------

  /* Forever loop */
  for (;;) {
    /* get character from UART */
    ch = getch();

    if(ch == STK_GET_PARAMETER) {
      unsigned char which = getch();
      verifySpace();
      if (which == 0x82) {
	/*
	 * Send optiboot version as "minor SW version"
	 */
		putch(OPTIBOOT_MINVER);
      } else if (which == 0x81) {
	  putch(OPTIBOOT_MAJVER);
      } else {
	/*
	 * GET PARAMETER returns a generic 0x03 reply for
         * other parameters - enough to keep Avrdude happy
	 */
	putch(0x03);
      }
    }
    else if(ch == STK_SET_DEVICE) {
      // SET DEVICE is ignored
      getNch(20);
    }
    else if(ch == STK_SET_DEVICE_EXT) {
      // SET DEVICE EXT is ignored
      getNch(5);
    }
    else if(ch == STK_LOAD_ADDRESS) {
      // LOAD ADDRESS
      uint16_t newAddress;
      newAddress = getch();
      newAddress = (newAddress & 0xff) | (getch() << 8);

#ifdef RAMPZ
      // Transfer top bit to RAMPZ
      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif

      newAddress += newAddress; // Convert from word address to byte address
      address = newAddress;
      verifySpace();
    }
    else if(ch == STK_UNIVERSAL) {
      // UNIVERSAL command is ignored
      getNch(4);
      putch(0x00);
    }
    /* Write memory, length is big endian and is in bytes */
    else if(ch == STK_PROG_PAGE) {
      // PROGRAM PAGE - we support flash programming only, not EEPROM
      uint8_t *bufPtr;
      uint16_t addrPtr;

      getch();			/* getlen() */
      length = getch();
      getch();

      // If we are in RWW section, immediately start page erase
      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);

      // While that is going on, read in page contents
      bufPtr = buff;
      do *bufPtr++ = getch();
      while (--length);

      // If we are in NRWW section, page erase has to be delayed until now.
      // Todo: Take RAMPZ into account
      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);

      // Read command terminator, start reply
      verifySpace();

      // If only a partial page is to be programmed, the erase might not be complete.
      // So check that here
      boot_spm_busy_wait();

#ifdef VIRTUAL_BOOT_PARTITION
      if ((uint16_t)(void*)address == 0) {
        // This is the reset vector page. We need to live-patch the code so the
        // bootloader runs.
        //
        // Move RESET vector to WDT vector
        uint16_t vect = buff[0] | (buff[1]<<8);
        rstVect = vect;
        wdtVect = buff[8] | (buff[9]<<8);
        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
        buff[8] = vect & 0xff;
        buff[9] = vect >> 8;

        // Add jump to bootloader at RESET vector
        buff[0] = 0x7f;
        buff[1] = 0xce; // rjmp 0x1d00 instruction
      }
#endif

      // Copy buffer into programming buffer
      bufPtr = buff;
      addrPtr = (uint16_t)(void*)address;
      ch = SPM_PAGESIZE / 2;
      do {
        uint16_t a;
        a = *bufPtr++;
        a |= (*bufPtr++) << 8;
        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
        addrPtr += 2;
      } while (--ch);

      // Write from programming buffer
      __boot_page_write_short((uint16_t)(void*)address);
      boot_spm_busy_wait();

#if defined(RWWSRE)
      // Reenable read access to flash
      boot_rww_enable();
#endif

    }
    /* Read memory block mode, length is big endian.  */
    else if(ch == STK_READ_PAGE) {
      // READ PAGE - we only read flash
      getch();			/* getlen() */
      length = getch();
      getch();

      verifySpace();

#ifdef VIRTUAL_BOOT_PARTITION
      do {
        // Undo vector patch in bottom page so verify passes
        if (address == 0)       ch=rstVect & 0xff;
        else if (address == 1)  ch=rstVect >> 8;
        else if (address == 8)  ch=wdtVect & 0xff;
        else if (address == 9) ch=wdtVect >> 8;
        else ch = pgm_read_byte_near(address);
        address++;
        putch(ch);
      } while (--length);
#else
      do putch(pgm_read_byte_near(address++));
      while (--length);
#endif
    }

    /* Get device signature bytes  */
    else if(ch == STK_READ_SIGN) {
      // READ SIGN - return what Avrdude wants to hear
      verifySpace();
      putch(SIGNATURE_0);
      putch(SIGNATURE_1);
      putch(SIGNATURE_2);
    }
    else if (ch == 'Q') {
      // Adaboot no-wait mod
      watchdogConfig(WATCHDOG_16MS);
      verifySpace();
    }
    else {
      // This covers the response to commands like STK_ENTER_PROGMODE
      verifySpace();
    }
    putch(STK_OK);
  }
}

From what I've seen of the bootloader, it looks for a subset of the codes, the subset that actually gets sent.

oric_dan(333):
Although I'm a little surprised the value is so big = 128, see next post.

That's the flash page size. It doesn't necessarily send that many bytes. More likely it would read the .hex file and send a "line" (16 bytes) but don't quote me on that.

That's the flash page size. It doesn't necessarily send that many bytes. More likely it would read the .hex file and send a "line" (16 bytes) but don't quote me on that.

That's what I was hoping for. Makes sense to send a line or 2 from the .hex file, burn
it into the Flash, and then send back an acknowledge. But really sounds like no one
knows for sure, except maybe 2 guys in the world, LOL.

I'll try maybe rationalizing the info from the verbose-mode windows with the
download-capture stuff I show above. I'll first rewrite the capture stuff for my
PIC24 chip which is so fast I'm sure won't miss any data. Thanks a load.

Can't you tell from the avrdude output? eg.

######avrdude: Send: U [55] . [80] . [01]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10] 
avrdude: Send: d [64] . [00] . [80] F [46] . [fc] . [01] 4 [34] . [91] J [4a] W [57] _ [5f] O [4f] . [fa] . [01] . [84] . [91] . [88] # [23] i [69] . [f1] . [90] . [e0] . [88] . [0f] . [99] . [1f] . [fc] . [01] . [e8] Y [59] . [ff] O [4f] . [a5] . [91] . [b4] . [91] . [fc] . [01] . [ee] X [58] . [ff] O [4f] . [c5] . [91] . [d4] . [91] f [66] # [23] Q [51] . [f4] / [2f] . [b7] . [f8] . [94] . [8c] . [91] . [93] / [2f] . [90] . [95] . [89] # [23] . [8c] . [93] . [88] . [81] . [89] # [23] . [0b] . [c0] b [62] 0 [30] a [61] . [f4] / [2f] . [b7] . [f8] . [94] . [8c] . [91] . [93] / [2f] . [90] . [95] . [89] # [23] . [8c] . [93] . [88] . [81] . [83] + [2b] . [88] . [83] / [2f] . [bf] . [06] . [c0] . [9f] . [b7] . [f8] . [94] . [8c] . [91] . [83] + [2b] . [8c] . [93] . [9f] . [bf] . [df] . [91] . [cf] . [91] . [08] . [95] H [48] / [2f] P [50] . [e0] . [ca] . [01] . [82] U [55] . [9f] O [4f] . [fc] . [01] $ [24] . [91] . [ca] . [01]   [20] 
avrdude: Recv: . [14] 
avrdude: Recv: . [10]

It looks to me like it is sending an address, followed by some data. The first byte is 64, so I guess that is the length. It is followed by 132 hex bytes, so I guess the length is in words, not bytes.

Actually that is hex 64, so it is more likely:

#define STK_PROG_PAGE       0x64  // 'd'

So, sends a page of stuff.

Yeah, that looks good. Per the protocol in the bootloader source, 'd' = 0x64 =
STK_PROG_PAGE, and the next 2 bytes are the length of the data block.
Unfortunately, 0x00, 0x80 = 128 bytes. Darn, not small like 16. Also,

U = STK_LOAD_ADDRESS --> 0x0120 [big endian].
0x14 = STK_INSYNC signal.
0x10 = STK_OK signal.

Well, a little progress at last.

There are two versions of protocol called stk500. The version in avr068 is "version 2", which adds the packet protocol you are not seeing (and is used on the arduino Mega.)
Version 1 of the protocol (or rather, a subset of it) is used on the smaller Arduinos, and is described in avr061...

The bootloader will break badly if the page size downloaded does not match the native flash page size of the chip. If there is insufficient intermediate buffering, you can send smaller bursts; stk500v1 has no inter-character or block timeout other than the one second bootloader timeout. (so you do have to send the data faster than one byte per second.)

The bootloader will break badly if the page size downloaded does not match the native flash page size of the chip. If there is insufficient intermediate buffering, you can send smaller bursts; stk500v1 has no inter-character or block timeout other than the one second bootloader timeout. (so you do have to send the data faster than one byte per second.)

Thanks for the info. I was trying to get enough info to determine whether the
Arduino IDE downloader [avrdude] could be used directly with the XBee transceivers
for wireless programming. The TX holding buffer in the XBees is only 100 bytes,
so there can possibly be a problem with dropped data if the transfer size is 256 bytes,
and the transmission utility does not pace properly.

May require writing a separate downloader utility that can properly pace smaller
bursts, as you indicate.

The Fio board allows use of Xbee for wireless sketch downloads.
Have you looked at this page?

The Fio board allows use of Xbee for wireless sketch downloads.
Have you looked at this page?
http://arduino.cc/en/Main/ArduinoBoardFioProgramming

Thanks, I had not seen that. It does look very similar to the Adafruit tutorial on
same, and neither of them really describes the comms protocol, but only how
to configure the breakout boards. I'd still like to understand how it actually
works. :slight_smile: But pretty soon, I've probably just have to go ahead and do it, and
not worry about the nuts'n'bolts.