📄 pspan_diag.c
字号:
//////////////////////////////////////////////////////////////////////////////
// File - PSPAN_DIAG.C
//
// o A simple diagnostics program that lets you access the
// PSPAN registers and local memory.
// o This program is meant to be used as an example for using the PSPAN_LIB.H API,
// you may use it as a skeleton for your driver, or 'cut & paste' parts
// of it into your device driver code.
// o For a more advanced monitor program, use the standard PLXMON.EXE
// from PLX.
//
/////////////////////////////////////////////////////////////////////////////
#include "../lib/pspan_lib.h"
#include "../../../samples/shared/pci_diag_lib.h"
#include <stdio.h>
// input of command from user
static char line[256];
void PSPAN_EditReg(PSPAN_HANDLE hPlx)
{
struct
{
CHAR *name;
DWORD dwOffset;
DWORD dwVal;
} fields[30];
int cmd;
int i;
int field_count;
i = 0;
fields[i].name = "T_P1_TI0_CTL"; fields[i++].dwOffset = 0x100;
fields[i].name = "T_P1_TI0_ADDR"; fields[i++].dwOffset = 0x104;
fields[i].name = "T_P1_TI1_CTL"; fields[i++].dwOffset = 0x110;
fields[i].name = "T_P1_TI1_ADDR"; fields[i++].dwOffset = 0x114;
fields[i].name = "T_P1_TI2_CTL"; fields[i++].dwOffset = 0x120;
fields[i].name = "T_P1_TI2_ADDR"; fields[i++].dwOffset = 0x124;
fields[i].name = "T_P1_TI3_CTL"; fields[i++].dwOffset = 0x130;
fields[i].name = "T_P1_TI3_ADDR"; fields[i++].dwOffset = 0x134;
fields[i].name = "T_P1_CONF_INFO"; fields[i++].dwOffset = 0x144;
fields[i].name = "T_P1_CONF_DATA"; fields[i++].dwOffset = 0x148;
fields[i].name = "T_P1_IACK"; fields[i++].dwOffset = 0x14C;
fields[i].name = "T_P1_ERRCS"; fields[i++].dwOffset = 0x150;
fields[i].name = "T_P1_AERR"; fields[i++].dwOffset = 0x154;
fields[i].name = "T_P1_MISC_CSR"; fields[i++].dwOffset = 0x160;
fields[i].name = "T_P1_ARB_CTRL"; fields[i++].dwOffset = 0x164;
fields[i].name = "T_PB_SI0_CTL"; fields[i++].dwOffset = 0x200;
fields[i].name = "T_PB_SI0_TADDR"; fields[i++].dwOffset = 0x204;
fields[i].name = "T_PB_SI0_BADDR"; fields[i++].dwOffset = 0x208;
fields[i].name = "T_PB_SI1_CTL"; fields[i++].dwOffset = 0x210;
fields[i].name = "T_PB_SI1_TADDR"; fields[i++].dwOffset = 0x214;
fields[i].name = "T_PB_SI1_BADDR"; fields[i++].dwOffset = 0x218;
field_count = i;
do
{
int row;
int col;
int row_count = field_count/2 + field_count%2;
printf ("\n");
printf ("Edit PSPAN registers\n");
printf ("--------------------------------\n");
for (row = 0; row<row_count; row++)
{
for (col = 0; col<=1; col++)
{
if (col==0) i = row;
else i = row + row_count;
if (i<field_count)
{
char buf[10];
fields[i].dwVal = PSPAN_ReadReg(hPlx, fields[i].dwOffset);
sprintf(buf, "%08x",fields[i].dwVal);
printf ("%2d. %7s : %s ",i+1, fields[i].name, buf);
}
if (col==1) printf ("\n");
}
}
printf ("99. Back to main menu\n");
printf ("Choose register to write to, or 99 to exit: ");
cmd = 0;
fgets(line, sizeof(line), stdin);
sscanf (line, "%d",&cmd);
if (cmd>=1 && cmd <=21)
{
i = cmd-1;
printf ("Enter value to write to %s register (or 'X' to cancel): ",fields[i].name);
fgets(line, sizeof(line), stdin);
if (toupper (line[0])!='X')
{
DWORD dwVal;
dwVal = 0;
sscanf (line,"%x",&dwVal);
PSPAN_WriteReg(hPlx, fields[i].dwOffset, dwVal);
}
}
} while (cmd!=99);
}
char *PLX_GetAddrRangeName(PSPAN_ADDR addrSpace)
{
return
addrSpace==PSPAN_ADDR_SPACE0 ? "Addr Space 0 - (BAR2)" :
addrSpace==PSPAN_ADDR_SPACE1 ? "Addr Space 1 - (BAR3)" :
addrSpace==PSPAN_ADDR_SPACE2 ? "Addr Space 2 - (BAR4)" :
addrSpace==PSPAN_ADDR_SPACE3 ? "Addr Space 3 - (BAR5)" :
addrSpace==PSPAN_ADDR_EPROM ? "EEPROM Addr Space" : "Invalid";
}
void PSPAN_BoardAccess(PSPAN_HANDLE hPlx, BOOL fLocalAddr)
{
int cmd, cmd2, i;
DWORD addr, data;
PSPAN_ADDR ad_sp = PSPAN_ADDR_SPACE0;
PSPAN_MODE ad_mode = PSPAN_MODE_DWORD;
char *pcMemoryType = fLocalAddr ? "local address" : "offset";
//pgn ++
char *pBuffer = malloc(200);
//
for (; ad_sp<=PSPAN_ADDR_EPROM && !PSPAN_IsAddrSpaceActive(hPlx, ad_sp); ad_sp++)
if (ad_sp>PSPAN_ADDR_EPROM)
{
printf ("No active memory spaces on board!\n");
return;
}
do
{
printf ("Access the board's %s ranges\n",pcMemoryType);
printf ("-------------------------------------------\n");
printf ("(Access to invalid %s may hang the computer!)\n", pcMemoryType);
printf ("1. Change active memory space: %s\n",PLX_GetAddrRangeName(ad_sp));
printf ("2. Toggle active mode: %s\n",
ad_mode==PSPAN_MODE_BYTE ? "BYTE (8 bit)" :
ad_mode==PSPAN_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)" );
printf ("3. Read from board\n");
printf ("4. Write to board\n");
printf ("99. Back to main menu\n");
printf ("\n");
printf ("Enter option: ");
cmd = 0;
fgets(line, sizeof(line), stdin);
sscanf (line, "%d",&cmd);
switch (cmd)
{
case 1:
printf ("Choose memory space:\n");
printf ("--------------------\n");
for (i=PSPAN_ADDR_SPACE0; i<=PSPAN_ADDR_EPROM; i++)
{
printf ("%d. %s", i, PLX_GetAddrRangeName(i));
if (PSPAN_IsAddrSpaceActive(hPlx, i)) printf ("\n");
else printf (" - space not active\n");
}
printf ("Enter option: ");
cmd2 = 99;
fgets(line, sizeof(line), stdin);
sscanf (line, "%d",&cmd2);
if (cmd2>=PSPAN_ADDR_SPACE0 && cmd2<=PSPAN_ADDR_EPROM)
{
int new_ad_sp = cmd2;
if (PSPAN_IsAddrSpaceActive(hPlx, new_ad_sp)) ad_sp = new_ad_sp;
else printf ("Chosen space not active!\n");
}
break;
case 2:
//ad_mode = (ad_mode + 1) % 3;
//pgn
ad_mode += 1;
if(ad_mode == 4)
ad_mode = 0;
break;
case 3:
printf ("Enter %s to read from: ", pcMemoryType);
fgets(line, sizeof(line), stdin);
sscanf (line, "%x", &addr);
switch (ad_mode)
{
case PSPAN_MODE_BYTE:
if (fLocalAddr) data = PSPAN_ReadByte(hPlx, ad_sp, addr);
else data = PSPAN_ReadSpaceByte(hPlx, ad_sp, addr);
break;
case PSPAN_MODE_WORD:
if (fLocalAddr) data = PSPAN_ReadWord(hPlx, ad_sp, addr);
else data = PSPAN_ReadSpaceWord(hPlx, ad_sp, addr);
break;
case PSPAN_MODE_DWORD:
if (fLocalAddr) data = PSPAN_ReadDWord(hPlx, ad_sp, addr);
else data = PSPAN_ReadSpaceDWord(hPlx, ad_sp, addr);
break;
//pgn
case 3:
memset(pBuffer,0,200);
if(fLocalAddr)
PSPAN_ReadWriteBlock (hPlx, addr, pBuffer, 100, TRUE, ad_sp, RM_SDWORD);
else
PSPAN_ReadWriteSpaceBlock (hPlx, addr, pBuffer, 100, TRUE, ad_sp, RM_SDWORD);
printf ("block read: %s\n", pBuffer);
break;
}
printf ("Value read: %x\n", data);
break;
case 4:
printf ("Enter %s to write to: ", pcMemoryType);
fgets(line, sizeof(line), stdin);
sscanf (line, "%x", &addr);
printf ("Enter data to write %s: ",
ad_mode==PSPAN_MODE_BYTE ? "BYTE (8 bit)" :
ad_mode==PSPAN_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)");
fgets(line, sizeof(line), stdin);
sscanf (line, "%x",&data);
switch (ad_mode)
{
case PSPAN_MODE_BYTE:
if (fLocalAddr) PSPAN_WriteByte(hPlx, ad_sp, addr, (BYTE) data);
else PSPAN_WriteSpaceByte(hPlx, ad_sp, addr, (BYTE) data);
break;
case PSPAN_MODE_WORD:
if (fLocalAddr) PSPAN_WriteWord(hPlx, ad_sp, addr, (WORD) data);
else PSPAN_WriteSpaceWord(hPlx, ad_sp, addr, (WORD) data);
break;
case PSPAN_MODE_DWORD:
if (fLocalAddr) PSPAN_WriteDWord(hPlx, ad_sp, addr, data);
else PSPAN_WriteSpaceDWord(hPlx, ad_sp, addr, data);
break;
//pgn
case 3:
printf("Now write block... \n");
memset(pBuffer,0,200);
sscanf (line, "%s", pBuffer);
if(fLocalAddr)
PSPAN_ReadWriteBlock (hPlx, addr, pBuffer, 100, FALSE, ad_sp, WM_SDWORD);
else
PSPAN_ReadWriteSpaceBlock (hPlx, addr, pBuffer, 100, FALSE, ad_sp, WM_SDWORD);
break;
}
break;
}
} while (cmd!=99);
free(pBuffer);//pgn
}
//void PSPAN_IntHandlerRoutine(PSPAN_HANDLE hPlx/*, PSPAN_INT_RESULT *intResult*/)
void PSPAN_IntHandlerRoutine(PSPAN_HANDLE hPlx)
{
///////////////////////
/////// DMA interrupt isr begin
DWORD ulITType;
unsigned long i, temp, channel=0;
//read the ISR0 register to find out which kind of interrupt it is
ulITType = PSPAN_ReadReg(hPlx, T_ISR0);
// is there a pending DMA interrupt?
if ((ulITType & 0x0F000000) == 0UL)
{
// it is not for us
// logMsg("Spurious interrupt : ISR0 = 0x%08lX\n",ulITType,0,0,0,0,0);
return;
}
// test the source of interrupt
for (channel = 0; channel < 4; channel++)
{
temp = 0;
if (ulITType & (0x01000000 << channel))
{
temp = PSPAN_ReadReg(hPlx, T_DMA0_GCSR + channel*0x30);
temp &= (DMAx_GCR_DACT_MASK | DMAx_GCR_DONE_MASK);
if ( temp == DMAx_GCR_DONE_MASK )
{
logMsg("Now Got interrupt--I am in Pspan II IntHandlerRoutine.\n",0,0,0,0,0,0);
// here add your isr codes
temp = PSPAN_ReadReg(hPlx, T_DMA0_GCSR + channel*0x30);
temp |= DMAx_GCR_DONE_MASK;
PSPAN_WriteReg(hPlx, T_DMA0_GCSR + channel*0x30, temp);
for ( i = 0; i < 100; i++ ); // wait a bit
PSPAN_ReadReg(hPlx, T_DMA0_GCSR + channel*0x30); // read to flush
// clear DMA interrupts bit in ISR0
PSPAN_WriteReg(hPlx, T_ISR0, PSPAN_ReadReg(hPlx, T_ISR0) | (0x01000000 << channel));
for ( i = 0; i < 100; i++ ); // wait a bit
temp = PSPAN_ReadReg(hPlx, T_ISR0); // read to flush
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -