Forum: Mikrocontroller und Digitale Elektronik USBaspLoader und ATmega32 wollen nicht


von Dead D. (deaddealer)


Lesenswert?

Hi,

ich sitze nun schon eine Weile an der Labnode 
(https://www.das-labor.org/wiki/Labnode) und versuche da den 
USBaspLoader drauf laufen zu lassen. Doch irgendwie will das nicht so 
recht. Das Original-Makefile ist nur passend für einen ATmega328p 
geschrieben, und ich bin mir nicht ganz sicher, welche Punkte ich da 
drin ändern muss, damit der Bootloader startet.

Ich habe mich dazu entschieden, den Jumper auf PA1 zu legen. Die 
Änderungen habe ich entsprechend in der bootloaderconfig.h, main.c und 
der Makefile gemacht. Hier die Quellcodes der modifizierten Dateien...

bootloaderconfig.h:
1
/* Name: bootloaderconfig.h
2
 * Project: USBaspLoader
3
 * Author: Christian Starkjohann
4
 * Creation Date: 2007-12-08
5
 * Tabsize: 4
6
 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
7
 * License: GNU GPL v2 (see License.txt)
8
 * This Revision: $Id: bootloaderconfig.h 729 2009-03-20 09:03:58Z cs $
9
 */
10
11
#ifndef __bootloaderconfig_h_included__
12
#define __bootloaderconfig_h_included__
13
14
/*
15
General Description:
16
This file (together with some settings in Makefile) configures the boot loader
17
according to the hardware.
18
19
This file contains (besides the hardware configuration normally found in
20
usbconfig.h) two functions or macros: bootLoaderInit() and
21
bootLoaderCondition(). Whether you implement them as macros or as static
22
inline functions is up to you, decide based on code size and convenience.
23
24
bootLoaderInit() is called as one of the first actions after reset. It should
25
be a minimum initialization of the hardware so that the boot loader condition
26
can be read. This will usually consist of activating a pull-up resistor for an
27
external jumper which selects boot loader mode.
28
29
bootLoaderCondition() is called immediately after initialization and in each
30
main loop iteration. If it returns TRUE, the boot loader will be active. If it
31
returns FALSE, the boot loader jumps to address 0 (the loaded application)
32
immediately.
33
34
For compatibility with Thomas Fischl's avrusbboot, we also support the macro
35
names BOOTLOADER_INIT and BOOTLOADER_CONDITION for this functionality. If
36
these macros are defined, the boot loader usees them.
37
*/
38
39
/* ---------------------------- Hardware Config ---------------------------- */
40
41
#define USB_CFG_IOPORTNAME      C
42
/* This is the port where the USB bus is connected. When you configure it to
43
 * "B", the registers PORTB, PINB and DDRB will be used.
44
 */
45
#define USB_CFG_DMINUS_BIT      3
46
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
47
 * This may be any bit in the port.
48
 */
49
#define USB_CFG_DPLUS_BIT       2
50
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
51
 * This may be any bit in the port. Please note that D+ must also be connected
52
 * to interrupt pin INT0!
53
 */
54
#define USB_CFG_CLOCK_KHZ       (F_CPU/1000)
55
/* Clock rate of the AVR in MHz. Legal values are 12000, 16000 or 16500.
56
 * The 16.5 MHz version of the code requires no crystal, it tolerates +/- 1%
57
 * deviation from the nominal frequency. All other rates require a precision
58
 * of 2000 ppm and thus a crystal!
59
 * Default if not specified: 12 MHz
60
 */
61
62
/* ----------------------- Optional Hardware Config ------------------------ */
63
64
/* #define USB_CFG_PULLUP_IOPORTNAME   D */
65
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
66
 * V+, you can connect and disconnect the device from firmware by calling
67
 * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
68
 * This constant defines the port on which the pullup resistor is connected.
69
 */
70
/* #define USB_CFG_PULLUP_BIT          4 */
71
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
72
 * above) where the 1.5k pullup resistor is connected. See description
73
 * above for details.
74
 */
75
76
/* ------------------------------------------------------------------------- */
77
/* ---------------------- feature / code size options ---------------------- */
78
/* ------------------------------------------------------------------------- */
79
80
#define HAVE_EEPROM_PAGED_ACCESS    1
81
/* If HAVE_EEPROM_PAGED_ACCESS is defined to 1, page mode access to EEPROM is
82
 * compiled in. Whether page mode or byte mode access is used by AVRDUDE
83
 * depends on the target device. Page mode is only used if the device supports
84
 * it, e.g. for the ATMega88, 168 etc. You can save quite a bit of memory by
85
 * disabling page mode EEPROM access. Costs ~ 138 bytes.
86
 */
87
#define HAVE_EEPROM_BYTE_ACCESS     1
88
/* If HAVE_EEPROM_BYTE_ACCESS is defined to 1, byte mode access to EEPROM is
89
 * compiled in. Byte mode is only used if the device (as identified by its
90
 * signature) does not support page mode for EEPROM. It is required for
91
 * accessing the EEPROM on the ATMega8. Costs ~54 bytes.
92
 */
93
#define BOOTLOADER_CAN_EXIT         1
94
/* If this macro is defined to 1, the boot loader will exit shortly after the
95
 * programmer closes the connection to the device. Costs ~36 bytes.
96
 */
97
#define HAVE_CHIP_ERASE             0
98
/* If this macro is defined to 1, the boot loader implements the Chip Erase
99
 * ISP command. Otherwise pages are erased on demand before they are written.
100
 */
101
//#define SIGNATURE_BYTES             0x1e, 0x93, 0x07, 0     /* ATMega8 */
102
/* This macro defines the signature bytes returned by the emulated USBasp to
103
 * the programmer software. They should match the actual device at least in
104
 * memory size and features. If you don't define this, values for ATMega8,
105
 * ATMega88, ATMega168 and ATMega328 are guessed correctly.
106
 */
107
108
/* The following block guesses feature options so that the resulting code
109
 * should fit into 2k bytes boot block with the given device and clock rate.
110
 * Activate by passing "-DUSE_AUTOCONFIG=1" to the compiler.
111
 * This requires gcc 3.4.6 for small enough code size!
112
 */
113
#if USE_AUTOCONFIG
114
#   undef HAVE_EEPROM_PAGED_ACCESS
115
#   define HAVE_EEPROM_PAGED_ACCESS     (USB_CFG_CLOCK_KHZ >= 16000)
116
#   undef HAVE_EEPROM_BYTE_ACCESS
117
#   define HAVE_EEPROM_BYTE_ACCESS      1
118
#   undef BOOTLOADER_CAN_EXIT
119
#   define BOOTLOADER_CAN_EXIT          1
120
#   undef SIGNATURE_BYTES
121
#endif /* USE_AUTOCONFIG */
122
123
/* ------------------------------------------------------------------------- */
124
125
/* Example configuration: Port C bit 0 is connected to a jumper which ties
126
 * this pin to GND if the boot loader is requested. Initialization allows
127
 * several clock cycles for the input voltage to stabilize before
128
 * bootLoaderCondition() samples the value.
129
 * We use a function for bootLoaderInit() for convenience and a macro for
130
 * bootLoaderCondition() for efficiency.
131
 */
132
133
#ifndef __ASSEMBLER__   /* assembler cannot parse function definitions */
134
135
#define JUMPER_BIT  PA1   /* jumper is connected to this bit in port C, active low */
136
137
#ifndef MCUCSR          /* compatibility between ATMega8 and ATMega88 */
138
#   define MCUCSR   MCUSR
139
#endif
140
141
static inline void  bootLoaderInit(void)
142
{
143
    PORTA |= (1 << JUMPER_BIT);     /* activate pull-up */
144
    if(!(MCUCSR & (1 << EXTRF)))    /* If this was not an external reset, ignore */
145
        leaveBootloader();
146
    MCUCSR = 0;                     /* clear all reset flags for next time */
147
}
148
149
static inline void  bootLoaderExit(void)
150
{
151
  PORTA = 0;                      /* undo bootLoaderInit() changes */
152
}
153
154
#define bootLoaderCondition()   ((PINA & (1 << JUMPER_BIT)) == 0)
155
156
#endif /* __ASSEMBLER__ */
157
158
/* ------------------------------------------------------------------------- */
159
160
#endif /* __bootloader_h_included__ */

main.c:
1
/* Name: main.c
2
 * Project: USBaspLoader
3
 * Author: Christian Starkjohann
4
 * Creation Date: 2007-12-08
5
 * Tabsize: 4
6
 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
7
 * License: GNU GPL v2 (see License.txt)
8
 * This Revision: $Id: main.c 786 2010-05-30 20:41:40Z cs $
9
 */
10
11
#include <avr/io.h>
12
#include <avr/interrupt.h>
13
#include <avr/pgmspace.h>
14
#include <avr/wdt.h>
15
#include <avr/boot.h>
16
#include <avr/eeprom.h>
17
#include <util/delay.h>
18
#include <string.h>
19
20
static void leaveBootloader() __attribute__((__noreturn__));
21
22
#include "bootloaderconfig.h"
23
#include "usbdrv/usbdrv.c"
24
25
/* ------------------------------------------------------------------------ */
26
27
/* Request constants used by USBasp */
28
#define USBASP_FUNC_CONNECT         1
29
#define USBASP_FUNC_DISCONNECT      2
30
#define USBASP_FUNC_TRANSMIT        3
31
#define USBASP_FUNC_READFLASH       4
32
#define USBASP_FUNC_ENABLEPROG      5
33
#define USBASP_FUNC_WRITEFLASH      6
34
#define USBASP_FUNC_READEEPROM      7
35
#define USBASP_FUNC_WRITEEEPROM     8
36
#define USBASP_FUNC_SETLONGADDRESS  9
37
38
/* ------------------------------------------------------------------------ */
39
40
#ifndef ulong
41
#   define ulong    unsigned long
42
#endif
43
#ifndef uint
44
#   define uint     unsigned int
45
#endif
46
47
/* defaults if not in config file: */
48
#ifndef HAVE_EEPROM_PAGED_ACCESS
49
#   define HAVE_EEPROM_PAGED_ACCESS 0
50
#endif
51
#ifndef HAVE_EEPROM_BYTE_ACCESS
52
#   define HAVE_EEPROM_BYTE_ACCESS  0
53
#endif
54
#ifndef BOOTLOADER_CAN_EXIT
55
#   define  BOOTLOADER_CAN_EXIT     0
56
#endif
57
58
/* allow compatibility with avrusbboot's bootloaderconfig.h: */
59
#ifdef BOOTLOADER_INIT
60
#   define bootLoaderInit()         BOOTLOADER_INIT
61
#   define bootLoaderExit()
62
#endif
63
#ifdef BOOTLOADER_CONDITION
64
#   define bootLoaderCondition()    BOOTLOADER_CONDITION
65
#endif
66
67
/* device compatibility: */
68
#ifndef GICR    /* ATMega*8 don't have GICR, use MCUCR instead */
69
#   define GICR     MCUCR
70
#endif
71
72
/* ------------------------------------------------------------------------ */
73
74
#if (FLASHEND) > 0xffff /* we need long addressing */
75
#   define CURRENT_ADDRESS  currentAddress.l
76
#   define addr_t           ulong
77
#else
78
#   define CURRENT_ADDRESS  currentAddress.w[0]
79
#   define addr_t           uint
80
#endif
81
82
typedef union longConverter{
83
    addr_t  l;
84
    uint    w[sizeof(addr_t)/2];
85
    uchar   b[sizeof(addr_t)];
86
}longConverter_t;
87
88
static uchar            requestBootLoaderExit;
89
static longConverter_t  currentAddress; /* in bytes */
90
static uchar            bytesRemaining;
91
static uchar            isLastPage;
92
#if HAVE_EEPROM_PAGED_ACCESS
93
static uchar            currentRequest;
94
#else
95
static const uchar      currentRequest = 0;
96
#endif
97
98
static const uchar  signatureBytes[4] = {
99
#ifdef SIGNATURE_BYTES
100
    SIGNATURE_BYTES
101
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
102
    0x1e, 0x93, 0x07, 0
103
#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
104
    0x1e, 0x92, 0x05, 0
105
#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
106
    0x1e, 0x93, 0x0a, 0
107
#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
108
    0x1e, 0x94, 0x06, 0
109
#elif defined (__AVR_ATmega328P__)
110
    0x1e, 0x95, 0x0f, 0
111
#elif defined (__AVR_ATmega32__)
112
    0x1e, 0x95, 0x02, 0
113
#else
114
#   error "Device signature is not known, please edit main.c!"
115
#endif
116
};
117
118
/* ------------------------------------------------------------------------ */
119
120
static void (*nullVector)(void) __attribute__((__noreturn__));
121
122
static void leaveBootloader()
123
{
124
    DBG1(0x01, 0, 0);
125
    bootLoaderExit();
126
    cli();
127
    USB_INTR_ENABLE = 0;
128
    USB_INTR_CFG = 0;       /* also reset config bits */
129
    GICR = (1 << IVCE);     /* enable change of interrupt vectors */
130
    GICR = (0 << IVSEL);    /* move interrupts to application flash section */
131
/* We must go through a global function pointer variable instead of writing
132
 *  ((void (*)(void))0)();
133
 * because the compiler optimizes a constant 0 to "rcall 0" which is not
134
 * handled correctly by the assembler.
135
 */
136
    nullVector();
137
}
138
139
/* ------------------------------------------------------------------------ */
140
141
uchar   usbFunctionSetup(uchar data[8])
142
{
143
usbRequest_t    *rq = (void *)data;
144
uchar           len = 0;
145
static uchar    replyBuffer[4];
146
147
    usbMsgPtr = replyBuffer;
148
    if(rq->bRequest == USBASP_FUNC_TRANSMIT){   /* emulate parts of ISP protocol */
149
        uchar rval = 0;
150
        usbWord_t address;
151
        address.bytes[1] = rq->wValue.bytes[1];
152
        address.bytes[0] = rq->wIndex.bytes[0];
153
        if(rq->wValue.bytes[0] == 0x30){        /* read signature */
154
            rval = rq->wIndex.bytes[0] & 3;
155
            rval = signatureBytes[rval];
156
#if HAVE_EEPROM_BYTE_ACCESS
157
        }else if(rq->wValue.bytes[0] == 0xa0){  /* read EEPROM byte */
158
            rval = eeprom_read_byte((void *)address.word);
159
        }else if(rq->wValue.bytes[0] == 0xc0){  /* write EEPROM byte */
160
            eeprom_write_byte((void *)address.word, rq->wIndex.bytes[1]);
161
#endif
162
#if HAVE_CHIP_ERASE
163
        }else if(rq->wValue.bytes[0] == 0xac && rq->wValue.bytes[1] == 0x80){  /* chip erase */
164
            addr_t addr;
165
            for(addr = 0; addr < FLASHEND + 1 - 2048; addr += SPM_PAGESIZE) {
166
                /* wait and erase page */
167
                DBG1(0x33, 0, 0);
168
#   ifndef NO_FLASH_WRITE
169
                boot_spm_busy_wait();
170
                cli();
171
                boot_page_erase(addr);
172
                sei();
173
#   endif
174
            }
175
#endif
176
        }else{
177
            /* ignore all others, return default value == 0 */
178
        }
179
        replyBuffer[3] = rval;
180
        len = 4;
181
    }else if(rq->bRequest == USBASP_FUNC_ENABLEPROG){
182
        /* replyBuffer[0] = 0; is never touched and thus always 0 which means success */
183
        len = 1;
184
    }else if(rq->bRequest >= USBASP_FUNC_READFLASH && rq->bRequest <= USBASP_FUNC_SETLONGADDRESS){
185
        currentAddress.w[0] = rq->wValue.word;
186
        if(rq->bRequest == USBASP_FUNC_SETLONGADDRESS){
187
#if (FLASHEND) > 0xffff
188
            currentAddress.w[1] = rq->wIndex.word;
189
#endif
190
        }else{
191
            bytesRemaining = rq->wLength.bytes[0];
192
            /* if(rq->bRequest == USBASP_FUNC_WRITEFLASH) only evaluated during writeFlash anyway */
193
            isLastPage = rq->wIndex.bytes[1] & 0x02;
194
#if HAVE_EEPROM_PAGED_ACCESS
195
            currentRequest = rq->bRequest;
196
#endif
197
            len = 0xff; /* hand over to usbFunctionRead() / usbFunctionWrite() */
198
        }
199
#if BOOTLOADER_CAN_EXIT
200
    }else if(rq->bRequest == USBASP_FUNC_DISCONNECT){
201
        requestBootLoaderExit = 1;      /* allow proper shutdown/close of connection */
202
#endif
203
    }else{
204
        /* ignore: USBASP_FUNC_CONNECT */
205
    }
206
    return len;
207
}
208
209
uchar usbFunctionWrite(uchar *data, uchar len)
210
{
211
uchar   isLast;
212
213
    DBG1(0x31, (void *)&currentAddress.l, 4);
214
    if(len > bytesRemaining)
215
        len = bytesRemaining;
216
    bytesRemaining -= len;
217
    isLast = bytesRemaining == 0;
218
    if(currentRequest >= USBASP_FUNC_READEEPROM){
219
        uchar i;
220
        for(i = 0; i < len; i++){
221
            eeprom_write_byte((void *)(currentAddress.w[0]++), *data++);
222
        }
223
    }else{
224
        uchar i;
225
        for(i = 0; i < len;){
226
#if !HAVE_CHIP_ERASE
227
            if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0){    /* if page start: erase */
228
                DBG1(0x33, 0, 0);
229
#   ifndef NO_FLASH_WRITE
230
                cli();
231
                boot_page_erase(CURRENT_ADDRESS);   /* erase page */
232
                sei();
233
                boot_spm_busy_wait();               /* wait until page is erased */
234
#   endif
235
            }
236
#endif
237
            i += 2;
238
            DBG1(0x32, 0, 0);
239
            cli();
240
            boot_page_fill(CURRENT_ADDRESS, *(short *)data);
241
            sei();
242
            CURRENT_ADDRESS += 2;
243
            data += 2;
244
            /* write page when we cross page boundary or we have the last partial page */
245
            if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0 || (isLast && i >= len && isLastPage)){
246
                DBG1(0x34, 0, 0);
247
#ifndef NO_FLASH_WRITE
248
                cli();
249
                boot_page_write(CURRENT_ADDRESS - 2);
250
                sei();
251
                boot_spm_busy_wait();
252
                cli();
253
                boot_rww_enable();
254
                sei();
255
#endif
256
            }
257
        }
258
        DBG1(0x35, (void *)&currentAddress.l, 4);
259
    }
260
    return isLast;
261
}
262
263
uchar usbFunctionRead(uchar *data, uchar len)
264
{
265
uchar   i;
266
267
    if(len > bytesRemaining)
268
        len = bytesRemaining;
269
    bytesRemaining -= len;
270
    for(i = 0; i < len; i++){
271
        if(currentRequest >= USBASP_FUNC_READEEPROM){
272
            *data = eeprom_read_byte((void *)currentAddress.w[0]);
273
        }else{
274
            *data = pgm_read_byte((void *)CURRENT_ADDRESS);
275
        }
276
        data++;
277
        CURRENT_ADDRESS++;
278
    }
279
    return len;
280
}
281
282
/* ------------------------------------------------------------------------ */
283
284
static void initForUsbConnectivity(void)
285
{
286
uchar   i = 0;
287
288
    usbInit();
289
    /* enforce USB re-enumerate: */
290
    usbDeviceDisconnect();  /* do this while interrupts are disabled */
291
    while(--i){         /* fake USB disconnect for > 250 ms */
292
        wdt_reset();
293
        _delay_ms(1);
294
    }
295
    usbDeviceConnect();
296
    sei();
297
}
298
299
int __attribute__((noreturn)) main(void)
300
{
301
    /* initialize  */
302
    wdt_disable();      /* main app may have enabled watchdog */
303
    bootLoaderInit();
304
    odDebugInit();
305
    DBG1(0x00, 0, 0);
306
  
307
#ifndef NO_FLASH_WRITE
308
    GICR = (1 << IVCE);  /* enable change of interrupt vectors */
309
    GICR = (1 << IVSEL); /* move interrupts to boot flash section */
310
#endif
311
    if(bootLoaderCondition()){
312
        uchar i = 0, j = 0;
313
        initForUsbConnectivity();
314
        do{
315
            usbPoll();
316
#if BOOTLOADER_CAN_EXIT
317
            if(requestBootLoaderExit){
318
                if(--i == 0){
319
                    if(--j == 0)
320
                        break;
321
                }
322
            }
323
#endif
324
        }while(bootLoaderCondition());  /* main event loop */
325
    }
326
    leaveBootloader();
327
}
328
329
/* ------------------------------------------------------------------------ */

Makefile:
1
# Name: Makefile
2
# Project: USBaspLoader
3
# Author: Christian Starkjohann
4
# Creation Date: 2007-12-10
5
# Tabsize: 4
6
# Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
7
# License: GNU GPL v2 (see License.txt)
8
# This Revision: $Id: Makefile 798 2010-07-27 17:29:28Z cs $
9
10
###############################################################################
11
# Configure the following variables according to your AVR.
12
# Program the device with
13
#     make fuse    # to set the clock generator, boot section size etc.
14
#     make flash   # to load the boot loader into flash
15
#     make lock    # to protect the boot loader from overwriting
16
17
F_CPU = 16000000
18
DEVICE = atmega32
19
# BOOTLOADER_ADDRESS is 1800 for 8k devices, 3800 for 16k and 7800 for 32k.
20
BOOTLOADER_ADDRESS = 7800
21
FUSEOPT = $(FUSEOPT_32)
22
LOCKOPT = -U lock:w:0x2f:m
23
24
PROGRAMMER = -c stk500v2 -P avrdoper
25
# PROGRAMMER contains AVRDUDE options to address your programmer
26
27
FUSEOPT_8 = -U hfuse:w:0xc0:m -U lfuse:w:0x9f:m
28
FUSEOPT_88 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m
29
FUSEOPT_168 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m
30
FUSEOPT_32 = -U lfuse:w:0x7f:m -U hfuse:w:0xda:m 
31
FUSEOPT_328 = -U lfuse:w:0xf7:m -U hfuse:w:0xda:m -U efuse:w:0x03:m
32
# You may have to change the order of these -U commands.
33
34
#---------------------------------------------------------------------
35
# ATMega8
36
#---------------------------------------------------------------------
37
# Fuse high byte:
38
# 0xc0 = 1 1 0 0   0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800)
39
#        ^ ^ ^ ^   ^ ^ ^------ BOOTSZ0
40
#        | | | |   | +-------- BOOTSZ1
41
#        | | | |   + --------- EESAVE (preserve EEPROM over chip erase)
42
#        | | | +-------------- CKOPT (full output swing)
43
#        | | +---------------- SPIEN (allow serial programming)
44
#        | +------------------ WDTON (WDT not always on)
45
#        +-------------------- RSTDISBL (reset pin is enabled)
46
# Fuse low byte:
47
# 0x9f = 1 0 0 1   1 1 1 1
48
#        ^ ^ \ /   \--+--/
49
#        | |  |       +------- CKSEL 3..0 (external >8M crystal)
50
#        | |  +--------------- SUT 1..0 (crystal osc, BOD enabled)
51
#        | +------------------ BODEN (BrownOut Detector enabled)
52
#        +-------------------- BODLEVEL (2.7V)
53
#---------------------------------------------------------------------
54
# ATMega88, ATMega168
55
#---------------------------------------------------------------------
56
# Fuse extended byte:
57
# 0x00 = 0 0 0 0   0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800)
58
#                    \+/
59
#                     +------- BOOTSZ (00 = 2k bytes)
60
# Fuse high byte:
61
# 0xd6 = 1 1 0 1   0 1 1 0
62
#        ^ ^ ^ ^   ^ \-+-/
63
#        | | | |   |   +------ BODLEVEL 0..2 (110 = 1.8 V)
64
#        | | | |   + --------- EESAVE (preserve EEPROM over chip erase)
65
#        | | | +-------------- WDTON (if 0: watchdog always on)
66
#        | | +---------------- SPIEN (allow serial programming)
67
#        | +------------------ DWEN (debug wire enable)
68
#        +-------------------- RSTDISBL (reset pin is enabled)
69
# Fuse low byte:
70
# 0xdf = 1 1 0 1   1 1 1 1
71
#        ^ ^ \ /   \--+--/
72
#        | |  |       +------- CKSEL 3..0 (external >8M crystal)
73
#        | |  +--------------- SUT 1..0 (crystal osc, BOD enabled)
74
#        | +------------------ CKOUT (if 0: Clock output enabled)
75
#        +-------------------- CKDIV8 (if 0: divide by 8)
76
#---------------------------------------------------------------------
77
# ATMega328P
78
#---------------------------------------------------------------------
79
# Fuse extended byte:
80
# 0x03 = - - - -   - 0 1 1
81
#                    \-+-/
82
#                      +------ BODLEVEL 0..2 (011 = 4.3V)
83
# Fuse high byte:
84
# 0xda = 1 1 0 1   1 0 1 0 <-- BOOTRST (0 = jump to bootloader at start)
85
#        ^ ^ ^ ^   ^ \+/
86
#        | | | |   |  +------- BOOTSZ 0..1 (01 = 2KB starting at 0x7800)
87
#        | | | |   + --------- EESAVE (don't preserve EEPROM over chip erase)
88
#        | | | +-------------- WDTON (1 = watchdog disabled at start)
89
#        | | +---------------- SPIEN (0 = allow serial programming)
90
#        | +------------------ DWEN (1 = debug wire disable)
91
#        +-------------------- RSTDISBL (1 = reset pin is enabled)
92
# Fuse low byte:
93
# 0xf7 = 1 1 1 1   0 1 1 1
94
#        ^ ^ \ /   \--+--/
95
#        | |  |       +------- CKSEL 3..0 (0111 = external full-swing crystal)
96
#        | |  +--------------- SUT 1..0 (11 = startup time 16K CK/14K + 65ms)
97
#        | +------------------ CKOUT (1 = clock output disabled)
98
#        +-------------------- CKDIV8 (1 = do not divide clock by 8)
99
100
101
###############################################################################
102
103
# Tools:
104
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE)
105
CC = avr-gcc
106
107
# Options:
108
DEFINES = #-DDEBUG_LEVEL=2
109
# Remove the -fno-* options when you use gcc 3, it does not understand them
110
CFLAGS = -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) $(DEFINES)
111
LDFLAGS = -Wl,--relax,--gc-sections -Wl,--section-start=.text=$(BOOTLOADER_ADDRESS)
112
113
OBJECTS =  usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
114
115
# symbolic targets:
116
all: main.hex
117
118
.c.o:
119
  $(CC) $(CFLAGS) -c $< -o $@
120
121
.S.o:
122
  $(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@
123
# "-x assembler-with-cpp" should not be necessary since this is the default
124
# file type for the .S (with capital S) extension. However, upper case
125
# characters are not always preserved on Windows. To ensure WinAVR
126
# compatibility define the file type manually.
127
128
.c.s:
129
  $(CC) $(CFLAGS) -S $< -o $@
130
131
flash:  all
132
  $(AVRDUDE) -U flash:w:main.hex:i
133
134
readflash:
135
  $(AVRDUDE) -U flash:r:read.hex:i
136
137
fuse:
138
  $(AVRDUDE) $(FUSEOPT)
139
140
lock:
141
  $(AVRDUDE) $(LOCKOPT)
142
143
read_fuses:
144
  $(UISP) --rd_fuses
145
146
clean:
147
  rm -f main.hex main.bin *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
148
149
# file targets:
150
main.bin:  $(OBJECTS)
151
  $(CC) $(CFLAGS) -o main.bin $(OBJECTS) $(LDFLAGS)
152
153
main.hex:  main.bin
154
  rm -f main.hex main.eep.hex
155
  avr-objcopy -j .text -j .data -O ihex main.bin main.hex
156
  avr-size main.hex
157
158
disasm:  main.bin
159
  avr-objdump -d main.bin
160
161
cpp:
162
  $(CC) $(CFLAGS) -E main.c
163
164
# Special rules for generating hex files for various devices and clock speeds
165
ALLHEXFILES = hexfiles/mega8_12mhz.hex hexfiles/mega8_15mhz.hex hexfiles/mega8_16mhz.hex \
166
  hexfiles/mega88_12mhz.hex hexfiles/mega88_15mhz.hex hexfiles/mega88_16mhz.hex hexfiles/mega88_20mhz.hex\
167
  hexfiles/mega168_12mhz.hex hexfiles/mega168_15mhz.hex hexfiles/mega168_16mhz.hex hexfiles/mega168_20mhz.hex\
168
  hexfiles/mega328p_12mhz.hex hexfiles/mega328p_15mhz.hex hexfiles/mega328p_16mhz.hex hexfiles/mega328p_20mhz.hex
169
170
allhexfiles: $(ALLHEXFILES)
171
  $(MAKE) clean
172
  avr-size hexfiles/*.hex
173
174
$(ALLHEXFILES):
175
  @[ -d hexfiles ] || mkdir hexfiles
176
  @device=`echo $@ | sed -e 's|.*/mega||g' -e 's|_.*||g'`; \
177
  clock=`echo $@ | sed -e 's|.*_||g' -e 's|mhz.*||g'`; \
178
  addr=`echo $$device | sed -e 's/\([0-9]\)8/\1/g' | awk '{printf("%x", ($$1 - 2) * 1024)}'`; \
179
  echo "### Make with F_CPU=$${clock}000000 DEVICE=atmega$$device BOOTLOADER_ADDRESS=$$addr"; \
180
  $(MAKE) clean; \
181
  $(MAKE) main.hex F_CPU=$${clock}000000 DEVICE=atmega$$device BOOTLOADER_ADDRESS=$$addr DEFINES=-DUSE_AUTOCONFIG=1
182
  mv main.hex $@

Die anderen Dateien wurden nicht geändert.

Fuses:
High Fuse 0xDA
Low Fuse 0x7F

avrdude: Device signature = 0x1e9502

Ausgabe von WINAVR:
1
> "make.exe" all
2
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=atmega32 -DF_CPU=16000000  -x assembler-with-cpp -c usbdrv/usbdrvasm.s -o usbdrv/usbdrvasm.o
3
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=atmega32 -DF_CPU=16000000  -c usbdrv/oddebug.c -o usbdrv/oddebug.o
4
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=atmega32 -DF_CPU=16000000  -c main.c -o main.o
5
usbdrv/usbdrv.h:213: warning: 'usbFunctionDescriptor' used but never defined
6
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -mmcu=atmega32 -DF_CPU=16000000  -o main.bin usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o -Wl,--relax,--gc-sections -Wl,--section-start=.text=7800
7
rm -f main.hex main.eep.hex
8
avr-objcopy -j .text -j .data -O ihex main.bin main.hex
9
avr-size main.hex
10
   text     data      bss      dec      hex  filename
11
      0     1966        0     1966      7ae  main.hex
12
13
> Process Exit Code: 0
14
> Time Taken: 00:02

P.S.: Das CRC-232 Projekt habe ich bereits erfolgreich auf dem selben 
Board zum Laufen gebracht, an der Hardware sollte es demnach nicht 
liegen.

von Dead D. (deaddealer)


Lesenswert?

ähh, kleiner Nachtrag:

Bin jetzt total verwirrt. Hatte die Bootloadergröße nicht korrekt 
eingestellt auf dem AVR selbst.
Nach der Korrektur und setzen des Jumpers meldete sich die Labnode als 
USBasp an! Aber schon nach dem Auslesen der Signatur kam wieder die 
übliche Fehlermeldung "Unbekanntes Gerät" bla bla ... Auch ein erneutes 
Anstecken brachte nur die Fehlermeldung rauß.
Also nochmal den Bootloader flashen, und siehe da, er macht wieder was 
er soll. Diesmal hatte ich direkt in SinaProg die CDC-232 Firmware 
ausgewählt und geflasht... und DAS hat er sogar richtig gemacht! Ich 
kann über Hterm wie sonst auch z.B. Textdateien mit 56 kbaud an Putty 
verschicken und es kommt alles an wie es soll.

Jetzt ist die Frage: Warum kann ich mit dem Bootloader nur eine Aktion 
machen und danach ist er unbrauchbar? Die Lock Fuses sind auf 0x2F 
gesetzt, er dürfte also nicht irgendwie was am Bootloader rumfuschen.

von pommes s. (pommes_s)


Lesenswert?

Dead Dealer schrieb:
> Hatte die Bootloadergröße nicht korrekt
> eingestellt auf dem AVR selbst.

Das finde ich auf verwirrend. im Makefile von USBaspLoader
steht: hfuse: DA -> 1k für bootloader, also zu klein.

> Jetzt ist die Frage: Warum kann ich mit dem Bootloader nur eine Aktion
> machen und danach ist er unbrauchbar?

Ich habe einen atmega328 und da ist es genau so.
Sobald man mit avrdude via USBaspLoader ein Programm lädt wird der 
Bootloader offenbar überschrieben.  :-(

von Oliver J. (skriptkiddy)


Lesenswert?

pommes s. schrieb:
> Ich habe einen atmega328 und da ist es genau so.
> Sobald man mit avrdude via USBaspLoader ein Programm lädt wird der
> Bootloader offenbar überschrieben.  :-(

Ich hatte mit einem Bootloader auch mal solch ein Problem. Nur eine 
Schreibaktion und dann lief nur das geflashte Programm - kein 
Lebenszeichen vom Bootloader.

Der Grund war der:
Falscher Restvektor gefused. Der AVR startete immer bei 0x0000 aber der 
Bootloader liegt wesentlich weiter hinten im Flash. Wenn nur der 
Bootloader gelfasht ist, dann steht vorne alles voll mit 0xffff. Das 
sind lauter "SBRS r31, 7". Der AVR führt also nach Flashen des 
Bootloaders von Adresse 0x0000 an solange nichts sinnvolles aus, bis der 
PC dann am Bootloader ankommt und schließlich diesen ausführt. Die 
logische Konsequenz davon ist, wenn man nun ein Programm mit dem 
Bootloader flasht und sich etwas Anderes (Endlosschleife) als nur 
sinnlose Befehle vor dem Bootloader befindet, dann wird der natürlich 
nicht mehr ausgeführt.

Gruß Oliver

von pommes s. (pommes_s)


Lesenswert?


von marixstorm (Gast)


Lesenswert?

Mit der github Version https://github.com/baerwolf/USBaspLoader
sollten nun die meisten ATmegas funktionieren.
Ggf. probiert das mal...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.