Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
smileymicros
PostPosted: Jun 24, 2005 - 03:19 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

There have been a few threads going back to 2001 where an AVRProg error says that at such and such address it expected 0x940c but got so and so. The number ox940c just happens to be the number at the first address location of the bootloader, but these folks aren't trying to download the bootloader. This pops up in the Butterfly a lot, but other threads have it on the ATmega16 and 32.

One definite cause is trying to download code larger than the space available so AVRProg attempts to write to the bootloader section which doesn't happen and when it goes to verfiy the write it sees that 0x940c where it expected whatever it was trying to write there.

But there are some folks who are getting this error when they are writing small programs which makes me suspect --
1. They have set something so that the AVRProg thinks it's got a larger program and trys to overwrite the boot section.
2. They have done something that makes their small program very large so the AVRProg is doing what it is told.
3. They have set something that tells AVRProg to alias the code start section of 0x0000 to the bootloader start section address of ?0x1c00? (I don't remember that address)

So they could be setting something wrong in the makefile or they could be setting something wrong in the compiler setup or it could be something simple that we are all missing.

Any other possibilities?
Any ideas of avenues to explore?

Woof...
Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 04:42 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

Quote:
The number ox940c just happens to be the number at the first address location of the bootloader

...For what AVR?

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
dwh3
PostPosted: Jun 24, 2005 - 05:14 PM
Wannabe


Joined: Nov 18, 2004
Posts: 51


In this case I think he is talking about the butterfly
 
 View user's profile Send private message  
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 05:28 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

dwh3 wrote:
In this case I think he is talking about the butterfly

Oh, sorry... but this 0x940C seems familiar somehow...
I don't recall very well where I have seen this hex number... maybe @ATmega64/128... first word in the flash.

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
smileymicros
PostPosted: Jun 24, 2005 - 05:34 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

Urmm... like I say in the first paragraph, searching the forum shows this magic number for the Butterfly, the Atmega16 and 32.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
theusch
PostPosted: Jun 24, 2005 - 07:09 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 26115
Location: Wisconsin USA

groenhen wrote:
Quote:
The number ox940c just happens to be the number at the first address location of the bootloader

...For what AVR?


Probably for all of them with a JMP instruction (if JMP is used as the instruction at the interrupt vector). Example:

Code:
         ;INTERRUPT VECTORS
000000 940c 03da    JMP  __RESET
000002 940c 0000    JMP  0x00
 
 View user's profile Send private message  
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 07:31 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

Quote:
Probably for all of them with a JMP instruction (if JMP is used as the instruction at the interrupt vector).

Yep... correct, if JMP...
But, there are at least two other possibilities:
Here's one (with RJMP):
Code:
         ;INTERRUPT VECTORS
000000 c065         RJMP __RESET
000001 cffe         RJMP 0x00

And the second possibility is... Question
[s#it... I don't recall now... sorry]

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
theusch
PostPosted: Jun 24, 2005 - 08:03 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 26115
Location: Wisconsin USA

>>Typically<<, vector tables (especially compiler generated) will tend to have a series of JMP instructions on AVRs with more than 8kb of flash, and RJMP in AVRs with 8kb of flash or less. When writing your own programs you are, of course, free to put whatever instruction you please at any loaction.

Smiley's point (and it sounds like a good one) is that the reported failures may well have something to do with trying to overwrite the bootloader's vector table.

So the answer to your question "for what AVR?" remains the same:
Quote:

...all of them with a JMP instruction (if JMP is used as the instruction at the interrupt vector).


Lee
 
 View user's profile Send private message  
Reply with quote Back to top
glitch
PostPosted: Jun 24, 2005 - 08:17 PM
Raving lunatic


Joined: Jan 12, 2002
Posts: 7832
Location: Canada

theusch wrote:
>>Typically<<, vector tables (especially compiler generated) will tend to have a series of JMP instructions on AVRs with more than 8kb of flash, and RJMP in AVRs with 8kb of flash or less. When writing your own programs you are, of course, free to put whatever instruction you please at any loaction.


Not quite, as there is one limitation. AVR's with less than 8kb of flash have a vector table that has only one word reserved for each entry (rjmp is the only real option here), while those with more than 8kb have 2 words per entry (thus allowing for jmp, instead of rjmp). Technically one could use RJMP here as well, as long as they remember to skip the unused word, or fill it with a NOP.

As for >>ANY<< code, technically one could place normal code in the unused areas of the table as well, but this is not an advisable practise.

groenhen wrote:
Quote:
Probably for all of them with a JMP instruction (if JMP is used as the instruction at the interrupt vector).

Yep... correct, if JMP...
But, there are at least two other possibilities:
Here's one (with RJMP):
Code:
         ;INTERRUPT VECTORS
000000 c065         RJMP __RESET
000001 cffe         RJMP 0x00

And the second possibility is... Question
[s#it... I don't recall now... sorry]


You're probably thinking of IJMP as the 3rd option. Use of IJMP in an interrupt vector table is not advisable, as it relies on the contents of the Z register being correct.

CALL, RCALL, and ICALL are not good options, because they would require a 2nd return, so DO NOT use these in your vector table. Though they may be viable options in a software vector table, but I doubt it.


Last edited by glitch on Jun 24, 2005 - 08:34 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 08:21 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

Quote:
Smiley's point (and it sounds like a good one) is that the reported failures may well have something to do with trying to overwrite the bootloader's vector table.

1) Maybe the application is too large to fit in the app. section...
2) Maybe they have instructed the compiler to put some functions in the BL space. (I do have a project where one function is located in the BL section).

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 08:35 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

Hi glitch!
Quote:
You're probably thinking of IJMP as the 3rd option. Use of IJMP in an interrupt vector table is not advisable, as it relies on the contents of the Z register being correct.

Hehe, I did recall... I wasn't thinking of IJMP...
I was thinking of using RETI.

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
groenhen
PostPosted: Jun 24, 2005 - 08:39 PM
Posting Freak


Joined: Apr 09, 2005
Posts: 1387
Location: Belgium

Quote:
Though they may be viable options in a software vector table, but I doubt it.

IV hijacking?... or what?

_________________
Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
glitch
PostPosted: Jun 24, 2005 - 08:44 PM
Raving lunatic


Joined: Jan 12, 2002
Posts: 7832
Location: Canada

groenhen wrote:
Hi glitch!
Quote:
You're probably thinking of IJMP as the 3rd option. Use of IJMP in an interrupt vector table is not advisable, as it relies on the contents of the Z register being correct.

Hehe, I did recall... I wasn't thinking of IJMP...
I was thinking of using RETI.


RETI will simply return you to the interrupted code without doing anything... this may not be a bad approach for unused vectors. Though it can still be dangerous, as you can get stuck in an infinite loop of INTERRUPT/RETI's if the particular interrupt that was accidentally enabled is level triggered. I will quite often flesh out all interrupt handlers, even the ones I don't plan on using, and have them disable their interrupt source if they ever get called. During debugging I will also have them log the misfire, so I can try to track down the source of the error.


Last edited by glitch on Jun 24, 2005 - 08:52 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
glitch
PostPosted: Jun 24, 2005 - 08:49 PM
Raving lunatic


Joined: Jan 12, 2002
Posts: 7832
Location: Canada

groenhen wrote:
Quote:
Though they may be viable options in a software vector table, but I doubt it.

IV hijacking?... or what?


No, this would allow for multiple entries to be called in sequence, if needed, since the return value will be the next vector entry. Think of a switch/case where for one value you perform one action, and want it to also be processed for the next entry as well. (ie no break statement at the end of the case) This is about the only possible use I can think of, and there are better ways of doing it. You cannot hijack an interrupt vector on an AVR, since the vector table is in flash, and not ram, so you cannot dynamically change the vector. (with the exception of using IJMP, but, as above, this has it's dangers)
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Jun 24, 2005 - 09:53 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

Back to the topic: what would be ways that a relative newbie doing what seem to be normal things like compiling and loading very simple programs could cause the error? I've seen several newbies get this error, have hacking fits and nearly quit then the problem goes away. They don't know what caused it nor what fixed it and neither do I. I'm guessing they are making an easy to make mistake, then floundering around until they try something different that works, then they don't do the 'easy mistake' any more. Then another newbie gets impaled by the same thing and I don't know what to tell them.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
fmannai
PostPosted: Jun 25, 2005 - 08:10 PM
Newbie


Joined: Jun 11, 2005
Posts: 7


I am one of the newbies and I agree with Smiley. Is there anything that a newbie can do to avoide writing in the bootloader's address. Or is there any way a newbie can check his or her source program for that error. Is that error from the compiler or from something in the flash of the butterfly ATmega169 ?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
BillH308
PostPosted: Aug 11, 2005 - 06:27 PM
Newbie


Joined: Jul 26, 2005
Posts: 15


This error message has nothing to do with the bootloader. Your butterfly has a lock on the application data. You try to program it, you think you did, and when it verifies it says error. It never programmed it thats why the verification failed. What your going to need to do is program the butterfly with the ISP interface, erase the device and make sure under lock bits there is no locks anywhere. Then you will need to reflash the device with the hex from atmel and your good to go.
 
 View user's profile Send private message  
Reply with quote Back to top
hgo
PostPosted: Aug 15, 2005 - 12:39 PM
Newbie


Joined: May 18, 2004
Posts: 4


I have about 50 students and I think maybe 20 of them had this problem. The problem showed up after a few weeks of programming.

I agree with BillH308, but the main question is: why does the lockbit change during programming via the bootloader?

Is there a flash security function, is it the voltage level, or is it the RC oscillator or what?
/Magnus
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Aug 15, 2005 - 03:06 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

okay, now i'm really scared. We are beginning to get this problem well characterized and it still seems a mystery. Either the AvrProg is doing something, or the bootloader is doing something, or a downloaded program is doing something, or -- the worse case -- something wierd is happening inside the AVR that causes this with no particular external influence.

I've submitted a question to the AVR technical folks and gotten no response. Either they don't know, don't care, or are hiding something.

If the bootloader is capable of spontaneously locking up and one needs an ISP to reset it, then the main reason I moved to AVR is gone and I have to rethink everything.

I hope we can get someone at Atmel to respond.

[EDIT 8/17/05] There is a guy at Atmel trying to replicate the problem. He says that there is not a known bug of having the lockbits set themselves. Stay tuned.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com


Last edited by smileymicros on Aug 17, 2005 - 02:59 PM; edited 1 time in total
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
lutecki
PostPosted: Aug 17, 2005 - 12:35 PM
Newbie


Joined: Feb 03, 2003
Posts: 5
Location: Poland

Hi.
I have similiar problem (getting message like this: Adress 0x0000, Expected 0x940c, received 0xffff). I'm using following code for bootloader (from DN032, slightly changed to work with Mega16):


;********** B O O T L O A D E R F O R A T m e g a 1 6 3 **********
;* File : AVRBoot2.asm (Include chip erase counter)
;* Version : 1.2
;* Compiler : AVR Studio
;* Target : ATmega163
;* Output size : 392 bytes

.equ DT = 0x75 ;Device Type = 0x66 (ATmega163)

;.equ DT = 0x82 ;STK500
;.equ DT = 0x74 ;AVR910


.equ SB1 = 0x1E ;Signature byte 1
.equ SB2 = 0x94 ;Signature byte 2
.equ SB3 = 0x03 ;Signature byte 3
;.equ UBR = 23 ;Baud rate = 19.200 bps with fCK = 7.3728 MHz
.equ UBR = 51 ;Baud rate = 19.200 bps with fCK = 16 MHz
;.equ UBR = 103 ;Baud rate = 9.600 bps with fCK = 16 MHz
.INCLUDE "m16def.inc" ;Include Register/Bit Definitions for the mega163

.org SECONDBOOTSTART ;($1F00) second boot. Block size is 512B



ldi R24,0xff ;zapisz do portu A 0xff - wlaczenie pull-up
out PORTA,R24

;sbic PINA,PINA0 ;Skip next instruction if PINC0 cleared
;sbic PINC,PINC0 ;Skip next instruction if PINC0 cleared

in R24,PINA
cpi R24,0x00
breq SKIP
rjmp FLASHEND+1 ;else normal execution from Reset (FLASHEND+1 = Address 0000)

; Programming mode
SKIP:
ldi R24,low(RAMEND)
ldi R25,high(RAMEND)
out SPL,R24
out SPH,R25 ;SP = RAMEND
ldi R24,UBR ;Baud rate = 19.200 bps
out UBRRL,R24
ldi R24,(1<<RXEN)|(1<<TXEN)
out UCSRB,R24 ;Enable receiver & transmitter, 8-bit mode

;-------------------------------------------------------------------------------
;L10
;-------------------------------------------------------------------------------
L10: rcall uartGet ;repeat (R16 = uartGet)
cpi R16,27 ;while (R16 == ESCAPE)
breq L10
cpi R16, 'a' ;if(R16=='a') 'a' = Autoincrement?
brne L12
ldi R16,'Y' ;Yes, autoincrement is quicker
rjmp L70 ;uartSend(R16)
;-------------------------------------------------------------------------------
;L12
;-------------------------------------------------------------------------------
L12: cpi R16,'A' ;else if(R16=='A') write address
brne L14
rcall uartGet
mov R27,R16 ;R27 = address high byte
rcall uartGet
mov R26,R16 ;R26 = address low byte
lsl R26 ;address=address<<1
rol R27 ;convert from byte address to word address
rjmp L68 ;uartSend('\r')

;-------------------------------------------------------------------------------
;L14
;-------------------------------------------------------------------------------
L14: cpi R16,'c' ;else if(R16=='c') write program memory, low byte
brne L16
rcall uartGet
mov R22,R16 ;R22 = data low byte
rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L16
;-------------------------------------------------------------------------------
L16: cpi R16,'C' ;else if(R16=='C') write program memory,high byte
brne L18
rcall uartGet
mov R23,R16 ;R23 = data high byte
movw R30,R26 ;Z pointer = address
movw R0,R22 ;R0&R1 = data
ldi R24,1 ;SPMCR = 0x01
out SPMCR,R24 ;page load (fill temporary buffer)
spm ;Store program memory
adiw R26,2 ;address=address+2
rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L18
;-------------------------------------------------------------------------------
L18: cpi R16,'e' ;else if(R16=='e') Chip erase
brne L28
; for(address=0; address < (2*SECONDBOOTSTART); address += (2*PAGESIZE))
clr R26 ;page_erase();
clr R27
rjmp L24
;-------------------------------------------------------------------------------
;L20
;-------------------------------------------------------------------------------
L20: movw R30,R26 ;Z-pointer = address
ldi R24,3 ;SPMCR = 0x03
out SPMCR,R24 ;page_erase
spm

SPM_WAIT: in R24, SPMCR
sbrc R24,PGERS ;czekaj na wykonanie zapisu
rjmp SPM_WAIT

subi R26,low(-2*PAGESIZE) ;address += (2*PAGESIZE)
sbci R27,high(-2*PAGESIZE)
;adiw R26,2*PAGESIZE
;-------------------------------------------------------------------------------
;L24
;-------------------------------------------------------------------------------
L24: ldi R24,low(2*SECONDBOOTSTART)
ldi R25,high(2*SECONDBOOTSTART)

cp R26,R24 ;address < Boot Flash address(byte address) 0x3E00 ?
cpc R27,R25
brlo L20

ldi R26,low(E2END-1) ;increment Chip Erase Counter located
ldi R27,high(E2END-1) ;at address E2END-1

movw R22,R26 ;Save Chip Erase Counter Address in R22
ldi R17,(1<<EERE) ;read EEPROM
rcall EepromTalk
mov R24,R16 ;R24 = Chip Erase Counter low byte
rcall EepromTalk
mov R25,R16 ;R25 = Chip Erase Counter high byte
adiw R24,1 ;counter ++
out EEDR,R24 ;EEDR = R24 Chip Erase Counter low byte
movw R26,R22 ;R26 = Chip Erase Counter Address
ldi R17,(1<<EEMWE)|(1<<EEWE) ;write EEPROM
rcall EepromTalk
out EEDR,R25 ;EEDR = R25 Chip Erase Counter high byte
rcall EepromTalk

rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L28
;-------------------------------------------------------------------------------
L28: cpi R16,'m' ;else if(R16== 'm') Write page
brne L34
movw R30,R26 ;Z-pointer = address
ldi R24,5 ;SPMCR = 0x05 Write page
out SPMCR,R24
spm ;Store program memory
SPM_WAIT_1: in R24, SPMCR ;
sbrc R24,PGERS ;czekaj na wykonanie zapisu!!!!!!!!!
rjmp SPM_WAIT_1 ;
;-------------------------------------------------------------------------------
;L32
;-------------------------------------------------------------------------------
L32: rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L34
;-------------------------------------------------------------------------------
L34:
cpi R16,'P' ;else if(R16=='P') Enter programming mode
breq L32 ;uartSend('\r')
;rjmp RESET

cpi R16,'L' ;else if(R16=='L') Leave programming mode
breq L32 ;uartSend('\r')

cpi R16,'p' ;else if (R16=='p') Return programmer type
brne L38

ldi R16,'S' ;uartSend('S') Serial
rjmp L70 ;uartSend(R16)
;-------------------------------------------------------------------------------
;L38
;-------------------------------------------------------------------------------
L38: cpi R16,'R' ;else if(R16=='R') Read program memory
brne L40

movw ZL,R26 ;Z-pointer <= address


;ldi R30,0
;ldi R31,0

ldi R24,0xff
out DDRB,R24
out PORTB,R30

lpm R24,Z+ ;read program memory LSB; store LSB in R24 and Z pointer ++
lpm R16,Z+ ;read program memory MSB; store MSB in R16 and Z pointer ++

movw R26,ZL ;address += 2
rcall uartSend ;uartSend(R16) MSB
;movw R26,30 ;address += 2
mov R16,R24 ;LSB stored in R16
rjmp L70 ;uartSend(R16) LSB

;-------------------------------------------------------------------------------
;L40
;-------------------------------------------------------------------------------
L40: cpi R16,'D' ;else if (R16=='D') Write data to EEPROM
brne L42
rcall uartGet
out EEDR,R16 ;EEDR = uartGet()
ldi R17,6 ;write EEPROM
rcall EepromTalk
rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L42
;-------------------------------------------------------------------------------
L42: cpi R16,'d' ;else if (R16=='d') Read data from EEPROM
brne L44
ldi R17,1 ;read EEPROM
rcall EepromTalk ;R16 = EEPROM data
rjmp L70 ;uartSend(R16)
L44: cpi R16,'F' ;else if(R16=='F') Read fuse bits
brne L46
clr R30 ;Z-pointer = 0000
rjmp L50 ;rcall readFuseAndLock
;-------------------------------------------------------------------------------
;L46
;-------------------------------------------------------------------------------
L46: cpi R16,'r' ;else if(R16=='r') Read lock bits
brne L48
ldi R30,1 ;Z pointer = 0001
rjmp L50 ;rcall readFuseAndLock
;-------------------------------------------------------------------------------
;L48
;-------------------------------------------------------------------------------
L48: cpi R16,'N' ;else if(R16=='N') Read high fuse bits
brne L52
ldi R30,3 ;Z-pointer = 0003
;-------------------------------------------------------------------------------
;L50
;-------------------------------------------------------------------------------
L50: rcall readFuseAndLock
rjmp L70 ;uartSend(R16)
L52: cpi R16,'t' ;else if(R16=='t') Return supported devices code
brne L54
ldi R16,DT ;Device Type
rcall uartSend ;uartSend(DT) send Device Type
clr R16
rjmp L70 ;uartSend(0)
;-------------------------------------------------------------------------------
;L54
;-------------------------------------------------------------------------------
L54: ;else if ((R16=='l')||(R16=='x')||(R16=='y')||(R16=='T'))
cpi R16,'l' ;'l' = Write Boot Loader lockbits
breq L56
cpi R16,'x' ;'x' = Set LED
breq L56
cpi R16,'y' ;'y' = Clear LED
breq L56
cpi R16,'T' ;'T' = Select device type
brne L60
;-------------------------------------------------------------------------------
;L56
;-------------------------------------------------------------------------------
L56: rcall uartGet ;R16 = uartGet()
;YOU CAN INSERT LEDs CODE HERE
rjmp L68 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L60
;-------------------------------------------------------------------------------
L60: cpi R16,'S' ;else if (R16=='S') Return software identifier
brne L62
ldi R30,low(2*Soft_Id)
ldi R31,high(2*Soft_Id)
;-------------------------------------------------------------------------------
;L61
;-------------------------------------------------------------------------------
L61: lpm R16,Z+
tst R16
breq L72 ;branch is end of string ((Z) == 0)
rcall uartSend ;else send char
rjmp L61
;-------------------------------------------------------------------------------
;L62
;-------------------------------------------------------------------------------
L62: cpi R16,'V' ;else if (R16=='V') Return Software Version
brne L64
ldi R16,'1' ;uartSend('1')
rcall uartSend
ldi R16,'0' ;uartSend('2')
rjmp L70 ;uartSend(R16)
;-------------------------------------------------------------------------------
;L64
;-------------------------------------------------------------------------------
L64: cpi R16,'s' ;else if (R16=='s') Return Signature Byte
brne L66
ldi R16,SB1 ;uartSend(SB1) Signature Byte 1
rcall uartSend
ldi R16,SB2 ;uartSend(SB2) Signature Byte 2
rcall uartSend
ldi R16,SB3 ;uartSend(SB3) Signature Byte 3
rjmp L70 ;uartSend(R16)
;-------------------------------------------------------------------------------
;L66
;-------------------------------------------------------------------------------
L66: ldi R16,'?' ;else uartSend('?')
rjmp L70 ;uartSend(R16)
;-------------------------------------------------------------------------------
;L68
;-------------------------------------------------------------------------------
L68: ldi R16,13 ;uartSend('\r')
;-------------------------------------------------------------------------------
;L70
;-------------------------------------------------------------------------------
L70: rcall uartSend ; uartSend(R16)
;-------------------------------------------------------------------------------
;L72
;-------------------------------------------------------------------------------
L72: rjmp L10
;-------------------------------------------------------------------------------
;readFuseAndLock
;-------------------------------------------------------------------------------
readFuseAndLock:
clr R31 ;Z pointer high byte = 0
ldi R24,9 ;SPMCR = 0x09
out SPMCR,R24 ;read fuse and lock
lpm R16,Z ;read program memory
ret
;-------------------------------------------------------------------------------
;EepromTalk
;-------------------------------------------------------------------------------
EepromTalk: ;if R17 == 6 then Write, if R17 == 1 then Read
out EEARL,R26 ;EEARL = address low
out EEARH,R27 ;EEARH = address high
adiw R26,1 ;address++

sbrc R17,(1<<EERE) ;skip if R17 == 1 (read Eeprom)
sbi EECR,EEMWE ;EEMWE = 1 (write Eeprom)
out EECR,R17 ;EECR = R17 (6 write, 1 read)
E2_WAIT: sbic EECR,EEWE ;wait until EEWE == 0
rjmp E2_WAIT
in R16,EEDR ;R16 = EEDR
ret
;-------------------------------------------------------------------------------
;uartSend
;-------------------------------------------------------------------------------
uartSend: ; send R16
sbis UCSRA,UDRE ;wait for empty transmit buffer (until UDRE==1)
rjmp uartSend
out UDR,R16 ;UDR = R16, start transmission
uart_wait:
sbis UCSRA,TXC
rjmp uart_wait
ret
;-------------------------------------------------------------------------------
;uartGet
;-------------------------------------------------------------------------------
uartGet:
sbis UCSRA,RXC ;wait for incoming data (until RXC==1)
rjmp uartGet
in R16,UDR ;return received data in R16
ret
;-------------------------------------------------------------------------------
;Soft_id
;-------------------------------------------------------------------------------
Soft_Id: .DB "AVRBOOT", 0
; END of BOOT LOADER PROGRAM



When uploading program to the processor, everything seems ok. When avrprog tries to verify the program, I get message I wrote earlier. The stange thing is, when I reset processor, verify is correct. When using terminal to see what is transmitted from uC, I discovered, that after programing using avrprog, command used to read memory ('R') returns 0xff all the time. I'm quite sure, that the problem lies in manipulating Z-pointer and R27:R26 pair (used for holding adress). I tried to force Z-pointer to point 0x0000. It still give wrong reading (comparing to memory downloaded using PonyProg). By the way, application code that is uploaded thru boot loader begins with 0x940c. Please help.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits