diff src/external_flash.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children 13cda523891f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external_flash.asm	Wed Apr 24 19:22:45 2013 +0200
@@ -0,0 +1,279 @@
+;=============================================================================
+;
+;   File external_flash.asm
+;
+;   External flash
+;
+;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
+;=============================================================================
+; HISTORY
+;  2011-08-12 : [mH] creation
+
+	#include "ostc3.inc"
+	#include "wait.inc"
+
+basic    CODE
+;=============================================================================
+
+	global		incf_ext_flash_address_p1
+incf_ext_flash_address_p1:					; Increase by one
+	movlw		.1
+
+	global	incf_ext_flash_address0
+incf_ext_flash_address0:
+    addwf		ext_flash_address+0,F      ; increase address
+    movlw		d'0'
+    addwfc		ext_flash_address+1,F
+    addwfc		ext_flash_address+2,F
+
+	movlw		0x40
+	cpfseq		ext_flash_address+2			; at address 40FFFF?
+	return									; No, return
+	clrf		ext_flash_address+0			; Yes, rollover to 0x000000
+	clrf		ext_flash_address+1
+	clrf		ext_flash_address+2
+	return
+
+	global		incf_ext_flash_address0_p1_0x20
+incf_ext_flash_address0_p1_0x20:			; Increase by one
+	movlw		.1
+
+	global		incf_ext_flash_address0_0x20
+incf_ext_flash_address0_0x20:		 	; with roll-over at 0x200000 to 0x000000
+    addwf		ext_flash_address+0,F      ; increase address
+    movlw		d'0'
+    addwfc		ext_flash_address+1,F
+    addwfc		ext_flash_address+2,F
+
+	movlw		0x20
+	cpfseq		ext_flash_address+2			; at address 0x200000?
+	return									; No, return
+	clrf		ext_flash_address+0			; Yes, rollover to 0x000000
+	clrf		ext_flash_address+1
+	clrf		ext_flash_address+2
+	return
+
+	global	decf_ext_flash_address0
+decf_ext_flash_address0:
+    subwf		ext_flash_address+0,F      ; decrease address: do a 16-8bits substract.
+    movlw		d'0'
+    subwfb		ext_flash_address+1,F
+    movlw		d'0'
+    subwfb		ext_flash_address+2,F
+
+	btfss		ext_flash_address+2,7		; Rollover to 0xFFFFFF?
+	return									; No, return
+	clrf		ext_flash_address+2			; Set to 0x00FFFFF
+	setf		ext_flash_address+1
+	setf		ext_flash_address+0
+	return
+
+	global	ext_flash_power_down
+ext_flash_power_down:
+	movlw		0x04				; Write disable
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	return
+
+	global	ext_flash_byte_read_plus	; Return data read in WREG and SSP2BUF and 
+ext_flash_byte_read_plus:				; increase address after read
+	rcall	ext_flash_byte_read
+	movwf	temp1						; store received data
+	bra		incf_ext_flash_address_p1	; +1 and return
+
+	global	ext_flash_byte_read_plus_0x20; Return data read in WREG and SSP2BUF and 
+ext_flash_byte_read_plus_0x20:			; increase address after read with banking at 0x200000
+	rcall	ext_flash_byte_read
+	movwf	temp1						; store received data
+	bra		incf_ext_flash_address0_p1_0x20 ;+1 and return
+
+
+	global	ext_flash_byte_read		; Return data read in WREG
+ext_flash_byte_read:
+	movlw		0x03				; Read command
+	rcall		write_spi
+    rcall       ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
+	rcall		write_spi			; Dummy write to read data into WREG
+	bsf			flash_ncs			; CS=1
+	movwf		temp1
+	return							; Return data read in WREG and temp1
+
+ext_flash_write_address: ; Write 24bit address ext_flash_address:3 via SPI
+	movf		ext_flash_address+2,W	; 24Bit Address
+	rcall		write_spi
+	movf		ext_flash_address+1,W
+	rcall		write_spi
+	movf		ext_flash_address+0,W
+	bra 		write_spi               ; And return....
+
+	global	ext_flash_read_block_start		; Return data read in WREG
+ext_flash_read_block_start:
+	movlw		0x03				; Read command
+	rcall		write_spi
+    rcall       ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
+	rcall		write_spi			; Dummy write to read data into WREG
+	return							; Return data read in WREG
+
+	global	ext_flash_read_block		; Return data read in WREG
+ext_flash_read_block:
+	rcall		incf_ext_flash_address_p1	; Increase address +1
+	bra			write_spi1			; Dummy write to read data into WREG and return
+
+	global	ext_flash_read_block_stop	; Return data read in WREG
+ext_flash_read_block_stop:
+	bsf			flash_ncs			; CS=1
+	return							; NO data in WREG
+
+	global	write_byte_ext_flash_plus_header
+write_byte_ext_flash_plus_header:		; Write from WREG and increase address after write
+	movwf		temp1					; store data
+	; test if write is done at first byte of 4kB block
+	; if yes -> delete 4kB block first
+	tstfsz		ext_flash_address+0			; at 0x00?
+	bra			write_byte_ext_flash_plus_h1	; No, normal Write
+
+	movf		ext_flash_address+1,W
+	andlw		0x0F						; Mask lower nibble
+	tstfsz		WREG						; at 0x.0?
+	bra			write_byte_ext_flash_plus_h1; No, normal Write
+	
+	; At beginning of 4kB block -> rease first!
+	rcall		ext_flash_erase4kB		; Erases 4kB sector @ext_flash_address:3
+write_byte_ext_flash_plus_h1:
+	movf		temp1,W
+	rcall		ext_flash_byte_write	; Write the byte
+	bra			incf_ext_flash_address_p1	; +1 and return
+
+	global	write_byte_ext_flash_plus	; Write from WREG and increase address after write with banking at 0x200000
+write_byte_ext_flash_plus:
+	movwf		temp1					; store data
+    
+    ; First, increase dive length counter
+    incf        ext_flash_dive_counter+0,F
+    movlw       .0
+    addwfc      ext_flash_dive_counter+1,F
+    addwfc      ext_flash_dive_counter+2,F  ; 24bit++
+
+	; Now test if write is done at first byte of 4kB block
+	; if yes -> delete 4kB block first
+	tstfsz		ext_flash_address+0			; at 0x00?
+	bra			write_byte_ext_flash_plus1	; No, normal Write
+
+	movf		ext_flash_address+1,W
+	andlw		0x0F						; Mask lower nibble
+	tstfsz		WREG						; at 0x.0?
+	bra			write_byte_ext_flash_plus1	; No, normal Write
+	
+	; At beginning of 4kB block -> erase first!
+	rcall		ext_flash_erase4kB		; Erases 4kB sector @ext_flash_address:3
+write_byte_ext_flash_plus1:
+	movf		temp1,W
+	rcall		ext_flash_byte_write	; Write the byte
+	bra			incf_ext_flash_address0_p1_0x20		 ; +1 and roll over at 0x200000 to 0x000000	and return
+
+	global	ext_flash_byte_write	; Write from WREG
+ext_flash_byte_write:
+	movwf		temp1				; store data byte
+	bsf			flash_ncs			; CS=1
+	movlw		0x06				; WREN command
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	movlw		0x02				; Write command
+	rcall		write_spi
+    rcall       ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
+	movf		temp1,W				; load data byte
+	rcall		write_spi			; write one byte of data!
+	bsf			flash_ncs			; CS=1
+	return
+	
+	global	ext_flash_disable_protection		; Disable write protection
+ext_flash_disable_protection:
+	bsf			flash_ncs			; CS=1
+	movlw		0x50				; EWSR command
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+
+	movlw		0x01				; WRSR command
+	rcall		write_spi
+	movlw		b'00000000'			; New status
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	return
+
+	global	ext_flash_enable_protection
+ext_flash_enable_protection:
+	bsf			flash_ncs			; CS=1
+	movlw		0x50				; EWSR command
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+
+	movlw		0x01				; WRSR command
+	rcall		write_spi
+	movlw		b'00011100'			; New status (Write protect on)
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	return
+
+
+	global	ext_flash_erase4kB		; Erases 4kB sector
+ext_flash_erase4kB:
+	bsf			flash_ncs			; CS=1
+	movlw		0x06				; WREN command
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	movlw		0x20				; Sector erase command
+	rcall		write_spi
+    rcall       ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
+	bsf			flash_ncs			; CS=1
+;	bra			ext_flash_wait_write	; Wait for write... and return
+ext_flash_wait_write:
+	WAITMS		d'1'				; TBE=25ms...
+	movlw		0x05				; RDSR command
+	rcall		write_spi			; Read status
+	rcall		write_spi			; Read status into WREG
+	bsf			flash_ncs			; CS=1
+	btfsc		SSP2BUF,0			; Write operation in process?
+	bra			ext_flash_wait_write	; Yes, wait more..
+	return
+
+	global	ext_flash_erase_logbook	; erases logbook memory (000000h -> 2FFFFFh -> 3MByte)
+ext_flash_erase_logbook:
+	bsf			flash_ncs			; CS=1
+	clrf		ext_flash_address+0
+	clrf		ext_flash_address+1
+	clrf		ext_flash_address+2
+
+	movlw		d'48'
+	movwf		temp1				; 48*64kB=917504 Bytes
+ext_flash_erase_logbook_loop:
+	movlw		0x06				; WREN command
+	rcall		write_spi
+	bsf			flash_ncs			; CS=1
+	movlw		0xD8				; 64kB erase command
+	rcall		write_spi
+    rcall       ext_flash_write_address ; Write 24bit address ext_flash_address:3 via SPI
+	bsf			flash_ncs			; CS=1
+	rcall		ext_flash_wait_write	; Wait for write...
+
+	incf		ext_flash_address+2,F	; 64kB ahead
+	decfsz		temp1,F
+	bra			ext_flash_erase_logbook_loop
+	return
+
+
+write_spi:		; With data in WREG...
+	bcf			flash_ncs			; CS
+	global	write_spi1
+write_spi1:		; With data in WREG...
+	bcf			SSP2STAT,WCOL		; Clear flag	
+	movwf		SSP2BUF				; Write to buffer
+	btfsc		SSP2STAT,WCOL		; Was buffer full?
+	bra			write_spi1			; Yes, try again
+
+write_spi2:	; Wait for write command
+	btfss		SSP2STAT, BF		; Buffer full?
+	bra			write_spi2			; No, wait.
+	movf		SSP2BUF,W			
+	return	; Returns RX data in WREG and SSP2BUF
+
+	END
\ No newline at end of file