📄 avr910.asm
字号:
;***************************************************************************;*;* Title : AVR ISP (Auto adr inc, 19200bps);* Version : 2.0;* Last updated : 1998.01.06 (mlund);* Target : AT90S1200;* File : ispprog.asm;* Author : Atmel Norway;*;* DESCRIPTION;* The firmware on all programmers now support a unified protocol for ;* program and data memory programming. The host computer do not need;* to know if the programmer operates in serial or parallel mode.;*;* The following commands are supported. All commands start with a;* single letter. The programmer returns 13d (carriage return) or the;* data read after the command is finished.;*;* +-------------+------------+------+;* Commands | Host writes | Host reads | |;* -------- +-----+-------+------+-----+ |;* | ID | data | data | | Note |;* +-----------------------------------+-----+-------+------+-----+------+;* | Enter programming mode | 'P' | | | 13d | 1 |;* | Set address | 'A' | ah al | | 13d | 2 |;* | Write program memory, low byte | 'c' | dd | | 13d | 3 |;* | Write program memory, high byte | 'C' | dd | | 13d | 3 |;* | Issue Page Write | 'm' | | | 13d | |;* | Read program memory | 'R' | |dd(dd)| | 4 |;* | Write data memory | 'D' | dd | | 13d | |;* | Read data memory | 'd' | | dd | | |;* | Chip erase | 'e' | | | 13d | |;* | Write lock bits | 'l' | dd | | 13d | |;* | Write fuse bits | 'f' | dd | | 13d | 11 |;* | Read fuse and lock bits | 'F' | | dd | | 11 |;* | Leave programming mode | 'L' | | | 13d | 5 |;* | Select device type | 'T' | dd | | 13d | 6 |;* | Read signature bytes | 's' | | 3*dd | | |;* | Return supported device codes | 't' | | n*dd | 00d | 7 |;* | Return software identifier | 'S' | | s[7] | | 8 |;* | Return sofware version | 'V' | |dd dd | | 9 |;* | Return hardware version | 'v' | |dd dd | | 9 |;* | Return programmer type | 'p' | | dd | | 10 |;* | Set LED | 'x' | dd | | 13d | 12 |;* | Clear LED | 'y' | dd | | 13d | 12 |;* | Universial command | ':' | 3*dd | dd | 13d | |;* +-----------------------------------+-----+-------+------+-----+------+;*;* NOTE 1;* The Enter programming mode command MUST be sent one time prior to;* the other commands, with the exception of the 't', 'S', 'V', 'v';* and 'T' commands. The 'T' command must be sent before this command;* (see note 6).;*;* For programmers supporting both parallel and serial programming;* mode this command enters parallel programming mode. For programmers;* supporting only serial programming mode, this command enters serial;* programming mode.;*;* NOTE 2;* The ah and al are the high and low order bytes of the address. For;* parallel programmers this command issues the Load Address Low/High;* Byte command. For serial programmers the address byte is stored for;* use by the Read/Write commands.;*;* NOTE 3;* For parallel programmers this command issues the Program Flash;* command. For serial programmers this command iussues the Write;* Program Memory Command. For devices with byte-wide program memories;* only the low byte command should be used.;*;* NOTE 4;* The contents of the program memory at the address given by the 'A';* command are written to the serial port in binary form. For byte;* wide memories one byte is written. For 16 bit memories two bytes;* are written,MSB first.;*;* NOTE 5;* This command must be executed after the programming is finished.;*;* NOTE 6;* The select device type command must be sent before the enter;* programming command;*;* NOTE 7;* The supported device codes are returned in binary form terminated;* by 0x00.;*;* NOTE 8;* This return a 7 character ASCII string identifying the programmer.;* For the in-system programmer it is "AVR ISP".;*;* NOTE 9;* The software/hardware version are returned as two ASCII numbers.;*;* NOTE 10;* This command should be used to identify the programmer type. The;* return value is 'S' for serial (or SPI) programmers or 'P' for;* parallel programmers.;*;* NOTE 11;* The write fuse bits command are available only on parallel;* programmers and only for AVR devices (device code < 0x80). The host;* should use the return programmer type command to determine the;* programmer type, do not use the "AVR PPR" idenifier because other;* programmers may be available in the future.;*;* NOTE 12;* Currently only the AVR development board has LEDs. The other boards;* must implement this commands as NOPs.;*;* NOTE 13;* Devices using Page Mode Programming write one page of flash memory;* before issuing a Page Mode Write Pulse.;***************************************************************************;**** includes ****.include "1200def.inc";***************************************************************************;*;* 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.;*;* The following devices are supported (make a new table for each;* software release):;*;* SW_MAJOR=1, SW_MINOR=5 ;* AT90S1200 rev. C (abbreviated S1200C);* AT90S1200 rev. D (abbreviated S1200D);* AT90S8515 rev. A (abbreviated S8515A);* AT89S8252 (abbreviated S8252);*;* SW_MAJOR=1, SW_MINOR=6;* AT90S1200 rev. C (abbreviated S1200C);* AT90S1200 rev. D (abbreviated S1200D);* AT90S8515 rev. A (abbreviated S8515A);* AT89S8252 (abbreviated S8252);* ATmega103 rev. A (abbreviated S01838A);*;***************************************************************************.equ S1200C = 0x12.equ S1200D = 0x13.equ S2313A = 0x20.equ S4414A = 0x28.equ S8515A = 0x38.equ S8252 = 0x86.equ S2323A = 0x48.equ S01838C = 0x40.equ S01838D = 0x41;**** Revision Codes ****.equ SW_MAJOR = 2 ; Major SW revision number.equ SW_MINOR = 0 ; Minor SW revision number.equ HW_MAJOR = 1 ; Major HW revision number.equ 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.;*;***************************************************************************.macro set_reset sbi portb,4.endm.macro clr_reset cbi portb,4.endm.macro ddrd_init nop; sbi ddrd,3.endm.macro ddrb_init ldi temp1,0xdf out ddrb,temp1 ; PB5 is input, the rest is output.endm.macro ddrb_release ldi temp1,(1<<PB4) out ddrb,temp1 ; PB4 (RESET) is output, the rest is input.endm.macro pulse_sck sbi portb,SCK ldi temp2,6m0: dec temp2 brne m0 cbi portb,SCK ldi temp2,1 ; 3m1: dec temp2 brne m1.endm;*****************;* SPI Constants *;*****************.equ MOSI = 6 ; Bit number on PORTB.equ MISO = 5 ; Bit number on PORTB.equ SCK = 7 ; Bit number on PORTB;******************;* UART Constants *;******************;**** Constant declarations Data Rate ****;.equ N = 95 ; 115200 BAUD when R=1 and XTAL=11.059MHz;.equ N = 31 ; 57600 BAUD when R=2 and XTAL=11.059MHz;.equ N = 43 ; 38400 BAUD when R=2 and XTAL=11.059MHz.equ N = 33 ; 19200 BAUD when R=2 and XTAL=4.00MHz;.equ N = 102 ; 38400 BAUD when R=1 and XTAL=4.00MHz.equ R = 2;**** UART transmit pin in PORTD ****.equ TXPIN = 1.equ RXPIN = 0 ; Receive pin must be external interrupt !!;**** Bit positions in UART Status Register ****.equ TXC = 0 ; Transmit.equ RXC = 1 ; Receive;*****************************;* Global Register Variables *;*****************************.def device = r16 ; Device code.def temp1 = r17.def temp2 = r18.def s_data = r19 ; SPI data.def u_data = r20 ; UART data.def addrl = r21 ; Low order byte of address.def addrh = r22 ; High order byte of address.def bit_cnt = r23 ; Bit count used by UART routine.def u_stat = r24 ; Status byte used by UART routine.def cmd = r25 ; Serial programming command.def count = r26 ; Time out variable for "enter programming mode".def param1 = r27.def cmd1 = r28.def cmd2 = r29.def cmd3 = r30;*********************;* Interrupt Vectors *;*********************.CSEG rjmp RESET ; Reset Handle reti ; IRQ0 Handle (not used) rjmp TIM0_OVF ; Timer0 Overflow Handle reti ; Analog Comparator Handle (not used);***************************************************************************;*;* INTERRUPT;* TIM0_OVF - Software UART Service Routine;*;***************************************************************************TIM0_OVF: in r0,SREG ; store SREG ldi temp1,(256-N+8) out TCNT0,temp1 ; reset T/C0 to one bit lenght inc bit_cnt ; increment bit counter sbrs u_stat,TXC ; if (transmit complete flag clear) rjmp transmit ; goto transmitto_0: sec ; set carry sbis PIND,RXPIN ; if (RxD == LOW) clc ; clear carry ror u_data ; shift carry into u_data cpi bit_cnt,8 ; if (bit_cnt == 8) brne to_1 ; { clr temp1 ; disable T/C0 Overflow Interrupt out TIMSK,temp1 sbr u_stat,1<<RXC ; set receive completeto_1: ; } out SREG,r0 ; restore SREG reti ; exittransmit: cpi bit_cnt,1 ; if (bit_cnt == 1) \\ start bit brne to_2 ; { cbi PORTD,TXPIN ; generate start bit rjmp to_1 ; exitto_2: ; } cpi bit_cnt,10 ; if (bit_cnt == 10) \\ stop bit brne to_3 ; { sbi PORTD,TXPIN ; generate stop bit clr temp1 ; disable TC0 overflow interrupt out TIMSK,temp1 sbr u_stat,1<<TXC ; set transmit complete bit rjmp to_1 ; exitto_3: ; } sbrc u_data,0 ; if (LSB set) sbi PORTD,TXPIN ; PD3 = HIGH sbrs u_data,0 ; if (LSB clear) cbi PORTD,TXPIN ; PD3 = LOW lsr u_data ; shift left u_data rjmp to_1 ; exit;***************************************************************************;*;* FUNCTION;* u_init;*;* DESCRIPTION;* Initialize UART.;*;***************************************************************************u_init: ldi u_stat,1<<TXC ; set TXC ldi temp1,R ; set clock rate out TCCR0,temp1 sbi DDRD,TXPIN ; initialize UART pins cbi DDRD,RXPIN ret;***************************************************************************;*;* FUNCTION;* putc;*;* DESCRIPTION;* Send a character on the UART Tx line.;*;***************************************************************************putc: clr u_stat ; clear UART status flags clr bit_cnt ; clear bit counter ldi temp1,1<<TOV0 ; enable T/C0 overflow interrupt out TIMSK,temp1putc0: sbrs u_stat,TXC ; while (!(u_stat & TXC)); // Wait for TXC rjmp putc0 ret;***************************************************************************;*;* FUNCTION;* getc;*;* DESCRIPTION;* Wait for start bit and receive a character on the UART Rx line.;*;***************************************************************************getc: sbis PIND,RXPIN rjmp getcgetc0: sbic PIND,RXPIN rjmp getc0 ldi temp1,(256-(N+N/2)+8+12); out TCNT0,temp1 ; preset T/C0 to 1.5 bit lengths ldi temp1,1<<TOIE0 out TIFR,temp1 ; clear T/C0 overflow flag out TIMSK,temp1 ; enable T/C0 overflow Interrupt clr bit_cnt ; clear bit countergetc1: sbrs u_stat,RXC ; wait for Receive Complete rjmp getc1 cbr u_stat,1<<RXC ; clear RXC ret;***************************************************************************;*;* FUNCTION;* delay;*;* DESCRIPTION;* Make a small delay.;*;***************************************************************************delay: ldi temp2,0xffdl: dec temp2 brne dl dec temp1 brne delay ret;***************************************************************************;*;* FUNCTION;* wrser;*;* DESCRIPTION;* Write a byte to the SPI.;*;***************************************************************************wrser: ldi temp1,8wrs0: rol s_data brcc wrs1 sbi portb,MOSI rjmp wrs2wrs1: cbi portb,MOSIwrs2: pulse_sck dec temp1 brne wrs0 ret;***************************************************************************;*;* FUNCTION;* rdser;*;* DESCRIPTION;* Read a byte from the SPI.;*;***************************************************************************rdser: ldi temp1,8 ldi s_data,0rd0: lsl s_data sbic pinb,MISO ori s_data,1 pulse_sck dec temp1 brne rd0 ret;***************************************************************************;*;* FUNCTION;* spiinit (Enter programming mode);*;* DESCRIPTION;* Initialize SPI interface on AVR or 'AT89 device.;*;***************************************************************************spiinit:ddrd_init ; initialize port D ddrb_init ; initialize port B cbi portb,SCK ; clear SCK cpi device,S8252 ; if (device != S8252) breq s89 ; { set_reset ; set RESET = 1 ldi temp1,0xff ; delay(0xff); rcall delay clr_reset ; set RESET = 0 rjmp s0 ; } ; elses89: ; { clr_reset ; set RESET = 0 ldi temp1,0xff ; delay(0xff); rcall delay set_reset ; set RESET = 1s0: ; } 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 s2s0b: ; { 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 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 ; } ; elses2: ; { ldi s_data,0x00 ; wrser(0x00); // SPI write (byte 3) rcall wrsers3: ; } cpi device,S8252 ; if (device != S8252) breq s4 ; { ldi s_data,0x00 ; wrser(0x00); // SPI write (byte 4) rcall wrsers4: ; } ldi temp1,0x10 ; delay(0x10); rcall delay ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -