Project

General

Profile

Revision 154

added bootloader code

View differences:

trunk/toolbox/main.c
143 143
	init_pins();		//Set pin directions
144 144
	init_uart(51);		//Set registers for uart
145 145
	/***** End Start-up Sequence *****/
146
    while(1) {
147
      PORTB |= _BV(PORTB1);
148
      _delay_ms(100);
149
      PORTB &= ~_BV(PORTB1);
150
      _delay_ms(100);
151
    }
146 152

  
147 153
    uint8_t r;
148 154
    
trunk/toolbox/bootloader/uart.h
1
/********
2
 * This file is part of Tooltron.
3
 *
4
 * Tooltron is free software: you can redistribute it and/or modify
5
 * it under the terms of the Lesser GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Tooltron is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * Lesser GNU General Public License for more details.
13
 * You should have received a copy of the Lesser GNU General Public License
14
 * along with Tooltron.  If not, see <http://www.gnu.org/licenses/>.
15
 *
16
 * Copyright 2009 Kevin Woo <kwoo@2ndt.com>
17
 *
18
 ********/
19
/** @file uart.h
20
 *
21
 *	@brief Initializes UART functions using the UART hardware module
22
 *
23
 *	@author Kevin Woo (kwoo)
24
 */
25

  
26
#ifndef UART_H
27
#define UART_H
28

  
29
#include <avr/io.h>
30
#include <avr/interrupt.h>
31
#include <stdint.h>
32
/** **/
33
#define UART_TX_OFF 0
34
#define UART_TX_ON 1
35

  
36
/** @brief RX Pin for the UART **/
37
#define RX		_BV(PORTD0)
38
#define TX		_BV(PORTD1)
39
#define TX_EN	_BV(PORTD5)
40

  
41
/** @brief The most recently received byte **/
42
extern uint8_t received_byte;
43
/** @brief If the value in received_byte has been read or not **/
44
extern uint8_t byte_ready;
45

  
46
/** @brief Initializes the UART registers and sets it to the buad rate 
47
 *         which msut be the value that is defined in the datasheet 
48
 *         for any particular speed (ie: 51 -> 9600bps)
49
 **/
50
void init_uart(uint16_t baud);
51
/** @brief Gets latest byte and returns it in output_byte. If the byte 
52
 *         was already read, returns -1 otherwise it returns 0 
53
 **/
54
int8_t uart_get_byte(uint8_t *output_byte);
55
/** @brief Sends a character array of size size. If we are currently 
56
 *         transmitting it will block until the the current transmit 
57
 *         is done. 
58
 **/
59
void uart_send_byte(uint8_t data);
60
void uart_toggle_transmit(uint8_t state);
61
#endif
trunk/toolbox/bootloader/bootloader.c
1
/*
2
    1-24-09
3
    Copyright Spark Fun Electronics? 2009
4
    Nathan Seidle
5
    
6
    Wireless bootloader for the ATmega168 and XBee Series 1 modules
7
	
8
	This is a small (728 byte) serial bootloader designed to be a robust solution for remote reset and wireless
9
	booloading. It's not extremely fast, but is very hardy.
10
    
11
	The remote unit (the AVR usually) broadcasts the non-visible character ASCII(6). It then waits for a response
12
	over the serial link for the non-visible character ASCII(5). If received, the remote unit enters bootloading mode.
13
	If the correct character 5 is not received, the remote unit jumps to the beginning of the regular program code.
14
	
15
	Bootloading includes checksum calculation, and timeouts. Timeouts is most important because a wireless
16
	link does not always deliver segments of the serial stream in a deterministic fashion - a good wireless unit
17
	will buffer all sorts of stuff, making the connection stream irregular in throughput.
18
	
19
	This bootloader accepts a pure binary stream (not an intel hex file format). All file parsing is done on the 
20
	base side (usually a beefy computer with lots of extra processing ability).
21
	
22
	Things I learned from testing:
23
	
24
	XBee series 2.5 units have their uses, but not here. I beat my head against the wall trying to form a sensible link and failed.
25
	Ultimately, plugging series 1 in, it worked wonderfully. If you need point-to-point, series 1 is wonderful. If you really
26
	need true mesh node networking, Series 2.5 is good.
27
	
28
	XBee Series 2.5 ships with CTS enabled! That's why the AT commands through hyperterminal were not working. Grr.
29
	
30
	To get a Series 2.5 link to work, you must configure device on XBee Explorer as Coordinator, and the device in your arduino board as the end device.
31
	
32
	Trying to use Series 2.5 for a good point-to-point link:
33
	With CTS Enabled, 19200bps, Packetization Timeout at 3 (default), still bit errors, even with 1ms delay between characters
34
	With CTS Enabled, 19200bps, Packetization Timeout at 0, with 1ms delay between characters helps a lot, but will get character errors if there is RF interferance (units further than a few feet apart)
35

  
36
	With CTS/RTS Enabled, 19200bps, Packet timeout at 0, no delay but with flow control, we have very solid link -> one way!
37
	while( (PIND & (1<<CTS)) != 0); //Don't send anything to the XBee, it is thinking
38
	
39
	You do not seem to need CTS/RTS/DTR to read or program an XBee.
40

  
41
	With XB24-ZB unit, the end device can transmit all it wants, the coordinator seems to die after a few seconds. This
42
	was the ultimate downfall of the series 2.5 for me. The link would work, but the coordinator would drop off after a few
43
	seconds? Series 1 did not do this.
44
	
45
	All of the following code works exceptionally well with Series 1 "XB24" "XBee 802.15.4" "v10CD" firmware
46
	
47
	To configure the XBees, follow "Lady Ada wireless arduino" info
48

  
49
	Series 1 module settings:
50
	Baud: 19200
51
	No flow control (CTS is left on as default)
52
	No change to packetization timeout (default = 3?)
53
	
54
	RTS on XBee board goes up and down with the com advanced trick NOT checked, and hardware control turned ON under terminal
55

  
56
	In VB, turn handshaking off. When RTSEnable = True, the RTS pin goes low, resetting the AVR
57

  
58
	Wireless:
59
	38 seconds to load 14500 code words (most of the space) at 38400 / 8MHz (internal osc)
60
	38 seconds to load 14500 code words (most of the space) at 19200 / 8MHz (internal osc)
61
	Wired:
62
	11 seconds to load 14500 code words (most of the space) at 19200 / 8MHz (internal osc)
63
	so you see, there is no benefit to a higher baud rate. The XBee protocol is the bottleneck
64

  
65
	How to read the flash contents to file : 
66
	avrdude -c stk200 -p m168 -P lpt1 -Uflash:r:bl.hex:i
67
	This will dump the current flash contents of an AVR to a read-able hex file called "bl.hex". This
68
	was very helpful when testing whether flash writing was actually working.
69

  
70
	Oh, and if you happen to be using an XBee with a UFL antenna connector (and don't have a UFL antenna sitting around)
71
	you can convert it to a wire antenna simply by soldering in a short wire into the XBee. It may not be the best, 
72
	but it works.
73

  
74
*/
75

  
76

  
77
#include <avr/io.h>
78
#include <util/delay.h>
79
#include <avr/boot.h>
80

  
81
#include "uart.h"
82

  
83
#define TRUE	0
84
#define FALSE	1
85

  
86
#define MAX_WAIT_IN_CYCLES 800000
87

  
88
//Status LED
89
#define LED_DDR  DDRB
90
#define LED_PORT PORTB
91
#define LED      PORTB1
92

  
93
//Function prototypes
94
void flash_led(uint8_t);
95
void onboard_program_write(uint32_t page, uint8_t *buf);
96
void (*main_start)(void) = 0x0000;
97

  
98
//Variables
99
uint8_t incoming_page_data[256];
100
uint8_t page_length;
101
uint8_t retransmit_flag = FALSE;
102

  
103
union page_address_union {
104
  uint16_t word;
105
  uint8_t  byte[2];
106
} page_address;
107

  
108
char getch(void);
109

  
110
int main(void)
111
{
112
  uint8_t check_sum = 0;
113
  uint16_t i;
114

  
115
  //  init_uart(51); //MAGIC NUMBER??
116

  
117
  //set LED pin as output
118
  //  LED_DDR |= _BV(LED);
119
  
120
    DDRB = 0x00;
121
    DDRB = _BV(DDB0) | _BV(DDB1) | _BV(DDB2) | _BV(DDB5);
122
    DDRD = _BV(DDB4);
123
    PORTB = 0x00;
124

  
125
    // Clear timmer on OCRA1 Compare match
126
    // No prescale
127
    TCCR1B |= _BV(WGM12) | _BV(CS12);
128
    
129
    // 1 second @ 8MHz clock
130
    OCR1AH =0x7A;
131
    OCR1AL =0x12;
132

  
133
    TIMSK = _BV(OCIE1A);
134

  
135
  //flash onboard LED to signal entering of bootloader
136
    while(1) {
137
      PORTB |= _BV(LED);
138
      _delay_ms(100);
139
      PORTB &= ~_BV(LED);
140
      _delay_ms(100);
141
    }
142
  flash_led(1);
143

  
144
  //Start bootloading process
145

  
146
  uart_send_byte(5); //Tell the world we can be bootloaded
147

  
148
  //Check to see if the computer responded
149
  uint32_t count = 0;
150
  uint8_t resp;
151
  while(uart_get_byte(&resp) == -1) {
152
    count++;
153
    if (count > MAX_WAIT_IN_CYCLES)
154
      //TODO: flash some leds or something
155
      main_start();
156
  }
157

  
158
  /* If the computer did not respond correctly with a ACK, we jump to
159
   * user's program
160
   */
161
  if(resp != 6)
162
    main_start(); 
163

  
164
  while(1) {
165
    //Determine if the last received data was good or bad
166
    if (check_sum != 0) //If the check sum does not compute, tell computer to resend same line
167
    RESTART:
168
      uart_send_byte(7); //Ascii character BELL
169
    else            
170
      uart_send_byte('T'); //Tell the computer that we are ready for the next line
171
        
172
    while(1) {//Wait for the computer to initiate transfer
173
      if (getch() == ':') break; //This is the "gimme the next chunk" command
174
      if (retransmit_flag == TRUE) goto RESTART;
175
    }
176

  
177
    page_length = getch(); //Get the length of this block
178
    if (retransmit_flag == TRUE) goto RESTART;
179

  
180
    if (page_length == 'S') {//Check to see if we are done - this is the "all done" command
181
      //boot_rww_enable (); //Wait for any flash writes to complete?
182
      main_start(); 
183
    }
184
	
185
    //Get the memory address at which to store this block of data
186
    page_address.byte[0] = getch(); if (retransmit_flag == TRUE) goto RESTART;
187
    page_address.byte[1] = getch(); if (retransmit_flag == TRUE) goto RESTART;
188

  
189
    check_sum = getch(); //Pick up the check sum for error dectection
190
    if (retransmit_flag == TRUE) goto RESTART;
191
		
192
    for(i = 0 ; i < page_length ; i++) {//Read the program data
193
      incoming_page_data[i] = getch();
194
      if (retransmit_flag == TRUE) goto RESTART;
195
    }
196
        
197
    //Calculate the checksum
198
    for(i = 0 ; i < page_length ; i++)
199
      check_sum = check_sum + incoming_page_data[i];
200
        
201
    check_sum = check_sum + page_length;
202
    check_sum = check_sum + page_address.byte[0];
203
    check_sum = check_sum + page_address.byte[1];
204
		
205
    if(check_sum == 0) //If we have a good transmission, put it in ink
206
      onboard_program_write((uint32_t)page_address.word, incoming_page_data);
207
  }
208

  
209
}
210

  
211
//#define SPM_PAGESIZE 128
212
void onboard_program_write(uint32_t page, uint8_t *buf)
213
{
214
  uint16_t i;
215
	//uint8_t sreg;
216

  
217
	// Disable interrupts.
218

  
219
	//sreg = SREG;
220
	//cli();
221

  
222
	//eeprom_busy_wait ();
223

  
224
  boot_page_erase (page);
225
  boot_spm_busy_wait ();      // Wait until the memory is erased.
226

  
227
  for (i=0; i<SPM_PAGESIZE; i+=2){
228
    // Set up little-endian word.
229

  
230
    uint16_t w = *buf++;
231
    w += (*buf++) << 8;
232
	
233
    boot_page_fill (page + i, w);
234
  }
235

  
236
  boot_page_write (page);     // Store buffer in flash page.
237
  boot_spm_busy_wait();       // Wait until the memory is written.
238

  
239
	// Reenable RWW-section again. We need this if we want to jump back
240
	// to the application after bootloading.
241

  
242
	//boot_rww_enable ();
243

  
244
	// Re-enable interrupts (if they were ever enabled).
245

  
246
	//SREG = sreg;
247
}
248

  
249
char getch(void) {
250
  retransmit_flag = FALSE;
251
	
252
  uint32_t count = 0;
253
  uint8_t resp;
254
  while(uart_get_byte(&resp)==-1) {
255
    count++;
256
    if (count > MAX_WAIT_IN_CYCLES) {
257
      retransmit_flag = TRUE;
258
      break;
259
    }
260
  }
261

  
262
  return resp;
263
}
264

  
265
void flash_led(uint8_t count)
266
{
267
	uint8_t i;
268
	
269
	for (i = 0; i < count; ++i) {
270
		LED_PORT |= _BV(LED);
271
		_delay_ms(100);
272
		LED_PORT &= ~_BV(LED);
273
		_delay_ms(100);
274
	}
275
}
trunk/toolbox/bootloader/uart.c
1
/********
2
 * This file is part of Tooltron.
3
 *
4
 * Tooltron is free software: you can redistribute it and/or modify
5
 * it under the terms of the Lesser GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Tooltron is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * Lesser GNU General Public License for more details.
13
 * You should have received a copy of the Lesser GNU General Public License
14
 * along with Tooltron.  If not, see <http://www.gnu.org/licenses/>.
15
 *
16
 * Copyright 2009 Kevin Woo <kwoo@2ndt.com>
17
 *
18
 ********/
19
/** @file uart.c
20
 *	
21
 *	@brief Implements UART functionality in hardware
22
 *
23
 *	@author Kevin Woo (kwoo)
24
 */
25

  
26
#include "uart.h"
27
#include <util/delay.h>
28
#include <stdint.h>
29

  
30
uint8_t received_byte;     //Byte received
31
uint8_t byte_ready;        //New byte has been received
32

  
33
void init_uart(uint16_t baud) {
34
	// Set baud rate
35
	UBRRH = (uint8_t)(baud>>8);
36
	UBRRL = (uint8_t)baud;
37
	
38
	// Enable RX/TX and RX/TX Interrupt
39
	UCSRB = _BV(RXCIE) | _BV(RXEN) | _BV(TXCIE) | _BV(TXEN);
40
 
41
	// Enable the TXEN pin as output
42
	DDRD |= TX_EN;
43

  
44
    // Initialize receive variables
45
    byte_ready = 0;
46
    received_byte = 0x0;
47
}
48

  
49
int8_t uart_get_byte(uint8_t *output_byte) {
50
	if (byte_ready) {
51
		byte_ready = 0;
52
		*output_byte = received_byte;
53
		return 0;
54
	} else {
55
		return -1;
56
	}
57
}
58

  
59
void uart_send_byte(uint8_t data) {
60
	//Waits until current transmit is done
61
    while (!(UCSRA & _BV(UDRE)));
62

  
63
    // Enable writes and send
64
	uart_toggle_transmit(UART_TX_ON);
65
    UDR = data;
66
	return;
67
}
68

  
69
void uart_toggle_transmit(uint8_t state) {
70
	if (state == UART_TX_ON) {
71
		PORTD |= TX_EN;
72
	} else {
73
		PORTD &= ~TX_EN;
74
	}
75
}
76

  
77
ISR(USART_RX_vect) {
78
    received_byte = UDR;
79
    byte_ready = 1;    
80
}
81

  
82
ISR(USART_TX_vect) {
83
    // Re-enable reads
84
    uart_toggle_transmit(UART_TX_OFF);
85
}
trunk/toolbox/bootloader/Makefile
1
# Hey Emacs, this is a -*- makefile -*-
2
#----------------------------------------------------------------------------
3
# WinAVR Makefile Template written by Eric B. Weddington, J?rg Wunsch, et al.
4
#
5
# Released to the Public Domain
6
#
7
# Additional material for this makefile was written by:
8
# Peter Fleury
9
# Tim Henigan
10
# Colin O'Flynn
11
# Reiner Patommel
12
# Markus Pfaff
13
# Sander Pool
14
# Frederik Rouleau
15
#
16
#----------------------------------------------------------------------------
17
# On command line:
18
#
19
# make all = Make software.
20
#
21
# make clean = Clean out built project files.
22
#
23
# make coff = Convert ELF to AVR COFF.
24
#
25
# make extcoff = Convert ELF to AVR Extended COFF.
26
#
27
# make program = Download the hex file to the device, using avrdude.
28
#                Please customize the avrdude settings below first!
29
#
30
# make debug = Start either simulavr or avarice as specified for debugging, 
31
#              with avr-gdb or avr-insight as the front end for debugging.
32
#
33
# make filename.s = Just compile filename.c into the assembler code only.
34
#
35
# make filename.i = Create a preprocessed source file for use in submitting
36
#                   bug reports to the GCC project.
37
#
38
# To rebuild project do "make clean" then "make all".
39
#----------------------------------------------------------------------------
40

  
41

  
42
# MCU name
43
MCU = attiny2313
44

  
45
# Processor frequency.
46
#     This will define a symbol, F_CPU, in all source code files equal to the 
47
#     processor frequency. You can then use this symbol in your source code to 
48
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
49
#     automatically to create a 32-bit value in your source code.
50
F_CPU = 8000000
51

  
52

  
53
# Output format. (can be srec, ihex, binary)
54
FORMAT = ihex
55

  
56
# Target file name (without extension).
57
TARGET = bootloader
58

  
59
# List C source files here. (C dependencies are automatically generated.)
60
SRC =  $(wildcard *.c)
61

  
62
# List Assembler source files here.
63
#     Make them always end in a capital .S.  Files ending in a lowercase .s
64
#     will not be considered source files but generated files (assembler
65
#     output from the compiler), and will be deleted upon "make clean"!
66
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
67
#     it will preserve the spelling of the filenames, and gcc itself does
68
#     care about how the name is spelled on its command-line.
69
ASRC = 
70

  
71

  
72
# Optimization level, can be [0, 1, 2, 3, s]. 
73
#     0 = turn off optimization. s = optimize for size.
74
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
75
OPT = s
76

  
77

  
78
# Debugging format.
79
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
80
#     AVR Studio 4.10 requires dwarf-2.
81
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
82
DEBUG =
83

  
84

  
85
# List any extra directories to look for include files here.
86
#     Each directory must be seperated by a space.
87
#     Use forward slashes for directory separators.
88
#     For a directory that has spaces, enclose it in quotes.
89
#EXTRAINCDIRS = C:\WinAVR\include\fwr
90

  
91

  
92
# Compiler flag to set the C Standard level.
93
#     c89   = "ANSI" C
94
#     gnu89 = c89 plus GCC extensions
95
#     c99   = ISO C99 standard (not yet fully implemented)
96
#     gnu99 = c99 plus GCC extensions
97
CSTANDARD = -std=gnu99
98

  
99

  
100
# Place -D or -U options here
101
CDEFS = -DF_CPU=$(F_CPU)UL
102

  
103

  
104
# Place -I options here
105
CINCS =
106

  
107

  
108

  
109
#---------------- Compiler Options ----------------
110
#  -g*:          generate debugging information
111
#  -O*:          optimization level
112
#  -f...:        tuning, see GCC manual and avr-libc documentation
113
#  -Wall...:     warning level
114
#  -Wa,...:      tell GCC to pass this to the assembler.
115
#    -adhlns...: create assembler listing
116
#CFLAGS = -g$(DEBUG)
117
CFLAGS += $(CDEFS) $(CINCS)
118
CFLAGS += -O$(OPT)
119
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
120
CFLAGS += -Wall -Wstrict-prototypes
121
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
122
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
123
CFLAGS += $(CSTANDARD)
124

  
125

  
126
#---------------- Assembler Options ----------------
127
#  -Wa,...:   tell GCC to pass this to the assembler.
128
#  -ahlms:    create listing
129
#  -gstabs:   have the assembler create line number information; note that
130
#             for use in COFF files, additional information about filenames
131
#             and function names needs to be present in the assembler source
132
#             files -- see avr-libc docs [FIXME: not yet described there]
133
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
134

  
135

  
136
#---------------- Library Options ----------------
137
# Minimalistic printf version
138
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
139

  
140
# Floating point printf version (requires MATH_LIB = -lm below)
141
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
142

  
143
# If this is left blank, then it will use the Standard printf version.
144
PRINTF_LIB = 
145
#PRINTF_LIB = $(PRINTF_LIB_MIN)
146
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
147

  
148

  
149
# Minimalistic scanf version
150
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
151

  
152
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
153
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
154

  
155
# If this is left blank, then it will use the Standard scanf version.
156
SCANF_LIB = 
157
#SCANF_LIB = $(SCANF_LIB_MIN)
158
#SCANF_LIB = $(SCANF_LIB_FLOAT)
159

  
160

  
161
MATH_LIB = -lm
162

  
163

  
164

  
165
#---------------- External Memory Options ----------------
166

  
167
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
168
# used for variables (.data/.bss) and heap (malloc()).
169
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
170

  
171
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
172
# only used for heap (malloc()).
173
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
174

  
175
EXTMEMOPTS =
176

  
177

  
178

  
179
#---------------- Linker Options ----------------
180
#  -Wl,...:     tell GCC to pass this to linker.
181
#    -Map:      create map file
182
#    --cref:    add cross reference to  map file
183
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
184
LDFLAGS += $(EXTMEMOPTS)
185
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
186

  
187

  
188

  
189
#---------------- Programming Options (avrdude) ----------------
190

  
191
# Programming hardware: alf avr910 avrisp bascom bsd 
192
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
193
#
194
# Type: avrdude -c ?
195
# to get a full listing.
196
#
197
AVRDUDE_PROGRAMMER = avrispmkII
198

  
199
# com1 = serial port. Use lpt1 to connect to parallel port.
200
AVRDUDE_PORT = usb 
201
# programmer connected to serial device
202

  
203
AVRDUDE_WRITE_FLASH = -b 4800 -U flash:w:$(TARGET).hex
204
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
205

  
206

  
207
# Uncomment the following if you want avrdude's erase cycle counter.
208
# Note that this counter needs to be initialized first using -Yn,
209
# see avrdude manual.
210
#AVRDUDE_ERASE_COUNTER = -y
211

  
212
# Uncomment the following if you do /not/ wish a verification to be
213
# performed after programming the device.
214
#AVRDUDE_NO_VERIFY = -V
215

  
216
# Increase verbosity level.  Please use this when submitting bug
217
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
218
# to submit bug reports.
219
#AVRDUDE_VERBOSE = -v -v
220

  
221
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
222
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
223
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
224
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
225

  
226

  
227

  
228
#---------------- Debugging Options ----------------
229

  
230
# For simulavr only - target MCU frequency.
231
DEBUG_MFREQ = $(F_CPU)
232

  
233
# Set the DEBUG_UI to either gdb or insight.
234
# DEBUG_UI = gdb
235
DEBUG_UI = insight
236

  
237
# Set the debugging back-end to either avarice, simulavr.
238
DEBUG_BACKEND = avarice
239
#DEBUG_BACKEND = simulavr
240

  
241
# GDB Init Filename.
242
GDBINIT_FILE = __avr_gdbinit
243

  
244
# When using avarice settings for the JTAG
245
JTAG_DEV = /dev/com1
246

  
247
# Debugging port used to communicate between GDB / avarice / simulavr.
248
DEBUG_PORT = 4242
249

  
250
# Debugging host used to communicate between GDB / avarice / simulavr, normally
251
#     just set to localhost unless doing some sort of crazy debugging when 
252
#     avarice is running on a different computer.
253
DEBUG_HOST = localhost
254

  
255

  
256

  
257
#============================================================================
258

  
259

  
260
# Define programs and commands.
261
SHELL = sh
262
CC = avr-gcc
263
OBJCOPY = avr-objcopy
264
OBJDUMP = avr-objdump
265
SIZE = avr-size
266
NM = avr-nm
267
AVRDUDE = avrdude
268
REMOVE = rm -f
269
COPY = cp
270
WINSHELL = cmd
271

  
272

  
273
# Define Messages
274
# English
275
MSG_ERRORS_NONE = Errors: none
276
MSG_BEGIN = -------- begin --------
277
MSG_END = --------  end  --------
278
MSG_SIZE_BEFORE = Size before: 
279
MSG_SIZE_AFTER = Size after:
280
MSG_COFF = Converting to AVR COFF:
281
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
282
MSG_FLASH = Creating load file for Flash:
283
MSG_EEPROM = Creating load file for EEPROM:
284
MSG_EXTENDED_LISTING = Creating Extended Listing:
285
MSG_SYMBOL_TABLE = Creating Symbol Table:
286
MSG_LINKING = Linking:
287
MSG_COMPILING = Compiling:
288
MSG_ASSEMBLING = Assembling:
289
MSG_CLEANING = Cleaning project:
290

  
291

  
292

  
293

  
294
# Define all object files.
295
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
296

  
297
# Define all listing files.
298
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) 
299

  
300

  
301
# Compiler flags to generate dependency files.
302
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
303

  
304

  
305
# Combine all necessary flags and optional flags.
306
# Add target processor to flags.
307
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
308
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
309

  
310

  
311

  
312

  
313

  
314
# Default target.
315
all: begin gccversion sizebefore build sizeafter end
316

  
317
build: elf hex eep lss sym
318

  
319
elf: $(TARGET).elf
320
hex: $(TARGET).hex
321
eep: $(TARGET).eep
322
lss: $(TARGET).lss 
323
sym: $(TARGET).sym
324

  
325

  
326

  
327
# Eye candy.
328
# AVR Studio 3.x does not check make's exit code but relies on
329
# the following magic strings to be generated by the compile job.
330
begin:
331
	@echo
332
	@echo $(MSG_BEGIN)
333

  
334
end:
335
	@echo $(MSG_END)
336
	@echo
337

  
338

  
339
# Display size of file.
340
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
341
ELFSIZE = $(SIZE) -A $(TARGET).elf
342
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
343

  
344
sizebefore:
345
	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
346
	$(AVRMEM) 2>/dev/null; echo; fi
347

  
348
sizeafter:
349
	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
350
	$(AVRMEM) 2>/dev/null; echo; fi
351

  
352

  
353

  
354
# Display compiler version information.
355
gccversion : 
356
	@$(CC) --version
357

  
358

  
359

  
360
# Program the device.  
361
program: $(TARGET).hex $(TARGET).eep
362
	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
363

  
364

  
365
# Generate avr-gdb config/init file which does the following:
366
#     define the reset signal, load the target file, connect to target, and set 
367
#     a breakpoint at main().
368
gdb-config: 
369
	@$(REMOVE) $(GDBINIT_FILE)
370
	@echo define reset >> $(GDBINIT_FILE)
371
	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
372
	@echo end >> $(GDBINIT_FILE)
373
	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
374
	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
375
ifeq ($(DEBUG_BACKEND),simulavr)
376
	@echo load  >> $(GDBINIT_FILE)
377
endif	
378
	@echo break main >> $(GDBINIT_FILE)
379
	
380
debug: gdb-config $(TARGET).elf
381
ifeq ($(DEBUG_BACKEND), avarice)
382
	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
383
	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
384
	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
385
	@$(WINSHELL) /c pause
386
	
387
else
388
	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
389
	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
390
endif
391
	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
392
	
393

  
394

  
395

  
396
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
397
COFFCONVERT=$(OBJCOPY) --debugging \
398
--change-section-address .data-0x800000 \
399
--change-section-address .bss-0x800000 \
400
--change-section-address .noinit-0x800000 \
401
--change-section-address .eeprom-0x810000 
402

  
403

  
404
coff: $(TARGET).elf
405
	@echo
406
	@echo $(MSG_COFF) $(TARGET).cof
407
	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
408

  
409

  
410
extcoff: $(TARGET).elf
411
	@echo
412
	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
413
	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
414

  
415

  
416

  
417
# Create final output files (.hex, .eep) from ELF output file.
418
%.hex: %.elf
419
	@echo
420
	@echo $(MSG_FLASH) $@
421
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
422

  
423
%.eep: %.elf
424
	@echo
425
	@echo $(MSG_EEPROM) $@
426
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
427
	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
428

  
429
# Create extended listing file from ELF output file.
430
%.lss: %.elf
431
	@echo
432
	@echo $(MSG_EXTENDED_LISTING) $@
433
	$(OBJDUMP) -h -S $< > $@
434

  
435
# Create a symbol table from ELF output file.
436
%.sym: %.elf
437
	@echo
438
	@echo $(MSG_SYMBOL_TABLE) $@
439
	$(NM) -n $< > $@
440

  
441

  
442

  
443
# Link: create ELF output file from object files.
444
.SECONDARY : $(TARGET).elf
445
.PRECIOUS : $(OBJ)
446
%.elf: $(OBJ)
447
	@echo
448
	@echo $(MSG_LINKING) $@
449
	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
450

  
451

  
452
# Compile: create object files from C source files.
453
%.o : %.c
454
	@echo
455
	@echo $(MSG_COMPILING) $<
456
	$(CC) -c $(ALL_CFLAGS) $< -o $@ 
457

  
458

  
459
# Compile: create assembler files from C source files.
460
%.s : %.c
461
	$(CC) -S $(ALL_CFLAGS) $< -o $@
462

  
463

  
464
# Assemble: create object files from assembler source files.
465
%.o : %.S
466
	@echo
467
	@echo $(MSG_ASSEMBLING) $<
468
	$(CC) -c $(ALL_ASFLAGS) $< -o $@
469

  
470
# Create preprocessed source for use in sending a bug report.
471
%.i : %.c
472
	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
473

  
474

  
475
# Target: clean project.
476
clean: begin clean_list end
477

  
478
clean_list :
479
	@echo
480
	@echo $(MSG_CLEANING)
481
	$(REMOVE) $(TARGET).hex
482
	$(REMOVE) $(TARGET).eep
483
	$(REMOVE) $(TARGET).cof
484
	$(REMOVE) $(TARGET).elf
485
	$(REMOVE) $(TARGET).map
486
	$(REMOVE) $(TARGET).sym
487
	$(REMOVE) $(TARGET).lss
488
	$(REMOVE) $(OBJ)
489
	$(REMOVE) $(LST)
490
	$(REMOVE) $(SRC:.c=.s)
491
	$(REMOVE) $(SRC:.c=.d)
492
	$(REMOVE) .dep/*
493

  
494

  
495

  
496
# Include the dependency files.
497
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
498

  
499

  
500
# Listing of phony targets.
501
.PHONY : all begin finish end sizebefore sizeafter gccversion \
502
build elf hex eep lss sym coff extcoff \
503
clean clean_list program debug gdb-config
504

  

Also available in: Unified diff