📄 spi.c
字号:
#include "system.h"
#include "spi_dma.h"
#define rSPTXFIFO1 (*(volatile unsigned *)0x59000018)
#define rSPRXFIFO1 (*(volatile unsigned *)0x5900001C)
#define rSPFIC1 (*(volatile unsigned *)0x59000024)
#define rSPTOV (*(volatile unsigned *)0x59000028)
#define WrSPTDAT1(ch) (*(volatile unsigned char*)0x59000010)=(unsigned char)(ch)
#define RdSPRDAT1() (*(volatile unsigned char*)0x59000014)
#define RdSPRDATB1() (*(volatile unsigned char*)0x59000020)
#define WrSPTXFIFO1(ch) (*(volatile unsigned char*)0x59000018)=(unsigned char)(ch)
#define RdSPRXFIFO1() (*(volatile unsigned char*)0x5900001C)
#define REDY1_org (rSPSTA1>>3)&0x1 // In Slave, for Rx Checking
#define REDY1 rSPSTA1&0x1
#define SPI_BUFFER1 _NONCACHE_STARTADDRESS
volatile char *spi1TxStr,*spi1RxStr;
volatile int endSpi1Tx,endSpi1Rx;
volatile int tx_dmaDone, rx_dmaDone;
volatile int trans_count;
// For SPI Port Recovery
U32 rGPECON_saved;
U32 rGPEUDP_saved;
U32 rGPLCON_saved;
U32 rGPLUDP_saved;
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 Test_Spi1_Loopback_Poll(void);
void Test_Spi1_Loopback_Int(void);
void __irq Spi1_LoopBack_Int(void);
void Test_Spi1_M_Buf_Poll(void);
void Test_Spi1_S_Buf_Poll(void);
void Test_Spi1_M_Buf_Int(void);
void Test_Spi1_S_Buf_Int(void);
void __irq Spi1_M_Buf_Int(void);
void __irq Spi1_S_Buf_Int(void);
void Test_Spi1_M_Tx_Buf_DMA(void);
void Test_Spi1_S_Rx_Buf_DMA(void);
void Test_Spi1_M_Rx_Buf_DMA(void);
void Test_Spi1_S_Tx_Buf_DMA(void);
void Set_Spi1_Tx_DMA_Set(U32 ch);
void Set_Spi1_Rx_DMA_Set(U32 ch);
void __irq DmaTx_Int(void);
void __irq DmaRx_Int(void);
void Test_Spi1_M_Tx_Fifo_Int(void);
void Test_Spi1_M_Tx_Fifo_Int2(void);
void Test_Spi1_S_Rx_Fifo_Int(void);
void Test_Spi1_M_Rx_Fifo_Int(void);
void Test_Spi1_S_Tx_Fifo_Int(void);
void Test_Spi1_S_Tx_Fifo_Int2(void);
void __irq Spi1_Tx_fifo_Int(void);
void __irq Spi1_Rx_fifo_Int(void);
void Test_Spi1_M_Tx_Fifo_DMA(void);
void Test_Spi1_S_Rx_Fifo_DMA(void);
void Test_Spi1_M_Rx_Fifo_DMA(void);
void Test_Spi1_S_Tx_Fifo_DMA(void);
void Set_Spi1_Tx_Fifo_DMA(U32 ch);
void Set_Spi1_Rx_Fifo_DMA(U32 ch);
void SPI_Port_Init(void);
void SPI_Port_Recovery(void);
void SPI1_Master_nSS_Con(U32 CSout);
void SPI_Baud_Rate_Set(float BaudRate);
void SPI_Transfer_Format(void);
void * func_spi_test[][2]=
{
// "0123456789012345" max 15磊 肺茄沥窍咯 comment窍技夸.
//SPI
(void *)Test_Spi1_Loopback_Poll, "SPI1 loopback Poll",
(void *)Test_Spi1_Loopback_Int, "SPI1 loopback Int",
(void *)Test_Spi1_M_Buf_Poll, "SPI1:Master (Tx/Rx), Byte Access POLL",
(void *)Test_Spi1_S_Buf_Poll, "SPI1:Slave (Tx/Rx), Byte Access POLL",
(void *)Test_Spi1_M_Buf_Int, "SPI1:Master (Tx/Rx), Byte Access INT",
(void *)Test_Spi1_S_Buf_Int, "SPI1:Slave (Tx/Rx), Byte Access INT",
(void *)Test_Spi1_M_Tx_Buf_DMA, "SPI1:Master (Tx), Byte Access DMA",
(void *)Test_Spi1_S_Rx_Buf_DMA, "SPI1:Slave (Rx), Byte Access DMA",
(void *)Test_Spi1_M_Rx_Buf_DMA, "SPI1:Master (Rx), Byte Access DMA",
(void *)Test_Spi1_S_Tx_Buf_DMA, "SPI1:Slave (Tx), Byte Access DMA",
(void *)Test_Spi1_M_Tx_Fifo_Int, "SPI1:Master (Tx), Fifo INT",
(void *)Test_Spi1_M_Tx_Fifo_Int2, "SPI1:Master (2nd Tx), Fifo INT",
(void *)Test_Spi1_S_Rx_Fifo_Int, "SPI1:Slave (Rx), Fifo INT",
(void *)Test_Spi1_M_Rx_Fifo_Int, "SPI1:Master (Rx), Fifo INT",
(void *)Test_Spi1_S_Tx_Fifo_Int, "SPI1:Slave (Tx), Fifo INT",
(void *)Test_Spi1_S_Tx_Fifo_Int2, "SPI1:Slave (2nd Tx), Fifo INT",
(void *)Test_Spi1_M_Tx_Fifo_DMA, "SPI1:Master (Tx), Fifo DMA",
(void *)Test_Spi1_S_Rx_Fifo_DMA, "SPI1:Slave (Rx), Fifo DMA",
(void *)Test_Spi1_M_Rx_Fifo_DMA, "SPI1:Master (Rx), Fifo DMA",
(void *)Test_Spi1_S_Tx_Fifo_DMA, "SPI1:Slave (Tx), Fifo DMA",
0,0
};
void Test_SPI(void)
{
int i;
while(1)
{
i=0;
printf("\n====== SPI Test program start ======\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_spi_test[i][1]);
i++;
if((int)(func_spi_test[i][0])==0)
{
printf("\n");
break;
}
// if((i%4)==0)
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_spi_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_spi_test[i][0]) )();
}
printf("\n====== SPI Test program end ======\n");
}
void Test_Spi1_Loopback_Poll(void)
{
char *txStr,*rxStr;
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="Test Spi1 Loop Back Polling Mode acbedgfihkjmlonqpsrutwvyxz 1234567890 ACBEDGFIHKJMLONQPSRUTWVYXZ !@#$%^&*()_+|<>?";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
SPI_Baud_Rate_Set(25000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x6)|(0<<5)|(1<<4)|(1<<3)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
SPI1_Master_nSS_Con(0);
#if 1
while(endSpi1Tx==0)
{
if(REDY1) //Check Tx ready state
{
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
WrSPTDAT1(*spi1TxStr++); // Transfer last data(NULL Character)
endSpi1Tx=1;
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1();
}
}
#else
while(endSpi1Tx==0)
{
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
WrSPTDAT1(*spi1TxStr++); // Transfer last data(NULL Character)
endSpi1Tx=1;
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1();
}
#endif
SPI1_Master_nSS_Con(1);
*spi1RxStr++=RdSPRDAT1(); // read last data(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_Recovery();
}
void Test_Spi1_Loopback_Int(void)
{
char *txStr,*rxStr;
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="Test Spi1 Loop Back Interrupt Mode 1234567890 ACBEDGFIHKJMLONQPSRUTWVYXZ acbedgfihkjmlonqpsrutwvyxz !@#$%^&*()_+|<>?";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
SPI_Baud_Rate_Set(25000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x6)|(1<<5)|(1<<4)|(1<<3)|(0<<0);//Interrupt,en-SCK,master
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
SPI1_Master_nSS_Con(0);
pISR_SPI1=(unsigned)Spi1_LoopBack_Int;
rINTMSK&=~(BIT_SPI1);
while(endSpi1Tx==0);
SPI1_Master_nSS_Con(1);
*spi1RxStr++=RdSPRDAT1();
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_Recovery();
}
void __irq Spi1_LoopBack_Int(void)
{
ClearPending(BIT_SPI1);
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
WrSPTDAT1(*spi1TxStr++);
endSpi1Tx=1;
rINTMSK|=(BIT_SPI1);
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1(); //First Rx data is garbage data
}
void Test_Spi1_M_Buf_Poll(void)
{
char *txStr,*rxStr;
char dummy_read;
printf("[This Board is SPI1(Master TxRx), Another Board are SPI1(Slave TxRx) Poll test]\n");
printf("Slave is ready? Then press any key, Start\n");
getchar();
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="[B2B] Test Spi1 Master Tx/Rx BUF Poll Mode !@#$%^&*()_+|<>?";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
printf("spi1RxStr:%p\n",spi1RxStr); // for debug
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
dummy_read = RdSPRDAT1();
dummy_read = RdSPRDAT1();
// SPI_Baud_Rate_Set(25000000);
SPI_Baud_Rate_Set(1000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x6)|(0<<5)|(1<<4)|(1<<3)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
// rSPPIN1 &= ~(1<<0);//Feedback Clock Disable, Master Out Release
SPI1_Master_nSS_Con(0);
while(endSpi1Tx==0)
{
if(REDY1==1) //Check Tx ready state
{
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
endSpi1Tx=1;
WrSPTDAT1(*spi1TxStr++);
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1();
}
}
SPI1_Master_nSS_Con(1);
*spi1RxStr++=RdSPRDAT1(); // read last data(NULL)
rxStr++; // remove first dummy
printf("MASTER Tx Strings:%s\n",txStr);
printf("MASTER Rx Strings:%s\n",rxStr);
SPI_Port_Recovery();
}
void Test_Spi1_S_Buf_Poll(void)
{
char *txStr,*rxStr;
char dummy_read;
printf("[This Board is SPI1(Slave TxRx), Another Board are SPI1(Master TxRx) Poll test]\n");
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="[B2B] Test Spi1 Savle Tx/Rx BUF Poll Mode ABCDEFGHIJKLMNOP";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
printf("spi1RxStr:%p\n",spi1RxStr); // for debug
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
dummy_read = RdSPRDAT1();
dummy_read = RdSPRDAT1();
// SPI_Baud_Rate_Set(25000000);
SPI_Baud_Rate_Set(1000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x7)|(0<<5)|(0<<4)|(0<<3)|(0<<0);//Polling,en-SCK,master
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
while(endSpi1Tx==0)
{
if(REDY1==1) //Check Tx ready state
{
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
endSpi1Tx=1;
WrSPTDAT1(*spi1TxStr++);
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1();
}
}
while(!(REDY1_org)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1(); // read last data(NULL)
rxStr++; // remove first dummy
printf("SLAVE Tx Strings:%s\n",txStr);
printf("SLAVE Rx Strings:%s\n",rxStr);
SPI_Port_Recovery();
}
void Test_Spi1_M_Buf_Int(void)
{
char *txStr,*rxStr;
char dummy_read;
printf("[This Board is SPI1(Master TxRx), Another Board are SPI1(Slave TxRx) Int test]\n");
printf("Slave is ready? Then press any key, Start\n");
getchar();
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="[B2B] Test Spi1 Master Tx/Rx BUF Int. Mode ?><|+_)(*&^%$#@!";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
printf("spi1RxStr:%p\n",spi1RxStr); // for debug
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
dummy_read = RdSPRDAT1();
dummy_read = RdSPRDAT1();
// SPI_Baud_Rate_Set(25000000);
SPI_Baud_Rate_Set(1000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x6)|(1<<5)|(1<<4)|(1<<3)|(0<<0);//Interrupt,en-SCK,master,normal
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
// rSPPIN1 &= ~(1<<0);//Feedback Clock Disable, Master Out Release
SPI1_Master_nSS_Con(0);
pISR_SPI1=(unsigned)Spi1_M_Buf_Int;
rINTMSK&=~(BIT_SPI1);
while(endSpi1Tx==0);
SPI1_Master_nSS_Con(1);
*spi1RxStr++=RdSPRDAT1(); // read last data(NULL)
rxStr++; // remove first dummy
printf("MASTER Tx Strings:%s\n",txStr);
printf("MASTER Rx Strings:%s\n",rxStr);
SPI_Port_Recovery();
}
void __irq Spi1_M_Buf_Int(void)
{
ClearPending(BIT_SPI1);
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
WrSPTDAT1(*spi1TxStr++);
endSpi1Tx=1;
rINTMSK|=(BIT_SPI1);
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1(); //First Rx data is garbage data
}
void Test_Spi1_S_Buf_Int(void)
{
char *txStr,*rxStr;
char dummy_read;
printf("[This Board is SPI1(Slave TxRx), Another Board are SPI1(Master TxRx) Poll test]\n");
SPI_Port_Init();
endSpi1Tx=0;
spi1TxStr="[B2B] Test Spi1 Savle Tx/Rx BUF Int. Mode abcdefghijklmnop";
spi1RxStr=(char *) SPI_BUFFER1; // Rx Buffer to receive
printf("spi1RxStr:%p\n",spi1RxStr); // for debug
txStr=(char *)spi1TxStr;
rxStr=(char *)spi1RxStr;
dummy_read = RdSPRDAT1();
dummy_read = RdSPRDAT1();
// SPI_Baud_Rate_Set(25000000);
SPI_Baud_Rate_Set(1000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x7)|(1<<5)|(0<<4)|(0<<3)|(0<<0);//Polling,en-SCK,master
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
pISR_SPI1=(unsigned)Spi1_S_Buf_Int;
rINTMSK&=~(BIT_SPI1);
while(endSpi1Tx==0);
while(!(REDY1_org)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1(); // read last data(NULL)
rxStr++; // remove first dummy
printf("SLAVE Tx Strings:%s\n",txStr);
printf("SLAVE Rx Strings:%s\n",rxStr);
SPI_Port_Recovery();
}
void __irq Spi1_S_Buf_Int(void)
{
ClearPending(BIT_SPI1);
if(*spi1TxStr!='\0')
WrSPTDAT1(*spi1TxStr++);
else {
WrSPTDAT1(*spi1TxStr++);
endSpi1Tx=1;
rINTMSK|=(BIT_SPI1);
}
while(!(REDY1)); //Check Rx ready state
*spi1RxStr++=RdSPRDAT1(); //First Rx data is garbage data
}
void Test_Spi1_M_Tx_Buf_DMA(void)
{
int i;
printf("[This Board is SPI1(Master Tx), Another Board are SPI1(Slave Rx) DMA test]\n");
printf("Slave is ready? Then press any key, Start\n");
getchar();
SPI_Port_Init();
SPI_Baud_Rate_Set(1000000);
SPI_Transfer_Format();
rSPCON1 = (rSPCON1&0x7)|(2<<5)|(1<<4)|(1<<3)|(0<<0);//DMA,en-SCK,master
rSPPIN1 |= (1<<0);//Feedback Clock Disable, Master Out Keep
SPI1_Master_nSS_Con(0);
Set_Spi1_Tx_DMA_Set(0); // Spi1 Master DMA channel 1 Set
while(tx_dmaDone) {
if(Uart_GetKey())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -