From a7fcfaf7b98bed606ec13d6f4ec6845bda699f68 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sun, 26 Dec 2010 19:32:28 +0100 Subject: [PATCH] new i2c protocol --- Makefile | 7 +- main.c | 245 +++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 158 insertions(+), 94 deletions(-) diff --git a/Makefile b/Makefile index 5890c34..3746230 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PRG = fc_boot OBJ = main.o -MCU_TARGET = atmega644 +MCU_TARGET = atmega644p OPTIMIZE = -Os DEFS = @@ -22,7 +22,7 @@ $(PRG).elf: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) clean: - rm -rf *.o *.lst *.map $(PRG).elf *.hex *.bin + rm -rf *.o $(PRG).lst $(PRG).map $(PRG).elf $(PRG).hex $(PRG).bin lst: $(PRG).lst @@ -41,5 +41,4 @@ bin: $(PRG).bin $(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 + avrdude -c dragon_isp -P usb -p m644p -B0.3 -V -U flash:w:$(PRG).hex diff --git a/main.c b/main.c index b0675e3..dfdca5e 100644 --- a/main.c +++ b/main.c @@ -22,39 +22,50 @@ #include #include -#include +/* + * ATMega 644P: + * Fuse E: 0xFD (2.7V BOD) + * Fuse H: 0xDA (2048 words bootloader) + * Fuse L: 0xFF (ext. Crystal) + */ #define F_CPU 20000000 #include -#define BAUDRATE 19200 +#define BAUDRATE 57600 #define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1) -#define APP_END 0xF000 +#define APP_END 0xF000 -#define LED_RT (1<> 4) & 0x0F; + sendchar((tmp < 0x0A) ? ('0' + tmp) : ('a' - 0x0A + tmp)); -static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); + tmp = val & 0x0F; + sendchar((tmp < 0x0A) ? ('0' + tmp) : ('a' - 0x0A + tmp)); +} static uint8_t i2c_master_tx(uint8_t val) { @@ -104,14 +114,14 @@ static uint8_t i2c_master_rx(uint8_t *val, uint8_t ack) static void i2c_stop(void) { - PORTB &= ~LED_RT; + PORTB |= LED_RT; TWCR = (1<> 8) & 0xFF); - sendchar(sizeof(page_buf) & 0xFF); + page_size = (i2c_dev == 0) ? sizeof(page_buf) : chipinfo[3]; + sendchar((page_size >> 8) & 0xFF); + sendchar(page_size & 0xFF); // Start buffer load } else if (val == 'B') { @@ -277,27 +293,17 @@ void cmd_loop(void) size |= recvchar(); val = recvchar(); - for (cnt = 0; cnt < sizeof(page_buf); cnt++) + for (cnt = 0; cnt < page_size; cnt++) *tmp++ = (cnt < size) ? recvchar() : 0xFF; if (i2c_dev != 0) { i2c_start_address(i2c_dev); - if (val == 'F') { - i2c_master_tx(CMD_WRITE_FLASH); - // FIXME: Flashwriting is not working. see bl_master (which works) - - } else { - i2c_master_tx(CMD_WRITE_EEPROM); - /* no page align, transfer only needed bytes */ - cnt = size; - } - + i2c_master_tx(CMD_WRITE_MEMORY); + i2c_master_tx((val == 'F') ? MEMTYPE_FLASH : MEMTYPE_EEPROM); i2c_master_tx(address >> 8); i2c_master_tx(address & 0xFF); - address += sizeof(page_buf); - i2c_master_tx(WRITE_COOKIE >> 8); - i2c_master_tx(WRITE_COOKIE & 0xFF); + address += page_size; tmp = page_buf; while (cnt--) @@ -322,11 +328,8 @@ void cmd_loop(void) if (i2c_dev != 0) { i2c_start_address(i2c_dev); - if (val == 'F') - i2c_master_tx(CMD_READ_FLASH); - else - i2c_master_tx(CMD_READ_EEPROM); - + i2c_master_tx(CMD_READ_MEMORY); + i2c_master_tx((val == 'F') ? MEMTYPE_FLASH : MEMTYPE_EEPROM); i2c_master_tx(address >> 8); i2c_master_tx(address & 0xFF); @@ -363,18 +366,11 @@ void cmd_loop(void) } else if (val == 'P') { if (i2c_dev != 0) { i2c_start_address(i2c_dev); - i2c_master_tx(CMD_BOOT_LOADER); + i2c_master_tx(CMD_SWITCH_APPLICATION); + i2c_master_tx(BOOTTYPE_BOOTLOADER); i2c_stop(); _delay_ms(10); - - i2c_start_address(i2c_dev); - i2c_master_tx(CMD_GET_SIGNATURE); - i2c_start_address(i2c_dev | 0x01); - i2c_master_rx(&val, 1); - i2c_master_rx(&val, 1); - i2c_master_rx(&val, 0); - i2c_stop(); } sendchar('\r'); @@ -382,7 +378,8 @@ void cmd_loop(void) } else if (val == 'L') { if (i2c_dev != 0) { i2c_start_address(i2c_dev); - i2c_master_tx(CMD_BOOT_APPLICATION); + i2c_master_tx(CMD_SWITCH_APPLICATION); + i2c_master_tx(BOOTTYPE_APPLICATION); i2c_stop(); } sendchar('\r'); @@ -393,7 +390,7 @@ void cmd_loop(void) // Return device type } else if (val == 't') { - sendchar((i2c_dev == 0) ? DEVCODE_M644 : DEVCODE_M8); + sendchar((i2c_dev == 0) ? OWN_DEVCODE : TWI_DEVCODE); sendchar(0); // clear and set LED ignored @@ -424,14 +421,15 @@ void cmd_loop(void) // Return Signature Bytes } else if (val == 's') { if (i2c_dev != 0) { - sendchar(0x07); - sendchar(0x93); - sendchar(0x1e); + sendchar(chipinfo[2]); + sendchar(chipinfo[1]); + sendchar(chipinfo[0]); } else { - sendchar(0x09); - sendchar(0x96); - sendchar(0x1e); + uint8_t sig[3] = OWN_SIGNATURE; + sendchar(sig[2]); + sendchar(sig[1]); + sendchar(sig[0]); } // set i2c target @@ -440,27 +438,20 @@ void cmd_loop(void) sendchar(val); } else if (val >= '1' && val <= '4') { - i2c_dev = (val - '1' + 0x21) << 1; + i2c_dev = (val - '0' + TWI_ADDRESS_BASE) << 1; sendchar(val); + sendchar('<'); - // test props - } else if (val == 'l') { i2c_start_address(i2c_dev); - i2c_master_tx(CMD_SET_PWM); - i2c_master_tx(0x00); + i2c_master_tx(CMD_SWITCH_APPLICATION); + i2c_master_tx(BOOTTYPE_BOOTLOADER); i2c_stop(); - // test props - } else if (val == 'k') { - i2c_start_address(i2c_dev); - i2c_master_tx(CMD_SET_PWM); - i2c_master_tx(0x0f); - i2c_stop(); + for (val = 0; val < 10; val++) + _delay_ms(10); - // get Info - } else if (val == 'I') { i2c_start_address(i2c_dev); - i2c_master_tx(CMD_GET_INFO); + i2c_master_tx(CMD_READ_VERSION); i2c_start_address(i2c_dev | 0x01); uint8_t cnt; @@ -471,6 +462,62 @@ void cmd_loop(void) i2c_stop(); + sendchar(','); + + i2c_start_address(i2c_dev); + i2c_master_tx(CMD_READ_MEMORY); + i2c_master_tx(MEMTYPE_CHIPINFO); + i2c_master_tx(0x00); + i2c_master_tx(0x00); + i2c_start_address(i2c_dev | 0x01); + + uint8_t i; + for (i = 0; i < sizeof(chipinfo); i++) { + uint8_t more = (i < (sizeof(chipinfo) -1)); + i2c_master_rx(&chipinfo[i], more); + + sendchar('0'); + sendchar('x'); + print_byte(chipinfo[i]); + sendchar(more ? ',' : '>'); + } + i2c_stop(); + + // test props + } else if (val == 'k' || val == 'l') { + if (i2c_dev != 0) { + i2c_start_address(i2c_dev); + i2c_master_tx(0x00 + (val - 'k') * 0x10); + i2c_stop(); + + sendchar(val); + } + + // start Application / get Version + } else if (val == 'I') { + if (i2c_dev != 0) { + i2c_start_address(i2c_dev); + i2c_master_tx(CMD_SWITCH_APPLICATION); + i2c_master_tx(BOOTTYPE_APPLICATION); + i2c_stop(); + + for (val = 0; val < 10; val++) + _delay_ms(10); + + i2c_start_address(i2c_dev); + i2c_master_tx(CMD_READ_VERSION); + i2c_start_address(i2c_dev | 0x01); + + sendchar('<'); + uint8_t cnt; + for (cnt = 0; cnt < 16; cnt++) { + i2c_master_rx(&val, (cnt != 15)); + sendchar(val); + } + sendchar('>'); + i2c_stop(); + } + /* ESC */ } else if (val != 0x1b) { sendchar('?'); @@ -478,12 +525,28 @@ void cmd_loop(void) } } -static void (*jump_to_app)(void) = 0x0000; +static void (*jump_to_app)(void) __attribute__ ((noreturn)) = 0x0000; +/* + * For newer devices the watchdog timer remains active even after a + * system reset. So disable it as soon as possible. + * automagically called on startup + */ +#if defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__) +void disable_wdt_timer(void) __attribute__((naked, section(".init3"))); +void disable_wdt_timer(void) +{ + MCUSR = 0; + WDTCSR = (1<