;Correct video write sequence: send enable write: 2001a00 
;wait a MINIMUM of 35 ms for flash erase
;send frames... frame write takes about 550 us per frame
;wait at least 550 us after sending last frame
;send close write: 2000a00
;re-enable playback: 2080a00

;flash_memory_status
;bit 0 = 1 	ACTIVE
;bit 1 = 1 	ERASE
;bit 2 = 1	READ
;bit 3 = 1 	WRITE
;bit 4 = 1 	START
;bit 5 = 1 	END WRITE
;bit 6 = 1 	WRITE STATUS
;bit 7 = 1	VIDEO BUFFER 1/2 select
;time values @ 64 mhz, Fosc/16
;WRITE '00011001'writes contents of led_register to 48 bytes of flash pointed at by frame_pointer_0,1,2,
;time= ~550 us
;READ  '00010101'writes contents of flash to 48 bytes of RAM, one of two banks, video_buffer_1
;READ  '10010101'writes contents of flash to 48 bytes of RAM, one of two banks, video_buffer_2
;time= ~400 us
;ERASE '00010011'ERASES entire chip- poll ERASE BIT or ACTIVE for done.
;time= ~35 ms
;WRITE STATUS '01000001'writes 0x00 to status register- enables full write to chip.
;time= ~ 10 us
;frame_pointer is NOT corrupted by this routine.
;frame_pointer is multiplied by 48 to create memory pointer
;Uses FSR2!

flash_memory_routine

	btfss	flash_memory_status,0	;test ACTIVE bit
	return
	btfsc	flash_memory_status,1	;test ERASE bit
	bra		erase_mode
	btfsc	flash_memory_status,2	;test READ bit
	bra		read_mode
	btfsc	flash_memory_status,3	;test WRITE bit
	bra		write_mode
	btfsc	flash_memory_status,6	;test WRITE STATUS bit
	bra		write_status
	clrf	flash_memory_status		;illegal, clear and return
	return	

;**************************************************************
erase_mode	
	btfss	flash_memory_status,4	;test START bit
	bra		run_erase	;poll for busy bit clear = DONE
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x06		;WREN - write enable
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x60		;CHIP ERASE - ENTIRE MEMORY
	call	send_spi
	bcf		flash_memory_status,4	;clear START bit	
	bsf		LATD,7		;set /CE HIGH, Disable
	return
;**************************************************************************
run_erase
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x05		;read status
	call	send_spi
	movlw	0x00		;dummy data, generate clock
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	btfsc	SSP2BUF,0	;check BUSY BIT	
	return				;still busy...
	clrf	flash_memory_status
	return	;done with erase, reset status
;********************************************************
write_status
;clears write protection bits in STATUS REGISTER
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x06		;WREN - write enable
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x01		;WRITE STATUS
	call	send_spi
	movlw	0x00		;DATA TO STATUS REGISTER- disable write protect bits
	call	send_spi
	clrf	flash_memory_status		;reset STATUS	
	bsf		LATD,7			;set /CE HIGH, Disable
	return
;*************************************************************************
write_mode

	movf	write_bytes,F	;condition flags
	btfsc	STATUS,Z	
	return	;no bytes to write

	btfss	flash_memory_status,4	;test START bit
	bra		run_write	;write remaing bytes
;	call	calc_flash_address
;	lfsr	2,led_register 	;point FSR2 at LED REGISTER
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x70		;enable hardware BUSY checking
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x06		;WREN - write enable
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0xAD		;Auto-increment word program mode enable
	call	send_spi

	movlw	0		;High address
	call	send_spi

	movlw	0		;Mid address
	call	send_spi

	movlw	0		;Low address
	call	send_spi

	movf	POSTINC2,W		;DATA 0
	call	send_spi

	movf	POSTINC2,W		;DATA 1
	call	send_spi

	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable- now in HARDWARE DETECT MODE

	bcf		flash_memory_status,4	;clear START bit

	
	decf	write_bytes,F	;decrement
	return
;********************************************************
run_write
	btfss	PORTD,1					;test serial line for NOT BUSY= HI
	return							;it's busy, return
	bsf		LATD,7					;set /CE HIGH, Disable
	nop
	nop
	nop
	btfsc	flash_memory_status,5	;test WRITE END bit
	bra		write_end
;	movff	flash_fsr_0,FSR2L		;RESTORE FSR pointer value
;	movff	flash_fsr_1,FSR2H
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0xAD		;Auto-increment word program mode enable
	call	send_spi
	movf	POSTINC2,W		;DATA n
	call	send_spi
	movf	POSTINC2,W		;DATA n+1
;check for END OF WRITE SIGNAL
	btfss	WREG,7					;bit 7 of high byte is END WRITE SIGNAL
	bra		no_end
	btfss	WREG,6
	bra		no_end	
	bsf		flash_memory_status,5	;set WRITE END bit, BOTH bits 6 AND 7 must be HIGH
	bcf		LATC,7				;turn OFF RED STATUS LIGHT
no_end
	call	send_spi
	bsf		LATD,7					;set /CE HIGH, Disable
;	movff	FSR2L,flash_fsr_0		;save FSR pointer value
;	movff	FSR2H,flash_fsr_1
	nop
	bcf		LATD,7					;set /CE LOW, Enable- now in HARDWARE DETECT MODE	
	decf	write_bytes,F

	btfss	FSR2H,1
	return	
	lfsr	2,sample_buffer		;done 128 samples, reset
	return	

write_end	;shutdown write
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x04		;DISABLE WRITE
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	nop
	nop
	nop
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x80		;DISABLE HARDWARE BUSY TEST
	call	send_spi
	bsf		LATD,7		;set /CE HIGH, Disable
	clrf	flash_memory_status		;reset system.
	return
;********************************************************
read_mode
	btfss	flash_memory_status,4	;test START bit
	bra		run_read	;write remaing bytes
	bcf		LATD,7		;set /CE LOW, Enable
	movlw	0x03		;enable READ
	call	send_spi

	movlw	0				;High address
	call	send_spi

	movlw	0				;Mid address
	call	send_spi

	movlw	0				;Low address
	call	send_spi
	movlw	0x00		;DUMMY DATA		;data in buffer after this!
	call	send_spi
	bcf		flash_memory_status,4		;clear START bit
	return
run_read
	btfss	PIR3,SSP2IF	;test the interrupt flag
	return	;not ready
	movff	SSP2BUF,POSTINC2			;save byte
;	movf	SSP2BUF,W	;TEST GET DATA AND DO NOTHING
	movlw	0x00		;DUMMY DATA		;data in buffer after this!
	bcf		PIR3,SSP2IF	;clear the interrupt flag
	movwf	SSP2BUF		;load data into SPI buffer, start transmission

	btfss	FSR2L,0
	incf	write_bytes,F		;inc every other cycle

	btfss	FSR2H,1
	return	
	lfsr	2,sample_buffer		;done 128 samples, reset
	return	


	bsf		LATD,7						;set /CE HIGH, Disable
	clrf	flash_memory_status			;reset
	return




;*********************************************************
send_spi	;2 us time for this cycle
	bcf		PIR3,SSP2IF	;clear the interrupt flag
	movwf	SSP2BUF		;load data into SPI buffer, start transmission
spi_clear_loop
	btfss	PIR3,SSP2IF	;test the interrupt flag
	bra		spi_clear_loop
	return	;done with byte
;*********************************************************
erase_flash
;erase external flash video memory
	movlw	b'00010011'				;ERASES entire chip- poll ERASE BIT or ACTIVE for done.
	movwf	flash_memory_status
	call	flash_loop				;service ERASE
;35 ms has elapsed
	return
;*************************************************
flash_loop
	call	flash_memory_routine	;service flash erase cycle
	movf	flash_memory_status,W
	bnz		flash_loop				;loop for external flash_erase done
	return
;*************************************************

