Added bootloader files and the programming commands

including the script which sets the correct fuses
currently working only on mac os x but easy to port
to windows/linux
This commit is contained in:
Massimo Banzi 2005-09-14 17:04:31 +00:00
parent 5432861f2a
commit 15ae9ab1b0
9 changed files with 828 additions and 300 deletions

View File

@ -1,300 +0,0 @@
/*
// make sure the user didn't hide the sketch folder
ensureExistence();
zipFileContents = new Hashtable();
// nuke the old applet folder because it can cause trouble
File appletFolder = new File(folder, "applet");
Base.removeDir(appletFolder);
appletFolder.mkdirs();
// build the sketch
String foundName = build(appletFolder.getPath(), name);
// (already reported) error during export, exit this function
if (foundName == null) return false;
// if name != exportSketchName, then that's weirdness
// BUG unfortunately, that can also be a bug in the preproc :(
if (!name.equals(foundName)) {
Base.showWarning("Error during export",
"Sketch name is " + name + " but the sketch\n" +
"name in the code was " + foundName, null);
return false;
}
int wide = PApplet.DEFAULT_WIDTH;
int high = PApplet.DEFAULT_HEIGHT;
PatternMatcher matcher = new Perl5Matcher();
PatternCompiler compiler = new Perl5Compiler();
// this matches against any uses of the size() function,
// whether they contain numbers of variables or whatever.
// this way, no warning is shown if size() isn't actually
// used in the applet, which is the case especially for
// beginners that are cutting/pasting from the reference.
// modified for 83 to match size(XXX, ddd so that it'll
// properly handle size(200, 200) and size(200, 200, P3D)
String sizing =
"[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)";
Pattern pattern = compiler.compile(sizing);
// adds a space at the beginning, in case size() is the very
// first thing in the program (very common), since the regexp
// needs to check for things in front of it.
PatternMatcherInput input =
new PatternMatcherInput(" " + code[0].program);
if (matcher.contains(input, pattern)) {
MatchResult result = matcher.getMatch();
try {
wide = Integer.parseInt(result.group(1).toString());
high = Integer.parseInt(result.group(2).toString());
} catch (NumberFormatException e) {
// found a reference to size, but it didn't
// seem to contain numbers
final String message =
"The size of this applet could not automatically be\n" +
"determined from your code. You'll have to edit the\n" +
"HTML file to set the size of the applet.";
Base.showWarning("Could not find applet size", message, null);
}
} // else no size() command found
// originally tried to grab this with a regexp matcher,
// but it wouldn't span over multiple lines for the match.
// this could prolly be forced, but since that's the case
// better just to parse by hand.
StringBuffer dbuffer = new StringBuffer();
String lines[] = PApplet.split(code[0].program, '\n');
for (int i = 0; i < lines.length; i++) {
if (lines[i].trim().startsWith("/**")) { // this is our comment
// some smartass put the whole thing on the same line
//if (lines[j].indexOf("*/") != -1) break;
for (int j = i+1; j < lines.length; j++) {
if (lines[j].trim().endsWith("*/")) {
// remove the */ from the end, and any extra *s
// in case there's also content on this line
// nah, don't bother.. make them use the three lines
break;
}
int offset = 0;
while ((offset < lines[j].length()) &&
((lines[j].charAt(offset) == '*') ||
(lines[j].charAt(offset) == ' '))) {
offset++;
}
// insert the return into the html to help w/ line breaks
dbuffer.append(lines[j].substring(offset) + "\n");
}
}
}
String description = dbuffer.toString();
StringBuffer sources = new StringBuffer();
for (int i = 0; i < codeCount; i++) {
sources.append("<a href=\"" + code[i].file.getName() + "\">" +
code[i].name + "</a> ");
}
File htmlOutputFile = new File(appletFolder, "index.html");
FileOutputStream fos = new FileOutputStream(htmlOutputFile);
PrintStream ps = new PrintStream(fos);
// @@sketch@@, @@width@@, @@height@@, @@archive@@, @@source@@
// and now @@description@@
InputStream is = null;
// if there is an applet.html file in the sketch folder, use that
File customHtml = new File(folder, "applet.html");
if (customHtml.exists()) {
is = new FileInputStream(customHtml);
}
if (is == null) {
is = Base.getStream("applet.html");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
if (line.indexOf("@@") != -1) {
StringBuffer sb = new StringBuffer(line);
int index = 0;
while ((index = sb.indexOf("@@sketch@@")) != -1) {
sb.replace(index, index + "@@sketch@@".length(),
name);
}
while ((index = sb.indexOf("@@source@@")) != -1) {
sb.replace(index, index + "@@source@@".length(),
sources.toString());
}
while ((index = sb.indexOf("@@archive@@")) != -1) {
sb.replace(index, index + "@@archive@@".length(),
name + ".jar");
}
while ((index = sb.indexOf("@@width@@")) != -1) {
sb.replace(index, index + "@@width@@".length(),
String.valueOf(wide));
}
while ((index = sb.indexOf("@@height@@")) != -1) {
sb.replace(index, index + "@@height@@".length(),
String.valueOf(high));
}
while ((index = sb.indexOf("@@description@@")) != -1) {
sb.replace(index, index + "@@description@@".length(),
description);
}
line = sb.toString();
}
ps.println(line);
}
reader.close();
ps.flush();
ps.close();
// copy the loading gif to the applet
String LOADING_IMAGE = "loading.gif";
File loadingImage = new File(folder, LOADING_IMAGE);
if (!loadingImage.exists()) {
loadingImage = new File("lib", LOADING_IMAGE);
}
Base.copyFile(loadingImage, new File(appletFolder, LOADING_IMAGE));
// copy the source files to the target, since we like
// to encourage people to share their code
for (int i = 0; i < codeCount; i++) {
try {
Base.copyFile(code[i].file,
new File(appletFolder, code[i].file.getName()));
} catch (IOException e) {
e.printStackTrace();
}
}
// create new .jar file
FileOutputStream zipOutputFile =
new FileOutputStream(new File(appletFolder, name + ".jar"));
ZipOutputStream zos = new ZipOutputStream(zipOutputFile);
ZipEntry entry;
// add the manifest file
addManifest(zos);
// add the contents of the code folder to the jar
// unpacks all jar files
//File codeFolder = new File(folder, "code");
if (codeFolder.exists()) {
String includes = Compiler.contentsToClassPath(codeFolder);
packClassPathIntoZipFile(includes, zos);
}
// add contents of 'library' folders to the jar file
// if a file called 'export.txt' is in there, it contains
// a list of the files that should be exported.
// otherwise, all files are exported.
Enumeration en = importedLibraries.elements();
while (en.hasMoreElements()) {
// in the list is a File object that points the
// library sketch's "library" folder
File libraryFolder = (File)en.nextElement();
File exportSettings = new File(libraryFolder, "export.txt");
String exportList[] = null;
if (exportSettings.exists()) {
String info[] = Base.loadStrings(exportSettings);
for (int i = 0; i < info.length; i++) {
if (info[i].startsWith("applet")) {
int idx = info[i].indexOf('='); // get applet= or applet =
String commas = info[i].substring(idx+1).trim();
exportList = PApplet.split(commas, ", ");
}
}
} else {
exportList = libraryFolder.list();
}
for (int i = 0; i < exportList.length; i++) {
if (exportList[i].equals(".") ||
exportList[i].equals("..")) continue;
exportList[i] = PApplet.trim(exportList[i]);
if (exportList[i].equals("")) continue;
File exportFile = new File(libraryFolder, exportList[i]);
if (!exportFile.exists()) {
System.err.println("File " + exportList[i] + " does not exist");
} else if (exportFile.isDirectory()) {
System.err.println("Ignoring sub-folder \"" + exportList[i] + "\"");
} else if (exportFile.getName().toLowerCase().endsWith(".zip") ||
exportFile.getName().toLowerCase().endsWith(".jar")) {
packClassPathIntoZipFile(exportFile.getAbsolutePath(), zos);
} else { // just copy the file over.. prolly a .dll or something
Base.copyFile(exportFile,
new File(appletFolder, exportFile.getName()));
}
}
}
String bagelJar = "lib/core.jar";
packClassPathIntoZipFile(bagelJar, zos);
// files to include from data directory
// TODO this needs to be recursive
if (dataFolder.exists()) {
String dataFiles[] = dataFolder.list();
for (int i = 0; i < dataFiles.length; i++) {
// don't export hidden files
// skipping dot prefix removes all: . .. .DS_Store
if (dataFiles[i].charAt(0) == '.') continue;
entry = new ZipEntry(dataFiles[i]);
zos.putNextEntry(entry);
zos.write(Base.grabFile(new File(dataFolder, dataFiles[i])));
zos.closeEntry();
}
}
// add the project's .class files to the jar
// just grabs everything from the build directory
// since there may be some inner classes
// (add any .class files from the applet dir, then delete them)
// TODO this needs to be recursive (for packages)
String classfiles[] = appletFolder.list();
for (int i = 0; i < classfiles.length; i++) {
if (classfiles[i].endsWith(".class")) {
entry = new ZipEntry(classfiles[i]);
zos.putNextEntry(entry);
zos.write(Base.grabFile(new File(appletFolder, classfiles[i])));
zos.closeEntry();
}
}
// remove the .class files from the applet folder. if they're not
// removed, the msjvm will complain about an illegal access error,
// since the classes are outside the jar file.
for (int i = 0; i < classfiles.length; i++) {
if (classfiles[i].endsWith(".class")) {
File deadguy = new File(appletFolder, classfiles[i]);
if (!deadguy.delete()) {
Base.showWarning("Could not delete",
classfiles[i] + " could not \n" +
"be deleted from the applet folder. \n" +
"You'll need to remove it by hand.", null);
}
}
}
// close up the jar file
zos.flush();
zos.close();
Base.openFolder(appletFolder);
return true;
*/

BIN
bootloader/ATmegaBOOT.bin Executable file

Binary file not shown.

555
bootloader/ATmegaBOOT.c Executable file
View File

@ -0,0 +1,555 @@
/**********************************************************/
/* Serial Bootloader for Atmel megaAVR Controllers */
/* */
/* ATmegaBOOT.c */
/* */
/* build: 050123 */
/* */
/* Hacked by DojoCorp - ZGZ - MMX - IVR */
/* */
/* For the latest version see: */
/* http://www.0j0.org and */
/* http://www.potemkin.org */
/* */
/* ------------------------------------------------------ */
/* */
/* Copyleft (c) 2005, DojoDave */
/* Creative Commons . */
/* see avr1.org for original file and information */
/* */
/* This program is free software; you can redistribute it */
/* and/or modify it under the terms of the GNU General */
/* Public License as published by the Free Software */
/* Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will */
/* be useful, but WITHOUT ANY WARRANTY; without even the */
/* implied warranty of MERCHANTABILITY or FITNESS FOR A */
/* PARTICULAR PURPOSE. See the GNU General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU General */
/* Public License along with this program; if not, write */
/* to the Free Software Foundation, Inc., */
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* */
/* Licence can be viewed at */
/* http://www.fsf.org/licenses/gpl.txt */
/* */
/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */
/* m8515,m8535. ATmega161 has a very small boot block so */
/* isn't supported. */
/* */
/* Tested with m8 - */
/* */
/**********************************************************/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#define F_CPU 16000000
/* We, Malmoitians, like slow interaction
* therefore the slow baud rate ;-)
*/
#define BAUD_RATE 19200
/* 6.000.000 is more or less 8 seconds at the
* speed configured here
*/
#define MAX_TIME_COUNT 6000000
#define MAX_TIME_COUNT_MORATORY 1600000
#define DECRYPT 0
#define ENCRYPT 1
/* #define DES_ENCRYPTION */
/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
#define HW_VER 0x02
#define SW_MAJOR 0x01
#define SW_MINOR 0x12
// AVR-GCC compiler compatibility
// avr-gcc compiler v3.1.x and older doesn't support outb() and inb()
// if necessary, convert outb and inb to outp and inp
#ifndef outb
#define outb(sfr,val) (_SFR_BYTE(sfr) = (val))
#endif
#ifndef inb
#define inb(sfr) _SFR_BYTE(sfr)
#endif
/* defines for future compatibility */
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
#define eeprom_rb(addr) eeprom_read_byte ((uint8_t *)(addr))
#define eeprom_rw(addr) eeprom_read_word ((uint16_t *)(addr))
#define eeprom_wb(addr, val) eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))
/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
#define BL_DDR DDRD
#define BL_PORT PORTD
#define BL_PIN PIND
#define BL PIND6
/* define pin for onboard LED */
/* depends on product */
/* Onboard LED is connected to pin PB5 */
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define LED PINB5
#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
#define SIG2 0x93
#define SIG3 0x07
#define PAGE_SIZE 0x20U //32 words
void putch(char);
char getch(void);
void getNch(uint8_t);
void byte_response(uint8_t);
void nothing_response(void);
char gethex(void);
void puthex(char);
union address_union {
uint16_t word;
uint8_t byte[2];
} address;
union length_union {
uint16_t word;
uint8_t byte[2];
} length;
struct flags_struct {
unsigned eeprom : 1;
unsigned rampz : 1;
} flags;
uint8_t buff[256];
uint8_t address_high;
uint8_t pagesz=0x80;
uint8_t i;
uint8_t bootuart0=0,bootuart1=0;
void (*app_start)(void) = 0x0000;
int main(void)
{
uint8_t ch,ch2;
uint16_t w;
cbi(BL_DDR,BL);
sbi(BL_PORT,BL);
asm volatile("nop\n\t");
/* check if flash is programmed already, if not start bootloader anyway */
if(pgm_read_byte_near(0x0000) != 0xFF) {
/* check if bootloader pin is set low */
//if(bit_is_set(BL_PIN,BL)) app_start();
}
/* initialize UART(s) depending on CPU defined */
/* m8 */
UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
UCSRB =(1<<RXEN)|(1<<TXEN); // enable Rx & Tx
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
//UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
//UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
//UCSRA = 0x00;
//UCSRC = 0x86;
//UCSRB = _BV(TXEN)|_BV(RXEN);
putch('\0');
uint32_t l;
uint32_t time_count;
time_count=0;
/* set LED pin as output */
sbi(LED_DDR,LED);
/* flash onboard LED three times to signal entering of bootloader */
for(i=0; i<3; ++i) {
for(l=0; l<40000000; ++l);
sbi(LED_PORT,LED);
for(l=0; l<40000000; ++l);
cbi(LED_PORT,LED);
}
putch('\0'); // this line is needed for the synchronization of the programmer
/* forever */
for (;;) {
if((inb(UCSRA) & _BV(RXC))){
/* get character from UART */
ch = getch();
/* A bunch of if...else if... gives smaller code than switch...case ! */
/* Hello is anyone home ? */
if(ch=='0') {
nothing_response();
}
if(ch=='l') {
if (getch() == 'o') {
if (getch() == 'l') {
if (getch() == 'a') {
app_start();
}
}
}
}
/* Request programmer ID */
/* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */
/* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */
else if(ch=='1') {
if (getch() == ' ') {
putch(0x14);
putch('A');
putch('V');
putch('R');
putch(' ');
putch('I');
putch('S');
putch('P');
putch(0x10);
}
}
/* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */
else if(ch=='@') {
ch2 = getch();
if (ch2>0x85) getch();
nothing_response();
}
/* AVR ISP/STK500 board requests */
else if(ch=='A') {
ch2 = getch();
if(ch2==0x80) byte_response(HW_VER); // Hardware version
else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56
else byte_response(0x00); // Covers various unnecessary responses we don't care about
}
/* Device Parameters DON'T CARE, DEVICE IS FIXED */
else if(ch=='B') {
getNch(20);
nothing_response();
}
/* Parallel programming stuff DON'T CARE */
else if(ch=='E') {
getNch(5);
nothing_response();
}
/* Enter programming mode */
else if(ch=='P') {
nothing_response();
// FIXME: modified only here by DojoCorp, Mumbai, India, 20050626
time_count=0; // exted the delay once entered prog.mode
}
/* Leave programming mode */
else if(ch=='Q') {
nothing_response();
time_count=MAX_TIME_COUNT_MORATORY; // once the programming is done,
// we should start the application
// but uisp has problems with this,
// therefore we just change the times
// and give the programmer 1 sec to react
}
/* Erase device, don't care as we will erase one page at a time anyway. */
else if(ch=='R') {
nothing_response();
}
/* Set address, little endian. EEPROM in bytes, FLASH in words */
/* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */
/* This might explain why little endian was used here, big endian used everywhere else. */
else if(ch=='U') {
address.byte[0] = getch();
address.byte[1] = getch();
nothing_response();
}
/* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */
else if(ch=='V') {
getNch(4);
byte_response(0x00);
}
/* 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
}
if (getch() == ' ') {
if (flags.eeprom) { //Write to EEPROM one byte at a time
for(w=0;w<length.word;w++) {
eeprom_wb(address.word,buff[w]);
address.word++;
}
}
else { //Write to FLASH one page at a time
if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
else address_high = 0x00;
address.word = address.word << 1; //address * 2 -> byte location
/* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */
if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
cli(); //Disable interrupts, just to be sure
while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
asm volatile("clr r17 \n\t" //page_word_count
"lds r30,address \n\t" //Address of FLASH location (in bytes)
"lds r31,address+1 \n\t"
"ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM
"ldi r29,hi8(buff) \n\t"
"lds r24,length \n\t" //Length of data to be written (in bytes)
"lds r25,length+1 \n\t"
"length_loop: \n\t" //Main loop, repeat for number of words in block
"cpi r17,0x00 \n\t" //If page_word_count=0 then erase page
"brne no_page_erase \n\t"
"wait_spm1: \n\t"
"lds r16,%0 \n\t" //Wait for previous spm to complete
"andi r16,1 \n\t"
"cpi r16,1 \n\t"
"breq wait_spm1 \n\t"
"ldi r16,0x03 \n\t" //Erase page pointed to by Z
"sts %0,r16 \n\t"
"spm \n\t"
"wait_spm2: \n\t"
"lds r16,%0 \n\t" //Wait for previous spm to complete
"andi r16,1 \n\t"
"cpi r16,1 \n\t"
"breq wait_spm2 \n\t"
"ldi r16,0x11 \n\t" //Re-enable RWW section
"sts %0,r16 \n\t"
"spm \n\t"
"no_page_erase: \n\t"
"ld r0,Y+ \n\t" //Write 2 bytes into page buffer
"ld r1,Y+ \n\t"
"wait_spm3: \n\t"
"lds r16,%0 \n\t" //Wait for previous spm to complete
"andi r16,1 \n\t"
"cpi r16,1 \n\t"
"breq wait_spm3 \n\t"
"ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer
"sts %0,r16 \n\t"
"spm \n\t"
"inc r17 \n\t" //page_word_count++
"cpi r17,%1 \n\t"
"brlo same_page \n\t" //Still same page in FLASH
"write_page: \n\t"
"clr r17 \n\t" //New page, write current one first
"wait_spm4: \n\t"
"lds r16,%0 \n\t" //Wait for previous spm to complete
"andi r16,1 \n\t"
"cpi r16,1 \n\t"
"breq wait_spm4 \n\t"
"ldi r16,0x05 \n\t" //Write page pointed to by Z
"sts %0,r16 \n\t"
"spm \n\t"
"wait_spm5: \n\t"
"lds r16,%0 \n\t" //Wait for previous spm to complete
"andi r16,1 \n\t"
"cpi r16,1 \n\t"
"breq wait_spm5 \n\t"
"ldi r16,0x11 \n\t" //Re-enable RWW section
"sts %0,r16 \n\t"
"spm \n\t"
"same_page: \n\t"
"adiw r30,2 \n\t" //Next word in FLASH
"sbiw r24,2 \n\t" //length-2
"breq final_write \n\t" //Finished
"rjmp length_loop \n\t"
"final_write: \n\t"
"cpi r17,0 \n\t"
"breq block_done \n\t"
"adiw r24,2 \n\t" //length+2, fool above check on length after short page write
"rjmp write_page \n\t"
"block_done: \n\t"
"clr __zero_reg__ \n\t" //restore zero register
: "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31");
/* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
/* exit the bootloader without a power cycle anyhow */
}
putch(0x14);
putch(0x10);
}
}
/* Read memory block mode, length is big endian. */
else if(ch=='t') {
length.byte[1] = getch();
length.byte[0] = getch();
if (getch() == 'E') flags.eeprom = 1;
else {
flags.eeprom = 0;
address.word = address.word << 1; // address * 2 -> byte location
}
if (getch() == ' ') { // Command terminator
putch(0x14);
for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay
if (flags.eeprom) { // Byte access EEPROM read
putch(eeprom_rb(address.word));
address.word++;
}
else {
if (!flags.rampz) putch(pgm_read_byte_near(address.word));
address.word++;
}
}
putch(0x10);
}
}
/* Get device signature bytes */
else if(ch=='u') {
if (getch() == ' ') {
putch(0x14);
putch(SIG1);
putch(SIG2);
putch(SIG3);
putch(0x10);
}
}
/* Read oscillator calibration byte */
else if(ch=='v') {
byte_response(0x00);
}
}
else {
time_count++;
if (time_count>=MAX_TIME_COUNT) {
app_start();
}
}
}
/* end of forever loop */
}
char gethex(void) {
char ah,al;
ah = getch(); putch(ah);
al = getch(); putch(al);
if(ah >= 'a') {
ah = ah - 'a' + 0x0a;
} else if(ah >= '0') {
ah -= '0';
}
if(al >= 'a') {
al = al - 'a' + 0x0a;
} else if(al >= '0') {
al -= '0';
}
return (ah << 4) + al;
}
void puthex(char ch) {
char ah,al;
ah = (ch & 0xf0) >> 4;
if(ah >= 0x0a) {
ah = ah - 0x0a + 'a';
} else {
ah += '0';
}
al = (ch & 0x0f);
if(al >= 0x0a) {
al = al - 0x0a + 'a';
} else {
al += '0';
}
putch(ah);
putch(al);
}
void putch(char ch)
{
/* m8 */
while (!(inb(UCSRA) & _BV(UDRE)));
outb(UDR,ch);
}
char getch(void)
{
/* m8 */
while(!(inb(UCSRA) & _BV(RXC))) {
/* HACKME:: here is a good place to count times*/
}
return (inb(UDR));
}
void getNch(uint8_t count)
{
uint8_t i;
for(i=0;i<count;i++) {
/* m8 */
while(!(inb(UCSRA) & _BV(RXC)));
inb(UDR);
}
}
void byte_response(uint8_t val)
{
if (getch() == ' ') {
putch(0x14);
putch(val);
putch(0x10);
}
}
void nothing_response(void)
{
if (getch() == ' ') {
putch(0x14);
putch(0x10);
}
}
/* end of file ATmegaBOOT.c */

129
bootloader/ATmegaBOOT.srec Executable file
View File

@ -0,0 +1,129 @@
S012000041546D656761424F4F542E73726563AF
S113180012C02BC02AC029C028C027C026C025C0AA
S113181024C023C022C021C020C01FC01EC01DC0C0
S11318201CC01BC01AC011241FBECFE5D4E0DEBF0C
S1131830CDBF10E0A0E6B0E0E0EEFFE102C005900D
S11318400D92A236B107D9F711E0A2E6B0E001C0CB
S11318501D92AD36B107E1F738C0D2CF5D9BFECF04
S11318608CB908955F9BFECF8CB1992787FD909525
S113187008955F9BFECF8CB1803209F008955D9B83
S1131880FECF24E12CB95D9BFECF30E13CB9089535
S1131890982F5F9BFECF8CB1803209F008955D9B39
S11318A0FECF24E12CB95D9BFECF9CB95D9BFECF9E
S11318B030E13CB90895282F90E004C05F9BFECF2F
S11318C08CB19F5F9217D0F30895CFE5D4E0DEBFCB
S11318D0CDBF8E98969A000010BC13E319B908E1A5
S11318E00AB986E880BD5D9BFECF1CB8CC24DD24FC
S11318F07601BD9A10926A0120E08FEF99E5A2E685
S1131900B2E0C297A109B109B7FFFBCFC59A8FEF27
S113191099E5A2E6B2E0C297A109B109B7FFFBCFEE
S1131920C598822F8F5F282F833038F380936A0104
S11319305D9BFECF1CB85F9914C00894C11CD11CD8
S1131940E11CF11CF0E8CF16FDE8DF06FBE5EF062D
S1131950F0E0FF0680F3E0916200F09163000995E6
S1131960EACF5F9BFECF2CB1922F2033F1F19C364E
S113197009F4BFC2913309F493C2903409F437C215
S1131980913409F417C2923409F400C2953409F46D
S1131990E9C1903509F4CBC1913509F4BCC1923544
S11319A009F426C1953509F40CC1963509F4F2C041
S11319B0943609F495C0943709F43FC0953721F162
S11319C0963709F0B8CF5F9BFECF2CB1203209F0D7
S11319D0B2CF5D9BFECF34E13CB95D9BFECF1CB81A
S11319E05D9BFECF50E15CB9A6CF5F9BFECF3CB1BF
S11319F0303209F0BCCF5D9BFECF44E14CB95D9B16
S1131A00FECF50E15CB9B3CF5F9BFECFECB1E032C7
S1131A1009F091CF5D9BFECF04E10CB95D9BFECF35
S1131A201EE11CB95D9BFECF43E94CB95D9BFECF23
S1131A3067E06CB95D9BFECFD5CF5F9BFECF3CB119
S1131A40309369015F9BFECF5CB1509368015F9B4B
S1131A50FECF7CB1753409F43DC0B0916C01BE7FFA
S1131A60B0936C01C0916600D0916700CC0FDD1F6C
S1131A70D0936700C09366005F9BFECFFCB1F03249
S1131A8009F059CF5D9BFECF84E18CB9C0E0D0E072
S1131A90209168013091690112161306C0F48091F7
S1131AA06C0180FD1DC1869580FD30C1E09166000A
S1131AB0F091670084915D9BFECF8CB93196F093D1
S1131AC06700E09366002196C217D30740F35D9B3D
S1131AD0FECF88CF90916C01916090936C01CCCF34
S1131AE05F9BFECF9CB1909369015F9BFECFACB12D
S1131AF0A093680190916C019E7F5F9BFECFBCB167
S1131B00B53409F4916090936C0140E050E0209169
S1131B106801309169011216130658F4E8E6F0E002
S1131B205F9BFECFCCB1C1934F5F5F4F421753070A
S1131B30B8F35F9BFECFECB1E03209F0FCCEF0913C
S1131B406C01F0FF62C0C0E0D0E012161306D8F4B6
S1131B5008E610E0F80161918F0180916600909190
S1131B60670033D2A0916600B09167001196B093DC
S1131B706700A093660021968091680190916901A5
S1131B80C817D90738F35D9BFECF24E12CB95D9BC0
S1131B90FECF28CF90E05F9BFECF8CB19F5F943047
S1131BA0D0F35F9BFECF6CB1603209F0C4CE5D9B75
S1131BB0FECF74E17CB95D9BFECF1CB85D9BFECF6C
S1131BC011CF5F9BFECF2CB1209366005F9BFECFAD
S1131BD03CB1309367005F9BFECF4CB1403209F0BB
S1131BE0AACE5D9BFECF54E15CB95D9BFECFFACEDD
S1131BF05F9BFECF0CB1003209F09DCE5D9BFECF02
S1131C0014E11CB95D9BFECFEDCE0091670007FD8A
S1131C1063C010926B016091660070916700660F5B
S1131C20771F70936700609366004091680140FFDE
S1131C3006C02F5F3F4F3093690120936801F894E9
S1131C40E199FECF1127E0916600F0916700C8E6A4
S1131C50D0E08091680190916901103091F4009175
S1131C60570001700130D9F303E000935700E89561
S1131C700091570001700130D9F301E1009357003E
S1131C80E895099019900091570001700130D9F33B
S1131C9001E000935700E8951395103298F011274E
S1131CA00091570001700130D9F305E0009357000B
S1131CB0E8950091570001700130D9F301E10093D8
S1131CC05700E8953296029709F0C7CF103011F00B
S1131CD00296E5CF112457CF11E010936B019BCFEF
S1131CE0809166009091670068D15D9BFECF8CB9AE
S1131CF0A0916600B09167001196B0936700A0931D
S1131D0066002091680130916901DDCEE0916600A2
S1131D10F0916700D3CE5F9BFECFECB1E03281F04F
S1131D20C12C5AE6D52E58E1E52EF12C04CE5F9B4A
S1131D30FECFACB1A03269F0CC24DD247601FBCD1A
S1131D405D9BFECFF4E1FCB95D9BFECF80E18CB9D5
S1131D50E7CF5D9BFECFB4E1BCB95D9BFECFC0E194
S1131D60CCB9EACF90E05F9BFECF8CB19F5F9530FA
S1131D70D0F35F9BFECF7CB1703209F0DCCD5D9B6C
S1131D80FECF94E19CB95D9BFECF2CCE90E05F9B8F
S1131D90FECF8CB19F5F9431D0F35F9BFECF5CB1DB
S1131DA0503209F0C8CD5D9BFECF64E16CB95D9BF8
S1131DB0FECF18CE5F9BFECF8CB18038F1F1813815
S1131DC059F1823809F45BC0883909F447C05F9B34
S1131DD0FECF3CB1303209F0AECD5D9BFECF44E185
S1131DE04CB95D9BFECF1CB85D9BFECFFBCD5F9BCA
S1131DF0FECF3CB1363818F05F9BFECF8CB15F9BB1
S1131E00FECF4CB1403209F096CD5D9BFECF54E13C
S1131E105CB95D9BFECFE6CD5F9BFECFACB1A0323B
S1131E2009F089CD5D9BFECFB4E1BCB95D9BFECFCB
S1131E30C1E0CCB95D9BFECFD5CD5F9BFECF6CB12D
S1131E40603209F078CD5D9BFECF74E17CB95D9B77
S1131E50FECF92E09CB95D9BFECFC4CD5F9BFECFCD
S1131E600CB1003209F067CD5D9BFECF14E11CB9C3
S1131E705D9BFECF23E02CB95D9BFECFB3CD5F9B72
S1131E80FECFECB1E03209F056CD5D9BFECFF4E11C
S1131E90FCB95D9BFECF82E18CB95D9BFECFA2CDE8
S1131EA05F9BFECFACB1A03209F045CD5D9BFECF68
S1131EB0B4E1BCB95D9BFECFC1E4CCB95D9BFECF60
S1131EC0E6E5ECB95D9BFECFF2E5FCB95D9BFECF88
S1131ED080E28CB95D9BFECF09E40CB95D9BFECF1B
S1131EE013E51CB95D9BFECF20E52CB95D9BFECFAD
S1131EF079CD5F9BFECF6CB16F3609F01CCD5F9B33
S1131F00FECF7CB17C3609F016CD5F9BFECF9CB131
S1131F10913609F010CD1FCD5F9BFECF8CB1992770
S1131F2087FD9095282F5D9BFECF8CB95F9BFECFDC
S1131F308CB1992787FD9095382F5D9BFECF8CB986
S1131F4021362CF02755313634F0375507C020336D
S1131F50D4F32053F8CF30330CF030532295207F44
S1131F60230F822F992787FD90950895282F99276D
S1131F7087FD9095807F9070959587959595879529
S1131F8095958795959587958A306CF0982F995AF1
S1131F90822F8F708A306CF0895A5D9BFECF9CB97A
S1131FA05D9BFECF08C0982F905D822F8F708A3082
S1131FB09CF7805DF2CF8CB90895E199FECF9FBB69
S1131FC08EBBE09A99278DB30895E199FECF9FBB0C
S1131FD08EBB6DBB0FB6F894E29AE19A0FBE0895DA
S1051FE080007B
S9031800E4

109
bootloader/Makefile Normal file
View File

@ -0,0 +1,109 @@
# Makefile for ATmegaBOOT
# E.Lins, 2004-10-14
# program name should not be changed...
PROGRAM = ATmegaBOOT
# enter the product name for which you want to build the bootloader/monitor
# currently CRUMB8, CRUMB128 and PROBOMEGA128 are supported
PRODUCT = CRUMB8
# enter the parameters for the UISP isp tool
#ISPPARAMS = -dprog=stk200 -dlpt=0x378
ISPPARAMS = -dprog=stk500 -dserial=/dev/com1 -dspeed=115200
############################################################
# You should not have to change anything below here.
############################################################
DIRAVR = /usr/local/avr
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
ifeq ($(PRODUCT),CRUMB8)
MCU_TARGET = atmega8
LDSECTION = --section-start=.text=0x1800
FUSE_L = 0xdf
FUSE_H = 0xc8
ISPFUSES = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --wr_fuse_l=$(FUSE_L) --wr_fuse_h=$(FUSE_H)
ISPFLASH = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --erase --upload if=$(PROGRAM).hex -v
endif
ifeq ($(PRODUCT),CRUMB128)
MCU_TARGET = atmega128
LDSECTION = --section-start=.text=0x1E000
FUSE_L = 0xdf
FUSE_H = 0xc8
FUSE_E = 0xff
ISPFUSES = ./uisp -dpart=ATmega128 $(ISPPARAMS) --wr_fuse_l=$(FUSE_L) --wr_fuse_h=$(FUSE_H) --wr_fuse_e=$(FUSE_E)
ISPFLASH = ./uisp -dpart=ATmega128 $(ISPPARAMS) --erase --upload if=$(PROGRAM).hex -v
endif
ifeq ($(PRODUCT),PROBOMEGA128)
MCU_TARGET = atmega128
LDSECTION = --section-start=.text=0x1E000
FUSE_L = 0xdf
FUSE_H = 0xc8
FUSE_E = 0xff
ISPFUSES = ./uisp -dpart=ATmega128 $(ISPPARAMS) --wr_fuse_l=$(FUSE_L) --wr_fuse_h=$(FUSE_H) --wr_fuse_e=$(FUSE_E)
ISPFLASH = ./uisp -dpart=ATmega128 $(ISPPARAMS) --erase --upload if=$(PROGRAM).hex -v
endif
OBJ = $(PROGRAM).o
OPTIMIZE = -O3
DEFS =
LIBS =
CC = $(DIRAVRBIN)/avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -D$(PRODUCT) $(DEFS)
override LDFLAGS = -Wl,-Map,$(PROGRAM).map,$(LDSECTION)
OBJCOPY = $(DIRAVRBIN)/avr-objcopy
OBJDUMP = $(DIRAVRBIN)/avr-objdump
all: $(PROGRAM).elf lst text
isp: $(PROGRAM).hex
$(ISPFUSES)
$(ISPFLASH)
$(PROGRAM).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
rm -rf *.o *.elf
rm -rf *.lst *.map
lst: $(PROGRAM).lst
%.lst: %.elf
$(OBJDUMP) -h -S $< > $@
# Rules for building the .text rom images
text: hex bin srec
hex: $(PROGRAM).hex
bin: $(PROGRAM).bin
srec: $(PROGRAM).srec
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@

