📄 a_spi25128_spi.asm
字号:
.title "A_SPI25128_SPI.ASM"
.mmregs
.include "A_SPI25128_head.asm"
.def SPI_INIT, SPI_READ, SPI_WRITE
.def SPI_RDSR, SPI_WRSR, WR_WAIT
.text
*********************************************************************
* SPI_INIT - This routine is used to initialize the McBSP1 for use *
* as a SPI master. SPI mode0 (CLKSTP=10, CLKXP=0) is selected. The *
* following registers are used: *
* A - The clock divisor (CLKGDV) is passed in A. *
* SPI bitrate = CPU freq/( CLKGDV + 1 ), CLKGDV:[1,255] *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
*********************************************************************
SPI_INIT:
**** Init transmitter************************************************
ST #SPCR1_sub, *AR4+ ;Sub-bank Address (SPSA) = SPCR1.
ST #1800h, *AR4- ;Reset xmiter and enable clkstp=11b.
ST #XCR1_sub, *AR4+ ;Set Sub-bank Address to XCR1.
ST #0A0h, *AR4- ;Select 32-bit packets for xmit.
ST #XCR2_sub, *AR4+ ;Set Sub-bank Address to XCR2.
ST #1h, *AR4- ;Select 1bit delay for xmit.
**** Init reciever **************************************************
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address to SPCR2.
ST #0200h, *AR4- ;Reset rcvr and clk gen, FREE=1 .#1
ST #RCR1_sub, *AR4+ ;Set Sub-bank Address to RCR1.
ST #0A0h, *AR4- ;Select 32-bit packets for rcv.
ST #RCR2_sub, *AR4+ ;Set Sub-bank Address to RCR2.
ST #1h, *AR4- ;Select 1bit delay for rcv.
**** Init bit rate and frame generator ******************************
ST #SRGR1_sub, *AR4+ ;Set Sub-bank Address to SRGR1.
STL A, *AR4- ;bit rate=sysclk/(accuA+1).
ST #SRGR2_sub, *AR4+ ;Set Sub-bank Address to SRGR2.
ST #2000h, *AR4- ;Configure frames.
CALL DELAY2B ;Delay for 2bit clocks.
*** Start clock generator *******************************************
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address to SPCR2.
ST #0240h, *AR4- ;Take clk gen out of reset. #1.5
CALL DELAY2B ;Delay for 2bit clocks.
*** Configure pin directions and polarities *************************
ST #PCR_sub, *AR4+ ;Set Sub-bank Address to PCR.
ST #0A0Dh, *AR4- ;CLKXM=1/FSXM=1/CLKXP=0/CLKRP=1
;FSRP=FSXP=1. #2
CALL DELAY2B ;Delay for 2bit clocks.
*** Enable clock-stop mode (100) and enable rcvr/xmitr **************
ST #SPCR1_sub, *AR4+ ;Set Sub-bank Address to SPCR1.
ST #01801h, *AR4- ;Enable McBSP transmitter. #5
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address to SPCR2.
ST #0241h, *AR4- ;Enable McBSP reciever. #5
CALL DELAY2B ;Delay for 2bit clocks.
RET
*********************************************************************
* SPI_READ - This subroutine is used to read a byte from the EEPROM.*
* The following registers are used: *
* *
* A - The data read is returned in accu A. *
* AR3 - The address to read from is passed in AR3. *
* AR4 - Must point to serial port sub-bank address reg (SPSA) *
* AR5 - Must point to data transmit register2 (DXR2x). *
*********************************************************************
SPI_READ:
LD #READ, 16, B ;Get read command.
B SPI_CMD ;Re-use SPI_CMD subroutine.
*********************************************************************
* SPI_RDSR - This subroutine is used to read the EEPROM status reg. *
* The following registers are used: *
* *
* A - The data read is returned in accu A. *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
* AR5 - Must point to data transmit register2 (DXR2x). *
*********************************************************************
SPI_RDSR:
LD #RDSR, 16, B ;Get RDSR command.
B SPI_CMD ;Re-use SPI_CMD subroutine.
*********************************************************************
* SPI_WRITE - This subroutine is used to write a byte to the EEPROM.*
* The following registers are used: *
* *
* A - The data to be written is passed in accu A. *
* AR3 - The address to be written to is passed in AR3. *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
* AR5 - Must point to data transmit register2 (DXR2x). *
*********************************************************************
SPI_WRITE:
CALL WEL_SET ;Set write enable latch.
LD #WRITE, 16, B ;Get write command.
CALL SPI_CMD ;Re-use SPI_CMD subroutine.
CALL WR_WAIT ;Wait for EEPROM to finish.
RET
*********************************************************************
* SPI_WRSR - This subroutine is used to write the EEPROM status reg.*
* The following registers are used: *
* *
* A - The data to be written is passed in accu A. *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
* AR5 - Must point to data transmit register2 (DXR2x). *
*********************************************************************
SPI_WRSR:
CALL WEL_SET ;Set write enable latch.
LD #WRSR, 16, B ;Get WRSR command.
CALL SPI_CMD ;Re-use SPI_CMD subroutine.
CALL WR_WAIT ;Wait for EEPROM to finish.
RET
*********************************************************************
* SPI_CMD - This subroutine is used to read/write a byte from/to the*
* EEPROM based on the command passed in Acc B. *
* The following registers are used: *
* *
* A - The data to be written/read is passed/returned in accu A.*
* B - The command to be executed is passed in accu B high. *
* AR2 - Temp, local storage. *
* AR3 - Address to perform operation on is passed here. *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
* AR5 - Must point to data transmit register2 (DXR2x). *
* *
* The XRDY bit is first polled, to determine transmiter status. Then*
* the address is concatenated with the command and a write/dummy *
* byte to form a 32bit packet. The RRDY bit is then polled and the *
* byte is read from the McBSP recieve buffer into accu A. For a read*
* operation, this byte is the byte read from the EEPROM, otherwise *
* it's trash. *
*********************************************************************
SPI_CMD:
STM #AR3, AR2 ;AR2->AR3=address
OR *AR2, B ;Concatenate command and address.
SFTL B, 8 ;Shift over to MSB.
AND #0FFh, A ;Mask-off upper (only used for writes).
OR A, B ;Put in data (only used on writes).
; rpt #3
; nop
DST B, *AR5 ;Send out packet.
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address to SPCR2.
BIT *AR4, #14 ;TC=XRDY, for first poll.
BCD $, ntc ;Loop for polling.
BITF *AR4, #02h ;Poll XRDY.
***********Packet sent, now wait for recieved word*******************
MAR *AR4- ;AR4->SPSA
MAR *AR5- ;AR5->DRR1x
ST #SPCR1_sub, *AR4+ ;SPSA->SPCR1, AR4->SPSD.
BIT *AR4, #14 ;TC=RRDY, for first poll.
BCD $, ntc ;Loop for polling.
BITF *AR4, #02h ;Poll RRDY
LDM *AR5+, A ;Get recieved word.
AND #0FFh, A ;Mask-off upper (only used for reads).
MAR *AR4- ;AR4->SPSA
RET ;Return
************************************************************
* This routine polls the WIP bit of the EEPROM status reg. *
* It reads the status register and loops until D0=0. *
************************************************************
WR_WAIT:
CALL SPI_RDSR ;Send RDSR command.
AND #1,A ;Mask off D0 of EEPROM status reg.
BC WR_WAIT,ANEQ ;If busy (D0=1), wait.
RET ;Return
*********************************************************************
* This routine is used to set the write enable bit. (enable a write)*
* It sets the word-length to 8-bits, and sends the WREN command. *
* Then the wordlength is restored. *
* The following registers are used: *
* *
* AR4 - Must point to serial port sub-bank address reg (SPSA). *
* AR5 - Must point to data transmit register2 (DXR2x). *
*********************************************************************
WEL_SET:
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address to SPCR2.
BIT *AR4, #14 ;TC=XRDY, for first poll.
BCD $, ntc ;Loop for polling.
BITF *AR4, #02h ;Poll XRDY.
BIT *AR4, #13 ;TC=XEMPTY, for first poll.
BCD $, tc ;Loop for polling.
BITF *AR4, #04h ;Poll XEMPTY.
**** Now configure McBSP for 8-bits. ****
PSHD *AR4 ;Save SPCR2
ANDM #0FFFEh, *AR4- ;Reset transmitter (SPCR2=SPCR2.0).
ST #SPCR1_sub, *AR4+ ;Set Sub-bank Address to SPCR1.
PSHD *AR4 ;Save SPCR1
ANDM #0FFFEh, *AR4- ;Reset reciever (SPCR1=SPCR1.0).
ST #XCR1_sub, *AR4+ ;Set Sub-bank Address1 to XCR1.
PSHD *AR4 ;Save XCR1
ANDM #0F01Fh, *AR4- ;Set wordlength to 8-bits.
ST #SPCR2_sub, *AR4+ ;Set Sub-bank Address1 to SPCR2.
ORM #1, *AR4 ;Un-reset transmitter (SPCR2=SPCR2|1).
CALL DELAY2B ;Delay for 2bit clocks.
**** Now send out the WREN command. ****
ST #WREN, *+AR5 ;Send write-enable command.
MAR *AR5- ;AR5->DXR2x
BIT *AR4, #14 ;TC=XRDY, for first poll.
BCD $, ntc ;Loop for polling.
BITF *AR4, #02h ;Poll XRDY.
BIT *AR4, #13 ;TC=XEMPTY, for first poll.
BCD $, tc ;Loop for polling.
BITF *AR4, #04h ;Poll XEMPTY.
**** Now put things back as they were. ****
ANDM #0FFFEh, *AR4- ;Reset transmitter (SPCR2=SPCR2.0).
ST #XCR1_sub, *AR4+ ;Set Sub-bank Address1 to XCR1.
POPD *AR4- ;Restore XCR1
ST #SPCR1_sub, *AR4+ ;Set Sub-bank Address1 to SPCR1.
POPD *AR4- ;Restore SPCR1
STM #SPCR2_sub, *AR4+ ;Set Sub-bank Address1 to SPCR2.
POPD *AR4- ;Restore SPRC2.
CALL DELAY2B ;Delay for 2bit clocks.
RET ;Return
*********************************************************************
* Using this as a 2bit delay. Since fCLKX equals sysclk/(CLKDIV+1),
* a 2bit delay is 2*(SCLKDIV+1) cycles. The CALL takes-up 4cycles.
*********************************************************************
DELAY2B:
RPT #(2*SCLKDIV-18) ;1cycle
NOP ;2*(SCLKDIV-9) cycles
RET ;5cycles
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -