// Firmware und Seriennummer brennen
#define WIN32_LEAN_AND_MEAN
#define STRICT
//#define WINVER 0x0500
#include <windows.h>
#include <winioctl.h>
#include <shlwapi.h>
#include "C:/Programme/cypress/usb/Drivers/ezusbdrv/ezusbsys.h"
#define elemof(x) (sizeof(x)/sizeof(*(x)))
#define T(x) TEXT(x)
#define nobreak
typedef enum {false,true} bool;
typedef const TCHAR *PCTSTR,FAR*LPCTSTR,NEAR*NPCTSTR;
HANDLE hStdIn, hStdOut, hStdErr;
HANDLE hAccess;
DWORD DownloadIoctl; // je nach Treiber (EZUSB.SYS oder USB2LPT.SYS)
void _cdecl printf(const char*t,...){
TCHAR buf[1024];
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;
}
// etwa wie Speichereinblendung der IIC-Datei hier:
#define IICLEN 0x2000
BYTE IicData[IICLEN];
DWORD IicLen;
BYTE DataStart; // FX2: 8, AN2131: 7, wird von LoadIic festgelegt
WORD ResetAddr; // FX2: E600, AN2131: 7F92, wird von LoadIic festgelegt
//IIC-Datei einlesen
bool LoadIic(PCTSTR IicName) {
HANDLE f;
bool ret=false;
f=CreateFile(IicName,GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,0,0);
if (f==INVALID_HANDLE_VALUE) {
printf("Konnte IIC-Datei nicht öffnen!\n");
}else{
if (!ReadFile(f,IicData,IICLEN,&IicLen,NULL)) {
printf("Konnte IIC-Datei nicht lesen!\n");
}else switch (IicData[0]) {
case 0xB2: { //AN2131
DataStart=7;
ResetAddr=0x7F92;
ret=true;
}break;
case 0xC2: { //FX2
DataStart=8;
ResetAddr=0xE600;
ret=true;
}break;
default: printf("Datei ist keine gültige IIC-Datei!\n");
}
}
CloseHandle(f);
return ret;
}
// Daten ins 8051-XRAM laden, via ezusb.sys oder usb2lpt.sys
bool WriteRam(WORD adr, BYTE*data, DWORD len) {
if (!DeviceIoControl(hAccess,
DownloadIoctl,&adr,sizeof(adr),data,len,&len,NULL)) return false;
return true;
}
// IIC-Daten in RAM laden
bool LoadRam(void) {
bool ret=false;
BYTE Reset8051=1;
BYTE*p=IicData+DataStart;
if (!WriteRam(ResetAddr,&Reset8051,1)) goto ende;
for (;;) {
WORD len=MAKEWORD(p[1],p[0]);
WORD adr=MAKEWORD(p[3],p[2]);
if (adr==ResetAddr) break;
p+=4;
if (!WriteRam(adr,p,len)) goto ende;
p+=len;
}
Reset8051=0;
if (!WriteRam(ResetAddr,&Reset8051,1)) goto ende;
ret=true;
ende:
if (!ret) printf("Fehler beim RAM-Schreiben!\n");
return ret;
}
// Seriennummer von Konsole eingeben und dann brennen
bool NeueSeriennummer(void) {
static DWORD auto_sn;
DWORD sn,len;
WORD adr=0xFFFC;
TCHAR Number[12];
if (auto_sn) printf(T("(%u) "),auto_sn);
ReadConsole(hStdIn,Number,elemof(Number)-1,&len,NULL);
Number[len]=0;
if (!StrToIntEx(Number,STIF_SUPPORT_HEX,&sn) || !sn) sn=auto_sn;
if (!sn) return false;
if (!DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A2,METHOD_IN_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
&sn,sizeof(sn),&len,NULL)) return false;
// if (len!=sizeof(sn)) return false;
printf("Seriennummer %u gebrannt.\n",sn);
auto_sn=sn+1;
return true;
}
void TryOpen(LPTSTR TemplateName) {
int i;
for (i=9; i>=0; i--){
TCHAR DevName[12];
wsprintf(DevName,TemplateName,i);
hAccess=CreateFile(DevName,
GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
if (hAccess!=INVALID_HANDLE_VALUE) break;
}
}
bool ReadSerialNumber(DWORD *psn) {
DWORD sn,br;
struct {
WORD adr;
BYTE i2ca; // 0xA2 für 8-K-EEPROM
BYTE i2cs; // 0x02 für 8-K-EEPROM
}adr={0xFFFC,0xA2,0x02};
if (!DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A2,METHOD_OUT_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
&sn,sizeof(sn),&br,NULL)) return false;
if (~sn && !(~sn&0xFFFFFF)) sn>>=24; // Seriennummer im MSB (altes Format)
if (psn) *psn=sn;
return true;
}
void _cdecl mainCRTStartup(){
int j;
DWORD sn,br;
LPTSTR IicName;
hStdIn =GetStdHandle(STD_INPUT_HANDLE);
hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
hStdErr=GetStdHandle(STD_ERROR_HANDLE);
IicName=PathGetArgs(GetCommandLine());
if (!IicName || !*IicName) {
printf("Die zu brennende .iic-Datei muss angegeben werden!\n");
ExitProcess(1);
}
printf("Lese IIC-Datei...\n");
if (!LoadIic(IicName)) ExitProcess(2);
do{
DownloadIoctl=IOCTL_EZUSB_ANCHOR_DOWNLOAD; // via ezusb.sys
printf("Verbinde zu <ezusb.sys>...\n");
// Suche von hinten, um eventuelle Treiberleichen auszulassen
TryOpen("\\\\.\\EZUSB-%d");
if (hAccess==INVALID_HANDLE_VALUE) {
printf("Kein EZUSB-Gerät gefunden.\n");
// Alternativ ein USB2LPT mit Firmware suchen...
TryOpen("\\\\.\\LPT%d");
if (hAccess==INVALID_HANDLE_VALUE) goto ende;
if (!ReadSerialNumber(&sn)) goto ende;
printf("Stattdessen ein (programmiertes) USB2LPT-Gerät gefunden, Firmware-Update?");
if (JaNein()!=IDYES) goto ende;
DownloadIoctl=CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A0,METHOD_IN_DIRECT,FILE_ANY_ACCESS); // via usb2lpt.sys
}
printf("Lade IIC-Daten in RAM und starte neu...\n");
if (!LoadRam()) goto ende;
if (DownloadIoctl==IOCTL_EZUSB_ANCHOR_DOWNLOAD) {
CloseHandle(hAccess);
printf("Warte Renumeration ab, verbinde zu <usb2lpt.sys>...\n");
for (j=12; j; j--){
Sleep(500); // 6 Sekunden warten (nicht suchen; Absturz W2K!!)
printf("."); // Programm arbeitet noch:-)
}
printf("\n");
// usb2lpt.sys erzeugt LPTx-Geräte, die hinter den "normalen" LPT-Nummern
// liegen. Deshalb von hinten her suchen, um möglichst kein "normales"
// LPT (oder Treiberleichen) zu erwischen.
TryOpen("\\\\.\\LPT%d");
if (hAccess==INVALID_HANDLE_VALUE) {
printf("Kein (USB2)LPT-Gerät gefunden.\n");
goto ende;
}
// Höchstmögliches LPTx geöffnet, ist es auch ein USB2LPT?
// Dazu Seriennummer lesen. Wenn's nicht klappt, weiter abwarten.
if (!ReadSerialNumber(&sn)) {
printf("Problem: Kein USB2LPT gefunden!\n");
goto ende;
}
}
if (sn==(DWORD)-1) {
printf("Keine Seriennummer im EEPROM, neu eingeben: ");
if (!NeueSeriennummer()) goto ende;
}else{
printf("Seriennummer: %lu, neu eingeben?",sn);
if (JaNein()==IDYES && !NeueSeriennummer()) goto ende;
}
printf("Brenne Firmware...\n");
{
struct {
WORD adr; // Position (allein genügt sie nur, wenn EEPROM beim Start vorhanden war)
BYTE i2ca; // 0xA2 für 8-K-EEPROM
BYTE i2cs; // 0x02 für 8-K-EEPROM
}adr={0x0000,0xA2,0x02};
if (!DeviceIoControl(hAccess,
CTL_CODE(FILE_DEVICE_UNKNOWN,0x08A2,METHOD_IN_DIRECT,FILE_ANY_ACCESS),
&adr,sizeof(adr),
IicData,IicLen,&br,NULL)) {
printf("Fehler!\n");
goto ende;
}
}
printf("Fertig.\n");
ende:
if (hAccess!=INVALID_HANDLE_VALUE) CloseHandle(hAccess);
printf("\nBeliebige Taste zum Programmende drücken (J für Wiederholung)...");
}while (JaNein()==IDYES);
ExitProcess(0);
}
Detected encoding: UTF-8 | 0
|