da7b6e47c7
This includes the files as of wget http://www.fischl.de/usbasp/usbasp.2011-05-28.tar.gz tar -xf usbasp.2011.05-28.tar.gz
259 lines
4.6 KiB
ArmAsm
259 lines
4.6 KiB
ArmAsm
/**
|
|
* \brief Size-optimized code for TPI
|
|
* \file tpi.s
|
|
* \author S³awomir Fraœ
|
|
*/
|
|
#include <avr/io.h>
|
|
#include "tpi_defs.h"
|
|
|
|
|
|
#define TPI_CLK_PORT PORTB
|
|
#define TPI_CLK_DDR DDRB
|
|
#define TPI_CLK_BIT 5
|
|
#define TPI_DATAOUT_PORT PORTB
|
|
#define TPI_DATAOUT_DDR DDRB
|
|
#define TPI_DATAOUT_BIT 3
|
|
#ifdef TPI_WITH_OPTO
|
|
# define TPI_DATAIN_PIN PINB
|
|
# define TPI_DATAIN_DDR DDRB
|
|
# define TPI_DATAIN_BIT 4
|
|
#else
|
|
# define TPI_DATAIN_PIN PINB
|
|
# define TPI_DATAIN_BIT 3
|
|
#endif
|
|
|
|
.comm tpi_dly_cnt, 2
|
|
|
|
|
|
/**
|
|
* TPI init
|
|
*/
|
|
.global tpi_init
|
|
tpi_init:
|
|
/* CLK <= out */
|
|
sbi _SFR_IO_ADDR(TPI_CLK_DDR), TPI_CLK_BIT
|
|
#ifdef TPI_WITH_OPTO
|
|
/* DATAIN <= pull-up */
|
|
cbi _SFR_IO_ADDR(TPI_DATAIN_DDR), TPI_DATAIN_BIT
|
|
sbi _SFR_IO_ADDR(TPI_DATAIN_PORT), TPI_DATAIN_BIT
|
|
/* DATAOUT <= high */
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
#else
|
|
/* DATA <= pull-up */
|
|
cbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
#endif
|
|
|
|
/* 32 bits */
|
|
ldi r21, 32
|
|
1:
|
|
rcall tpi_bit_h
|
|
dec r21
|
|
brne 1b
|
|
|
|
ret
|
|
|
|
|
|
/**
|
|
* Update PR
|
|
* in: r25:r24 <= PR
|
|
* lost: r18-r21,r24,r30-r31
|
|
*/
|
|
tpi_pr_update:
|
|
movw r20, r24
|
|
ldi r24, TPI_OP_SSTPR(0)
|
|
rcall tpi_send_byte
|
|
mov r24, r20
|
|
rcall tpi_send_byte
|
|
ldi r24, TPI_OP_SSTPR(1)
|
|
rcall tpi_send_byte
|
|
mov r24, r21
|
|
// rjmp tpi_send_byte
|
|
|
|
|
|
/**
|
|
* Send one byte
|
|
* in: r24 <= byte
|
|
* lost: r18-r19,r30-r31
|
|
*/
|
|
.global tpi_send_byte
|
|
tpi_send_byte:
|
|
/* start bit */
|
|
rcall tpi_bit_l
|
|
/* 8 data bits */
|
|
ldi r18, 8
|
|
ldi r19, 0
|
|
1:
|
|
// parity
|
|
eor r19, r24
|
|
// get bit, shift
|
|
bst r24, 0
|
|
lsr r24
|
|
// send
|
|
rcall tpi_bit
|
|
dec r18
|
|
brne 1b
|
|
/* parity bit */
|
|
bst r19, 0
|
|
rcall tpi_bit
|
|
/* 2 stop bits */
|
|
rcall tpi_bit_h
|
|
// rjmp tpi_bit_h
|
|
|
|
|
|
/**
|
|
* Exchange of one bit
|
|
* in: T <= bit_in
|
|
* out: T => bit_out
|
|
* lost: r30-r31
|
|
*/
|
|
tpi_bit_h:
|
|
set
|
|
tpi_bit:
|
|
/* TPIDATA = T */
|
|
#ifdef TPI_WITH_OPTO
|
|
// DATAOUT = high (opto should allow TPIDATA to be pulled low by external device)
|
|
// if(T == 0)
|
|
// DATAOUT = low
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
brts 1f
|
|
tpi_bit_l:
|
|
cbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
1:
|
|
#else
|
|
// DATAOUT = pull-up
|
|
// if(T == 0)
|
|
// DATAOUT = low
|
|
cbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
brts 1f
|
|
tpi_bit_l:
|
|
cbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT
|
|
sbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT
|
|
1:
|
|
#endif
|
|
/* delay(); */
|
|
lds r30, tpi_dly_cnt
|
|
lds r31, tpi_dly_cnt+1
|
|
1:
|
|
sbiw r30, 1
|
|
brsh 1b
|
|
/* TPICLK = 1 */
|
|
sbi _SFR_IO_ADDR(TPI_CLK_PORT), TPI_CLK_BIT
|
|
/* T = TPIDATA */
|
|
in r30, _SFR_IO_ADDR(TPI_DATAIN_PIN)
|
|
bst r30, TPI_DATAIN_BIT
|
|
/* delay(); */
|
|
lds r30, tpi_dly_cnt
|
|
lds r31, tpi_dly_cnt+1
|
|
1:
|
|
sbiw r30, 1
|
|
brsh 1b
|
|
|
|
/* TPICLK = 0 */
|
|
cbi _SFR_IO_ADDR(TPI_CLK_PORT), TPI_CLK_BIT
|
|
ret
|
|
|
|
|
|
/**
|
|
* Receive one byte
|
|
* out: r24 => byte
|
|
* lost: r18-r19,r30-r31
|
|
*/
|
|
.global tpi_recv_byte
|
|
tpi_recv_byte:
|
|
/* waitfor(start_bit, 192); */
|
|
ldi r18, 192
|
|
1:
|
|
rcall tpi_bit_h
|
|
brtc .tpi_recv_found_start
|
|
dec r18
|
|
brne 1b
|
|
/* no start bit: set return value */
|
|
.tpi_break_ret0:
|
|
ldi r24, 0
|
|
/* send 2 breaks (24++ bits) */
|
|
ldi r18, 26
|
|
1:
|
|
rcall tpi_bit_l
|
|
dec r18
|
|
brne 1b
|
|
/* send hi */
|
|
rjmp tpi_bit_h
|
|
|
|
// ----
|
|
.tpi_recv_found_start:
|
|
/* recv 8bits(+calc.parity) */
|
|
ldi r18, 8
|
|
ldi r19, 0
|
|
1:
|
|
rcall tpi_bit_h
|
|
lsr r24
|
|
bld r24, 7
|
|
eor r19, r24
|
|
dec r18
|
|
brne 1b
|
|
/* recv parity */
|
|
rcall tpi_bit_h
|
|
bld r18, 7
|
|
eor r19, r18
|
|
brmi .tpi_break_ret0
|
|
/* recv stop bits */
|
|
rcall tpi_bit_h
|
|
rjmp tpi_bit_h
|
|
|
|
|
|
/**
|
|
* Read Block
|
|
*/
|
|
.global tpi_read_block
|
|
tpi_read_block:
|
|
// X <= dptr
|
|
movw XL, r22
|
|
// r23 <= len
|
|
mov r23, r20
|
|
/* set PR */
|
|
rcall tpi_pr_update
|
|
/* read data */
|
|
.tpi_read_loop:
|
|
ldi r24, TPI_OP_SLD_INC
|
|
rcall tpi_send_byte
|
|
rcall tpi_recv_byte
|
|
st X+, r24
|
|
dec r23
|
|
brne .tpi_read_loop
|
|
ret
|
|
|
|
|
|
/**
|
|
* Write block
|
|
*/
|
|
.global tpi_write_block
|
|
tpi_write_block:
|
|
// X <= sptr
|
|
movw XL, r22
|
|
// r23 <= len
|
|
mov r23, r20
|
|
/* set PR */
|
|
rcall tpi_pr_update
|
|
/* write data */
|
|
.tpi_write_loop:
|
|
ldi r24, TPI_OP_SOUT(NVMCMD)
|
|
rcall tpi_send_byte
|
|
ldi r24, NVMCMD_WORD_WRITE
|
|
rcall tpi_send_byte
|
|
ldi r24, TPI_OP_SST_INC
|
|
rcall tpi_send_byte
|
|
ld r24, X+
|
|
rcall tpi_send_byte
|
|
.tpi_nvmbsy_wait:
|
|
ldi r24, TPI_OP_SIN(NVMCSR)
|
|
rcall tpi_send_byte
|
|
rcall tpi_recv_byte
|
|
andi r24, NVMCSR_BSY
|
|
brne .tpi_nvmbsy_wait
|
|
dec r23
|
|
brne .tpi_write_loop
|
|
ret
|