📄 spi.c
字号:
/************************************************
//
// File Name :
// Description : SPI One board Test
// SPI0: Master Tx
// SPI1: Slave Rx
// Version :
// Date :
//
************************************************/
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2413addr.h"
#include "Console.h"
#include "System.h"
#include "spi.h"
//////// SPI Channel Status Bit Define ////////
#define RXFIFOAF0 (rSPSTA0>>11)&0x1
#define TXFIFOAE0 (rSPSTA0>>10)&0x1
#define RXFIFOFERR0 (rSPSTA0>>9)&0x1
#define TXFIFOEERR0 (rSPSTA0>>8)&0x1
#define RXFIFOFULL0 (rSPSTA0>>7)&0x1
#define RXFIFONEMPTY0 (rSPSTA0>>6)&0x1
#define TXFIFONFULL0 (rSPSTA0>>5)&0x1
#define TXFIFOEMPTY0 (rSPSTA0>>4)&0x1
#define REDY0_org (rSPSTA0>>3)&0x1
#define DCOL0 (rSPSTA0>>2)&0x1
#define REDY0 rSPSTA0&0x1
#define RXFIFOAF1 (rSPSTA1>>11)&0x1
#define TXFIFOAE1 (rSPSTA1>>10)&0x1
#define RXFIFOFERR1 (rSPSTA1>>9)&0x1
#define TXFIFOEERR1 (rSPSTA1>>8)&0x1
#define RXFIFOFULL1 (rSPSTA1>>7)&0x1
#define RXFIFONEMPTY1 (rSPSTA1>>6)&0x1
#define TXFIFONFULL1 (rSPSTA1>>5)&0x1
#define TXFIFOEMPTY1 (rSPSTA1>>4)&0x1
#define REDY1_org (rSPSTA1>>3)&0x1
#define DCOL1 (rSPSTA1>>2)&0x1
#define REDY1 rSPSTA1&0x1
#define SPI_BUFFER0 _NONCACHE_STARTADDRESS
#define SPI_BUFFER1 _NONCACHE_STARTADDRESS+0x1000
#define DMA1_RxBUFFER0 _NONCACHE_STARTADDRESS+0x2000
#define DMA1_TxBUFFER0 _NONCACHE_STARTADDRESS+0x3000
#define DMA3_RxBUFFER1 _NONCACHE_STARTADDRESS+0x4000
#define DMA3_TxBUFFER1 _NONCACHE_STARTADDRESS+0x5000
#define D_PAT0 _NONCACHE_STARTADDRESS+0x6000
#define D_PAT1 _NONCACHE_STARTADDRESS+0x7000
#define D_PAT2 _NONCACHE_STARTADDRESS+0x8000
#define D_PAT3 _NONCACHE_STARTADDRESS+0x9000
#define SPI_CLOCK 2500000
#define SPI_ONE_WAY
#define spitx_count 0xff
#define spirx_count 0xff
typedef struct tagDMA
{
volatile U32 DISRC; //0x0
volatile U32 DISRCC; //0x4
volatile U32 DIDST; //0x8
volatile U32 DIDSTC; //0xc
volatile U32 DCON; //0x10
volatile U32 DSTAT; //0x14
volatile U32 DCSRC; //0x18
volatile U32 DCDST; //0x1c
volatile U32 DMASKTRIG; //0x20
volatile U32 DMAREQSEL; //0x24
}DMA;
void (*Master_nSS_Con)(int); // Declare Chip Select Function Pointer
void SPI_Baud_Rate_Set(SPI_channel ch, float BaudRate); // General Function
void SPI_Port_Init(U32 WhichMstr); // General Function
void SPI_Port_Return(void); // General Function
void _Master_nSS_Con0(int Set); // General Function
void _Master_nSS_Con1(int Set); // General Function
void MakeDPAT(void);
void ElaseRxReg(void);
void BufFlush(void);
void Observer_Init(void); // Utility Function
void Toggle(void); // Utility Function
void Test_Spi0_MS_poll(void);
void Test_Spi0_MS_int(void);
void Test_SPI0_M_poll(void);
void Test_SPI0_S_poll(void);
void Test_SPI0_M_Tx_DMA(void);
void Test_SPI0_S_Rx_DMA(void);
void Test_SPI0_M_Rx_DMA(void);
void Test_SPI0_S_Tx_DMA(void);
void Test_SPI0_M_int(void);
void Test_SPI0_S_int(void);
void Test_SPI0_M_DMA_FIFO(void);
void Test_SPI0_S_DMA_FIFO(void);
void Test_SPI0_M_Rx_DMA_FIFO(void);
void Test_SPI0_S_Tx_DMA_FIFO(void);
void Test_FIFO_TIMEOUT_INT(void);
void TimerSet(void);
void Test_Spi0_M_Tx_DMA1_Set(void);
void Test_Spi0_S_Rx_DMA3_Set(void);
void Test_Spi0_S_Tx_DMA1_Set(void);
void Test_Spi0_M_Rx_DMA3_Set(void);
void Test_Spi0_M_Tx_DMA1_FIFO_Set(void);
void Test_Spi0_S_Rx_DMA3_FIFO_Set(void);
void __irq Spi0_LoopBack_Int(void);
void __irq Spi0_M_Int(void);
void __irq Spi0_S_Int(void);
void __irq Spi0_FIFO_Int(void);
void __irq Spi0_FIFO_TimeOut_Int(void);
void __irq Dma1Tx_Int(void);
void __irq Dma3Rx_Int(void);
volatile char *spi0TxStr,*spi0RxStr;
volatile char *spi1TxStr,*spi1RxStr;
volatile int endSpi0Tx;
volatile int endSpi1Tx;
volatile int end0SpiTx;
volatile int rxdone;
volatile int c1,c0;
unsigned int interrupt_count[2];
unsigned int spi_dma_done[4];
static unsigned char *tx_ptr[SPI_CHANNEL_MAX];
static unsigned char *rx_ptr[SPI_CHANNEL_MAX];
volatile int tx_dma1Done;
volatile int rx_dma1Done;
volatile int tx_dma3Done;
volatile int rx_dma3Done;
U32 spi0_rGPECON, spi0_rGPEDAT,spi0_rGPEDN; // for SPI0 Port Return
U32 spi1_rGPGCON, spi1_rGPGDAT,spi1_rGPGDN; // for SPI1 Port Return
void * spi_func[][2]=
{
///////////////////////// One Board Test /////////////////////////
(void *)Test_Spi0_MS_poll, "SPI0 RxTx POLL (Loop Back Test) ",
(void *)Test_Spi0_MS_int, "SPI0 RxTx INT (Loop Back Test) ",
///////////////////////// Two Board Test /////////////////////////
(void *)Test_SPI0_M_poll, "SPI0:Master(TxRx), POLL ",
(void *)Test_SPI0_S_poll, "SPI0:Slave (TxRx), POLL ",
(void *)Test_SPI0_M_int, "SPI0:Master(TxRx), INT ",
(void *)Test_SPI0_S_int, "SPI0:Slave (TxRx), INT ",
(void *)Test_SPI0_M_Tx_DMA, "SPI0:Master(Tx), DMA ",
(void *)Test_SPI0_S_Rx_DMA, "SPI0:Slave (Rx), DMA ",
(void *)Test_SPI0_M_Rx_DMA, "SPI0:Master(Rx), DMA ",
(void *)Test_SPI0_S_Tx_DMA, "SPI0:Slave (Tx), DMA ",
(void *)Test_SPI0_M_DMA_FIFO, "SPI0:Master(Tx), DMA with FIFO ",
(void *)Test_SPI0_S_DMA_FIFO, "SPI0:Slave (Rx), DMA with FIFO ",
(void *)Test_SPI0_M_Rx_DMA_FIFO, "SPI0:Master(Rx), DMA with FIFO ",
(void *)Test_SPI0_S_Tx_DMA_FIFO, "SPI0:Slave (Tx), DMA with FIFO ",
(void *)Test_FIFO_TIMEOUT_INT, "Rx FIFO Time Out Int Test (Slave Rx)",
(void *)SPI_master_slave_test, "SPI_master_slave_test ",
(void *)SPI_loop_test, "SPI_loop_test ",
(void *)SPI_master_master_test, "SPI_master_master_test ",
(void *)SPI_master_loop_int_test, "SPI_master_loop_int_test ",
(void*)SPI_slave_int_master_polling_test, "SPI_slave_int_master_polling_test ",
(void*)SPI_slave_polling_master_polling_test, "SPI_slave_polling_master_polling_test ",
(void*)SPI_slave_polling_master_polling_test_FIFO, "SPI_slave_polling_master_polling_test_FIFO ",
(void*) SPI_master_DMA_slave_polling_test, "SPI_master_DMA_slave_polling_test ",
(void*)SPI_slave_DMA_master_polling_test, "SPI_slave_DMA_master_polling_test ",
(void*)SPI_master_FIFO_DMA_slave_polling_test, "SPI_master_FIFO_DMA_slave_polling_test ",
(void*)SPI_slave_FIFO_DMA_master_polling_test, "SPI_slave_FIFO_DMA_master_polling_test ",
0,0
};
void Ch21_Spi(void)
{
int i=0;
// GPG0 甫 葛聪磐傅栏肺 荤侩窍扁 困秦 Output 栏肺 汲沥窃.
Observer_Init();
// 傈价瞪 data 甫 瘤沥等 皋肺府俊 历厘窃.
MakeDPAT();
while(1)
{
i=0;
while(1)
{ //display menu
if((i+1)%2)printf("\n");
printf("%2d:%s",i,spi_func[i][1]);
i++;
if((int)(spi_func[i][0])==0)
{
printf("\n");
break;
}
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(spi_func)-1)/8)) ) // select and execute...
( (void (*)(void)) (spi_func[i][0]) )();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Test_Spi0_MS_poll(void)
{
char *txStr,*rxStr;
printf("[SPI Polling Tx/Rx Self-Test]\n");
printf("Connect SPIMOSI 0 into SPIMISO 0 CON26: (2-3)\n");
ElaseRxReg();
endSpi0Tx=0;
spi0TxStr=(volatile char*)D_PAT0;
spi0RxStr=(char *) SPI_BUFFER0; // Rx Buffer to receive
txStr=(char *)spi0TxStr;
rxStr=(char *)spi0RxStr;
SPI_Port_Init(0);
SPI_Baud_Rate_Set(SPI_CHANNEL0, SPI_CLOCK); // SPI Channel 0, 25MHz
rSPCON0=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
// rSPCON0=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//Polling,en-SCK,master,low,B,normal
// rSPCON0=(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,high,A,normal
// rSPCON0=(0<<5)|(1<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0);//Polling,en-SCK,master,high,B,normal
rSPPIN0=(1<<3)|(1<<0);//Feedback Clock Enable, Master Out Keep
while(endSpi0Tx==0)
{
if(REDY0) //Check Tx ready state
{
if(*spi0TxStr!='\0')
WrSPTDAT0(*spi0TxStr++);
else {
endSpi0Tx=1;
break;
}
while(!(REDY0)); //Check Rx ready state
*spi0RxStr++=RdSPRDAT0();
}
}
*spi0RxStr++=RdSPRDAT0();
*spi0RxStr='\0'; // attach End of String(Null)
rxStr++; // remove first dummy
printf("Tx Strings:%s\n",txStr);
printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0) printf("O.K.\n");
else printf("ERROR!!!\n");
while(*rxStr!='\0') {
printf("%x\n",*rxStr++);
}
SPI_Port_Return();
}
void Test_Spi0_MS_int(void)
{
char *txStr,*rxStr;
printf("[SPI Interrupt Tx/Rx Self-Test]\n");
printf("Connect SPIMOSI 0 into SPIMISO 0 CON26: (2-3)\n");
ElaseRxReg();
endSpi0Tx=0;
spi0TxStr=(volatile char*)D_PAT1;
spi0RxStr=(char *) SPI_BUFFER0; // Rx Buffer to receive
txStr=(char *)spi0TxStr;
rxStr=(char *)spi0RxStr;
SPI_Port_Init(0);
SPI_Baud_Rate_Set(SPI_CHANNEL0, 25000000); // SPI Channel 0, 25MHz
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
pISR_SPI0=(unsigned)Spi0_LoopBack_Int;
rINTMSK&=~(BIT_SPI0);
while(endSpi0Tx==0);
*spi0RxStr='\0'; // attach End of String(Null)
rxStr++; // remove first dummy
printf("Tx Strings:%s\n",txStr);
printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0) printf("O.K.\n");
else printf("ERROR!!!\n");
SPI_Port_Return();
}
void __irq Spi0_LoopBack_Int(void)
{
ClearPending(BIT_SPI0);
c0++;
if(*spi0TxStr!='\0')
WrSPTDAT0(*spi0TxStr++);
else
endSpi0Tx=1;
*spi0RxStr++=RdSPRDAT0(); //First Rx data is garbage data
if(DCOL0) printf("Data Collision or Multi Master Error!!!\n");
}
void Test_SPI0_M_poll(void)
{
char *txStr,*rxStr;
printf("[One Board SPI0(Master Tx), Another Board SPI0(Slave Rx) Poll test]\n");
printf("First Slave is ready? Press any key, Start\n");
getchar();
ElaseRxReg();
endSpi0Tx=0;
spi0TxStr="1032547698ACBEDGFIHKJMLONQPSRUTWVYXZacbedgfihkjmlonqpsrutwvyxz";
spi0RxStr=(char *) SPI_BUFFER0; // Rx Buffer to receive
txStr=(char *)spi0TxStr;
rxStr=(char *)spi0RxStr;
SPI_Port_Init(0);
SPI_Baud_Rate_Set(SPI_CHANNEL0, 25000000); // SPI Channel 0, 25MHz
rSPCON0=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN0=(1<<3)|(1<<0);//Feedback Clock Enable, Master Out Keep
Master_nSS_Con(0); // Activate nSS
while(endSpi0Tx==0)
{
while(!(REDY0)); //Check Tx/Rx ready state
WrSPTDAT0(*spi0TxStr++);
if(*spi0TxStr=='\0')
endSpi0Tx=1;
while(!(REDY0)); //Check Rx ready state
*spi0RxStr++=RdSPRDAT0();
}
// *spi0RxStr++=RdSPRDAT0();
*spi0RxStr='\0'; // attach End of String(Null)
rxStr++; // remove first dummy
Master_nSS_Con(1); // dis-activate nSS
printf("Tx Strings:%s\n",txStr);
printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0) printf("O.K.\n");
else printf("ERROR!!!\n");
SPI_Port_Return();
}
void Test_SPI0_S_poll(void)
{
char *txStr,*rxStr;
printf("[SPI0(Slave Rx) Poll test]\n");
ElaseRxReg();
endSpi0Tx=0;
spi0TxStr="1032547698ACBEDGFIHKJMLONQPSRUTWVYXZacbedgfihkjmlonqpsrutwvyxz";
spi0RxStr=(char *) SPI_BUFFER0; // Rx Buffer to receive
txStr=(char *)spi0TxStr;
rxStr=(char *)spi0RxStr;
SPI_Port_Init(0);
SPI_Baud_Rate_Set(SPI_CHANNEL0, 25000000); // SPI Channel 0, 25MHz
rSPCON0=(0<<5)|(0<<4)|(0<<3)|(1<<2)|(0<<1)|(0<<0);//Interrupt,dis-SCK,slave,low,A,normal
rSPPIN0=(0<<2)|(1<<0);//dis-ENMUL,KEEP
while(endSpi0Tx==0)
{
while(!(REDY0)); //Check Rx ready state
WrSPTDAT0(*spi0TxStr++);
if(*spi0TxStr!='\0')
endSpi0Tx=1;
while(!(REDY0)); //Check Rx ready state
*spi0RxStr++=RdSPRDAT0();
}
// *spi0RxStr++=RdSPRDAT0();
*spi0RxStr='\0'; // attach End of String(Null)
rxStr++; // remove first dummy
printf("Tx Strings:%s\n",txStr);
printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0) printf("O.K.\n");
else printf("ERROR!!!\n");
SPI_Port_Return();
}
void Test_SPI0_M_int(void)// SPI0=Master
{
char *txStr,*rxStr;
c0=0;
printf("[One Board SPI0(Master Tx), Another Board SPI0(Slave Rx) Interrupt test]\n");
printf("First Slave is ready? Press any key, Start\n");
getchar();
ElaseRxReg();
endSpi0Tx=0;
spi0TxStr="zxyvwturspqnolmjkhifgdebcaZXYVWTURSPQNOLMJKHIFGDEBCA8967452301";
spi0RxStr=(char *) SPI_BUFFER0; // Rx Buffer to receive
txStr=(char *)spi0TxStr;
rxStr=(char *)spi0RxStr;
SPI_Port_Init(0);
SPI_Baud_Rate_Set(SPI_CHANNEL0, 25000000); // SPI Channel 0, 25MHz
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Interrupt,en-SCK,master,low,A,normal
rSPPIN0=(1<<3)|(0<<2)|(1<<1)|(1<<0);//dis-ENMUL,KEEP
Master_nSS_Con(0); // Activate nSS
pISR_SPI0=(unsigned)Spi0_M_Int;
rINTMSK&=~(BIT_SPI0);
while(endSpi0Tx==0);
rINTMSK|=(BIT_SPI0);
Master_nSS_Con(1); // Activate nSS
*spi0RxStr++=RdSPRDAT0(); // Get last rx data
*spi0RxStr='\0'; // attach End of String(Null)
rxStr++; // remove first dummy
printf("Tx Strings:%s\n",txStr);
printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0) printf("O.K.\n");
else printf("ERROR!!!\n");
SPI_Port_Return();
printf("c0=%d\n",c0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -