⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a_spi25128_spi.asm

📁 TSM320C5000系列控制SPI25128器件的代码
💻 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 + -