Rev Author Line No. Line
204 miho 1 unit PP_DEFS;
2  
3 {===========================================================================}
4 { (c) miho / DECROS 2000 }
5 {===========================================================================}
6 { Zde jsou definice zavisle na vlastnostech jednotlivych procesoru. }
7 { Dale jsou zde procedury, ktere prpimo souvisi s definovanymi datovymi }
8 { strukturami }
9 {===========================================================================}
10  
11 interface
12  
13 uses PP_COMON; { jen procedura Error }
14  
15 {===========================================================================}
16 { Definice celkoveho rozsahu adresoveho prostoru pri programovani PICu }
17 {===========================================================================}
18  
19 const DataBufLen=$4000; { Maximalne 2 x 8 K slov pameti programu }
20 { dat a konfigurace }
21  
22 {===========================================================================}
23 { Definice typu a konstant souvisejicich se zpracovanim prepinacu pro }
24 { definovani konfiguracniho slova. }
25 {===========================================================================}
26  
27 {-- Definice konstant pro rozsah mezi --}
28  
29 const CfgDefProcCount = 7; { pocet skupin procesoru }
30 CfgDefSwCount = 15; { maximalni pocet prepinacu u jedne skupiny }
31 CfgWordLen = 14; { maximalni pocet bitu Cfg slova }
32 CfgNameLen = 10; { maximalni delka jmena definice skupiny }
33 CfgKeyLen = 10; { maximalni delka prepinace }
34  
35 {-- Definice typu pro popis jednoho prepinace --}
36  
37 type CfgDefSw_t=record
38 Key : string[CfgKeyLen]; { jmeno prepinace }
39 On : string[CfgWordLen]; { hodnota pro stav _ON }
40 Off : string[CfgWordLen]; { hodnota pro stav _OFF }
41 Bits : string[CfgWordLen]; { definice pro _xxx u vicebitovych prepinacu }
42 end; {record}
43  
44 { Key definuje jmeno prepinace ( napr CP pro Code Protection ) }
45 { On definuje stav jednotlivych bitu pro stav On }
46 { Off definuje stav jednotlivych bity pro stav Off }
47 { Bits definuje kam prijdou jednotlive bity vicebitoveho prepinace }
48  
49 const CfgX:string[CfgWordLen]=''; { sama 'X' o delce Cfg slova }
50  
51 {-- Definice typu pro popis jedne skupinu procesoru --}
52  
53 type CfgDefProc_t=record
54 ProcId : string[CfgNameLen]; { jmeno skupiny procesoru }
55 Info : array[1..CfgDefSwCount] of CfgDefSw_t;
56 end; {record}
57  
58 {-- Definice typu pro popis vsech skupin procesoru --}
59  
60 type CfgDef_t=array[1..CfgDefProcCount] of CfgDefProc_t;
61  
62 {-- Definice konstanty popisu prepinace s prazdnym obsahem --}
63  
64 const CfgDefSwNull:CfgDefSw_t=
65 ( Key : '';
66 On : '';
67 Off : '';
68 Bits : ''
69 );
70  
71 {-- Vlastni definice vsech skupin procesoru --}
72  
73 {$I PP_CFG.PAS} { Abychom tady nemeli tisic radek definice }
74  
75 {===========================================================================}
76 { Hlavicky funkci a procedur pro podporu zpracovani prepinacu }
77 { modifikujicich konfiguracni slovo. }
78 {===========================================================================}
79  
80 function CfgFindProcGroup(Par:string;var CfgDef:CfgDef_t):integer;
81 {== Vrati index do tabulky CfgDef pro zadane jmeno skupiny procesoru ==}
82 { Pri nenalezeni vraci cilo 0 }
83  
84 procedure CfgDisplayHelp(var CfgDefProc:CfgDefProc_t);
85 {== Zobrazi help pro Cfg prepinace zadane skupiny procesoru ==}
86  
87 procedure CfgDisplayHelpAll(var CfgDef:CfgDef_t);
88 {== Zobrazi help od prepinacu Cfg slova pro vechny skupiny procesoru ==}
89  
90 function CfgTestKey(Par:string;var CfgDefProc:CfgDefProc_t):string;
91 {== Otestuje parametr ( retezec s jednim prepinacem ) na vsechny ==}
92 { prepinace dane skupiny procesoru a vrati vysledek jako }
93 { tristavovy retezec. Pri chybe vraci prazdny retezec. }
94  
95 function CfgOr(s1,s2:string):string;
96 {== Slouci dva Cfg retezce do jednoho. ==}
97 { V pripade konfliktu vraci prazdny retezec }
98  
99 function CfgOverride(s,os:string):string;
100 {== Modifikuje platne Cfg string s platnymi bity Cfg stringu os ==}
101 { V pripade chybneho rozmeru retezcu vraci prazdny retezec }
102  
103 function CfgTestKeyMultiple(var Pars:string;var CfgDefProc:CfgDefProc_t):string;
104 {== Zadavam retezec prepinacu a popis procesorove specifickych prepinacu. ==}
105 { Zpracovane parametry z Pars vykousnu. Vracim Cfg slovo jako tristavovy }
106 { retezec. }
107 { Pokud je chyba, vracim prazdny retezec a v Pars je prepinac, ktery }
108 { zpusobil chybu na prvni pozici }
109  
110 function Word2Str(W:word):string;
111 {== Prevede binarni data W na retezec ( tristavovy ) ==}
112  
113 function Str2Word(S:string):word;
114 {== Prevede Cfg string na binarni data ==}
115 { Misto bitu 'X' da '1' }
116  
117 {===========================================================================}
118 { Definice typu a konstant popisujicich parametry jednotlivych procesoru. }
119 {===========================================================================}
120  
121 {-- Definice konstant urcujicich meze -}
122  
123 const ProcName_l = 14; { Maxialni delka jmena procesoru }
124 ProcCount = 87; { Pocet definovanych procesoru }
125  
126 {-- Definice typu pro identifikaci programovaciho algoritmu --}
127  
128 type ProcAlg_t=
129 ( _NONE_, { Nedefinovana hodnota }
130 _NON2WIRE_, { Algoritmus neni seriovy ( nepodporuji ) }
131 {-- EPROM a OTP --}
132 _EPROM1_, { Stary algoritmus pro EPROM ( PIC12C5xx ) }
133 _EPROM2_, { Standardni EPROM }
134 _EPROM3_, { Standardni EPROM se slovem 16 bitu }
135 {-- EEPROM a FLASH --}
136 _EE1_, { Standardni Flash / EEPROM }
137 _EE2_, { Flash / EEPROM s prikazem }
138 { Begin Programming Only Cycle }
139 _EE3_, { Skupina 87xA }
140 _EE4_, { Skupina 627A/628A/648A (jiny erase) }
141 _EE5_ { Skupina 618/919 (jako EE3, jinak CFG slovo }
142 ); {---> nezapomen aktualizovat ProcDisplayAlg --}
143  
144 {-- Definice typu informace o procesoru --}
145  
146 type ProcNam_t=string[ProcName_l+1];
147  
148 type ProcInfo_t=record
149 Name : ProcNam_t; { jmeno procesoru }
150 Alg : ProcAlg_t; { identifikace algoritmu }
151 Tprog : word; { programovaci cas v us }
152 Bits : word; { pocet predavanych bitu }
153 Cfg : string[CfgNameLen]; { druh konfiguracniho slova }
154 Cfg_Base, Cfg_Mask : word; { adresa Cfg a maska platnych bitu }
155 PM_Base, PM_Len, PM_Mask : word; { pamet programu }
156 CM_Base, CM_Len, CM_Mask : word; { pamet konfigurace }
157 DM_Base, DM_Len, DM_Mask : word; { pamet dat }
158 end; {record}
159  
160 {-- Defince konstanty parametru procesoru s prazdnym obsahem --}
161  
162 const ProcDummyInfo:ProcInfo_t =
163 ( Name: '';
164 Alg: _NONE_;
165 Tprog: 0;
166 Bits: 0;
167 Cfg: '';
168 Cfg_Base: $0000;
169 Cfg_Mask: $0000;
170 PM_Base:$0000; PM_Len:$0000; PM_Mask:$0000;
171 CM_Base:$0000; CM_Len:$0000; CM_Mask:$0000;
172 DM_Base:$0000; DM_Len:$0000; DM_Mask:$0000
173 );
174  
175 {-- Defice vlastniho popisu vsech procesoru --}
176  
177 {$I PP_PROC.PAS}
178  
179 {===========================================================================}
180 { Hlavicky funkci a procedur souvisejicich s definici parametru procesoru. }
181 {===========================================================================}
182  
183 procedure ProcDisplayAlg(Alg:ProcAlg_t;Tprog:word);
184 {== Zobrazi citelne jmeno algoritmu ==}
185  
186 procedure ProcDisplayInfoAll;
187 {== Zobrazi info o vsech znamych procesorech ==}
188 { Strankuje s pauzou }
189  
190 procedure ProcDisplayInfo(ProcInfo:ProcInfo_t);
191 {== Zobrazi info o jednom procesoru i s nadpisem ==}
192  
193 procedure ProcFind(s:string; var ProcInfo:ProcInfo_t);
194 {== Najde podle retezce informace o procesoru ==}
195  
196 implementation
197  
198 {===========================================================================}
199 { Funkce a procedury pro podporu zpracovani prepinacu modifikujicich }
200 { konfiguracni slovo. }
201 {===========================================================================}
202  
203 function CfgFindProcGroup(Par:string;var CfgDef:CfgDef_t):integer;
204 {== Vrati index do tabulky CfgDef pro zadane jmeno skupiny procesoru ==}
205 { Pri nenalezeni vraci cilo 0 }
206 var i:integer;
207 begin i:=CfgDefProcCount+1;
208 repeat dec(i);
209 until (i=0) or (Par=CfgDef[i].ProcId);
210 CfgFindProcGroup:=i;
211 end; {CfgFindProcGroup}
212  
213 procedure CfgDisplayHelp(var CfgDefProc:CfgDefProc_t);
214 {== Zobrazi help pro Cfg prepinace zadane skupiny procesoru ==}
215 var i:integer;
216 begin write(CfgDefProc.ProcId:10,': ');
217 for i:=1 to CfgDefSwCount do
218 write(CfgDefProc.Info[i].Key,' ');
219 writeln;
220 end; {CfgDisplayHelp}
221  
222 procedure CfgDisplayHelpAll(var CfgDef:CfgDef_t);
223 {== Zobrazi help od prepinacu Cfg slova pro vechny skupiny procesoru ==}
224 var i:integer;
225 begin writeln('Processor specific switches for Config Word overiding: ');
226 writeln;
227 for i:=1 to CfgDefProcCount do
228 CfgDisplayHelp(CfgDef[i]);
229 writeln;
230 end; {CfgDisplayHelpAll}
231  
232 function CfgTestSingleKey(Par:string; Def:CfgDefSw_t):string;
233 {== Otestuje zda parametr Par odpovida definici Def a vrati retezec ==}
234 { obsahujici konfig slovo ve tristavove logice. Pri chybe varci }
235 { prazdny retezec }
236 { Pomocna funkce }
237 var i:integer;
238 BitCount:integer; { pocet bitu 1..8 podle definice }
239 ParValue:byte; { sem se nactou bity z Par }
240 begin if pos(Def.Key,Par)=0 then begin CfgTestSingleKey:='';
241 exit;
242 end;
243 if Par=Def.Key+'_ON' then begin CfgTestSingleKey:=Def.On;
244 exit;
245 end;
246 if Par=Def.Key then begin CfgTestSingleKey:=Def.On;
247 exit;
248 end;
249 if Par=Def.Key+'_OFF' then begin CfgTestSingleKey:=Def.Off;
250 exit;
251 end;
252 if Def.Bits='' then begin CfgTestSingleKey:='';
253 exit;
254 end;
255 {-- pocet definovanych bitu --}
256 BitCount:=0;
257 for i:=1 to length(Def.Bits) do
258 begin if (Def.Bits[i] <> 'X') and not (Def.Bits[i] in ['0'..'7'])
259 then Error('Internal Error 1 at TestKey',0);
260 if Def.Bits[i] in ['0'..'7']
261 then if 1+byte(Def.Bits[i])-byte('0') > BitCount
262 then BitCount:=1+byte(Def.Bits[i])-byte('0');
263 end;
264 if BitCount=0 then Error('Internal Error 2 at TestKey',0);
265 if BitCount>8 then Error('Internal Error 3 at TestKey',0);
266 if length(Par)<>length(Def.Key)+1+BitCount
267 then begin CfgTestSingleKey:='';
268 exit;
269 end;
270 {-- precti bity --}
271 ParValue:=0;
272 for i:=1 to BitCount do
273 begin case Par[length(Def.Key)+1+i] of
274 '0' : ParValue:=ParValue*2;
275 '1' : ParValue:=ParValue*2+1;
276 else begin CfgTestSingleKey:='';
277 exit;
278 end;
279 end; {case}
280 end;
281 {-- sestav vysledek --}
282 CfgTestSingleKey[0]:=char(CfgWordLen);
283 for i:=1 to CfgWordLen do
284 begin if Def.Bits[i]='X'
285 then CfgTestSingleKey[i]:='X'
286 else if ((ParValue shr (byte(Def.Bits[i])-byte('0'))) and 1) = 0
287 then CfgTestSingleKey[i]:='0'
288 else CfgTestSingleKey[i]:='1';
289 end;
290 end; {CfgTestSingleKey}
291  
292 function CfgTestKey(Par:string;var CfgDefProc:CfgDefProc_t):string;
293 {== Otestuje parametr ( retezec s jednim prepinacem ) na vsechny ==}
294 { prepinace dane skupiny procesoru a vrati vysledek jako }
295 { tristavovy retezec. Pri chybe vraci prazdny retezec. }
296 var i:integer;
297 s:string;
298 begin if Par='' then begin CfgTestKey:=''; { to je vlastne chyba, }
299 exit; { nevracim zadne slovo }
300 end;
301 i:=1;
302 repeat s:=CfgTestSingleKey(Par,CfgDefProc.Info[i]);
303 inc(i);
304 until (s<>'') or (i>CfgDefSwCount);
305 CfgTestKey:=s;
306 end; {CfgTestKey}
307  
308 procedure CfgDisplayCfgBits(s:string);
309 {== Zobrazi citelne druh konfiguracnich bitu ==}
310 { Pomocna procedura ( ProcDisplayInfoLine ) }
311 begin write(copy(s+' ',1,9));
312 end; {CfgDisplayCfgBits}
313  
314 function CfgOr(s1,s2:string):string;
315 {== Slouci dva Cfg retezce do jednoho. ==}
316 { V pripade konfliktu vraci prazdny retezec }
317 var i:integer;
318 begin CfgOr:='';
319 if length(s1)<>length(s2) then exit;
320 for i:=1 to length(s1) do
321 case s1[i] of
322 '0' : case s2[i] of
323 '0' : CfgOr[i]:='0';
324 '1' : exit;
325 'X' : CfgOr[i]:='0';
326 else exit;
327 end; {case}
328 '1' : case s2[i] of
329 '0' : exit;
330 '1' : CfgOr[i]:='1';
331 'X' : CfgOr[i]:='1';
332 else exit;
333 end; {case}
334 'X' : case s2[i] of
335 '0' : CfgOr[i]:='0';
336 '1' : CfgOr[i]:='1';
337 'X' : CfgOr[i]:='X';
338 else exit;
339 end; {case}
340 else exit; { chyba }
341 end; {case}
342 CfgOr[0]:=s1[0]; { delka retezce }
343 end; {CfgOr}
344  
345 function CfgOverride(s,os:string):string;
346 {== Modifikuje platne Cfg string s platnymi bity Cfg stringu os ==}
347 { V pripade chybneho rozmeru retezcu vraci prazdny retezec }
348 var i:integer;
349 begin CfgOverride:='';
350 if length(s)<>length(os) then exit;
351 for i:=1 to length(s) do
352 case os[i] of
353 '0' : CfgOverride[i]:='0';
354 '1' : CfgOverride[i]:='1';
355 'X' : CfgOverride[i]:=s[i];
356 else exit; { chyba }
357 end; {case}
358 CfgOverride[0]:=s[0]; { delka retezce }
359 end; {CfgOverride}
360  
361 function CfgTestKeyMultiple(var Pars:string;var CfgDefProc:CfgDefProc_t):string;
362 {== Zadavam retezec prepinacu a popis procesorove specifickych prepinacu. ==}
363 { Zpracovane parametry z Pars vykousnu. Vracim Cfg slovo jako tristavovy }
364 { retezec. }
365 { Pokud je chyba, vracim prazdny retezec a v Pars je prepinac, ktery }
366 { zpusobil chybu na prvni pozici }
367 var CfgOne : string; { jeden klic ( prepinac ) }
368 CfgSuma : string; { mezisoucet klicu }
369 ErrStr : string; { meziuschova nezpracovatelnych klicu }
370 begin ErrStr:='';
371 CfgSuma:=CfgX;
372 while Pars<>'' do { dokud nezpracuji vse z retezce Pars }
373 begin {-- zpracuj jeden prepinac --}
374 CfgOne:=CfgTestKey(GetWord(Pars),CfgDefProc);
375 if CfgOne=''
376 then ErrStr:=ErrStr+' '+GetWord(Pars)
377 else begin CfgSuma:=CfgOr(CfgSuma,CfgOne);
378 if CfgSuma=''
379 then begin {-- konfliktni parametry --}
380 CfgTestKeyMultiple:='';
381 Pars:=Pars+ErrStr;
382 exit;
383 end;
384 end;
385 Pars:=DelWord(Pars);
386 end;
387 CfgTestKeyMultiple:=CfgSuma; { vysledne konfiguracni slovo }
388 Pars:=ErrStr; { prepinace, ktere neznam }
389 end; {CfgTestKeyMultiple}
390  
391 function Word2Str(W:word):string;
392 {== Prevede binarni data W na retezec ( tristavovy ) ==}
393 var i:integer;
394 begin Word2Str[0]:=char(CfgWordLen); { delka retezce }
395 for i:=CfgWordLen downto 1 do
396 begin if ( W and 1 ) = 1 then Word2Str[i]:='1' { jednotlive bity }
397 else Word2Str[i]:='0';
398 W := W shr 1; { dalsi bit }
399 end;
400 end; {Word2Str}
401  
402 function Str2Word(S:string):word;
403 {== Prevede Cfg string na binarni data ==}
404 { Misto bitu 'X' da '1' }
405 var W:word;
406 i:integer;
407 begin W:=0;
408 for i:=1 to length(S) do
409 if S[i]<>'0' then W := ( W shl 1 ) + 1
410 else W := ( W shl 1 );
411 Str2Word:=W;
412 end; {Str2Word}
413  
414 {===========================================================================}
415 { Funkce a procedury souvisejicich s definici parametru procesoru. }
416 {===========================================================================}
417  
418 procedure ProcDisplayAlg(Alg:ProcAlg_t;Tprog:word);
419 {== Zobrazi citelne jmeno algoritmu ==}
420 begin case Alg of
421 _NONE_ : write('NONE ');
422 _EPROM1_ : write('EPROM1 ');
423 _EPROM2_ : write('EPROM2 ');
424 _EPROM3_ : write('EPROM3 ');
425 _EE1_ : write('EE1 ');
426 _EE2_ : write('EE2 ');
427 _EE3_ : write('EE3 ');
428 _EE4_ : write('EE4 ');
429 _EE5_ : write('EE5 ');
430 _NON2WIRE_ : write('NON2WIRE');
431 else write('?? ');
432 end; {case}
433 write(Tprog:6,' '); { programovaci cas v us }
434 end; {ProcDisplayAlg}
435  
436 procedure ProcDisplayInfoLine(ProcInfo:ProcInfo_t);
437 {== Zobrazi v lidske podobe nektere informace o procesoru ==}
438 var s:string;
439 i:integer;
440 begin s:=ProcInfo.Name;
441 for i:=length(s)+1 to ProcName_l do s:=s+' ';
442 write(s,' ');
443 ProcDisplayAlg(ProcInfo.Alg,ProcInfo.Tprog);
444 CfgDisplayCfgBits(ProcInfo.Cfg);
445 DisplayRange(ProcInfo.PM_Base,ProcInfo.PM_Len);
446 DisplayRange(ProcInfo.CM_Base,ProcInfo.CM_Len);
447 DisplayRange(ProcInfo.DM_Base,ProcInfo.DM_Len);
448 writeln;
449 end; {ProcDisplayInfoLine}
450  
451 procedure ProcDisplayInfoHeader;
452 {== Zobrazi nadpis ==}
453 begin writeln('Proc Name Alg Tprog[us] Cfg Bits Pgm Memory Cfg Memory Dat Memory');
454 writeln('--------------------------------------------------------------------------');
455 end; {ProcDisplayInfoHeader}
456  
457 procedure ProcDisplayInfoAll;
458 {== Zobrazi info o vsech znamych procesorech ==}
459 { Strankuje s pauzou }
460 var i,j:integer;
461 begin i:=0;
462 while i<ProcCount do
463 begin ProcDisplayInfoHeader;
464 j:=0;
465 while (i<ProcCount) and (j<22) do
466 begin inc(i);
467 inc(j);
468 ProcDisplayInfoLine(ProcInfoAll[i]);
469 end;
470 if i<ProcCount then PressEnter;
471 end;
472 end; {ProcDisplayInfoAll}
473  
474 procedure ProcDisplayInfo(ProcInfo:ProcInfo_t);
475 {== Zobrazi info o jednom procesoru i s nadpisem ==}
476 begin ProcDisplayInfoHeader;
477 ProcDisplayInfoLine(ProcInfo);
478 writeln;
479 end; {ProcDisplayInfo}
480  
481 procedure ProcFind(s:string; var ProcInfo:ProcInfo_t);
482 {== Najde podle retezce informace o procesoru ==}
483 var i:integer;
484 begin {-- separace jmena procesoru z retezce --}
485 s:=upstr(s)+' ';
486 ProcInfo:=ProcDummyInfo;
487 i:=pos('PIC',s);
488 if i=0 then exit;
489 s:=copy(s,i,255);
490 i:=pos(' ',s);
491 s:=copy(s,1,i-1);
492 {-- nalezeni informaci --}
493 for i:=1 to ProcCount do
494 if (ProcInfoAll[i].Name+' ') = s+' '
495 then ProcInfo:=ProcInfoAll[i];
496 end; {ProcFind}
497  
498 {===========================================================================}
499 { Telo jednotky. }
500 {===========================================================================}
501  
502 procedure VerifyProcInfo;
503 {== Procedura provede interni test konzistentnosti dat ==}
504 var i:integer;
505 begin for i:=1 to ProcCount do
506 with ProcInfoAll[i] do
507 begin {-- kontrola delky jmena procesoru --}
508 if length(Name) > ProcName_l
509 then Error('Internal Error: IE01',0);
510 {-- kontrola rozsahu pametovych prostoru --}
511 if PM_Base+PM_Len>DataBufLen
512 then Error('Internal Error: IE02',0);
513 if CM_Base+CM_Len>DataBufLen
514 then Error('Internal Error: IE03',0);
515 if DM_Base+DM_Len>DataBufLen
516 then Error('Internal Error: IE04',0);
517 {-- kontrola zda znam vsechny uvedene Cfg --}
518 if (ProcInfoAll[i].Cfg<>'') and (CfgFindProcGroup(ProcInfoAll[i].Cfg,CfgDefAll)=0)
519 then Error('Internal Error: IE5',0);
520 end;
521 end; {VerifyProcInfo}
522  
523 var i:integer;
524  
525 begin {-- kontroluje konzistentnost konstant --}
526 VerifyProcInfo;
527 {-- inicializace prazdne konstanty pro Cfg slovo ( same 'X' ) --}
528 CfgX[0]:=char(CfgWordLen);
529 for i:=1 to length(CfgX) do CfgX[i]:='X';
530 end.
531