Knowledge Base Nr: 00011 Dio_ISA_PCI.cpp - http://www.swe-kaiser.de
Downloads:
portierung p16r16 digital-io relais karte von isa nach pci
//(es gibt keine 8bit zugriffe mehr - nur noch 16bit)
//die DIO_OutputByte und DIO_InputByte funktionen werden emuliert
//indem die 'anderen' 8 bit in einem memory mapped file gemerkt und
//vor dem schreiben wieder gelesen werden.
########################################################
################## h file ##############################
#include <windows.h>
#define NoError 0
#define DriverOpenError 1
#define DriverNoOpen 2
#define GetDriverVersionError 3
#define InstallIrqError 4
#define ClearIntCountError 5
#define GetIntCountError 6
#define ResetError 7
#define DIO48_TIMER0 12
#define DIO48_TIMER1 13
#define DIO48_TIMER2 14
#define DIO48_TIMER_MODE0 15
#define DIO64_TIMER0 4
#define DIO64_TIMER1 5
#define DIO64_TIMER2 6
#define DIO64_TIMER_MODE0 7
#define DIO64_TIMER3 8
#define DIO64_TIMER4 9
#define DIO64_TIMER5 10
#define DIO64_TIMER_MODE1 11
// The DIO functions
void DIO_OutputByte(WORD wPortAddr, UCHAR bOutputValue);
WORD DIO_InputByte(WORD wPortAddr);
WORD DIO_InputWord(WORD wPortAddr);
// The Driver functions
WORD DIO_DriverInit(void);
########################################################
############### cpp file ###############################
#include <afx.h>
#include "dio.h"
#include "P16r16.h"
WORD g_wAddrKarte1 = 0;
WORD g_wAddrKarte2 = 0;
typedef struct //dieses struct representiert alle öfen
{
WORD wKarte1Read, wKarte1Write;
WORD wKarte2Read, wKarte2Write;
} MMFPARAM, *LPMMFPARAM;
int InitMMFData(); //initialisieren des memory mapped files (bei programmstart)
int CleanupMMFData(); //freigeben des memory mapped files (bei programmende)
int ReadWriteMMFData(LPMMFPARAM lpMMFPARAM, bool bWrite); //(zugriff auf den struct)
//diese funktionen sind auf den struct zugeschnitten!
WORD ReadDIOValue(WORD wAddr);
WORD WriteDIOValue(WORD wAddr, WORD nValue);
/////////////////////////////////////
HANDLE g_hFileMap = NULL;
int InitMMFData()
{
if (g_hFileMap == NULL) //noch nicht offen
{
g_hFileMap = CreateFileMapping((HANDLE)0xffffffff,
NULL,
PAGE_READWRITE,
0,
sizeof(MMFPARAM),
"DIOMemoryMappedFile");
if (g_hFileMap == NULL)
return ::GetLastError();
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
//file existiert bereits -> es kann z.b. gelesen werden
}
return 0;
}
int CleanupMMFData()
{
if (g_hFileMap != NULL) //nur wenn offen
{
BOOL bSucc = ::CloseHandle(g_hFileMap);
if (!bSucc)
return ::GetLastError();
}
return 0;
}
int ReadWriteMMFData(LPMMFPARAM lpMMFPARAM, bool bWrite)
{
InitMMFData(); //wenn schon initialisiert kehrt die funktion sofort zurück
if (g_hFileMap == NULL)
return -4711;
LPVOID lpView = MapViewOfFile(g_hFileMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0);
if (lpView == NULL)
{
CleanupMMFData();
return ::GetLastError();
}
LPMMFPARAM lpShared = (LPMMFPARAM) lpView;
if (bWrite) //schreiben
memcpy(lpShared, lpMMFPARAM, sizeof(MMFPARAM));
else //lesen
memcpy(lpMMFPARAM, lpShared, sizeof(MMFPARAM));
BOOL bSucc = UnmapViewOfFile(lpView);
if (!bSucc)
{
CleanupMMFData();
return ::GetLastError();
}
return 0;
}
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
// The DIO functions
void DIO_OutputByte(WORD wPortAddr, UCHAR bOutputValue)
{
MMFPARAM sMMFPARAM;
//lesen...
int nRes = ReadWriteMMFData(&sMMFPARAM, false);
//...verarbeiten...
switch (wPortAddr)
{
case 0x300:
sMMFPARAM.wKarte1Write = MAKEWORD(bOutputValue, HIBYTE(sMMFPARAM.wKarte1Write));
P16R16_DO(g_wAddrKarte1, sMMFPARAM.wKarte1Write);
break;
case 0x301:
sMMFPARAM.wKarte1Write = MAKEWORD(LOBYTE(sMMFPARAM.wKarte1Write), bOutputValue);
P16R16_DO(g_wAddrKarte1, sMMFPARAM.wKarte1Write);
break;
case 0x308:
sMMFPARAM.wKarte2Write = MAKEWORD(bOutputValue, HIBYTE(sMMFPARAM.wKarte2Write));
P16R16_DO(g_wAddrKarte2, sMMFPARAM.wKarte2Write);
break;
case 0x309:
sMMFPARAM.wKarte2Write = MAKEWORD(LOBYTE(sMMFPARAM.wKarte2Write), bOutputValue);
P16R16_DO(g_wAddrKarte2, sMMFPARAM.wKarte2Write);
break;
default:
::MessageBox(NULL, "illegale Addresse DIO_OutputByte!", "ERROR", MB_OK);
return;
}
//...und zurückschreiben
nRes = ReadWriteMMFData(&sMMFPARAM, true);
}
WORD DIO_InputByte(WORD wPortAddr)
{
BYTE b = 0;
WORD w = DIO_InputWord(wPortAddr&0xFFFE);
switch (wPortAddr)
{
case 0x300:
case 0x302:
case 0x308:
case 0x30a:
b = LOBYTE(w);
break;
case 0x301:
case 0x303:
case 0x309:
case 0x30b:
b = HIBYTE(w);
break;
default:
::MessageBox(NULL, "illegale Addresse DIO_InputByte!", "ERROR", MB_OK);
return -1;
}
return b;
}
WORD DIO_InputWord(WORD wPortAddr)
{
MMFPARAM sMMFPARAM;
//lesen...
int nRes = ReadWriteMMFData(&sMMFPARAM, false);
//...verarbeiten...
WORD w = 0;
switch (wPortAddr)
{
case 0x300:
w = sMMFPARAM.wKarte1Write;
break;
case 0x302:
sMMFPARAM.wKarte1Read = P16R16_DI(g_wAddrKarte1);
w = sMMFPARAM.wKarte1Read;
break;
case 0x308:
w = sMMFPARAM.wKarte2Write;
break;
case 0x30a:
sMMFPARAM.wKarte2Read = P16R16_DI(g_wAddrKarte2);
w = sMMFPARAM.wKarte2Read;
break;
default:
::MessageBox(NULL, "illegale Addresse DIO_InputWord!", "ERROR", MB_OK);
return -1;
}
return w;
}
// The Driver functions
WORD DIO_DriverInit(void)
{
InitMMFData(); //memory mapped file als shared memory
MMFPARAM sMMFPARAM;
memset(&sMMFPARAM, 0, sizeof(sMMFPARAM));
int nRes = ReadWriteMMFData(&sMMFPARAM, true);
//pci karte initialisieren
WORD wRes, wTotalBoards;
wRes = PCI_DriverInit(&wTotalBoards);
if ((wTotalBoards != 2) || (wRes != 0))
{
::MessageBox(NULL, "PCI_DriverInit() keine 2 boards!", "ERROR", MB_OK);
return -1;
}
WORD TypeID, wAddr0, wAddr1, wAddr2, wAddr3, wAddr4, wAddr5;
wRes = PCI_GetConfigAddressSpace(0, &TypeID, &wAddr0, &wAddr1, &wAddr2, &wAddr3, &wAddr4, &wAddr5);
if (wRes != 0)
{
::MessageBox(NULL, "PCI_GetConfigAddressSpace() karte 1 fehler!", "ERROR", MB_OK);
return -1;
}
g_wAddrKarte1 = wAddr2;
wRes = PCI_GetConfigAddressSpace(1, &TypeID, &wAddr0, &wAddr1, &wAddr2, &wAddr3, &wAddr4, &wAddr5);
if (wRes != 0)
{
::MessageBox(NULL, "PCI_GetConfigAddressSpace() karte 2 fehler!", "ERROR", MB_OK);
return -1;
}
g_wAddrKarte2 = wAddr2;
return 0;
}