;short (50 us) delay subroutine:
;======================================================
DELAY movlw h'10' ;49 cycles
movwf d1
dloop decfsz d1,f
goto dloop
nop ;1 cycle
return
;======================================================
;delay to wait for SPI send/receive to finish (checks BF flag only)
;======================================================
BFWAIT bsf STATUS,5 ;bank 1
btfss SSPSTAT,BF ;test if send/receive is complete
goto $-1 ;loop until receive is complete
bcf STATUS,5 ;bank 0
return
;======================================================
;Wait for flash writing to be complete
;======================================================
WRTWAIT movlw b'11111111'
movwf TMP ;set all TMP bits
WRTLOOP bcf CSEL ;select flash
movlw h'05'
movwf SSPBUF ;send read status register command
call BFWAIT ;wait for byte to be sent/received
movlw h'00'
movwf SSPBUF ;send dummy character
call BFWAIT ;wait for byte to be sent/received
bcf STATUS,5 ;bank 0
bsf CSEL ;deselect flash
movf SSPBUF,W ;move received data to W
movwf TMP ;then move to scratch
btfsc TMP,0 ;check 'write in progress bit'
goto WRTLOOP ;if still writing, check again
return
;======================================================
;Set up SPI module
;data shifted out of M45PE80 on falling edge of clock
;data shifted into M45PE80 on rising edge of clock
;======================================================
SPIINT bsf STATUS,5 ;bank 1
movlw b'10000000' ;input data sampled at end of data output time
movwf SSPSTAT ;txmit occurs on trans. from idle to active
bcf STATUS,5 ;bank 0
clrf SSPCON ;txmit happens on rising edge, idle state is low
;SPI module disabled
;SPI master mode, clock= OSC/4
;======================================================
;Test flash memory (M45PE80)
;======================================================
MEMORY movlw h'3C'
movwf BUFPT ;set buffer pointer to bottom of buffer
movf BUFPT,W
movwf FSR ;set indirect location
clrf BUFCT ;clear buffer counter
MPROMPT movlw 'W' ;">WRITE ADC OUPUT?"
call SEND ;
movlw 'R'
call SEND
movlw 'I'
call SEND
movlw 'T'
call SEND
movlw 'E'
call SEND
movlw ' '
call SEND
movlw 'A'
call SEND
movlw 'D'
call SEND
movlw 'C'
call SEND
movlw ' '
call SEND
movlw 'O'
call SEND
movlw 'U'
call SEND
movlw 'T'
call SEND
movlw 'P'
call SEND
movlw 'U'
call SEND
movlw 'T'
call SEND
movlw h'0D'
call SEND
movlw h'0A'
call SEND
call RECEIVE ;get character
movf INPUT,W ;move input character to W
movwf INDF ;move input character to data buffer
;getting everything set up for flash write:
FLWRITE bcf RCSTA,SPEN ;disable serial port
bsf STATUS,5 ;bank 1
bcf TRISB,2 ;set RXD/SDO pin as output for SPI communication
bcf STATUS,5 ;bank 0
bsf SSPCON,SSPEN ;enable SPI module
call WRTWAIT ;make sure no writing is happening
call DELAY
movlw h'06' ;move write enable (WREN) instruction to W
bcf CSEL ;select flash
movwf SSPBUF ;send WREN instruction
call BFWAIT ;wait for byte to be sent/received
bsf CSEL ;deselect flash
call DELAY
movlw h'02' ;move page program instrction to W
bcf CSEL ;pull chip select low
movwf SSPBUF ;send page program instruction
call BFWAIT ;wait for byte to be sent/received
movf NAFLH,W
movwf SSPBUF ;send high byte of next available flash address
call BFWAIT ;wait for byte to be sent/received
movf NAFLM,W
movwf SSPBUF ;send mid byte of address
call BFWAIT ;wait for byte to be sent/received
movf NAFLL,W
movwf SSPBUF ;send low byte of address
call BFWAIT ;wait for byte to be sent/received
;moves data buffer to flash:
movf INDF,W ;move data byte in buffer to W
movwf SSPBUF ;send data byte
call BFWAIT ;wait for byte to be sent/received
bsf CSEL ;deselect flash
call WRTWAIT ;wait for writing to be complete
bcf SSPCON,SSPEN ;disable SPI module
bsf RCSTA,SPEN ;enable serial port
bsf STATUS,5 ;bank 1
bsf TRISB,2 ;set RXD/SDO pin as input for serial communication
bcf STATUS,5 ;bank 0
OUTPUT movlw '>' ;">UPLOAD?"
call SEND
movlw 'U'
call SEND
movlw 'P'
call SEND
movlw 'L'
call SEND
movlw 'O'
call SEND
movlw 'A'
call SEND
movlw 'D'
call SEND
movlw '?'
call SEND
movlw h'0D'
call SEND
movlw h'0A'
call SEND
call RECEIVE ;wait for any input
UPLALL clrf DBUF ;clear 1st byte in buffer, to make sure it is actually getting writting/read to flash
bcf RCSTA,SPEN ;disable serial port
bsf STATUS,5 ;bank 1
bcf TRISB,2 ;set RXD/SDO pin as output for SPI communication
bcf STATUS,5 ;bank 0
bsf SSPCON,SSPEN ;enable SPI module
movlw h'3C'
movwf BUFPT ;set buffer pointer to bottom of buffer
movf BUFPT,W
movwf FSR ;set indirect location
movlw h'03'
bcf CSEL ;pull chip select low, select flash
movwf SSPBUF ;send READ instruction
call BFWAIT ;wait for byte to be sent/received
movf NAFLUH,W
movwf SSPBUF ;send high address byte
call BFWAIT ;wait for byte to be sent/received
movf NAFLUM,W
movwf SSPBUF ;send mid address byte
call BFWAIT ;wait for byte to be sent/received
movf NAFLUL,W
movwf SSPBUF ;send low address byte
call BFWAIT ;wait for byte to be sent/received
movlw h'00'
movwf SSPBUF ;send null character to initiate transmission
call BFWAIT ;wait for byte to be sent/received
;now moving this byte to the buffer:
movf SSPBUF,W ;move received byte to W
movwf INDF ;move to data buffer
bsf CSEL ;pull chip select high
bcf SSPCON,SSPEN ;disable SPI module
bsf RCSTA,SPEN ;enable serial port
bsf STATUS,5 ;bank 1
bsf TRISB,2 ;set RXD/SDO pin as input for UART
bcf STATUS,5 ;bank 0
XMIT movf INDF,W ;move byte to W
call SEND ;send first byte of buffer
movlw h'0D' ;CR
call SEND
movlw h'0A' ;LF
call SEND
movlw '>'
call SEND
movlw 'D' ;>DONE?
call SEND
movlw 'O'
call SEND
movlw 'N'
call SEND
movlw 'E'
call SEND
movlw '?'
call SEND
movlw h'0D'
call SEND
movlw h'0A'
call SEND
call RECEIVE ;get character
movlw 'y' ;test for input of y
subwf INPUT,f ;by subtraction
btfss STATUS,2 ;skip next if input is y
goto MEMORY ;if anything else, go back to MEMORY, repeat
goto MENU
;======================================================