diff --git a/optiboot/bootloaders/optiboot/Makefile.custom b/optiboot/bootloaders/optiboot/Makefile.custom index 4d08dd7b2..722469e27 100644 --- a/optiboot/bootloaders/optiboot/Makefile.custom +++ b/optiboot/bootloaders/optiboot/Makefile.custom @@ -13,3 +13,25 @@ wildfire: mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst +atmega16m1: MCU_TARGET = atmega16m1 +atmega16m1: CFLAGS += $(COMMON_OPTIONS) +atmega16m1: AVR_FREQ = 16000000L +atmega16m1: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffc +atmega16m1: $(PROGRAM)_atmega16m1.hex +atmega16m1: $(PROGRAM)_atmega16m1.lst + +mega16m1: TARGET = mega16m1 +mega16m1: CHIP = atmega16m1 +mega16m1: + $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=D0 + mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex + mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst + +mega16m1_isp: mega16m1 +mega16m1_isp: TARGET = mega16m1 +mega16m1_isp: MCU_TARGET = atmega16m1 +mega16m1_isp: HFUSE = DE +mega16m1_isp: LFUSE = DE +mega16m1_isp: EFUSE = FF +mega16m1_isp: isp + diff --git a/optiboot/bootloaders/optiboot/avrdude.rc b/optiboot/bootloaders/optiboot/avrdude.rc new file mode 100644 index 000000000..94920cb0f --- /dev/null +++ b/optiboot/bootloaders/optiboot/avrdude.rc @@ -0,0 +1,30 @@ +# +# Archivo para agregar soporte del atmega16m1 al avrdude +# +# Para que este archivo sea reconocido hay que: +# - En Windows: copiar este archivo (avrdude.rc) al mismo +# directorio del programa avrdude.exe +# - En Linux: copiar este archivo con el nombre .avrduderc +# en el directorio HOME +# +# http://www.nongnu.org/avrdude/user-manual/avrdude_10.html + +#------------------------------------------------------------ +# ATmega16m1 +#------------------------------------------------------------ + +part parent "m328" + id = "m16m1"; + desc = "ATmega16M1"; + # stk500_devcode = 0x; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x84; + bs2 = 0xe2; + + memory "efuse" + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x i i i i i i"; + ; +; diff --git a/optiboot/bootloaders/optiboot/optiboot.c b/optiboot/bootloaders/optiboot/optiboot.c index df807ab13..e45571910 100644 --- a/optiboot/bootloaders/optiboot/optiboot.c +++ b/optiboot/bootloaders/optiboot/optiboot.c @@ -236,7 +236,7 @@ #define OPTIBOOT_CUSTOMVER 0 #endif -unsigned const int __attribute__((section(".version"))) +unsigned const int __attribute__((section(".version"))) optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; @@ -288,8 +288,14 @@ optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; #define UART 0 #endif +#if defined(__AVR_ATmega16M1__) || defined(__AVR_ATmega32M1__) || defined(__AVR_ATmega64M1__) +#define BAUD_SETTING ( (F_CPU)/(BAUD_RATE * 8L) - 1 ) +#define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1))) +#else #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 ) #define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1))) +#endif + #if BAUD_ACTUAL <= BAUD_RATE #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE) #if BAUD_ERROR >= 5 @@ -306,14 +312,26 @@ optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; #endif #endif +#if defined(__AVR_ATmega16M1__) || defined(__AVR_ATmega32M1__) || defined(__AVR_ATmega64M1__) +// don't know how to choose the numbers +#if BAUD_SETTING > ( (1 << 12) - 1 ) +#error Unachievable baud rate (too slow) BAUD_RATE +#endif // baud rate slow check +#if BAUD_SETTING < 3 +#if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero +#error Unachievable baud rate (too fast) BAUD_RATE +#endif +#endif // baud rate fastn check +#else #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250 -#error Unachievable baud rate (too slow) BAUD_RATE +#error Unachievable baud rate (too slow) BAUD_RATE #endif // baud rate slow check #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3 #if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero -#error Unachievable baud rate (too fast) BAUD_RATE +#error Unachievable baud rate (too fast) BAUD_RATE #endif #endif // baud rate fastn check +#endif /* Watchdog settings */ #define WATCHDOG_OFF (0) @@ -495,6 +513,13 @@ int main(void) { UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#elif defined(__AVR_ATmega16M1__) || defined(__AVR_ATmega32M1__) || defined(__AVR_ATmega64M1__) + // USART 8N1, enable RX and TX + LINCR = (0 << LCONF1) | (0 << LCONF0) | (0 << LENA) | (1 << LCMD2) | (1 << LCMD1) | (1 << LCMD0); + LINENIR = 0; // disable interrupts + LINBTR = (1 << LDISR) | 8; // 8 samples per bit + LINBRR = (uint16_t)( F_CPU/(8*BAUD_RATE)-1); + LINCR |= (1 << LENA); #else UART_SRA = _BV(U2X0); //Double speed mode USART0 UART_SRB = _BV(RXEN0) | _BV(TXEN0); @@ -684,8 +709,13 @@ int main(void) { void putch(char ch) { #ifndef SOFT_UART +#if defined(__AVR_ATmega16M1__) || defined(__AVR_ATmega32M1__) || defined(__AVR_ATmega64M1__) + while ( LINSIR & _BV(LBUSY)); + LINDAT = ch; +#else while (!(UART_SRA & _BV(UDRE0))); UART_UDR = ch; +#endif #else __asm__ __volatile__ ( " com %[ch]\n" // ones complement, carry set @@ -748,6 +778,23 @@ uint8_t getch(void) { : "r25" ); +#else +#if defined(__AVR_ATmega16M1__) || defined(__AVR_ATmega32M1__) || defined(__AVR_ATmega64M1__) +while(!(LINSIR & _BV(LRXOK))) + ; +if (!(LINERR & _BV(LFERR))) { + /* + * A Framing Error indicates (probably) that something is talking + * to us at the wrong bit rate. Assume that this is because it + * expects to be talking to the application, and DON'T reset the + * watchdog. This should cause the bootloader to abort and run + * the application "soon", if it keeps happening. (Note that we + * don't care that an invalid char is returned...) + */ + watchdogReset(); +} + +ch = LINDAT; #else while(!(UART_SRA & _BV(RXC0))) ; @@ -765,6 +812,7 @@ uint8_t getch(void) { ch = UART_UDR; #endif +#endif #ifdef LED_DATA_FLASH #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)