I'm attempting to use the arduino as an ICSP AVR to flash hundreds of ATMEGA's 90USB162. I'm having some difficulties when trying to do the actual flashing of the chip. I've go all the wires done properly and I'm able to read the signature. My source is an Intel hex file and I'm reading it properly as I'm able to see each by as it is read from the arduino's memory. Where I'm getting lost is the documentation states that I need to set the low byte first before I set the high byte for the same memory address. Using the following as an example (underscores to break the data up) could someone help me descern what my SPI transaction bytes would look like?


I know the colon is the start code, 20 is the hex value of number of data bytes, 0000 is the address, 00 is the record type, the next 32 bytes is my data followed by the checksum.

I thought that I would loop over the data portion and increment the address every other byte

uint16_t addr = 0;

while (recordtype != endOfFile)
  auto data[] = parseData();

  for(uint8_t index = 0; index < 32;)
    SPITask.Send(0x40, 0x00, addr, data[index++]);//send low byte
    SPITask.Send(0x48, 0x00, addr, data[index++]);//send high byte
    SPITask.Send(0x4C, addr, addr, 0x00);//commit new bytes to address

I don't think this is right and some examples i'm loosely following comment that they are changing the address byte into a word, which makes some sense based on the command layouts of the data sheet (page 260) 90USB162 Data sheet. Can anyone please provide some guidance in how to break up this data into high and low bytes.

1 Answer 1


I have some code that does exactly what you want on GitHub.

Amongst other processors, it supports the At90USB162 chip. The code reads from an SD card in Intel hex format and writes to the chip at the press of a switch. This effectively is what you are trying to do.

Arduino forum moderator "Crossroads" (who has recently also joined Stack Exchange) has made a board to do the programming, hold the SD card, and have some status LEDs:

Board programmer

Here is my code to write to the flash:

// execute one programming instruction ... b1 is command, b2, b3, b4 are arguments
//  processor may return a result on the 4th transfer, this is returned.
byte program (const byte b1, const byte b2 = 0, const byte b3 = 0, const byte b4 = 0)
  noInterrupts ();
  BB_SPITransfer (b1);  
  BB_SPITransfer (b2);  
  BB_SPITransfer (b3);  
  byte b = BB_SPITransfer (b4);  
  interrupts ();
  return b;
  } // end of program

// write a byte to the flash memory buffer (ready for committing)
void writeFlash (unsigned long addr, const byte data)
  byte high = (addr & 1) ? 0x08 : 0;  // set if high byte wanted
  addr >>= 1;  // turn into word address
  program (loadProgramMemory | high, 0, lowByte (addr), data);
  } // end of writeFlash  

Your loop looks a bit strange, the page size (before you need to commit) is 128 bytes (64 bytes), not 2 bytes.

See the datasheet:

Flash page size

  • Are these boards available for purchase anywhere?
    – xtreampb
    Mar 2, 2018 at 13:59
  • Yes, boards are available as noted. I accept payment via paypal and can have one in the mail for you tomorrow. Send me e-mail at [email protected].
    – CrossRoads
    Mar 2, 2018 at 18:25
  • (xtreampb said in a comment under a now-deleted answer): I don't see where it also will flash the EEPROM of the target which is something I also desire with my final product - however this is not mentioned anywhere in the question.
    – Nick Gammon
    Mar 3, 2018 at 2:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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