From d53c24b1ca86fbdddb2d2fa6379a763f743f0853 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 21 May 2015 00:09:44 +0200 Subject: [PATCH] add bootloader --- bootloader/Makefile | 41 +++++ bootloader/main.c | 349 +++++++++++++++++++++++++++++++++++++++ bootloader/uart_config.h | 120 ++++++++++++++ 3 files changed, 510 insertions(+) create mode 100755 bootloader/Makefile create mode 100755 bootloader/main.c create mode 100755 bootloader/uart_config.h diff --git a/bootloader/Makefile b/bootloader/Makefile new file mode 100755 index 0000000..52543f8 --- /dev/null +++ b/bootloader/Makefile @@ -0,0 +1,41 @@ +TARGET = main + +# repertoire des modules +AVERSIVE_DIR ?= ../../.. +# VALUE, absolute or relative path : example ../.. # + +CFLAGS += -Werror + +# atm128 or atm1284 +# address is 0xf000 (in words) +LDFLAGS += -Wl,--section-start=.text=1e000 +UART_NUM = 1 + +# atm2560 +# address is 0x1f800 (in words) +# LDFLAGS += -Wl,--section-start=.text=3f000 +# UART_NUM = 1 + +CFLAGS += -DUART_NUM=$(UART_NUM) + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + +######################################## + +-include .aversive_conf +include $(AVERSIVE_DIR)/mk/aversive_project.mk + +program_noerase: $(TARGET).$(FORMAT_EXTENSION) $(TARGET).eep + echo $(AVRDUDE) -D -V $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) ;\ + $(AVRDUDE) -D -V $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) ;\ + diff --git a/bootloader/main.c b/bootloader/main.c new file mode 100755 index 0000000..cd0202e --- /dev/null +++ b/bootloader/main.c @@ -0,0 +1,349 @@ +/* + * Copyright Droids Corporation + * Olivier Matz + * + * 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 + * + * Revision : $Id: main.c,v 1.4 2009-05-27 20:04:06 zer0 Exp $ + * + */ + +/* + * A simple bootloader example. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#define NOECHO + +#ifdef NOECHO +#define echo(c) do {} while(0) +#else +#define echo(c) uart_send(c) +#endif + +#if UART_NUM == 0 + +#define UCSRxA UCSR0A +#define UCSRxB UCSR0B +#define UCSRxC UCSR0C +#define RXCx RXC0 +#define UDRx UDR0 +#define UDREx UDRE0 +#define U2Xx U2X0 +#define RXENx RXEN0 +#define TXENx TXEN0 +#define UCSZx0 UCSZ00 +#define UCSZx1 UCSZ01 +#define UBRRx UBRR0 + +#elif UART_NUM == 1 + +#define UCSRxA UCSR1A +#define UCSRxB UCSR1B +#define UCSRxC UCSR1C +#define RXCx RXC1 +#define UDRx UDR1 +#define UDREx UDRE1 +#define U2Xx U2X1 +#define RXENx RXEN1 +#define TXENx TXEN1 +#define UCSZx0 UCSZ10 +#define UCSZx1 UCSZ11 +#define UBRRx UBRR1 + +#elif UART_NUM == 2 + +#define UCSRxA UCSR2A +#define UCSRxB UCSR2B +#define UCSRxC UCSR2C +#define RXCx RXC2 +#define UDRx UDR2 +#define UDREx UDRE2 +#define U2Xx U2X2 +#define RXENx RXEN2 +#define TXENx TXEN2 +#define UCSZx0 UCSZ20 +#define UCSZx1 UCSZ21 +#define UBRRx UBRR2 + +#elif UART_NUM == 3 + +#define UCSRxA UCSR3A +#define UCSRxB UCSR3B +#define UCSRxC UCSR3C +#define RXCx RXC3 +#define UDRx UDR3 +#define UDREx UDRE3 +#define U2Xx U2X3 +#define RXENx RXEN3 +#define TXENx TXEN3 +#define UCSZx0 UCSZ30 +#define UCSZx1 UCSZ31 +#define UBRRx UBRR3 + +#endif + + +static char uart_recv(void) +{ + while ( !(UCSRxA & (1<= '0' && c <= '9') { + tmp <<= 4; + tmp += (c - '0'); + } + else if (c >= 'a' && c <= 'f') { + tmp <<= 4; + tmp += (c - 'a' + 10); + } + else if (c >= 'A' && c <= 'F') { + tmp <<= 4; + tmp += (c - 'A' + 10); + } + else + return -1; + } + return 0; +} + +/* launch application */ +static void launch_app(void) +{ + uart_puts("Boot..."); + MCUCR = (1 << IVCE); + MCUCR = (0 << IVSEL); + reset(); +} + +static void disp_digit(uint8_t x) +{ + if (x < 10) + x += '0'; + else + x += 'a' - 10 ; + uart_send(x); +} + +static void disp_hex8(uint8_t x) +{ + disp_digit(x>>4); + disp_digit(x&0xf); +} + +static void disp_hex16(uint16_t x) +{ + disp_hex8(x>>8); + disp_hex8(x); +} + +static void disp_hex32(uint32_t x) +{ + disp_hex16(x>>16); + disp_hex16(x); +} + +static void crc_app(void) +{ + uint32_t start_addr, addr, size; + uint8_t c; + uint16_t crc = 0xffff; + uint16_t sum = 0; + + uart_puts("addr?\r\n"); + if (bootloader_query_hex(&start_addr)) + goto fail; + if (start_addr > FLASHEND) + goto fail; + uart_puts("size?\r\n"); + if (bootloader_query_hex(&size)) + goto fail; + if (start_addr + size > FLASHEND) + goto fail; + for (addr=start_addr; addr= 256 && addr < 512) + continue; +#endif + c = pgm_read_byte_far(addr); + crc = _crc_ccitt_update(crc, c); + sum += c; + } + disp_hex16(crc); + disp_hex16(sum); + return; + fail: + uart_puts("KO"); +} + +static void read32(void) +{ + uint32_t start_addr, val = 0; + uint8_t c, i; + + uart_puts("addr?\r\n"); + if (bootloader_query_hex(&start_addr)) + goto fail; + if (start_addr > FLASHEND) + goto fail; + for (i=0; i<4; i++) { + c = pgm_read_byte_far(start_addr+i); + val <<= 8; + val |= c; + } + disp_hex32(val); + return; + fail: + uart_puts("KO"); +} + +static void prog_page(void) +{ + int c; + uint32_t addr; + uint16_t i; + uint16_t crc = 0xffff; + uint16_t sum = 0; + uint8_t buf[SPM_PAGESIZE]; + +#define SPM_PAGEMASK ((uint32_t)SPM_PAGESIZE-1) + uart_puts("addr?\r\n"); + if (bootloader_query_hex(&addr)) + goto fail; + if (addr > FLASHEND) + goto fail; + /* start_addr must be page aligned */ + if (addr & SPM_PAGEMASK) + goto fail; + + uart_puts("ok\r\n"); + + + /* data is received like the .bin format (which is already in + * little endian) */ + for (i=0; i "); + + /* timeout */ + while ( !(UCSRxA & (1<1000000) /* wait about 1 sec */ + launch_app(); + } + + while (1) { + uart_puts("\r\ncmd> "); + c = uart_recv(); + if (c == 'x') + launch_app(); + else if (c == 'c') + crc_app(); + else if (c == 'p') + prog_page(); + else if (c == 'd') + read32(); + else + uart_puts("p:prog_page c:crc x:exec d:dump32"); + } + + return 0; +} diff --git a/bootloader/uart_config.h b/bootloader/uart_config.h new file mode 100755 index 0000000..bdc9fa7 --- /dev/null +++ b/bootloader/uart_config.h @@ -0,0 +1,120 @@ +/* + * Copyright Droids Corporation, Microb Technology, Eirbot (2005) + * + * 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 + * + * Revision : $Id: uart_config.h,v 1.3 2009-05-27 20:04:06 zer0 Exp $ + * + */ + +/* Droids-corp 2004 - Zer0 + * config for uart module + */ + +#ifndef UART_CONFIG_H +#define UART_CONFIG_H + +#if UART_NUM == 0 + +/* compile uart0 fonctions, undefine it to pass compilation */ +#define UART0_COMPILE + +/* enable uart0 if == 1, disable if == 0 */ +#define UART0_ENABLED 1 + +/* enable uart0 interrupts if == 1, disable if == 0 */ +#define UART0_INTERRUPT_ENABLED 1 + +#define UART0_BAUDRATE 57600 + +#define UART0_USE_DOUBLE_SPEED 0 + +#define UART0_RX_FIFO_SIZE 64 +#define UART0_TX_FIFO_SIZE 16 + +#define UART0_NBITS 8 +#define UART0_PARITY UART_PARTITY_NONE +#define UART0_STOP_BIT UART_STOP_BITS_1 + +#elif UART_NUM == 1 + +/* compile uart1 fonctions, undefine it to pass compilation */ +#define UART1_COMPILE + +/* enable uart1 if == 1, disable if == 0 */ +#define UART1_ENABLED 1 + +/* enable uart1 interrupts if == 1, disable if == 0 */ +#define UART1_INTERRUPT_ENABLED 1 + +#define UART1_BAUDRATE 57600 + +#define UART1_USE_DOUBLE_SPEED 0 + +#define UART1_RX_FIFO_SIZE 32 +#define UART1_TX_FIFO_SIZE 4 + +#define UART1_NBITS 8 +#define UART1_PARITY UART_PARTITY_NONE +#define UART1_STOP_BIT UART_STOP_BITS_1 + +#elif UART_NUM == 2 + +/* compile uart2 fonctions, undefine it to pass compilation */ +#define UART2_COMPILE + +/* enable uart2 if == 1, disable if == 0 */ +#define UART2_ENABLED 1 + +/* enable uart2 interrupts if == 1, disable if == 0 */ +#define UART2_INTERRUPT_ENABLED 1 + +#define UART2_BAUDRATE 57600 + +#define UART2_USE_DOUBLE_SPEED 0 + +#define UART2_RX_FIFO_SIZE 32 +#define UART2_TX_FIFO_SIZE 4 + +#define UART2_NBITS 8 +#define UART2_PARITY UART_PARTITY_NONE +#define UART2_STOP_BIT UART_STOP_BITS_1 + +#elif UART_NUM == 3 + +/* compile uart3 fonctions, undefine it to pass compilation */ +#define UART3_COMPILE + +/* enable uart3 if == 1, disable if == 0 */ +#define UART3_ENABLED 1 + +/* enable uart3 interrupts if == 1, disable if == 0 */ +#define UART3_INTERRUPT_ENABLED 1 + +#define UART3_BAUDRATE 57600 + +#define UART3_USE_DOUBLE_SPEED 0 + +#define UART3_RX_FIFO_SIZE 32 +#define UART3_TX_FIFO_SIZE 4 + +#define UART3_NBITS 8 +#define UART3_PARITY UART_PARTITY_NONE +#define UART3_STOP_BIT UART_STOP_BITS_1 + +#endif /* uart num */ + +#endif + -- 2.20.1