#include "AD9834.h"
#include <shlwapi.h>
#include <setupapi.h>
/****************
* USB-Geraffel *
****************/
static const GUID GUID_DEVINTERFACE_USBPRINT = {
0x28d78fad,0x5a12,0x11D1,0xae,0x5b,0x00,0x00,0xf8,0x03,0xa8,0xc2};
int GetNumUsbPorts(void) {
int i;
SP_DEVICE_INTERFACE_DATA devinterface;
HDEVINFO devs = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBPRINT,0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
if (devs==INVALID_HANDLE_VALUE) return 0;
devinterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (i=0; SetupDiEnumDeviceInterfaces(devs,0,&GUID_DEVINTERFACE_USBPRINT,i,&devinterface); i++);
SetupDiDestroyDeviceInfoList(devs);
return i;
}
static HANDLE OpenUsbPort(int n,DWORD FlagsAndAttributes) {
HANDLE usbHandle=0;
SP_DEVICE_INTERFACE_DATA devinterface;
DWORD size;
PSP_DEVICE_INTERFACE_DETAIL_DATA interface_detail;
HDEVINFO devs = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBPRINT,0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
if (devs!=INVALID_HANDLE_VALUE) {
devinterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiEnumDeviceInterfaces(devs, 0, &GUID_DEVINTERFACE_USBPRINT, n, &devinterface)) {
size = 0;
SetupDiGetDeviceInterfaceDetail(devs, &devinterface, 0, 0, &size, 0);
interface_detail = LocalAlloc(LPTR,size);
if (interface_detail) {
interface_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(devs, &devinterface, interface_detail, size, NULL, NULL)) {
usbHandle = CreateFile(interface_detail->DevicePath,GENERIC_WRITE,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FlagsAndAttributes,NULL);
if (usbHandle == INVALID_HANDLE_VALUE) usbHandle = 0;
}
LocalFree(interface_detail);
}
}
SetupDiDestroyDeviceInfoList(devs);
}
return usbHandle;
}
/***************************
* Eigentliche Ein/Ausgabe *
***************************/
static HANDLE hCom;
static HANDLE hLibInOut;
static BYTE (_stdcall*inportb)(WORD); // 2 Funktionszeiger
static void (_stdcall*outportb)(WORD,BYTE);
static BYTE OutSave[2];
static BYTE DefData; // Sonstige Nicht-SPI-Datenbits (für parallel und USB->Drucker)
static bool ErrorPosted; // Fehlermeldung (bei USB oder seriell) nur 1x posten
static HANDLE hUsb;
static OVERLAPPED ovl;
static BYTE *UsbPrnPtr;
static BYTE UsbPrnBuf[33*7]; // maximal 7 Blöcke zu je 33 Bytes
#define USBROT(x) (BYTE)((x)<<3&0xF8|(x)>>5&7) // Bei USB alle Bits logisch um 3 Bit rotiert
static void PostError(void) {
if (ErrorPosted) return;
Beep(440,100);
if (PostMessage(hMainWnd,WM_IOERROR,0,0)) ErrorPosted=true;
}
static int WriteUsb(const void*p,int len) {
DWORD bw;
if (!WriteFile(hUsb,p,len,&bw,&ovl)) { // in einem Stück rausschießen
if (GetLastError()!=ERROR_IO_PENDING) PostError(); // Handle ungültig
else if (WaitForSingleObject(ovl.hEvent,200)) {
CancelIo(hUsb);
PostError(); // Brücke STB-ACK, BUSY-GND oder ERR-INIT fehlt
}
}
GetOverlappedResult(hUsb,&ovl,&bw,FALSE);
return bw;
}
void SpiSend(WORD w) {
int i=16;
switch (Config.iomode) {
case 1: { // seriell über Adapter
if (!hCom) break;
EscapeCommFunction(hCom,CLRBREAK); // PCK = LOW
do{ // so selten wie möglich EscapeCommFunction() aufrufen!
if (w&0x8000 && !DefData) EscapeCommFunction(hCom,SETRTS), DefData=1; // SDI = Datenbit
else if (!(w&0x8000) && DefData) EscapeCommFunction(hCom,CLRRTS), DefData=0;
EscapeCommFunction(hCom,CLRDTR); // SCK = LOW
EscapeCommFunction(hCom,SETDTR); // SCK = HIGH
w<<=1; // nächstes Bit
}while (--i);
if (!EscapeCommFunction(hCom,SETBREAK))
PostError(); // PCK = HIGH
}break;
case 2: {
if (!hLibInOut) break;
do{
BYTE b=DefData&~6; // Bit 1 (SDI) und 2 (PCK) löschen
if (w&0x8000) b|=2; // Bit 1 (SDI) setzen
outportb(Config.paradr,b); // PCK = LOW, SCK = HIGH, SDI = Datenbit
b&=~1;
outportb(Config.paradr,b); // SCK = LOW
w<<=1;
}while (--i);
outportb(Config.paradr,DefData); // PCK = HIGH
}break;
case 3: {
if (!hUsb) break;
do{
BYTE b=DefData&(BYTE)~USBROT(6); // Bit 4 (SDI) und 5 (PCK) löschen
if (w&0x8000) b|=USBROT(2); // Bit 4 (SDI) setzen
*UsbPrnPtr++=b; // PCK = LOW, SCK = HIGH, SDI = Datenbit
b&=~USBROT(1);
*UsbPrnPtr++=b; // SCK = LOW
w<<=1;
}while (--i);
*UsbPrnPtr++=DefData; // PCK = HIGH
if (UsbPrnPtr-UsbPrnBuf==elemof(UsbPrnBuf)) SpiFlush();
}break;
}
}
void SetResetPin(void) {
switch (Config.iomode) {
case 2: { // parallel
outportb(Config.paradr+2,Config.control&1<<8?0x0C:0x0E);
}break;
case 3: { // USB->Drucker
if (Config.control&1<<8) DefData|=USBROT(8); else DefData&=~USBROT(8); // hier Bit 6
}break;
}
}
void SetTrigger(bool t) {
BYTE m=Config.iomode==3?USBROT(0xF0):0xF0;
if (t) DefData|=m; else DefData&=~m; // in beiden Fällen alle restlichen Bits
}
void SpiFlush(void) {
switch (Config.iomode) {
case 3: {
if (UsbPrnPtr==UsbPrnBuf) break;
WriteUsb(UsbPrnBuf,UsbPrnPtr-UsbPrnBuf); // in einem Stück rausschießen
UsbPrnPtr=UsbPrnBuf;
}break;
}
}
bool SpiOpen(HWND w) {
switch (Config.iomode) {
case 1: { // seriell über Adapter
TCHAR ComName[12];
DCB dcb;
wnsprintf(ComName,elemof(ComName),S[6],Config.comnum+1);
hCom=CreateFile(ComName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
if (hCom==INVALID_HANDLE_VALUE) hCom=0;
if (!hCom) {
MBox(w,42,MB_OK,Config.comnum+1);
return false;
}
GetCommState(hCom,&dcb);
dcb.fDtrControl=DTR_CONTROL_ENABLE; // SCK = HIGH
dcb.fRtsControl=RTS_CONTROL_DISABLE; // SDI = LOW
SetCommState(hCom,&dcb);
DefData=0; // Bit 0 speichert hier SDI = LOW
EscapeCommFunction(hCom,SETBREAK); // PCK = HIGH
}break;
case 2: { // parallel AKA Direktzugriff
DefData=5;
hLibInOut=LoadLibraryA("inpout32.dll");
if (!hLibInOut) {
MBox(w,43,MB_OK);
return false;
}
(FARPROC)inportb=GetProcAddress(hLibInOut,"Inp32");
(FARPROC)outportb=GetProcAddress(hLibInOut,"Out32");
OutSave[0]=inportb(Config.paradr);
OutSave[1]=inportb(Config.paradr+2)&0x1F;
outportb(Config.paradr,DefData);
SetResetPin();
}break;
case 3: {
DefData=USBROT(5);
SetResetPin();
hUsb=OpenUsbPort(Config.u2pnum,FILE_FLAG_OVERLAPPED);
if (!hUsb) {
MBox(w,44,MB_OK,Config.u2pnum);
return false;
}
ovl.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
WriteUsb(&DefData,1);
UsbPrnPtr=UsbPrnBuf; // Füllzeiger auf Anfang setzen
}break;
default: return false;
}
return true;
}
void SpiClose(void) {
if (hCom) { // seriell über Adapter
CloseHandle(hCom);
hCom=0;
}
if (hLibInOut) { // parallel AKA Direktzugriff
outportb(Config.paradr,OutSave[0]);
outportb(Config.paradr+2,OutSave[1]);
FreeLibrary(hLibInOut);
hLibInOut=0;
}
if (hUsb) { // über USB-Drucker-Konverter (Schaltungsänderung)
CloseHandle(hUsb);
hUsb=0;
CloseHandle(ovl.hEvent);
ZeroMemory(&ovl,sizeof(ovl));
}
ErrorPosted=false;
}
Detected encoding: UTF-8 | 0
|