I had this weird idea yesterday of building an Atmega328 bootloader burner/sketch uploader using an Atmega328
The idea is to have a board that using a socket flashes the EEPROM of the plugged atmega with the hexfile+sketch and sets the fuses.
You can change the bootloader sketch and fused on the programmer using and SDCard or a bigger memory on the board itself and USB.
Do you think is possible to use a modified version of the ISP sketch to create a "Plug&Burn" experience?
I am going to dig more the avrdude source code and see.
I could even use 2 different Atmega, 1 for bootburning and 1 for sketchuploading
There does not seem to be a "page erase" command available in the SPI programming mode. Hence the chip must be completely erased before programming. During bootloader programming the bootloader can erase pages, which it has to do before re-writing to them.
If you are worried about the bootloader being erased, then you could modify my uploading sketch to not only upload your code, but also the bootloader (eg. from a different file). Then the fuses would need to be set to jump to the bootloader.
I don't totally see the point for day-to-day operations. If you are using the SPI programming, who cares if you have a bootloader? And if you have the bootloader you don't need the SPI programming.
I understand that having SPI and a bootloader is redundant, but the goal is to burn the bootloader with a test sketch and then use my DuemilaNove to program them. Also other than being cool, I need to flash something like 100 units and this is going to save me time.
I still want to be able to use the IDE to program my custom board, so I prefer to keep the bootloader.
Also can you explain this?
// bit banged SPI pins
#ifdef __AVR_ATmega2560__
 // Atmega2560
 const byte MSPIM_SCK = 4; // port G bit 5
 const byte MSPIM_SS = 5; // port E bit 3
 const byte BB_MISO = 6; // port H bit 3
 const byte BB_MOSI = 7; // port H bit 4
#else
 // Atmega328
 const byte MSPIM_SCK = 4; // port D bit 4
 const byte MSPIM_SS = 5; // port D bit 5
 const byte BB_MISO = 6; // port D bit 6
 const byte BB_MOSI = 7; // port D bit 7
#endif
I am going to refactor your code a bit, just to make it more API/third party friendly, decoupling the actual file reading from the programming.
It's documentation mainly. Further down they are different:
// for fast port access
#ifdef __AVR_ATmega2560__
 // Atmega2560
 #define BB_MISO_PORT PINH
 #define BB_MOSI_PORT PORTH
 #define BB_SCK_PORT PORTG
 const byte BB_SCK_BIT = 5;
 const byte BB_MISO_BIT = 3;
 const byte BB_MOSI_BIT = 4;
#else
 // Atmega328
 #define BB_MISO_PORT PIND
 #define BB_MOSI_PORT PORTD
 #define BB_SCK_PORT PORTD
 const byte BB_SCK_BIT = 4;
 const byte BB_MISO_BIT = 6;
 const byte BB_MOSI_BIT = 7;
#endif