program boot loader atmega 8

Upload: said-mukhsin-almahdaly

Post on 02-Apr-2018

231 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/27/2019 Program Boot Loader Atmega 8

    1/23

    Program boot loader atmega 8

    Hardware

    Basically AVRUSBBoot can be used with all circuits which are supported by the AVR USB driver. Toswitch between the bootloader and the application, an aditional jumper is necessary. Here is anexample (Here the levels on the data lines are 5V which doesn't meet the USB specification! Thesupply voltage should be regulated to 3,3V - 3,6V):

    ;----------------------------------------------------------------------------------------;; Program: Bootloader_Mega8.asm;; Writer: Herbert Dingfelder, DL5NEG; for contact information visit WWW.DL5NEG.DE;; Based on: AVR-Freaks Design Note #32;; Function: Bootloader for ATmega8, Works via the UART with thenormal; AVRProg PC-Software;; Hardware: ATmega8 with a 7.3728MHz crystal;; History:;; 13.07.2004 - Source code adapted for Mega8, assembles withouterrors;

  • 7/27/2019 Program Boot Loader Atmega 8

    2/23

    ; 15.07.2004 - Used crystal is not 7.3 but 3.686 MHz -> UARTsetting adapted; - LED on LEDport/LEDbit is switched onwithin the boot section,; tested in Hardware and works -> processorstarts correctly

    ; within the boot section; 18.07.2004 - Problem how to download the bootloader is solved:Simply use; the AVRProg in the "mega8" mode, not in"mega8boot" mode.; Since the Intel-Hex Format contains theaddress for the code; in each line, the programmers recognizesthat the code has to; go to the bootrom part of the flash(provide that the; ".org MY_BOOTSTART" is put at thebeginning of the source code)

    ; - UART communication between bootloader andhost PC works; (echo mode and character recognitiontested and works); - Crystal changed to 7.3728MHz in an attemptto fight "flushing"; problems in AVRProg (without success),UART setting adapted; - AVRProg is able to read the flashcorrectly (tested, works); - Reading and writing to EEPROM on hostcommands 'D' and 'd' works.; - Flash erase did not work in the NRWRsection (the last 1024; words of the flash) The original versionfrom DesignNote #32; was for ATmega163 which does not haveRWR/NRWR sections.; Problem solved by implementing thewait_for_spm function that; makes sure that a new SPM does only startwhen the previous one; is completed. (tested, works now); - function to reenable the RWW sectionimplemented ->; loading data into the application sectiontested and works fine; (Still some problems with sync on theinterface between AVRProg; and the boot loader, messagebox "flushing"appears, fuse bits are; read differently many times and softwaredownload needs to be; started twice sometimes. As it is knownthat AVRProg is very sensible; command/answer sync, this does not pointtowards real bootloader problems.; It has to be tracked on the interface.); -> Good enough to work with temporarily,Version 1.0 released.; - Startup-function implemented for 10 secondwait after power-on. If

  • 7/27/2019 Program Boot Loader Atmega 8

    3/23

  • 7/27/2019 Program Boot Loader Atmega 8

    4/23

  • 7/27/2019 Program Boot Loader Atmega 8

    5/23

    ;; The Fuse bits must be programmed before programming the Lockbits.;;; AVRProg Commands as defined by Atmel

    ;; Host Writes; ID; Enter Programming Mode 'P'; Auto Increment Address 'a' dd; Set Address 'A' ah al; Write Program Memory, Low Byte 'c' dd; Write Program Memory, High Byte 'C' dd 13d; Issue Page Write 'm'; Read Lock Bits 'r' dd; Read Program Memory 'R' 2*dd; Read EEPROM Memory 'd' dd; Write EEPROM Memory 'D' dd

    ; Chip Erase 'e'; Write Lock Bits 'l' dd; Read Fuse Bits 'F' dd; Read High Fuse Bits 'N' dd; Read Extended Fuse Bits 'Q' dd; Leave Programming Mode 'L'; Select Device Type 'T' dd; Read Signature Bytes 's' 3*dd; Return Supported Device Codes 't' n*dd 00d; Return Software Identifier 'S' s[7]; Return Software Version 'V' dd dd; Return Hardware Version 'v'; Return Programmer Type 'p' dd; Set LED 'x' dd; Clear LED 'y' dd; Exit Bootloader 'E'; Check Block Support 'b' 'Y' 2*dd; Start Block Flash Load 'B' 2*dd'F' 13d (not implemented);; Start Block EEPROM Load 'B' 2*dd 'E' 13d;; Start Block Flash Read 'g' 2*dd'F' n*dd (not implemented); Start Block EEPROM Read 'g' 2*dd 'E' n*dd; Universal Command (3 data bytes) ':' 3*dd dd 13d; New Universal Command (4 data bytes)'.' 4*dd dd 13d;

    ;-------------------------definition and includes ---------------------------------------

    .INCLUDE "m8def.inc" ; Include Register/BitDefinitions for the mega8.def tmp_r = r18 ; Use Reg. R18 fortemporary stuff.def pa_10ms = r19 ; used for selectingthe pause time in steps of 10ms

    .def uni_cmd1 = r20 ; Universal command':' send three bytes. These

  • 7/27/2019 Program Boot Loader Atmega 8

    6/23

    .def uni_cmd2 = r21 ; are stored forfuther usage in r20, r21, r28.def uni_cmd3 = r10

    .equ VER_H = '1' ; bootloader softwareversion higher number

    .equ VER_L = '3' ; bootloader softwareversion lower number

    .equ VERH_H = '1' ; bootloader hardwareversion higher number.equ VERH_L = '0' ; bootloader hardwareversion lower number

    .equ DT = 0x76 ; Device Type = 0x76(ATmega8)

    .equ SB1 = 0x07 ; Signature byte 1

    .equ SB2 = 0x93 ; Signature byte 2

    .equ SB3 = 0x1e ; Signature byte 3

    .equ ESC = 27 ; Ascii 27 = Escape

    ;LR*****************************************************.equ fCK = 7372800 ;X-tal frequency *.equ BaudR=19200 ;Baud rate *.equ Tr_Sp=0 ;Transmission speed (U2X) *.equ UBR=-1+(5+10*fCK/(16*BaudR-8*BaudR*Tr_Sp))/10 ; *.equ presc=1024 ; *.equ fTmr=100 ;freq. of Timer 0 (1/10ms=100) *.equ TmrLoad=256-(fCK/(presc*fTmr)) ; *.equ CR = 13 ; *

    ; *;Pin for LED and Boot escape definition: *.equ LEDport =PORTc ; *.equ LEDdir =DDRc ; *.equ LEDbit =1 ; *

    ; *.equ TestPort =PINC ; *.equ TestBit =1 ; *

    ; *.equ ActiveStatLED=0 ;0=low, 1=high active stat *.if ActiveStatLED ; *.macro set_led ; *

    sbi LEDport,LEDbit ; *.endm ; *

    ; *.macro clr_led ; *

    cbi LEDport,LEDbit ; *.endm ; *.else ; *.macro set_led ; *

    cbi LEDport,LEDbit ; *.endm ; *

    ; *.macro clr_led ; *

    sbi LEDport,LEDbit ; *.endm ; *.endif ; *

    ; *

  • 7/27/2019 Program Boot Loader Atmega 8

    7/23

    ;LR*****************************************************

    .equ MY_BOOTSTART = THIRDBOOTSTART ; here we define where the bootloaderstarts in the flash

    ;----------------------------- here we go ---------------------------------

    --------------

    .org MY_BOOTSTART ; bootstart address according to .equ above

    ; ---------------------------------- Boot Escape ------------------------------------------;LR***********************************

    in tmp_r,TestPort ; *sbrc tmp_r,TestBit ; *rjmp FLASHEND+1 ; *

    ;LR***********************************; ----------------------------------- init stackpointer ---------------------------------

    ldi R24, low(RAMEND) ; SP = RAMENDldi R25, high(RAMEND)out SPL, R24out SPH, R25

    ldi tmp_r, 0b00000101 ; set prescaler to 1024out TCCR0, tmp_r

    ; ---------------------------------- init UART ------------------------------------------;LR***********************************.if Tr_Sp ; *

    sbi UCSRA,U2x ; *.else ; *

    cbi UCSRA,U2x ; *.endif ; *;LR***********************************

    ldi tmp_r, LOW(UBR)out UBRRL, tmp_r

    .if HIGH(UBR)ldi tmp_r, HIGH(UBR)out UBRRH, tmp_r

    .endifldi tmp_r,(1

  • 7/27/2019 Program Boot Loader Atmega 8

    8/23

    start_wait:clr_led ; switch off the LEDrcall pause200 ; wait a momentsbic UCSRA,RXCrjmp Char_Rec0 ; check for incoming

    data (if RXC==1)

    st_wait2:set_led ; switch on the LEDrcall pause200 ; wait a momentsbic UCSRA,RXC ; check for incoming

    data (if RXC==1)rjmp Char_Rec1 ; check for incoming

    data (if RXC==1)

    dec R17 ; decremente the loopcounter

    brne start_wait ; and leave loop ifcounter has reached zero

    clr_led ; switch off the LEDrjmp FLASHEND+1 ; Start theapplication program

    ;--- some character was received ---Char_Rec0:

    set_led ; switch on the LEDChar_Rec1:

    in R16,UDR ; fetchreceived character and put it into R16

    cpi R16, ESC ; if the receivedcharacter was ESC

    brne No_ESC ; start thebootloader main loop;--------------------------------- start of main loop -----------------------------------;-------------------- wait for a character from UART other than ESC ---------------------L10:

    rcall uartGet ; repeat (R16 =uartGet)

    cpi R16, ESC ; while (R16 ==ESCAPE)

    breq L10No_ESC:;--------- Command 'E' leaves the bootloader mode and starts theapplication ------------

    cpi R16, 'E' ; if(R16=='E') 'E' =Exit bootloader

    brne L11;LR********************************

    ldi R16,CRrcall uartSend

    TstUDRE: sbis UCSRA,UDRE ; wait for empty transmitbuffer (until UDRE==1)

    rjmp TstUDRETstTXC: sbis UCSRA,TXC ; wait for USART Transmit Complete (untilTXC==1)

    rjmp TstTXC;LR********************************

    rcall pause200

  • 7/27/2019 Program Boot Loader Atmega 8

    9/23

    clr_led ; switch off the LEDrjmp FLASHEND+1 ; Start the

    application program;

    (flashend+1) = Address 0;--------- Command 'a' is question from host for autoimcrement capability--

    --------------; simple anser is 'Y' for yes, autoincrementis doneL11:

    cpi R16, 'a' ; if(R16=='a') 'a' =Autoincrement?

    brne L12

    ldi R16,'Y' ; Yes, autoincrementis quicker

    rjmp L70 ;uartSend(R16) Send the 'Y' and go up for next command

    ;--------- Command 'A' is setting the address for the next operation --------------------; two bytes (in total) for high and low address are sent fromthe hostL12:

    cpi R16,'A' ; else if(R16=='A')write address

    brne L14

    rcall uartGetmov R27,R16 ; address high byte

    is stored in R27

    rcall uartGetmov R26,R16 ; address low byte is

    stored in R26

    lsl R26 ;address=address

  • 7/27/2019 Program Boot Loader Atmega 8

    10/23

    rjmp L68 ;uartSend('\r') send CR and go up for next command

    ;--------- Command 'C' is write high byte to program memory -----------------------------

    ; together with the (already received) low byte, the highbyte is writen tothe flashes; page buffer. When the page buffer is completely written, it can betransfered into; the real flash by the "page write" command.;; If only SPMEN is written, the following SPM instruction will store thevalue in R1:R0; in the temporary page buffer addressed by the Z pointer.

    L16:

    cpi R16,'C' ; else if(R16=='C')

    write program memory,high bytebrne L18

    rcall uartGet ; read the high bytefrom the host

    mov R23,R16 ; store the data highbyte in R23

    movw ZL,R26 ; load the Z pointerwith the current address

    movw R0,R22 ; transfer the dataword (data high and low byte)

    ; intoregisters R0 and R1

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    ldi R24, (1

  • 7/27/2019 Program Boot Loader Atmega 8

    11/23

    ; the loop that has to be performed to clear the application

    section is:; for(address=0; address < (2*MY_BOOTSTART); address +=

    (2*PAGESIZE)); the "address" variable to be used are the registers R26 and R27

    clr R26 ; start withaddress 0

    clr R27

    rjmp L24 ; continue theloop at the check for

    ;"end-criteria reached"

    ;......... beginning of erase loop ............L20:

    ; If the PGERS bit is written to one at the same time as SPMEN, the nextSPM; instruction within four clock cycles executes page erase. The pageaddress; is taken from the high part of the Z pointer.

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    movw ZL,R26 ; load the Z-pointerwith the address of the

    ; pageto be erased

    ldi R24, (1

  • 7/27/2019 Program Boot Loader Atmega 8

    12/23

    ; ..... remember the number of flash-erases in the EEPROM .....

    ldi R26,low( E2END -1) ; increment ChipErase Counter located

    ldi R27,high(E2END -1) ; at address E2END-1movw R22,R26 ; Save Chip Erase

    Counter Address in R22ldi R17,1 ; read EEPROMrcall EepromTalkmov R24,R16 ; R24 = Chip Erase

    Counter low bytercall EepromTalkmov R25,R16 ; R25 = Chip Erase

    Counter high byteadiw R24,1 ; counter ++out EEDR,R24 ; EEDR = R24 Chip

    Erase Counter low bytemovw R26,R22 ; R26 = Chip Erase

    Counter Address

    ldi R17,6 ; write EEPROMrcall EepromTalkout EEDR,R25 ; EEDR = R25 Chip

    Erase Counter high bytercall EepromTalk

    ; ..........................................................

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    rcall enable_rww ; reenable theRWW section so it can be accessed again

    rjmp L68 ;uartSend('\r') send CR and go up for next command

    ;---------------------------- Command 'm' is write page ---------------------------------; To execute page write, set up the address in the Z pointer, write'X0000101' to SPMCR; and execute SPM within four clock cycles after writing SPMCR. The data inR1 and R0; is ignored. The page address must be written to PCPAGE. Other bits in theZ pointer will; be ignored during this operation.L28:

    cpi R16,'m' ; else if(R16== 'm')Write page

    brne L34

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    movw ZL,R26 ; load Z-pointer withaddress

    ldi R24, (1

  • 7/27/2019 Program Boot Loader Atmega 8

    13/23

    nop

    rcall enable_rww ; reenable theRWW section so it can be accessed again

    L32: rjmp L68 ;uartSend('\r') send CR and go up for next command

    ;--------------------- Command 'P' is enter programming mode ----------------------------; nothing is done here, only the command is confirmed to host by sending CRL34:

    cpi R16,'P' ; else if(R16=='P')Enter programming mode

    breq L32 ;uartSend('\r') Send CR to host and go up for next command

    ;--------------------- Command 'L' is leave programming mode ----------------------------; nothing is done here, only the command is confirmed to host by sending CR

    cpi R16,'L' ; else if(R16=='L')Leave programming mode

    breq L32 ;uartSend('\r') Send CR to host and go up for next command

    ;--------------------- Command 'p' is Return programmer type ----------------------------; simply return an 'S' to indicate to host that this is a serial programmer

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

    brne L38

    ldi R16,'S' ; uartSend('S')Serial

    rjmp L70 ;uartSend(R16) and go up for next command;--------------------- Command 'R' is "Read one word from program memory" ---------------; reads one word from the 'current' address that is stored in R26 andincrements R26L38:

    cpi R16,'R' ; else if(R16=='R')Read program memory

    brne L40

    movw ZL,R26 ; load Z-pointer withaddress of memory to be read

    lpm R24,Z+ ; read programmemory LSB; store LSB in R24 and Z pointer ++

    lpm R16,Z+ ; read programmemory MSB; store MSB in R16 and Z pointer ++

    rcall uartSend ; uartSend(R16) writeback MSB to host

  • 7/27/2019 Program Boot Loader Atmega 8

    14/23

    movw R26,ZL ; increment the

    'current' address += 2

    mov R16,R24 ; LSB stored in R16

    rjmp L70 ;uartSend(R16) write back the LSB to host and go; up for next command

    ;--------------------- Command 'D' is "write data to EEPROM" ----------------------------L40:

    cpi R16,'D' ; else if (R16=='D')Write data to EEPROM

    brne L41rcall uartGet ; fetch the data to

    write from the UARTout EEDR,R16 ; EEDR = uartGet()

    ldi R17,6 ; write EEPROMrcall EepromTalkrjmp L68 ;

    uartSend('\r') Confirm the command to host with CR

    ;--------- Command 'b' is question from host for block mode capability----------------; simple anser is 'N' 'N', no bootloader does not supportblockmodeL41:

    cpi R16, 'b' ; if(R16=='b') 'b' =Blockmode?

    brne L42

    ldi R16,'N' ; send 'N'rcall uartSend

    ldi R16,'N' ; send 'N'rjmp L70 ;

    uartSend(R16) Send the 'N' and go up for next command

    ;--------------------- Command 'd' is "read data from EEPROM -----------------------------L42:

    cpi R16,'d' ; else if (R16=='d')Read data from EEPROM

    brne L43ldi R17,1 ; read EEPROMrcall EepromTalk ; R16 = EEPROM datarjmp L70 ;

    uartSend(R16)

    ;-------------------------- Command ':' is universal command ----------------------------; Host sends 3 more bytes which must be used to determine the requiredaction. AVRProg; uses the ':' with parameters to do things that could simply be done byr/F/N.; We have to map recognized parameters to the refering action.

  • 7/27/2019 Program Boot Loader Atmega 8

    15/23

    L43:

    cpi R16,':' ; else if(R16==':')Universal Command

    brne L44

    ;.............. read in the parameters...............................

    rcall uartGet ; R16 = uartGet()mov uni_cmd1, r16 ; store the read byte

    rcall uartGet ; R16 = uartGet()mov uni_cmd2, r16 ; store the read byte

    rcall uartGet ; R16 = uartGet()mov uni_cmd3, r16 ; store the read byte

    ;.....................................................................

    clr r16 ; preset r16with zero, if parameters are not

    ;recognized, zero will be returned to host

    ;.....................................................................

    cpi uni_cmd1, 0x58 ; check if 1stparamter is 0x58

    brne cmd1_not_0x58

    cpi uni_cmd2, 0x00 ; check if 2ndparamter is 0x00

    brne cmd2_not_0x00_1

    ; -> 58 00 is read lock bits,ldi ZL,1 ; Z pointer =

    0001 (-> readFuseAndLock will read lock)rcall readFuseAndLock ; go get the requested bits

    cmd2_not_0x00_1:

    cpi uni_cmd2, 0x08 ; check if 2ndparamter is 0x08

    brne cmd2_not_0x08

    ; -> 58 08 is read fuse high bits,ldi ZL,3 ; Z pointer =

    0003 (-> readFuseAndLock will read high fuse)rcall readFuseAndLock ; go get the requested bits

    cmd2_not_0x08:

    cmd1_not_0x58:

    cpi uni_cmd1, 0x50 ; check if 1stparamter is 0x50

    brne cmd1_not_0x50

  • 7/27/2019 Program Boot Loader Atmega 8

    16/23

    cpi uni_cmd2, 0x00 ; check if 2nd

    paramter is 0x00brne cmd2_not_0x00_2

    ; -> 50 00 is read fuse bits,

    clr ZL ; Z-pointer =0000 (-> readFuseAndLock will read fuse)rcall readFuseAndLock ; go get the requested bits

    cmd2_not_0x00_2:

    cmd1_not_0x50:

    rcall uartSend ; uartSend(bits) sendthe read lock/fuse bits

    rjmp L68 ;uartSend('\r') and go up for next command

    ;--------------------- Command 'F' is "read fuse bits" ----------------------------------L44:

    cpi R16,'F' ; else if(R16=='F')Read fuse bits

    brne L46clr ZL ; Z-pointer =

    0000 (-> readFuseAndLock will read fuse)rjmp L50 ; rcall

    readFuseAndLock

    ;--------------------- Command 'r' is "read lock bits" ----------------------------------L46:

    cpi R16,'r' ; else if(R16=='r')Read lock bits

    brne L48ldi ZL,1 ; Z pointer =

    0001 (-> readFuseAndLock will read lock)rjmp L50 ; rcall

    readFuseAndLock

    ;--------------------- Command 'N' is "read fuse high bits" -----------------------------L48:

    cpi R16,'N' ; else if(R16=='N')Read high fuse bits

    brne L52ldi ZL,3 ; Z-pointer =

    0003 (-> readFuseAndLock will read high fuse)

    ;-------- for all previous commands F,r,N hear we call the readFuseAndLock--------------; function that will read the bits that are indicated by theZ-registerL50:

  • 7/27/2019 Program Boot Loader Atmega 8

    17/23

    rcall readFuseAndLockrjmp L70 ;

    uartSend(R16)

    ;--------------------- Command 't' is Return supported devices code -------

    --------------; obviously we return only the device code ofthe mega8 hereL52:

    cpi R16,'t' ; else if(R16=='t')Return supported devices code

    brne L54

    ldi R16,DT ; Device Typercall uartSend ; uartSend(DT) send

    Device Type of Mega8

    clr R16 ; command set

    of AVRProg requires the termination of ; thet-command with a \0 not with a CR as other commands

    rjmp L70 ; uartSend(0)and go up for next command

    ; ---------------- ignored commands that are not sensible for boot loader ---------------; The following 4 commands only make sense for a general programmer, notfor a bootloader.; As theres commands come with an additional byte as parameter, with haveto fetch that; byte from the UART to avoid messing up the UART reading.L54:

    cpi R16,'l' ; 'l' = Write BootLoader lockbits

    breq L56

    cpi R16,'x' ; 'x' = Set LEDbreq L56

    cpi R16,'y' ; 'y' = Clear LEDbreq L56

    cpi R16,'T' ; 'T' = Select devicetype

    brne L60

    L56:rcall uartGet ; R16 = uartGet()rjmp L68 ;

    uartSend('\r') and go up for next command

    ;--------------------- Command 'S' is Return software identifier ------------------------L60:

    cpi R16,'S' ; else if(R16=='S')Return software identifier

    brne L62

  • 7/27/2019 Program Boot Loader Atmega 8

    18/23

    ldi ZL,low(2*Soft_Id) ; load address of String intoZ-Register

    ldi ZH,high(2*Soft_Id)

    L61:lpm R16,Z+ ; read one

    character of the string and increment string pointer

    tst R16breq L72 ; exit the

    character output loop charcter was '\0'

    rcall uartSend ; send the readcharacter via the UART

    rjmp L61 ; go to startof loop for next character

    ;--------------------- Command 'V' is Return software Version ---------------------------L62:

    cpi R16,'V' ; else if (R16=='V')Return Software Version

    brne L63

    ldi R16, VER_H ; send bootloadersoftware version higher number

    rcall uartSend

    ldi R16, VER_L ; send bootloadersoftware version lower number

    rjmp L70 ; uartSend andgo up for next command

    ;--------------------- Command 'v' is Return hardware Version ---------------------------L63:

    cpi R16,'v' ; else if (R16=='v')Return hardware Version

    brne L64

    ldi R16, VERH_H ; send bootloadersoftware version higher number

    rcall uartSend

    ldi R16, VERH_L ; send bootloadersoftware version lower number

    rjmp L70 ; uartSend andgo up for next command

    ;--------------------- Command 's' is Return Signature Byte -----------------------------L64:

    cpi R16,'s' ; else if (R16=='s')Return Signature Byte

    brne L65

    ldi R16,SB1 ; uartSend(SB1)Signature Byte 1

  • 7/27/2019 Program Boot Loader Atmega 8

    19/23

    rcall uartSend

    ldi R16,SB2 ; uartSend(SB2)Signature Byte 2

    rcall uartSend

    ldi R16,SB3 ; uartSend(SB3)Signature Byte 3rjmp L70 ; uartSend and

    go up for next command

    ;--------------------- Command '.' is new universal command -----------------------------; this command will be ignored, only the inteface will be handled correctlyL65:

    cpi R16,'.' ; else if (R16=='.')New Universal Command

    brne L66

    ;.............. read in the 4 parameters...............................

    rcall uartGet ; R16 = uartGet()rcall uartGet ; R16 = uartGet()rcall uartGet ; R16 = uartGet()rcall uartGet ; R16 = uartGet()

    ;......................................................................

    clr R16 ; uartSend(/0)rcall uartSend

    rjmp L68 ;uartSend('\r') and go up for next command

    ;++++++++++++++ handling the different command till here++++++++++++++++++++++++++++++++; only general completion for all commands below

    ;---------------------- failed commands can end up here ---------------------------------; an '?' is send via the UART to indicate fail host, then main loopstarts again

    L66:ldi R16,'?' ; else uartSend('?')rjmp L70 ;

    uartSend(R16)

    ;--------- successfully completed commands without return value can end uphere ---------; an CR is sent via the UART to confirm execution to host, then mainloop starts again

    L68:ldi R16,13 ;

    uartSend('\r')

  • 7/27/2019 Program Boot Loader Atmega 8

    20/23

    ;------------ successfully completed commands with return value can end uphere ---------; the return value is sent via the UART to confirm execution to host; then main loop startsagain

    L70: rcall uartSend ; uartSend(R16)

    L72:rjmp L10 ; jump up to

    beginning of main loop

    ;-------------------------- end of main loop --------------------------------------------

    ;================= end of main program, only subroutines from here on

    ===================

    ;------------------ reads fuse or lock bits (depending on Z-Reg.) -------------readFuseAndLock:

    ; An LPM instruction within three cycles after BLBSET and SPMEN areset in the SPMCR

    ; Register, will read either the Lock bits or the Fuse bits; (depending on Z0 in the Z pointer) into the destination register.

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    clr ZH ; Z pointerhigh byte = 0

    ldi R24,(1

  • 7/27/2019 Program Boot Loader Atmega 8

    21/23

    L90:sbic EECR,EEWE ; wait until EEWE ==

    0rjmp L90in R16,EEDR ; R16 = EEDR

    ret

    ;---------------- send one character via UART (parameter is r16) --------------uartSend:

    sbis UCSRA,UDRE ; wait for emptytransmit buffer (until UDRE==1)

    rjmp uartSendout UDR,R16 ; UDR = R16, start

    transmission

    ret

    ;---------------- read one character from UART (returned in r16) --------------uartGet:

    sbis UCSRA,RXC ; wait for incomingdata (until RXC==1)

    rjmp uartGetin R16,UDR ; return

    received data in R16

    ret

    ;-------------------- wait for SPM to be ready for new tasks ------------------; while( SPMCR_REG & (1

  • 7/27/2019 Program Boot Loader Atmega 8

    22/23

    ; If this is not done, all addresses will read $FF even if they containother values.enable_rww:

    rcall wait_for_spm ; make sure SPM isready to accept a new task

    ldi r16, (1

  • 7/27/2019 Program Boot Loader Atmega 8

    23/23

    :101E3000809BFBCF0F2EC5950694E9F72397269636:101E400068F7EA35F20550F3F797F695E7952F0115:101E5000CAE0E6EBFFE10590002031F078D00016F3:101E6000D1F3CA9591F0F5CF06EA8AD070D0E1F7A8:101E70000AEA86D06CD0F1F76AD0F1F3F101E89468:101E80000430F0F059F1063018F422BA21BAB8C083

    :101E900031F45DD05CD0672859F331010FC00730B1:101EA00059F455D019F453D0005821F00590001280:101EB0006894F7CF1EF0DCCF07EADBCF0BEAD9CF6F:101EC000ECEBFFE1C0E0EC0FF21DC4910150D8F73C:101ED00008EA56D00591C150E0F7CACFA0E6B0E0BD:101EE000ED0135D021F433D00058689431F0E894F6:101EF0000D93A03204E0B007A1F7AC17BD0731F194:101F0000A0E2B4E0E054FC4F10E232971E900E9035:101F100001E015D01A95C9F7E0301EE1F107A8F4E9:101F200003E00DD005E009D0AC17BD0769F776F0E6:101F3000E054FC4F09EA24D0D4CF01D001E107BF1F:101F4000E89507B700FDFDCF0895B8CF91CF809BEE:101F5000FECF8099FECF18E0C2019695879523D0D9

    :101F600021D006958099006807FD642676946794D1:101F700008F4642608F475261A9591F7053A089531:101F800011D09198149119E0009500C000C00AD0BA:101F9000069518F40000919802C0919A00C01A9515:101FA000A1F70895C2010497F0F78D3F18F011F0E2:101FB0008F3F01F00895506564610000030107033D:0A1FC00003C0041E930704001E0076:00000001FF