Full Version : How to Setup ISP Connection (AVR ASM)
avr >>COMMUNICATIONS & WEB PROJECTS >>How to Setup ISP Connection (AVR ASM)


AVR_Admin- 05-17-2006
How to Setup ISP Connection (AVR ASM)

CODE

;***************************************************************************
;*
;* 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,6
m0: dec temp2
brne m0
cbi portb,SCK
ldi temp2,1; 3
m1: 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 transmit

to_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 complete
to_1:  ; }
out SREG,r0        ; restore SREG
reti  ; exit

transmit:
cpi bit_cnt,1; if (bit_cnt == 1) \\ start bit
brne to_2; {
cbi PORTD,TXPIN; generate start bit
rjmp to_1; exit
to_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; exit
to_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,temp1
putc0: 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 getc
getc0: 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 counter
getc1: 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,0xff
dl: dec temp2
brne dl
dec temp1
brne delay
ret


;***************************************************************************
;*
;* FUNCTION
;* wrser
;*
;* DESCRIPTION
;*  Write a byte to the SPI.
;*
;***************************************************************************

wrser: ldi temp1,8
wrs0: rol s_data
brcc wrs1
sbi portb,MOSI
rjmp wrs2
wrs1: cbi portb,MOSI
wrs2: pulse_sck
dec temp1
brne wrs0
ret


;***************************************************************************
;*
;* FUNCTION
;* rdser
;*
;* DESCRIPTION
;*  Read a byte from the SPI.
;*
;***************************************************************************

rdser: ldi temp1,8
ldi s_data,0
rd0: 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; }
 ; else
s89:  ; {
clr_reset;  set RESET = 0
ldi temp1,0xff; delay(0xff);
rcall delay
set_reset; set RESET = 1
s0:  ; }
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
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:  ; }
cpi device,S8252; if (device != S8252)
breq s4; {
ldi s_data,0x00; wrser(0x00); // SPI write (byte 4)
rcall wrser
s4:  ; }
ldi temp1,0x10; delay(0x10);
rcall delay
ret



;***************************************************************************
;*
;* FUNCTION
;* show_id
;*
;* DESCRIPTION
;* Show our ID ("AVR ISP") on the serial line.
;*
;***************************************************************************

show_id:ldi u_data,0x41; 'A'
rcall putc
ldi u_data,0x56; 'V'
rcall putc
ldi u_data,0x52; 'R'
rcall putc
ldi u_data,0x20; ' '
rcall putc
ldi u_data,0x49; 'I'
rcall putc
ldi u_data,0x53; 'S'
rcall putc
ldi u_data,0x50; 'P'
rcall putc
ret


;***************************************************************************
;*
;* RESET
;*
;* DESCRIPTION
;* Initialization
;*
;***************************************************************************

RESET: clr temp1
out GIMSK,temp1; disable external interrupt
ser temp1; Initialize
out PORTD,temp1
set_reset; set RESET=1
out PORTB,temp1
ddrb_release
rcall u_init; Initialize UART
sei  ; Enable interrupts


;***************************************************************************
;*
;* 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 w2
ldi u_data,0x30+SW_MAJOR; putc(0x30+SW_MAJOR);
rcall putc
ldi u_data,0x30+SW_MINOR; putc(0x30+SW_MINOR);
rcall putc
rjmp waitcmd

;**** Return Hardware Version ****

w2: cpi u_data,0x76;'v' Return hardware version
brne w3
ldi u_data,0x30+HW_MAJOR; putc(0x30+HW_MAJOR);
rcall putc
ldi u_data,0x30+HW_MINOR; putc(0x30+HW_MINOR);
rcall putc
rjmp waitcmd

;**** Show Supported Devices ****

w3: cpi u_data,0x74; 't' Show supported devices
brne w4
ldi u_data,S1200C; putc(S1200C);
rcall putc
ldi u_data,S1200D; putc(S1200D);
rcall putc
ldi u_data,S2313A; putc(S2313A);
rcall putc
ldi u_data,S4414A; putc(S4414A);
rcall putc
ldi u_data,S8515A; putc(S8515A);
rcall putc
ldi u_data,S2323A; putc(S2323A);
rcall putc
ldi u_data,S8252; putc(S8252);
rcall putc
ldi u_data,0x00; putc(0x00); // end of device list
rcall putc
rjmp waitcmd

;**** Return Programmer Type ****

w4: cpi u_data,0x70    ; 'p' Return programmer type
brne w5
ldi u_data,0x53    ; putc('S'); // serial programmer
rcall putc
rjmp waitcmd

;**** Set LED ****

w5: cpi u_data,0x78; 'x' Set LED (ignored)
brne w6
rjmp put_ret

;**** Clear LED ****

w6: cpi u_data,0x79    ; 'y' Clear LED (ignored)
brne w7
rjmp put_ret

;**** Enter Programming Mode ****

; We require that the device code be selected before any of the other commands

w7:
cpi device,S1200C; if ((device != S1200C) &&
breq w72
cpi device,S1200D;     (device != S1200D) &&
breq w72
cpi device,S8515A;     (device != S8515A) &&
breq w72
cpi device,S4414A;     (device != S4414A) &&
breq w72
cpi device,S2313A;     (device != S2313A) &&
breq w72
cpi device,S8252;     (device != S8252) &&
breq w72
cpi device,S01838C;     (device != S01838C) &&
breq w72
cpi device,S01838D;     (device != S01838D) &&
breq w72
cpi device,S2323A;     (device != S2323A))
breq w72
rjmp put_err; goto put_err();

w72: cpi u_data,0x50; 'P' Enter programming mode
brne w8
rcall spiinit; spiinit();
rjmp put_ret

;**** Wait Program Memory ****

;* USAGE
;* wait_pm(byte cmd, byte c_data);
;*
;* cmd :  0x28 - wait for high byte written
;*   0x20 - wait for low byte written
;* u_data : current data written

;wait_pm:  ; do
;  ; {
; mov s_data,cmd; wrser(cmd);  // SPI write (byte 1)
; rcall wrser
; mov s_data,addrh; wrser(addrh);  // SPI write (byte 2)
; rcall wrser
; mov s_data,addrl; wrser(addrl);  // SPI write (byte 3)
; rcall wrser
; rcall rdser; s_data = rdser(); // SPI read (byte 4)
 ; }
; cp s_data,u_data; while(s_data != u_data);
; brne wait_pm
; ret

;**** Write Program Memory, High Byte ****

w8: cpi u_data,0x43; 'C' Write program memory, high byte
brne w9
rcall getc
cpi device,S8252; if (device == S8252)
brne w81; {
rjmp put_err;  goto err();
 ; // (AT89 series have byte wide program memory !)
 ; }
w81: ldi s_data,0x48; wrser(0x48);  // SPI write (byte 1)
rcall wrser
mov s_data,addrh; wrser(addrh);  // SPI write (byte 2)
rcall wrser
mov s_data,addrl; wrser(addrl);  // SPI write (byte 3)
rcall wrser
cpi device,S01838C; invert data on 01838 rev C!
brne w81b
com u_data
w81b:
mov s_data,u_data; wrser(u_data); // SPI write (byte 4)
rcall wrser
cpi device,S01838C; no delay for S01838 (Uses Page Write Mode instead)
breq w82
cpi device,S01838D
breq w82

ldi temp1,0x20; delay(0x20);  // 24585 cycles delay
rcall delay;   // Page mode requires no delay!
w82:
ldi temp1,0x01; Auto increment address    !!!!
clr temp2
add addrl,temp1
adc addrh,temp2
rjmp put_ret; goto reply();

;**** Write Program Memory, Low Byte ****

w9: cpi u_data,0x63    ; 'c' Write program memory, low byte
brne w12
rcall getc

cpi device,S8252; if (device != S8252)
breq w989; {
ldi s_data,0x40; wrser(0x40); // SPI write (byte 1)
rcall wrser
mov s_data,addrh; s_data = addrh;
rjmp w91; }
 ; else
w989:  ; {
mov s_data,addrh; s_data = (addrh << 3) | 0x02;
rcall shift_s_data3
ori s_data,0x02
w91:  ; }
rcall wrser; wrser(s_data); // SPI write (byte 2)
mov s_data,addrl; wrser(addrl);  // SPI write (byte 3)
rcall wrser
cpi device,S01838C; invert data on 01838 rev C!
brne w91b
com u_data
w91b:
mov s_data,u_data; wrser(u_data); // SPI write (byte 4)
rcall wrser
cpi device,S01838C; no delay for S01838 (Uses Page Write Mode instead)
breq w92
cpi device,S01838D
breq w92
ldi temp1,0x20; delay(0x20);  // 24585 cycles delay
rcall delay;   // Page mode requires no delay!
w92:
rjmp put_ret; goto reply();

;**** Read Program Memory ****

w12: cpi u_data,0x52; 'R' Read program memory
brne w10;
cpi device,S8252; if (device != S8252)
breq w1289; {
ldi s_data,0x28; wrser(0x28); // SPI write (byte 1)
rcall wrser
mov s_data,addrh; s_data = addrh;
rjmp w121; }
 ; else
w1289:  ; {
mov s_data,addrh; s_data = (addrh << 3) | 0x01;
rcall shift_s_data3
ori s_data,0x01
w121:  ; }
rcall wrser; wrser(s_data); // SPI write (byte 2)
mov s_data,addrl; wrser(addrl);  // SPI write (byte 3)
rcall wrser
rcall rdser; putc(rdser()); // Send data (byte 4)
mov u_data,s_data
rcall putc
cpi device,S8252; if (device == S8252)
brne w122; {
rjmp waitcmd; goto waitcmd();
 ; }
 ; else
w122:  ; {
ldi s_data,0x20; wrser(0x20); // SPI write (byte 1)
rcall wrser
mov s_data,addrh; wrser(addrh); // SPI write (byte 2)
rcall wrser
mov s_data,addrl; wrser(addrl); // SPI write (byte 3)
rcall wrser
rcall rdser; putc(rdser()); // Send data (byte 4)
mov u_data,s_data
rcall putc

ldi temp1,0x01; Auto increment address    !!!!
clr temp2
add addrl,temp1
adc addrh,temp2

rjmp waitcmd; goto waitcmd();
 ; }
shift_s_data3:
lsl s_data
lsl s_data
lsl s_data
ret

;**** Load Address ****

w10: cpi u_data,0x41; 'A' Load address
brne w11
rcall getc; addrh = getc();
mov addrh,u_data
rcall getc; addrl = getc();
mov addrl,u_data
rjmp put_ret; goto reply();

;**** Write Data Memory ****

w11: cpi u_data,0x44; 'D' Write data memory
brne w13
rcall getc
cpi device,S8252
breq w1189

ldi s_data,0xc0
rcall wrser
mov s_data,addrh
rjmp w111

w1189: mov s_data,addrh
rcall shift_s_data3
ori s_data,0x06

w111: rcall wrser
mov s_data,addrl
rcall wrser
mov s_data,u_data
rcall wrser
ldi temp1,0x20
rcall delay
rjmp put_ret

;;**** Read Data Memory ****

w13: cpi u_data,0x64; 'd' Read data memory
brne w14
cpi device,S8252; if (device != S8252)
breq w1389; {
ldi s_data,0xa0; wrser(0xA0); // SPI write (byte 1)
rcall wrser
mov s_data,addrh; s_data = addrh;
rjmp w131; }
 ; else
w1389:  ; {
mov s_data,addrh; s_data = (addrh << 3) | 0x05;
rcall shift_s_data3
ori s_data,0x05
w131:  ; }
rcall wrser; wrser(s_data); // SPI write (byte 2)
mov s_data,addrl; wrser(addrl);  // SPI write (byte 3)
rcall wrser
rcall rdser; putc(rdser()); // Send data (byte 4)
mov u_data,s_data
rcall putc
rjmp waitcmd; goto waitcmd();


;**** Leave Programming Mode ****

w14: cpi u_data,0x4c; 'L' Leave programming mode
brne w15
ddrb_release
cpi device,S8252
breq w141
set_reset; set RESET = 1
rjmp    put_ret
w141: clr_reset; set RESET = 0
rjmp put_ret

;**** Chip Erase ****

w15: cpi u_data,0x65    ; 'e' Chip erase
       brne w16
ldi s_data,0xac
rcall wrser
cpi device,S8252
breq w1589
ldi s_data,0x80
rcall wrser
w1589: ldi s_data,0x04
rcall wrser
ldi s_data,0x00
rcall wrser
ldi temp1,0x30
rcall delay
rjmp put_ret

;**** Write Lock Bits ****

w16: cpi u_data,0x6c; 'l' Write lock bits
brne w17
rcall getc
ldi s_data,0xac
rcall wrser
mov s_data,u_data
cpi device,S8252
breq w1689
andi s_data,0x06
ori s_data,0xe0
rcall wrser
ldi s_data,0x00
rcall wrser
rjmp w162

w1689: andi s_data,0xe0
ori s_data,0x07
rcall wrser
w162: ldi s_data,0x00
rcall wrser
ldi temp1,0x30
rcall delay
rjmp put_ret

;**** Read Signature Bytes ****

w17: cpi u_data,0x73; 's' Read signature bytes
brne w18
cpi device,S8252
brne w17begin
rjmp put_err
w17begin:
ldi param1,0x02
rcall w17call
ldi param1,0x01
rcall w17call
ldi param1,0x00
rcall w17call
rjmp waitcmd

w17call:ldi s_data,0x30
rcall wrser
ldi s_data,0x00
rcall wrser
mov s_data,param1
rcall wrser
rcall rdser
mov u_data,s_data
rcall putc
ret


;**** Write Program Memory Page ****

w18: cpi u_data,0x6D; 'm' Write Program Memory Page
brne w19

ldi s_data,0x4c; wrser(0x4c); // SPI write (byte 1)
rcall wrser

mov s_data,addrh; wrser(addrh); // SPI write (byte 2)
rcall wrser
mov s_data,addrl; wrser(addrl); // SPI write (byte 3)
rcall wrser

ldi s_data,0x00; wrser(0x00); // SPI write (byte 4)
rcall wrser
ldi temp1,0xff;  delay(0xFF); // 0x20 = 24585 cycles delay
rcall delay
rjmp put_ret

;**** Universal Command ****

w19: cpi u_data,0x3A; ':' Universal Command
brne w99

rcall getc
mov cmd1,u_data
rcall getc
mov cmd2,u_data
rcall getc
mov cmd3,u_data
rcall universal
ldi temp1,0xff;  delay(0xFF); // 0x20 = 24585 cycles delay
rcall delay
rjmp put_ret

universal:
mov s_data,cmd1
rcall wrser
mov s_data,cmd2
rcall wrser
mov s_data,cmd3
rcall wrser
rcall rdser
mov u_data,s_data
rcall putc
ret

w99:

;**** Command Error ****

put_err:ldi u_data,0x3f; putc('?'); \\ send '?'
rcall putc
rjmp waitcmd

;**** Reply Command ****

put_ret:ldi u_data,0x0d; putc(0x0D); \\ send CR
rcall putc
rjmp waitcmd

;**** End of File ****



Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.