/*************************************************************************** * Copyright (C) 09/2007 by Olaf Rempel * * razzor@kopf-tisch.de * * * * 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; version 2 of the License, * * * * 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. * ***************************************************************************/ #include #include #include #include #define F_CPU 8000000 #include #define LED_RT (1<= APP_END) return; boot_page_erase(pagestart); boot_spm_busy_wait(); do { uint16_t data = *p++; data |= *p++ << 8; boot_page_fill(addr, data); addr += 2; size -= 2; } while (size); boot_page_write(pagestart); boot_spm_busy_wait(); boot_rww_enable(); } void write_eeprom_byte(uint8_t val) { EEARL = addr; EEARH = (addr >> 8); EEDR = val; addr++; EECR |= (1< receive data and ACK */ case 0x60: bcnt = 0; PORTB |= LED_RT; TWCR |= (1< receive data and ACK */ case 0x80: if (bcnt == 0) { cmd = TWDR; switch (cmd) { case CMD_GET_INFO: case CMD_GET_SIGNATURE: case CMD_WRITE_FLASH: case CMD_READ_FLASH: case CMD_WRITE_EEPROM: case CMD_READ_EEPROM: /* abort countdown */ boot_timeout = 0; case CMD_BOOT_APPLICATION: bcnt++; break; default: cmd = CMD_WAIT; bcnt = 0; break; } } else if (bcnt == 1) { addr = (TWDR << 8); bcnt++; } else if (bcnt == 2) { addr |= TWDR; bcnt++; } else if (bcnt == 3) { if (TWDR == (COOKIE >> 8)) bcnt++; else bcnt = 0; } else if (bcnt == 4) { if (TWDR == (COOKIE & 0xFF)) bcnt++; else bcnt = 0; } else if (bcnt >= 5 && cmd == CMD_WRITE_FLASH) { buf[bcnt -5] = TWDR; if (bcnt < sizeof(buf) +4) { bcnt++; } else { write_flash_page(); bcnt = 0; } } else if (bcnt >= 5 && cmd == CMD_WRITE_EEPROM) { write_eeprom_byte(TWDR); bcnt++; } TWCR |= (1< send data */ case 0xA8: bcnt = 0; PORTB |= LED_RT; /* prev. SLA+R, data sent, ACK returned -> send data */ case 0xB8: switch (cmd) { case CMD_GET_INFO: TWDR = info[bcnt++]; bcnt %= sizeof(info); break; case CMD_GET_SIGNATURE: TWDR = signature[bcnt++]; bcnt %= sizeof(signature); break; case CMD_READ_FLASH: TWDR = pgm_read_byte_near(addr++); break; case CMD_READ_EEPROM: EEARL = addr; EEARH = (addr >> 8); EECR |= (1< reset hardware */ case 0xF8: TWCR |= (1< 1) boot_timeout--; /* trigger app-boot */ else if (boot_timeout == 1) cmd = CMD_BOOT_APPLICATION; } static void (*jump_to_app)(void) = 0x0000; int main(void) { DDRB = LED_GN | LED_RT; PORTB = LED_GN; /* move interrupt-vectors to bootloader */ MCUCR = (1<