📄 spi.asm.txt
字号:
1.汇编主程序spi.asm
;DESCRIPTION: SPI Slave Code for Point-to-Point Communication
.include "x24x_app.h"
;1st Data Page of peripheral registers (7000h/80h)
DP_PF1 .set 224
BAD_CHKSUM .set 004h
INVALID_CHKSUM .set 004h
VALID_CHKSUM .set 000h
DATA_IN_LEN .set 010h
DATA_OUT_LEN .set 010h
STATUS_INFO_BYTES .set 005h
CONTEXT_MEM_PTR_BYTES .set 020h
CHKSM_RQST_MSG .set 008h
STATUS_RQST_MSG .set 002h
.bss CONTEXT_MEM_PTR, CONTEXT_MEM_PTR_BYTES
.bss STATUS_INFO, STATUS_INFO_BYTES
.bss DATA_IN_PTR,1
.bss DATA_IN, DATA_IN_LEN
.bss DATA_OUT_PTR,1
.bss DATA_OUT, DATA_OUT_LEN
RCV_MSG_TYPE .set DATA_IN
RCV_BYTE_NO .set DATA_IN + 1
RCV_DATA_START .set DATA_IN + 2
PARAMS .usect "VARS", 020h
.bss VAR1, 1 ;Scratchpad
.bss NEW_BYTE_FLAG, 1
.bss COPIED, 1
.data
ST0_TEMP .word 0
ST1_TEMP .word 0
KICK_DOG .macro
LDP #00E0H
SPLK #055H, WDKEY
SPLK #0AAH, WDKEY
LDP #DATA_IN_PTR
.endm
.text
START
CLRC SXM ;Clear Sign Extension Mode
CLRC OVM ;Reset Overflow Mode
;Set Data Page pointer to page 1 of the peripheral frame
LDP #DP_PF1 ;Page DP_PF1 includes WET through
;EINT frames
;initialize WDT registers
SPLK #06Fh, WDCR ;clear WDFLAG, Disable WDT, set WDT
;for 1 second
;overflow (max)
SPLK #07h, RTICR ;clear RTI Flag, set RTI for 1 second
;overflow (max)
;EVM 10MHz oscillator settings. (XTAL2 open, OSCBYP_=GND)
SPLK #00B1h,CKCR1 ;CLKIN(OSC)=10MHz, Mult by 2, Div by 1.
SPLK #00C3h,CKCR0 ;CLKMD=PLL Enable,SYSCLK=CPUCLK/2,
;Clear reset flag bits in SYSSR (PORRST, PLLRST, ILLRST, SWRST, WDRST)
LACL SYSSR ;ACCL <= SYSSR
AND #00FFh ;Clear upper 8 bits of SYSSR
SACL SYSSR ;Load new value into SYSSR
;initialize B1 RAM to zero's.
LAR AR1,#B1_SADDR ;AR1 <= B1 start address
MAR *,AR1 ;use B1 start address for next indirect
ZAC ;ACC <= 0
RPT #(CONTEXT_MEM_PTR_BYTES+STATUS_INFO_BYTES+DATA_OUT_LEN+DATA_IN_LEN+2)
;set repeat counter for sizeof(.bss)-1
;loops
SACL *+ ;write zeros to B1 RAM
;initialize B2 RAM to zero's.
LAR AR1,#B2_SADDR ;AR1 <= B2 start address
MAR *,AR1 ;use B2 start address for next indirect
ZAC ;ACC <= 0
RPT #1fh ;set repeat counter for 1fh+1=20h or 32
;loops
SACL *+ ;write zeros to B2 RAM
;initialize STATUS_INFO
LAR AR1,#STATUS_INFO
;AR1 <= STATUS_INFO start address
MAR *,AR1
SPLK #01,*+ ;STAT1 = 1
SPLK #02,*+ ;STAT2 = 2
SPLK #03,*+ ;STAT3 = 3
SPLK #04,*+ ;STAT4 = 4
SPLK #05,*+ ;STAT5 = 5
;Initialize NEW_BYTE_FLAG
LDP #NEW_BYTE_FLAG
SPLK #01h, NEW_BYTE_FLAG
SPLK #0, COPIED
;Initialize DSP for interrupts
LAR AR6,#IMR ;
LAR AR7,#IFR ;
MAR *,AR6
LACL #010h ;
SACL *,AR7 ;Enable interrupt 5 only (SPI low
;priority)
LACL * ;Clear IFR by reading and
SACL *,AR6 ;writing contents back into itself
;call SPI initialization routine
CALL INIT_SPI
LDP #DATA_IN_PTR
;Initialize RX and TX buffers
SPLK #DATA_IN, DATA_IN_PTR
;Reset RX buffer pointer
SPLK #DATA_OUT, DATA_OUT_PTR
;Reset TX buffer pointer
SPLK #0FFH, DATA_OUT ;Initialize default TX byte =
;ACKnowledge
CLRC INTM ;Enable DSP interrupts
MAIN
LDP #NEW_BYTE_FLAG
MAR *, AR5
LAR AR5, NEW_BYTE_FLAG
;UPDATE AR5
BANZ MAIN,*
RD_MSG
LDP #IMR/128
LACL IMR ;Mask SPI interrupt to avoid changes
AND #0FFEFh ;to DATA_IN_PTR. NEW_BYTE_FLAG is used
SACL IMR ;as a handshake between SPI_ISR & RD_MSG.
LDP #NEW_BYTE_FLAG
SPLK #1, NEW_BYTE_FLAG
;UPDATE FLAG, NEW BYTE HAS BEEN READ
LDP #IMR/128
LACL IMR ;Unmask SPI interrupt to avoid changes
OR #010h ;to DATA_IN_PTR
SACL IMR
CHECKSUM_RQST
LDP #DATA_IN
LACC DATA_IN ;Is this 1st byte a Checksum Request
SUB #CHKSM_RQST_MSG ;message from the Master SPI? If so,
BCND RESET_RCV_BFR, EQ
;then no processing is required,
;reset receive buffer and return.
STATUS_INFO_RQST ;Is status info requested? It is if
BIT RCV_MSG_TYPE, BIT1
;bit #1 is set in the first rcvd byte,
BCND STATUS_RQST, NTC
;the msg-type byte. If status info
;is requested then copy it into DATA_OUT.
COPY_STATUS_INFO
BIT COPIED, BIT0
BCND MSG_COMPLETE, TC
;Don't copy if it was copied before
LDP #IMR/128
LACL IMR ;Mask SPI interrupt until DATA_OUT
AND #0FFEFh ;has been updated.
SACL IMR
LDP #DATA_OUT_PTR ;Copy status info into DATA_OUT buffer.
MAR *, AR6
LAR AR6, DATA_OUT_PTR
ADRK #01
SAR AR6, DATA_OUT_PTR
LDP #STATUS_INFO
RPT #(STATUS_INFO_BYTES - 1)
BLDD #STATUS_INFO, *+
SBRK #1
SAR AR6, DATA_OUT_PTR
SPLK #01, COPIED ;Set flag to copy only once
LDP #IMR/128
LACL IMR ;Unmask SPI interrupt
OR #010h
SACL IMR
STATUS_RQST
LDP #DATA_IN
LACC DATA_IN ;Is this 1st byte a Status Request
SUB #STATUS_RQST_MSG
;message from the Master SPI? If so,
BCND RESET_RCV_BFR, EQ
;then no further processing is
;required,
;reset receive buffer and return.
MSG_COMPLETE
LDP #DATA_IN_PTR
LACC DATA_IN_PTR ;Are all bytes rcvd for the current
;msg? If not, then do not process.
SUB #DATA_IN ;Min bytes in
SUB #04h ;message = 4, excluding ChksumRqst.
BCND MAIN, LT
LACC DATA_IN_PTR
SUB #DATA_IN
LAR AR6, #RCV_BYTE_NO
MAR *, AR6
SUB *
BCND MAIN, LT
DATA_OUT_EMPTY
LACC DATA_OUT_PTR ;Is the DATA_OUT buffer empty?
SUB #DATA_OUT ;If not, then do not process.
BCND MAIN, NEQ
SPLK #0, COPIED ;Reset COPIED flag for next status
;rqst msg
VERIFY_CHECKSUM
LACL *- ;Calculate checksum and compare
;with received
SUB #02H ;value. Checksum is calculated by
;adding all
SACL VAR1 ;received bytes except the received
;checksum.
LACC #0 ;Only the LSB of the result is used.
RPT VAR1
ADD *+
AND #0FFh
SACL VAR1
SUB *
BCND STORE_CHECKSUM, EQ
LACL #INVALID_CHKSUM
STORE_CHECKSUM ;Store result of checksum comparison
;into
LAR AR6, DATA_OUT_PTR
;DATA_OUT buffer.
ADRK #01h
SAR AR6, DATA_OUT_PTR
SACL *+
PARAMS_RQST ;Were new parameters downloaded?
BIT RCV_MSG_TYPE, BIT0
;If so, transfer them from DATA_OUT
;buffer
BCND RESET_RCV_BFR, NTC
;to memory.
STORE_PARAMS
LACL RCV_BYTE_NO ;Get # of data bytes
SUB #04H
SACL VAR1
LAR AR6, #RCV_DATA_START
;Point to 1st data byte
RPT VAR1 ;Copy data bytes to mem location PARAMS
BLDD *+, #PARAMS
RESET_RCV_BFR
LDP #DATA_IN
SPLK #DATA_IN, DATA_IN_PTR
;Reset rcv buffer pointer
B MAIN
;INIT_SPI
;DESCRIPTION: SPI initialization subroutine. This SR initializes
;the SPI for data stream transfer to a master SPI.
;The 240 SPI is configured for 8-bit transfers as a slave.
INIT_SPI
;initialize SPI in slave mode
LDP #DP_PF1
SPLK #00C7h,SPICCR ;Reset SPI by writing 1 to SWRST
SPLK #0000h,SPICTL ;Disable ints & TALK, normal clock, SLAVE
;mode
SPLK #0040h,SPIPRI ;Set SPI interrupt to low priority.
;For emulation purposes, allow the SPI
;to continue after an XDS suspension.
;HAS NO EFFECT ON THE ACTUAL DEVICE.
SPLK #0000h,SPISTS ;Clear the SPI interrupt status bits
;falling edge with No delay
SPLK #0013h,SPICTL ;Enable TALK, ena SPI int, CLK ph 0, slave
;mode
SPLK #0002h,SPIPC1
SPLK #0022h,SPIPC2 ;Set SIMO & SOMI functions to serial I/O
SPLK #0047h,SPICCR ;Release SWRST, clock polarity 1, 8 bits
RET ;Return to MAIN routine.
;SPI_ISR
;DESCRIPTION: SPI interrupt service routine.
SPI_ISR
SST #0, ST0_TEMP ;Auto page-0 DP
SST #1, ST1_TEMP
LDP #CONTEXT_MEM_PTR
SACL CONTEXT_MEM_PTR
SACH CONTEXT_MEM_PTR+1
SAR AR7, CONTEXT_MEM_PTR+2
SAR AR6, CONTEXT_MEM_PTR+3
LDP #IMR/128
LACL IMR
LDP #CONTEXT_MEM_PTR
SACL CONTEXT_MEM_PTR+4
OVER_RUN
LDP #DP_PF1 ;Page DP_PF1 includes SPI
BIT SPISTS, 8 ;Overrun flag (SPISTS.7) set?
BCND CLEAR_FLAG, TC ;If set, clear & return
;Send next TX byte
NEXT_TX
LDP #DATA_OUT_PTR
LAR AR6, DATA_OUT_PTR
MAR *,AR6
LACL *- ;ACC = next byte out
LDP #DP_PF1
SACL SPIDAT ;Send next byte out, ACK is default
LDP #DATA_OUT_PTR
LACC #DATA_OUT ;If the TX pointer is not at the start
;pos.
SUB DATA_OUT_PTR ;then point it at next byte to be send.
BCND READ_SPI, EQ
SAR AR6, DATA_OUT_PTR
;Save TX pointer back to memory
READ_SPI
LDP #DP_PF1 ;Page DP_PF1 includes SPI
LACC SPIBUF ;load rcvd data into ACC
LDP #DATA_IN_PTR ;Set data page pointer to B1 page
LAR AR7, DATA_IN_PTR
;update RX ptr
MAR *, AR7
SACL *+
SAR AR7, DATA_IN_PTR;Set RX pointer to next entry
LDP #NEW_BYTE_FLAG ;Trigger RD_MSG
SPLK #0, NEW_BYTE_FLAG
SPI_DONE
LDP #CONTEXT_MEM_PTR
LACL CONTEXT_MEM_PTR+4
LDP #IMR/128
SACL IMR
LDP #CONTEXT_MEM_PTR
LAR AR6, CONTEXT_MEM_PTR+3
LAR AR7, CONTEXT_MEM_PTR+2
LACC CONTEXT_MEM_PTR+1,16
ADDS CONTEXT_MEM_PTR
LDP #0
LST #1, ST1_TEMP
LST #0, ST0_TEMP
CLRC INTM
RET
CLEAR_FLAG
SPLK #0H, SPISTS
B SPI_DONE
;Interrupt Vectors
;DESCRIPTION: Used by linker to place this section at the reset vector
;location.
.sect "vectors"
B START ;reset
B START ;Int level 1 not used
B START ;Int level 2 not used
B START ;Int level 3 not used
B START ;Int level 4 not used
B SPI_ISR ;Int level 5, low priority SPI
2.评估板调试文件spi1.tak
cd c:\dspcode\x240\f240evm\spi_app\slave
load spi.out
WA TEST_MSG,,x
WA *TEST_MSG_PTR,,x
WA *TEST_MSG_END,,x
WA DATA_IN,,x
WA DATA_IN_PTR,,x
WA *DATA_IN_PTR,,x
WA DATA_OUT,,x
WA DATA_OUT_PTR,,x
WA *DATA_OUT_PTR,,x
WA STATUS_INFO,,x
WA *STATUS_INFO,,x
WA *VAR1,,x
WA *NEW_BYTE_FLAG,,x
WA *COPIED
;ba XINT1_ISR
;ba SPI_ISR
;ba RD_MSG
BA VERIFY_CHECKSUM
MEM DATA_IN_PTR
MEM1 DATA_OUT_PTR
;MEM2 TEST_MSG
MEM2 PARAMS
MEM3 STATUS_INFO
bl
7.3.2主节点源程序
1.汇编主程序spi.asm
;DESCRIPTION: SPI Code Example for Point-to-Point Communication
.def STATUS_INFO ;General purpose registers.
.def DATA_IN
.def DATA_OUT
.include "x24x_app.h"
;1st Data Page of peripheral registers (7000h/80h)
DP_PF1 .set 224h
BAD_CHKSUM .set 004h
DATA_IN_LEN .set 010h
DATA_OUT_LEN .set 010h
STATUS_INFO_BYTES .set 005h
CONTEXT_MEM_PTR_BYTES .set 020h
SLAVE_SEND .set 0FEh
.bss CONTEXT_MEM_PTR, CONTEXT_MEM_PTR_BYTES
.bss STATUS_INFO, STATUS_INFO_BYTES
.bss DATA_IN_PTR,1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -