Merge branch 'master' into wifly_integration

This commit is contained in:
amcewen 2011-08-28 20:28:53 +01:00
commit 8ce77304f7
31 changed files with 2299 additions and 1336 deletions

View File

@ -14,10 +14,11 @@ uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L uno.build.f_cpu=16000000L
uno.build.core=arduino uno.build.core=arduino
uno.build.variant=standard
############################################################## ##############################################################
atmega328.name=Arduino Duemilanove or Nano w/ ATmega328 atmega328.name=Arduino Duemilanove w/ ATmega328
atmega328.upload.protocol=stk500 atmega328.upload.protocol=stk500
atmega328.upload.maximum_size=30720 atmega328.upload.maximum_size=30720
@ -34,10 +35,11 @@ atmega328.bootloader.lock_bits=0x0F
atmega328.build.mcu=atmega328p atmega328.build.mcu=atmega328p
atmega328.build.f_cpu=16000000L atmega328.build.f_cpu=16000000L
atmega328.build.core=arduino atmega328.build.core=arduino
atmega328.build.variant=standard
############################################################## ##############################################################
diecimila.name=Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168
diecimila.upload.protocol=stk500 diecimila.upload.protocol=stk500
diecimila.upload.maximum_size=14336 diecimila.upload.maximum_size=14336
@ -54,6 +56,49 @@ diecimila.bootloader.lock_bits=0x0F
diecimila.build.mcu=atmega168 diecimila.build.mcu=atmega168
diecimila.build.f_cpu=16000000L diecimila.build.f_cpu=16000000L
diecimila.build.core=arduino diecimila.build.core=arduino
diecimila.build.variant=standard
##############################################################
nano328.name=Arduino Nano w/ ATmega328
nano328.upload.protocol=stk500
nano328.upload.maximum_size=30720
nano328.upload.speed=57600
nano328.bootloader.low_fuses=0xFF
nano328.bootloader.high_fuses=0xDA
nano328.bootloader.extended_fuses=0x05
nano328.bootloader.path=atmega
nano328.bootloader.file=ATmegaBOOT_168_atmega328.hex
nano328.bootloader.unlock_bits=0x3F
nano328.bootloader.lock_bits=0x0F
nano328.build.mcu=atmega328p
nano328.build.f_cpu=16000000L
nano328.build.core=arduino
nano328.build.variant=eightanaloginputs
##############################################################
nano.name=Arduino Nano w/ ATmega168
nano.upload.protocol=stk500
nano.upload.maximum_size=14336
nano.upload.speed=19200
nano.bootloader.low_fuses=0xff
nano.bootloader.high_fuses=0xdd
nano.bootloader.extended_fuses=0x00
nano.bootloader.path=atmega
nano.bootloader.file=ATmegaBOOT_168_diecimila.hex
nano.bootloader.unlock_bits=0x3F
nano.bootloader.lock_bits=0x0F
nano.build.mcu=atmega168
nano.build.f_cpu=16000000L
nano.build.core=arduino
nano.build.variant=eightanaloginputs
############################################################## ##############################################################
@ -74,6 +119,7 @@ mega2560.bootloader.lock_bits=0x0F
mega2560.build.mcu=atmega2560 mega2560.build.mcu=atmega2560
mega2560.build.f_cpu=16000000L mega2560.build.f_cpu=16000000L
mega2560.build.core=arduino mega2560.build.core=arduino
mega2560.build.variant=mega
############################################################## ##############################################################
@ -94,6 +140,7 @@ mega.bootloader.lock_bits=0x0F
mega.build.mcu=atmega1280 mega.build.mcu=atmega1280
mega.build.f_cpu=16000000L mega.build.f_cpu=16000000L
mega.build.core=arduino mega.build.core=arduino
mega.build.variant=mega
############################################################## ##############################################################
@ -114,6 +161,7 @@ mini.bootloader.lock_bits=0x0F
mini.build.mcu=atmega168 mini.build.mcu=atmega168
mini.build.f_cpu=16000000L mini.build.f_cpu=16000000L
mini.build.core=arduino mini.build.core=arduino
mini.build.variant=eightanaloginputs
############################################################## ##############################################################
@ -133,7 +181,8 @@ fio.bootloader.lock_bits=0x0F
fio.build.mcu=atmega328p fio.build.mcu=atmega328p
fio.build.f_cpu=8000000L fio.build.f_cpu=8000000L
fio.build.core=arduino:arduino fio.build.core=arduino
fio.build.variant=eightanaloginputs
############################################################## ##############################################################
@ -155,6 +204,7 @@ bt328.bootloader.lock_bits=0x0F
bt328.build.mcu=atmega328p bt328.build.mcu=atmega328p
bt328.build.f_cpu=16000000L bt328.build.f_cpu=16000000L
bt328.build.core=arduino bt328.build.core=arduino
bt328.build.variant=eightanaloginputs
############################################################## ##############################################################
@ -176,6 +226,7 @@ bt.bootloader.lock_bits=0x0F
bt.build.mcu=atmega168 bt.build.mcu=atmega168
bt.build.f_cpu=16000000L bt.build.f_cpu=16000000L
bt.build.core=arduino bt.build.core=arduino
bt.build.variant=eightanaloginputs
############################################################## ##############################################################
@ -196,6 +247,7 @@ lilypad328.bootloader.lock_bits=0x0F
lilypad328.build.mcu=atmega328p lilypad328.build.mcu=atmega328p
lilypad328.build.f_cpu=8000000L lilypad328.build.f_cpu=8000000L
lilypad328.build.core=arduino lilypad328.build.core=arduino
lilypad328.build.variant=standard
############################################################## ##############################################################
@ -216,6 +268,7 @@ lilypad.bootloader.lock_bits=0x0F
lilypad.build.mcu=atmega168 lilypad.build.mcu=atmega168
lilypad.build.f_cpu=8000000L lilypad.build.f_cpu=8000000L
lilypad.build.core=arduino lilypad.build.core=arduino
lilypad.build.variant=standard
############################################################## ##############################################################
@ -236,6 +289,7 @@ pro5v328.bootloader.lock_bits=0x0F
pro5v328.build.mcu=atmega328p pro5v328.build.mcu=atmega328p
pro5v328.build.f_cpu=16000000L pro5v328.build.f_cpu=16000000L
pro5v328.build.core=arduino pro5v328.build.core=arduino
pro5v328.build.variant=standard
############################################################## ##############################################################
@ -256,6 +310,7 @@ pro5v.bootloader.lock_bits=0x0F
pro5v.build.mcu=atmega168 pro5v.build.mcu=atmega168
pro5v.build.f_cpu=16000000L pro5v.build.f_cpu=16000000L
pro5v.build.core=arduino pro5v.build.core=arduino
pro5v.build.variant=standard
############################################################## ##############################################################
@ -276,6 +331,7 @@ pro328.bootloader.lock_bits=0x0F
pro328.build.mcu=atmega328p pro328.build.mcu=atmega328p
pro328.build.f_cpu=8000000L pro328.build.f_cpu=8000000L
pro328.build.core=arduino pro328.build.core=arduino
pro328.build.variant=standard
############################################################## ##############################################################
@ -296,6 +352,7 @@ pro.bootloader.lock_bits=0x0F
pro.build.mcu=atmega168 pro.build.mcu=atmega168
pro.build.f_cpu=8000000L pro.build.f_cpu=8000000L
pro.build.core=arduino pro.build.core=arduino
pro.build.variant=standard
############################################################## ##############################################################
@ -316,6 +373,7 @@ atmega168.bootloader.lock_bits=0x0F
atmega168.build.mcu=atmega168 atmega168.build.mcu=atmega168
atmega168.build.f_cpu=16000000L atmega168.build.f_cpu=16000000L
atmega168.build.core=arduino atmega168.build.core=arduino
atmega168.build.variant=standard
############################################################## ##############################################################
@ -335,4 +393,4 @@ atmega8.bootloader.lock_bits=0x0F
atmega8.build.mcu=atmega8 atmega8.build.mcu=atmega8
atmega8.build.f_cpu=16000000L atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino atmega8.build.core=arduino
atmega8.build.variant=standard

View File

@ -213,7 +213,7 @@ int main(void) {
// If not, uncomment the following instructions: // If not, uncomment the following instructions:
// cli(); // cli();
// SP=RAMEND; // This is done by hardware reset // SP=RAMEND; // This is done by hardware reset
// asm volatile ("clr __zero_reg__"); asm volatile ("clr __zero_reg__");
uint8_t ch; uint8_t ch;

View File

@ -1,33 +1,33 @@
:107E000085E08093810082E08093C00088E18093C8 :107E0000112485E08093810082E08093C00088E1A6
:107E1000C10086E08093C20080E18093C40084B7F3 :107E10008093C10086E08093C20080E18093C4001B
:107E200014BE81FFD0D08DE0C8D0259A86E020E333 :107E200084B714BE81FFD0D08DE0C8D0259A86E0FB
:107E30003CEF91E0309385002093840096BBB09B8B :107E300020E33CEF91E0309385002093840096BBD3
:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 :107E4000B09BFECF1D9AA8958150A9F7DD24D3944D
:107E5000EA2EF1E1FF2EA4D0813421F481E0BED0DE :107E5000A5E0EA2EF1E1FF2EA4D0813421F481E0E7
:107E600083E024C0823411F484E103C0853419F422 :107E6000BED083E024C0823411F484E103C08534A1
:107E700085E0B4D08AC08535A1F492D0082F10E0F7 :107E700019F485E0B4D08AC08535A1F492D0082FDA
:107E800010930102009300028BD090E0982F882776 :107E800010E010930102009300028BD090E0982F35
:107E9000802B912B880F991F9093010280930002F1 :107E90008827802B912B880F991F90930102809344
:107EA00073C0863529F484E099D080E071D06DC02C :107EA000000273C0863529F484E099D080E071D057
:107EB000843609F043C07CD0E0910002F0910102C9 :107EB0006DC0843609F043C07CD0E0910002F0919F
:107EC00083E080935700E895C0E0D1E069D08993C2 :107EC000010283E080935700E895C0E0D1E069D0DB
:107ED000809102028150809302028823B9F778D002 :107ED0008993809102028150809302028823B9F72E
:107EE00007B600FCFDCF4091000250910102A0E0D6 :107EE00078D007B600FCFDCF40910002509101020E
:107EF000B1E02C9130E011968C91119790E0982F81 :107EF000A0E0B1E02C9130E011968C91119790E0C8
:107F00008827822B932B1296FA010C01D0925700EE :107F0000982F8827822B932B1296FA010C01D0927E
:107F1000E89511244E5F5F4FF1E0A038BF0749F7A5 :107F10005700E89511244E5F5F4FF1E0A038BF078E
:107F2000E0910002F0910102E0925700E89507B657 :107F200049F7E0910002F0910102E0925700E895D4
:107F300000FCFDCFF0925700E89527C08437B9F4D4 :107F300007B600FCFDCFF0925700E89527C08437C4
:107F400037D046D0E0910002F09101023196F093D3 :107F4000B9F437D046D0E0910002F09101023196A9
:107F50000102E09300023197E4918E2F19D08091B5 :107F5000F0930102E09300023197E4918E2F19D043
:107F60000202815080930202882361F70EC0853798 :107F600080910202815080930202882361F70EC043
:107F700039F42ED08EE10CD085E90AD08FE096CF6F :107F7000853739F42ED08EE10CD085E90AD08FE018
:107F8000813511F488E019D023D080E101D063CF8E :107F800096CF813511F488E019D023D080E101D05B
:107F9000982F8091C00085FFFCCF9093C600089574 :107F900063CF982F8091C00085FFFCCF9093C600DF
:107FA000A8958091C00087FFFCCF8091C6000895FE :107FA0000895A8958091C00087FFFCCF8091C600FE
:107FB000F7DFF6DF80930202F3CFE0E6F0E098E12E :107FB0000895F7DFF6DF80930202F3CFE0E6F0E00A
:107FC00090838083089580E0F8DFEE27FF270994EF :107FC00098E190838083089580E0F8DFEE27FF2713
:107FD000E7DF803209F0F7DF84E1DACF1F93182F53 :107FD0000994E7DF803209F0F7DF84E1DACF1F93FD
:0C7FE000DFDF1150E9F7F4DF1F91089576 :0E7FE000182FDFDF1150E9F7F4DF1F9108952D
:0400000300007E007B :0400000300007E007B
:00000001FF :00000001FF

View File

@ -3,25 +3,25 @@ optiboot_atmega328.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn Idx Name Size VMA LMA File off Algn
0 .text 000001ec 00007e00 00007e00 00000054 2**1 0 .text 000001ee 00007e00 00007e00 00000054 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .debug_aranges 00000028 00000000 00000000 00000240 2**0 1 .debug_aranges 00000028 00000000 00000000 00000242 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000268 2**0 2 .debug_pubnames 0000006a 00000000 00000000 0000026a 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000269 00000000 00000000 000002d2 2**0 3 .debug_info 00000269 00000000 00000000 000002d4 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 00000196 00000000 00000000 0000053b 2**0 4 .debug_abbrev 00000196 00000000 00000000 0000053d 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003d3 00000000 00000000 000006d1 2**0 5 .debug_line 000003db 00000000 00000000 000006d3 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000aa4 2**2 6 .debug_frame 00000090 00000000 00000000 00000ab0 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000135 00000000 00000000 00000b34 2**0 7 .debug_str 00000124 00000000 00000000 00000b40 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001d1 00000000 00000000 00000c69 2**0 8 .debug_loc 000001d1 00000000 00000000 00000c64 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000e3a 2**0 9 .debug_ranges 00000068 00000000 00000000 00000e35 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@ -33,488 +33,492 @@ Disassembly of section .text:
#endif #endif
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
7e00: 85 e0 ldi r24, 0x05 ; 5 7e00: 11 24 eor r1, r1
7e02: 80 93 81 00 sts 0x0081, r24
uint8_t ch;
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
7e02: 85 e0 ldi r24, 0x05 ; 5
7e04: 80 93 81 00 sts 0x0081, r24
#endif #endif
#ifndef SOFT_UART #ifndef SOFT_UART
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
7e06: 82 e0 ldi r24, 0x02 ; 2 7e08: 82 e0 ldi r24, 0x02 ; 2
7e08: 80 93 c0 00 sts 0x00C0, r24 7e0a: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
7e0c: 88 e1 ldi r24, 0x18 ; 24 7e0e: 88 e1 ldi r24, 0x18 ; 24
7e0e: 80 93 c1 00 sts 0x00C1, r24 7e10: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
7e12: 86 e0 ldi r24, 0x06 ; 6 7e14: 86 e0 ldi r24, 0x06 ; 6
7e14: 80 93 c2 00 sts 0x00C2, r24 7e16: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
7e18: 80 e1 ldi r24, 0x10 ; 16 7e1a: 80 e1 ldi r24, 0x10 ; 16
7e1a: 80 93 c4 00 sts 0x00C4, r24 7e1c: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
7e1e: 84 b7 in r24, 0x34 ; 52 7e20: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
7e20: 14 be out 0x34, r1 ; 52 7e22: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
7e22: 81 ff sbrs r24, 1 7e24: 81 ff sbrs r24, 1
7e24: d0 d0 rcall .+416 ; 0x7fc6 <appStart> 7e26: d0 d0 rcall .+416 ; 0x7fc8 <appStart>
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_500MS); watchdogConfig(WATCHDOG_500MS);
7e26: 8d e0 ldi r24, 0x0D ; 13 7e28: 8d e0 ldi r24, 0x0D ; 13
7e28: c8 d0 rcall .+400 ; 0x7fba <watchdogConfig> 7e2a: c8 d0 rcall .+400 ; 0x7fbc <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
7e2a: 25 9a sbi 0x04, 5 ; 4 7e2c: 25 9a sbi 0x04, 5 ; 4
7e2c: 86 e0 ldi r24, 0x06 ; 6 7e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e2e: 20 e3 ldi r18, 0x30 ; 48 7e30: 20 e3 ldi r18, 0x30 ; 48
7e30: 3c ef ldi r19, 0xFC ; 252 7e32: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e32: 91 e0 ldi r25, 0x01 ; 1 7e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e34: 30 93 85 00 sts 0x0085, r19 7e36: 30 93 85 00 sts 0x0085, r19
7e38: 20 93 84 00 sts 0x0084, r18 7e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e3c: 96 bb out 0x16, r25 ; 22 7e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
7e3e: b0 9b sbis 0x16, 0 ; 22 7e40: b0 9b sbis 0x16, 0 ; 22
7e40: fe cf rjmp .-4 ; 0x7e3e <main+0x3e> 7e42: fe cf rjmp .-4 ; 0x7e40 <main+0x40>
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
7e42: 1d 9a sbi 0x03, 5 ; 3 7e44: 1d 9a sbi 0x03, 5 ; 3
return getch(); return getch();
} }
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
7e44: a8 95 wdr 7e46: a8 95 wdr
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
7e46: 81 50 subi r24, 0x01 ; 1 7e48: 81 50 subi r24, 0x01 ; 1
7e48: a9 f7 brne .-22 ; 0x7e34 <main+0x34> 7e4a: a9 f7 brne .-22 ; 0x7e36 <main+0x36>
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
getNch(1); getNch(1);
7e4a: dd 24 eor r13, r13 7e4c: dd 24 eor r13, r13
7e4c: d3 94 inc r13 7e4e: d3 94 inc r13
boot_page_fill((uint16_t)(void*)addrPtr,a); boot_page_fill((uint16_t)(void*)addrPtr,a);
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
boot_page_write((uint16_t)(void*)address); boot_page_write((uint16_t)(void*)address);
7e4e: a5 e0 ldi r26, 0x05 ; 5 7e50: a5 e0 ldi r26, 0x05 ; 5
7e50: ea 2e mov r14, r26 7e52: ea 2e mov r14, r26
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7e52: f1 e1 ldi r31, 0x11 ; 17 7e54: f1 e1 ldi r31, 0x11 ; 17
7e54: ff 2e mov r15, r31 7e56: ff 2e mov r15, r31
#endif #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
7e56: a4 d0 rcall .+328 ; 0x7fa0 <getch> 7e58: a4 d0 rcall .+328 ; 0x7fa2 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
7e58: 81 34 cpi r24, 0x41 ; 65 7e5a: 81 34 cpi r24, 0x41 ; 65
7e5a: 21 f4 brne .+8 ; 0x7e64 <main+0x64> 7e5c: 21 f4 brne .+8 ; 0x7e66 <main+0x66>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
getNch(1); getNch(1);
7e5c: 81 e0 ldi r24, 0x01 ; 1 7e5e: 81 e0 ldi r24, 0x01 ; 1
7e5e: be d0 rcall .+380 ; 0x7fdc <verifySpace+0xc> 7e60: be d0 rcall .+380 ; 0x7fde <verifySpace+0xc>
putch(0x03); putch(0x03);
7e60: 83 e0 ldi r24, 0x03 ; 3 7e62: 83 e0 ldi r24, 0x03 ; 3
7e62: 24 c0 rjmp .+72 ; 0x7eac <main+0xac> 7e64: 24 c0 rjmp .+72 ; 0x7eae <main+0xae>
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
7e64: 82 34 cpi r24, 0x42 ; 66 7e66: 82 34 cpi r24, 0x42 ; 66
7e66: 11 f4 brne .+4 ; 0x7e6c <main+0x6c> 7e68: 11 f4 brne .+4 ; 0x7e6e <main+0x6e>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
7e68: 84 e1 ldi r24, 0x14 ; 20 7e6a: 84 e1 ldi r24, 0x14 ; 20
7e6a: 03 c0 rjmp .+6 ; 0x7e72 <main+0x72> 7e6c: 03 c0 rjmp .+6 ; 0x7e74 <main+0x74>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
7e6c: 85 34 cpi r24, 0x45 ; 69 7e6e: 85 34 cpi r24, 0x45 ; 69
7e6e: 19 f4 brne .+6 ; 0x7e76 <main+0x76> 7e70: 19 f4 brne .+6 ; 0x7e78 <main+0x78>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
7e70: 85 e0 ldi r24, 0x05 ; 5 7e72: 85 e0 ldi r24, 0x05 ; 5
7e72: b4 d0 rcall .+360 ; 0x7fdc <verifySpace+0xc> 7e74: b4 d0 rcall .+360 ; 0x7fde <verifySpace+0xc>
7e74: 8a c0 rjmp .+276 ; 0x7f8a <main+0x18a> 7e76: 8a c0 rjmp .+276 ; 0x7f8c <main+0x18c>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
7e76: 85 35 cpi r24, 0x55 ; 85 7e78: 85 35 cpi r24, 0x55 ; 85
7e78: a1 f4 brne .+40 ; 0x7ea2 <main+0xa2> 7e7a: a1 f4 brne .+40 ; 0x7ea4 <main+0xa4>
// LOAD ADDRESS // LOAD ADDRESS
address = getch(); address = getch();
7e7a: 92 d0 rcall .+292 ; 0x7fa0 <getch> 7e7c: 92 d0 rcall .+292 ; 0x7fa2 <getch>
7e7c: 08 2f mov r16, r24 7e7e: 08 2f mov r16, r24
7e7e: 10 e0 ldi r17, 0x00 ; 0 7e80: 10 e0 ldi r17, 0x00 ; 0
7e80: 10 93 01 02 sts 0x0201, r17 7e82: 10 93 01 02 sts 0x0201, r17
7e84: 00 93 00 02 sts 0x0200, r16 7e86: 00 93 00 02 sts 0x0200, r16
address = (address & 0xff) | (getch() << 8); address = (address & 0xff) | (getch() << 8);
7e88: 8b d0 rcall .+278 ; 0x7fa0 <getch> 7e8a: 8b d0 rcall .+278 ; 0x7fa2 <getch>
7e8a: 90 e0 ldi r25, 0x00 ; 0 7e8c: 90 e0 ldi r25, 0x00 ; 0
7e8c: 98 2f mov r25, r24 7e8e: 98 2f mov r25, r24
7e8e: 88 27 eor r24, r24 7e90: 88 27 eor r24, r24
7e90: 80 2b or r24, r16 7e92: 80 2b or r24, r16
7e92: 91 2b or r25, r17 7e94: 91 2b or r25, r17
address += address; // Convert from word address to byte address address += address; // Convert from word address to byte address
7e94: 88 0f add r24, r24 7e96: 88 0f add r24, r24
7e96: 99 1f adc r25, r25 7e98: 99 1f adc r25, r25
7e98: 90 93 01 02 sts 0x0201, r25 7e9a: 90 93 01 02 sts 0x0201, r25
7e9c: 80 93 00 02 sts 0x0200, r24 7e9e: 80 93 00 02 sts 0x0200, r24
7ea0: 73 c0 rjmp .+230 ; 0x7f88 <main+0x188> 7ea2: 73 c0 rjmp .+230 ; 0x7f8a <main+0x18a>
verifySpace(); verifySpace();
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
7ea2: 86 35 cpi r24, 0x56 ; 86 7ea4: 86 35 cpi r24, 0x56 ; 86
7ea4: 29 f4 brne .+10 ; 0x7eb0 <main+0xb0> 7ea6: 29 f4 brne .+10 ; 0x7eb2 <main+0xb2>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
7ea6: 84 e0 ldi r24, 0x04 ; 4 7ea8: 84 e0 ldi r24, 0x04 ; 4
7ea8: 99 d0 rcall .+306 ; 0x7fdc <verifySpace+0xc> 7eaa: 99 d0 rcall .+306 ; 0x7fde <verifySpace+0xc>
putch(0x00); putch(0x00);
7eaa: 80 e0 ldi r24, 0x00 ; 0 7eac: 80 e0 ldi r24, 0x00 ; 0
7eac: 71 d0 rcall .+226 ; 0x7f90 <putch> 7eae: 71 d0 rcall .+226 ; 0x7f92 <putch>
7eae: 6d c0 rjmp .+218 ; 0x7f8a <main+0x18a> 7eb0: 6d c0 rjmp .+218 ; 0x7f8c <main+0x18c>
} }
/* Write memory, length is big endian and is in bytes */ /* Write memory, length is big endian and is in bytes */
else if(ch == STK_PROG_PAGE) { else if(ch == STK_PROG_PAGE) {
7eb0: 84 36 cpi r24, 0x64 ; 100 7eb2: 84 36 cpi r24, 0x64 ; 100
7eb2: 09 f0 breq .+2 ; 0x7eb6 <main+0xb6> 7eb4: 09 f0 breq .+2 ; 0x7eb8 <main+0xb8>
7eb4: 43 c0 rjmp .+134 ; 0x7f3c <main+0x13c> 7eb6: 43 c0 rjmp .+134 ; 0x7f3e <main+0x13e>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getLen();
7eb6: 7c d0 rcall .+248 ; 0x7fb0 <getLen> 7eb8: 7c d0 rcall .+248 ; 0x7fb2 <getLen>
// Immediately start page erase - this will 4.5ms // Immediately start page erase - this will 4.5ms
boot_page_erase((uint16_t)(void*)address); boot_page_erase((uint16_t)(void*)address);
7eb8: e0 91 00 02 lds r30, 0x0200 7eba: e0 91 00 02 lds r30, 0x0200
7ebc: f0 91 01 02 lds r31, 0x0201 7ebe: f0 91 01 02 lds r31, 0x0201
7ec0: 83 e0 ldi r24, 0x03 ; 3 7ec2: 83 e0 ldi r24, 0x03 ; 3
7ec2: 80 93 57 00 sts 0x0057, r24 7ec4: 80 93 57 00 sts 0x0057, r24
7ec6: e8 95 spm 7ec8: e8 95 spm
7ec8: c0 e0 ldi r28, 0x00 ; 0 7eca: c0 e0 ldi r28, 0x00 ; 0
7eca: d1 e0 ldi r29, 0x01 ; 1 7ecc: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
7ecc: 69 d0 rcall .+210 ; 0x7fa0 <getch> 7ece: 69 d0 rcall .+210 ; 0x7fa2 <getch>
7ece: 89 93 st Y+, r24 7ed0: 89 93 st Y+, r24
while (--length); while (--length);
7ed0: 80 91 02 02 lds r24, 0x0202 7ed2: 80 91 02 02 lds r24, 0x0202
7ed4: 81 50 subi r24, 0x01 ; 1 7ed6: 81 50 subi r24, 0x01 ; 1
7ed6: 80 93 02 02 sts 0x0202, r24 7ed8: 80 93 02 02 sts 0x0202, r24
7eda: 88 23 and r24, r24 7edc: 88 23 and r24, r24
7edc: b9 f7 brne .-18 ; 0x7ecc <main+0xcc> 7ede: b9 f7 brne .-18 ; 0x7ece <main+0xce>
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
7ede: 78 d0 rcall .+240 ; 0x7fd0 <verifySpace> 7ee0: 78 d0 rcall .+240 ; 0x7fd2 <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
7ee0: 07 b6 in r0, 0x37 ; 55 7ee2: 07 b6 in r0, 0x37 ; 55
7ee2: 00 fc sbrc r0, 0 7ee4: 00 fc sbrc r0, 0
7ee4: fd cf rjmp .-6 ; 0x7ee0 <main+0xe0> 7ee6: fd cf rjmp .-6 ; 0x7ee2 <main+0xe2>
} }
#endif #endif
// Copy buffer into programming buffer // Copy buffer into programming buffer
bufPtr = buff; bufPtr = buff;
addrPtr = (uint16_t)(void*)address; addrPtr = (uint16_t)(void*)address;
7ee6: 40 91 00 02 lds r20, 0x0200 7ee8: 40 91 00 02 lds r20, 0x0200
7eea: 50 91 01 02 lds r21, 0x0201 7eec: 50 91 01 02 lds r21, 0x0201
7eee: a0 e0 ldi r26, 0x00 ; 0 7ef0: a0 e0 ldi r26, 0x00 ; 0
7ef0: b1 e0 ldi r27, 0x01 ; 1 7ef2: b1 e0 ldi r27, 0x01 ; 1
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
7ef2: 2c 91 ld r18, X 7ef4: 2c 91 ld r18, X
7ef4: 30 e0 ldi r19, 0x00 ; 0 7ef6: 30 e0 ldi r19, 0x00 ; 0
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
7ef6: 11 96 adiw r26, 0x01 ; 1 7ef8: 11 96 adiw r26, 0x01 ; 1
7ef8: 8c 91 ld r24, X 7efa: 8c 91 ld r24, X
7efa: 11 97 sbiw r26, 0x01 ; 1 7efc: 11 97 sbiw r26, 0x01 ; 1
7efc: 90 e0 ldi r25, 0x00 ; 0 7efe: 90 e0 ldi r25, 0x00 ; 0
7efe: 98 2f mov r25, r24 7f00: 98 2f mov r25, r24
7f00: 88 27 eor r24, r24 7f02: 88 27 eor r24, r24
7f02: 82 2b or r24, r18 7f04: 82 2b or r24, r18
7f04: 93 2b or r25, r19 7f06: 93 2b or r25, r19
#ifdef VIRTUAL_BOOT_PARTITION #ifdef VIRTUAL_BOOT_PARTITION
#define rstVect (*(uint16_t*)(0x204)) #define rstVect (*(uint16_t*)(0x204))
#define wdtVect (*(uint16_t*)(0x206)) #define wdtVect (*(uint16_t*)(0x206))
#endif #endif
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
7f06: 12 96 adiw r26, 0x02 ; 2 7f08: 12 96 adiw r26, 0x02 ; 2
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
boot_page_fill((uint16_t)(void*)addrPtr,a); boot_page_fill((uint16_t)(void*)addrPtr,a);
7f08: fa 01 movw r30, r20 7f0a: fa 01 movw r30, r20
7f0a: 0c 01 movw r0, r24 7f0c: 0c 01 movw r0, r24
7f0c: d0 92 57 00 sts 0x0057, r13 7f0e: d0 92 57 00 sts 0x0057, r13
7f10: e8 95 spm 7f12: e8 95 spm
7f12: 11 24 eor r1, r1 7f14: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
7f14: 4e 5f subi r20, 0xFE ; 254 7f16: 4e 5f subi r20, 0xFE ; 254
7f16: 5f 4f sbci r21, 0xFF ; 255 7f18: 5f 4f sbci r21, 0xFF ; 255
} while (--ch); } while (--ch);
7f18: f1 e0 ldi r31, 0x01 ; 1 7f1a: f1 e0 ldi r31, 0x01 ; 1
7f1a: a0 38 cpi r26, 0x80 ; 128 7f1c: a0 38 cpi r26, 0x80 ; 128
7f1c: bf 07 cpc r27, r31 7f1e: bf 07 cpc r27, r31
7f1e: 49 f7 brne .-46 ; 0x7ef2 <main+0xf2> 7f20: 49 f7 brne .-46 ; 0x7ef4 <main+0xf4>
// Write from programming buffer // Write from programming buffer
boot_page_write((uint16_t)(void*)address); boot_page_write((uint16_t)(void*)address);
7f20: e0 91 00 02 lds r30, 0x0200 7f22: e0 91 00 02 lds r30, 0x0200
7f24: f0 91 01 02 lds r31, 0x0201 7f26: f0 91 01 02 lds r31, 0x0201
7f28: e0 92 57 00 sts 0x0057, r14 7f2a: e0 92 57 00 sts 0x0057, r14
7f2c: e8 95 spm 7f2e: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
7f2e: 07 b6 in r0, 0x37 ; 55 7f30: 07 b6 in r0, 0x37 ; 55
7f30: 00 fc sbrc r0, 0 7f32: 00 fc sbrc r0, 0
7f32: fd cf rjmp .-6 ; 0x7f2e <main+0x12e> 7f34: fd cf rjmp .-6 ; 0x7f30 <main+0x130>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7f34: f0 92 57 00 sts 0x0057, r15 7f36: f0 92 57 00 sts 0x0057, r15
7f38: e8 95 spm 7f3a: e8 95 spm
7f3a: 27 c0 rjmp .+78 ; 0x7f8a <main+0x18a> 7f3c: 27 c0 rjmp .+78 ; 0x7f8c <main+0x18c>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
7f3c: 84 37 cpi r24, 0x74 ; 116 7f3e: 84 37 cpi r24, 0x74 ; 116
7f3e: b9 f4 brne .+46 ; 0x7f6e <main+0x16e> 7f40: b9 f4 brne .+46 ; 0x7f70 <main+0x170>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getLen();
7f40: 37 d0 rcall .+110 ; 0x7fb0 <getLen> 7f42: 37 d0 rcall .+110 ; 0x7fb2 <getLen>
verifySpace(); verifySpace();
7f42: 46 d0 rcall .+140 ; 0x7fd0 <verifySpace> 7f44: 46 d0 rcall .+140 ; 0x7fd2 <verifySpace>
else ch = pgm_read_byte_near(address); else ch = pgm_read_byte_near(address);
address++; address++;
putch(ch); putch(ch);
} while (--length); } while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
7f44: e0 91 00 02 lds r30, 0x0200 7f46: e0 91 00 02 lds r30, 0x0200
7f48: f0 91 01 02 lds r31, 0x0201 7f4a: f0 91 01 02 lds r31, 0x0201
7f4c: 31 96 adiw r30, 0x01 ; 1 7f4e: 31 96 adiw r30, 0x01 ; 1
7f4e: f0 93 01 02 sts 0x0201, r31 7f50: f0 93 01 02 sts 0x0201, r31
7f52: e0 93 00 02 sts 0x0200, r30 7f54: e0 93 00 02 sts 0x0200, r30
7f56: 31 97 sbiw r30, 0x01 ; 1 7f58: 31 97 sbiw r30, 0x01 ; 1
7f58: e4 91 lpm r30, Z+ 7f5a: e4 91 lpm r30, Z+
7f5a: 8e 2f mov r24, r30 7f5c: 8e 2f mov r24, r30
7f5c: 19 d0 rcall .+50 ; 0x7f90 <putch> 7f5e: 19 d0 rcall .+50 ; 0x7f92 <putch>
while (--length); while (--length);
7f5e: 80 91 02 02 lds r24, 0x0202 7f60: 80 91 02 02 lds r24, 0x0202
7f62: 81 50 subi r24, 0x01 ; 1 7f64: 81 50 subi r24, 0x01 ; 1
7f64: 80 93 02 02 sts 0x0202, r24 7f66: 80 93 02 02 sts 0x0202, r24
7f68: 88 23 and r24, r24 7f6a: 88 23 and r24, r24
7f6a: 61 f7 brne .-40 ; 0x7f44 <main+0x144> 7f6c: 61 f7 brne .-40 ; 0x7f46 <main+0x146>
7f6c: 0e c0 rjmp .+28 ; 0x7f8a <main+0x18a> 7f6e: 0e c0 rjmp .+28 ; 0x7f8c <main+0x18c>
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
7f6e: 85 37 cpi r24, 0x75 ; 117 7f70: 85 37 cpi r24, 0x75 ; 117
7f70: 39 f4 brne .+14 ; 0x7f80 <main+0x180> 7f72: 39 f4 brne .+14 ; 0x7f82 <main+0x182>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
7f72: 2e d0 rcall .+92 ; 0x7fd0 <verifySpace> 7f74: 2e d0 rcall .+92 ; 0x7fd2 <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
7f74: 8e e1 ldi r24, 0x1E ; 30 7f76: 8e e1 ldi r24, 0x1E ; 30
7f76: 0c d0 rcall .+24 ; 0x7f90 <putch> 7f78: 0c d0 rcall .+24 ; 0x7f92 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
7f78: 85 e9 ldi r24, 0x95 ; 149 7f7a: 85 e9 ldi r24, 0x95 ; 149
7f7a: 0a d0 rcall .+20 ; 0x7f90 <putch> 7f7c: 0a d0 rcall .+20 ; 0x7f92 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
7f7c: 8f e0 ldi r24, 0x0F ; 15 7f7e: 8f e0 ldi r24, 0x0F ; 15
7f7e: 96 cf rjmp .-212 ; 0x7eac <main+0xac> 7f80: 96 cf rjmp .-212 ; 0x7eae <main+0xae>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
7f80: 81 35 cpi r24, 0x51 ; 81 7f82: 81 35 cpi r24, 0x51 ; 81
7f82: 11 f4 brne .+4 ; 0x7f88 <main+0x188> 7f84: 11 f4 brne .+4 ; 0x7f8a <main+0x18a>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
7f84: 88 e0 ldi r24, 0x08 ; 8 7f86: 88 e0 ldi r24, 0x08 ; 8
7f86: 19 d0 rcall .+50 ; 0x7fba <watchdogConfig> 7f88: 19 d0 rcall .+50 ; 0x7fbc <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
7f88: 23 d0 rcall .+70 ; 0x7fd0 <verifySpace> 7f8a: 23 d0 rcall .+70 ; 0x7fd2 <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
7f8a: 80 e1 ldi r24, 0x10 ; 16 7f8c: 80 e1 ldi r24, 0x10 ; 16
7f8c: 01 d0 rcall .+2 ; 0x7f90 <putch> 7f8e: 01 d0 rcall .+2 ; 0x7f92 <putch>
7f8e: 63 cf rjmp .-314 ; 0x7e56 <main+0x56> 7f90: 63 cf rjmp .-314 ; 0x7e58 <main+0x58>
00007f90 <putch>: 00007f92 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
7f90: 98 2f mov r25, r24 7f92: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
7f92: 80 91 c0 00 lds r24, 0x00C0 7f94: 80 91 c0 00 lds r24, 0x00C0
7f96: 85 ff sbrs r24, 5 7f98: 85 ff sbrs r24, 5
7f98: fc cf rjmp .-8 ; 0x7f92 <putch+0x2> 7f9a: fc cf rjmp .-8 ; 0x7f94 <putch+0x2>
UDR0 = ch; UDR0 = ch;
7f9a: 90 93 c6 00 sts 0x00C6, r25 7f9c: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
7f9e: 08 95 ret 7fa0: 08 95 ret
00007fa0 <getch>: 00007fa2 <getch>:
return getch(); return getch();
} }
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
7fa0: a8 95 wdr 7fa2: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)));
7fa2: 80 91 c0 00 lds r24, 0x00C0 7fa4: 80 91 c0 00 lds r24, 0x00C0
7fa6: 87 ff sbrs r24, 7 7fa8: 87 ff sbrs r24, 7
7fa8: fc cf rjmp .-8 ; 0x7fa2 <getch+0x2> 7faa: fc cf rjmp .-8 ; 0x7fa4 <getch+0x2>
ch = UDR0; ch = UDR0;
7faa: 80 91 c6 00 lds r24, 0x00C6 7fac: 80 91 c6 00 lds r24, 0x00C6
#ifdef LED_DATA_FLASH #ifdef LED_DATA_FLASH
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
return ch; return ch;
} }
7fae: 08 95 ret 7fb0: 08 95 ret
00007fb0 <getLen>: 00007fb2 <getLen>:
} while (--count); } while (--count);
} }
#endif #endif
uint8_t getLen() { uint8_t getLen() {
getch(); getch();
7fb0: f7 df rcall .-18 ; 0x7fa0 <getch> 7fb2: f7 df rcall .-18 ; 0x7fa2 <getch>
length = getch(); length = getch();
7fb2: f6 df rcall .-20 ; 0x7fa0 <getch> 7fb4: f6 df rcall .-20 ; 0x7fa2 <getch>
7fb4: 80 93 02 02 sts 0x0202, r24 7fb6: 80 93 02 02 sts 0x0202, r24
return getch(); return getch();
} }
7fb8: f3 cf rjmp .-26 ; 0x7fa0 <getch> 7fba: f3 cf rjmp .-26 ; 0x7fa2 <getch>
00007fba <watchdogConfig>: 00007fbc <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
7fba: e0 e6 ldi r30, 0x60 ; 96 7fbc: e0 e6 ldi r30, 0x60 ; 96
7fbc: f0 e0 ldi r31, 0x00 ; 0 7fbe: f0 e0 ldi r31, 0x00 ; 0
7fbe: 98 e1 ldi r25, 0x18 ; 24 7fc0: 98 e1 ldi r25, 0x18 ; 24
7fc0: 90 83 st Z, r25 7fc2: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
7fc2: 80 83 st Z, r24 7fc4: 80 83 st Z, r24
} }
7fc4: 08 95 ret 7fc6: 08 95 ret
00007fc6 <appStart>: 00007fc8 <appStart>:
void appStart() { void appStart() {
watchdogConfig(WATCHDOG_OFF); watchdogConfig(WATCHDOG_OFF);
7fc6: 80 e0 ldi r24, 0x00 ; 0 7fc8: 80 e0 ldi r24, 0x00 ; 0
7fc8: f8 df rcall .-16 ; 0x7fba <watchdogConfig> 7fca: f8 df rcall .-16 ; 0x7fbc <watchdogConfig>
__asm__ __volatile__ ( __asm__ __volatile__ (
7fca: ee 27 eor r30, r30 7fcc: ee 27 eor r30, r30
7fcc: ff 27 eor r31, r31 7fce: ff 27 eor r31, r31
7fce: 09 94 ijmp 7fd0: 09 94 ijmp
00007fd0 <verifySpace>: 00007fd2 <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) appStart();
7fd0: e7 df rcall .-50 ; 0x7fa0 <getch> 7fd2: e7 df rcall .-50 ; 0x7fa2 <getch>
7fd2: 80 32 cpi r24, 0x20 ; 32 7fd4: 80 32 cpi r24, 0x20 ; 32
7fd4: 09 f0 breq .+2 ; 0x7fd8 <verifySpace+0x8> 7fd6: 09 f0 breq .+2 ; 0x7fda <verifySpace+0x8>
7fd6: f7 df rcall .-18 ; 0x7fc6 <appStart> 7fd8: f7 df rcall .-18 ; 0x7fc8 <appStart>
putch(STK_INSYNC); putch(STK_INSYNC);
7fd8: 84 e1 ldi r24, 0x14 ; 20 7fda: 84 e1 ldi r24, 0x14 ; 20
} }
7fda: da cf rjmp .-76 ; 0x7f90 <putch> 7fdc: da cf rjmp .-76 ; 0x7f92 <putch>
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
7fdc: 1f 93 push r17 7fde: 1f 93 push r17
7fde: 18 2f mov r17, r24 7fe0: 18 2f mov r17, r24
00007fe0 <getNch>: 00007fe2 <getNch>:
do getch(); while (--count); do getch(); while (--count);
7fe0: df df rcall .-66 ; 0x7fa0 <getch> 7fe2: df df rcall .-66 ; 0x7fa2 <getch>
7fe2: 11 50 subi r17, 0x01 ; 1 7fe4: 11 50 subi r17, 0x01 ; 1
7fe4: e9 f7 brne .-6 ; 0x7fe0 <getNch> 7fe6: e9 f7 brne .-6 ; 0x7fe2 <getNch>
verifySpace(); verifySpace();
7fe6: f4 df rcall .-24 ; 0x7fd0 <verifySpace> 7fe8: f4 df rcall .-24 ; 0x7fd2 <verifySpace>
} }
7fe8: 1f 91 pop r17 7fea: 1f 91 pop r17
7fea: 08 95 ret 7fec: 08 95 ret

205
cores/arduino/Arduino.h Executable file
View File

@ -0,0 +1,205 @@
#ifndef Arduino_h
#define Arduino_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "binary.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define true 0x1
#define false 0x0
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define interrupts() sei()
#define noInterrupts() cli()
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
typedef unsigned int word;
#define bit(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void init(void);
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
#define analogInPinToBit(P) (P)
// On the ATmega1280, the addresses of some of the port registers are
// greater than 255, so we can't store them in uint8_t's.
extern const uint16_t PROGMEM port_to_mode_PGM[];
extern const uint16_t PROGMEM port_to_input_PGM[];
extern const uint16_t PROGMEM port_to_output_PGM[];
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
#define NOT_A_PIN 0
#define NOT_A_PORT 0
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 10
#define PK 11
#define PL 12
#define NOT_ON_TIMER 0
#define TIMER0A 1
#define TIMER0B 2
#define TIMER1A 3
#define TIMER1B 4
#define TIMER2 5
#define TIMER2A 6
#define TIMER2B 7
#define TIMER3A 8
#define TIMER3B 9
#define TIMER3C 10
#define TIMER4A 11
#define TIMER4B 12
#define TIMER4C 13
#define TIMER5A 14
#define TIMER5B 15
#define TIMER5C 16
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);
#endif
#include "pins_arduino.h"
#endif

View File

@ -24,7 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include "wiring.h" #include "Arduino.h"
#include "wiring_private.h" #include "wiring_private.h"
// this next line disables the entire HardwareSerial.cpp, // this next line disables the entire HardwareSerial.cpp,
@ -34,149 +34,223 @@
#include "HardwareSerial.h" #include "HardwareSerial.h"
// Define constants and variables for buffering incoming serial data. We're // Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the // using a ring buffer (I think), in which head is the index of the location
// location to which to write the next incoming character and rx_buffer_tail // to which to write the next incoming character and tail is the index of the
// is the index of the location from which to read. // location from which to read.
#if (RAMEND < 1000) #if (RAMEND < 1000)
#define RX_BUFFER_SIZE 32 #define SERIAL_BUFFER_SIZE 16
#else #else
#define RX_BUFFER_SIZE 128 #define SERIAL_BUFFER_SIZE 64
#endif #endif
struct ring_buffer struct ring_buffer
{ {
unsigned char buffer[RX_BUFFER_SIZE]; unsigned char buffer[SERIAL_BUFFER_SIZE];
int head; volatile int head;
int tail; volatile int tail;
}; };
#if defined(UBRRH) || defined(UBRR0H) #if defined(UBRRH) || defined(UBRR0H)
ring_buffer rx_buffer = { { 0 }, 0, 0 }; ring_buffer rx_buffer = { { 0 }, 0, 0 };
ring_buffer tx_buffer = { { 0 }, 0, 0 };
#endif #endif
#if defined(UBRR1H) #if defined(UBRR1H)
ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
ring_buffer tx_buffer1 = { { 0 }, 0, 0 };
#endif #endif
#if defined(UBRR2H) #if defined(UBRR2H)
ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
ring_buffer tx_buffer2 = { { 0 }, 0, 0 };
#endif #endif
#if defined(UBRR3H) #if defined(UBRR3H)
ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
ring_buffer tx_buffer3 = { { 0 }, 0, 0 };
#endif #endif
inline void store_char(unsigned char c, ring_buffer *rx_buffer) inline void store_char(unsigned char c, ring_buffer *buffer)
{ {
int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE; int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location // if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the // just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer // current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head. // and so we don't write the character or advance the head.
if (i != rx_buffer->tail) { if (i != buffer->tail) {
rx_buffer->buffer[rx_buffer->head] = c; buffer->buffer[buffer->head] = c;
rx_buffer->head = i; buffer->head = i;
} }
} }
#if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \
!defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \
!defined(SIG_UART_RECV)
#error Don't know what the Data Received vector is called for the first UART
#else
void serialEvent() __attribute__((weak));
void serialEvent() {}
#if defined(USART_RX_vect) #if defined(USART_RX_vect)
SIGNAL(USART_RX_vect) SIGNAL(USART_RX_vect)
{ #elif defined(SIG_USART0_RECV)
#if defined(UDR0)
unsigned char c = UDR0;
#elif defined(UDR)
unsigned char c = UDR; // atmega8535
#else
#error UDR not defined
#endif
store_char(c, &rx_buffer);
}
#elif defined(SIG_USART0_RECV) && defined(UDR0)
SIGNAL(SIG_USART0_RECV) SIGNAL(SIG_USART0_RECV)
{ #elif defined(SIG_UART0_RECV)
unsigned char c = UDR0;
store_char(c, &rx_buffer);
}
#elif defined(SIG_UART0_RECV) && defined(UDR0)
SIGNAL(SIG_UART0_RECV) SIGNAL(SIG_UART0_RECV)
{
unsigned char c = UDR0;
store_char(c, &rx_buffer);
}
//#elif defined(SIG_USART_RECV)
#elif defined(USART0_RX_vect) #elif defined(USART0_RX_vect)
// fixed by Mark Sproul this is on the 644/644p
//SIGNAL(SIG_USART_RECV)
SIGNAL(USART0_RX_vect) SIGNAL(USART0_RX_vect)
#elif defined(SIG_UART_RECV)
SIGNAL(SIG_UART_RECV)
#endif
{ {
#if defined(UDR0) #if defined(UDR0)
unsigned char c = UDR0; unsigned char c = UDR0;
#elif defined(UDR) #elif defined(UDR)
unsigned char c = UDR; // atmega8, atmega32 unsigned char c = UDR;
#else #else
#error UDR not defined #error UDR not defined
#endif #endif
store_char(c, &rx_buffer); store_char(c, &rx_buffer);
serialEvent();
} }
#elif defined(SIG_UART_RECV)
// this is for atmega8
SIGNAL(SIG_UART_RECV)
{
#if defined(UDR0)
unsigned char c = UDR0; // atmega645
#elif defined(UDR)
unsigned char c = UDR; // atmega8
#endif
store_char(c, &rx_buffer);
}
#elif defined(USBCON)
#warning No interrupt handler for usart 0
#warning Serial(0) is on USB interface
#else
#error No interrupt handler for usart 0
#endif #endif
//#if defined(SIG_USART1_RECV)
#if defined(USART1_RX_vect) #if defined(USART1_RX_vect)
//SIGNAL(SIG_USART1_RECV) void serialEvent1() __attribute__((weak));
void serialEvent1() {}
SIGNAL(USART1_RX_vect) SIGNAL(USART1_RX_vect)
{ {
unsigned char c = UDR1; unsigned char c = UDR1;
store_char(c, &rx_buffer1); store_char(c, &rx_buffer1);
serialEvent1();
} }
#elif defined(SIG_USART1_RECV) #elif defined(SIG_USART1_RECV)
#error SIG_USART1_RECV #error SIG_USART1_RECV
#endif #endif
#if defined(USART2_RX_vect) && defined(UDR2) #if defined(USART2_RX_vect) && defined(UDR2)
void serialEvent2() __attribute__((weak));
void serialEvent2() {}
SIGNAL(USART2_RX_vect) SIGNAL(USART2_RX_vect)
{ {
unsigned char c = UDR2; unsigned char c = UDR2;
store_char(c, &rx_buffer2); store_char(c, &rx_buffer2);
serialEvent2();
} }
#elif defined(SIG_USART2_RECV) #elif defined(SIG_USART2_RECV)
#error SIG_USART2_RECV #error SIG_USART2_RECV
#endif #endif
#if defined(USART3_RX_vect) && defined(UDR3) #if defined(USART3_RX_vect) && defined(UDR3)
void serialEvent3() __attribute__((weak));
void serialEvent3() {}
SIGNAL(USART3_RX_vect) SIGNAL(USART3_RX_vect)
{ {
unsigned char c = UDR3; unsigned char c = UDR3;
store_char(c, &rx_buffer3); store_char(c, &rx_buffer3);
serialEvent3();
} }
#elif defined(SIG_USART3_RECV) #elif defined(SIG_USART3_RECV)
#error SIG_USART3_RECV #error SIG_USART3_RECV
#endif #endif
#if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect)
#error Don't know what the Data Register Empty vector is called for the first UART
#else
#if defined(UART0_UDRE_vect)
ISR(UART0_UDRE_vect)
#elif defined(UART_UDRE_vect)
ISR(UART_UDRE_vect)
#elif defined(USART0_UDRE_vect)
ISR(USART0_UDRE_vect)
#elif defined(USART_UDRE_vect)
ISR(USART_UDRE_vect)
#endif
{
if (tx_buffer.head == tx_buffer.tail) {
// Buffer empty, so disable interrupts
#if defined(UCSR0B)
cbi(UCSR0B, UDRIE0);
#else
cbi(UCSRB, UDRIE);
#endif
}
else {
// There is more data in the output buffer. Send the next byte
unsigned char c = tx_buffer.buffer[tx_buffer.tail];
tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
#if defined(UDR0)
UDR0 = c;
#elif defined(UDR)
UDR = c;
#else
#error UDR not defined
#endif
}
}
#endif
#ifdef USART1_UDRE_vect
ISR(USART1_UDRE_vect)
{
if (tx_buffer1.head == tx_buffer1.tail) {
// Buffer empty, so disable interrupts
cbi(UCSR1B, UDRIE1);
}
else {
// There is more data in the output buffer. Send the next byte
unsigned char c = tx_buffer1.buffer[tx_buffer1.tail];
tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;
UDR1 = c;
}
}
#endif
#ifdef USART2_UDRE_vect
ISR(USART2_UDRE_vect)
{
if (tx_buffer2.head == tx_buffer2.tail) {
// Buffer empty, so disable interrupts
cbi(UCSR2B, UDRIE2);
}
else {
// There is more data in the output buffer. Send the next byte
unsigned char c = tx_buffer2.buffer[tx_buffer2.tail];
tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;
UDR2 = c;
}
}
#endif
#ifdef USART3_UDRE_vect
ISR(USART3_UDRE_vect)
{
if (tx_buffer3.head == tx_buffer3.tail) {
// Buffer empty, so disable interrupts
cbi(UCSR3B, UDRIE3);
}
else {
// There is more data in the output buffer. Send the next byte
unsigned char c = tx_buffer3.buffer[tx_buffer3.tail];
tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;
UDR3 = c;
}
}
#endif
// Constructors //////////////////////////////////////////////////////////////// // Constructors ////////////////////////////////////////////////////////////////
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr, volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre, uint8_t u2x) uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
{ {
_rx_buffer = rx_buffer; _rx_buffer = rx_buffer;
_tx_buffer = tx_buffer;
_ubrrh = ubrrh; _ubrrh = ubrrh;
_ubrrl = ubrrl; _ubrrl = ubrrl;
_ucsra = ucsra; _ucsra = ucsra;
@ -185,13 +259,13 @@ HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
_rxen = rxen; _rxen = rxen;
_txen = txen; _txen = txen;
_rxcie = rxcie; _rxcie = rxcie;
_udre = udre; _udrie = udrie;
_u2x = u2x; _u2x = u2x;
} }
// Public Methods ////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////
void HardwareSerial::begin(long baud) void HardwareSerial::begin(unsigned long baud)
{ {
uint16_t baud_setting; uint16_t baud_setting;
bool use_u2x = true; bool use_u2x = true;
@ -204,6 +278,8 @@ void HardwareSerial::begin(long baud)
use_u2x = false; use_u2x = false;
} }
#endif #endif
try_again:
if (use_u2x) { if (use_u2x) {
*_ucsra = 1 << _u2x; *_ucsra = 1 << _u2x;
@ -212,6 +288,12 @@ void HardwareSerial::begin(long baud)
*_ucsra = 0; *_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2; baud_setting = (F_CPU / 8 / baud - 1) / 2;
} }
if ((baud_setting > 4095) && use_u2x)
{
use_u2x = false;
goto try_again;
}
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8; *_ubrrh = baud_setting >> 8;
@ -220,18 +302,27 @@ void HardwareSerial::begin(long baud)
sbi(*_ucsrb, _rxen); sbi(*_ucsrb, _rxen);
sbi(*_ucsrb, _txen); sbi(*_ucsrb, _txen);
sbi(*_ucsrb, _rxcie); sbi(*_ucsrb, _rxcie);
cbi(*_ucsrb, _udrie);
} }
void HardwareSerial::end() void HardwareSerial::end()
{ {
// wait for transmission of outgoing data
while (_tx_buffer->head != _tx_buffer->tail)
;
cbi(*_ucsrb, _rxen); cbi(*_ucsrb, _rxen);
cbi(*_ucsrb, _txen); cbi(*_ucsrb, _txen);
cbi(*_ucsrb, _rxcie); cbi(*_ucsrb, _rxcie);
cbi(*_ucsrb, _udrie);
// clear any received data
_rx_buffer->head = _rx_buffer->tail;
} }
int HardwareSerial::available(void) int HardwareSerial::available(void)
{ {
return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE; return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
} }
int HardwareSerial::peek(void) int HardwareSerial::peek(void)
@ -250,39 +341,41 @@ int HardwareSerial::read(void)
return -1; return -1;
} else { } else {
unsigned char c = _rx_buffer->buffer[_rx_buffer->tail]; unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
_rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE; _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
return c; return c;
} }
} }
void HardwareSerial::flush() void HardwareSerial::flush()
{ {
// don't reverse this or there may be problems if the RX interrupt while (_tx_buffer->head != _tx_buffer->tail)
// occurs after reading the value of rx_buffer_head but before writing ;
// the value to rx_buffer_tail; the previous value of rx_buffer_head
// may be written to rx_buffer_tail, making it appear as if the buffer
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of rx_buffer_head but before writing
// the value to rx_buffer_tail; the previous value of rx_buffer_head
// may be written to rx_buffer_tail, making it appear as if the buffer
// were full, not empty.
_rx_buffer->head = _rx_buffer->tail;
} }
void HardwareSerial::write(uint8_t c) size_t HardwareSerial::write(uint8_t c)
{ {
while (!((*_ucsra) & (1 << _udre))) int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
// ???: return 0 here instead?
while (i == _tx_buffer->tail)
; ;
*_udr = c; _tx_buffer->buffer[_tx_buffer->head] = c;
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
return 1;
} }
// Preinstantiate Objects ////////////////////////////////////////////////////// // Preinstantiate Objects //////////////////////////////////////////////////////
#if defined(UBRRH) && defined(UBRRL) #if defined(UBRRH) && defined(UBRRL)
HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X); HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
#elif defined(UBRR0H) && defined(UBRR0L) #elif defined(UBRR0H) && defined(UBRR0L)
HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0); HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
#elif defined(USBCON) #elif defined(USBCON)
#warning no serial port defined (port 0) #warning no serial port defined (port 0)
#else #else
@ -290,13 +383,13 @@ void HardwareSerial::write(uint8_t c)
#endif #endif
#if defined(UBRR1H) #if defined(UBRR1H)
HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1); HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
#endif #endif
#if defined(UBRR2H) #if defined(UBRR2H)
HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2); HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
#endif #endif
#if defined(UBRR3H) #if defined(UBRR3H)
HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3); HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
#endif #endif
#endif // whole file #endif // whole file

View File

@ -32,6 +32,7 @@ class HardwareSerial : public Stream
{ {
private: private:
ring_buffer *_rx_buffer; ring_buffer *_rx_buffer;
ring_buffer *_tx_buffer;
volatile uint8_t *_ubrrh; volatile uint8_t *_ubrrh;
volatile uint8_t *_ubrrl; volatile uint8_t *_ubrrl;
volatile uint8_t *_ucsra; volatile uint8_t *_ucsra;
@ -40,21 +41,21 @@ class HardwareSerial : public Stream
uint8_t _rxen; uint8_t _rxen;
uint8_t _txen; uint8_t _txen;
uint8_t _rxcie; uint8_t _rxcie;
uint8_t _udre; uint8_t _udrie;
uint8_t _u2x; uint8_t _u2x;
public: public:
HardwareSerial(ring_buffer *rx_buffer, HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr, volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre, uint8_t u2x); uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
void begin(long); void begin(unsigned long);
void end(); void end();
virtual int available(void); virtual int available(void);
virtual int peek(void); virtual int peek(void);
virtual int read(void); virtual int read(void);
virtual void flush(void); virtual void flush(void);
virtual void write(uint8_t); virtual size_t write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print using Print::write; // pull in write(str) and write(buf, size) from Print
}; };

View File

@ -1,5 +1,5 @@
#include <WProgram.h> #include <Arduino.h>
#include <IPAddress.h> #include <IPAddress.h>
IPAddress::IPAddress() IPAddress::IPAddress()
@ -42,3 +42,15 @@ bool IPAddress::operator==(const uint8_t* addr)
return memcmp(addr, _address, sizeof(_address)) == 0; return memcmp(addr, _address, sizeof(_address)) == 0;
} }
size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address[i], DEC);
n += p.print('.');
}
n += p.print(_address[3], DEC);
return n;
}

View File

@ -26,9 +26,11 @@
#ifndef IPAddress_h #ifndef IPAddress_h
#define IPAddress_h #define IPAddress_h
#include <Printable.h>
// A class to make it easier to handle and pass around IP addresses // A class to make it easier to handle and pass around IP addresses
class IPAddress { class IPAddress : public Printable {
private: private:
uint8_t _address[4]; // IPv4 address uint8_t _address[4]; // IPv4 address
// Access the raw byte array containing the address. Because this returns a pointer // Access the raw byte array containing the address. Because this returns a pointer
@ -58,6 +60,8 @@ public:
IPAddress& operator=(const uint8_t *address); IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address); IPAddress& operator=(uint32_t address);
virtual size_t printTo(Print& p) const;
friend class EthernetClass; friend class EthernetClass;
friend class UDP; friend class UDP;
friend class Client; friend class Client;

View File

@ -23,173 +23,223 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "wiring.h" #include "Arduino.h"
#include "Print.h" #include "Print.h"
// Public Methods ////////////////////////////////////////////////////////////// // Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */ /* default implementation: may be overridden */
void Print::write(const char *str) size_t Print::write(const char *str)
{ {
while (*str) size_t n = 0;
write(*str++); while (*str) {
n += write(*str++);
}
return n;
} }
/* default implementation: may be overridden */ /* default implementation: may be overridden */
void Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
while (size--) size_t n = 0;
write(*buffer++); while (size--) {
} n += write(*buffer++);
void Print::print(const String &s)
{
for (int i = 0; i < s.length(); i++) {
write(s[i]);
} }
return n;
} }
void Print::print(const char str[]) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
write(str); const prog_char *p = (const prog_char *)ifsh;
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
n += write(c);
}
return n;
} }
void Print::print(char c, int base) size_t Print::print(const String &s)
{ {
print((long) c, base); size_t n = 0;
for (int i = 0; i < s.length(); i++) {
n += write(s[i]);
}
return n;
} }
void Print::print(unsigned char b, int base) size_t Print::print(const char str[])
{ {
print((unsigned long) b, base); return write(str);
} }
void Print::print(int n, int base) size_t Print::print(char c)
{ {
print((long) n, base); return write(c);
} }
void Print::print(unsigned int n, int base) size_t Print::print(unsigned char b, int base)
{ {
print((unsigned long) n, base); return print((unsigned long) b, base);
} }
void Print::print(long n, int base) size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0) {
write(n); return write(n);
} else if (base == 10) { } else if (base == 10) {
if (n < 0) { if (n < 0) {
print('-'); int t = print('-');
n = -n; n = -n;
return printNumber(n, 10) + t;
} }
printNumber(n, 10); return printNumber(n, 10);
} else { } else {
printNumber(n, base); return printNumber(n, base);
} }
} }
void Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) write(n); if (base == 0) return write(n);
else printNumber(n, base); else return printNumber(n, base);
} }
void Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
printFloat(n, digits); return printFloat(n, digits);
} }
void Print::println(void) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
print('\r'); size_t n = print(ifsh);
print('\n'); n += println();
return n;
} }
void Print::println(const String &s) size_t Print::print(const Printable& x)
{ {
print(s); return x.printTo(*this);
println();
} }
void Print::println(const char c[]) size_t Print::println(void)
{ {
print(c); size_t n = print('\r');
println(); n += print('\n');
return n;
} }
void Print::println(char c, int base) size_t Print::println(const String &s)
{ {
print(c, base); size_t n = print(s);
println(); n += println();
return n;
} }
void Print::println(unsigned char b, int base) size_t Print::println(const char c[])
{ {
print(b, base); size_t n = print(c);
println(); n += println();
return n;
} }
void Print::println(int n, int base) size_t Print::println(char c)
{ {
print(n, base); size_t n = print(c);
println(); n += println();
return n;
} }
void Print::println(unsigned int n, int base) size_t Print::println(unsigned char b, int base)
{ {
print(n, base); size_t n = print(b, base);
println(); n += println();
return n;
} }
void Print::println(long n, int base) size_t Print::println(int num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(unsigned long n, int base) size_t Print::println(unsigned int num, int base)
{ {
print(n, base); size_t n = print(num, base);
println(); n += println();
return n;
} }
void Print::println(double n, int digits) size_t Print::println(long num, int base)
{ {
print(n, digits); size_t n = print(num, base);
println(); n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
void Print::printNumber(unsigned long n, uint8_t base) size_t Print::printNumber(unsigned long n, uint8_t base) {
{ char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. char *str = &buf[sizeof(buf) - 1];
unsigned long i = 0;
if (n == 0) { *str = '\0';
print('0');
return;
}
while (n > 0) { // prevent crash if called with base == 1
buf[i++] = n % base; if (base < 2) base = 10;
do {
unsigned long m = n;
n /= base; n /= base;
} char c = m - base * n;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
for (; i > 0; i--) return write(str);
print((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
} }
void Print::printFloat(double number, uint8_t digits) size_t Print::printFloat(double number, uint8_t digits)
{ {
size_t n = 0;
// Handle negative numbers // Handle negative numbers
if (number < 0.0) if (number < 0.0)
{ {
print('-'); n += print('-');
number = -number; number = -number;
} }
@ -203,18 +253,21 @@ void Print::printFloat(double number, uint8_t digits)
// Extract the integer part of the number and print it // Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number; unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part; double remainder = number - (double)int_part;
print(int_part); n += print(int_part);
// Print the decimal point, but only if there are digits beyond // Print the decimal point, but only if there are digits beyond
if (digits > 0) if (digits > 0) {
print("."); n += print(".");
}
// Extract digits from the remainder one at a time // Extract digits from the remainder one at a time
while (digits-- > 0) while (digits-- > 0)
{ {
remainder *= 10.0; remainder *= 10.0;
int toPrint = int(remainder); int toPrint = int(remainder);
print(toPrint); n += print(toPrint);
remainder -= toPrint; remainder -= toPrint;
} }
return n;
} }

View File

@ -24,43 +24,55 @@
#include <stdio.h> // for size_t #include <stdio.h> // for size_t
#include "WString.h" #include "WString.h"
#include "Printable.h"
#define DEC 10 #define DEC 10
#define HEX 16 #define HEX 16
#define OCT 8 #define OCT 8
#define BIN 2 #define BIN 2
#define BYTE 0
class Print class Print
{ {
private: private:
void printNumber(unsigned long, uint8_t); int write_error;
void printFloat(double, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
public: public:
virtual void write(uint8_t) = 0; Print() : write_error(0) {}
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size); int writeError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
virtual size_t write(const char *str);
virtual size_t write(const uint8_t *buffer, size_t size);
void print(const String &); size_t print(const __FlashStringHelper *);
void print(const char[]); size_t print(const String &);
void print(char, int = BYTE); size_t print(const char[]);
void print(unsigned char, int = BYTE); size_t print(char);
void print(int, int = DEC); size_t print(unsigned char, int = DEC);
void print(unsigned int, int = DEC); size_t print(int, int = DEC);
void print(long, int = DEC); size_t print(unsigned int, int = DEC);
void print(unsigned long, int = DEC); size_t print(long, int = DEC);
void print(double, int = 2); size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
void println(const String &s); size_t println(const __FlashStringHelper *);
void println(const char[]); size_t println(const String &s);
void println(char, int = BYTE); size_t println(const char[]);
void println(unsigned char, int = BYTE); size_t println(char);
void println(int, int = DEC); size_t println(unsigned char, int = DEC);
void println(unsigned int, int = DEC); size_t println(int, int = DEC);
void println(long, int = DEC); size_t println(unsigned int, int = DEC);
void println(unsigned long, int = DEC); size_t println(long, int = DEC);
void println(double, int = 2); size_t println(unsigned long, int = DEC);
void println(void); size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
}; };
#endif #endif

40
cores/arduino/Printable.h Normal file
View File

@ -0,0 +1,40 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include <new.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif

233
cores/arduino/Stream.cpp Normal file
View File

@ -0,0 +1,233 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
*/
#include "Arduino.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
// private method to read stream with timeout
int Stream::timedRead()
{
//Serial.println(_timeout);
this->_startMillis = millis();
while(millis() - this->_startMillis < this->_timeout)
{
if (this->available() > 0) {
return this->read();
}
}
return -1; // -1 indicates timeout
}
// returns the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::getNextDigit()
{
int c;
do{
c = timedRead();
if( c < 0)
return c; // timeout
}
while( c != '-' && (c < '0' || c > '9') ) ;
return c;
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout( long timeout) // sets the maximum number of milliseconds to wait
{
this->_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, NULL);
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;
if( *target == 0)
return true; // return true if target is a null string
while( (c = timedRead()) > 0){
if( c == target[index]){
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen){ // return true if all chars in the target match
return true;
}
}
else{
index = 0; // reset index if any char does not match
}
if(termLen > 0 && c == terminator[termIndex]){
if(++termIndex >= termLen)
return false; // return false if terminate string found before target string
}
else
termIndex = 0;
}
return false;
}
// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}
// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;
c = getNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
c = timedRead();
}
while( (c >= '0' && c <= '9') || c == skipChar );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat()
{
parseFloat(NO_SKIP_CHAR);
}
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar){
boolean isNegative = false;
boolean isFraction = false;
long value = 0;
float fValue;
char c;
float fraction = 1.0;
c = getNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == skipChar)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1;
}
c = timedRead();
}
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, null is detected or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
int Stream::readBytes( char *buffer, size_t length)
{
return readBytesUntil( 0, buffer, length);
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
int Stream::readBytesUntil( char terminator, char *buffer, size_t length)
{
int index = 0;
*buffer = 0;
while(index < length-1 ){
int c = timedRead();
if( c <= 0 ){
return 0; // timeout returns 0 !
}
else if( c == terminator){
buffer[index] = 0; // terminate the string
return index; // data got successfully
}
else{
buffer[index++] = (char)c;
}
}
buffer[index] = 0;
return index; // here if buffer is full before detecting the terminator
}

View File

@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/ */
#ifndef Stream_h #ifndef Stream_h
@ -23,13 +25,69 @@
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #include "Print.h"
// compatability macros for testing
/*
#define getInt() parseInt()
#define getInt(skipChar) parseInt(skipchar)
#define getFloat() parseFloat()
#define getFloat(skipChar) parseFloat(skipChar)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
class Stream : public Print class Stream : public Print
{ {
private:
long _timeout; // number of milliseconds to wait for the next char before aborting timed read
long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout
int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
public: public:
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
virtual void flush() = 0; virtual void flush() = 0;
Stream() {_timeout=1000;}
// parsing methods
void setTimeout(long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
bool find(char *target); // reads data from the stream until the target string is found
// returns true if target string is found, false if timed out (see setTimeout)
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
long parseInt(); // returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// integer is terminated by the first character that is not a digit.
long parseInt(char skipChar); // as above but the given skipChar is ignored
// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float parseFloat(); // float version of parseInt
float parseFloat(char skipChar); // as above but the given skipChar is ignored
int readBytes( char *buffer, size_t length); // read chars from stream into buffer
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
int readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
}; };
#endif #endif

View File

@ -33,7 +33,7 @@ Version Modified By Date Comments
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "wiring.h" #include "Arduino.h"
#include "pins_arduino.h" #include "pins_arduino.h"
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__) #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)

View File

@ -1 +0,0 @@
#include "wiring.h"

View File

@ -30,7 +30,6 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <stdio.h> #include <stdio.h>
#include "WConstants.h"
#include "wiring_private.h" #include "wiring_private.h"
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];

View File

@ -1,63 +0,0 @@
#ifndef WProgram_h
#define WProgram_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/interrupt.h>
#include "wiring.h"
#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
const static uint8_t A0 = 54;
const static uint8_t A1 = 55;
const static uint8_t A2 = 56;
const static uint8_t A3 = 57;
const static uint8_t A4 = 58;
const static uint8_t A5 = 59;
const static uint8_t A6 = 60;
const static uint8_t A7 = 61;
const static uint8_t A8 = 62;
const static uint8_t A9 = 63;
const static uint8_t A10 = 64;
const static uint8_t A11 = 65;
const static uint8_t A12 = 66;
const static uint8_t A13 = 67;
const static uint8_t A14 = 68;
const static uint8_t A15 = 69;
#else
const static uint8_t A0 = 14;
const static uint8_t A1 = 15;
const static uint8_t A2 = 16;
const static uint8_t A3 = 17;
const static uint8_t A4 = 18;
const static uint8_t A5 = 19;
const static uint8_t A6 = 20;
const static uint8_t A7 = 21;
#endif
#endif
#endif

View File

@ -1,6 +1,8 @@
/* /*
WString.cpp - String library for Wiring & Arduino WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved. Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -17,427 +19,627 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <stdlib.h>
#include "WProgram.h"
#include "WString.h" #include "WString.h"
String::String( const char *value ) /*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{ {
if ( value == NULL ) init();
value = ""; if (cstr) copy(cstr, strlen(cstr));
getBuffer( _length = strlen( value ) );
if ( _buffer != NULL )
strcpy( _buffer, value );
} }
String::String( const String &value ) String::String(const String &value)
{ {
getBuffer( _length = value._length ); init();
if ( _buffer != NULL ) *this = value;
strcpy( _buffer, value._buffer );
} }
String::String( const char value ) #ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{ {
_length = 1; init();
getBuffer(1); move(rval);
if ( _buffer != NULL ) { }
_buffer[0] = value; String::String(StringSumHelper &&rval)
_buffer[1] = 0; {
} init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
} }
String::String( const unsigned char value ) String::String(unsigned char value, unsigned char base)
{ {
_length = 1; init();
getBuffer(1); char buf[9];
if ( _buffer != NULL) { utoa(value, buf, base);
_buffer[0] = value; *this = buf;
_buffer[1] = 0;
}
} }
String::String( const int value, const int base ) String::String(int value, unsigned char base)
{ {
char buf[33]; init();
itoa((signed long)value, buf, base); char buf[18];
getBuffer( _length = strlen(buf) ); itoa(value, buf, base);
if ( _buffer != NULL ) *this = buf;
strcpy( _buffer, buf );
} }
String::String( const unsigned int value, const int base ) String::String(unsigned int value, unsigned char base)
{ {
char buf[33]; init();
ultoa((unsigned long)value, buf, base); char buf[17];
getBuffer( _length = strlen(buf) ); utoa(value, buf, base);
if ( _buffer != NULL ) *this = buf;
strcpy( _buffer, buf );
} }
String::String( const long value, const int base ) String::String(long value, unsigned char base)
{ {
char buf[33]; init();
ltoa(value, buf, base); char buf[34];
getBuffer( _length = strlen(buf) ); ltoa(value, buf, base);
if ( _buffer != NULL ) *this = buf;
strcpy( _buffer, buf );
} }
String::String( const unsigned long value, const int base ) String::String(unsigned long value, unsigned char base)
{ {
char buf[33]; init();
ultoa(value, buf, 10); char buf[33];
getBuffer( _length = strlen(buf) ); ultoa(value, buf, base);
if ( _buffer != NULL ) *this = buf;
strcpy( _buffer, buf );
} }
char String::charAt( unsigned int loc ) const String::~String()
{ {
return operator[]( loc ); free(buffer);
} }
void String::setCharAt( unsigned int loc, const char aChar ) /*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{ {
if(_buffer == NULL) return; buffer = NULL;
if(_length > loc) { capacity = 0;
_buffer[loc] = aChar; len = 0;
} flags = 0;
} }
int String::compareTo( const String &s2 ) const void String::invalidate(void)
{ {
return strcmp( _buffer, s2._buffer ); if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
} }
const String & String::concat( const String &s2 ) unsigned char String::reserve(unsigned int size)
{ {
return (*this) += s2; if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
} }
const String & String::operator=( const String &rhs ) unsigned char String::changeBuffer(unsigned int maxStrLen)
{ {
if ( this == &rhs ) char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
return *this; if (newbuffer) {
buffer = newbuffer;
if ( rhs._length > _length ) capacity = maxStrLen;
{ return 1;
free(_buffer); }
getBuffer( rhs._length ); return 0;
}
if ( _buffer != NULL ) {
_length = rhs._length;
strcpy( _buffer, rhs._buffer );
}
return *this;
} }
//const String & String::operator+=( const char aChar ) /*********************************************/
//{ /* Copy and Move */
// if ( _length == _capacity ) /*********************************************/
// doubleBuffer();
//
// _buffer[ _length++ ] = aChar;
// _buffer[ _length ] = '\0';
// return *this;
//}
const String & String::operator+=( const String &other ) String & String::copy(const char *cstr, unsigned int length)
{ {
_length += other._length; if (!reserve(length)) {
if ( _length > _capacity ) invalidate();
{ return *this;
char *temp = (char *)realloc(_buffer, _length + 1); }
if ( temp != NULL ) { len = length;
_buffer = temp; strcpy(buffer, cstr);
_capacity = _length; return *this;
} else {
_length -= other._length;
return *this;
}
}
strcat( _buffer, other._buffer );
return *this;
} }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
int String::operator==( const String &rhs ) const void String::move(String &rhs)
{ {
return ( _length == rhs._length && strcmp( _buffer, rhs._buffer ) == 0 ); if (buffer) {
if (capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
} }
int String::operator!=( const String &rhs ) const #ifdef __GXX_EXPERIMENTAL_CXX0X__
String & String::operator = (String &&rval)
{ {
return ( _length != rhs.length() || strcmp( _buffer, rhs._buffer ) != 0 ); if (this != &rval) move(rval);
return *this;
} }
int String::operator<( const String &rhs ) const String & String::operator = (StringSumHelper &&rval)
{ {
return strcmp( _buffer, rhs._buffer ) < 0; if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
} }
int String::operator>( const String &rhs ) const /*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{ {
return strcmp( _buffer, rhs._buffer ) > 0; return concat(s.buffer, s.len);
} }
int String::operator<=( const String &rhs ) const unsigned char String::concat(const char *cstr, unsigned int length)
{ {
return strcmp( _buffer, rhs._buffer ) <= 0; unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, cstr);
len = newlen;
return 1;
} }
int String::operator>=( const String & rhs ) const unsigned char String::concat(const char *cstr)
{ {
return strcmp( _buffer, rhs._buffer ) >= 0; if (!cstr) return 0;
return concat(cstr, strlen(cstr));
} }
char & String::operator[]( unsigned int index ) unsigned char String::concat(char c)
{ {
static char dummy_writable_char; char buf[2];
if (index >= _length || !_buffer) { buf[0] = c;
dummy_writable_char = 0; buf[1] = 0;
return dummy_writable_char; return concat(buf, 1);
} }
return _buffer[ index ];
unsigned char String::concat(unsigned char num)
{
char buf[4];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
char buf[7];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
char buf[6];
utoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
char buf[12];
ltoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
char buf[11];
ultoa(num, buf, 10);
return concat(buf, strlen(buf));
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
} }
char String::operator[]( unsigned int index ) const char String::operator[]( unsigned int index ) const
{ {
// need to check for valid index, to do later if (index >= len || !buffer) return 0;
return _buffer[ index ]; return buffer[index];
} }
boolean String::endsWith( const String &s2 ) const void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{ {
if ( _length < s2._length ) if (!bufsize || !buf) return;
return 0; if (index >= len) {
buf[0] = 0;
return strcmp( &_buffer[ _length - s2._length], s2._buffer ) == 0; return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
} }
boolean String::equals( const String &s2 ) const /*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{ {
return ( _length == s2._length && strcmp( _buffer,s2._buffer ) == 0 ); return indexOf(c, 0);
}
boolean String::equalsIgnoreCase( const String &s2 ) const
{
if ( this == &s2 )
return true; //1;
else if ( _length != s2._length )
return false; //0;
return strcmp(toLowerCase()._buffer, s2.toLowerCase()._buffer) == 0;
}
String String::replace( char findChar, char replaceChar )
{
if ( _buffer == NULL ) return *this;
String theReturn = _buffer;
char* temp = theReturn._buffer;
while( (temp = strchr( temp, findChar )) != 0 )
*temp = replaceChar;
return theReturn;
}
String String::replace( const String& match, const String& replace )
{
if ( _buffer == NULL ) return *this;
String temp = _buffer, newString;
int loc;
while ( (loc = temp.indexOf( match )) != -1 )
{
newString += temp.substring( 0, loc );
newString += replace;
temp = temp.substring( loc + match._length );
}
newString += temp;
return newString;
}
int String::indexOf( char temp ) const
{
return indexOf( temp, 0 );
} }
int String::indexOf( char ch, unsigned int fromIndex ) const int String::indexOf( char ch, unsigned int fromIndex ) const
{ {
if ( fromIndex >= _length ) if (fromIndex >= len) return -1;
return -1; const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
const char* temp = strchr( &_buffer[fromIndex], ch ); return temp - buffer;
if ( temp == NULL )
return -1;
return temp - _buffer;
} }
int String::indexOf( const String &s2 ) const int String::indexOf(const String &s2) const
{ {
return indexOf( s2, 0 ); return indexOf(s2, 0);
} }
int String::indexOf( const String &s2, unsigned int fromIndex ) const int String::indexOf(const String &s2, unsigned int fromIndex) const
{ {
if ( fromIndex >= _length ) if (fromIndex >= len) return -1;
return -1; const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
const char *theFind = strstr( &_buffer[ fromIndex ], s2._buffer ); return found - buffer;
if ( theFind == NULL )
return -1;
return theFind - _buffer; // pointer subtraction
} }
int String::lastIndexOf( char theChar ) const int String::lastIndexOf( char theChar ) const
{ {
return lastIndexOf( theChar, _length - 1 ); return lastIndexOf(theChar, len - 1);
} }
int String::lastIndexOf( char ch, unsigned int fromIndex ) const int String::lastIndexOf(char ch, int fromIndex) const
{ {
if ( fromIndex >= _length ) if (fromIndex >= len || fromIndex < 0) return -1;
return -1; char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char tempchar = _buffer[fromIndex + 1]; char* temp = strrchr( buffer, ch );
_buffer[fromIndex + 1] = '\0'; buffer[fromIndex + 1] = tempchar;
char* temp = strrchr( _buffer, ch ); if (temp == NULL) return -1;
_buffer[fromIndex + 1] = tempchar; return temp - buffer;
if ( temp == NULL )
return -1;
return temp - _buffer;
} }
int String::lastIndexOf( const String &s2 ) const int String::lastIndexOf(const String &s2) const
{ {
return lastIndexOf( s2, _length - s2._length ); return lastIndexOf(s2, len - s2.len);
} }
int String::lastIndexOf( const String &s2, unsigned int fromIndex ) const int String::lastIndexOf(const String &s2, int fromIndex) const
{ {
// check for empty strings if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
if ( s2._length == 0 || s2._length - 1 > fromIndex || fromIndex >= _length ) if (fromIndex >= len) fromIndex = len - 1;
return -1; int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
// matching first character p = strstr(p, s2.buffer);
char temp = s2[ 0 ]; if (!p) break;
if (p - buffer <= fromIndex) found = p - buffer;
for ( int i = fromIndex; i >= 0; i-- ) }
{ return found;
if ( _buffer[ i ] == temp && (*this).substring( i, i + s2._length ).equals( s2 ) )
return i;
}
return -1;
}
boolean String::startsWith( const String &s2 ) const
{
if ( _length < s2._length )
return 0;
return startsWith( s2, 0 );
}
boolean String::startsWith( const String &s2, unsigned int offset ) const
{
if ( offset > _length - s2._length )
return 0;
return strncmp( &_buffer[offset], s2._buffer, s2._length ) == 0;
} }
String String::substring( unsigned int left ) const String String::substring( unsigned int left ) const
{ {
return substring( left, _length ); return substring(left, len);
} }
String String::substring( unsigned int left, unsigned int right ) const String String::substring(unsigned int left, unsigned int right) const
{ {
if ( left > right ) if (left > right) {
{ unsigned int temp = right;
int temp = right; right = left;
right = left; left = temp;
left = temp; }
} String out;
if (left > len) return out;
if ( right > _length ) if (right > len) right = len;
{ char temp = buffer[right]; // save the replaced character
right = _length; buffer[right] = '\0';
} out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
char temp = _buffer[ right ]; // save the replaced character return out;
_buffer[ right ] = '\0';
String outPut = ( _buffer + left ); // pointer arithmetic
_buffer[ right ] = temp; //restore character
return outPut;
} }
String String::toLowerCase() const /*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{ {
String temp = _buffer; if (!buffer) return;
for (char *p = buffer; *p; p++) {
for ( unsigned int i = 0; i < _length; i++ ) if (*p == find) *p = replace;
temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] ); }
return temp;
} }
String String::toUpperCase() const void String::replace(const String& find, const String& replace)
{ {
String temp = _buffer; if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
for ( unsigned int i = 0; i < _length; i++ ) char *readFrom = buffer;
temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] ); char *foundAt;
return temp; if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while ((index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
} }
String String::trim() const void String::toLowerCase(void)
{ {
if ( _buffer == NULL ) return *this; if (!buffer) return;
String temp = _buffer; for (char *p = buffer; *p; p++) {
unsigned int i,j; *p = tolower(*p);
}
for ( i = 0; i < _length; i++ )
{
if ( !isspace(_buffer[i]) )
break;
}
for ( j = temp._length - 1; j > i; j-- )
{
if ( !isspace(_buffer[j]) )
break;
}
return temp.substring( i, j + 1);
} }
void String::getBytes(unsigned char *buf, unsigned int bufsize) void String::toUpperCase(void)
{ {
if (!bufsize || !buf) return; if (!buffer) return;
unsigned int len = bufsize - 1; for (char *p = buffer; *p; p++) {
if (len > _length) len = _length; *p = toupper(*p);
strncpy((char *)buf, _buffer, len); }
buf[len] = 0;
} }
void String::toCharArray(char *buf, unsigned int bufsize) void String::trim(void)
{ {
if (!bufsize || !buf) return; if (!buffer || len == 0) return;
unsigned int len = bufsize - 1; char *begin = buffer;
if (len > _length) len = _length; while (isspace(*begin)) begin++;
strncpy(buf, _buffer, len); char *end = buffer + len - 1;
buf[len] = 0; while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
} }
long String::toInt() {
return atol(_buffer);
}

View File

@ -1,6 +1,8 @@
/* /*
WString.h - String library for Wiring & Arduino WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved. Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -17,96 +19,187 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef String_h #ifndef String_class_h
#define String_h #define String_class_h
#ifdef __cplusplus
//#include "WProgram.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<__FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String class String
{ {
public: // use a function pointer to allow for "if (s)" without the
// constructors // complications of an operator bool(). for more information, see:
String( const char *value = "" ); // http://www.artima.com/cppsource/safebool.html
String( const String &value ); typedef void (String::*StringIfHelperType)() const;
String( const char ); void StringIfHelper() const {}
String( const unsigned char );
String( const int, const int base=10);
String( const unsigned int, const int base=10 );
String( const long, const int base=10 );
String( const unsigned long, const int base=10 );
~String() { free(_buffer); _length = _capacity = 0;} //added _length = _capacity = 0;
// operators public:
const String & operator = ( const String &rhs ); // constructors
const String & operator +=( const String &rhs ); // creates a copy of the initial value.
//const String & operator +=( const char ); // if the initial value is null or invalid, or if memory allocation
int operator ==( const String &rhs ) const; // fails, the string will be marked as invalid (i.e. "if (s)" will
int operator !=( const String &rhs ) const; // be false).
int operator < ( const String &rhs ) const; String(const char *cstr = "");
int operator > ( const String &rhs ) const; String(const String &str);
int operator <=( const String &rhs ) const; #ifdef __GXX_EXPERIMENTAL_CXX0X__
int operator >=( const String &rhs ) const; String(String &&rval);
char operator []( unsigned int index ) const; String(StringSumHelper &&rval);
char& operator []( unsigned int index ); #endif
//operator const char *() const { return _buffer; } explicit String(char c);
explicit String(unsigned char, unsigned char base=10);
// general methods explicit String(int, unsigned char base=10);
char charAt( unsigned int index ) const; explicit String(unsigned int, unsigned char base=10);
int compareTo( const String &anotherString ) const; explicit String(long, unsigned char base=10);
unsigned char endsWith( const String &suffix ) const; explicit String(unsigned long, unsigned char base=10);
unsigned char equals( const String &anObject ) const; ~String(void);
unsigned char equalsIgnoreCase( const String &anotherString ) const;
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
const unsigned int length( ) const { return _length; }
void setCharAt(unsigned int index, const char ch);
unsigned char startsWith( const String &prefix ) const;
unsigned char startsWith( const String &prefix, unsigned int toffset ) const;
String substring( unsigned int beginIndex ) const;
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
String toLowerCase( ) const;
String toUpperCase( ) const;
String trim( ) const;
void getBytes(unsigned char *buf, unsigned int bufsize);
void toCharArray(char *buf, unsigned int bufsize);
long toInt( );
const String& concat( const String &str );
String replace( char oldChar, char newChar );
String replace( const String& match, const String& replace );
friend String operator + ( String lhs, const String &rhs );
protected: // memory management
char *_buffer; // the actual char array // return true on success, false on failure (in which case, the string
unsigned int _capacity; // the array length minus one (for the '\0') // is left unchanged). reserve(0), if successful, will validate an
unsigned int _length; // the String length (not counting the '\0') // invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}
void getBuffer(unsigned int maxStrLen); // creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
private: // concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
String & operator += (const char *cstr) {concat(cstr); return (*this);}
String & operator += (char c) {concat(c); return (*this);}
String & operator += (unsigned char num) {concat(num); return (*this);}
String & operator += (int num) {concat(num); return (*this);}
String & operator += (unsigned int num) {concat(num); return (*this);}
String & operator += (long num) {concat(num); return (*this);}
String & operator += (unsigned long num) {concat(num); return (*this);}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, int fromIndex ) const;
String substring( unsigned int beginIndex ) const;
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
unsigned char flags; // unused, for future features
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs);
#endif
}; };
// allocate buffer space class StringSumHelper : public String
inline void String::getBuffer(unsigned int maxStrLen)
{ {
_capacity = maxStrLen; public:
_buffer = (char *) malloc(_capacity + 1); StringSumHelper(const String &s) : String(s) {}
if (_buffer == NULL) _length = _capacity = 0; StringSumHelper(const char *p) : String(p) {}
} StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
};
inline String operator+( String lhs, const String &rhs ) #endif // __cplusplus
{ #endif // String_class_h
return lhs += rhs;
}
#endif

View File

@ -1,4 +1,5 @@
#include <WProgram.h> #define ARDUINO_MAIN
#include <Arduino.h>
int main(void) int main(void)
{ {

18
cores/arduino/new.cpp Normal file
View File

@ -0,0 +1,18 @@
#include <new.h>
void * operator new(size_t size)
{
return malloc(size);
}
void operator delete(void * ptr)
{
free(ptr);
}
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};
void __cxa_pure_virtual(void) {};

22
cores/arduino/new.h Normal file
View File

@ -0,0 +1,22 @@
/* Header to define new/delete operators as they aren't provided by avr-gcc by default
Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
*/
#ifndef NEW_H
#define NEW_H
#include <stdlib.h>
void * operator new(size_t size);
void operator delete(void * ptr);
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
extern "C" void __cxa_pure_virtual(void);
#endif

View File

@ -1,88 +0,0 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <avr/pgmspace.h>
#define NOT_A_PIN 0
#define NOT_A_PORT 0
#define NOT_ON_TIMER 0
#define TIMER0A 1
#define TIMER0B 2
#define TIMER1A 3
#define TIMER1B 4
#define TIMER2 5
#define TIMER2A 6
#define TIMER2B 7
#define TIMER3A 8
#define TIMER3B 9
#define TIMER3C 10
#define TIMER4A 11
#define TIMER4B 12
#define TIMER4C 13
#define TIMER5A 14
#define TIMER5B 15
#define TIMER5C 16
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
const static uint8_t SS = 53;
const static uint8_t MOSI = 51;
const static uint8_t MISO = 50;
const static uint8_t SCK = 52;
#else
const static uint8_t SS = 10;
const static uint8_t MOSI = 11;
const static uint8_t MISO = 12;
const static uint8_t SCK = 13;
#endif
// On the ATmega1280, the addresses of some of the port registers are
// greater than 255, so we can't store them in uint8_t's.
extern const uint16_t PROGMEM port_to_mode_PGM[];
extern const uint16_t PROGMEM port_to_input_PGM[];
extern const uint16_t PROGMEM port_to_output_PGM[];
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
#endif

View File

@ -212,10 +212,10 @@ void init()
// note, however, that fast pwm mode can achieve a frequency of up // note, however, that fast pwm mode can achieve a frequency of up
// 8 MHz (with a 16 MHz clock) at 50% duty cycle // 8 MHz (with a 16 MHz clock) at 50% duty cycle
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
TCCR1B = 0; TCCR1B = 0;
// set timer 1 prescale factor to 64 // set timer 1 prescale factor to 64
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
sbi(TCCR1B, CS11); sbi(TCCR1B, CS11);
sbi(TCCR1B, CS10); sbi(TCCR1B, CS10);
#elif defined(TCCR1) && defined(CS11) && defined(CS10) #elif defined(TCCR1) && defined(CS11) && defined(CS10)

View File

@ -1,135 +0,0 @@
/*
wiring.h - Partial implementation of the Wiring API for the ATmega8.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id$
*/
#ifndef Wiring_h
#define Wiring_h
#include <avr/io.h>
#include <stdlib.h>
#include "binary.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define true 0x1
#define false 0x0
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define interrupts() sei()
#define noInterrupts() cli()
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
typedef unsigned int word;
#define bit(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void init(void);
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -136,17 +136,16 @@ void digitalWrite(uint8_t pin, uint8_t val)
out = portOutputRegister(port); out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) { if (val == LOW) {
uint8_t oldSREG = SREG;
cli();
*out &= ~bit; *out &= ~bit;
SREG = oldSREG;
} else { } else {
uint8_t oldSREG = SREG;
cli();
*out |= bit; *out |= bit;
SREG = oldSREG;
} }
SREG = oldSREG;
} }
int digitalRead(uint8_t pin) int digitalRead(uint8_t pin)

View File

@ -31,7 +31,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include "wiring.h" #include "Arduino.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C"{

View File

@ -0,0 +1,27 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#include "../standard/pins_arduino.h"
#undef NUM_ANALOG_INPUTS
#define NUM_ANALOG_INPUTS 8

View File

@ -1,8 +1,8 @@
/* /*
pins_arduino.c - pin definitions for the Arduino board pins_arduino.h - Pin definition functions for Arduino
Part of Arduino / Wiring Lite Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005 David A. Mellis Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -19,112 +19,118 @@
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA Boston, MA 02111-1307 USA
$Id$ $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/ */
#include <avr/io.h> #ifndef Pins_Arduino_h
#include "wiring_private.h" #define Pins_Arduino_h
#include "pins_arduino.h"
// On the Arduino board, digital pins are also used #include <avr/pgmspace.h>
// for the analog output (software PWM). Analog input
// pins are a separate set.
// ATMEL ATMEGA8 & 168 / ARDUINO #define NUM_DIGITAL_PINS 70
// #define NUM_ANALOG_INPUTS 16
// +-\/-+ #define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1)
// PC6 1| |28 PC5 (AI 5) #define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46))
// (D 0) PD0 2| |27 PC4 (AI 4)
// (D 1) PD1 3| |26 PC3 (AI 3)
// (D 2) PD2 4| |25 PC2 (AI 2)
// PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
// (D 4) PD4 6| |23 PC0 (AI 0)
// VCC 7| |22 GND
// GND 8| |21 AREF
// PB6 9| |20 AVCC
// PB7 10| |19 PB5 (D 13)
// PWM+ (D 5) PD5 11| |18 PB4 (D 12)
// PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
// (D 7) PD7 13| |16 PB2 (D 10) PWM
// (D 8) PB0 14| |15 PB1 (D 9) PWM
// +----+
//
// (PWM+ indicates the additional PWM pins on the ATmega168.)
// ATMEL ATMEGA1280 / ARDUINO const static uint8_t SS = 53;
// const static uint8_t MOSI = 51;
// 0-7 PE0-PE7 works const static uint8_t MISO = 50;
// 8-13 PB0-PB5 works const static uint8_t SCK = 52;
// 14-21 PA0-PA7 works
// 22-29 PH0-PH7 works
// 30-35 PG5-PG0 works
// 36-43 PC7-PC0 works
// 44-51 PJ7-PJ0 works
// 52-59 PL7-PL0 works
// 60-67 PD7-PD0 works
// A0-A7 PF0-PF7
// A8-A15 PK0-PK7
#define PA 1 const static uint8_t SDA = 20;
#define PB 2 const static uint8_t SCL = 21;
#define PC 3 const static uint8_t LED = 13;
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 10
#define PK 11
#define PL 12
const static uint8_t A0 = 54;
const static uint8_t A1 = 55;
const static uint8_t A2 = 56;
const static uint8_t A3 = 57;
const static uint8_t A4 = 58;
const static uint8_t A5 = 59;
const static uint8_t A6 = 60;
const static uint8_t A7 = 61;
const static uint8_t A8 = 62;
const static uint8_t A9 = 63;
const static uint8_t A10 = 64;
const static uint8_t A11 = 65;
const static uint8_t A12 = 66;
const static uint8_t A13 = 67;
const static uint8_t A14 = 68;
const static uint8_t A15 = 69;
// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
// Only pins available for RECEIVE (TRANSMIT can be on any pin):
// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
(((p) >= 50) && ((p) <= 53)) || \
(((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
( (((p) >= 62) && ((p) <= 69)) ? 2 : \
0 ) )
#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
((uint8_t *)0) ) )
#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
( ((p) == 50) ? 3 : \
( ((p) == 51) ? 2 : \
( ((p) == 52) ? 1 : \
( ((p) == 53) ? 0 : \
( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
0 ) ) ) ) ) )
#ifdef ARDUINO_MAIN
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
const uint16_t PROGMEM port_to_mode_PGM[] = { const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT, NOT_A_PORT,
&DDRA, (uint16_t) &DDRA,
&DDRB, (uint16_t) &DDRB,
&DDRC, (uint16_t) &DDRC,
&DDRD, (uint16_t) &DDRD,
&DDRE, (uint16_t) &DDRE,
&DDRF, (uint16_t) &DDRF,
&DDRG, (uint16_t) &DDRG,
&DDRH, (uint16_t) &DDRH,
NOT_A_PORT, NOT_A_PORT,
&DDRJ, (uint16_t) &DDRJ,
&DDRK, (uint16_t) &DDRK,
&DDRL, (uint16_t) &DDRL,
}; };
const uint16_t PROGMEM port_to_output_PGM[] = { const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT, NOT_A_PORT,
&PORTA, (uint16_t) &PORTA,
&PORTB, (uint16_t) &PORTB,
&PORTC, (uint16_t) &PORTC,
&PORTD, (uint16_t) &PORTD,
&PORTE, (uint16_t) &PORTE,
&PORTF, (uint16_t) &PORTF,
&PORTG, (uint16_t) &PORTG,
&PORTH, (uint16_t) &PORTH,
NOT_A_PORT, NOT_A_PORT,
&PORTJ, (uint16_t) &PORTJ,
&PORTK, (uint16_t) &PORTK,
&PORTL, (uint16_t) &PORTL,
}; };
const uint16_t PROGMEM port_to_input_PGM[] = { const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PIN, NOT_A_PIN,
&PINA, (uint16_t) &PINA,
&PINB, (uint16_t) &PINB,
&PINC, (uint16_t) &PINC,
&PIND, (uint16_t) &PIND,
&PINE, (uint16_t) &PINE,
&PINF, (uint16_t) &PINF,
&PING, (uint16_t) &PING,
&PINH, (uint16_t) &PINH,
NOT_A_PIN, NOT_A_PIN,
&PINJ, (uint16_t) &PINJ,
&PINK, (uint16_t) &PINK,
&PINL, (uint16_t) &PINL,
}; };
const uint8_t PROGMEM digital_pin_to_port_PGM[] = { const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
@ -351,115 +357,7 @@ const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
NOT_ON_TIMER , // PK 6 ** 68 ** A14 NOT_ON_TIMER , // PK 6 ** 68 ** A14
NOT_ON_TIMER , // PK 7 ** 69 ** A15 NOT_ON_TIMER , // PK 7 ** 69 ** A15
}; };
#else
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
&DDRB,
&DDRC,
&DDRD,
};
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
&PORTB,
&PORTC,
&PORTD,
};
const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
&PINB,
&PINC,
&PIND,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PB, /* 8 */
PB,
PB,
PB,
PB,
PB,
PC, /* 14 */
PC,
PC,
PC,
PC,
PC,
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(0), /* 0, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 8, port B */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(0), /* 14, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
NOT_ON_TIMER, /* 0 - port D */
NOT_ON_TIMER,
NOT_ON_TIMER,
// on the ATmega168, digital pin 3 has hardware pwm
#if defined(__AVR_ATmega8__)
NOT_ON_TIMER,
#else
TIMER2B,
#endif
NOT_ON_TIMER,
// on the ATmega168, digital pins 5 and 6 have hardware pwm
#if defined(__AVR_ATmega8__)
NOT_ON_TIMER,
NOT_ON_TIMER,
#else
TIMER0B,
TIMER0A,
#endif
NOT_ON_TIMER,
NOT_ON_TIMER, /* 8 - port B */
TIMER1A,
TIMER1B,
#if defined(__AVR_ATmega8__)
TIMER2,
#else
TIMER2A,
#endif
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER, /* 14 - port C */
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
#endif #endif
#endif

View File

@ -0,0 +1,218 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <avr/pgmspace.h>
#define NUM_DIGITAL_PINS 20
#define NUM_ANALOG_INPUTS 6
#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1)
#if defined(__AVR_ATmega8__)
#define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11)
#else
#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11)
#endif
const static uint8_t SS = 10;
const static uint8_t MOSI = 11;
const static uint8_t MISO = 12;
const static uint8_t SCK = 13;
const static uint8_t SDA = 18;
const static uint8_t SCL = 19;
const static uint8_t LED = 13;
const static uint8_t A0 = 14;
const static uint8_t A1 = 15;
const static uint8_t A2 = 16;
const static uint8_t A3 = 17;
const static uint8_t A4 = 18;
const static uint8_t A5 = 19;
const static uint8_t A6 = 20;
const static uint8_t A7 = 21;
#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
#ifdef ARDUINO_MAIN
// On the Arduino board, digital pins are also used
// for the analog output (software PWM). Analog input
// pins are a separate set.
// ATMEL ATMEGA8 & 168 / ARDUINO
//
// +-\/-+
// PC6 1| |28 PC5 (AI 5)
// (D 0) PD0 2| |27 PC4 (AI 4)
// (D 1) PD1 3| |26 PC3 (AI 3)
// (D 2) PD2 4| |25 PC2 (AI 2)
// PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
// (D 4) PD4 6| |23 PC0 (AI 0)
// VCC 7| |22 GND
// GND 8| |21 AREF
// PB6 9| |20 AVCC
// PB7 10| |19 PB5 (D 13)
// PWM+ (D 5) PD5 11| |18 PB4 (D 12)
// PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
// (D 7) PD7 13| |16 PB2 (D 10) PWM
// (D 8) PB0 14| |15 PB1 (D 9) PWM
// +----+
//
// (PWM+ indicates the additional PWM pins on the ATmega168.)
// ATMEL ATMEGA1280 / ARDUINO
//
// 0-7 PE0-PE7 works
// 8-13 PB0-PB5 works
// 14-21 PA0-PA7 works
// 22-29 PH0-PH7 works
// 30-35 PG5-PG0 works
// 36-43 PC7-PC0 works
// 44-51 PJ7-PJ0 works
// 52-59 PL7-PL0 works
// 60-67 PD7-PD0 works
// A0-A7 PF0-PF7
// A8-A15 PK0-PK7
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &DDRB,
(uint16_t) &DDRC,
(uint16_t) &DDRD,
};
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
};
const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PINB,
(uint16_t) &PINC,
(uint16_t) &PIND,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PB, /* 8 */
PB,
PB,
PB,
PB,
PB,
PC, /* 14 */
PC,
PC,
PC,
PC,
PC,
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(0), /* 0, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 8, port B */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(0), /* 14, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
NOT_ON_TIMER, /* 0 - port D */
NOT_ON_TIMER,
NOT_ON_TIMER,
// on the ATmega168, digital pin 3 has hardware pwm
#if defined(__AVR_ATmega8__)
NOT_ON_TIMER,
#else
TIMER2B,
#endif
NOT_ON_TIMER,
// on the ATmega168, digital pins 5 and 6 have hardware pwm
#if defined(__AVR_ATmega8__)
NOT_ON_TIMER,
NOT_ON_TIMER,
#else
TIMER0B,
TIMER0A,
#endif
NOT_ON_TIMER,
NOT_ON_TIMER, /* 8 - port B */
TIMER1A,
TIMER1B,
#if defined(__AVR_ATmega8__)
TIMER2,
#else
TIMER2A,
#endif
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER, /* 14 - port C */
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
#endif
#endif