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 = 5; { 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 = 78; { 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 );
140  
141 {-- Definice typu informace o procesoru --}
142  
143 type ProcNam_t=string[ProcName_l+1];
144  
145 type ProcInfo_t=record
146 Name : ProcNam_t; { jmeno procesoru }
147 Alg : ProcAlg_t; { identifikace algoritmu }
148 Tprog : word; { programovaci cas v us }
149 Bits : word; { pocet predavanych bitu }
150 Cfg : string[CfgNameLen]; { druh konfiguracniho slova }
151 Cfg_Base, Cfg_Mask : word; { adresa Cfg a maska platnych bitu }
152 PM_Base, PM_Len, PM_Mask : word; { pamet programu }
153 CM_Base, CM_Len, CM_Mask : word; { pamet konfigurace }
154 DM_Base, DM_Len, DM_Mask : word; { pamet dat }
155 end; {record}
156  
157 {-- Defince konstanty parametru procesoru s prazdnym obsahem --}
158  
159 const ProcDummyInfo:ProcInfo_t =
160 ( Name: '';
161 Alg: _NONE_;
162 Tprog: 0;
163 Bits: 0;
164 Cfg: '';
165 Cfg_Base: $0000;
166 Cfg_Mask: $0000;
167 PM_Base:$0000; PM_Len:$0000; PM_Mask:$0000;
168 CM_Base:$0000; CM_Len:$0000; CM_Mask:$0000;
169 DM_Base:$0000; DM_Len:$0000; DM_Mask:$0000
170 );
171  
172 {-- Defice vlastniho popisu vsech procesoru --}
173  
174 {$I PP_PROC.PAS}
175  
176 {===========================================================================}
177 { Hlavicky funkci a procedur souvisejicich s definici parametru procesoru. }
178 {===========================================================================}
179  
180 procedure ProcDisplayAlg(Alg:ProcAlg_t;Tprog:word);
181 {== Zobrazi citelne jmeno algoritmu ==}
182  
183 procedure ProcDisplayInfoAll;
184 {== Zobrazi info o vsech znamych procesorech ==}
185 { Strankuje s pauzou }
186  
187 procedure ProcDisplayInfo(ProcInfo:ProcInfo_t);
188 {== Zobrazi info o jednom procesoru i s nadpisem ==}
189  
190 procedure ProcFind(s:string; var ProcInfo:ProcInfo_t);
191 {== Najde podle retezce informace o procesoru ==}
192  
193 implementation
194  
195 {===========================================================================}
196 { Funkce a procedury pro podporu zpracovani prepinacu modifikujicich }
197 { konfiguracni slovo. }
198 {===========================================================================}
199  
200 function CfgFindProcGroup(Par:string;var CfgDef:CfgDef_t):integer;
201 {== Vrati index do tabulky CfgDef pro zadane jmeno skupiny procesoru ==}
202 { Pri nenalezeni vraci cilo 0 }
203 var i:integer;
204 begin i:=CfgDefProcCount+1;
205 repeat dec(i);
206 until (i=0) or (Par=CfgDef[i].ProcId);
207 CfgFindProcGroup:=i;
208 end; {CfgFindProcGroup}
209  
210 procedure CfgDisplayHelp(var CfgDefProc:CfgDefProc_t);
211 {== Zobrazi help pro Cfg prepinace zadane skupiny procesoru ==}
212 var i:integer;
213 begin write(CfgDefProc.ProcId:10,': ');
214 for i:=1 to CfgDefSwCount do
215 write(CfgDefProc.Info[i].Key,' ');
216 writeln;
217 end; {CfgDisplayHelp}
218  
219 procedure CfgDisplayHelpAll(var CfgDef:CfgDef_t);
220 {== Zobrazi help od prepinacu Cfg slova pro vechny skupiny procesoru ==}
221 var i:integer;
222 begin writeln('Processor specific switches for Config Word overiding: ');
223 writeln;
224 for i:=1 to CfgDefProcCount do
225 CfgDisplayHelp(CfgDef[i]);
226 writeln;
227 end; {CfgDisplayHelpAll}
228  
229 function CfgTestSingleKey(Par:string; Def:CfgDefSw_t):string;
230 {== Otestuje zda parametr Par odpovida definici Def a vrati retezec ==}
231 { obsahujici konfig slovo ve tristavove logice. Pri chybe varci }
232 { prazdny retezec }
233 { Pomocna funkce }
234 var i:integer;
235 BitCount:integer; { pocet bitu 1..8 podle definice }
236 ParValue:byte; { sem se nactou bity z Par }
237 begin if pos(Def.Key,Par)=0 then begin CfgTestSingleKey:='';
238 exit;
239 end;
240 if Par=Def.Key+'_ON' then begin CfgTestSingleKey:=Def.On;
241 exit;
242 end;
243 if Par=Def.Key then begin CfgTestSingleKey:=Def.On;
244 exit;
245 end;
246 if Par=Def.Key+'_OFF' then begin CfgTestSingleKey:=Def.Off;
247 exit;
248 end;
249 if Def.Bits='' then begin CfgTestSingleKey:='';
250 exit;
251 end;
252 {-- pocet definovanych bitu --}
253 BitCount:=0;
254 for i:=1 to length(Def.Bits) do
255 begin if (Def.Bits[i] <> 'X') and not (Def.Bits[i] in ['0'..'7'])
256 then Error('Internal Error 1 at TestKey',0);
257 if Def.Bits[i] in ['0'..'7']
258 then if 1+byte(Def.Bits[i])-byte('0') > BitCount
259 then BitCount:=1+byte(Def.Bits[i])-byte('0');
260 end;
261 if BitCount=0 then Error('Internal Error 2 at TestKey',0);
262 if BitCount>8 then Error('Internal Error 3 at TestKey',0);
263 if length(Par)<>length(Def.Key)+1+BitCount
264 then begin CfgTestSingleKey:='';
265 exit;
266 end;
267 {-- precti bity --}
268 ParValue:=0;
269 for i:=1 to BitCount do
270 begin case Par[length(Def.Key)+1+i] of
271 '0' : ParValue:=ParValue*2;
272 '1' : ParValue:=ParValue*2+1;
273 else begin CfgTestSingleKey:='';
274 exit;
275 end;
276 end; {case}
277 end;
278 {-- sestav vysledek --}
279 CfgTestSingleKey[0]:=char(CfgWordLen);
280 for i:=1 to CfgWordLen do
281 begin if Def.Bits[i]='X'
282 then CfgTestSingleKey[i]:='X'
283 else if ((ParValue shr (byte(Def.Bits[i])-byte('0'))) and 1) = 0
284 then CfgTestSingleKey[i]:='0'
285 else CfgTestSingleKey[i]:='1';
286 end;
287 end; {CfgTestSingleKey}
288  
289 function CfgTestKey(Par:string;var CfgDefProc:CfgDefProc_t):string;
290 {== Otestuje parametr ( retezec s jednim prepinacem ) na vsechny ==}
291 { prepinace dane skupiny procesoru a vrati vysledek jako }
292 { tristavovy retezec. Pri chybe vraci prazdny retezec. }
293 var i:integer;
294 s:string;
295 begin if Par='' then begin CfgTestKey:=''; { to je vlastne chyba, }
296 exit; { nevracim zadne slovo }
297 end;
298 i:=1;
299 repeat s:=CfgTestSingleKey(Par,CfgDefProc.Info[i]);
300 inc(i);
301 until (s<>'') or (i>CfgDefSwCount);
302 CfgTestKey:=s;
303 end; {CfgTestKey}
304  
305 procedure CfgDisplayCfgBits(s:string);
306 {== Zobrazi citelne druh konfiguracnich bitu ==}
307 { Pomocna procedura ( ProcDisplayInfoLine ) }
308 begin write(copy(s+' ',1,9));
309 end; {CfgDisplayCfgBits}
310  
311 function CfgOr(s1,s2:string):string;
312 {== Slouci dva Cfg retezce do jednoho. ==}
313 { V pripade konfliktu vraci prazdny retezec }
314 var i:integer;
315 begin CfgOr:='';
316 if length(s1)<>length(s2) then exit;
317 for i:=1 to length(s1) do
318 case s1[i] of
319 '0' : case s2[i] of
320 '0' : CfgOr[i]:='0';
321 '1' : exit;
322 'X' : CfgOr[i]:='0';
323 else exit;
324 end; {case}
325 '1' : case s2[i] of
326 '0' : exit;
327 '1' : CfgOr[i]:='1';
328 'X' : CfgOr[i]:='1';
329 else exit;
330 end; {case}
331 'X' : case s2[i] of
332 '0' : CfgOr[i]:='0';
333 '1' : CfgOr[i]:='1';
334 'X' : CfgOr[i]:='X';
335 else exit;
336 end; {case}
337 else exit; { chyba }
338 end; {case}
339 CfgOr[0]:=s1[0]; { delka retezce }
340 end; {CfgOr}
341  
342 function CfgOverride(s,os:string):string;
343 {== Modifikuje platne Cfg string s platnymi bity Cfg stringu os ==}
344 { V pripade chybneho rozmeru retezcu vraci prazdny retezec }
345 var i:integer;
346 begin CfgOverride:='';
347 if length(s)<>length(os) then exit;
348 for i:=1 to length(s) do
349 case os[i] of
350 '0' : CfgOverride[i]:='0';
351 '1' : CfgOverride[i]:='1';
352 'X' : CfgOverride[i]:=s[i];
353 else exit; { chyba }
354 end; {case}
355 CfgOverride[0]:=s[0]; { delka retezce }
356 end; {CfgOverride}
357  
358 function CfgTestKeyMultiple(var Pars:string;var CfgDefProc:CfgDefProc_t):string;
359 {== Zadavam retezec prepinacu a popis procesorove specifickych prepinacu. ==}
360 { Zpracovane parametry z Pars vykousnu. Vracim Cfg slovo jako tristavovy }
361 { retezec. }
362 { Pokud je chyba, vracim prazdny retezec a v Pars je prepinac, ktery }
363 { zpusobil chybu na prvni pozici }
364 var CfgOne : string; { jeden klic ( prepinac ) }
365 CfgSuma : string; { mezisoucet klicu }
366 ErrStr : string; { meziuschova nezpracovatelnych klicu }
367 begin ErrStr:='';
368 CfgSuma:=CfgX;
369 while Pars<>'' do { dokud nezpracuji vse z retezce Pars }
370 begin {-- zpracuj jeden prepinac --}
371 CfgOne:=CfgTestKey(GetWord(Pars),CfgDefProc);
372 if CfgOne=''
373 then ErrStr:=ErrStr+' '+GetWord(Pars)
374 else begin CfgSuma:=CfgOr(CfgSuma,CfgOne);
375 if CfgSuma=''
376 then begin {-- konfliktni parametry --}
377 CfgTestKeyMultiple:='';
378 Pars:=Pars+ErrStr;
379 exit;
380 end;
381 end;
382 Pars:=DelWord(Pars);
383 end;
384 CfgTestKeyMultiple:=CfgSuma; { vysledne konfiguracni slovo }
385 Pars:=ErrStr; { prepinace, ktere neznam }
386 end; {CfgTestKeyMultiple}
387  
388 function Word2Str(W:word):string;
389 {== Prevede binarni data W na retezec ( tristavovy ) ==}
390 var i:integer;
391 begin Word2Str[0]:=char(CfgWordLen); { delka retezce }
392 for i:=CfgWordLen downto 1 do
393 begin if ( W and 1 ) = 1 then Word2Str[i]:='1' { jednotlive bity }
394 else Word2Str[i]:='0';
395 W := W shr 1; { dalsi bit }
396 end;
397 end; {Word2Str}
398  
399 function Str2Word(S:string):word;
400 {== Prevede Cfg string na binarni data ==}
401 { Misto bitu 'X' da '1' }
402 var W:word;
403 i:integer;
404 begin W:=0;
405 for i:=1 to length(S) do
406 if S[i]<>'0' then W := ( W shl 1 ) + 1
407 else W := ( W shl 1 );
408 Str2Word:=W;
409 end; {Str2Word}
410  
411 {===========================================================================}
412 { Funkce a procedury souvisejicich s definici parametru procesoru. }
413 {===========================================================================}
414  
415 procedure ProcDisplayAlg(Alg:ProcAlg_t;Tprog:word);
416 {== Zobrazi citelne jmeno algoritmu ==}
417 begin case Alg of
418 _NONE_ : write('NONE ');
419 _EPROM1_ : write('EPROM1 ');
420 _EPROM2_ : write('EPROM2 ');
421 _EPROM3_ : write('EPROM3 ');
422 _EE1_ : write('EE1 ');
423 _EE2_ : write('EE2 ');
424 _NON2WIRE_ : write('NON2WIRE');
425 else write('?? ');
426 end; {case}
427 write(Tprog:6,' '); { programovaci cas v us }
428 end; {ProcDisplayAlg}
429  
430 procedure ProcDisplayInfoLine(ProcInfo:ProcInfo_t);
431 {== Zobrazi v lidske podobe nektere informace o procesoru ==}
432 var s:string;
433 i:integer;
434 begin s:=ProcInfo.Name;
435 for i:=length(s)+1 to ProcName_l do s:=s+' ';
436 write(s,' ');
437 ProcDisplayAlg(ProcInfo.Alg,ProcInfo.Tprog);
438 CfgDisplayCfgBits(ProcInfo.Cfg);
439 DisplayRange(ProcInfo.PM_Base,ProcInfo.PM_Len);
440 DisplayRange(ProcInfo.CM_Base,ProcInfo.CM_Len);
441 DisplayRange(ProcInfo.DM_Base,ProcInfo.DM_Len);
442 writeln;
443 end; {ProcDisplayInfoLine}
444  
445 procedure ProcDisplayInfoHeader;
446 {== Zobrazi nadpis ==}
447 begin writeln('Proc Name Alg Tprog[us] Cfg Bits Pgm Memory Cfg Memory Dat Memory');
448 writeln('--------------------------------------------------------------------------');
449 end; {ProcDisplayInfoHeader}
450  
451 procedure ProcDisplayInfoAll;
452 {== Zobrazi info o vsech znamych procesorech ==}
453 { Strankuje s pauzou }
454 var i,j:integer;
455 begin i:=0;
456 while i<ProcCount do
457 begin ProcDisplayInfoHeader;
458 j:=0;
459 while (i<ProcCount) and (j<22) do
460 begin inc(i);
461 inc(j);
462 ProcDisplayInfoLine(ProcInfoAll[i]);
463 end;
464 if i<ProcCount then PressEnter;
465 end;
466 end; {ProcDisplayInfoAll}
467  
468 procedure ProcDisplayInfo(ProcInfo:ProcInfo_t);
469 {== Zobrazi info o jednom procesoru i s nadpisem ==}
470 begin ProcDisplayInfoHeader;
471 ProcDisplayInfoLine(ProcInfo);
472 writeln;
473 end; {ProcDisplayInfo}
474  
475 procedure ProcFind(s:string; var ProcInfo:ProcInfo_t);
476 {== Najde podle retezce informace o procesoru ==}
477 var i:integer;
478 begin {-- separace jmena procesoru z retezce --}
479 s:=upstr(s)+' ';
480 ProcInfo:=ProcDummyInfo;
481 i:=pos('PIC',s);
482 if i=0 then exit;
483 s:=copy(s,i,255);
484 i:=pos(' ',s);
485 s:=copy(s,1,i-1);
486 {-- nalezeni informaci --}
487 for i:=1 to ProcCount do
488 if (ProcInfoAll[i].Name+' ') = s+' '
489 then ProcInfo:=ProcInfoAll[i];
490 end; {ProcFind}
491  
492 {===========================================================================}
493 { Telo jednotky. }
494 {===========================================================================}
495  
496 procedure VerifyProcInfo;
497 {== Procedura provede interni test konzistentnosti dat ==}
498 var i:integer;
499 begin for i:=1 to ProcCount do
500 with ProcInfoAll[i] do
501 begin {-- kontrola delky jmena procesoru --}
502 if length(Name) > ProcName_l
503 then Error('Internal Error: IE01',0);
504 {-- kontrola rozsahu pametovych prostoru --}
505 if PM_Base+PM_Len>DataBufLen
506 then Error('Internal Error: IE02',0);
507 if CM_Base+CM_Len>DataBufLen
508 then Error('Internal Error: IE03',0);
509 if DM_Base+DM_Len>DataBufLen
510 then Error('Internal Error: IE04',0);
511 {-- kontrola zda znam vsechny uvedene Cfg --}
512 if (ProcInfoAll[i].Cfg<>'') and (CfgFindProcGroup(ProcInfoAll[i].Cfg,CfgDefAll)=0)
513 then Error('Internal Error: IE5',0);
514 end;
515 end; {VerifyProcInfo}
516  
517 var i:integer;
518  
519 begin {-- kontroluje konzistentnost konstant --}
520 VerifyProcInfo;
521 {-- inicializace prazdne konstanty pro Cfg slovo ( same 'X' ) --}
522 CfgX[0]:=char(CfgWordLen);
523 for i:=1 to length(CfgX) do CfgX[i]:='X';
524 end.
525