├── arduino_dualboot.out ├── uart.h ├── uart.c ├── i2c.h ├── Makefile ├── README.txt ├── stk500.h ├── i2c.c ├── arduino_dualboot.hex ├── main.c ├── pin_defs.h ├── tags └── boot.h /arduino_dualboot.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinodstanur/arduino_dualboot_bootlaoder/HEAD/arduino_dualboot.out -------------------------------------------------------------------------------- /uart.h: -------------------------------------------------------------------------------- 1 | #ifndef __UART_H_ 2 | #define __UART_H_ 3 | 4 | /*=========================================================================== 5 | * Function declaration 6 | *===========================================================================*/ 7 | void putch(uint8_t); 8 | uint8_t getch(); 9 | void uart_init(); 10 | 11 | #endif //#ifndef __UART_H_ 12 | 13 | -------------------------------------------------------------------------------- /uart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define F_CPU 16000000UL 3 | #include 4 | #include "uart.h" 5 | 6 | #define USART_BAUD 115200UL 7 | #define BAUDRATE (F_CPU/(8UL*USART_BAUD))-1 8 | 9 | void uart_init() 10 | { 11 | /* Set baud rate */ 12 | UBRR0H = (uint8_t) ((BAUDRATE) >> 8); 13 | UBRR0L = (uint8_t) BAUDRATE; 14 | UCSR0B = (1 << RXEN0) | (1 << TXEN0); // | (1 << RXCIE0); 15 | UCSR0C = (3 << UCSZ00); 16 | UCSR0A = 1 << U2X0; 17 | } 18 | 19 | void putch(uint8_t c) 20 | { 21 | while (!(UCSR0A & (1 << UDRE0))) ; 22 | UDR0 = c; 23 | } 24 | 25 | uint8_t getch(void) 26 | { 27 | while (!(UCSR0A & (1 << RXC0))) ; 28 | return UDR0; 29 | } 30 | -------------------------------------------------------------------------------- /i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef I2C_MASTER_H 2 | #define I2C_MASTER_H 3 | 4 | #define I2C_READ 0x01 5 | #define I2C_WRITE 0x00 6 | 7 | void i2c_init(void); 8 | uint8_t i2c_start(uint8_t address); 9 | uint8_t i2c_write(uint8_t data); 10 | uint8_t i2c_read_ack(void); 11 | uint8_t i2c_read_nack(void); 12 | uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length); 13 | uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length); 14 | uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); 15 | uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); 16 | void i2c_stop(void); 17 | 18 | #endif // I2C_MASTER_H 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | # Makefile for arduino_dualboot hack 3 | # visit http://blog.vinu.co.in for more details 4 | ################################################################### 5 | 6 | PROJECT=arduino_dualboot 7 | SOURCES=main.c i2c.c uart.c 8 | CC=avr-gcc 9 | OBJCOPY=avr-objcopy 10 | MMCU=atmega328p 11 | LD_FLAGS = -Wl,--section-start=.text=0x7800 12 | C_FLAGS = -mmcu=$(MMCU) -Os -Wall -std=c99 13 | PROGRAMMER=usbasp 14 | BURN=avrdude 15 | MCU=m328p 16 | 17 | 18 | $(PROJECT).hex: $(PROJECT).out 19 | $(OBJCOPY) -j .text -j .data -O ihex $(PROJECT).out $(PROJECT).hex 20 | 21 | 22 | $(PROJECT).out: $(SOURCES) 23 | $(CC) $(C_FLAGS) $(LD_FLAGS) -I./ -o $(PROJECT).out $(SOURCES) 24 | avr-size $(PROJECT).out 25 | 26 | p: $(PROJECT).hex 27 | $(BURN) -c $(PROGRAMMER) -p $(MCU) -U flash:w:$(PROJECT).hex 28 | 29 | f: 30 | $(BURN) -c $(PROGRAMMER) -p $(MCU) -U lfuse:w:0xef:m -U hfuse:w:0xda:m -U efuse:w:0xfd:m 31 | 32 | clean: 33 | rm -f *.hex *.out 34 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2 | This is a modified arduino bootloader which supports dual boot. Here the trick is to save a backup ROM in external eeprom which is then invoked from the bootloader on hardware reset. This dualboot feature will be invoked only if the pin 10 and 9 of arduino (here uno/pro mini) is shorted before and while a hardware reset is performed. After hardwareset the on board LED will glow for 1 seconds if the pin 10 and 11 are shorted while reset is performed. If we remove the short before 1 seconds (ie before the LED is turned off), then it enter into dualboot operation. It do a swap operation ie it will backup the current ROM to external eeprom and writes the existing rom in external eeprom to internal flash and starts booting into the new ROM. If we do the same again, the reverse will happen as we are swapping between the backup ROM and current ROM. 3 | 4 | At that same time, this is arduino supported bootloader so we can upload sketches via arduino software or commandline as usual. 5 | 6 | Currently You can try with UNO as the board even if the baord is pro-mini-16. Bootloader works at 115200 BAUD. 7 | 8 | For detailed explanation please visit http://blog.vinu.co.in 9 | -------------------------------------------------------------------------------- /stk500.h: -------------------------------------------------------------------------------- 1 | /* STK500 constants list, from AVRDUDE 2 | * 3 | * Trivial set of constants derived from Atmel App Note AVR061 4 | * Not copyrighted. Released to the public domain. 5 | */ 6 | 7 | #define STK_OK 0x10 8 | #define STK_FAILED 0x11 // Not used 9 | #define STK_UNKNOWN 0x12 // Not used 10 | #define STK_NODEVICE 0x13 // Not used 11 | #define STK_INSYNC 0x14 // ' ' 12 | #define STK_NOSYNC 0x15 // Not used 13 | #define ADC_CHANNEL_ERROR 0x16 // Not used 14 | #define ADC_MEASURE_OK 0x17 // Not used 15 | #define PWM_CHANNEL_ERROR 0x18 // Not used 16 | #define PWM_ADJUST_OK 0x19 // Not used 17 | #define CRC_EOP 0x20 // 'SPACE' 18 | #define STK_GET_SYNC 0x30 // '0' 19 | #define STK_GET_SIGN_ON 0x31 // '1' 20 | #define STK_SET_PARAMETER 0x40 // '@' 21 | #define STK_GET_PARAMETER 0x41 // 'A' 22 | #define STK_SET_DEVICE 0x42 // 'B' 23 | #define STK_SET_DEVICE_EXT 0x45 // 'E' 24 | #define STK_ENTER_PROGMODE 0x50 // 'P' 25 | #define STK_LEAVE_PROGMODE 0x51 // 'Q' 26 | #define STK_CHIP_ERASE 0x52 // 'R' 27 | #define STK_CHECK_AUTOINC 0x53 // 'S' 28 | #define STK_LOAD_ADDRESS 0x55 // 'U' 29 | #define STK_UNIVERSAL 0x56 // 'V' 30 | #define STK_PROG_FLASH 0x60 // '`' 31 | #define STK_PROG_DATA 0x61 // 'a' 32 | #define STK_PROG_FUSE 0x62 // 'b' 33 | #define STK_PROG_LOCK 0x63 // 'c' 34 | #define STK_PROG_PAGE 0x64 // 'd' 35 | #define STK_PROG_FUSE_EXT 0x65 // 'e' 36 | #define STK_READ_FLASH 0x70 // 'p' 37 | #define STK_READ_DATA 0x71 // 'q' 38 | #define STK_READ_FUSE 0x72 // 'r' 39 | #define STK_READ_LOCK 0x73 // 's' 40 | #define STK_READ_PAGE 0x74 // 't' 41 | #define STK_READ_SIGN 0x75 // 'u' 42 | #define STK_READ_OSCCAL 0x76 // 'v' 43 | #define STK_READ_FUSE_EXT 0x77 // 'w' 44 | #define STK_READ_OSCCAL_EXT 0x78 // 'x' 45 | #define STK_SW_MAJOR 0x81 // ' ' 46 | #define STK_SW_MINOR 0x82 // ' ' 47 | -------------------------------------------------------------------------------- /i2c.c: -------------------------------------------------------------------------------- 1 | #ifndef F_CPU 2 | #define F_CPU 16000000UL 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | #include "i2c.h" 9 | 10 | #define F_SCL 100000UL // SCL frequency 11 | #define Prescaler 1 12 | #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2) 13 | 14 | void i2c_init(void) 15 | { 16 | TWBR = (uint8_t) TWBR_val; 17 | } 18 | 19 | uint8_t i2c_start(uint8_t address) 20 | { 21 | // reset TWI control register 22 | TWCR = 0; 23 | // transmit START condition 24 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); 25 | // wait for end of transmission 26 | while (!(TWCR & (1 << TWINT))) ; 27 | 28 | // check if the start condition was successfully transmitted 29 | if ((TWSR & 0xF8) != TW_START) { 30 | return 1; 31 | } 32 | // load slave address into data register 33 | TWDR = address; 34 | // start transmission of address 35 | TWCR = (1 << TWINT) | (1 << TWEN); 36 | // wait for end of transmission 37 | while (!(TWCR & (1 << TWINT))) ; 38 | 39 | // check if the device has acknowledged the READ / WRITE mode 40 | uint8_t twst = TW_STATUS & 0xF8; 41 | if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) 42 | return 1; 43 | 44 | return 0; 45 | } 46 | 47 | uint8_t i2c_write(uint8_t data) 48 | { 49 | // load data into data register 50 | TWDR = data; 51 | // start transmission of data 52 | TWCR = (1 << TWINT) | (1 << TWEN); 53 | // wait for end of transmission 54 | while (!(TWCR & (1 << TWINT))) ; 55 | 56 | if ((TWSR & 0xF8) != TW_MT_DATA_ACK) { 57 | return 1; 58 | } 59 | 60 | return 0; 61 | } 62 | 63 | uint8_t i2c_read_ack(void) 64 | { 65 | 66 | // start TWI module and acknowledge data after reception 67 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); 68 | // wait for end of transmission 69 | while (!(TWCR & (1 << TWINT))) ; 70 | // return received data from TWDR 71 | return TWDR; 72 | } 73 | 74 | uint8_t i2c_read_nack(void) 75 | { 76 | 77 | // start receiving without acknowledging reception 78 | TWCR = (1 << TWINT) | (1 << TWEN); 79 | // wait for end of transmission 80 | while (!(TWCR & (1 << TWINT))) ; 81 | // return received data from TWDR 82 | return TWDR; 83 | } 84 | 85 | uint8_t i2c_transmit(uint8_t address, uint8_t * data, uint16_t length) 86 | { 87 | if (i2c_start(address | I2C_WRITE)) 88 | return 1; 89 | 90 | for (uint16_t i = 0; i < length; i++) { 91 | if (i2c_write(data[i])) 92 | return 1; 93 | } 94 | 95 | i2c_stop(); 96 | 97 | return 0; 98 | } 99 | 100 | uint8_t i2c_receive(uint8_t address, uint8_t * data, uint16_t length) 101 | { 102 | if (i2c_start(address | I2C_READ)) 103 | return 1; 104 | 105 | for (uint16_t i = 0; i < (length - 1); i++) { 106 | data[i] = i2c_read_ack(); 107 | } 108 | data[(length - 1)] = i2c_read_nack(); 109 | 110 | i2c_stop(); 111 | 112 | return 0; 113 | } 114 | 115 | uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t * data, 116 | uint16_t length) 117 | { 118 | if (i2c_start(devaddr | 0x00)) 119 | return 1; 120 | 121 | i2c_write(regaddr); 122 | 123 | for (uint16_t i = 0; i < length; i++) { 124 | if (i2c_write(data[i])) 125 | return 1; 126 | } 127 | 128 | i2c_stop(); 129 | 130 | return 0; 131 | } 132 | 133 | uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t * data, 134 | uint16_t length) 135 | { 136 | if (i2c_start(devaddr)) 137 | return 1; 138 | 139 | i2c_write(regaddr); 140 | 141 | if (i2c_start(devaddr | 0x01)) 142 | return 1; 143 | 144 | for (uint16_t i = 0; i < (length - 1); i++) { 145 | data[i] = i2c_read_ack(); 146 | } 147 | data[(length - 1)] = i2c_read_nack(); 148 | 149 | i2c_stop(); 150 | 151 | return 0; 152 | } 153 | 154 | void i2c_stop(void) 155 | { 156 | // transmit STOP condition 157 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); 158 | } 159 | -------------------------------------------------------------------------------- /arduino_dualboot.hex: -------------------------------------------------------------------------------- 1 | :107800000C94343C0C94463C0C94463C0C94463C02 2 | :107810000C94463C0C94463C0C94463C0C94463CE0 3 | :107820000C94463C0C94463C0C94463C0C94463CD0 4 | :107830000C94463C0C94463C0C94463C0C94463CC0 5 | :107840000C94463C0C94463C0C94463C0C94463CB0 6 | :107850000C94463C0C94463C0C94463C0C94463CA0 7 | :107860000C94463C0C94463C11241FBECFEFD8E04C 8 | :10787000DEBFCDBF21E0A0E0B1E001C01D92AA3C77 9 | :10788000B207E1F70E94103E0C94553F0C94003C67 10 | :10789000E0E6F0E088E180831082EE27FF2709947C 11 | :1078A00008950E94093E803239F088E1809360009B 12 | :1078B0008EE080936000FFCF84E10C94023ECF9372 13 | :1078C000C82F0E94093EC150E1F7CF910C94513C62 14 | :1078D000E0E6F0E098E1908380830895A89508950C 15 | :1078E000CF92DF92EF92FF920F931F93CF93DF938C 16 | :1078F00000D01F92CDB7DEB76B0149838A839B838B 17 | :107900000E946E3C23E0F60127BFE8959B818A81A7 18 | :10791000498107B600FCFDCFDC01B601681B790B7D 19 | :1079200021E0480F7D01E60EF71E8C9112968D0125 20 | :1079300001501109F801308190E0932BF7010C01FF 21 | :1079400027BFE89511244A13EDCF85E0F60187BFE4 22 | :10795000E89507B600FCFDCF81E180935700E895DC 23 | :10796000FFFF00000F900F900F90DF91CF911F91BC 24 | :107970000F91FF90EF90DF90CF90089588E480936F 25 | :10798000B80008951092BC0094EA9093BC009091C6 26 | :10799000BC0097FFFCCF9091B900987F983011F010 27 | :1079A00081E008958093BB0084E88093BC008091BF 28 | :1079B000BC0087FFFCCF8091B900887F883111F02F 29 | :1079C000803471F780E008958093BB0084E8809351 30 | :1079D000BC008091BC0087FFFCCF9091B900987FDC 31 | :1079E00081E0983209F480E0089584EC8093BC0033 32 | :1079F0008091BC0087FFFCCF8091BB00089584E894 33 | :107A00008093BC008091BC0087FFFCCF8091BB00BD 34 | :107A10000895CF92DF92EF92FF921F93CF93DF935F 35 | :107A200000D0CDB7DEB77A0169837A830E94C23C69 36 | :107A3000182F69817A8181110DC06B01EC0CFD1C3E 37 | :107A4000CE14DF0449F0F60181916F010E94E43CFD 38 | :107A50008823B1F311E003C084E98093BC00812F37 39 | :107A60000F900F90DF91CF911F91FF90EF90DF90DB 40 | :107A7000CF900895AF92BF92CF92DF92FF920F9373 41 | :107A80001F93CF93DF936B018A0181600E94C23CF8 42 | :107A9000F82E811118C05601E8012197C5018C19F3 43 | :107AA0009D098C179D0730F40E94F53CF5018193E8 44 | :107AB0005F01F4CFCC0DDD1D0E94FF3C888384E97B 45 | :107AC0008093BC0002C0FF24F3948F2DDF91CF91EF 46 | :107AD0001F910F91FF90DF90CF90BF90AF900895CE 47 | :107AE000AF92BF92DF92EF92FF920F931F93CF93CB 48 | :107AF000DF931F92CDB7DEB7D42E052F79016983AE 49 | :107B00000E94C23C182F6981882311F011E015C032 50 | :107B1000862F0E94E43CAD2CB02EEA0CFB1CAE1468 51 | :107B2000BF0441F0F50181915F010E94E43C88238C 52 | :107B3000B1F3ECCF84E98093BC00812F0F90DF91EB 53 | :107B4000CF911F910F91FF90EF90DF90BF90AF907A 54 | :107B50000895AF92BF92CF92DF92FF920F931F933F 55 | :107B6000CF93DF931F92CDB7DEB7F82E6A0189015C 56 | :107B700069830E94C23C6981882319F0FF24F39431 57 | :107B800022C0862F0E94E43C8F2D81600E94C23C5F 58 | :107B9000F82E8111F3CF560101501109C5018C193E 59 | :107BA0009D098017910730F40E94F53CF5018193FF 60 | :107BB0005F01F4CFC00ED11E0E94FF3CF60180830E 61 | :107BC00084E98093BC008F2D0F90DF91CF911F919E 62 | :107BD0000F91FF90DF90CF90BF90AF90089584E910 63 | :107BE0008093BC0008951092C50080E18093C4008A 64 | :107BF00088E18093C10086E08093C20082E0809398 65 | :107C0000C00008959091C00095FFFCCF8093C600FE 66 | :107C100008958091C00087FFFCCF8091C600089531 67 | :107C2000CF93DF93CDB7DEB7C350D1400FB6F894F2 68 | :107C3000DEBF0FBECDBF84B714BE98E19093600045 69 | :107C4000109260008D7011F00E94483C2D98259A8A 70 | :107C50002A98229A2B9A23988FE39CE90197F1F7AF 71 | :107C600000C000002D9A1B9985C09FEFA3EDB0E3E3 72 | :107C70009150A040B040E1F700C000002D981B9B40 73 | :107C80000E94483C0E94BE3C88E1809360001092B4 74 | :107C9000600000E010E07E01E1E8EE0EF11CCE0194 75 | :107CA00001966C01DE01AF5FBE4FCF5FDE4FB9833F 76 | :107CB000A883C150D14080EA0E94C23C8111FBCF11 77 | :107CC000212E812F0E94E43C302E802F0E94E43C24 78 | :107CD00081EA0E94C23C47015601260138016C1816 79 | :107CE0007D080E94F53CF40181934F01F201E60DFD 80 | :107CF000F71DE491D201ED932D01CF5FDE4FE881B6 81 | :107D0000F981C150D1408E169F0659F70E94EF3D70 82 | :107D100080EA0E94C23C822D0E94E43C832D0E9496 83 | :107D2000E43CD5018D915D010E94E43CAE14BF049A 84 | :107D3000C1F70E94EF3D40E8B801C7010E94703CC6 85 | :107D4000EFE3FFE13197F1F700C0000000581F4F4B 86 | :107D500085B1F0E28F2785B9011520E7120709F0F8 87 | :107D6000AACF1B9BFECF88E18093600088E08093C0 88 | :107D70006000FFCF0E94F33D88E1809360008EE0B9 89 | :107D8000809360000E946E3C00E010E028E1E22E4B 90 | :107D90003EE0932E42E0C42E41E0D42E0E94093EE4 91 | :107DA0008134D1F40E94093ECD5FDE4F8883C350F9 92 | :107DB000D1400E94513CCD5FDE4F8881C350D140FD 93 | :107DC000823811F482E005C0813811F486E001C0E8 94 | :107DD00083E00E94023E65C0823411F484E103C056 95 | :107DE000853421F485E00E945F3C5BC0853551F409 96 | :107DF0000E94093E082F0E94093E10E0182B000F38 97 | :107E0000111F4DC0863529F484E00E945F3C80E05C 98 | :107E1000E0CF8436E9F40E94093E0E94093EF82E24 99 | :107E20000E94093E82E0A82E81E0B82E8F2C8C0C97 100 | :107E30000E94093ED5018D935D018A12F9CF0E94FF 101 | :107E4000513C4F2DB80182E091E00E94703C29C066 102 | :107E5000843799F40E94093E0E94093EF82E0E9440 103 | :107E6000093E0E94513C5801F50185915F010E9435 104 | :107E7000023EFA94F110F8CF14C0853751F40E94F5 105 | :107E8000513C8EE10E94023E85E90E94023E8FE055 106 | :107E9000A0CF813521F4E0926000909260000E94B2 107 | :0E7EA000513C80E10E94023E79CFF894FFCF62 108 | :040000030000780081 109 | :00000001FF 110 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Vinod S 3 | http://blog.vinu.co.in 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | */ 19 | 20 | #include 21 | #define F_CPU 16000000 22 | #include 23 | #include "uart.h" 24 | #include "i2c.h" 25 | #include "boot.h" 26 | #include 27 | #include 28 | #include "stk500.h" 29 | #include "pin_defs.h" 30 | 31 | /////////////////////// definitions ///////////////////////////////////////////////////// 32 | #define FUNC_READ 1 33 | #define FUNC_WRITE 1 34 | #define ER 0b10100001 35 | #define EW 0b10100000 36 | #define OPTIBOOT_MAJVER 6 37 | #define OPTIBOOT_MINVER 2 38 | #define LED_START_FLASHES 0 39 | #define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch() 40 | #define save_vect_num (SPM_RDY_vect_num) 41 | #define appstart_vec (save_vect_num*2) 42 | #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE)) 43 | #define WATCHDOG_OFF (0) 44 | #define WATCHDOG_16MS (_BV(WDE)) 45 | 46 | ////////////////////// global variables //////////////////////////////////////////////// 47 | volatile uint16_t dd = 0; 48 | typedef uint8_t pagelen_t; 49 | uint8_t buff[200]; 50 | 51 | ///////////////////// function prototypes ////////////////////////////////////////////// 52 | static inline void writebuffer(int8_t memtype, uint8_t * mybuff, 53 | uint16_t address, pagelen_t len); 54 | static inline void read_mem(uint8_t memtype, uint16_t address, 55 | pagelen_t length); 56 | void watchdogReset(); 57 | void verifySpace(); 58 | void watchdogConfig(uint8_t x); 59 | void getNch(uint8_t count); 60 | 61 | //////////////////// JUMP to main application function //////////////////////////////// 62 | void app_start(void) 63 | { 64 | 65 | watchdogConfig(WATCHDOG_OFF); 66 | __asm__ __volatile__("clr r30\n" "clr r31\n" "ijmp"); 67 | } 68 | 69 | ///////////////// main function //////////////////////////////////////////////////////// 70 | int main() 71 | { 72 | 73 | uint8_t ch; 74 | uint16_t address = 0; 75 | 76 | pagelen_t length; 77 | 78 | ch = MCUSR; 79 | MCUSR = 0; 80 | 81 | watchdogConfig(WATCHDOG_OFF); 82 | 83 | if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF))) 84 | app_start(); 85 | 86 | PORTB &= ~(1 << PB5); 87 | DDRB |= 1 << PB5; 88 | 89 | //PIN 10 of arduino as ZERO 90 | PORTB &= ~(1 << PB2); 91 | //enable pin10 as output 92 | DDRB |= 1 << PB2; 93 | 94 | //PULL UP pin 11 of arduino 95 | PORTB |= 1 << PB3; 96 | //enable pin11 as input. 97 | DDRB &= ~(1 << PB3); 98 | 99 | _delay_ms(10); 100 | 101 | //check if 10 and 11 is shorted while MCU is reset. 102 | 103 | //LED ON 104 | PORTB |= 1 << PB5; 105 | 106 | if ((PINB & (1 << PB3)) == 0) { 107 | 108 | uint8_t buff2[128]; 109 | uint8_t buff1[128]; 110 | _delay_ms(1000); 111 | PORTB &= ~(1 << PB5); 112 | if ((PINB & (1 << PB3)) == 0) { 113 | app_start(); 114 | } 115 | 116 | i2c_init(); 117 | 118 | watchdogConfig(WATCHDOG_OFF); 119 | uint16_t addr = 0; 120 | for (int i = 0; i < 224; i++) { 121 | while (i2c_start(EW)) ; 122 | i2c_write(addr >> 8); 123 | i2c_write(addr); 124 | i2c_start(ER); 125 | //read one page from i2c eeprom 126 | //read one page from internal flash 127 | for (int j = 0; j < 128; j++) { 128 | buff2[j] = i2c_read_ack(); 129 | buff1[j] = pgm_read_byte_near(addr + j); 130 | } 131 | i2c_stop(); 132 | i2c_start(EW); 133 | i2c_write(addr >> 8); 134 | i2c_write(addr); 135 | //write the page read from internal flash to i2c eeprom. (Swap write) 136 | for (int j = 0; j < 128; j++) { 137 | i2c_write(buff1[j]); 138 | } 139 | 140 | i2c_stop(); 141 | 142 | //write the page read from external eeprom to internal flash. 143 | writebuffer(0, buff2, addr, 128); 144 | 145 | _delay_ms(2); 146 | 147 | //increment page address. Here both flash and eeprom are of same page size. 148 | addr += 128; 149 | 150 | //toggle LED 151 | PORTB ^= 1 << PB5; 152 | } 153 | 154 | // wait while dualboot enable pin is LOW 155 | while ((PINB & (1 << PB3)) == 0) ; 156 | 157 | //forcefull watchdog reset for app start. 158 | watchdogConfig(WATCHDOG_16MS); 159 | while (1) ; 160 | } 161 | 162 | uart_init(); 163 | watchdogConfig(WATCHDOG_1S); 164 | watchdogReset(); 165 | 166 | for (;;) { 167 | /* get character from UART */ 168 | ch = getch(); 169 | 170 | if (ch == STK_GET_PARAMETER) { 171 | unsigned char which = getch(); 172 | verifySpace(); 173 | /* 174 | * Send optiboot version as "SW version" 175 | * Note that the references to memory are optimized away. 176 | */ 177 | if (which == STK_SW_MINOR) { 178 | putch((256 * 6 + 2) & 0xFF); 179 | } else if (which == STK_SW_MAJOR) { 180 | putch((256 * 6 + 2) >> 8); 181 | } else { 182 | /* 183 | * GET PARAMETER returns a generic 0x03 reply for 184 | * other parameters - enough to keep Avrdude happy 185 | */ 186 | putch(0x03); 187 | } 188 | } else if (ch == STK_SET_DEVICE) { 189 | // SET DEVICE is ignored 190 | getNch(20); 191 | } else if (ch == STK_SET_DEVICE_EXT) { 192 | // SET DEVICE EXT is ignored 193 | getNch(5); 194 | } else if (ch == STK_LOAD_ADDRESS) { 195 | // LOAD ADDRESS 196 | uint16_t newAddress; 197 | 198 | newAddress = getch(); 199 | newAddress = (newAddress & 0xff) | (getch() << 8); 200 | 201 | newAddress += newAddress; // Convert from word address to byte address 202 | address = newAddress; 203 | verifySpace(); 204 | } else if (ch == STK_UNIVERSAL) { 205 | // UNIVERSAL command is ignored 206 | getNch(4); 207 | putch(0x00); 208 | } 209 | /* Write memory, length is big endian and is in bytes */ 210 | else if (ch == STK_PROG_PAGE) { 211 | // PROGRAM PAGE - we support flash programming only, not EEPROM 212 | uint8_t desttype; 213 | uint8_t *bufPtr; 214 | pagelen_t savelength; 215 | 216 | GETLENGTH(length); 217 | savelength = length; 218 | desttype = getch(); 219 | 220 | // read a page worth of contents 221 | bufPtr = buff; 222 | do 223 | *bufPtr++ = getch(); 224 | while (--length); 225 | 226 | // Read command terminator, start reply 227 | verifySpace(); 228 | 229 | writebuffer(desttype, buff, address, savelength); 230 | 231 | } 232 | /* Read memory block mode, length is big endian. */ 233 | else if (ch == STK_READ_PAGE) { 234 | uint8_t desttype; 235 | GETLENGTH(length); 236 | 237 | desttype = getch(); 238 | 239 | verifySpace(); 240 | 241 | read_mem(desttype, address, length); 242 | } 243 | 244 | /* Get device signature bytes */ 245 | else if (ch == STK_READ_SIGN) { 246 | // READ SIGN - return what Avrdude wants to hear 247 | verifySpace(); 248 | putch(SIGNATURE_0); 249 | putch(SIGNATURE_1); 250 | putch(SIGNATURE_2); 251 | } 252 | 253 | else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ 254 | // Adaboot no-wait mod 255 | watchdogConfig(WATCHDOG_1S); 256 | verifySpace(); 257 | } else { 258 | // This covers the response to commands like STK_ENTER_PROGMODE 259 | verifySpace(); 260 | } 261 | putch(STK_OK); 262 | } 263 | 264 | } 265 | 266 | /* 267 | * void writebuffer(memtype, buffer, address, length) 268 | */ 269 | static inline void writebuffer(int8_t memtype, uint8_t * mybuff, 270 | uint16_t address, pagelen_t len) 271 | { 272 | // Copy buffer into programming buffer 273 | uint8_t *bufPtr = mybuff; 274 | uint16_t addrPtr = (uint16_t) (void *)address; 275 | watchdogReset(); 276 | /* 277 | * Start the page erase and wait for it to finish. There 278 | * used to be code to do this while receiving the data over 279 | * the serial link, but the performance improvement was slight, 280 | * and we needed the space back. 281 | */ 282 | __boot_page_erase_short((uint16_t) (void *)address); 283 | boot_spm_busy_wait(); 284 | 285 | /* 286 | * Copy data from the buffer into the flash write buffer. 287 | */ 288 | do { 289 | uint16_t a; 290 | a = *bufPtr++; 291 | a |= (*bufPtr++) << 8; 292 | __boot_page_fill_short((uint16_t) (void *)addrPtr, a); 293 | addrPtr += 2; 294 | } while (len -= 2); 295 | 296 | /* 297 | * Actually Write the buffer to flash (and wait for it to finish.) 298 | */ 299 | __boot_page_write_short((uint16_t) (void *)address); 300 | boot_spm_busy_wait(); 301 | 302 | __boot_rww_enable_alternate(); 303 | 304 | } 305 | 306 | static inline void read_mem(uint8_t memtype, uint16_t address, pagelen_t length) 307 | { 308 | uint8_t cc; 309 | //watchdogReset(); 310 | // read a Flash byte and increment the address 311 | 312 | do { 313 | __asm__("lpm %0,Z+\n": "=r"(cc), "=z"(address):"1"(address)); 314 | putch(cc); 315 | } while (--length); 316 | 317 | } 318 | 319 | void verifySpace() 320 | { 321 | if (getch() != CRC_EOP) { 322 | watchdogConfig(WATCHDOG_1S); // shorten WD timeout 323 | while (1) // and busy-loop so that WD causes 324 | ; // a reset and app start. 325 | } 326 | putch(STK_INSYNC); 327 | } 328 | 329 | void getNch(uint8_t count) 330 | { 331 | do 332 | getch(); 333 | while (--count); 334 | verifySpace(); 335 | } 336 | 337 | void watchdogConfig(uint8_t x) 338 | { 339 | WDTCSR = _BV(WDCE) | _BV(WDE); 340 | WDTCSR = x; 341 | } 342 | 343 | // Watchdog functions. These are only safe with interrupts turned off. 344 | void watchdogReset() 345 | { 346 | __asm__ __volatile__("wdr\n"); 347 | } 348 | -------------------------------------------------------------------------------- /pin_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_defs.h 3 | * optiboot helper defining the default pin assignments (LED, SOFT_UART) 4 | * for the various chips that are supported. This also has some ugly macros 5 | * for selecting among various UARTs and LED possibilities using command-line 6 | * defines like "UART=2 LED=B5" 7 | * 8 | * Copyright 2013-2015 by Bill Westfield. 9 | * Copyright 2010 by Peter Knight. 10 | * This software is licensed under version 2 of the Gnu Public Licence. 11 | * See optiboot.c for details. 12 | */ 13 | 14 | /*------------------------------------------------------------------------ */ 15 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) 16 | /*------------------------------------------------------------------------ */ 17 | 18 | /* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove 19 | */ 20 | #if !defined(LED) 21 | #define LED B5 22 | #endif 23 | 24 | /* Ports for soft UART */ 25 | #ifdef SOFT_UART 26 | #define UART_PORT PORTD 27 | #define UART_PIN PIND 28 | #define UART_DDR DDRD 29 | #define UART_TX_BIT 1 30 | #define UART_RX_BIT 0 31 | #endif 32 | #endif 33 | 34 | /* 35 | * Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly. 36 | * Note that mega8/m32 still needs special handling, because ubrr is handled 37 | * differently. 38 | */ 39 | #if UART == 0 40 | # define UART_SRA UCSR0A 41 | # define UART_SRB UCSR0B 42 | # define UART_SRC UCSR0C 43 | # define UART_SRL UBRR0L 44 | # define UART_UDR UDR0 45 | #elif UART == 1 46 | #if !defined(UDR1) 47 | #error UART == 1, but no UART1 on device 48 | #endif 49 | # define UART_SRA UCSR1A 50 | # define UART_SRB UCSR1B 51 | # define UART_SRC UCSR1C 52 | # define UART_SRL UBRR1L 53 | # define UART_UDR UDR1 54 | #elif UART == 2 55 | #if !defined(UDR2) 56 | #error UART == 2, but no UART2 on device 57 | #endif 58 | # define UART_SRA UCSR2A 59 | # define UART_SRB UCSR2B 60 | # define UART_SRC UCSR2C 61 | # define UART_SRL UBRR2L 62 | # define UART_UDR UDR2 63 | #elif UART == 3 64 | #if !defined(UDR3) 65 | #error UART == 3, but no UART3 on device 66 | #endif 67 | # define UART_SRA UCSR3A 68 | # define UART_SRB UCSR3B 69 | # define UART_SRC UCSR3C 70 | # define UART_SRL UBRR3L 71 | # define UART_UDR UDR3 72 | #endif 73 | 74 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__) 75 | //Name conversion R.Wiersma 76 | #define UCSR0A UCSRA 77 | #define UDR0 UDR 78 | #define UDRE0 UDRE 79 | #define RXC0 RXC 80 | #define FE0 FE 81 | #define TIFR1 TIFR 82 | #define WDTCSR WDTCR 83 | #endif 84 | #if defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__) 85 | #define WDCE WDTOE 86 | #endif 87 | 88 | /* Luminet support */ 89 | /*------------------------------------------------------------------------ */ 90 | #if defined(__AVR_ATtiny84__) 91 | /*------------------------------------------------------------------------ */ 92 | /* Red LED is connected to pin PA4 */ 93 | #if !defined(LED) 94 | #define LED A4 95 | #endif 96 | 97 | /* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */ 98 | #ifdef SOFT_UART 99 | #define UART_PORT PORTA 100 | #define UART_PIN PINA 101 | #define UART_DDR DDRA 102 | #define UART_TX_BIT 2 103 | #define UART_RX_BIT 3 104 | #endif 105 | #endif 106 | 107 | /*------------------------------------------------------------------------ */ 108 | /* Sanguino support (and other 40pin DIP cpus) */ 109 | #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega32__) || defined (__AVR_ATmega16__) 110 | /*------------------------------------------------------------------------ */ 111 | /* Onboard LED is connected to pin PB0 on Sanguino */ 112 | #if !defined(LED) 113 | #define LED B0 114 | #endif 115 | 116 | /* Ports for soft UART */ 117 | #ifdef SOFT_UART 118 | #define UART_PORT PORTD 119 | #define UART_PIN PIND 120 | #define UART_DDR DDRD 121 | #define UART_TX_BIT 1 122 | #define UART_RX_BIT 0 123 | #endif 124 | #endif 125 | 126 | /*------------------------------------------------------------------------ */ 127 | /* Mega support */ 128 | #if defined(__AVR_ATmega1280__) 129 | /*------------------------------------------------------------------------ */ 130 | /* Onboard LED is connected to pin PB7 on Arduino Mega */ 131 | #if !defined(LED) 132 | #define LED B7 133 | #endif 134 | 135 | /* Ports for soft UART */ 136 | #ifdef SOFT_UART 137 | #define UART_PORT PORTE 138 | #define UART_PIN PINE 139 | #define UART_DDR DDRE 140 | #define UART_TX_BIT 1 141 | #define UART_RX_BIT 0 142 | #endif 143 | #endif 144 | 145 | /* 146 | * ------------------------------------------------------------------------ 147 | * A bunch of macros to enable the LED to be specifed as "B5" for bit 5 148 | * of port B, and similar. 149 | */ 150 | 151 | #define A0 0x100 152 | #define A1 0x101 153 | #define A2 0x102 154 | #define A3 0x103 155 | #define A4 0x104 156 | #define A5 0x105 157 | #define A6 0x106 158 | #define A7 0x107 159 | 160 | #define B0 0x200 161 | #define B1 0x201 162 | #define B2 0x202 163 | #define B3 0x203 164 | #define B4 0x204 165 | #define B5 0x205 166 | #define B6 0x206 167 | #define B7 0x207 168 | 169 | #define C0 0x300 170 | #define C1 0x301 171 | #define C2 0x302 172 | #define C3 0x303 173 | #define C4 0x304 174 | #define C5 0x305 175 | #define C6 0x306 176 | #define C7 0x307 177 | 178 | #define D0 0x400 179 | #define D1 0x401 180 | #define D2 0x402 181 | #define D3 0x403 182 | #define D4 0x404 183 | #define D5 0x405 184 | #define D6 0x406 185 | #define D7 0x407 186 | 187 | #define E0 0x500 188 | #define E1 0x501 189 | #define E2 0x502 190 | #define E3 0x503 191 | #define E4 0x504 192 | #define E5 0x505 193 | #define E6 0x506 194 | #define E7 0x507 195 | 196 | #define F0 0x600 197 | #define F1 0x601 198 | #define F2 0x602 199 | #define F3 0x603 200 | #define F4 0x604 201 | #define F5 0x605 202 | #define F6 0x606 203 | #define F7 0x607 204 | 205 | #define G0 0x700 206 | #define G1 0x701 207 | #define G2 0x702 208 | #define G3 0x703 209 | #define G4 0x704 210 | #define G5 0x705 211 | #define G6 0x706 212 | #define G7 0x707 213 | 214 | #define H0 0x800 215 | #define H1 0x801 216 | #define H2 0x802 217 | #define H3 0x803 218 | #define H4 0x804 219 | #define H5 0x805 220 | #define H6 0x806 221 | #define H7 0x807 222 | 223 | #define J0 0xA00 224 | #define J1 0xA01 225 | #define J2 0xA02 226 | #define J3 0xA03 227 | #define J4 0xA04 228 | #define J5 0xA05 229 | #define J6 0xA06 230 | #define J7 0xA07 231 | 232 | #define K0 0xB00 233 | #define K1 0xB01 234 | #define K2 0xB02 235 | #define K3 0xB03 236 | #define K4 0xB04 237 | #define K5 0xB05 238 | #define K6 0xB06 239 | #define K7 0xB07 240 | 241 | #define L0 0xC00 242 | #define L1 0xC01 243 | #define L2 0xC02 244 | #define L3 0xC03 245 | #define L4 0xC04 246 | #define L5 0xC05 247 | #define L6 0xC06 248 | #define L7 0xC07 249 | 250 | 251 | 252 | #if LED == B0 253 | #undef LED 254 | #define LED_DDR DDRB 255 | #define LED_PORT PORTB 256 | #define LED_PIN PINB 257 | #define LED PINB0 258 | #elif LED == B1 259 | #undef LED 260 | #define LED_DDR DDRB 261 | #define LED_PORT PORTB 262 | #define LED_PIN PINB 263 | #define LED PINB1 264 | #elif LED == B2 265 | #undef LED 266 | #define LED_DDR DDRB 267 | #define LED_PORT PORTB 268 | #define LED_PIN PINB 269 | #define LED PINB2 270 | #elif LED == B3 271 | #undef LED 272 | #define LED_DDR DDRB 273 | #define LED_PORT PORTB 274 | #define LED_PIN PINB 275 | #define LED PINB3 276 | #elif LED == B4 277 | #undef LED 278 | #define LED_DDR DDRB 279 | #define LED_PORT PORTB 280 | #define LED_PIN PINB 281 | #define LED PINB4 282 | #elif LED == B5 283 | #undef LED 284 | #define LED_DDR DDRB 285 | #define LED_PORT PORTB 286 | #define LED_PIN PINB 287 | #define LED PINB5 288 | #elif LED == B6 289 | #undef LED 290 | #define LED_DDR DDRB 291 | #define LED_PORT PORTB 292 | #define LED_PIN PINB 293 | #define LED PINB6 294 | #elif LED == B7 295 | #undef LED 296 | #define LED_DDR DDRB 297 | #define LED_PORT PORTB 298 | #define LED_PIN PINB 299 | #define LED PINB7 300 | 301 | #elif LED == C0 302 | #undef LED 303 | #define LED_DDR DDRC 304 | #define LED_PORT PORTC 305 | #define LED_PIN PINC 306 | #define LED PINC0 307 | #elif LED == C1 308 | #undef LED 309 | #define LED_DDR DDRC 310 | #define LED_PORT PORTC 311 | #define LED_PIN PINC 312 | #define LED PINC1 313 | #elif LED == C2 314 | #undef LED 315 | #define LED_DDR DDRC 316 | #define LED_PORT PORTC 317 | #define LED_PIN PINC 318 | #define LED PINC2 319 | #elif LED == C3 320 | #undef LED 321 | #define LED_DDR DDRC 322 | #define LED_PORT PORTC 323 | #define LED_PIN PINC 324 | #define LED PINC3 325 | #elif LED == C4 326 | #undef LED 327 | #define LED_DDR DDRC 328 | #define LED_PORT PORTC 329 | #define LED_PIN PINC 330 | #define LED PINC4 331 | #elif LED == C5 332 | #undef LED 333 | #define LED_DDR DDRC 334 | #define LED_PORT PORTC 335 | #define LED_PIN PINC 336 | #define LED PINC5 337 | #elif LED == C6 338 | #undef LED 339 | #define LED_DDR DDRC 340 | #define LED_PORT PORTC 341 | #define LED_PIN PINC 342 | #define LED PINC6 343 | #elif LED == C7 344 | #undef LED 345 | #define LED_DDR DDRC 346 | #define LED_PORT PORTC 347 | #define LED_PIN PINC 348 | #define LED PINC7 349 | 350 | #elif LED == D0 351 | #undef LED 352 | #define LED_DDR DDRD 353 | #define LED_PORT PORTD 354 | #define LED_PIN PIND 355 | #define LED PIND0 356 | #elif LED == D1 357 | #undef LED 358 | #define LED_DDR DDRD 359 | #define LED_PORT PORTD 360 | #define LED_PIN PIND 361 | #define LED PIND1 362 | #elif LED == D2 363 | #undef LED 364 | #define LED_DDR DDRD 365 | #define LED_PORT PORTD 366 | #define LED_PIN PIND 367 | #define LED PIND2 368 | #elif LED == D3 369 | #undef LED 370 | #define LED_DDR DDRD 371 | #define LED_PORT PORTD 372 | #define LED_PIN PIND 373 | #define LED PIND3 374 | #elif LED == D4 375 | #undef LED 376 | #define LED_DDR DDRD 377 | #define LED_PORT PORTD 378 | #define LED_PIN PIND 379 | #define LED PIND4 380 | #elif LED == D5 381 | #undef LED 382 | #define LED_DDR DDRD 383 | #define LED_PORT PORTD 384 | #define LED_PIN PIND 385 | #define LED PIND5 386 | #elif LED == D6 387 | #undef LED 388 | #define LED_DDR DDRD 389 | #define LED_PORT PORTD 390 | #define LED_PIN PIND 391 | #define LED PIND6 392 | #elif LED == D7 393 | #undef LED 394 | #define LED_DDR DDRD 395 | #define LED_PORT PORTD 396 | #define LED_PIN PIND 397 | #define LED PIND7 398 | 399 | #elif LED == E0 400 | #undef LED 401 | #define LED_DDR DDRE 402 | #define LED_PORT PORTE 403 | #define LED_PIN PINE 404 | #define LED PINE0 405 | #elif LED == E1 406 | #undef LED 407 | #define LED_DDR DDRE 408 | #define LED_PORT PORTE 409 | #define LED_PIN PINE 410 | #define LED PINE1 411 | #elif LED == E2 412 | #undef LED 413 | #define LED_DDR DDRE 414 | #define LED_PORT PORTE 415 | #define LED_PIN PINE 416 | #define LED PINE2 417 | #elif LED == E3 418 | #undef LED 419 | #define LED_DDR DDRE 420 | #define LED_PORT PORTE 421 | #define LED_PIN PINE 422 | #define LED PINE3 423 | #elif LED == E4 424 | #undef LED 425 | #define LED_DDR DDRE 426 | #define LED_PORT PORTE 427 | #define LED_PIN PINE 428 | #define LED PINE4 429 | #elif LED == E5 430 | #undef LED 431 | #define LED_DDR DDRE 432 | #define LED_PORT PORTE 433 | #define LED_PIN PINE 434 | #define LED PINE5 435 | #elif LED == E6 436 | #undef LED 437 | #define LED_DDR DDRE 438 | #define LED_PORT PORTE 439 | #define LED_PIN PINE 440 | #define LED PINE6 441 | #elif LED == E7 442 | #undef LED 443 | #define LED_DDR DDRE 444 | #define LED_PORT PORTE 445 | #define LED_PIN PINE 446 | #define LED PINE7 447 | 448 | #elif LED == F0 449 | #undef LED 450 | #define LED_DDR DDRF 451 | #define LED_PORT PORTF 452 | #define LED_PIN PINF 453 | #define LED PINF0 454 | #elif LED == F1 455 | #undef LED 456 | #define LED_DDR DDRF 457 | #define LED_PORT PORTF 458 | #define LED_PIN PINF 459 | #define LED PINF1 460 | #elif LED == F2 461 | #undef LED 462 | #define LED_DDR DDRF 463 | #define LED_PORT PORTF 464 | #define LED_PIN PINF 465 | #define LED PINF2 466 | #elif LED == F3 467 | #undef LED 468 | #define LED_DDR DDRF 469 | #define LED_PORT PORTF 470 | #define LED_PIN PINF 471 | #define LED PINF3 472 | #elif LED == F4 473 | #undef LED 474 | #define LED_DDR DDRF 475 | #define LED_PORT PORTF 476 | #define LED_PIN PINF 477 | #define LED PINF4 478 | #elif LED == F5 479 | #undef LED 480 | #define LED_DDR DDRF 481 | #define LED_PORT PORTF 482 | #define LED_PIN PINF 483 | #define LED PINF5 484 | #elif LED == F6 485 | #undef LED 486 | #define LED_DDR DDRF 487 | #define LED_PORT PORTF 488 | #define LED_PIN PINF 489 | #define LED PINF6 490 | #elif LED == F7 491 | #undef LED 492 | #define LED_DDR DDRF 493 | #define LED_PORT PORTF 494 | #define LED_PIN PINF 495 | #define LED PINF7 496 | 497 | #elif LED == G0 498 | #undef LED 499 | #define LED_DDR DDRG 500 | #define LED_PORT PORTG 501 | #define LED_PIN PING 502 | #define LED PING0 503 | #elif LED == G1 504 | #undef LED 505 | #define LED_DDR DDRG 506 | #define LED_PORT PORTG 507 | #define LED_PIN PING 508 | #define LED PING1 509 | #elif LED == G2 510 | #undef LED 511 | #define LED_DDR DDRG 512 | #define LED_PORT PORTG 513 | #define LED_PIN PING 514 | #define LED PING2 515 | #elif LED == G3 516 | #undef LED 517 | #define LED_DDR DDRG 518 | #define LED_PORT PORTG 519 | #define LED_PIN PING 520 | #define LED PING3 521 | #elif LED == G4 522 | #undef LED 523 | #define LED_DDR DDRG 524 | #define LED_PORT PORTG 525 | #define LED_PIN PING 526 | #define LED PING4 527 | #elif LED == G5 528 | #undef LED 529 | #define LED_DDR DDRG 530 | #define LED_PORT PORTG 531 | #define LED_PIN PING 532 | #define LED PING5 533 | #elif LED == G6 534 | #undef LED 535 | #define LED_DDR DDRG 536 | #define LED_PORT PORTG 537 | #define LED_PIN PING 538 | #define LED PING6 539 | #elif LED == G7 540 | #undef LED 541 | #define LED_DDR DDRG 542 | #define LED_PORT PORTG 543 | #define LED_PIN PING 544 | #define LED PING7 545 | 546 | #elif LED == H0 547 | #undef LED 548 | #define LED_DDR DDRH 549 | #define LED_PORT PORTH 550 | #define LED_PIN PINH 551 | #define LED PINH0 552 | #elif LED == H1 553 | #undef LED 554 | #define LED_DDR DDRH 555 | #define LED_PORT PORTH 556 | #define LED_PIN PINH 557 | #define LED PINH1 558 | #elif LED == H2 559 | #undef LED 560 | #define LED_DDR DDRH 561 | #define LED_PORT PORTH 562 | #define LED_PIN PINH 563 | #define LED PINH2 564 | #elif LED == H3 565 | #undef LED 566 | #define LED_DDR DDRH 567 | #define LED_PORT PORTH 568 | #define LED_PIN PINH 569 | #define LED PINH3 570 | #elif LED == H4 571 | #undef LED 572 | #define LED_DDR DDRH 573 | #define LED_PORT PORTH 574 | #define LED_PIN PINH 575 | #define LED PINH4 576 | #elif LED == H5 577 | #undef LED 578 | #define LED_DDR DDRH 579 | #define LED_PORT PORTH 580 | #define LED_PIN PINH 581 | #define LED PINH5 582 | #elif LED == H6 583 | #undef LED 584 | #define LED_DDR DDRH 585 | #define LED_PORT PORTH 586 | #define LED_PIN PINH 587 | #define LED PINH6 588 | #elif LED == H7 589 | #undef LED 590 | #define LED_DDR DDRH 591 | #define LED_PORT PORTH 592 | #define LED_PIN PINH 593 | #define LED PINH7 594 | 595 | #elif LED == J0 596 | #undef LED 597 | #define LED_DDR DDRJ 598 | #define LED_PORT PORTJ 599 | #define LED_PIN PINJ 600 | #define LED PINJ0 601 | #elif LED == J1 602 | #undef LED 603 | #define LED_DDR DDRJ 604 | #define LED_PORT PORTJ 605 | #define LED_PIN PINJ 606 | #define LED PINJ1 607 | #elif LED == J2 608 | #undef LED 609 | #define LED_DDR DDRJ 610 | #define LED_PORT PORTJ 611 | #define LED_PIN PINJ 612 | #define LED PINJ2 613 | #elif LED == J3 614 | #undef LED 615 | #define LED_DDR DDRJ 616 | #define LED_PORT PORTJ 617 | #define LED_PIN PINJ 618 | #define LED PINJ3 619 | #elif LED == J4 620 | #undef LED 621 | #define LED_DDR DDRJ 622 | #define LED_PORT PORTJ 623 | #define LED_PIN PINJ 624 | #define LED PINJ4 625 | #elif LED == J5 626 | #undef LED 627 | #define LED_DDR DDRJ 628 | #define LED_PORT PORTJ 629 | #define LED_PIN PINJ 630 | #define LED PINJ5 631 | #elif LED == J6 632 | #undef LED 633 | #define LED_DDR DDRJ 634 | #define LED_PORT PORTJ 635 | #define LED_PIN PINJ 636 | #define LED PINJ6 637 | #elif LED == J7 638 | #undef LED 639 | #define LED_DDR DDRJ 640 | #define LED_PORT PORTJ 641 | #define LED_PIN PINJ 642 | #define LED PINJ7 643 | 644 | #elif LED == K0 645 | #undef LED 646 | #define LED_DDR DDRK 647 | #define LED_PORT PORTK 648 | #define LED_PIN PINK 649 | #define LED PINK0 650 | #elif LED == K1 651 | #undef LED 652 | #define LED_DDR DDRK 653 | #define LED_PORT PORTK 654 | #define LED_PIN PINK 655 | #define LED PINK1 656 | #elif LED == K2 657 | #undef LED 658 | #define LED_DDR DDRK 659 | #define LED_PORT PORTK 660 | #define LED_PIN PINK 661 | #define LED PINK2 662 | #elif LED == K3 663 | #undef LED 664 | #define LED_DDR DDRK 665 | #define LED_PORT PORTK 666 | #define LED_PIN PINK 667 | #define LED PINK3 668 | #elif LED == K4 669 | #undef LED 670 | #define LED_DDR DDRK 671 | #define LED_PORT PORTK 672 | #define LED_PIN PINK 673 | #define LED PINK4 674 | #elif LED == K5 675 | #undef LED 676 | #define LED_DDR DDRK 677 | #define LED_PORT PORTK 678 | #define LED_PIN PINK 679 | #define LED PINK5 680 | #elif LED == K6 681 | #undef LED 682 | #define LED_DDR DDRK 683 | #define LED_PORT PORTK 684 | #define LED_PIN PINK 685 | #define LED PINK6 686 | #elif LED == K7 687 | #undef LED 688 | #define LED_DDR DDRK 689 | #define LED_PORT PORTK 690 | #define LED_PIN PINK 691 | #define LED PINK7 692 | 693 | #elif LED == L0 694 | #undef LED 695 | #define LED_DDR DDRL 696 | #define LED_PORT PORTL 697 | #define LED_PIN PINL 698 | #define LED PINL0 699 | #elif LED == L1 700 | #undef LED 701 | #define LED_DDR DDRL 702 | #define LED_PORT PORTL 703 | #define LED_PIN PINL 704 | #define LED PINL1 705 | #elif LED == L2 706 | #undef LED 707 | #define LED_DDR DDRL 708 | #define LED_PORT PORTL 709 | #define LED_PIN PINL 710 | #define LED PINL2 711 | #elif LED == L3 712 | #undef LED 713 | #define LED_DDR DDRL 714 | #define LED_PORT PORTL 715 | #define LED_PIN PINL 716 | #define LED PINL3 717 | #elif LED == L4 718 | #undef LED 719 | #define LED_DDR DDRL 720 | #define LED_PORT PORTL 721 | #define LED_PIN PINL 722 | #define LED PINL4 723 | #elif LED == L5 724 | #undef LED 725 | #define LED_DDR DDRL 726 | #define LED_PORT PORTL 727 | #define LED_PIN PINL 728 | #define LED PINL5 729 | #elif LED == L6 730 | #undef LED 731 | #define LED_DDR DDRL 732 | #define LED_PORT PORTL 733 | #define LED_PIN PINL 734 | #define LED PINL6 735 | #elif LED == L7 736 | #undef LED 737 | #define LED_DDR DDRL 738 | #define LED_PORT PORTL 739 | #define LED_PIN PINL 740 | #define LED PINL7 741 | 742 | #elif LED == A0 743 | #undef LED 744 | #define LED_DDR DDRA 745 | #define LED_PORT PORTA 746 | #define LED_PIN PINA 747 | #define LED PINA0 748 | #elif LED == A1 749 | #undef LED 750 | #define LED_DDR DDRA 751 | #define LED_PORT PORTA 752 | #define LED_PIN PINA 753 | #define LED PINA1 754 | #elif LED == A2 755 | #undef LED 756 | #define LED_DDR DDRA 757 | #define LED_PORT PORTA 758 | #define LED_PIN PINA 759 | #define LED PINA2 760 | #elif LED == A3 761 | #undef LED 762 | #define LED_DDR DDRA 763 | #define LED_PORT PORTA 764 | #define LED_PIN PINA 765 | #define LED PINA3 766 | #elif LED == A4 767 | #undef LED 768 | #define LED_DDR DDRA 769 | #define LED_PORT PORTA 770 | #define LED_PIN PINA 771 | #define LED PINA4 772 | #elif LED == A5 773 | #undef LED 774 | #define LED_DDR DDRA 775 | #define LED_PORT PORTA 776 | #define LED_PIN PINA 777 | #define LED PINA5 778 | #elif LED == A6 779 | #undef LED 780 | #define LED_DDR DDRA 781 | #define LED_PORT PORTA 782 | #define LED_PIN PINA 783 | #define LED PINA6 784 | #elif LED == A7 785 | #undef LED 786 | #define LED_DDR DDRA 787 | #define LED_PORT PORTA 788 | #define LED_PIN PINA 789 | #define LED PINA7 790 | 791 | #else 792 | #error ------------------------------------------- 793 | #error Unrecognized LED name. Should be like "B5" 794 | #error ------------------------------------------- 795 | #endif 796 | -------------------------------------------------------------------------------- /tags: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ 2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ 3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ 4 | !_TAG_PROGRAM_NAME Exuberant Ctags // 5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ 6 | !_TAG_PROGRAM_VERSION 5.9~svn20110310 // 7 | A0 pin_defs.h 151;" d 8 | A1 pin_defs.h 152;" d 9 | A2 pin_defs.h 153;" d 10 | A3 pin_defs.h 154;" d 11 | A4 pin_defs.h 155;" d 12 | A5 pin_defs.h 156;" d 13 | A6 pin_defs.h 157;" d 14 | A7 pin_defs.h 158;" d 15 | ADC_CHANNEL_ERROR stk500.h 13;" d 16 | ADC_MEASURE_OK stk500.h 14;" d 17 | B0 pin_defs.h 160;" d 18 | B1 pin_defs.h 161;" d 19 | B2 pin_defs.h 162;" d 20 | B3 pin_defs.h 163;" d 21 | B4 pin_defs.h 164;" d 22 | B5 pin_defs.h 165;" d 23 | B6 pin_defs.h 166;" d 24 | B7 pin_defs.h 167;" d 25 | BAUDRATE uart.c 7;" d file: 26 | BLB01 boot.h 167;" d 27 | BLB02 boot.h 166;" d 28 | BLB11 boot.h 165;" d 29 | BLB12 boot.h 164;" d 30 | BOOTLOADER_SECTION boot.h 147;" d 31 | C0 pin_defs.h 169;" d 32 | C1 pin_defs.h 170;" d 33 | C2 pin_defs.h 171;" d 34 | C3 pin_defs.h 172;" d 35 | C4 pin_defs.h 173;" d 36 | C5 pin_defs.h 174;" d 37 | C6 pin_defs.h 175;" d 38 | C7 pin_defs.h 176;" d 39 | CRC_EOP stk500.h 17;" d 40 | D0 pin_defs.h 178;" d 41 | D1 pin_defs.h 179;" d 42 | D2 pin_defs.h 180;" d 43 | D3 pin_defs.h 181;" d 44 | D4 pin_defs.h 182;" d 45 | D5 pin_defs.h 183;" d 46 | D6 pin_defs.h 184;" d 47 | D7 pin_defs.h 185;" d 48 | E0 pin_defs.h 187;" d 49 | E1 pin_defs.h 188;" d 50 | E2 pin_defs.h 189;" d 51 | E3 pin_defs.h 190;" d 52 | E4 pin_defs.h 191;" d 53 | E5 pin_defs.h 192;" d 54 | E6 pin_defs.h 193;" d 55 | E7 pin_defs.h 194;" d 56 | ER i2c.h 5;" d 57 | EW i2c.h 6;" d 58 | F0 pin_defs.h 196;" d 59 | F1 pin_defs.h 197;" d 60 | F2 pin_defs.h 198;" d 61 | F3 pin_defs.h 199;" d 62 | F4 pin_defs.h 200;" d 63 | F5 pin_defs.h 201;" d 64 | F6 pin_defs.h 202;" d 65 | F7 pin_defs.h 203;" d 66 | FE0 pin_defs.h 80;" d 67 | FUNC_READ main.c 12;" d file: 68 | FUNC_WRITE main.c 13;" d file: 69 | F_CPU i2c.c 2;" d file: 70 | F_CPU main.c 2;" d file: 71 | F_CPU uart.c 2;" d file: 72 | F_SCL i2c.c 10;" d file: 73 | G0 pin_defs.h 205;" d 74 | G1 pin_defs.h 206;" d 75 | G2 pin_defs.h 207;" d 76 | G3 pin_defs.h 208;" d 77 | G4 pin_defs.h 209;" d 78 | G5 pin_defs.h 210;" d 79 | G6 pin_defs.h 211;" d 80 | G7 pin_defs.h 212;" d 81 | GETLENGTH main.c 21;" d file: 82 | GET_EXTENDED_FUSE_BITS boot.h 597;" d 83 | GET_HIGH_FUSE_BITS boot.h 602;" d 84 | GET_LOCK_BITS boot.h 592;" d 85 | GET_LOW_FUSE_BITS boot.h 587;" d 86 | H0 pin_defs.h 214;" d 87 | H1 pin_defs.h 215;" d 88 | H2 pin_defs.h 216;" d 89 | H3 pin_defs.h 217;" d 90 | H4 pin_defs.h 218;" d 91 | H5 pin_defs.h 219;" d 92 | H6 pin_defs.h 220;" d 93 | H7 pin_defs.h 221;" d 94 | I2C_MASTER_H i2c.h 2;" d 95 | I2C_READ i2c.h 8;" d 96 | I2C_WRITE i2c.h 9;" d 97 | J0 pin_defs.h 223;" d 98 | J1 pin_defs.h 224;" d 99 | J2 pin_defs.h 225;" d 100 | J3 pin_defs.h 226;" d 101 | J4 pin_defs.h 227;" d 102 | J5 pin_defs.h 228;" d 103 | J6 pin_defs.h 229;" d 104 | J7 pin_defs.h 230;" d 105 | K0 pin_defs.h 232;" d 106 | K1 pin_defs.h 233;" d 107 | K2 pin_defs.h 234;" d 108 | K3 pin_defs.h 235;" d 109 | K4 pin_defs.h 236;" d 110 | K5 pin_defs.h 237;" d 111 | K6 pin_defs.h 238;" d 112 | K7 pin_defs.h 239;" d 113 | L0 pin_defs.h 241;" d 114 | L1 pin_defs.h 242;" d 115 | L2 pin_defs.h 243;" d 116 | L3 pin_defs.h 244;" d 117 | L4 pin_defs.h 245;" d 118 | L5 pin_defs.h 246;" d 119 | L6 pin_defs.h 247;" d 120 | L7 pin_defs.h 248;" d 121 | LED pin_defs.h 113;" d 122 | LED pin_defs.h 132;" d 123 | LED pin_defs.h 21;" d 124 | LED pin_defs.h 253;" d 125 | LED pin_defs.h 257;" d 126 | LED pin_defs.h 259;" d 127 | LED pin_defs.h 263;" d 128 | LED pin_defs.h 265;" d 129 | LED pin_defs.h 269;" d 130 | LED pin_defs.h 271;" d 131 | LED pin_defs.h 275;" d 132 | LED pin_defs.h 277;" d 133 | LED pin_defs.h 281;" d 134 | LED pin_defs.h 283;" d 135 | LED pin_defs.h 287;" d 136 | LED pin_defs.h 289;" d 137 | LED pin_defs.h 293;" d 138 | LED pin_defs.h 295;" d 139 | LED pin_defs.h 299;" d 140 | LED pin_defs.h 302;" d 141 | LED pin_defs.h 306;" d 142 | LED pin_defs.h 308;" d 143 | LED pin_defs.h 312;" d 144 | LED pin_defs.h 314;" d 145 | LED pin_defs.h 318;" d 146 | LED pin_defs.h 320;" d 147 | LED pin_defs.h 324;" d 148 | LED pin_defs.h 326;" d 149 | LED pin_defs.h 330;" d 150 | LED pin_defs.h 332;" d 151 | LED pin_defs.h 336;" d 152 | LED pin_defs.h 338;" d 153 | LED pin_defs.h 342;" d 154 | LED pin_defs.h 344;" d 155 | LED pin_defs.h 348;" d 156 | LED pin_defs.h 351;" d 157 | LED pin_defs.h 355;" d 158 | LED pin_defs.h 357;" d 159 | LED pin_defs.h 361;" d 160 | LED pin_defs.h 363;" d 161 | LED pin_defs.h 367;" d 162 | LED pin_defs.h 369;" d 163 | LED pin_defs.h 373;" d 164 | LED pin_defs.h 375;" d 165 | LED pin_defs.h 379;" d 166 | LED pin_defs.h 381;" d 167 | LED pin_defs.h 385;" d 168 | LED pin_defs.h 387;" d 169 | LED pin_defs.h 391;" d 170 | LED pin_defs.h 393;" d 171 | LED pin_defs.h 397;" d 172 | LED pin_defs.h 400;" d 173 | LED pin_defs.h 404;" d 174 | LED pin_defs.h 406;" d 175 | LED pin_defs.h 410;" d 176 | LED pin_defs.h 412;" d 177 | LED pin_defs.h 416;" d 178 | LED pin_defs.h 418;" d 179 | LED pin_defs.h 422;" d 180 | LED pin_defs.h 424;" d 181 | LED pin_defs.h 428;" d 182 | LED pin_defs.h 430;" d 183 | LED pin_defs.h 434;" d 184 | LED pin_defs.h 436;" d 185 | LED pin_defs.h 440;" d 186 | LED pin_defs.h 442;" d 187 | LED pin_defs.h 446;" d 188 | LED pin_defs.h 449;" d 189 | LED pin_defs.h 453;" d 190 | LED pin_defs.h 455;" d 191 | LED pin_defs.h 459;" d 192 | LED pin_defs.h 461;" d 193 | LED pin_defs.h 465;" d 194 | LED pin_defs.h 467;" d 195 | LED pin_defs.h 471;" d 196 | LED pin_defs.h 473;" d 197 | LED pin_defs.h 477;" d 198 | LED pin_defs.h 479;" d 199 | LED pin_defs.h 483;" d 200 | LED pin_defs.h 485;" d 201 | LED pin_defs.h 489;" d 202 | LED pin_defs.h 491;" d 203 | LED pin_defs.h 495;" d 204 | LED pin_defs.h 498;" d 205 | LED pin_defs.h 502;" d 206 | LED pin_defs.h 504;" d 207 | LED pin_defs.h 508;" d 208 | LED pin_defs.h 510;" d 209 | LED pin_defs.h 514;" d 210 | LED pin_defs.h 516;" d 211 | LED pin_defs.h 520;" d 212 | LED pin_defs.h 522;" d 213 | LED pin_defs.h 526;" d 214 | LED pin_defs.h 528;" d 215 | LED pin_defs.h 532;" d 216 | LED pin_defs.h 534;" d 217 | LED pin_defs.h 538;" d 218 | LED pin_defs.h 540;" d 219 | LED pin_defs.h 544;" d 220 | LED pin_defs.h 547;" d 221 | LED pin_defs.h 551;" d 222 | LED pin_defs.h 553;" d 223 | LED pin_defs.h 557;" d 224 | LED pin_defs.h 559;" d 225 | LED pin_defs.h 563;" d 226 | LED pin_defs.h 565;" d 227 | LED pin_defs.h 569;" d 228 | LED pin_defs.h 571;" d 229 | LED pin_defs.h 575;" d 230 | LED pin_defs.h 577;" d 231 | LED pin_defs.h 581;" d 232 | LED pin_defs.h 583;" d 233 | LED pin_defs.h 587;" d 234 | LED pin_defs.h 589;" d 235 | LED pin_defs.h 593;" d 236 | LED pin_defs.h 596;" d 237 | LED pin_defs.h 600;" d 238 | LED pin_defs.h 602;" d 239 | LED pin_defs.h 606;" d 240 | LED pin_defs.h 608;" d 241 | LED pin_defs.h 612;" d 242 | LED pin_defs.h 614;" d 243 | LED pin_defs.h 618;" d 244 | LED pin_defs.h 620;" d 245 | LED pin_defs.h 624;" d 246 | LED pin_defs.h 626;" d 247 | LED pin_defs.h 630;" d 248 | LED pin_defs.h 632;" d 249 | LED pin_defs.h 636;" d 250 | LED pin_defs.h 638;" d 251 | LED pin_defs.h 642;" d 252 | LED pin_defs.h 645;" d 253 | LED pin_defs.h 649;" d 254 | LED pin_defs.h 651;" d 255 | LED pin_defs.h 655;" d 256 | LED pin_defs.h 657;" d 257 | LED pin_defs.h 661;" d 258 | LED pin_defs.h 663;" d 259 | LED pin_defs.h 667;" d 260 | LED pin_defs.h 669;" d 261 | LED pin_defs.h 673;" d 262 | LED pin_defs.h 675;" d 263 | LED pin_defs.h 679;" d 264 | LED pin_defs.h 681;" d 265 | LED pin_defs.h 685;" d 266 | LED pin_defs.h 687;" d 267 | LED pin_defs.h 691;" d 268 | LED pin_defs.h 694;" d 269 | LED pin_defs.h 698;" d 270 | LED pin_defs.h 700;" d 271 | LED pin_defs.h 704;" d 272 | LED pin_defs.h 706;" d 273 | LED pin_defs.h 710;" d 274 | LED pin_defs.h 712;" d 275 | LED pin_defs.h 716;" d 276 | LED pin_defs.h 718;" d 277 | LED pin_defs.h 722;" d 278 | LED pin_defs.h 724;" d 279 | LED pin_defs.h 728;" d 280 | LED pin_defs.h 730;" d 281 | LED pin_defs.h 734;" d 282 | LED pin_defs.h 736;" d 283 | LED pin_defs.h 740;" d 284 | LED pin_defs.h 743;" d 285 | LED pin_defs.h 747;" d 286 | LED pin_defs.h 749;" d 287 | LED pin_defs.h 753;" d 288 | LED pin_defs.h 755;" d 289 | LED pin_defs.h 759;" d 290 | LED pin_defs.h 761;" d 291 | LED pin_defs.h 765;" d 292 | LED pin_defs.h 767;" d 293 | LED pin_defs.h 771;" d 294 | LED pin_defs.h 773;" d 295 | LED pin_defs.h 777;" d 296 | LED pin_defs.h 779;" d 297 | LED pin_defs.h 783;" d 298 | LED pin_defs.h 785;" d 299 | LED pin_defs.h 789;" d 300 | LED pin_defs.h 94;" d 301 | LED_DDR pin_defs.h 254;" d 302 | LED_DDR pin_defs.h 260;" d 303 | LED_DDR pin_defs.h 266;" d 304 | LED_DDR pin_defs.h 272;" d 305 | LED_DDR pin_defs.h 278;" d 306 | LED_DDR pin_defs.h 284;" d 307 | LED_DDR pin_defs.h 290;" d 308 | LED_DDR pin_defs.h 296;" d 309 | LED_DDR pin_defs.h 303;" d 310 | LED_DDR pin_defs.h 309;" d 311 | LED_DDR pin_defs.h 315;" d 312 | LED_DDR pin_defs.h 321;" d 313 | LED_DDR pin_defs.h 327;" d 314 | LED_DDR pin_defs.h 333;" d 315 | LED_DDR pin_defs.h 339;" d 316 | LED_DDR pin_defs.h 345;" d 317 | LED_DDR pin_defs.h 352;" d 318 | LED_DDR pin_defs.h 358;" d 319 | LED_DDR pin_defs.h 364;" d 320 | LED_DDR pin_defs.h 370;" d 321 | LED_DDR pin_defs.h 376;" d 322 | LED_DDR pin_defs.h 382;" d 323 | LED_DDR pin_defs.h 388;" d 324 | LED_DDR pin_defs.h 394;" d 325 | LED_DDR pin_defs.h 401;" d 326 | LED_DDR pin_defs.h 407;" d 327 | LED_DDR pin_defs.h 413;" d 328 | LED_DDR pin_defs.h 419;" d 329 | LED_DDR pin_defs.h 425;" d 330 | LED_DDR pin_defs.h 431;" d 331 | LED_DDR pin_defs.h 437;" d 332 | LED_DDR pin_defs.h 443;" d 333 | LED_DDR pin_defs.h 450;" d 334 | LED_DDR pin_defs.h 456;" d 335 | LED_DDR pin_defs.h 462;" d 336 | LED_DDR pin_defs.h 468;" d 337 | LED_DDR pin_defs.h 474;" d 338 | LED_DDR pin_defs.h 480;" d 339 | LED_DDR pin_defs.h 486;" d 340 | LED_DDR pin_defs.h 492;" d 341 | LED_DDR pin_defs.h 499;" d 342 | LED_DDR pin_defs.h 505;" d 343 | LED_DDR pin_defs.h 511;" d 344 | LED_DDR pin_defs.h 517;" d 345 | LED_DDR pin_defs.h 523;" d 346 | LED_DDR pin_defs.h 529;" d 347 | LED_DDR pin_defs.h 535;" d 348 | LED_DDR pin_defs.h 541;" d 349 | LED_DDR pin_defs.h 548;" d 350 | LED_DDR pin_defs.h 554;" d 351 | LED_DDR pin_defs.h 560;" d 352 | LED_DDR pin_defs.h 566;" d 353 | LED_DDR pin_defs.h 572;" d 354 | LED_DDR pin_defs.h 578;" d 355 | LED_DDR pin_defs.h 584;" d 356 | LED_DDR pin_defs.h 590;" d 357 | LED_DDR pin_defs.h 597;" d 358 | LED_DDR pin_defs.h 603;" d 359 | LED_DDR pin_defs.h 609;" d 360 | LED_DDR pin_defs.h 615;" d 361 | LED_DDR pin_defs.h 621;" d 362 | LED_DDR pin_defs.h 627;" d 363 | LED_DDR pin_defs.h 633;" d 364 | LED_DDR pin_defs.h 639;" d 365 | LED_DDR pin_defs.h 646;" d 366 | LED_DDR pin_defs.h 652;" d 367 | LED_DDR pin_defs.h 658;" d 368 | LED_DDR pin_defs.h 664;" d 369 | LED_DDR pin_defs.h 670;" d 370 | LED_DDR pin_defs.h 676;" d 371 | LED_DDR pin_defs.h 682;" d 372 | LED_DDR pin_defs.h 688;" d 373 | LED_DDR pin_defs.h 695;" d 374 | LED_DDR pin_defs.h 701;" d 375 | LED_DDR pin_defs.h 707;" d 376 | LED_DDR pin_defs.h 713;" d 377 | LED_DDR pin_defs.h 719;" d 378 | LED_DDR pin_defs.h 725;" d 379 | LED_DDR pin_defs.h 731;" d 380 | LED_DDR pin_defs.h 737;" d 381 | LED_DDR pin_defs.h 744;" d 382 | LED_DDR pin_defs.h 750;" d 383 | LED_DDR pin_defs.h 756;" d 384 | LED_DDR pin_defs.h 762;" d 385 | LED_DDR pin_defs.h 768;" d 386 | LED_DDR pin_defs.h 774;" d 387 | LED_DDR pin_defs.h 780;" d 388 | LED_DDR pin_defs.h 786;" d 389 | LED_PIN pin_defs.h 256;" d 390 | LED_PIN pin_defs.h 262;" d 391 | LED_PIN pin_defs.h 268;" d 392 | LED_PIN pin_defs.h 274;" d 393 | LED_PIN pin_defs.h 280;" d 394 | LED_PIN pin_defs.h 286;" d 395 | LED_PIN pin_defs.h 292;" d 396 | LED_PIN pin_defs.h 298;" d 397 | LED_PIN pin_defs.h 305;" d 398 | LED_PIN pin_defs.h 311;" d 399 | LED_PIN pin_defs.h 317;" d 400 | LED_PIN pin_defs.h 323;" d 401 | LED_PIN pin_defs.h 329;" d 402 | LED_PIN pin_defs.h 335;" d 403 | LED_PIN pin_defs.h 341;" d 404 | LED_PIN pin_defs.h 347;" d 405 | LED_PIN pin_defs.h 354;" d 406 | LED_PIN pin_defs.h 360;" d 407 | LED_PIN pin_defs.h 366;" d 408 | LED_PIN pin_defs.h 372;" d 409 | LED_PIN pin_defs.h 378;" d 410 | LED_PIN pin_defs.h 384;" d 411 | LED_PIN pin_defs.h 390;" d 412 | LED_PIN pin_defs.h 396;" d 413 | LED_PIN pin_defs.h 403;" d 414 | LED_PIN pin_defs.h 409;" d 415 | LED_PIN pin_defs.h 415;" d 416 | LED_PIN pin_defs.h 421;" d 417 | LED_PIN pin_defs.h 427;" d 418 | LED_PIN pin_defs.h 433;" d 419 | LED_PIN pin_defs.h 439;" d 420 | LED_PIN pin_defs.h 445;" d 421 | LED_PIN pin_defs.h 452;" d 422 | LED_PIN pin_defs.h 458;" d 423 | LED_PIN pin_defs.h 464;" d 424 | LED_PIN pin_defs.h 470;" d 425 | LED_PIN pin_defs.h 476;" d 426 | LED_PIN pin_defs.h 482;" d 427 | LED_PIN pin_defs.h 488;" d 428 | LED_PIN pin_defs.h 494;" d 429 | LED_PIN pin_defs.h 501;" d 430 | LED_PIN pin_defs.h 507;" d 431 | LED_PIN pin_defs.h 513;" d 432 | LED_PIN pin_defs.h 519;" d 433 | LED_PIN pin_defs.h 525;" d 434 | LED_PIN pin_defs.h 531;" d 435 | LED_PIN pin_defs.h 537;" d 436 | LED_PIN pin_defs.h 543;" d 437 | LED_PIN pin_defs.h 550;" d 438 | LED_PIN pin_defs.h 556;" d 439 | LED_PIN pin_defs.h 562;" d 440 | LED_PIN pin_defs.h 568;" d 441 | LED_PIN pin_defs.h 574;" d 442 | LED_PIN pin_defs.h 580;" d 443 | LED_PIN pin_defs.h 586;" d 444 | LED_PIN pin_defs.h 592;" d 445 | LED_PIN pin_defs.h 599;" d 446 | LED_PIN pin_defs.h 605;" d 447 | LED_PIN pin_defs.h 611;" d 448 | LED_PIN pin_defs.h 617;" d 449 | LED_PIN pin_defs.h 623;" d 450 | LED_PIN pin_defs.h 629;" d 451 | LED_PIN pin_defs.h 635;" d 452 | LED_PIN pin_defs.h 641;" d 453 | LED_PIN pin_defs.h 648;" d 454 | LED_PIN pin_defs.h 654;" d 455 | LED_PIN pin_defs.h 660;" d 456 | LED_PIN pin_defs.h 666;" d 457 | LED_PIN pin_defs.h 672;" d 458 | LED_PIN pin_defs.h 678;" d 459 | LED_PIN pin_defs.h 684;" d 460 | LED_PIN pin_defs.h 690;" d 461 | LED_PIN pin_defs.h 697;" d 462 | LED_PIN pin_defs.h 703;" d 463 | LED_PIN pin_defs.h 709;" d 464 | LED_PIN pin_defs.h 715;" d 465 | LED_PIN pin_defs.h 721;" d 466 | LED_PIN pin_defs.h 727;" d 467 | LED_PIN pin_defs.h 733;" d 468 | LED_PIN pin_defs.h 739;" d 469 | LED_PIN pin_defs.h 746;" d 470 | LED_PIN pin_defs.h 752;" d 471 | LED_PIN pin_defs.h 758;" d 472 | LED_PIN pin_defs.h 764;" d 473 | LED_PIN pin_defs.h 770;" d 474 | LED_PIN pin_defs.h 776;" d 475 | LED_PIN pin_defs.h 782;" d 476 | LED_PIN pin_defs.h 788;" d 477 | LED_PORT pin_defs.h 255;" d 478 | LED_PORT pin_defs.h 261;" d 479 | LED_PORT pin_defs.h 267;" d 480 | LED_PORT pin_defs.h 273;" d 481 | LED_PORT pin_defs.h 279;" d 482 | LED_PORT pin_defs.h 285;" d 483 | LED_PORT pin_defs.h 291;" d 484 | LED_PORT pin_defs.h 297;" d 485 | LED_PORT pin_defs.h 304;" d 486 | LED_PORT pin_defs.h 310;" d 487 | LED_PORT pin_defs.h 316;" d 488 | LED_PORT pin_defs.h 322;" d 489 | LED_PORT pin_defs.h 328;" d 490 | LED_PORT pin_defs.h 334;" d 491 | LED_PORT pin_defs.h 340;" d 492 | LED_PORT pin_defs.h 346;" d 493 | LED_PORT pin_defs.h 353;" d 494 | LED_PORT pin_defs.h 359;" d 495 | LED_PORT pin_defs.h 365;" d 496 | LED_PORT pin_defs.h 371;" d 497 | LED_PORT pin_defs.h 377;" d 498 | LED_PORT pin_defs.h 383;" d 499 | LED_PORT pin_defs.h 389;" d 500 | LED_PORT pin_defs.h 395;" d 501 | LED_PORT pin_defs.h 402;" d 502 | LED_PORT pin_defs.h 408;" d 503 | LED_PORT pin_defs.h 414;" d 504 | LED_PORT pin_defs.h 420;" d 505 | LED_PORT pin_defs.h 426;" d 506 | LED_PORT pin_defs.h 432;" d 507 | LED_PORT pin_defs.h 438;" d 508 | LED_PORT pin_defs.h 444;" d 509 | LED_PORT pin_defs.h 451;" d 510 | LED_PORT pin_defs.h 457;" d 511 | LED_PORT pin_defs.h 463;" d 512 | LED_PORT pin_defs.h 469;" d 513 | LED_PORT pin_defs.h 475;" d 514 | LED_PORT pin_defs.h 481;" d 515 | LED_PORT pin_defs.h 487;" d 516 | LED_PORT pin_defs.h 493;" d 517 | LED_PORT pin_defs.h 500;" d 518 | LED_PORT pin_defs.h 506;" d 519 | LED_PORT pin_defs.h 512;" d 520 | LED_PORT pin_defs.h 518;" d 521 | LED_PORT pin_defs.h 524;" d 522 | LED_PORT pin_defs.h 530;" d 523 | LED_PORT pin_defs.h 536;" d 524 | LED_PORT pin_defs.h 542;" d 525 | LED_PORT pin_defs.h 549;" d 526 | LED_PORT pin_defs.h 555;" d 527 | LED_PORT pin_defs.h 561;" d 528 | LED_PORT pin_defs.h 567;" d 529 | LED_PORT pin_defs.h 573;" d 530 | LED_PORT pin_defs.h 579;" d 531 | LED_PORT pin_defs.h 585;" d 532 | LED_PORT pin_defs.h 591;" d 533 | LED_PORT pin_defs.h 598;" d 534 | LED_PORT pin_defs.h 604;" d 535 | LED_PORT pin_defs.h 610;" d 536 | LED_PORT pin_defs.h 616;" d 537 | LED_PORT pin_defs.h 622;" d 538 | LED_PORT pin_defs.h 628;" d 539 | LED_PORT pin_defs.h 634;" d 540 | LED_PORT pin_defs.h 640;" d 541 | LED_PORT pin_defs.h 647;" d 542 | LED_PORT pin_defs.h 653;" d 543 | LED_PORT pin_defs.h 659;" d 544 | LED_PORT pin_defs.h 665;" d 545 | LED_PORT pin_defs.h 671;" d 546 | LED_PORT pin_defs.h 677;" d 547 | LED_PORT pin_defs.h 683;" d 548 | LED_PORT pin_defs.h 689;" d 549 | LED_PORT pin_defs.h 696;" d 550 | LED_PORT pin_defs.h 702;" d 551 | LED_PORT pin_defs.h 708;" d 552 | LED_PORT pin_defs.h 714;" d 553 | LED_PORT pin_defs.h 720;" d 554 | LED_PORT pin_defs.h 726;" d 555 | LED_PORT pin_defs.h 732;" d 556 | LED_PORT pin_defs.h 738;" d 557 | LED_PORT pin_defs.h 745;" d 558 | LED_PORT pin_defs.h 751;" d 559 | LED_PORT pin_defs.h 757;" d 560 | LED_PORT pin_defs.h 763;" d 561 | LED_PORT pin_defs.h 769;" d 562 | LED_PORT pin_defs.h 775;" d 563 | LED_PORT pin_defs.h 781;" d 564 | LED_PORT pin_defs.h 787;" d 565 | LED_START_FLASHES main.c 19;" d file: 566 | OPTIBOOT_MAJVER main.c 15;" d file: 567 | OPTIBOOT_MINVER main.c 16;" d file: 568 | PWM_ADJUST_OK stk500.h 16;" d 569 | PWM_CHANNEL_ERROR stk500.h 15;" d 570 | Prescaler i2c.c 11;" d file: 571 | RXC0 pin_defs.h 79;" d 572 | STK_CHECK_AUTOINC stk500.h 27;" d 573 | STK_CHIP_ERASE stk500.h 26;" d 574 | STK_ENTER_PROGMODE stk500.h 24;" d 575 | STK_FAILED stk500.h 8;" d 576 | STK_GET_PARAMETER stk500.h 21;" d 577 | STK_GET_SIGN_ON stk500.h 19;" d 578 | STK_GET_SYNC stk500.h 18;" d 579 | STK_INSYNC stk500.h 11;" d 580 | STK_LEAVE_PROGMODE stk500.h 25;" d 581 | STK_LOAD_ADDRESS stk500.h 28;" d 582 | STK_NODEVICE stk500.h 10;" d 583 | STK_NOSYNC stk500.h 12;" d 584 | STK_OK stk500.h 7;" d 585 | STK_PROG_DATA stk500.h 31;" d 586 | STK_PROG_FLASH stk500.h 30;" d 587 | STK_PROG_FUSE stk500.h 32;" d 588 | STK_PROG_FUSE_EXT stk500.h 35;" d 589 | STK_PROG_LOCK stk500.h 33;" d 590 | STK_PROG_PAGE stk500.h 34;" d 591 | STK_READ_DATA stk500.h 37;" d 592 | STK_READ_FLASH stk500.h 36;" d 593 | STK_READ_FUSE stk500.h 38;" d 594 | STK_READ_FUSE_EXT stk500.h 43;" d 595 | STK_READ_LOCK stk500.h 39;" d 596 | STK_READ_OSCCAL stk500.h 42;" d 597 | STK_READ_OSCCAL_EXT stk500.h 44;" d 598 | STK_READ_PAGE stk500.h 40;" d 599 | STK_READ_SIGN stk500.h 41;" d 600 | STK_SET_DEVICE stk500.h 22;" d 601 | STK_SET_DEVICE_EXT stk500.h 23;" d 602 | STK_SET_PARAMETER stk500.h 20;" d 603 | STK_SW_MAJOR stk500.h 45;" d 604 | STK_SW_MINOR stk500.h 46;" d 605 | STK_UNIVERSAL stk500.h 29;" d 606 | STK_UNKNOWN stk500.h 9;" d 607 | TIFR1 pin_defs.h 81;" d 608 | TWBR_val i2c.c 12;" d file: 609 | UART_DDR pin_defs.h 101;" d 610 | UART_DDR pin_defs.h 120;" d 611 | UART_DDR pin_defs.h 139;" d 612 | UART_DDR pin_defs.h 28;" d 613 | UART_PIN pin_defs.h 100;" d 614 | UART_PIN pin_defs.h 119;" d 615 | UART_PIN pin_defs.h 138;" d 616 | UART_PIN pin_defs.h 27;" d 617 | UART_PORT pin_defs.h 118;" d 618 | UART_PORT pin_defs.h 137;" d 619 | UART_PORT pin_defs.h 26;" d 620 | UART_PORT pin_defs.h 99;" d 621 | UART_RX_BIT pin_defs.h 103;" d 622 | UART_RX_BIT pin_defs.h 122;" d 623 | UART_RX_BIT pin_defs.h 141;" d 624 | UART_RX_BIT pin_defs.h 30;" d 625 | UART_SRA pin_defs.h 40;" d 626 | UART_SRA pin_defs.h 49;" d 627 | UART_SRA pin_defs.h 58;" d 628 | UART_SRA pin_defs.h 67;" d 629 | UART_SRB pin_defs.h 41;" d 630 | UART_SRB pin_defs.h 50;" d 631 | UART_SRB pin_defs.h 59;" d 632 | UART_SRB pin_defs.h 68;" d 633 | UART_SRC pin_defs.h 42;" d 634 | UART_SRC pin_defs.h 51;" d 635 | UART_SRC pin_defs.h 60;" d 636 | UART_SRC pin_defs.h 69;" d 637 | UART_SRL pin_defs.h 43;" d 638 | UART_SRL pin_defs.h 52;" d 639 | UART_SRL pin_defs.h 61;" d 640 | UART_SRL pin_defs.h 70;" d 641 | UART_TX_BIT pin_defs.h 102;" d 642 | UART_TX_BIT pin_defs.h 121;" d 643 | UART_TX_BIT pin_defs.h 140;" d 644 | UART_TX_BIT pin_defs.h 29;" d 645 | UART_UDR pin_defs.h 44;" d 646 | UART_UDR pin_defs.h 53;" d 647 | UART_UDR pin_defs.h 62;" d 648 | UART_UDR pin_defs.h 71;" d 649 | UCSR0A pin_defs.h 76;" d 650 | UDR0 pin_defs.h 77;" d 651 | UDRE0 pin_defs.h 78;" d 652 | USART_BAUD uart.c 6;" d file: 653 | WATCHDOG_1S main.c 27;" d file: 654 | WATCHDOG_OFF main.c 28;" d file: 655 | WDCE pin_defs.h 85;" d 656 | WDTCSR pin_defs.h 82;" d 657 | _AVR_BOOT_H_ boot.h 43;" d 658 | __BOOT_LOCK_BITS_SET boot.h 209;" d 659 | __BOOT_PAGE_ERASE boot.h 205;" d 660 | __BOOT_PAGE_FILL boot.h 207;" d 661 | __BOOT_PAGE_WRITE boot.h 206;" d 662 | __BOOT_RWW_ENABLE boot.h 208;" d 663 | __BOOT_SIGROW_READ boot.h 663;" d 664 | __COMMON_ASB boot.h 151;" d 665 | __COMMON_ASB boot.h 153;" d 666 | __COMMON_ASRE boot.h 157;" d 667 | __COMMON_ASRE boot.h 159;" d 668 | __SPM_ENABLE boot.h 132;" d 669 | __SPM_ENABLE boot.h 134;" d 670 | __SPM_REG boot.h 122;" d 671 | __SPM_REG boot.h 124;" d 672 | __UART_H_ uart.h 2;" d 673 | __boot_lock_bits_set boot.h 526;" d 674 | __boot_lock_bits_set_alternate boot.h 544;" d 675 | __boot_lock_bits_set_short boot.h 508;" d 676 | __boot_page_erase_alternate boot.h 331;" d 677 | __boot_page_erase_extended boot.h 346;" d 678 | __boot_page_erase_extended_short boot.h 362;" d 679 | __boot_page_erase_normal boot.h 318;" d 680 | __boot_page_erase_short boot.h 304;" d 681 | __boot_page_fill_alternate boot.h 245;" d 682 | __boot_page_fill_extended boot.h 264;" d 683 | __boot_page_fill_extended_short boot.h 284;" d 684 | __boot_page_fill_normal boot.h 228;" d 685 | __boot_page_fill_short boot.h 211;" d 686 | __boot_page_write_alternate boot.h 405;" d 687 | __boot_page_write_extended boot.h 420;" d 688 | __boot_page_write_extended_short boot.h 436;" d 689 | __boot_page_write_normal boot.h 392;" d 690 | __boot_page_write_short boot.h 379;" d 691 | __boot_rww_enable boot.h 465;" d 692 | __boot_rww_enable_alternate boot.h 477;" d 693 | __boot_rww_enable_short boot.h 453;" d 694 | appstart_vec main.c 26;" d file: 695 | boot_is_spm_interrupt boot.h 185;" d 696 | boot_lock_bits_set boot.h 766;" d 697 | boot_lock_bits_set boot.h 775;" d 698 | boot_lock_bits_set boot.h 784;" d 699 | boot_lock_bits_set_safe boot.h 841;" d 700 | boot_lock_fuse_bits_get boot.h 634;" d 701 | boot_lock_fuse_bits_get_short boot.h 616;" d 702 | boot_page_erase boot.h 763;" d 703 | boot_page_erase boot.h 772;" d 704 | boot_page_erase boot.h 781;" d 705 | boot_page_erase_safe boot.h 805;" d 706 | boot_page_fill boot.h 762;" d 707 | boot_page_fill boot.h 771;" d 708 | boot_page_fill boot.h 780;" d 709 | boot_page_fill_safe boot.h 793;" d 710 | boot_page_write boot.h 764;" d 711 | boot_page_write boot.h 773;" d 712 | boot_page_write boot.h 782;" d 713 | boot_page_write_safe boot.h 817;" d 714 | boot_rww_busy boot.h 191;" d 715 | boot_rww_enable boot.h 765;" d 716 | boot_rww_enable boot.h 774;" d 717 | boot_rww_enable boot.h 783;" d 718 | boot_rww_enable_safe boot.h 829;" d 719 | boot_signature_byte_get boot.h 681;" d 720 | boot_signature_byte_get_short boot.h 665;" d 721 | boot_spm_busy boot.h 197;" d 722 | boot_spm_busy_wait boot.h 203;" d 723 | boot_spm_interrupt_disable boot.h 179;" d 724 | boot_spm_interrupt_enable boot.h 173;" d 725 | buff main.c /^uint8_t buff[200];\/\/ ((uint8_t*)(RAMSTART + 300))$/;" v 726 | getch uart.c /^uint8_t getch(void)$/;" f 727 | i2c_init i2c.c /^void i2c_init(void)$/;" f 728 | i2c_readReg i2c.c /^uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)$/;" f 729 | i2c_read_ack i2c.c /^uint8_t i2c_read_ack(void)$/;" f 730 | i2c_read_nack i2c.c /^uint8_t i2c_read_nack(void)$/;" f 731 | i2c_receive i2c.c /^uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)$/;" f 732 | i2c_start i2c.c /^uint8_t i2c_start(uint8_t address)$/;" f 733 | i2c_stop i2c.c /^void i2c_stop(void)$/;" f 734 | i2c_transmit i2c.c /^uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)$/;" f 735 | i2c_write i2c.c /^uint8_t i2c_write(uint8_t data)$/;" f 736 | i2c_writeReg i2c.c /^uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)$/;" f 737 | main main.c /^int main()$/;" f 738 | pagelen_t main.c /^typedef uint8_t pagelen_t;$/;" t file: 739 | putch uart.c /^void putch(uint8_t c)$/;" f 740 | save_vect_num main.c 24;" d file: 741 | uart_init uart.c /^void uart_init()$/;" f 742 | -------------------------------------------------------------------------------- /boot.h: -------------------------------------------------------------------------------- 1 | /* Modified to use out for SPM access 2 | ** Peter Knight, Optiboot project http://optiboot.googlecode.com 3 | ** 4 | ** Todo: Tidy up 5 | ** 6 | ** "_short" routines execute 1 cycle faster and use 1 less word of flash 7 | ** by using "out" instruction instead of "sts". 8 | ** 9 | ** Additional elpm variants that trust the value of RAMPZ 10 | */ 11 | 12 | /* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Eric B. Weddington 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | * Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in 22 | the documentation and/or other materials provided with the 23 | distribution. 24 | * Neither the name of the copyright holders nor the names of 25 | contributors may be used to endorse or promote products derived 26 | from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 32 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | POSSIBILITY OF SUCH DAMAGE. */ 39 | 40 | /* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */ 41 | 42 | #ifndef _AVR_BOOT_H_ 43 | #define _AVR_BOOT_H_ 1 44 | 45 | /** \file */ 46 | /** \defgroup avr_boot : Bootloader Support Utilities 47 | \code 48 | #include 49 | #include 50 | \endcode 51 | 52 | The macros in this module provide a C language interface to the 53 | bootloader support functionality of certain AVR processors. These 54 | macros are designed to work with all sizes of flash memory. 55 | 56 | Global interrupts are not automatically disabled for these macros. It 57 | is left up to the programmer to do this. See the code example below. 58 | Also see the processor datasheet for caveats on having global interrupts 59 | enabled during writing of the Flash. 60 | 61 | \note Not all AVR processors provide bootloader support. See your 62 | processor datasheet to see if it provides bootloader support. 63 | 64 | \todo From email with Marek: On smaller devices (all except ATmega64/128), 65 | __SPM_REG is in the I/O space, accessible with the shorter "in" and "out" 66 | instructions - since the boot loader has a limited size, this could be an 67 | important optimization. 68 | 69 | \par API Usage Example 70 | The following code shows typical usage of the boot API. 71 | 72 | \code 73 | #include 74 | #include 75 | #include 76 | 77 | void boot_program_page (uint32_t page, uint8_t *buf) 78 | { 79 | uint16_t i; 80 | uint8_t sreg; 81 | 82 | // Disable interrupts. 83 | 84 | sreg = SREG; 85 | cli(); 86 | 87 | eeprom_busy_wait (); 88 | 89 | boot_page_erase (page); 90 | boot_spm_busy_wait (); // Wait until the memory is erased. 91 | 92 | for (i=0; i 116 | #include 117 | #include 118 | #include 119 | 120 | /* Check for SPM Control Register in processor. */ 121 | #if defined (SPMCSR) 122 | # define __SPM_REG SPMCSR 123 | #elif defined (SPMCR) 124 | # define __SPM_REG SPMCR 125 | #else 126 | # error AVR processor does not provide bootloader support! 127 | #endif 128 | 129 | 130 | /* Check for SPM Enable bit. */ 131 | #if defined(SPMEN) 132 | # define __SPM_ENABLE SPMEN 133 | #elif defined(SELFPRGEN) 134 | # define __SPM_ENABLE SELFPRGEN 135 | #else 136 | # error Cannot find SPM Enable bit definition! 137 | #endif 138 | 139 | /** \ingroup avr_boot 140 | \def BOOTLOADER_SECTION 141 | 142 | Used to declare a function or variable to be placed into a 143 | new section called .bootloader. This section and its contents 144 | can then be relocated to any address (such as the bootloader 145 | NRWW area) at link-time. */ 146 | 147 | #define BOOTLOADER_SECTION __attribute__ ((section (".bootloader"))) 148 | 149 | /* Create common bit definitions. */ 150 | #ifdef ASB 151 | #define __COMMON_ASB ASB 152 | #else 153 | #define __COMMON_ASB RWWSB 154 | #endif 155 | 156 | #ifdef ASRE 157 | #define __COMMON_ASRE ASRE 158 | #else 159 | #define __COMMON_ASRE RWWSRE 160 | #endif 161 | 162 | /* Define the bit positions of the Boot Lock Bits. */ 163 | 164 | #define BLB12 5 165 | #define BLB11 4 166 | #define BLB02 3 167 | #define BLB01 2 168 | 169 | /** \ingroup avr_boot 170 | \def boot_spm_interrupt_enable() 171 | Enable the SPM interrupt. */ 172 | 173 | #define boot_spm_interrupt_enable() (__SPM_REG |= (uint8_t)_BV(SPMIE)) 174 | 175 | /** \ingroup avr_boot 176 | \def boot_spm_interrupt_disable() 177 | Disable the SPM interrupt. */ 178 | 179 | #define boot_spm_interrupt_disable() (__SPM_REG &= (uint8_t)~_BV(SPMIE)) 180 | 181 | /** \ingroup avr_boot 182 | \def boot_is_spm_interrupt() 183 | Check if the SPM interrupt is enabled. */ 184 | 185 | #define boot_is_spm_interrupt() (__SPM_REG & (uint8_t)_BV(SPMIE)) 186 | 187 | /** \ingroup avr_boot 188 | \def boot_rww_busy() 189 | Check if the RWW section is busy. */ 190 | 191 | #define boot_rww_busy() (__SPM_REG & (uint8_t)_BV(__COMMON_ASB)) 192 | 193 | /** \ingroup avr_boot 194 | \def boot_spm_busy() 195 | Check if the SPM instruction is busy. */ 196 | 197 | #define boot_spm_busy() (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE)) 198 | 199 | /** \ingroup avr_boot 200 | \def boot_spm_busy_wait() 201 | Wait while the SPM instruction is busy. */ 202 | 203 | #define boot_spm_busy_wait() do{}while(boot_spm_busy()) 204 | 205 | #define __BOOT_PAGE_ERASE (_BV(__SPM_ENABLE) | _BV(PGERS)) 206 | #define __BOOT_PAGE_WRITE (_BV(__SPM_ENABLE) | _BV(PGWRT)) 207 | #define __BOOT_PAGE_FILL _BV(__SPM_ENABLE) 208 | #define __BOOT_RWW_ENABLE (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE)) 209 | #define __BOOT_LOCK_BITS_SET (_BV(__SPM_ENABLE) | _BV(BLBSET)) 210 | 211 | #define __boot_page_fill_short(address, data) \ 212 | (__extension__({ \ 213 | __asm__ __volatile__ \ 214 | ( \ 215 | "movw r0, %3\n\t" \ 216 | "out %0, %1\n\t" \ 217 | "spm\n\t" \ 218 | "clr r1\n\t" \ 219 | : \ 220 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 221 | "r" ((uint8_t)__BOOT_PAGE_FILL), \ 222 | "z" ((uint16_t)address), \ 223 | "r" ((uint16_t)data) \ 224 | : "r0" \ 225 | ); \ 226 | })) 227 | 228 | #define __boot_page_fill_normal(address, data) \ 229 | (__extension__({ \ 230 | __asm__ __volatile__ \ 231 | ( \ 232 | "movw r0, %3\n\t" \ 233 | "sts %0, %1\n\t" \ 234 | "spm\n\t" \ 235 | "clr r1\n\t" \ 236 | : \ 237 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 238 | "r" ((uint8_t)__BOOT_PAGE_FILL), \ 239 | "z" ((uint16_t)address), \ 240 | "r" ((uint16_t)data) \ 241 | : "r0" \ 242 | ); \ 243 | })) 244 | 245 | #define __boot_page_fill_alternate(address, data)\ 246 | (__extension__({ \ 247 | __asm__ __volatile__ \ 248 | ( \ 249 | "movw r0, %3\n\t" \ 250 | "sts %0, %1\n\t" \ 251 | "spm\n\t" \ 252 | ".word 0xffff\n\t" \ 253 | "nop\n\t" \ 254 | "clr r1\n\t" \ 255 | : \ 256 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 257 | "r" ((uint8_t)__BOOT_PAGE_FILL), \ 258 | "z" ((uint16_t)address), \ 259 | "r" ((uint16_t)data) \ 260 | : "r0" \ 261 | ); \ 262 | })) 263 | 264 | #define __boot_page_fill_extended(address, data) \ 265 | (__extension__({ \ 266 | __asm__ __volatile__ \ 267 | ( \ 268 | "movw r0, %4\n\t" \ 269 | "movw r30, %A3\n\t" \ 270 | "sts %1, %C3\n\t" \ 271 | "sts %0, %2\n\t" \ 272 | "spm\n\t" \ 273 | "clr r1\n\t" \ 274 | : \ 275 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 276 | "i" (_SFR_MEM_ADDR(RAMPZ)), \ 277 | "r" ((uint8_t)__BOOT_PAGE_FILL), \ 278 | "r" ((uint32_t)address), \ 279 | "r" ((uint16_t)data) \ 280 | : "r0", "r30", "r31" \ 281 | ); \ 282 | })) 283 | 284 | #define __boot_page_fill_extended_short(address, data) \ 285 | (__extension__({ \ 286 | __asm__ __volatile__ \ 287 | ( \ 288 | "movw r0, %4\n\t" \ 289 | "movw r30, %A3\n\t" \ 290 | "out %1, %C3\n\t" \ 291 | "out %0, %2\n\t" \ 292 | "spm\n\t" \ 293 | "clr r1\n\t" \ 294 | : \ 295 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 296 | "i" (_SFR_IO_ADDR(RAMPZ)), \ 297 | "r" ((uint8_t)__BOOT_PAGE_FILL), \ 298 | "r" ((uint32_t)address), \ 299 | "r" ((uint16_t)data) \ 300 | : "r0", "r30", "r31" \ 301 | ); \ 302 | })) 303 | 304 | #define __boot_page_erase_short(address) \ 305 | (__extension__({ \ 306 | __asm__ __volatile__ \ 307 | ( \ 308 | "out %0, %1\n\t" \ 309 | "spm\n\t" \ 310 | : \ 311 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 312 | "r" ((uint8_t)__BOOT_PAGE_ERASE), \ 313 | "z" ((uint16_t)address) \ 314 | ); \ 315 | })) 316 | 317 | 318 | #define __boot_page_erase_normal(address) \ 319 | (__extension__({ \ 320 | __asm__ __volatile__ \ 321 | ( \ 322 | "sts %0, %1\n\t" \ 323 | "spm\n\t" \ 324 | : \ 325 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 326 | "r" ((uint8_t)__BOOT_PAGE_ERASE), \ 327 | "z" ((uint16_t)address) \ 328 | ); \ 329 | })) 330 | 331 | #define __boot_page_erase_alternate(address) \ 332 | (__extension__({ \ 333 | __asm__ __volatile__ \ 334 | ( \ 335 | "sts %0, %1\n\t" \ 336 | "spm\n\t" \ 337 | ".word 0xffff\n\t" \ 338 | "nop\n\t" \ 339 | : \ 340 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 341 | "r" ((uint8_t)__BOOT_PAGE_ERASE), \ 342 | "z" ((uint16_t)address) \ 343 | ); \ 344 | })) 345 | 346 | #define __boot_page_erase_extended(address) \ 347 | (__extension__({ \ 348 | __asm__ __volatile__ \ 349 | ( \ 350 | "movw r30, %A3\n\t" \ 351 | "sts %1, %C3\n\t" \ 352 | "sts %0, %2\n\t" \ 353 | "spm\n\t" \ 354 | : \ 355 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 356 | "i" (_SFR_MEM_ADDR(RAMPZ)), \ 357 | "r" ((uint8_t)__BOOT_PAGE_ERASE), \ 358 | "r" ((uint32_t)address) \ 359 | : "r30", "r31" \ 360 | ); \ 361 | })) 362 | #define __boot_page_erase_extended_short(address) \ 363 | (__extension__({ \ 364 | __asm__ __volatile__ \ 365 | ( \ 366 | "movw r30, %A3\n\t" \ 367 | "out %1, %C3\n\t" \ 368 | "out %0, %2\n\t" \ 369 | "spm\n\t" \ 370 | : \ 371 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 372 | "i" (_SFR_IO_ADDR(RAMPZ)), \ 373 | "r" ((uint8_t)__BOOT_PAGE_ERASE), \ 374 | "r" ((uint32_t)address) \ 375 | : "r30", "r31" \ 376 | ); \ 377 | })) 378 | 379 | #define __boot_page_write_short(address) \ 380 | (__extension__({ \ 381 | __asm__ __volatile__ \ 382 | ( \ 383 | "out %0, %1\n\t" \ 384 | "spm\n\t" \ 385 | : \ 386 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 387 | "r" ((uint8_t)__BOOT_PAGE_WRITE), \ 388 | "z" ((uint16_t)address) \ 389 | ); \ 390 | })) 391 | 392 | #define __boot_page_write_normal(address) \ 393 | (__extension__({ \ 394 | __asm__ __volatile__ \ 395 | ( \ 396 | "sts %0, %1\n\t" \ 397 | "spm\n\t" \ 398 | : \ 399 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 400 | "r" ((uint8_t)__BOOT_PAGE_WRITE), \ 401 | "z" ((uint16_t)address) \ 402 | ); \ 403 | })) 404 | 405 | #define __boot_page_write_alternate(address) \ 406 | (__extension__({ \ 407 | __asm__ __volatile__ \ 408 | ( \ 409 | "sts %0, %1\n\t" \ 410 | "spm\n\t" \ 411 | ".word 0xffff\n\t" \ 412 | "nop\n\t" \ 413 | : \ 414 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 415 | "r" ((uint8_t)__BOOT_PAGE_WRITE), \ 416 | "z" ((uint16_t)address) \ 417 | ); \ 418 | })) 419 | 420 | #define __boot_page_write_extended(address) \ 421 | (__extension__({ \ 422 | __asm__ __volatile__ \ 423 | ( \ 424 | "movw r30, %A3\n\t" \ 425 | "sts %1, %C3\n\t" \ 426 | "sts %0, %2\n\t" \ 427 | "spm\n\t" \ 428 | : \ 429 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 430 | "i" (_SFR_MEM_ADDR(RAMPZ)), \ 431 | "r" ((uint8_t)__BOOT_PAGE_WRITE), \ 432 | "r" ((uint32_t)address) \ 433 | : "r30", "r31" \ 434 | ); \ 435 | })) 436 | #define __boot_page_write_extended_short(address) \ 437 | (__extension__({ \ 438 | __asm__ __volatile__ \ 439 | ( \ 440 | "movw r30, %A3\n\t" \ 441 | "out %1, %C3\n\t" \ 442 | "out %0, %2\n\t" \ 443 | "spm\n\t" \ 444 | : \ 445 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 446 | "i" (_SFR_IO_ADDR(RAMPZ)), \ 447 | "r" ((uint8_t)__BOOT_PAGE_WRITE), \ 448 | "r" ((uint32_t)address) \ 449 | : "r30", "r31" \ 450 | ); \ 451 | })) 452 | 453 | #define __boot_rww_enable_short() \ 454 | (__extension__({ \ 455 | __asm__ __volatile__ \ 456 | ( \ 457 | "out %0, %1\n\t" \ 458 | "spm\n\t" \ 459 | : \ 460 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 461 | "r" ((uint8_t)__BOOT_RWW_ENABLE) \ 462 | ); \ 463 | })) 464 | 465 | #define __boot_rww_enable() \ 466 | (__extension__({ \ 467 | __asm__ __volatile__ \ 468 | ( \ 469 | "sts %0, %1\n\t" \ 470 | "spm\n\t" \ 471 | : \ 472 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 473 | "r" ((uint8_t)__BOOT_RWW_ENABLE) \ 474 | ); \ 475 | })) 476 | 477 | #define __boot_rww_enable_alternate() \ 478 | (__extension__({ \ 479 | __asm__ __volatile__ \ 480 | ( \ 481 | "sts %0, %1\n\t" \ 482 | "spm\n\t" \ 483 | ".word 0xffff\n\t" \ 484 | "nop\n\t" \ 485 | : \ 486 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 487 | "r" ((uint8_t)__BOOT_RWW_ENABLE) \ 488 | ); \ 489 | })) 490 | 491 | /* From the mega16/mega128 data sheets (maybe others): 492 | 493 | Bits by SPM To set the Boot Loader Lock bits, write the desired data to 494 | R0, write "X0001001" to SPMCR and execute SPM within four clock cycles 495 | after writing SPMCR. The only accessible Lock bits are the Boot Lock bits 496 | that may prevent the Application and Boot Loader section from any 497 | software update by the MCU. 498 | 499 | If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit 500 | will be programmed if an SPM instruction is executed within four cycles 501 | after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is 502 | don't care during this operation, but for future compatibility it is 503 | recommended to load the Z-pointer with $0001 (same as used for reading the 504 | Lock bits). For future compatibility It is also recommended to set bits 7, 505 | 6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the 506 | Lock bits the entire Flash can be read during the operation. */ 507 | 508 | #define __boot_lock_bits_set_short(lock_bits) \ 509 | (__extension__({ \ 510 | uint8_t value = (uint8_t)(~(lock_bits)); \ 511 | __asm__ __volatile__ \ 512 | ( \ 513 | "ldi r30, 1\n\t" \ 514 | "ldi r31, 0\n\t" \ 515 | "mov r0, %2\n\t" \ 516 | "out %0, %1\n\t" \ 517 | "spm\n\t" \ 518 | : \ 519 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 520 | "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \ 521 | "r" (value) \ 522 | : "r0", "r30", "r31" \ 523 | ); \ 524 | })) 525 | 526 | #define __boot_lock_bits_set(lock_bits) \ 527 | (__extension__({ \ 528 | uint8_t value = (uint8_t)(~(lock_bits)); \ 529 | __asm__ __volatile__ \ 530 | ( \ 531 | "ldi r30, 1\n\t" \ 532 | "ldi r31, 0\n\t" \ 533 | "mov r0, %2\n\t" \ 534 | "sts %0, %1\n\t" \ 535 | "spm\n\t" \ 536 | : \ 537 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 538 | "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \ 539 | "r" (value) \ 540 | : "r0", "r30", "r31" \ 541 | ); \ 542 | })) 543 | 544 | #define __boot_lock_bits_set_alternate(lock_bits) \ 545 | (__extension__({ \ 546 | uint8_t value = (uint8_t)(~(lock_bits)); \ 547 | __asm__ __volatile__ \ 548 | ( \ 549 | "ldi r30, 1\n\t" \ 550 | "ldi r31, 0\n\t" \ 551 | "mov r0, %2\n\t" \ 552 | "sts %0, %1\n\t" \ 553 | "spm\n\t" \ 554 | ".word 0xffff\n\t" \ 555 | "nop\n\t" \ 556 | : \ 557 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 558 | "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \ 559 | "r" (value) \ 560 | : "r0", "r30", "r31" \ 561 | ); \ 562 | })) 563 | 564 | /* 565 | Reading lock and fuse bits: 566 | 567 | Similarly to writing the lock bits above, set BLBSET and SPMEN (or 568 | SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an 569 | LPM instruction. 570 | 571 | Z address: contents: 572 | 0x0000 low fuse bits 573 | 0x0001 lock bits 574 | 0x0002 extended fuse bits 575 | 0x0003 high fuse bits 576 | 577 | Sounds confusing, doesn't it? 578 | 579 | Unlike the macros in pgmspace.h, no need to care for non-enhanced 580 | cores here as these old cores do not provide SPM support anyway. 581 | */ 582 | 583 | /** \ingroup avr_boot 584 | \def GET_LOW_FUSE_BITS 585 | address to read the low fuse bits, using boot_lock_fuse_bits_get 586 | */ 587 | #define GET_LOW_FUSE_BITS (0x0000) 588 | /** \ingroup avr_boot 589 | \def GET_LOCK_BITS 590 | address to read the lock bits, using boot_lock_fuse_bits_get 591 | */ 592 | #define GET_LOCK_BITS (0x0001) 593 | /** \ingroup avr_boot 594 | \def GET_EXTENDED_FUSE_BITS 595 | address to read the extended fuse bits, using boot_lock_fuse_bits_get 596 | */ 597 | #define GET_EXTENDED_FUSE_BITS (0x0002) 598 | /** \ingroup avr_boot 599 | \def GET_HIGH_FUSE_BITS 600 | address to read the high fuse bits, using boot_lock_fuse_bits_get 601 | */ 602 | #define GET_HIGH_FUSE_BITS (0x0003) 603 | 604 | /** \ingroup avr_boot 605 | \def boot_lock_fuse_bits_get(address) 606 | 607 | Read the lock or fuse bits at \c address. 608 | 609 | Parameter \c address can be any of GET_LOW_FUSE_BITS, 610 | GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS. 611 | 612 | \note The lock and fuse bits returned are the physical values, 613 | i.e. a bit returned as 0 means the corresponding fuse or lock bit 614 | is programmed. 615 | */ 616 | #define boot_lock_fuse_bits_get_short(address) \ 617 | (__extension__({ \ 618 | uint8_t __result; \ 619 | __asm__ __volatile__ \ 620 | ( \ 621 | "ldi r30, %3\n\t" \ 622 | "ldi r31, 0\n\t" \ 623 | "out %1, %2\n\t" \ 624 | "lpm %0, Z\n\t" \ 625 | : "=r" (__result) \ 626 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 627 | "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \ 628 | "M" (address) \ 629 | : "r0", "r30", "r31" \ 630 | ); \ 631 | __result; \ 632 | })) 633 | 634 | #define boot_lock_fuse_bits_get(address) \ 635 | (__extension__({ \ 636 | uint8_t __result; \ 637 | __asm__ __volatile__ \ 638 | ( \ 639 | "ldi r30, %3\n\t" \ 640 | "ldi r31, 0\n\t" \ 641 | "sts %1, %2\n\t" \ 642 | "lpm %0, Z\n\t" \ 643 | : "=r" (__result) \ 644 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 645 | "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \ 646 | "M" (address) \ 647 | : "r0", "r30", "r31" \ 648 | ); \ 649 | __result; \ 650 | })) 651 | 652 | /** \ingroup avr_boot 653 | \def boot_signature_byte_get(address) 654 | 655 | Read the Signature Row byte at \c address. For some MCU types, 656 | this function can also retrieve the factory-stored oscillator 657 | calibration bytes. 658 | 659 | Parameter \c address can be 0-0x1f as documented by the datasheet. 660 | \note The values are MCU type dependent. 661 | */ 662 | 663 | #define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD)) 664 | 665 | #define boot_signature_byte_get_short(addr) \ 666 | (__extension__({ \ 667 | uint16_t __addr16 = (uint16_t)(addr); \ 668 | uint8_t __result; \ 669 | __asm__ __volatile__ \ 670 | ( \ 671 | "out %1, %2\n\t" \ 672 | "lpm %0, Z" "\n\t" \ 673 | : "=r" (__result) \ 674 | : "i" (_SFR_IO_ADDR(__SPM_REG)), \ 675 | "r" ((uint8_t) __BOOT_SIGROW_READ), \ 676 | "z" (__addr16) \ 677 | ); \ 678 | __result; \ 679 | })) 680 | 681 | #define boot_signature_byte_get(addr) \ 682 | (__extension__({ \ 683 | uint16_t __addr16 = (uint16_t)(addr); \ 684 | uint8_t __result; \ 685 | __asm__ __volatile__ \ 686 | ( \ 687 | "sts %1, %2\n\t" \ 688 | "lpm %0, Z" "\n\t" \ 689 | : "=r" (__result) \ 690 | : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ 691 | "r" ((uint8_t) __BOOT_SIGROW_READ), \ 692 | "z" (__addr16) \ 693 | ); \ 694 | __result; \ 695 | })) 696 | 697 | /** \ingroup avr_boot 698 | \def boot_page_fill(address, data) 699 | 700 | Fill the bootloader temporary page buffer for flash 701 | address with data word. 702 | 703 | \note The address is a byte address. The data is a word. The AVR 704 | writes data to the buffer a word at a time, but addresses the buffer 705 | per byte! So, increment your address by 2 between calls, and send 2 706 | data bytes in a word format! The LSB of the data is written to the lower 707 | address; the MSB of the data is written to the higher address.*/ 708 | 709 | /** \ingroup avr_boot 710 | \def boot_page_erase(address) 711 | 712 | Erase the flash page that contains address. 713 | 714 | \note address is a byte address in flash, not a word address. */ 715 | 716 | /** \ingroup avr_boot 717 | \def boot_page_write(address) 718 | 719 | Write the bootloader temporary page buffer 720 | to flash page that contains address. 721 | 722 | \note address is a byte address in flash, not a word address. */ 723 | 724 | /** \ingroup avr_boot 725 | \def boot_rww_enable() 726 | 727 | Enable the Read-While-Write memory section. */ 728 | 729 | /** \ingroup avr_boot 730 | \def boot_lock_bits_set(lock_bits) 731 | 732 | Set the bootloader lock bits. 733 | 734 | \param lock_bits A mask of which Boot Loader Lock Bits to set. 735 | 736 | \note In this context, a 'set bit' will be written to a zero value. 737 | Note also that only BLBxx bits can be programmed by this command. 738 | 739 | For example, to disallow the SPM instruction from writing to the Boot 740 | Loader memory section of flash, you would use this macro as such: 741 | 742 | \code 743 | boot_lock_bits_set (_BV (BLB11)); 744 | \endcode 745 | 746 | \note Like any lock bits, the Boot Loader Lock Bits, once set, 747 | cannot be cleared again except by a chip erase which will in turn 748 | also erase the boot loader itself. */ 749 | 750 | /* Normal versions of the macros use 16-bit addresses. 751 | Extended versions of the macros use 32-bit addresses. 752 | Alternate versions of the macros use 16-bit addresses and require special 753 | instruction sequences after LPM. 754 | 755 | FLASHEND is defined in the ioXXXX.h file. 756 | USHRT_MAX is defined in . */ 757 | 758 | #if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \ 759 | || defined(__AVR_ATmega323__) 760 | 761 | /* Alternate: ATmega161/163/323 and 16 bit address */ 762 | #define boot_page_fill(address, data) __boot_page_fill_alternate(address, data) 763 | #define boot_page_erase(address) __boot_page_erase_alternate(address) 764 | #define boot_page_write(address) __boot_page_write_alternate(address) 765 | #define boot_rww_enable() __boot_rww_enable_alternate() 766 | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits) 767 | 768 | #elif (FLASHEND > USHRT_MAX) 769 | 770 | /* Extended: >16 bit address */ 771 | #define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data) 772 | #define boot_page_erase(address) __boot_page_erase_extended_short(address) 773 | #define boot_page_write(address) __boot_page_write_extended_short(address) 774 | #define boot_rww_enable() __boot_rww_enable_short() 775 | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits) 776 | 777 | #else 778 | 779 | /* Normal: 16 bit address */ 780 | #define boot_page_fill(address, data) __boot_page_fill_short(address, data) 781 | #define boot_page_erase(address) __boot_page_erase_short(address) 782 | #define boot_page_write(address) __boot_page_write_short(address) 783 | #define boot_rww_enable() __boot_rww_enable_short() 784 | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits) 785 | 786 | #endif 787 | 788 | /** \ingroup avr_boot 789 | 790 | Same as boot_page_fill() except it waits for eeprom and spm operations to 791 | complete before filling the page. */ 792 | 793 | #define boot_page_fill_safe(address, data) \ 794 | do { \ 795 | boot_spm_busy_wait(); \ 796 | eeprom_busy_wait(); \ 797 | boot_page_fill(address, data); \ 798 | } while (0) 799 | 800 | /** \ingroup avr_boot 801 | 802 | Same as boot_page_erase() except it waits for eeprom and spm operations to 803 | complete before erasing the page. */ 804 | 805 | #define boot_page_erase_safe(address) \ 806 | do { \ 807 | boot_spm_busy_wait(); \ 808 | eeprom_busy_wait(); \ 809 | boot_page_erase (address); \ 810 | } while (0) 811 | 812 | /** \ingroup avr_boot 813 | 814 | Same as boot_page_write() except it waits for eeprom and spm operations to 815 | complete before writing the page. */ 816 | 817 | #define boot_page_write_safe(address) \ 818 | do { \ 819 | boot_spm_busy_wait(); \ 820 | eeprom_busy_wait(); \ 821 | boot_page_write (address); \ 822 | } while (0) 823 | 824 | /** \ingroup avr_boot 825 | 826 | Same as boot_rww_enable() except waits for eeprom and spm operations to 827 | complete before enabling the RWW mameory. */ 828 | 829 | #define boot_rww_enable_safe() \ 830 | do { \ 831 | boot_spm_busy_wait(); \ 832 | eeprom_busy_wait(); \ 833 | boot_rww_enable(); \ 834 | } while (0) 835 | 836 | /** \ingroup avr_boot 837 | 838 | Same as boot_lock_bits_set() except waits for eeprom and spm operations to 839 | complete before setting the lock bits. */ 840 | 841 | #define boot_lock_bits_set_safe(lock_bits) \ 842 | do { \ 843 | boot_spm_busy_wait(); \ 844 | eeprom_busy_wait(); \ 845 | boot_lock_bits_set (lock_bits); \ 846 | } while (0) 847 | 848 | #endif /* _AVR_BOOT_H_ */ 849 | --------------------------------------------------------------------------------