From 5eca151828773e4a2f450fe6019e556b6bafbbf8 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Fri, 5 Oct 2007 01:45:15 +0200 Subject: [PATCH] initial with isr driven twi --- .gitignore | 6 + Makefile | 45 +++++ main.c | 579 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 630 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d36148 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.elf +*.bin +*.hex +*.lst +*.map diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5890c34 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +PRG = fc_boot +OBJ = main.o +MCU_TARGET = atmega644 +OPTIMIZE = -Os + +DEFS = +LIBS = + +# Override is only needed by avr-lib build system. +override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) +override LDFLAGS = -Wl,-Map,$(PRG).map,--section-start=.text=0xF000 + +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + +all: $(PRG).elf lst text + $(SIZE) -x -A $(PRG).elf + +$(PRG).elf: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + +clean: + rm -rf *.o *.lst *.map $(PRG).elf *.hex *.bin + +lst: $(PRG).lst + +%.lst: %.elf + $(OBJDUMP) -h -S $< > $@ + +text: hex bin + +hex: $(PRG).hex +bin: $(PRG).bin + +%.hex: %.elf + $(OBJCOPY) -j .text -j .data -O ihex $< $@ + +%.bin: %.elf + $(OBJCOPY) -j .text -j .data -O binary $< $@ + +install: text +# uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex + avrdude -p m644 -c butterfly -b 115200 -P /dev/ttyS0 -u -V -U flash:w:$(PRG).hex \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..abb4561 --- /dev/null +++ b/main.c @@ -0,0 +1,579 @@ +/*************************************************************************** + * 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 +#include + +#include + +#define F_CPU 20000000 +#include + +#define BAUDRATE 19200 +#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1) + +#define APP_END 0xF000 + +#define LED_RT (1< send SLA+W */ + case 0x08: + bcnt = 0; + TWDR = (i2c_dev << 1); + TWCR &= ~(1< send SLA+R */ + case 0x10: + bcnt = 0; + TWDR = (i2c_dev << 1) | 0x01; + TWCR &= ~(1< send command */ + case 0x18: + bcnt++; + TWDR = i2c_cmd; + TWCR |= (1< ? */ + case 0x28: + switch (i2c_cmd) { + case CMD_GET_INFO: + case CMD_GET_SIGNATURE: + case CMD_READ_FLASH: + case CMD_READ_EEPROM: + TWCR |= (1<> 8); + + } else if (bcnt == 2) { + TWDR = (i2c_address & 0xFF); + + } else if (bcnt == 3) { + TWDR = (WRITE_COOKIE >> 8); + + } else if (bcnt == 4) { + TWDR = (WRITE_COOKIE & 0xFF); + + } else if (bcnt >= 5 && bcnt < (64 +5)) { + TWDR = i2c_buf[bcnt -5]; + + } else { + i2c_complete = 1; + TWCR |= (1< send ACK (send more data) */ + case 0x40: + TWCR |= (1< 0) + boot_timeout--; +} + +static uint16_t address; +static uint8_t page_buf[256]; + +static void eraseFlash(void) +{ + uint32_t addr = 0; + while (APP_END > addr) { + boot_page_erase(addr); + boot_spm_busy_wait(); + addr += SPM_PAGESIZE; + } + boot_rww_enable(); +} + +static uint16_t writeFlashPage(uint16_t waddr, uint16_t size) +{ + uint32_t pagestart = (uint32_t)waddr<<1; + uint32_t baddr = pagestart; + uint16_t data; + uint8_t *tmp = page_buf; + + do { + data = *tmp++; + data |= *tmp++ << 8; + boot_page_fill(baddr, data); + + baddr += 2; + size -= 2; + } while (size); + + boot_page_write(pagestart); + boot_spm_busy_wait(); + boot_rww_enable(); + + return baddr>>1; +} + +static uint16_t writeEEpromPage(uint16_t address, uint16_t size) +{ + uint8_t *tmp = page_buf; + + do { + EEARL = address; + EEARH = (address >> 8); + EEDR = *tmp++; + address++; + + EECR |= (1<> 8)); + baddr += 2; + size -= 2; + } while (size); + + return baddr>>1; +} + +static uint16_t readEEpromPage(uint16_t address, uint16_t size) +{ + do { + EEARL = address; + EEARH = (address >> 8); + EECR |= (1<> 8) & 0xFF); + sendchar(sizeof(page_buf) & 0xFF); + + // Start buffer load + } else if (val == 'B') { + uint16_t size; + uint16_t cnt; + uint8_t *tmp = page_buf; + + size = recvchar() << 8; + size |= recvchar(); + val = recvchar(); + + for (cnt = 0; cnt < sizeof(page_buf); cnt++) + *tmp++ = (cnt < size) ? recvchar() : 0xFF; + + if (dev == DEVCODE_M8) { + if (val == 'F') { + tmp = page_buf; + while (size) { + i2c_address = address; + for (cnt = 0; cnt < sizeof(i2c_buf); cnt++) + i2c_buf[cnt] = *tmp++; + + i2c_transfer(CMD_WRITE_FLASH); + address += sizeof(i2c_buf); + + size -= sizeof(i2c_buf); + } + + } else if (val == 'E') { + + } + + } else if (dev == DEVCODE_M644) { + if (val == 'F') { + address = writeFlashPage(address, size); + } else if (val == 'E') { + address = writeEEpromPage(address, size); + } + } + sendchar('\r'); + + // Block read + } else if (val == 'g') { + uint16_t size = recvchar() << 8; + size |= recvchar(); + val = recvchar(); + + if (dev == DEVCODE_M8) { + if (val == 'F') { + while (size > 0) { + uint8_t i = 0; + i2c_address = address; + i2c_transfer(CMD_READ_FLASH); + + address += sizeof(i2c_buf); + while (size-- && i < sizeof(i2c_buf)) + sendchar(i2c_buf[i++]); + } + + } else if (val == 'E') { + sendchar(0xff); + + } + + } else if (dev == DEVCODE_M644) { + if (val == 'F') { + address = readFlashPage(address, size); + } else if (val == 'E') { + address = readEEpromPage(address, size); + } + } + + // Chip erase + } else if (val == 'e') { + eraseFlash(); + sendchar('\r'); + + // Exit upgrade + } else if (val == 'E') { + boot_timeout = 0; + sendchar('\r'); + _delay_ms(10); + break; + + // Enter programming mode + } else if (val == 'P') { + /* boot loader */ + i2c_transfer(CMD_BOOT_LOADER); + sendchar('\r'); + + // Leave programming mode + } else if (val == 'L') { + /* boot application */ + i2c_transfer(CMD_BOOT_APPLICATION); + sendchar('\r'); + + // return programmer type + } else if (val == 'p') { + sendchar('S'); + + // Return device type + } else if (val == 't') { + sendchar(DEVCODE_M8); + sendchar(DEVCODE_M644); + sendchar(0); + + // clear and set LED ignored + } else if ((val == 'x') || (val == 'y')) { + recvchar(); + sendchar('\r'); + + // set device + } else if (val == 'T') { + dev = recvchar(); + sendchar('\r'); + + // Return software identifier + } else if (val == 'S') { + sendchar('F'); + sendchar('C'); + sendchar('_'); + sendchar('B'); + sendchar('O'); + sendchar('O'); + sendchar('T'); + + // Return Software Version + } else if (val == 'V') { + sendchar('0'); + sendchar('8'); + + // Return Signature Bytes + } else if (val == 's') { + if (dev == DEVCODE_M8) { + sendchar(0x07); + sendchar(0x93); + sendchar(0x1e); + + } else if (dev == DEVCODE_M644) { + sendchar(0x09); + sendchar(0x96); + sendchar(0x1e); + + } else { + sendchar(0xFF); + sendchar(0xFF); + sendchar(0xFF); + } + + // set i2c target + } else if (val >= '1' && val <= '4') { + i2c_dev = val - '1' + 0x21; + sendchar(val); + + /* ESC */ + } else if (val != 0x1b) { + sendchar('?'); + } + } +} + +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<>8) & 0xFF; + UBRR0L = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF); + + /* USART: rx/tx enable, 8n1 */ + UCSR0B = (1< 0) { + if (UCSR0A & (1<