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

📄 ivgx_handler.asm

📁 ADI公司SHARC与BlackFin通过SPI协议相互通信的源代码
💻 ASM
字号:
/****************************************************************************
 Include Section
*****************************************************************************/

#include "global.h"
#include "SPI.h"

/*****************************************************************************
 Prototypes
******************************************************************************/

.GLOBAL __ivg7_handler;
.GLOBAL __ivg10_handler;

//.GLOBAL ivg7_handler.spi_error;
//.GLOBAL ivg10_handler.spi_dma.tx;
//.GLOBAL ivg10_handler.spi_dma.rx;

/*****************************************************************************
 Functions
******************************************************************************/

.SECTION L1_code;

/****************************************************************************
 Function:              __ivg7_handler
 Description:           generic IVG7 handler
 Input Parameters:      none
 Return Parameters:     none
 Registers Used:        R7,P5,ASTAT
 Global Registers Used: none
 Global Variables Used: none
 C-Callable :           no
*****************************************************************************/

__ivg7_handler:

    link 0;
    [--SP] = (R7:7,P5:5);
    [--SP] = ASTAT;
    IMM32(P5,SYS_MMR_BASE);

    #if defined (SPI_SLAVE_MODE) && defined (PFHW)
        call __hostwait_assert;
    #endif

    /* Was it a SPI error interrupt? */
    R7 = [P5 + lo(SIC_ISR)];
    CC = bittst(R7, bitpos(IRQ_ERROR2));
    if !CC jump ivg7_handler.completed;
    call ivg7_handler.spi_error;

    ivg7_handler.completed:
    #if defined (SPI_SLAVE_MODE) && defined (PFHW)
        call __hostwait_assert;
    #endif

    ASTAT = [SP++];
    (R7:7,P5:5) = [SP++];
    unlink;

    rti;
__ivg7_handler.end:


/*************************************************************************************
 Function:              ivg7_handler.spi_error
 Description:           specific SPI error handler
 HINT:                  An SPI Error interrupt is generated in a master device
                        when a Mode Fault Error occurs in both DMA and non-DMA modes.
                        An error interrupt can also be generated in DMA mode when
                        there is an underflow (TXE when TIMOD = 11) or an
                        overflow (RBSY when TIMOD = 10) error condition.
                        In non-DMA mode, the underflow and overflow conditions set the
                        TXE and RBSY bits in the SPIx_STAT register, respectively,
                        but DO NOT generate an error interrupt.
 Input Parameters:      none
 Return Parameters:     none
 Registers Used:        R7:6,P5,ASTAT
 Global Registers Used: none
 Global Variables Used: none
 C-Callable :           no
**************************************************************************************/

ivg7_handler.spi_error:

    link 0;
    [--SP] = (R7:6,P5:5);
    [--SP] = ASTAT;
    IMM32(P5,SYS_MMR_BASE);


    ivg7_handler.spi_error.MODF:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst(R7,bitpos(MODF));
    if !CC jump ivg7_handler.spi_error.TXE;
    EMUEXCPT;
    jump ivg7_handler.spi_error.MODF;


    ivg7_handler.spi_error.TXE:
    R7 = w[P5 + lo(SPI_CTL)] (z);
    R6 = TIMOD (z);
    R7 = R7 & R6;
    R6 = TDBR_DMA (z);
    CC = R7 == R6;
    if !CC jump ivg7_handler.spi_error.RBSY;
    R7 = TXE (z);
    w[P5 + lo(SPI_STAT)] = R7; /* W1C: clear status bits */
    jump ivg7_handler.spi_error.verify;


    ivg7_handler.spi_error.RBSY:
    R7 = w[P5 + lo(SPI_CTL)] (z);
    R6 = TIMOD (z);
    R7 = R7 & R6;
    R6 = RDBR_DMA (z);
    CC = R7 == R6;
    if !CC jump ivg7_handler.spi_error.verify;
    R7 = ( RBSY | TXE ) (z); /* a SPI receive operation will always cause a TXE error interrupt */
    w[P5 + lo(SPI_STAT)] = R7; /* W1C: clear status bits */


    ivg7_handler.spi_error.verify:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    R6 = SPIF (z);
    CC = R7 == R6;
    if CC jump ivg7_handler.spi_error.completed;
    jump ivg7_handler.spi_error.verify;


    ivg7_handler.spi_error.completed:
    ASTAT = [SP++];
    (R7:6,P5:5) = [SP++];
    unlink;

    rts;
ivg7_handler.spi_error.end:


/****************************************************************************
 Function:              __ivg10_handler
 Description:           generic IVG10 handler
 Input Parameters:      none
 Return Parameters:     none
 Registers Used:        R7:6,P5,ASTAT
 Global Registers Used: none
 Global Variables Used: none
 C-Callable :           no
*****************************************************************************/

__ivg10_handler:

    link 0;
    [--SP] = (R7:6,P5:5);
    [--SP] = ASTAT;
    [--SP] = RETI;
    IMM32(P5,SYS_MMR_BASE);


    R7 = w[P5 + lo(DMA7_IRQ_STATUS)] (z);
    CC = bittst(R7,bitpos(DMA_DONE));
    if CC jump ivg10_handler.SPI_DMA;
    
    ivg10_handler.spi_data:
    R7 = [P5 + lo(SPI_CTL)];
    CC = bittst(R7,bitpos(EMISO));
    if CC jump ivg10_handler.spi_data_tx;

    ivg10_handler.spi_data_rx:
    jump ivg10_handler.spi_data_rx;
    jump ivg10_handler.completed;

    ivg10_handler.spi_data_tx:
    jump ivg10_handler.spi_data_tx;
    jump ivg10_handler.completed;


    ivg10_handler.SPI_DMA:
    R7 = [P5 + lo(SPI_CTL)];
    R6 = TIMOD (z);
    R7 = R7 & R6;
    R6 = TDBR_DMA (z);
    CC = R7 == R6;
    if CC jump ivg10_handler.spi_dma.tx;

    ivg10_handler.spi_dma_rx:
    call ivg10_handler.spi_dma.rx;
    jump ivg10_handler.completed;

    ivg10_handler.spi_dma_tx:
    call ivg10_handler.spi_dma.tx;
    jump ivg10_handler.completed;


    ivg10_handler.completed:
    RETI = [SP++];
    ASTAT = [SP++];
    (R7:6,P5:5) = [SP++];
    unlink;

    rti;
__ivg10_handler.end:


/****************************************************************************
 Function:              ivg10_handler.spi_dma.tx
 Description:           specific SPI DMA handler
 Input Parameters:      none
 Return Parameters:     none
 Registers Used:        R7,P5,ASTAT
 Global Registers Used: none
 Global Variables Used: none
 C-Callable :           no
*****************************************************************************/

ivg10_handler.spi_dma.tx:

    link 0;
    [--SP] = (R7:7,P5:5);
    [--SP] = ASTAT;
    IMM32(P5,SYS_MMR_BASE);


    /****************************************************************************************************
     Reset DMA DONE Status
     Note the DMA_DONE interrupt is asserted when the last memory access (read or write) has completed.
     For a transmit (memory read) transfer to a peripheral, there may be up to four data words in the
     channel抯 DMA FIFO when the interrupt occurs.
    ****************************************************************************************************/
    R7 = DMA_DONE (z);
    w[P5 + lo(DMA7_IRQ_STATUS)] = R7;


    /****************************************************************************************************
     Poll DMA RUN Status
     For a memory transfer to a peripheral, there may be up to four data words in
     the channel's DMA FIFO when the interrupt occurs. At this point, it is normal
     to immediately start the next work unit. If, however, the application needs to
     know when the final data item is actually transferred to the peripheral,
     the application can test or poll the DMA_RUN bit.
     As long as there is undelivered transmit data in the FIFO, the DMA_RUN bit is 1.
    ****************************************************************************************************/
    ivg10_handler.spi_dma.tx.dma7_run_status:
    R7 = w[P5 + lo(DMA7_IRQ_STATUS)] (z);
    CC = bittst (R7,bitpos(DMA_RUN));
    if CC jump ivg10_handler.spi_dma.tx.dma7_run_status;


    /****************************************************************************************************
     NOTE: When using DMA for SPI transmit, the DMA_DONE interrupt signifies that the DMA FIFO is empty.
     However, at this point there may still be data in the SPI DMA FIFO waiting to be transmitted.
     Therefore, software needs to poll TXS in the SPI_STAT register until it goes low
     for two successive reads, at which point the SPI DMA FIFO will be empty.
    ****************************************************************************************************/
    /* Wait for two straight reads of TXS = 0 in SPI_STAT */
    ivg10_handler.spi_dma.tx.ivg10_handler.spi_dma.rx.check_rxs:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst (R7,bitpos(TXS));
    if CC jump ivg10_handler.spi_dma.tx.ivg10_handler.spi_dma.rx.check_rxs;
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst (R7,bitpos(TXS));
    if CC jump ivg10_handler.spi_dma.tx.ivg10_handler.spi_dma.rx.check_rxs;

    /* Wait for SPIF = 1 in SPI_STAT */
    /* If Blackfin SPI Master device is running in SPI_DMA mode, this can cause to stuck the slave here !!! */
    ivg10_handler.spi_dma.tx.check_spif:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst (R7,bitpos(SPIF));
    if !CC jump ivg10_handler.spi_dma.tx.check_spif;

    /**************
    * SPI Disable *
    **************/
    call __spi_stop;


    ASTAT = [SP++];
    (R7:7,P5:5) = [SP++];
    unlink;

    rts;
ivg10_handler.spi_dma.tx.end:


/****************************************************************************
 Function:              ivg10_handler.spi_dma.rx
 Description:           specific SPI DMA handler
 Input Parameters:      none
 Return Parameters:     none
 Registers Used:        R7,P5,ASTAT
 Global Registers Used: none
 Global Variables Used: none
 C-Callable :           no
*****************************************************************************/

ivg10_handler.spi_dma.rx:

    link 0;
    [--SP] = (R7:7,P5:5);
    [--SP] = ASTAT;
    IMM32(P5,SYS_MMR_BASE);


    ivg10_handler.spi_dma.rx.check_rxs:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst (R7,bitpos(RXS));
    if CC jump ivg10_handler.spi_dma.rx.check_rxs;

    /* Wait for SPIF = 1 in SPI_STAT */
    /* If Blackfin SPI Master device is running in SPI_DMA mode, this can cause to stuck the slave here !!! */
    ivg10_handler.spi_dma.rx.check_spif:
    R7 = w[P5 + lo(SPI_STAT)] (z);
    CC = bittst (R7,bitpos(SPIF));
    if !CC jump ivg10_handler.spi_dma.rx.check_spif;


    R7 = DMA_DONE (z);
    w[P5 + lo(DMA7_IRQ_STATUS)] = R7;

    /**************
    * SPI Disable *
    **************/
    call __spi_stop;


    ASTAT = [SP++];
    (R7:7,P5:5) = [SP++];
    unlink;

    rts;
ivg10_handler.spi_dma.rx.end:


/*****************************************************************************
 EOF
******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -