#include <windows.h>
#include <winioctl.h>
HANDLE hStdIn, hStdOut, hStdErr;
HANDLE hAccess;
BYTE gError;
#define DDR_OUT 0xFF // Firmware ab 28.1.2007
void outb(BYTE a, BYTE b) {
BYTE IoData[2];
DWORD BytesRet;
IoData[0]=a;
IoData[1]=b;
DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x804,METHOD_BUFFERED,FILE_ANY_ACCESS),
IoData,sizeof(IoData),NULL,0,&BytesRet,NULL);
}
BYTE inb(BYTE a) {
BYTE IoData[1];
DWORD BytesRet;
IoData[0]=a|0x10; // Lese-Bit
DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x804,METHOD_BUFFERED,FILE_ANY_ACCESS),
IoData,sizeof(IoData),IoData,sizeof(IoData),&BytesRet,NULL);
return IoData[0];
}
void _cdecl printf(const char*t,...){
TCHAR buf[256];
DWORD len;
len=wvsprintf(buf,t,(va_list)(&t+1));
CharToOemBuff(buf,buf,len);
WriteConsole(hStdOut,buf,len,&len,NULL);
}
int JaNein(void){
char c;
DWORD len,OldMode;
GetConsoleMode(hStdIn,&OldMode);
SetConsoleMode(hStdIn,0);
ReadConsole(hStdIn,&c,1,&len,NULL);
printf("%c\n",c);
SetConsoleMode(hStdIn,OldMode);
switch (c){
case 'J':
case 'j':
case 'Y':
case 'y': return IDYES;
case 'N':
case 'n': return IDNO;
}
return 0;
}
void Check(BYTE bData, BYTE bStatus, BYTE bControl, BYTE bDoOut){
if (bDoOut){
if ((inb(0x0D)^DDR_OUT)&0xC0) bStatus|=0xC0; // kann nicht ausgeben!
outb(0,bData);
outb(1,(bStatus^0x80)|0x07);
outb(2,(bControl^0x0B)&0x0F);
}
bData^=inb(0);
bStatus^=inb(1)^0x80; bStatus&=0xF8;
bControl^=inb(2)^0x0B; bControl&=0x0F;
if (bData) printf("Datenfehler: %02X\n",bData);
if (bStatus) printf("Statusfehler: %02X\n",bStatus);
if (bControl) printf("Steuerfehler: %02X\n",bControl);
gError|=bData|bStatus|bControl;
}
int _cdecl mainCRTStartup(){
BYTE b,MerkFeature;
WORD adr,date;
DWORD sn,br;
hStdIn =GetStdHandle(STD_INPUT_HANDLE);
hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
hStdErr=GetStdHandle(STD_ERROR_HANDLE);
rept:
for (sn=8;sn;sn--){ // von hinten probieren
TCHAR DevName[12];
wsprintf(DevName,"\\\\.\\LPT%u",sn);
hAccess=CreateFile(DevName,
GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
if (hAccess!=INVALID_HANDLE_VALUE) break;
}
if (hAccess==INVALID_HANDLE_VALUE){
printf("USB2LPT stick on, must be LPTx!\n");
goto ende;
}
MerkFeature=inb(0x0F);
outb(0x0F,0x00); // Normalbetrieb ohne Features
outb(0x0A,0x00); // SPP-Modus
outb(0x0D,DDR_OUT); // Statusleitungen Ausgänge
if ((inb(0x0D)^DDR_OUT)&0x38){
printf("This test requires firmware 060629 or greater!\n");
goto ende;
}
#if 0 // C2-Byte delete (bridge does not function!)
adr=0;
sn=(DWORD)-1;
DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A2,METHOD_IN_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
&sn,sizeof(sn),&br,NULL);
#endif
adr=0xFFFC; // Seriennummer-Position
DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A2,METHOD_OUT_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
&sn,sizeof(sn),&br,NULL);
if (!(~sn&0xFFFFFF)) sn>>=24; // Seriennummer im MSB (altes Format)
printf("Serial number: %u\n",sn);
adr=0x0006; // Datums-Position
DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A3,METHOD_OUT_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
&date,sizeof(date),&br,NULL);
printf("Firmware date of preparation: %u-%02u-%02u\n",
(date>>9)+1980,(date>>5)&0x0F,date&0x1F);
gError=FALSE;
// Prüfen auf Kurz- und Masseschlüsse
printf("Automatic short-circuit and earthing examination...\n");
for(b=1;b;b<<=1) { // Daten testen
Check(b,0,0,TRUE);
Check(~b,0xFF,0xFF,TRUE);
}
for(b=8;b;b<<=1) { // Statusleitungen
Check(0,b,0,TRUE);
Check(0xFF,~b,0xFF,TRUE);
}
for(b=1;b<0x10;b<<=1) {// Steuerleitungen
Check(0,0,b,TRUE);
Check(0xFF,0xFF,~b,TRUE);
}
outb(2,0xFF^0x0B);
// Prüfen auf Vorhandensein der Pullups
outb(0x0C,(BYTE)~DDR_OUT); // Alles Eingänge
outb(0x0D,(BYTE)~DDR_OUT);
if (!(inb(0x0F)&0x02)) outb(0x0E,(BYTE)~DDR_OUT); // Steuerport nur, wenn Pull-Up vorhanden
Check(0xFF,0xFF,0xFF,FALSE); // muss alles High sein
// Gegenprobe funktioniert nur mit Rev.3
// Irgendwo Fehler!!! Firmware? Logik?
printf("Control port BEFORE pullup switching off: %02X %02X\n",inb(2),inb(0x0E));
outb(0x0F,0x80); // Pullups AUS (Feature)
printf("Control port AFTER Pullup switching off: %02X %02X\n",inb(2),inb(0x0E));
if (inb(0x0F)&0x80){ // falls Pullups ausgeschaltet werden konnten
printf("Rev.3: The LEDs (of the LptChk) are now very dark? ");
if (JaNein()==IDNO) gError|=1;
outb(0x0F,0x00); // Pullups EIN
}
outb(0x0C,DDR_OUT);
outb(0x0D,DDR_OUT);
outb(0x0E,DDR_OUT);
printf("Lights all LEDs brightly? ");
if (JaNein()==IDNO) gError|=1;
// Prüfung, ob die Pins angelötet(!) sind
Check(0x00,0x00,0x00,TRUE);
printf("Are all LEDs out? ");
if (JaNein()==IDNO) gError|=1;
if (gError){
SetConsoleTextAttribute(hStdOut,FOREGROUND_RED|FOREGROUND_INTENSITY);
printf("!!! ERROR!!! Soldering work!\n");
SetConsoleTextAttribute(hStdOut,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}else{
SetConsoleTextAttribute(hStdOut,FOREGROUND_GREEN|FOREGROUND_INTENSITY);
printf("Keine Kurz- und Masseschlüsse. Alles OK.\n");
SetConsoleTextAttribute(hStdOut,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}
outb(0x0D,(BYTE)~DDR_OUT); // Eingänge
Check(0xFF,0xFF,0x07,TRUE); // etwaiger Ausgangszustand
Check(0x00,0xFF,0x07,TRUE);
//eigentlich nur bei Firmware ab 9.2.2007
printf("Brightness the blue LED switch?");
if (JaNein()==IDYES) MerkFeature^=0x20;
ende:
outb(0x0F,MerkFeature);
CloseHandle(hAccess);
printf("\nPress arbitrary key to end program (Y for repetition)...");
if (JaNein()==IDYES) goto rept;
return 0;
}
Detected encoding: ANSI (CP1252) | 4
|
|