📄 sisp.s
字号:
;; Copyright (C) 2002-2003 by egnite Software GmbH. All rights reserved.;; Redistribution and use in source and binary forms, with or without; modification, are permitted provided that the following conditions; are met:;; 1. Redistributions of source code must retain the above copyright; notice, this list of conditions and the following disclaimer.; 2. Redistributions in binary form must reproduce the above copyright; notice, this list of conditions and the following disclaimer in the; documentation and/or other materials provided with the distribution.; 3. All advertising materials mentioning features or use of this; software must display the following acknowledgement:;; This product includes software developed by egnite Software GmbH; and its contributors.;; THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE; SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF; THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF; SUCH DAMAGE.;; For additional information see http://www.ethernut.de/;; $Log: sisp.S,v $; Revision 1.1 2003/11/03 15:51:31 haraldkipp; First check in;;.nolist#include "avr/io.h".list; This program implements a minimalist STK500 compatible programming; adapter for the serial port on an AT90S2313 MCU. It had been; originally written for AVR Studio, but then ported to AVR-GCC and; will no longer build with AVR Studio. However, the resulting; programmer had been successfully tested with AVR Studio 4.07 and; uisp version 20030827cvs on ATmega128 and ATmega13 targets.;; *********************************************************************; Protocol definitions; Initially the STK500 protocol had been evaluated by re-engineering.; Some months later Atmel decided to publish it. See; http://www.atmel.com/atmel/acrobat/doc2525.pdf#define STK_OK 0x10#define STK_INSYNC 0x14#define STK_NOSYNC 0x15#define CRC_EOP 0x20; *********************************************************************; General configurations; Baudrate factor. AVR Studio uses a fixed rate of 115,200 Baud, which; results in a baudrate register factor of 1 on a 3.6864 MHz MCU. See; the AT90S2313 datasheet for further details.#define BRFACTOR 1; *********************************************************************; Port Usage; PB0: Unused; PB1: Unused; PB2: ISP-LED (out); PB3: LED (out); PB4: ISP-RESET (out); PB5: ISP-MOSI (out); PB6: ISP-MISO (in); PB7: ISP-SCK (out);; PD0: RXD (in); PD1: TXD (out); PD2: HSIN/INT0 (in); PD3: HSOUT (out); PD4: unused; PD5: unused; PD6: unused;#define ISPLED 2#define LEDIND 3#define ISPRST 4#define ISPMOSI 5#define ISPMISO 6#define ISPSCK 7#define HSIN 2#define HSOUT 3; *********************************************************************; Register usage#define r_temp r16#define r_data r17#define r_isp r18#define r_shift r19#define r_delay r20#define r_retry r21#define r_size r22#define r_parm r23; *********************************************************************; RAM variables .section .bsspaddrl: .space 1paddrh: .space 1unicmd1: .space 1unicmd2: .space 1unicmd3: .space 1unicmd4: .space 1pm_devicecode: .space 1 ; device codepm_revision: .space 1 ; device revisionpm_progtype: .space 1 ; "0" both, "1" par onlypm_parmode: .space 1 ; "0" pseudo, "1" fullpm_polling: .space 1 ; "0" no, "1" yespm_selftimed: .space 1 ; "0" no, "1" yespm_lockbytes: .space 1 ; # of lock bytespm_fusebytes: .space 1 ; # of fuse bytespm_flpollval1: .space 1 ; Flash polling valuepm_flpollval2: .space 1 ; Flash polling valuepm_eepollval1: .space 1 ; EEPROM polling valuepm_eepollval2: .space 1 ; EEPROM polling valuepm_pagesizeh: .space 1 ; Page size high bytepm_pagesizel: .space 1 ; Page size low bytepm_eesizeh: .space 1 ; EEPROM size high bytepm_eesizel: .space 1 ; EEPROM size low bytepm_flsize4: .space 1 ; Flash size MSBpm_flsize3: .space 1 ; Flash sizepm_flsize2: .space 1 ; Flash sizepm_flsize1: .space 1 ; Flash size LSB; *********************************************************************; Vector table .section .text .global sispsisp: rjmp main; *********************************************************************; Constant data .type signon_msg, @object .global signon_msgsignon_msg: .string "\x14\x41VR STK\x10" .type version_msg, @object .global version_msgversion_msg: .string "SISP 1.1.1 Copyright 2002-2003 by egnite Software GmbH\r\n"; *********************************************************************; Main program entry.global mainmain: ; ; Set stack pointer ldi r_temp, lo8(RAMEND) out _SFR_IO_ADDR(SPL), r_temp ; ; Initialize Port B ; PB2: ISP-LED z-state ; PB3: LED output low ; PB4: ISP-RESET z-state ; PB5: ISP-MOSI z-state ; PB6: ISP-MISO input ; PB7: ISP-SCK z-state clr r_temp out _SFR_IO_ADDR(PORTB), r_temp out _SFR_IO_ADDR(DDRB), r_temp sbi _SFR_IO_ADDR(DDRB), LEDIND ldi r_retry, 3blink: rcall xdelay rcall xdelay cbi _SFR_IO_ADDR(PORTB), LEDIND ; LED on ldi r_delay, 64 rcall xdelay sbi _SFR_IO_ADDR(PORTB), LEDIND ; LED off dec r_retry brne blink ; ; Init UART ldi r_temp, BRFACTOR out _SFR_IO_ADDR(UBRR), r_temp ldi r_temp, (1<<RXEN) | (1<<TXEN) out _SFR_IO_ADDR(UCR), r_temp ; ; Set handshake line sbi _SFR_IO_ADDR(PORTD), HSOUT sbi _SFR_IO_ADDR(DDRD), HSOUT; *********************************************************************; Command handlercmdnxt: sbi _SFR_IO_ADDR(PORTB), LEDIND ; LED off rcall getc cbi _SFR_IO_ADDR(PORTB), LEDIND ; LED on ; *********************************************************************; Version output cpi r_data, 0x18 ; Ctrl-X brne c30 ldi r30, lo8(version_msg) ldi r31, hi8(version_msg) rjmp c31a; *********************************************************************; PC command: Get synchronization.;; The PC uses this command to regain synchronization with the; programmer. The command may be send several times until the; programmer responds with STK_INSYNC.c30: cpi r_data, 0x30 ; '0' brne c31; Receive last character of a command. If it's an EOP, then; respond with INSYNC. Otherwise send back NOSYNC.cmdend: rcall getc cpi r_data, CRC_EOP breq cmdok ldi r_data, STK_NOSYNC rcall putc rjmp cmdnxt ; Wait for next command; Send back positive response.cmdok: ldi r_data, STK_INSYNC rcall putccmdfirm: ldi r_data, STK_OK rcall putc rjmp cmdnxt ; Wait for next command ; *********************************************************************; PC command: Check if starterkit present.;; The programmer responds with a sign-on message.;c31: cpi r_data, 0x31 ; '1' brne c41 rcall getc ; Ignore CRC_EOP ldi r30, lo8(signon_msg) ldi r31, hi8(signon_msg)c31a: lpm tst r0 breq cmdnxt ; Done, wait for next command mov r_data, r0 rcall putc adiw r30, 1 rjmp c31a; *********************************************************************; PC command: Get parameter valuec41: cpi r_data, 0x41 ; 'A' brne c42 rcall getc ; Receive parameter id mov r_parm, r_data rcall getc ; Ignore CRC_EOP ldi r_data, STK_INSYNC rcall putc rcall getparm rcall putc rjmp cmdfirm; *********************************************************************; PC command: Set device programming parameters;; We ignore these parameters.c42: cpi r_data, 0x42 ; 'B' brne c45 ldi r_size, 20_c42nxt: rcall getc dec r_size brne _c42nxt rjmp cmdend; *********************************************************************; PC command: Set extended device programming parameters;; We ignore these parameters.c45: cpi r_data, 0x45 ; 'E' brne c50 ldi r_size, 5_c45nxt: rcall getc dec r_size brne _c45nxt rjmp cmdend; *********************************************************************; PC command: Enter Program Modec50: cpi r_data, 0x50 ; 'P' brne c51 rcall getc ; Ignore CRC_EOP ; ; Enable ISP interface. ; PB2: ISP-LED output low ; PB3: LED output low ; PB4: ISP-RESET output low ; PB5: ISP-MOSI output high ; PB6: ISP-MISO input ; PB7: ISP-SCK output low ldi r_temp, (1<<ISPMISO) out _SFR_IO_ADDR(PORTB), r_temp ldi r_temp, (1<<ISPLED)|(1<<LEDIND)|(1<<ISPRST)|(1<<ISPMOSI)|(1<<ISPSCK) out _SFR_IO_ADDR(DDRB), r_temp rcall xdelay ldi r_retry, 32 ; ; Send programming enablec50a: ldi r_isp, 0xAC rcall ispxcg ldi r_isp, 0x53 rcall ispxcg rcall ispget cpi r_isp, 0x53 ; Are we in sync breq c50z ; Yes, jump ; ; Handle sync failure rcall ispget ; Read last SPI byte sbi _SFR_IO_ADDR(PORTB), ISPRST ; Toggle target's reset line rcall xdelay cbi _SFR_IO_ADDR(PORTB), ISPRST rcall xdelay dec r_retry ; Loop for retries brne c50a rjmp cmdok ; Send positive resopnsec50z: rcall ispget rjmp cmdok ; Send positive resopnse; *********************************************************************; PC command: Leave program modec51: cpi r_data, 0x51 ; 'Q' brne c52 rcall getc ; Ignore CRC_EOP ; ; Disable ISP interface. ; PB2: ISP-LED z-state ; PB3: LED output low ; PB4: ISP-RESET z-state ; PB5: ISP-MOSI z-state ; PB6: ISP-MISO input ; PB7: ISP-SCK z-state clr r_temp out _SFR_IO_ADDR(PORTB), r_temp out _SFR_IO_ADDR(DDRB), r_temp sbi _SFR_IO_ADDR(DDRB), LEDIND rjmp cmdok ; Send positive resopnse; *********************************************************************; PC command: Chip erasec52: cpi r_data, 0x52 ; 'R' brne c55 rcall getc ldi r_isp, 0xAC rcall ispxcg ldi r_isp, 0x80 rcall ispxcg ldi r_isp, 0x04 rcall ispxcg rcall ispget rcall xdelay ; Very long delay. May be reduced rcall xdelay ; but who really cares? rjmp cmdok ; Send positive resopnse; *********************************************************************; PC command: Load addressc55: cpi r_data, 0x55 ; 'U' brne c56 rcall getc sts paddrl, r_data rcall getc sts paddrh, r_data rjmp cmdend; *********************************************************************; PC command: Universalc56: cpi r_data, 0x56 ; 'V' brne c64 rcall getc sts unicmd1, r_data rcall getc sts unicmd2, r_data rcall getc sts unicmd3, r_data rcall getc sts unicmd4, r_data rcall getc ; EOP ldi r_data, STK_INSYNC rcall putc lds r_isp, unicmd1 rcall ispxcg lds r_isp, unicmd2 rcall ispxcg lds r_isp, unicmd3 rcall ispxcg lds r_isp, unicmd4 rcall ispxcg ldi r_delay, 64 rcall delay mov r_data, r_isp rcall putc rjmp cmdfirm; *********************************************************************; PC command: Program page; This is a very tricky routine. The STK500 insists on sending; data with 115,200 Baud. We hope, that the target MCU will be; fast enough.c64: cpi r_data, 0x64 ; 'd' brne c72 rcall getc ; Size of this block to Y-register mov r29, r_data rcall getc mov r28, r_data rcall getc ; Memory type (F)lash or (E)eprom cpi r_data, 'F' brne c64ee clr r30c64a: ldi r_isp, 0x40 ; Send low byte rcall ispput clr r_isp rcall ispput mov r_isp, r30 rcall ispputc64b: sbis _SFR_IO_ADDR(USR), RXC rjmp c64b in r_isp, _SFR_IO_ADDR(UDR) rcall ispput ldi r_isp, 0x48 ; Send high byte rcall ispput clr r_isp rcall ispput mov r_isp, r30 rcall ispputc64c: sbis _SFR_IO_ADDR(USR), RXC rjmp c64c in r_isp, _SFR_IO_ADDR(UDR) rcall ispput inc r30 ; Increment address sbiw r28, 2 ; Decrement length brne c64a rcall getc ldi r_isp, 0x4C ; Write memory page rcall ispxcg lds r_isp, paddrh rcall ispxcg lds r_isp, paddrl rcall ispxcg rcall ispget ldi r_delay, 168 ; Target requires delay after each write rcall delay ; We use 35 milliseconds, OK for most targets rjmp cmdok ; Send positive resopnsec64ee:c64ea: sbis _SFR_IO_ADDR(USR), RXC rjmp c64ea in r_isp, _SFR_IO_ADDR(UDR)c64ec: sbis _SFR_IO_ADDR(USR), RXC rjmp c64ec in r_isp, _SFR_IO_ADDR(UDR) sbiw r28, 2 brne c64a rjmp cmdend; *********************************************************************; PC command: Read Fuse Bitsc72: cpi r_data, 0x72 ; 'r' brne c73
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -