📄 hspi.c
字号:
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
pISR_SPI0 = (unsigned)HSPI_Tx_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
rMODE_CFG &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode
rSPI_INT_EN |= INT_TX_FIFORDY;
rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_TXCH_ON; // Rx Channel On
rINTMSK &= ~(BIT_SPI0);
nSSLow();
while(!SpiTxIntEnd);
while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
nSSHigh();
printf("\nTransfer End\n");
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void Test_SlaveRxOnly_INT(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
pISR_SPI0 = (unsigned)HSPI_Rx_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Slave
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
rMODE_CFG &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode
rPENDING_CLR = 0xffffffff;
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
rSPI_INT_EN |= INT_RX_FIFORDY;
rCH_CFG |= CH_RXCH_ON; // Tx Rx Channel On
rINTMSK &= ~(BIT_SPI0);
while(!SpiRxIntEnd);
//while ((rSPI_STATUS>>13)&0x7f); // check if Rx Fifo empty
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void Test_MasterRxOnly_INT(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
m_uTxTrigLvl = 0x8;
m_uRxTrigLvl = 0x8;
#endif
pISR_SPI0 = (unsigned)HSPI_Rx_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
//printf("\nTotal Transfer size = %d",DataCnt);
rPACKET_CNT = (1<<16) | (PacketCntValue);
rMODE_CFG = (rMODE_CFG & ~(MODE_RXDMA_ON | MODE_TXDMA_ON)) | (0x3ff<<19); // Set the INT mode
rPENDING_CLR = 0xffffffff;
rSPI_INT_EN |= INT_TRAILING | INT_RX_FIFORDY;
rCH_CFG |= CH_RXCH_ON; // Tx Rx Channel On
rINTMSK &= ~(BIT_SPI0);
nSSLow();
while(SpiRxIntEnd == 0);
SpiRxIntEnd = 0;
//Uart_getc();
nSSHigh();
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void Test_SlaveTxOnly_INT(void)
{
U32 i;
//U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
//U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
pISR_SPI0 = (unsigned)HSPI_Tx_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt+20; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Master
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
rMODE_CFG &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode
rSPI_INT_EN |= INT_TX_FIFORDY;
rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_TXCH_ON; // Rx Channel On
rINTMSK &= ~(BIT_SPI0);
while(SpiTxIntEnd == 0);
SpiTxIntEnd = 0;
while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
printf("\nTransfer Complete");
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void HS_SPI_ERROR_CHECK(void)
{
printf("\nError check");
pISR_SPI0 = (unsigned)HSPI_ERR_Int;
rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
rINTMSK &= ~(BIT_SPI0);
}
void InitHSPI(U32 MasterSlave, U32 Cpol, U32 Cpha, U32 ClkSel)
{
float uPrescaler = .0;
if(BYTEOPERATION == 1)
PacketCntValue = DataCnt;
else
PacketCntValue = DataCnt*4;
if (ClkSel == HSPI_PCLK)
uPrescaler = (float)(PCLK/2/Baudrate) - 1;
else if(ClkSel == HSPI_EPLL)
uPrescaler = (float)(ECLK/2/Baudrate) - 1;
printf("\nuPrescaler = %f",uPrescaler);
// 1. Set Tranfer Type
rCH_CFG = (rCH_CFG & ~(0x3f)) |
((MasterSlave == Master)? CH_MASTER : CH_SLAVE) |
((Cpol == CPOLHIGH)? CH_RISING : CH_FALLING) |
((Cpha == FORMAT_A)? CH_FORMAT_A : CH_FORMAT_B);
// 2. Clock Config
rCLK_CFG = (rCLK_CFG & ~(0x7ff)) |
((ClkSel == HSPI_PCLK)? CLK_CLKSEL_PCLK : CLK_CLKSEL_ECLK) |
((MasterSlave == Master)? CLK_ENCLK_ENABLE : CLK_ENCLK_DISABLE)| // SPI clk enable
PRESCALER((U8)uPrescaler);
// 3. Mode Config
rMODE_CFG = (rMODE_CFG & ~(0x1fffffff)) |
TRAIL_CNT(0x3ff) |
((BYTEOPERATION == 0)? MODE_BUS_SZ_WORD : MODE_BUS_SZ_BYTE) |
RX_TRIG_LVL(m_uRxTrigLvl) |
TX_TRIG_LVL(m_uTxTrigLvl) |
//(1<<4)|
((BURSTOPERATION == 1)? MODE_BUS_4BURST : MODE_BUS_SINGLE);
}
void TxDMAInit(U32 uSrcAddr, U32 uDstAddr,U32 uDataCnt)
{
U32 uIsSrcApb = LOCAHB;
U32 uIsDstApb = LOCAPB;
U32 bSrcFixed = ADDRINC;
U32 bDstFixed = ADDRFIX;
U32 TC=0;
U32 eDataSz=0, Burst=0;
if(BYTEOPERATION == 1 && BURSTOPERATION == 1)
{
eDataSz = HSPI_BYTE;
TC = uDataCnt/4;
}
else if(BYTEOPERATION == 1 && BURSTOPERATION == 0)
{
eDataSz = HSPI_BYTE;
TC = uDataCnt;
}
else if(BYTEOPERATION == 0 && BURSTOPERATION == 1)
{
eDataSz = HSPI_WORD;
TC = uDataCnt/4;
}
else if(BYTEOPERATION == 0 && BURSTOPERATION == 0)
{
eDataSz = HSPI_WORD;
TC = uDataCnt;
}
Burst = BURSTOPERATION;
printf("\nTC = %x",TC);
rDISRC0 = uSrcAddr;
rDISRCC0 = uIsSrcApb<<1 | bSrcFixed<<0;
rDIDST0 = uDstAddr;
rDIDSTC0 = uIsDstApb<<1 | bDstFixed<<0;
rDCON0 = (rDCON0 & ~(0xffffffff)) |(U32)( (1<<31) |(1<<29) |(Burst<<28) |(0<<27)|(1<<24) |(1<<22) |(eDataSz<<20) |(TC));
rDMAREQSEL0 = (0 <<1) | 1;
}
void RxDMAInit(U32 uSrcAddr, U32 uDstAddr, U32 uDataCnt)
{
U32 uIsSrcApb = LOCAPB;
U32 uIsDstApb = LOCAHB;
U32 bSrcFixed = ADDRFIX;
U32 bDstFixed = ADDRINC;
U32 TC=0;
U32 eDataSz=0, Burst=0;
if(BYTEOPERATION == 1 && BURSTOPERATION == 1)
{
eDataSz = HSPI_BYTE;
TC = uDataCnt/4;
}
else if(BYTEOPERATION == 1 && BURSTOPERATION == 0)
{
eDataSz = HSPI_BYTE;
TC = uDataCnt;
}
else if(BYTEOPERATION == 0 && BURSTOPERATION == 1)
{
eDataSz = HSPI_WORD;
TC = uDataCnt/4;
}
else if(BYTEOPERATION == 0 && BURSTOPERATION == 0)
{
eDataSz = HSPI_WORD;
TC = uDataCnt;
}
Burst = BURSTOPERATION;
printf("\nTC = %x",TC);
rDISRC1 = uSrcAddr;
rDISRCC1 = uIsSrcApb<<1 | bSrcFixed<<0;
rDIDST1 = uDstAddr;
rDIDSTC1 = uIsDstApb<<1 | bDstFixed<<0;
rDCON1 = (rDCON1 & ~(0xffffffff)) | (U32)((1<<31) |(1<<29) |(Burst<<28) |(0<<27) |(1<<24) |(1<<22) |(eDataSz<<20) |(TC));
rDMAREQSEL1 = (1 <<1) | 1;
}
void __irq HSPI_Tx_Int(void)
{
U32 i=0;
U32 x,TxTriglevel =0;
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);
#if BYTEOPERATION
x = ((rSPI_STATUS>>6)&0x7f);
TxTriglevel = 64 -x;
#else
x = ((rSPI_STATUS>>6)&0x7f)/4;
TxTriglevel = 16-x;
#endif
while (i<TxTriglevel && TransferdDataCnt < DataCnt) // check if Rx Fifo empty
{
rSPI_TX_DATA = (*(TxBufAddr+TransferdDataCnt));
TransferdDataCnt++;
i++;
//printf("TransferdDataCnt ISR= %d\n",TransferdDataCnt);
}
rINTMSK &= ~(BIT_SPI0);
if(TransferdDataCnt == DataCnt)
{
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
SpiTxIntEnd = 1;
}
}
void __irq HSPI_Rx_Int(void)
{
int i=0;
int RxTriglevel=0;
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);
#if BYTEOPERATION
RxTriglevel = ((rSPI_STATUS>>13)&0x7f);
#else
RxTriglevel = ((rSPI_STATUS>>13)&0x7f)/4;
#endif
//printf("\nRxTriglevel = %x",(rSPI_STATUS>>13)&0x7f);
while (i<RxTriglevel) // check if Rx Fifo empty
{
*(RxBufAddr+ReceivedDataCnt) = rSPI_RX_DATA;
i++;
ReceivedDataCnt ++;
//printf("TransferdDataCnt ISR= %d\n",ReceivedDataCnt);
}
rINTMSK &= ~(BIT_SPI0);
if(ReceivedDataCnt == DataCnt)
{
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
SpiRxIntEnd = 1;
}
}
void __irq HSPI_Int(void)
{
int i=0;
int RxReadCnt=0;
int x, TxWriteCnt=0;
int Status = 0;
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
Status = rSPI_STATUS;
rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);
if(Status & (1<<1) || Status & (1<<20))//Read FIFO ready
{
if(BYTEOPERATION)
{
RxReadCnt = ((rSPI_STATUS>>13)&0x7f);
}
else
RxReadCnt = ((rSPI_STATUS>>13)&0x7f)/4;
while (i<RxReadCnt) // check if Rx Fifo empty
{
*(RxBufAddr+ReceivedDataCnt) = rSPI_RX_DATA;
i++;
ReceivedDataCnt ++;
//printf("Rx ISR cnt= %d\n",ReceivedDataCnt);
//if(ReceivedDataCnt == DataCnt)
// break;
}
}
else if(Status & (1<<0))//Write FIFO ready
{
if(BYTEOPERATION)
{
x = ((rSPI_STATUS>>6)&0x7f);
TxWriteCnt = 64 -x;
}
else
{
x = ((rSPI_STATUS>>6)&0x7f)/4;
TxWriteCnt = 16-x;
}
while (i<TxWriteCnt && TransferdDataCnt < DataCnt) // check if Rx Fifo empty
{
rSPI_TX_DATA = (*(TxBufAddr+TransferdDataCnt));
TransferdDataCnt++;
i++;
//printf("Tx ISR cnt= %d\n",TransferdDataCnt);
//if(TransferdDataCnt == DataCnt)
// break;
}
}
/*
else if(1<<2)
{
printf("\nTx Underrun Error");
}
else if(1<<3)
{
printf("\nTx Overrun Error");
}
else if(1<<4)
{
printf("\nRx Underrun Error");
}
else if(1<<5)
{
printf("\nRx Overrun Error");
}
*/
rINTMSK &= ~(BIT_SPI0);
if(TransferdDataCnt == DataCnt && ReceivedDataCnt == DataCnt)
{
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
SpiTxIntEnd = 1;
SpiRxIntEnd = 1;
}
}
void __irq DmaDone(void)
{
rINTMSK|=BIT_DMA;
ClearPending(BIT_DMA);
if(rSUBSRCPND & BIT_SUB_DMA0)
{
printf("\nTX DMA Done");
SpiTxDmaEnd=1;
rINTSUBMSK |= BIT_SUB_DMA0;
rSUBSRCPND |= BIT_SUB_DMA0;
}
else if(rSUBSRCPND & BIT_SUB_DMA1)
{
printf("\nRX DMA Done");
SpiRxDmaEnd=1;
rINTSUBMSK |= BIT_SUB_DMA1;
rSUBSRCPND |= BIT_SUB_DMA1;
}
}
void __irq HSPI_ERR_Int(void)
{
rINTMSK |= (BIT_SPI0);
ClearPending(BIT_SPI0);
printf("\nError ISR");
if(rSPI_STATUS & (INT_RX_OVERRUN))
printf("\nRx Overrun Error");
else if(rSPI_STATUS & (INT_RX_UNDERRUN))
printf("\nRx Underrun Error");
else if(rSPI_STATUS & (INT_TX_OVERRUN))
printf("\nRx Overrun Error");
else if(rSPI_STATUS & (INT_TX_UNDERRUN))
printf("\nTx Underrun Error");
rSPI_STATUS = INT_RX_OVERRUN |INT_RX_UNDERRUN | INT_TX_OVERRUN |INT_TX_UNDERRUN;
}
void CompareData(U32 a0, U32 a1, U32 bytes)
{
U32 * pD0 = (U32 *)a0;
U32 * pD1 = (U32 *)a1;
U32 ErrCnt = 0;
U32 i;
#if BYTEOPERATION
bytes = DataCnt;
#else
bytes = DataCnt/4;
#endif
for (i=0; i<bytes; i++)
{
if (*pD0 != *pD1)
{
printf("\n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1);
ErrCnt++;
}
pD0++;
pD1++;
}
printf("\nTotal Error cnt = %d",ErrCnt);
if(ErrCnt == 0)
printf("\nData Compare Ok\n");
}
void CompareDataByte(U8 a0, U8 a1, U8 bytes)
{
U8 * pD0 = (U8 *)a0;
U8 * pD1 = (U8 *)a1;
U8 ErrCnt = 0;
U32 i;
for (i=0; i<bytes; i++)
{
if (*pD0 != *pD1)
{
printf("\n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1);
ErrCnt++;
}
pD0++;
pD1++;
}
printf("\nTotal Error cnt = %d",ErrCnt);
if(ErrCnt == 0)
printf("\nData Compare Ok\n");
}
void Reset(void)
{
rCH_CFG |= (1<<5);
printf("\nHS SPI reset\n");
rCH_CFG &= ~(1<<5);
}
void nSSLow(void)
{
rSLAVE_SEL = 0;
}
void nSSHigh(void)
{
rSLAVE_SEL = 1;
}
void GPIOPortSet(void)
{
rMISCCR |= (U32)(1<<31);
rGPECON = rGPECON & ~(0x3f<<22) | (1<<27) | (1<<25) | (1<<23); // SPICLK0, SPIMOSI0, SPIMISO0
rGPLCON = rGPLCON & ~(0x3ff<<20) | (1<<29) | (1<<27) | (1<<25) | (1<<23) | (1<<21); // SS1, SS0, SPIMISO1, SPIMOSI1, SPICLK1
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -