#include <string.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
//#define epp
#define BYTEREV 2 /* Byte-Reversion (Motorola) */
#define BITREV 4 /* Bit-Reversion (krankhaft) */
typedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char UCHAR;
typedef float TREAL;
typedef struct {
int verz[16];
TREAL frequenz; /* in MHz */
UINT CodeWortPos;
UINT CodeWortNeg;
UINT MaskePos;
UINT MaskeNeg;
UINT Pulslen;
ULONG Zykluszeit;
}TConfig,*PConfig;
//################################################################################
//# global values
//################################################################################
UINT LptBase= 0x378;
TREAL fosz=16.0; /*MHz*/
/* Current Config */
ULONG IcdWort;
int IcdWortLen;
TConfig cc={{0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1},0.96,0x1FFF,0x0000,-1,-1,4,100000};
/* Vorberechnete Konfigurationen */
TConfig pc[5]={
{{0,1,2,3,4,4,5,5,5,5,5,4,4,3,2,1}, 1,0x1FFF,0x0000,-1,-1,4,100000},
{{0,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}, 5,0xF00F,0xE0F0,-1,-1,4,100000},
{{0,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}, 10,0x00F0,0x100F,-1,-1,4,100000},
{{8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1}, 33.3333,0x9001,0x0000,0x0F30,0x0F30,4,100000},
{{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, 100,0x1FFF,0x0000,-1,-1,4,100000}};
UCHAR bitrev(UCHAR b) {
/* Bitreversion (Spiegelung) im Byte */
UCHAR c;
int i;
for (c=0,i=8; i--;) {
c<<=1;
if (b&1) c|=1;
b>>=1;
}
return c;
}
int bitcalc(TREAL fdesired) {
TREAL fintern,pq,f,ff; /*in MHz*/
int ip,iq,p,q,m,i;
ULONG bits; /*22 bits*/
UCHAR *bptr;
if (fdesired<(TREAL)50/128) return 0;
if (fdesired>100) return 0;
for (fintern=fdesired, m=0; fintern<50; fintern*=2, m++);
pq=fintern/(fosz*2);
ff=1E30;
for (iq=3; iq<=129; iq++) {
ip=(int)(pq*iq+0.5);
f=fabs((TREAL)ip/iq-pq);
if ((ip>=4) && (ip<=130) && (f<ff)) {
p=ip;
q=iq;
ff=f; /* Minimalen Fehler suchen */
}
}
bits=(p-3); /* Bits zusammensetzen */
bits=bits<<1|1;
bits=bits<<3|m;
bits=bits<<7|(q-2);
bits=bits<<4|(fintern>=80?8:0);
IcdWort=m=0; /* Bits umkehren und "stuffen" */
IcdWortLen=22;
for (i=22; i--; ) {
IcdWort>>=1;
if (bits&1) {
IcdWort|=0x80000000;
if (++m==3) {
IcdWort>>=1; /* Null einschieben */
IcdWortLen++;
m=0;
}
}else{
m=0;
}
bits>>=1;
}
IcdWort>>=(32-IcdWortLen); /* wieder lsb-bündig machen */
return 1;
}
TREAL bitshow(int silent) {
/* reverse Rechnung und Anzeige (zur Kontrolle) */
ULONG bits,iw;
int i,p,q,m,d,iwl;
TREAL f,fi;
char s[32];
UCHAR *bptr; /* Byte-Zeiger */
iw=IcdWort;
bits=m=0;
iwl=IcdWortLen; /* Gesamt-Bitzähler (muß 22 ergeben) */
for (i=IcdWortLen; i--; ) {
bits>>=1;
if (iw&1) {
bits|=0x80000000;
if (++m==3) {
iw>>=1;
if (iw&1 && !silent)
puts("FEHLER: mehr als 3 aufeinanderfolgende 1-Bits!");
iwl--;
i--;
m=0;
}
}else{
m=0;
}
iw>>=1;
}
bits>>=(32-iwl); /* schön rechtsbündig machen */
if (!silent) {
if (iwl!=22) puts("FEHLER: resultierende Bitzahl ungleich 22!");
ultoa(bits,s,2);
printf("Bits \"ohne Füllung\" und umgekehrt: %022s (%06lXh)\n",s,bits);
}
i=bits&0x0F; bits>>=4; /* Bitfelder extrahieren (portabel statt STRUCT) */
q=(bits&0x7F)+2; bits>>=7;
m=bits&0x07; bits>>=3;
d=bits&0x01; bits>>=1;
p=(bits&0x7F)+3;
if (!silent) printf("p=%d, d=%d, m=%d, q=%d, i=%d\n",p,d,m,q,i);
fi=2*fosz*p/q;
m=1<<m;
f=fi/m;
if (!silent) {
printf("f(intern)=%1.6gMHz, f(extern)=[33m%1.6g[0mMHz\n",fi,f);
if ((fi<80)&&(i!=0)||(fi>=80)&&(i!=8)) puts("FEHLER: i ungültig!");
if (fi<50 || fi>100) puts("FEHLER: f(intern) ungültig!");
}
return f;
}
char* code2str(char *sp) {
/* Umwandlung Sendecode in Sendesignalfolge (ASCII-Kunst:-)
* liefert Zeiger auf String-Ende (auf die Null) */
UINT p,n;
p=cc.CodeWortPos&0x1FFF; n=cc.CodeWortNeg&0x1FFF;
while (p || n) {
*sp=' ';
if (p&1) *sp='^';
if (n&1) *sp='v';
if (n&p&1) *sp='#';
sp++;
p>>=1;
n>>=1;
}
*sp='\0';
return sp;
}
int str2code(char *s) {
/* benutzerfreundlichere ternäre Sendesignalfolgen-Eingabe ("Code") */
UINT p,n;
int i;
p=n=0;
i=13;
for ( ;*s && i ;s++) {
switch (tolower(*s)) {
case '#': p>>=1; n>>=1; p|=0x1000; n|=0x1000; i--; break;
/* Eingabe der eigentlich verbotenen Kombination ermöglichen */
case 'p':
case '^':
case '+':
case 'h':
case '1': p>>=1; n>>=1; p|=0x1000; i--; break;
case 'n':
case 'v':
case 'L':
case '-': p>>=1; n>>=1; n|=0x1000; i--; break;
case '0':
case '.':
case ' ': p>>=1; n>>=1; i--; break;
default: puts("Falsche Eingabe!"); return 0;
}/*switch*/
}/*for*/
p>>=i; n>>=i; /* rechtsbündig machen */
if (~p&~n&1) {
puts("Ungültige Eingabe (Startbit [LSB] muß <>0 sein)");
return 0;
}
cc.CodeWortPos=p;
cc.CodeWortNeg=n;
return 1;
}
void KanalInfo(void){
int i;
char s[64], *sp;
puts(" (^=pos, v=neg)\n");
for (i=0; i<16; i++) {
printf(" Kanal %2d : %-3d ",i,cc.verz[i]);
if (cc.verz[i]<40) {
memset(s,'·',sizeof(s));
sp=s+cc.verz[i];
}else{
strcpy(s,"--> ");
sp=s+5;
}
code2str(sp);
puts(s);
}
}
int input(const char *prompt,char *data, int datalen) {
/* Eingabefunktion, liefert Anzahl eingegebener Zeichen und
* nullterminierten String nach data */
int i;
printf("%s: ",prompt);
fflush(stdout);
fgets(data,datalen,stdin);
i=strlen(data);
if (i && data[i-1]=='\n') {
data[--i]='\0'; /* ENTER abhacken */
}
return i;
}
void more(const char *msg) {
/* ein Prompt vor dem Bildschirmlöschen */
char s[16];
printf("%s",msg?msg:" ENTER ");
fflush(stdout);
fgets(s,sizeof(s),stdin);
}
void main_menu(void) {
char s[16];
puts("[2J[32m");
puts("\t########################################################");
puts("\t# [1mTU Chemnitz, Professur Schaltungs- und Systementwurf[0;32m #");
puts("\t########################################################");
puts("[0m");
printf(" Momentane Konfiguration: "
"Frequenz = [33;1m%1.6g MHz[0m, Codewort = [33;1m%s[0m\n\n",
cc.frequenz,(code2str(s),s));
puts("\t\tHauptmenü");
puts("\t\t─────────\n");
puts("\t\tLPT-Portadresse . . . . . . . . . ([1ml[0m)");
puts("\t\tVoreinstellung laden . . . . . ([1m1-5[0m)");
puts("\t\tPLL-Oszillatorfrequenz stellen . ([1mi[0m)");
puts("\t\tKanalverzögerungen einstellen . . ([1md[0m)");
puts("\t\tPulslänge einstellen . . . . . . ([1mp[0m)");
puts("\t\tMaske einstellen . . . . . . . . ([1mm[0m)");
puts("\t\tZykluszeit einstellen . . . . . . ([1mw[0m)");
puts("\t\tTernärcode einstellen . . . . . . ([1mc[0m)");
puts("\t\tStarten . . . . . . . . . . . . . ([1mr[0m)");
puts("\t\tStarten im Einzelschritt . . . . ([1ms[0m)");
puts("\t\tEnde . . . . . . . . . . . . . ([1mq,e[0m)\n\n");
}
void ConfigStart(void) {
puts("[2J\n\n\n"
" [36mMomentane Konfiguration:[0m\n"
" ────────────────────────\n");
}
void load_pre(int n) {
cc=pc[n];
bitcalc(cc.frequenz);
}
//################################################################################
//# Funktion delay
//################################################################################
void delay_menu(void){
int i;
char s[16];
ConfigStart();
KanalInfo();
puts("\n\n[5;50HNeue Kanalverzögerungen:\n[50C────────────────────────\n");
for (i=0; i<16; i++) {
sprintf(s,"[50CKanal %2d",i);
if (input(s,s,sizeof(s))) cc.verz[i]=atoi(s); /*keine Leereingabe*/
}
}
//################################################################################
//# Funktion lpt
//################################################################################
void lpt_port(void){
int i;
char s[8];
ConfigStart();
printf(" Portadresse ist %03Xh\n\n",LptBase);
if (input(" Neue Adresse (hex)",s,sizeof(s))) LptBase=strtoul(s,NULL,16);
}
//###############################
//# Funktion Zykluszeit-Eingabe #
//###############################
void enter_Zykluszeit(void){
int i;
char s[8];
ConfigStart();
printf(" Zykluszeit ist %lu oder %g ms\n\n",cc.Zykluszeit,
(TREAL)cc.Zykluszeit/cc.frequenz*0.001);
if (input(" Neue Zykluszeit",s,sizeof(s))) cc.Zykluszeit=strtoul(s,NULL,0);
}
//###############################
//# Funktion Pulslängen-Eingabe #
//###############################
void enter_Pulslen(void){
int i;
char s[8];
ConfigStart();
printf(" Pulslänge ist %u\n\n",cc.Pulslen);
if (input(" Neue Pulslänge",s,sizeof(s))) cc.Pulslen=strtoul(s,NULL,0);
}
//###########################
//# Funktion Masken-Eingabe #
//###########################
void enter_Maske(void){
int i;
char s[18];
ConfigStart();
itoa(cc.MaskePos,s,2);
printf(" Maske=%sb\n\n",s);
if (input(" Neue Maske (binär)",s,sizeof(s)))
cc.MaskePos=cc.MaskeNeg=strtoul(s,NULL,2);
}
//################################################################################
//# Funktion icd
//################################################################################
void icdprog_menu(void){
char s[32];
TREAL f;
ConfigStart();
ultoa(IcdWort,s,2);
printf(" Programmierwort: %0*s (%06lXh)\n\n",IcdWortLen,s,IcdWort);
printf(" Programmierwortlänge: %d\n\n",IcdWortLen);
bitshow(0);
retry:
if (input("\n Neue Frequenz [MHz]",s,sizeof(s))) {
f=strtod(s,NULL);
if (!bitcalc(f)) {
puts("FEHLER: Zahl ungültig");
goto retry;
}
cc.frequenz=f;
puts("");
bitshow(0);
more(NULL);
}
}
//################################################################################
//# Funktion code
//################################################################################
void code_menu(void){
int i;
char s[32],*sp;
ConfigStart();
ultoa(cc.CodeWortPos,s,2);
printf(" Codewort positiv: %013s (%04Xh)\n",s,cc.CodeWortPos);
ultoa(cc.CodeWortNeg,s,2);
printf(" Codewort negativ: %013s (%04Xh)\n",s,cc.CodeWortNeg);
code2str(s);
printf(" Ternärcode zus. : %s\n\n[56C├───────────╢\n",s);
while (input(" Codewort (P=^=+=1=positiv, N=v=-=negativ, 0=.= =Null)",s,sizeof(s))
&& !str2code(s));
}
//################################################################################
//# Funktion run
//################################################################################
int dreher;
int CheckBusy(void) {
printf("%c\b","\\|/-"[dreher++&3]);
return inportb(LptBase+1)&0x80;
}
void ByteOut(int addr,int value, int stepping) {
int i;
if (stepping) printf(addr ? "Adresse: %-4d(%02Xh) " :
" Datum: %-4d(%02Xh)\n", value, value);
#ifdef epp
outportb(LptBase+(addr ? 3 : 4),value);
delay(10);
#else
outportb(LptBase+0, value);
outportb(LptBase+0, value);
outportb(LptBase+0, value);
outportb(LptBase+2, addr ? 0x0D : 0x07);
for (i=500; i--; ) if (!CheckBusy()) goto raus;
putchar('L'); /* Fehler: Leitung klemmt */
raus:
outportb(LptBase+2, 0x05);
if (!CheckBusy()) putchar('H'); /* Fehler: Leitung klemmt */
#endif
if (stepping) more(NULL);
}
void PutByte(UCHAR addr, UCHAR value, int stepping) {
/* Ausgabe Byte <value> auf ECP-Adresse <addr> */
ByteOut(1,addr,stepping);
ByteOut(0,value,stepping);
}
void PutWort(UCHAR addr, ULONG value, int vbytes, UCHAR stepping) {
/* Ausgabe eines Wortes <value> mit angebbarer Bytezahl <vbytes>
* auf aufeinanderfolgende ECP-Adressen <addr>, beginnend mit LSByte */
UCHAR b;
if (!vbytes) ByteOut(1,addr,stepping&1);
if (stepping&BYTEREV) {
for(addr+=vbytes; vbytes--; ) { /* absteigende Adressen nehmen */
b=value&0xFF;
if (stepping&BITREV) b=bitrev(b);
PutByte(--addr,b,stepping&1);
value>>=8;
}
}else{
for(; vbytes--; ) {
b=value&0xFF;
if (stepping&BITREV) b=bitrev(b);
PutByte(addr++,b,stepping&1);
value>>=8;
}
}
}
int run_data(int stepping){
int i,cycle,cycles=1;
char s[8];
puts("[K\n");
if (!stepping && input(" Zyklenzahl [1]",s,sizeof(s))) cycles=atoi(s);
puts("Init LPT-EPP...");
outportb(LptBase+2,5);
delay(1000);
puts("\nBeginn Programmierung ");
for(cycle=0; cycle<cycles; cycle++) {
if (!stepping) putchar('.');
PutWort(0x52,0,0,stepping);
PutWort(0x00,cc.CodeWortPos,2,stepping);
PutWort(0x02,cc.CodeWortNeg,2,stepping);
PutWort(0x14,IcdWort,4,stepping|BITREV);
PutByte(0x18,IcdWortLen,stepping);
for (i=0; i<16; i++) {
PutByte(0x04+i,cc.verz[i],stepping);
}
PutByte(0x19,cc.Pulslen,stepping);
PutWort(0x1A,cc.Zykluszeit,3,stepping|BYTEREV);
PutWort(0x1D,cc.MaskePos,2,stepping|BITREV);
PutWort(0x1F,cc.MaskeNeg,2,stepping|BITREV);
if (stepping) puts("Fertig mit Laden, nun ICD-Programmierung");
PutWort(0x50,0,0,stepping);
sleep(1);
if (stepping) puts("Fertig mit ICD-Programierung, nun Pulsausgabe (Action)");
PutWort(0x51,0,0,stepping);
delay(300);
}
more("Fertig!");
return 0;
}
//################################################################################
//# Funktion main
//################################################################################
void main(void) {
int i;
char s[8];
bitcalc(cc.frequenz);
while (1) {
main_menu();
retry:
input("[23;16H?",s,sizeof(s));
switch (tolower(*s)) {;
case 'l': lpt_port(); break;
case 'f':
case 'i': icdprog_menu(); break;
case 'v':
case 'd': delay_menu(); break;
case 'z': enter_Zykluszeit(); break;
case 'p': enter_Pulslen(); break;
case 'm': enter_Maske(); break;
case 't':
case 'c': code_menu(); break;
case 'r': run_data(0); break;
case 's': run_data(1); break;
case '1': load_pre(0); break;
case '2': load_pre(1); break;
case '3': load_pre(2); break;
case '4': load_pre(3); break;
case '5': load_pre(4); break;
case 'q':
case 'e': return;
default: puts("\t\tUngültige Eingabe!"); goto retry;
}
}
}
Detected encoding: OEM (CP437) | 1
|
|