6
bootloader/build.bat Executable file
View File

@ -0,0 +1,6 @@
avr-gcc -g -Wall -O3 -mmcu=atmega8 -DCRUMB8 -c -o ATmegaBOOT.o ATmegaBOOT.c
avr-gcc -g -Wall -O3 -mmcu=atmega8 -DCRUMB8 -Wl,-Map,ATmegaBOOT.map,--section-start=.text=0x1800 -o ATmegaBOOT.elf ATmegaBOOT.o
avr-objdump -S -h ATmegaBOOT.elf > ATmegaBOOT.lst
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT.elf ATmegaBOOT.hex
avr-objcopy -j .text -j .data -O binary ATmegaBOOT.elf ATmegaBOOT.bin
avr-objcopy -j .text -j .data -O srec ATmegaBOOT.elf ATmegaBOOT.srec

View File

@ -0,0 +1,26 @@
#!/bin/sh
# fixmybootloader.command 25.06.2005 mbanzi
#
# Arduino project http://arduino.berlios.de
#
# quick and dirty script to set the proper fuses and lock bits
# while loading the bootloader onto a brand new arduino board
#
# very useful also when for some reasons the bootloader disappears
#
# TODO: cleanup and make it more user friendly
#
# expects an STK500 compatible programmer on the specified serial port
# if you use the parallel port programmer you need to change the dprog
# parametre
#
BINDIR=/usr/local/avr/bin
#PORT=/dev/tty.usbserial0
PORT=/dev/tty.USA19QW3b1P1.1
$BINDIR/uisp -dpart=ATmega8 -dprog=stk500 -dserial=$PORT -dspeed=115200 --wr_lock=0xFF
$BINDIR/uisp -dpart=ATmega8 -dprog=stk500 -dserial=$PORT -dspeed=115200 --wr_fuse_l=0xdf --wr_fuse_h=0xc8
$BINDIR/uisp -dpart=ATmega8 -dprog=stk500 -dserial=$PORT -dspeed=115200 --erase --upload if=ATMegaBOOT.hex -v
$BINDIR/uisp -dpart=ATmega8 -dprog=stk500 -dserial=$PORT -dspeed=115200 --wr_lock=0xCF

2
bootloader/program.bat Executable file
View File

@ -0,0 +1,2 @@
..\wiringlite\bin\uisp -dpart=ATmega8 -dprog=stk500 -dserial=com1 -dspeed=115200 --wr_fuse_l=0xdf --wr_fuse_h=0xc8
..\wiringlite\bin\uisp -dpart=ATmega8 -dprog=stk500 -dserial=com1 -dspeed=115200 --erase --upload --verify if=ATMegaBOOT.hex

1
bootloader/program.command Executable file
View File

@ -0,0 +1 @@
uisp -dpart=ATmega8 -dprog=avrisp -dserial=/dev/tty.usbserial0 -dspeed=115200 if=ATMegaBOOT.hex --erase --upload --verify