📄 ivgx_handler.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 + -