.include "2313def.inc"		;you can change this to any device
.include "vs1001par.inc"

.equ	int1_falling	= 0x08
.equ	int1_rising	= 0x0C
.equ	int0_rising	= 0x03
.equ	int1_ena	= 0x80
.equ	int0_ena	= 0x40

.def	vs1001_reg=	r10
.def	reg_data_hi=	r11
.def	reg_data_lo=	r12

.def	sreg_bak	=r15
.def	temp	=r16	;misc usage, must be in upper regs for IMMED mode
.def	spi_lo	=r17	;change as needed
.def	isr_temp_a	=r18
.def	isr_temp_b	=r19
.def	dly_a	=r20
.def	dly_b	=r21
.def	dly_c	=r22

;***************************************************************************
;*
;* SAMPLE APPLICATION, READY TO RUN ON AN AT90S1200
;*
;***************************************************************************

.cseg
.org	0
Rvect:	rjmp	Reset
;ext0:	reti
ext0:	rjmp	int_vs
ext1:	rjmp	int_pp

init_spi:
	nreset_hi
	sbi	p_nreset - 1,nreset
	
	ncs_hi
	sbi	p_ncs - 1,ncs	;make it an output
	
	si_lo
	sbi	p_si - 1,si	;make it an output
	;
	sclk_lo			
	sbi	p_sclk - 1,sclk	;make it an output
	;
	dclk_lo			
	sbi	p_dclk - 1,dclk	;make it an output
	;
	bsync_lo
	sbi	p_bsync - 1,bsync
	;
	cbi	p_so - 1,so
	cbi	p_dreq - 1,dreq	;not really required, it powers up clr'd!
	
	sr_clk_lo
	sbi	p_sr_clk - 1,sr_clk
	
	busy_hi
	sbi	p_busy - 1,busy
	
	nack_hi
	sbi	p_nack - 1,nack
	
	cbi	p_sr_out - 1,sr_out
	cbi	p_strobe - 1,strobe
		
	ret

ena_sci:
	sclk_lo			;(should already be there...)
	si_lo
	ret

ena_sdi:
	dclk_lo			;(should already be there...)
	sdata_lo
	ret

;*****************************
rw_sci:	
        ldi	temp,8		;use THIS line instead if 8-bit desired
sci_loop:
	lsl	spi_lo		;move 0 into D0, all other bits UP one slot,
	brcc	lo_si
	si_hi
	rjmp	si_done		;this branch creates setup time on MOSI
lo_si:
	si_lo
	nop			;also create setup time on MOSI
si_done:
	sclk_hi
	set_delay temp,4	;(4 * 3) cycle delay; range is from 1 to 7!
time_hi_1:
	inc_delay temp		;inc upper nibble until it rolls over; then,
	brcs	time_hi_1	; C gets CLEARED, & temp has original valu
	sclk_lo			;drop clock line low
	set_delay temp,4
time_lo_1:
	inc_delay temp
	brcs	time_lo_1
	sbic	p_so - 2,so		;after delay, read in SPI bit & put into D0
	inc	spi_lo		;we FORCED D0=0, so use INC to set D0.
	dec	temp
	brne	sci_loop
	ret
;****************************************
rw_sdi:	
	bsync_hi
        ldi	temp,8		;use THIS line instead if 8-bit desired
sdi_loop:
	lsl	spi_lo		;move 0 into D0, all other bits UP one slot,
	brcc	lo_sdata
	sdata_hi
	rjmp	sdata_done	;this branch creates setup time on MOSI
lo_sdata:
	sdata_lo
	nop			;also create setup time on MOSI
sdata_done:
	dclk_hi
	set_delay temp,4	;(4 * 3) cycle delay; range is from 1 to 7!
time_hi_2:
	inc_delay temp		;inc upper nibble until it rolls over; then,
	brcs	time_hi_2	; C gets CLEARED, & temp has original valu
	dclk_lo			;drop clock line low
	set_delay temp,4
time_lo_2:
	inc_delay temp
	brcs	time_lo_2
	
	dec	temp
	brne	sdi_loop
	
	bsync_lo
	ret


;*********************************************************************

five_us_delay:
	ldi	dly_a, 20
dlay:	dec	dly_a
	brne	dlay
	ret
;******************************************

write_reg:
	ldi 	spi_lo, vs_write
	rjmp	rw_common
read_reg:
	ldi	spi_lo, vs_read
rw_common:
	rcall	ena_sci
	ncs_lo
	rcall	rw_sci
	mov	spi_lo, vs1001_reg
	rcall	rw_sci
	mov	spi_lo, reg_data_hi
	rcall	rw_sci
	mov	reg_data_hi,spi_lo
	mov	spi_lo, reg_data_lo
	rcall	rw_sci
	mov	reg_data_lo,spi_lo
	ncs_hi
	ret
	
;***************VS DREQ interrupt
int_vs:	
	in	sreg_bak,SREG	;Saves the status register

	sbic	p_dreq - 2, dreq
	busy_lo

INT0_EXIT:
	out	SREG,sreg_bak	;restore the status register
	reti

;***************PP /STROBE interrupt************************************************************
int_pp:
	in	sreg_bak,SREG	;Saves the status register
	
w_hi:	sbis	p_strobe - 2,strobe
	rjmp	w_hi
	
	nack_lo
;	rcall five_us_delay
	nack_hi
	
;	busy_hi
	bsync_hi
	
	ldi	temp,8
	
sr_loop:
	sbic	p_sr_out - 2,sr_out		;after delay, read in SPI bit & put into D0
	rjmp	raise_sdata
	sdata_lo
	rjmp	sdata_dne	;this branch creates setup time on MOSI
raise_sdata:
	sdata_hi
	nop			;also create setup time on MOSI
sdata_dne:

	sr_clk_hi
	dclk_hi	
	
;	ldi dly_a,4	
;ck_hi:	dec dly_a
;	brne	ck_hi	
	
	sr_clk_lo			;drop clock line low
	dclk_lo
	
;	ldi dly_a,4	
;ck_lo:	dec dly_a	
;	brne	ck_lo
	
	dec	temp
	brne	sr_loop
	bsync_lo

	sbis	p_dreq - 2,dreq
	busy_hi
	
;	sbic	p_dreq - 2,dreq
;	busy_lo
	
INT1_EXIT:
	out	SREG,sreg_bak	;restore the status register
	reti
	
;***************************************************************************************************	
	
;**** Application example ****

Reset:	ldi	temp,low(RAMEND)	 
	out	SPL,temp
	
	rcall	init_spi
	
;* insert VS1001 initialization here
	nreset_lo
	nreset_hi
wait1:
	sbic	p_dreq - 2,dreq
	rjmp	wait1
wait2:
	sbis	p_dreq - 2,dreq
	rjmp	wait2
	
	ldi	temp,vs_clockf
	mov	vs1001_reg,temp
	ldi	temp,high(clockf)
	mov	reg_data_hi,temp
	ldi	temp,low(clockf)
	mov	reg_data_lo,temp
	rcall	write_reg
	
	rcall	five_us_delay
	
	ldi	temp,vs_vol
	mov	vs1001_reg,temp
	ldi	temp,0x00
	mov	reg_data_hi,temp
	ldi	temp, 0x00
	mov	reg_data_lo,temp
	rcall	write_reg
	
	rcall	five_us_delay
	
	ldi	temp,vs_mode
	mov	vs1001_reg,temp
	ldi	temp,0x00
	mov	reg_data_hi,temp
	ldi	temp, 0x00
	mov	reg_data_lo,temp
	rcall	read_reg
	
	rcall	five_us_delay
	
	ldi	temp,0x04
	or	reg_data_lo,temp
	ldi	temp,vs_mode
	mov	vs1001_reg,temp
	rcall	write_reg
	
	rcall	five_us_delay
	
init_isrs:		
	ldi	temp, int0_rising + int1_falling
	out	MCUCR,temp
	ldi	temp, int0_ena + int1_ena
;	ldi	temp, int1_ena
	out	GIMSK, temp
	sei
	rjmp	Main
	
Main:	rjmp	Main

;**** End of File ****



