📄 isojtag_avr910_3.4.s
字号:
//***************************************************************************
//*
//* Title : AVR ISP (Auto adr inc, 19200bps)
//* Version : 3.4
//* Last updated : 25/May/06
//* Target : ATmega16 @ 7.ladida Mhz
//* File : AVR910_2313_v3_2.asm
//* Author(s) : Andrew Leech, Ole Saether, Terje Frostad,
//* Ingar Fredriksen, Morten W. Lund
//* Haakon Skar, Paal Kastnes
//*
//See original appnote for more info.
//*
//* HISTORY
//* V3.4 17/Apr/06 (A.Leech) Ported to avr-gcc and m16 to be used in IsoJTAG.
//*
//* V3.3 05/Jan/06 (J.Samperi) Fixed bug with page mode. See note at w7:
//*
//* V3.2 17/Jan/05 (J.Samperi)Added support for newer devices supported by AVRprog 1.4
//* Some doubtfull or non working device codes commented out
//* Make use on newer conditional assembler to switch between
//* standard pinout for Mosi and Miso and the reversed pinout
//* for the Silicon Chip kit (Australia)
//*
//* V3.1 Modified by others to swap Miso and Mosi to original configuration
//*
//* V3.0?? 16/June/03 (J.Samperi) This version works with AT90S2313 because it
//* uses the LPM instruction and also uses the
//* hardware UART. Added lookup table for device
//* codes and program mode. Device can be added or
//* removed by simply changing parameters in one
//* location only.
//*
//* V2.2c 03.06.07 (sjdavies) Changed the 'x' and 'y' commands to make
//* them accept a parameter ('flushing' bugfix)
//* V2.2b 02.08.16 (sc) Swapped MOSI & MISO port bits
//* V2.2 02.04.10 (sjdavies) Ported to AT90S2313 running at 4MHz for
//* Silicon Chip article.
//* V2.2 02.01.23 (sjdavies) Ported from a 4Mhz 1200 to an 8Mhz 8535.
//* Serial IO modified to use hardware UART.
//* Timing updated.
//* Device specific modifications.
//* V2.2 00.03.10 (pkastnes) Added support for multiple new devices
//* V2.1 98.10.26 (mlund) New date marking.
//* Removed support for AT90S1200C.
//* Added support for AT90S4433A.
//* V2.0 98.01.06 (mlund) ATmega103 support
//* V1.7 97.11.06 (mlund) Universial command (':') implemented.
//* Releases all pins when not in
//* programming mode.
//* V1.6e 97.11.04 (mlund) mega103 rev D support
//* V1.6c 97.10.30 (mlund) Auto incrementing / SPI sync
//* also works for mega103.
//* V1.6 97.09.09 (hskar) Created Page Mode Version (mega103)
//* V1.5 97.08.21 (mlund) Modified / Bugfix / Major cleanup
//* ... ... (no records)
//* V?.? 97.03.15 (OS) Created
//*
//See original appnote for more info.
//*
//* LEGEND:
//* -------
//* Signature - Device Signature Byte
//* Code - Unique device code used by AVRProg to identify device
//* Flash - Flash size in bytes
//* EEProm - EEProm size in bytes
//* Lock - Lockbits
//* Fuse - Fusebits
//* PMode - Indicates if device uses byte or page programming mode
//*
//* R/W - Read and Write Access
//* R - Read Access Only
//* W - Write Access Only
//* NA - Not Accessible
//*
//***************************************************************************
.arch atmega16
//.include <m16def.inc>
#define __SFR_OFFSET 0
#include <avr/io.h>
#include <avr/iom16.h>
#include "crystal.h"
.list
//***************************************************************************
//*
//* CONSTANTS
//* device codes
//*
//* DESCRIPTION
//* The following device codes must be used by the host computer. Note
//* that the device codes are arbitrary selected, they do not have any
//* thing in common with the signature bytes stored in the device.
//*
//***************************************************************************
//See original appnote for more info.
//**** Revision Codes ****
#define SW_MAJOR '3' // Major SW revision number
#define SW_MINOR '4' // Minor SW revision number
#define HW_MAJOR '1' // Major HW revision number
#define HW_MINOR '0' // Minor HW revision number
//***************************************************************************
//*
//* MACROS
//* Program Macros
//*
//* DESCRIPTION
//* Change the following four macros if the RESET pin to the
//* target moves and/or if the SCK/MISO/MOSO moves.
//*
//***************************************************************************
#define resetpin 1
#define set_reset sbi PORTB,resetpin
#define clr_reset cbi PORTB,resetpin
#define ddrd_init nop
#define LEDDDR DDRB
#define LEDPORT PORTB
#define LEDBIT 3
//*****************
//* SPI Constants *
//*****************
#define MOSI 5 // Bit number on PORTB
#define MISO 6 // Bit number on PORTB
#define SCK 7 // Bit number on PORTB
//******************
//* UART Constants *
//******************
//
//#define N 23 // 19.2k data rate value (7.3728MHz crystal)
#define N N19200
//*****************************
//* Global Register Variables *
//*****************************
//New registers used for get_codes (V3.0)
#define dev_code r1 //Device code returned by get_codes
#define pgm_mode r2 //Program mode for device 0=byte mode
// //<>0=page mode
#define device r16 // Device code
#define temp1 r17
#define temp2 r18
#define s_data r19 //SPI data
#define u_data r20 //UART data
#define addrl r21 //Low order byte of address
#define addrh r22 //High order byte of address
#define cmd3 r23 //Used to be r30 (V3.0)
#define rd_s_data r24 //Used to be r31 (V3.0)
#define cmd r25 //Serial programming command
#define count r26 //Time out variable for "enter programming mode"
#define param1 r27
#define cmd1 r28
#define cmd2 r29
// =r30 //Leave Z register free for LPM
// =r31 (V3.0)
//*********************
//* Interrupt Vectors *
//*********************
.section .text
.global isp_start
isp_start:
rjmp RESET // Reset Handle
// Pulse SCK Line
pulse_sck:
sbi PORTB,SCK
ldi temp2,30 //11
m0:
dec temp2
brne m0
cbi PORTB,SCK
ldi temp2,20 //6
m1:
dec temp2
brne m1
ret
//Initialize UART.
u_init:
ldi temp1,N // set baud rate
out UBRRL,temp1
ldi temp1,1<<TXEN|1<<RXEN // initialize UART for TX and RX
out UCSRB,temp1
ret
putc:
sbis UCSRA,UDRE // test for TX register empty
rjmp putc // loop until TX empty
out UDR,u_data // send the byte
ret
getc:
sbis UCSRA,RXC // wait until a character has been received
rjmp getc
in u_data,UDR // Read byte from the UART
ret
delay:
ldi temp2,0xff
dl: dec temp2
brne dl
dec temp1
brne delay
ret
//***************************************************************************
//*
//* FUNCTION
//* wrser
//*
//* DESCRIPTION
//* Software master SPI implementation.
//*
//* Writes and reads data to/from the target's SPI (programming) port.
//*
//***************************************************************************
rdser:
clr s_data
wrser:
ldi temp1,8
ldi rd_s_data,0
wrs0:
rol s_data
brcc wrs1
sbi PORTB,MOSI
rjmp wrs2
wrs1:
cbi PORTB,MOSI
wrs2:
lsl rd_s_data
sbic PINB,MISO
ori rd_s_data,1
rcall pulse_sck
dec temp1
brne wrs0
mov s_data,rd_s_data
ret
//***************************************************************************
//*
//* FUNCTION
//* spiinit (Enter programming mode)
//*
//* DESCRIPTION
//* Initialize SPI interface on AVR or 'AT89 device.
//*
//***************************************************************************
spiinit:
ddrd_init // initialize port D
ldi temp1,(0xFF ^ (1<<MISO))
out DDRB,temp1 // PB6 (MISO) is input, the rest is output
cbi PORTB,SCK // clear SCK
set_reset // set RESET = 1
ldi temp1,0xff // delay(0xff)//
rcall delay
clr_reset // set RESET = 0
ldi temp1,0xff // delay(0xff)//
rcall delay
ldi s_data,0xac // wrser(0xac)// // SPI write (byte 1)
rcall wrser
ldi s_data,0x53 // wrser(0x53)// // SPI write (byte 2)
rcall wrser
// // SPI Synchronization (fix!)
cpi device,0x20 // if ( (device >= 0x20) && (device <= 0x7F) )
brlo s2
tst device
brmi s2
s0b: // {
ldi count,32 // count = 32//
s1: // do {
rcall rdser // if (rdser == 0x53) // SPI read (byte 3)
cpi s_data,0x53
breq s3 // break//
ldi s_data,0x00 // wrser(0x00)// // SPI write (byte 4)
rcall wrser
rcall pulse_sck // pulse SCK
ldi s_data,0xac // wrser(0xac)// // SPI write (byte 1)
rcall wrser
ldi s_data,0x53 // wrser(0x53)// // SPI write (byte 2)
rcall wrser
dec count // } while(--count)//
brne s1
rjmp s3 // }
// else
s2: // {
ldi s_data,0x00 // wrser(0x00)// // SPI write (byte 3)
rcall wrser
s3: // }
ldi s_data,0x00 // wrser(0x00)// // SPI write (byte 4)
rcall wrser
ldi temp1,0x10 // delay(0x10)//
rcall delay
ret
//Show our ID ("AVR ISP") on the serial line.
//@@ Changes (V3.0)
show_id:
ldi ZL,lo8(pm(ID)) //Point Z to ID string
ldi ZH,hi8(pm(ID))
lsl ZL
rol ZH
rcall msg_out
ret
//@@
RESET:
sbi LEDDDR,LEDBIT
cbi LEDPORT,LEDBIT
ldi temp1,lo8(RAMEND)
out SPL,temp1 // init stack
clr temp1
out GICR,temp1 // disable external interrupt
ser temp1 // Initialize
out PORTD,temp1
set_reset // set RESET=1
out PORTB,temp1
ldi temp1,(1<<resetpin)
out DDRB,temp1 // PB4 (RESET) is output, the rest is input
sbi LEDDDR,LEDBIT
cbi LEDPORT,LEDBIT
rcall u_init // Initialize UART
//***************************************************************************
//*
//* PROGRAM
//* waitcmd -> main
//*
//* DESCRIPTION
//* Wait for and execute commands.
//*
//***************************************************************************
waitcmd:
rcall getc // while (getc() == ESC) {}//
cpi u_data,0x1b
breq waitcmd
//**** Device Type ****
cpi u_data,0x54 // 'T' Device type
brne w0
rcall getc // getc()// // dummy
mov device,u_data // putc(device)//
rjmp put_ret
//**** Return Software Identifier ****
w0:
cpi u_data,0x53 // 'S' Return software identifier
brne w1
rcall show_id // show_id()//
rjmp waitcmd
//**** Return Software Version ****
w1:
cpi u_data,0x56 //'V' Return software version
brne w20
ldi u_data,SW_MAJOR
rcall putc
ldi u_data,SW_MINOR
rcall putc
rjmp waitcmd
//**** Exit ****
w20:
cpi u_data,0x45 // 'E' Exit
brne w2
ldi temp1,0x06 // .
out WDTCR,temp1 // .. Set watchdog prescaler to 1.1s
ldi temp1,0x0E
out WDTCR,temp1 // Enable watchdog
rjmp put_ret
//**** Return Hardware Version ****
w2:
cpi u_data,0x76 //'v' Return hardware version
brne w3
//*** deleted sd 02.04.10 - correct what looks like an Atmel error
// ldi u_data,0x30+HW_MAJOR // putc(0x30+HW_MAJOR)//
//*** end delete
//*** added sd 02.04.10 - correct what looks like an Atmel error
ldi u_data,HW_MAJOR // putc(HW_MAJOR)//
//*** end add
rcall putc
//*** deleted sd 02.04.10 - correct what looks like an Atmel error
// ldi u_data,0x30+HW_MINOR // putc(0x30+HW_MINOR)//
//*** end delete
//*** added sd 02.04.10 - correct what looks like an Atmel error
ldi u_data,HW_MINOR // putc(HW_MINOR)//
//*** end add
rcall putc
rjmp waitcmd
//**** Show Supported Devices ****
w3:
cpi u_data,0x74 // 't' Show supported devices
brne w4
//@@ Changes (V3.0)
ldi ZL,lo8(pm(device_codes)) //Point Z to device code table
ldi ZH,hi8(pm(device_codes))
lsl ZL
rol ZH
show_devices:
rcall get_codes //Returns device code in dev_code
mov u_data,dev_code
cpi u_data,0xff //Check for end of table
breq end_of_devices //Finished
rcall putc //Not finished, send out
rjmp show_devices
end_of_devices:
clr u_data
rcall putc //End of device list
rjmp waitcmd
//@@
//**** Return Programmer Type ****
w4:
cpi u_data,0x70 // 'p' Return programmer type
brne w51
ldi u_data,0x53 // putc('S')// // serial programmer
rcall putc
rjmp waitcmd
//**** Return autoincrement address support
w51:
cpi u_data,'a' // 'a' Return address auto increment
brne w5
ldi u_data,'Y' // putc('Y')// // supports autoinc
rcall putc
rjmp waitcmd
w5:
cpi u_data,0x78 // 'x' Set LED (ignored)
brne w6
rcall getc // ignore data byte
cbi LEDPORT,LEDBIT
rjmp put_ret
//**** Clear LED ****
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -