📄 spi.asm
字号:
Initialize DMA for receiving if defined
Input Parameters: none
Return Parameters: none
Registers Used: R7:6,P5
Global Variables Used: none
C-Callable : no
*****************************************************************************/
spi_init_rx:
link 0;
[--SP] = (R7:6,P5:5);
IMM32(P5,SYS_MMR_BASE);
/******
* SPI *
******/
R7 = SPI_CTL_VAL_RX (z);
#if defined SPI_GM
bitset(R7,bitpos(GM));
#endif
w[P5 + lo(SPI_CTL)] = R7;
/******
* DMA *
******/
#if defined SPI_DMA
R7 = FLOW_STOP | /* Next Operation */
DI_EN | /* Data Interrupt Enable */
nDI_SEL | /* Data Interrupt Timing Select */
nSYNC | /* Work Unit Transitions */
nDMA2D | /* DMA Mode */
WDSIZE_8 | /* Transfer Word Size */
WNR | /* DMA Direction */
nDMAEN (z);/* DMA Channel Enable */
w[P5 + lo(DMA7_CONFIG)] = R7;
IMM32(R7,rx_buf);
[P5 + lo(DMA7_START_ADDR)] = R7;
#endif
call spi_init;
(R7:6,P5:5) = [SP++];
unlink;
rts;
spi_init_rx.end:
/*****************************************************************************
Function: spi_init
Description: Basic SPI settings, that are not specific to
direction and/or master<->slave mode
Start SPI
Start DMA, if defined
Input Parameters: none
Return Parameters: none
Registers Used: R7:6,R0,P5,ASTAT
Global Variables Used: none
C-Callable : no
*****************************************************************************/
spi_init:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:6,P5:5);
[--SP] = R0;
IMM32(P5,SYS_MMR_BASE);
/* In Master SPI Receive Mode, TIMOD = 10 */
/* Always enable first DMA, then SPI */
/* SPI raises immediately an interrupt when enabled */
/* In Master SPI Transmit Mode, TIMOD = 11 */
/* SPI starts with the first write access of the DMA */
/* When SPI is enabled (without enabled DMA), SPI clock is going down (if pulled-up) */
/******
* DMA *
******/
#if defined SPI_DMA
R7 = 0 (z);
[P5 + lo(DMA7_NEXT_DESC_PTR)] = R7;
[P5 + lo(DMA7_CURR_DESC_PTR)] = R7;
[P5 + lo(DMA7_CURR_ADDR)] = R7;
R7 = PMAP_SPI (z);
w[P5 + lo(DMA7_PERIPHERAL_MAP)] = R7;
R7 = DMA7_X_COUNT_VAL (z);
w[P5 + lo(DMA7_X_COUNT)] = R7;
R7 = DMA7_Y_COUNT_VAL (z);
w[P5 + lo(DMA7_Y_COUNT)] = R7;
R7 = DMA7_X_MODIFY_VAL (z);
w[P5 + lo(DMA7_X_MODIFY)] = R7;
R7 = DMA7_Y_MODIFY_VAL (z);
w[P5 + lo(DMA7_Y_MODIFY)] = R7;
R7 = w[P5 + lo(DMA7_CONFIG)] (z);
#if defined SPI_WDSIZE_16
bitset(R7,bitpos(WDSIZE_16));
#endif
w[P5 + lo(DMA7_CONFIG)] = R7;
#endif
/******
* SPI *
******/
#if defined SPI_MASTER_MODE
#if defined SPI_BAUD_VAL
R7 = SPI_BAUD_VAL (z);
/* ensure that SPI baud register value is >= 2 */
CC = R7 < 2;
if !CC jump rskip;
R7 = 2 (z);
rskip:
/* set SPI Baud register value */
w[P5 + lo(SPI_BAUD)] = R7;
#else
call spi_calc_baud;
w[P5 + lo(SPI_BAUD)] = R0;
#endif
R7 = w[P5 + lo(SPI_FLG)] (z);
R6 = 0x1;
R6 <<= SPI_SLAVE;
R7 = R7 | R6;
#if defined SPI_CPHA /* if CPHA = 1 and MSTR = 1, write to SPI_FLG to select slave(s) via FLGx bits */
R6 <<= 8;
R6 = ~R6;
R7 = R6 & R7;
#endif
w[P5 + lo(SPI_FLG)] = R7;
#endif
R7 = w[P5 + lo(SPI_CTL)] (z);
#if defined SPI_WDSIZE_16
bitset(R7,bitpos(SIZE));
#endif
#if defined SPI_LSBF
bitset(R7,bitpos(LSBF));
#endif
#if defined SPI_CPHA
bitset(R7,bitpos(CPHA));
#endif
#if defined SPI_CPOL_LOW
bitset(R7,bitpos(CPOL));
#endif
#if defined SPI_MASTER_MODE
bitset(R7,bitpos(MSTR));
#endif
w[P5 + lo(SPI_CTL)] = R7;
R0 = [SP++];
(R7:6,P5:5) = [SP++];
ASTAT = [SP++];
unlink;
rts;
spi_init.end:
/*****************************************************************************
Function: spi_start
Description: Basic SPI settings, that are not specific to
direction and/or master<->slave mode
Start SPI
Start DMA, if defined
Input Parameters: none
Return Parameters: none
Registers Used: R7:6,P5
Global Variables Used: none
C-Callable : no
*****************************************************************************/
spi_start:
link 0;
[--SP] = (R7:6,P5:5);
IMM32(P5,SYS_MMR_BASE);
/* In Master SPI Receive Mode, TIMOD = 10 */
/* Always enable first DMA, then SPI */
/* SPI raises immediately an interrupt when enabled */
/* In Master SPI Transmit Mode, TIMOD = 11 */
/* SPI starts with the first write access of the DMA */
/* When SPI is enabled (without enabled DMA), SPI clock is going down (if pulled-up) */
/******
* DMA *
******/
#if defined SPI_DMA
R7 = w[P5 + lo(DMA7_CONFIG)] (z);
bitset(R7,bitpos(DMAEN));
w[P5 + lo(DMA7_CONFIG)] = R7;
ssync;
#endif
/******
* SPI *
******/
R7 = w[P5 + lo(SPI_CTL)] (z);
bitset(R7,bitpos(SPE));
w[P5 + lo(SPI_CTL)] = R7;
ssync;
#if defined (SPI_SLAVE_MODE) && defined (PFHW)
call hostwait_deassert;
#endif
#if defined SPI_DMA
idle; /* wait for SPI DMA interrupt wake-up */
#endif
(R7:6,P5:5) = [SP++];
unlink;
rts;
spi_start.end:
/****************************************************************************
Function: __spi_stop
Description: Stop and disable SPI (and SPI DMA)
Stop and disable SPI DMA, if defined
Input Parameters: none
Return Parameters: none
Registers Used: R7,P5
Global Variables Used: none
C-Callable : no
*****************************************************************************/
__spi_stop:
link 0;
[--SP] = (R7:7,P5:5);
IMM32(P5,SYS_MMR_BASE);
#if defined (SPI_SLAVE_MODE) && defined (PFHW)
call __hostwait_assert;
#endif
#if defined SPI_DMA
R7 = 0 (z);
w[P5 + lo(DMA7_CONFIG)] = R7; /* Disable DMA */
#endif
#if defined SPI_MASTER_MODE
R7 = 0xFF00 (z);
w[P5 + lo(SPI_FLG)] = R7; /* reset SPI_FLAG register */
#endif
R7 = 0 (z);
w[P5 + lo(SPI_BAUD)] = R7;
R7 = CPHA (z);
w[P5 + lo(SPI_CTL)] = R7; /* reset SPI_CTL register -> disable SPI */
R7 = nSPIF | /* SPI Finished (RO) */
MODF | /* Mode Fault Error (W1C) */
TXE | /* Transmission Error (W1C) */
nTXS | /* TDBR Data Buffer Status (RO) */
RBSY | /* Receive Error (W1C) */
nRXS | /* RDBR Data Buffer Status (RO) */
TXCOL (z);/* Transmit Collision Error (W1C) */
w[P5 + lo(SPI_STAT)] = R7; /* W1C: clear status bits */
R7 = w[P5 + lo(SPI_RDBR)] (z); /* dummy read to clear RXS bit */
R7 = w[P5 + lo(SPI_SHADOW)] (z); /* dummy read to clear RXS bit */
(R7:7,P5:5) = [SP++];
unlink;
rts;
__spi_stop.end:
#if defined SPI_MASTER_MODE
/****************************************************************************
Function: spi_calc_baud
Description: generic SPI baud rate calculation function
Input Parameters: none
Return Parameters: R0
Registers Used: R1,R0,ASTAT
Global Variables Used: none
C-Callable : no
*****************************************************************************/
spi_calc_baud:
link 0;
[--SP] = ASTAT;
[--SP] = R1;
call __get_sclk_hz;
IMM32(R1,2*FSPI0CLK_Hz);
udiv32();
/* SPI_BAUD <= 0xFFFF */
spi_calc_baud.check_once:
IMM32(R1,0xFFFF);
CC = R1 < R0;
if !CC jump spi_calc_baud.check_twice;
R0 = R1;
jump spi_calc_baud.completed;
/* SPI_BAUD > 0x1 */
spi_calc_baud.check_twice:
R1 = 2 (z);
CC = R0 < R1;
if !CC jump spi_calc_baud.completed;
R0 = R1;
spi_calc_baud.completed:
R1 = [SP++];
ASTAT = [SP++];
unlink;
rts;
spi_calc_baud.end:
#endif /* SPI_MASTER_MODE */
#if defined PFHW
/*****************************************************************************
Function: __hostwait_assert
Description: assert hostwait signal, active low signal
Input Parameters: none
Return Parameters: none
Registers Used: R7,P5
Global Variables Used: none
C-Callable : no
******************************************************************************/
__hostwait_assert:
link 0;
[--SP] = (R7:7,P5:5);
IMM32(P5,SYS_MMR_BASE);
R7 = PFHW (z);
w[P5 + lo(PORTFIO_CLEAR)] = R7;
ssync;
(R7:7,P5:5) = [SP++];
unlink;
rts;
__hostwait_assert.end:
/*****************************************************************************
Function: hostwait_deassert
Description: de-assert hostwait signal, active low signal
Input Parameters: none
Return Parameters: none
Registers Used: R7,P5
Global Variables Used: none
C-Callable : no
******************************************************************************/
hostwait_deassert:
link 0;
[--SP] = (R7:7,P5:5);
IMM32(P5,SYS_MMR_BASE);
R7 = PFHW (z);
w[P5 + lo(PORTFIO_SET)] = R7;
ssync;
(R7:7,P5:5) = [SP++];
unlink;
rts;
hostwait_deassert.end:
/*****************************************************************************
Function: __hostwait_check
Description: wait for HOSTWAIT signal to be deasserted
Input Parameters: none
Return Parameters: none
Registers Used: R7,P5,ASTAT
Global Variables Used: none
C-Callable : no
*****************************************************************************/
__hostwait_check:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:7,P5:5);
IMM32(P5,SYS_MMR_BASE);
__hostwait_check.wait:
R7 = w[P5 + lo(PORTFIO)] (z);
CC = bittst(R7,bitpos(PFHW));
if !CC jump __hostwait_check.wait;
(R7:7,P5:5) = [SP++];
ASTAT = [SP++];
unlink;
rts;
__hostwait_check.END:
#endif /* defined PFHW */
/*****************************************************************************
EOF
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -