USBaspLoader and ATmega32

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
booble

USBaspLoader and ATmega32

Post by booble » Mon Jul 28, 2008 12:41 pm

Hello, everybody. I got a trouble with usbasploader and atmega32. I wired D+ to PD3(INT1), D- to PD6, jumper to PD7. My board doen't recognized by pc. I have added some code to main.c, so i can see when controller is rebooting and so on. I see, that after board starts it behaves ok, it recognizes the jumper position and so on. But when PC is sending anything over D+ line - the board reboots. I read MCUCSR register and it is filled by zeroes after such reboot. If i disable interrupt handling board dont reboots, but doesn't work too. I have added some asm code to interrupt handler, but that code never executes.
I think that after an interrupt on D+ controller jumps not to INT1 handler, but to 0 or other place. The datasheet says that INT1 vector position is BOOTLOADER_START+0x04, INT0 - +0x02 and so on. But i did avr-objdump -d main.bin and saw that INT1 vector was placed at +0x08 position.
I built my project with latest gcc-avr in Gnetoo Linux and with winavr gcc-3.4.6 - results are absolutly same. Also i tried to simulate atmega32 in Proteus, but it reboots after any activity on D+ line.
I use 5V power source, tried to solder zener diodes(3V6), pull-down resistor(1M1) to D+, but that didn't help. Tried to use another atmega32, but results stay the same. I googled for a long time, but nothing helps :(
Unfortunatly, i cant debug avr-usb driver, because my usart over max232 don't works too :) I'll try to use INT0 tomorrow.
Here are relevant parts of my project:
usbconfig.h:
#define USB_INTR_CFG MCUCR
#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11))
#define USB_INTR_CFG_CLR 0
#define USB_INTR_ENABLE GICR
#define USB_INTR_ENABLE_BIT INT1
#define USB_INTR_PENDING GIFR
#define USB_INTR_PENDING_BIT INTF1
#define USB_INTR_VECTOR SIG_INTERRUPT1 //tried SIG_INTERRUPT0 to place handler at +0x04 address, but no success

bootloaderconfig.h:
#define USB_CFG_IOPORTNAME D
#define USB_CFG_DMINUS_BIT 6
#define USB_CFG_DPLUS_BIT 3
#define JUMPER_BIT 7
static inline void bootLoaderInit(void)
{
PORTD |= (1 << JUMPER_BIT); /* activate pull-up */
//if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */
// leaveBootloader();
MCUCSR = 0; /* clear all reset flags for next time */
}

Makefile:
F_CPU = 16000000
DEVICE = atmega32
BOOTLOADER_ADDRESS = 7800
FUSEOPT = $(FUSEOPT_168)
LOCKOPT = -U lock:w:0x2f:m

PROGRAMMER = -c stk500v2 -P avrdoper
# PROGRAMMER contains AVRDUDE options to address your programmer

FUSEOPT_32 = -U hfuse:w:0xc0:m -U lfuse:w:0x8f:m
FUSEOPT_8 = -U hfuse:w:0xc0:m -U lfuse:w:0x9f:m
FUSEOPT_88 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m
FUSEOPT_168 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m

main.c:
/* DEBUG */
// enable PB1 as output
#define LED1_INIT DDRD|=_BV(PD4)
// // led on, pin=0
#define LED1_OFF PORTD&=~_BV(PD4)
// // led off, pin=1
#define LED1_ON PORTD|=_BV(PD4)
// enable PB1 as output
#define LED2_INIT DDRD|=_BV(PD5)
// // led on, pin=0
#define LED2_OFF PORTD&=~_BV(PD5)
// // led off, pin=1
#define LED2_ON PORTD|=_BV(PD5)

int main(void)
{
LED1_INIT;
LED2_INIT;
LED1_ON;
LED2_ON;
_delay_ms(200);

/* initialize */
bootLoaderInit();
odDebugInit();
DBG1(0x00, 0, 0);
#ifndef NO_FLASH_WRITE
GICR = (1 << IVCE); /* enable change of interrupt vectors */
GICR = (1 << IVSEL); /* move interrupts to boot flash section */
#endif
if(bootLoaderCondition()){
uint i = 0;
initForUsbConnectivity();
do{
LED2_OFF;
usbPoll();
#if BOOTLOADER_CAN_EXIT
if(requestBootLoaderExit){
if(--i == 0)
break;
}
#endif
}while(bootLoaderCondition()); /* main event loop */
}
LED1_OFF;
_delay_ms(200);
leaveBootloader();
return 0;
}
/*
After start we see 2 leds, wait 200ms. If led2 is on and led1 - off it means that bootloader condition don't met. If led1 is on and led2 is off - we are in main loop. So if we reboot somewhere during this loop we will see two leds on again.
*/


main.bin:
main.bin: file format elf32-avr

Disassembly of section .text:

00007800 <__vectors>:
7800: 0c 94 53 3c jmp 0x78a6 <__init>
7804: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7808: 0c 94 8d 3c jmp 0x791a <__vector_2>
780c: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7810: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7814: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7818: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
781c: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7820: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7824: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7828: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
782c: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7830: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7834: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7838: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
783c: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7840: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7844: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7848: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
784c: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
7850: 0c 94 6e 3c jmp 0x78dc <__bad_interrupt>
********************************************

0000791a <__vector_2>:
791a: cf 93 push r28
791c: cf b7 in r28, 0x3f ; 63
791e: cf 93 push r28

00007920 <waitForJ>:
7920: 86 9b sbis 0x10, 6 ; 16
7922: fe cf rjmp .-4 ; 0x7920 <waitForJ>

****************************************************

booble

USBaspLoader and ATmega32

Post by booble » Mon Jul 28, 2008 9:27 pm

Tried to use INT0 instead of INT1. Soldered PD3 to PD2 and disabled PD3. Than i modified usbconfig.h to reflect changes. Same behavior. It reboots continuosly when there is some activity on D+. I dont't know what to do. I tried almost everything, but bootloader doesn't work :(

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Tue Jul 29, 2008 5:51 pm

Please start with a less complex example, something which does not require the boot section and switching the interrupt vectors. When that works, you can at least be sure that the hardware infrastructure is OK.

booble

USBaspLoader and ATmega32

Post by booble » Tue Jul 29, 2008 10:33 pm

Thank you for your advice, Christian. I configured PowerSwitch, flashed by board and it works! I didn't try to use PowerSwitch, but it is detected by my laptop and lsusb -v tells some information. So it works.
Then i tried to use INT1 and it works too.
Here are interrupt vectors table:
00000000 <__vectors>:
0: 0c 94 57 00 jmp 0xae ; 0xae <__ctors_end>
4: 0c 94 74 00 jmp 0xe8 ; 0xe8 <__bad_interrupt>
8: 0c 94 98 01 jmp 0x330 ; 0x330 <__vector_2>
c: 0c 94 74 00 jmp 0xe8 ; 0xe8 <__bad_interrupt>
10: 0c 94 74 00 jmp 0xe8 ; 0xe8 <__bad_interrupt>

You see, that jmp takes 4 bytes, but datasheet tells that jmp in this table must take 2 bytes. I think i don't really understand interrupts or it is an error in datasheet. Anyway, avr-usb driver works perfectly, but USBaspLoader don't.

booble

USBaspLoader and ATmega32

Post by booble » Tue Jul 29, 2008 10:53 pm

Just made these changes to bootloader code:
Makefile:
BOOTLOADER_ADDRESS = 0

main.c:
//Commented code which moves interrupt table to bootloader section
bootLoaderInit();
odDebugInit();
DBG1(0x00, 0, 0);
#ifndef NO_FLASH_WRITE
//GICR = (1 << IVCE); /* enable change of interrupt vectors */
//GICR = (1 << IVSEL); /* move interrupts to boot flash section */
#endif

So now booloader boots not like bootloader, but like ordinary program. Of course in such state it can't load a program to flash. But it works! It is recognised by laptop. I don't know how to make bootloader to make it to work. I can't see where are interrupt vectors are really situated after movement.

booble

USBaspLoader and ATmega32

Post by booble » Tue Jul 29, 2008 11:17 pm

Hello again. I discovered that i've made a big mistake. All sizes in datasheet are given in words and word size is 2 bytes. So BOOTLOADER_ADDRESS should be 7800, because this value is given in bytes. I thought that maximum bootloader size is 2048 bytes, but it is 2048 words, or 4096 bytes, So BOOTSZ1 and 0 bits in high fuse byte should be 0 and 1 respectivly. It means that atmega started execution from 4096 byte from flash end, but bootloader was situated at 2048 bytes from flash end. And in this situation bootloader starts ok and only thing that don't work is interrupt handlers. I think atmega startt execution at 4096 from flashend, executes 2048 zeroes(may be they are omitted or treated as nops) and then starts execution of bootloader.
So i fixed hfuse byte and my bootloader is detected from pc. Thank you, Christian, for your help!

suriva.25

question about source code bootloader for atmega32

Post by suriva.25 » Mon Sep 01, 2008 10:57 am

hi all. can somebody guide me to build my own bootloader for atmega32??

i need to porting avr jtag isp from http://www.floppyspongeonline.com/autom ... tagisp.php

but i would use atmega32

thanks

Post Reply