← Back to dashboard

File view

plc_utility.lib

1
//$Id: plc_utility.lib,v 1.8 2008-09-15 21:48:55 charlie Exp $
2
/*
3
   $Log: plc_utility.lib,v $
4
5
6
*/
7
8
/*** BeginHeader */
9
10
#ifndef __ISM_UTILITY_
11
#define __ISM_UTILITY_
12
13
/*** EndHeader */
14
15
/*** BeginHeader
16
	InitializeUtility,
17
	MsDelay,
18
	BitToMask,
19
	GetXmemChar,
20
	StrSafeCopy,
21
	IntUnitString3,
22
	IntUnitString,
23
	ParseFloatString,
24
	ParseIntString,
25
	Halt,
26
	RuntimeHalt,
27
	SetNow,
28
	GetNow,
29
	IbRegister,
30
	ExternalAddress,
31
	ForceSetVectExtern,
32
	BeepToggleQuiet,
33
	DivRound,
34
	GetTimeOfDay,
35
	SetTimeOfDay,
36
	AccumInt,
37
   UpdateDigit,
38
	_my_xexit,
39
   mygetcrc,
40
	 UpdateConfiguration,
41
	 TestConfiguration,
42
	 DupeConfiguration,
43
	 CorrespondingMd5,
44
    CalculateMd5,
45
    SourcePort,
46
    mid
47
48
*/
49
50
nodebug void InitializeUtility();
51
nodebug void MsDelay(int);
52
nodebug int  BitToMask(int i);
53
nodebug void StrSafeCopy(char *dst, char *src, int n);
54
nodebug char *IntUnitString3(char *s, long x, char *units);
55
nodebug char *IntUnitString(char *s, long x, char *units, int len);
56
nodebug void SeqDiag1d(char *fmt, double ts, int n1);
57
nodebug void SeqDiag2d(char *fmt, double ts, int n1, int n2);
58
nodebug void SeqDiag1s1f(char *fmt, double ts, char *s1, double f1);
59
nodebug void SeqDiag1s(char *fmt, double ts, char *s1);
60
nodebug void SeqDiag(char *fmt);
61
nodebug void SeqDiag1s1d(char *fmt, double ts, char *s1, int n1);
62
nodebug void SeqDiag1s2d(char *fmt, double ts, char *s1, int n1, int n2);
63
nodebug void SeqDiag2s1d(char *fmt, double td, char *s1, char *s2, int n1);
64
nodebug void SeqDiag1s1d1s1d(char *fmt, double td, char *s1, int n1, char *s2, int n2);
65
nodebug void SeqDiag3d(char *fmt, double ts, int n1, int n2, int n3);
66
nodebug void SeqDiagnt3d(char *fmt, int n1, int n2, int n3);
67
nodebug unsigned long ParseFloatString(char *s, int endOfNumber, unsigned long multiplier);
68
nodebug unsigned long ParseIntString(char *s, int endOfNumber);
69
nodebug void Halt();
70
nodebug void RuntimeHalt(int errorCode, int extra, int xpc, int returnAdr);
71
nodebug void SetNow();
72
nodebug Ms GetNow();
73
nodebug int  IbRegister(int bit);
74
nodebug int  ExternalAddress(int bit);
75
nodebug useix nodebug unsigned ForceSetVectExtern(int interruptNum, void *isr);
76
nodebug void BeepToggleQuiet();
77
nodebug long DivRound(long dividend, int divisor);
78
nodebug void  SetTimeOfDay (int year, int month, int day, int hour, int minute, int second);
79
nodebug void  GetTimeOfDay (struct tm *tod);
80
nodebug int  AccumInt(int code, char *aString, int aLabelStart, int aLabelEnd, int intSize);
81
nodebug void UpdateDigit(int code, char *aString, int aLabelStart, int aLabelEnd,
82
				    float aResolution, float aLowLimit, float aHighLimit, int aFast);
83
nodebug int mygetcrc(char *data, int count, int accum);
84
nodebug void trim(char *s);
85
nodebug void rtrim( char * string, char * trim );
86
nodebug void ltrim( char * string, char * trim );
87
88
/*** EndHeader */
89
90
Ms nowTime;
91
92
nodebug void stringPair(char *buffer, int len, int left, char *leftMsg, char *rightMsg, int right);
93
94
int beepQuietness;
95
96
void InitializeUtility()
97
{
98
	char aNull;
99
	printf("Init Utility ...\n");
100
	aNull = 0;
101
	beepQuietness = 0;
102
}
103
104
void MsDelay(int t)
105
{
106
	Ms now;
107
	now = (Ms)MS_TIMER;
108
	while (MS_TIMER  - now < (Ms)t);
109
}
110
111
int BitToMask(int i)
112
{
113
  int result;
114
  result = 1;
115
  result <<= i;
116
  return result;
117
}
118
119
void StrSafeCopy(char *dst, char *src, int n)
120
{
121
	strncpy(dst, src, n);
122
  dst[n] = 0;
123
}
124
125
long DivRound(long dividend, int divisor)
126
{
127
	long result;
128
	result = 0;
129
	if (divisor != 0)
130
	{
131
		result = dividend;
132
		if (result > 0) result += divisor / 2;
133
		else result -= divisor / 2;
134
		result /= divisor;
135
	}
136
	return result;
137
}
138
139
140
141
unsigned long ParseFloatString(char *s, int endOfNumber, unsigned long multiplier)
142
{
143
	int i;
144
	unsigned long result;
145
	long intPart;
146
	long fracPart;
147
	long div;
148
149
	result = 0L;
150
	div = 0;
151
	intPart = 0L;
152
	fracPart = 0L;
153
154
	for (i = 0 ; i < endOfNumber ; i++)
155
	{
156
		if (s[i] >= '0' && s[i] <=  '9')
157
		{
158
			if (div == 0)
159
			{
160
				intPart *= 10;
161
				intPart += s[i] - '0';
162
			}
163
			else
164
			{
165
				div *= 10;
166
				fracPart *= 10;
167
				fracPart += s[i] - '0';
168
			}
169
		}
170
		else if (s[i] == '.')
171
		{
172
			div = 1;
173
		}
174
	}
175
	result = intPart * multiplier;
176
	if (div != 0) result += fracPart * multiplier / div;
177
	return result;
178
}
179
180
unsigned long ParseIntString(char *s, int endOfNumber)
181
{
182
	int i;
183
	unsigned long result;
184
	long intPart;
185
186
	result = 0L;
187
	intPart = 0L;
188
189
	for (i = 0 ; i < endOfNumber ; i++)
190
	{
191
		if (s[i] >= '0' && s[i] <=  '9')
192
		{
193
			intPart *= 10;
194
			intPart += s[i] - '0';
195
		}
196
	}
197
	result = intPart;;
198
	return result;
199
}
200
201
void RuntimeHalt(int errorCode, int extra, int returnXpc, int returnAdr)
202
{
203
Ms start;
204
205
#if CRASHREBOOT == 1
206
   printf("Rebooting!!!!!\n");
207
   start = MS_TIMER;
208
   while (MS_TIMER - start < 2000);
209
   forceSoftReset();
210
#else
211
	   sprintf(ErrorMessage, "Runtime error #%d at %02x%04x", errorCode, (int)((returnXpc>>8)&0xff), returnAdr);
212
	   Halt();
213
#endif
214
}
215
216
const char flag[] = " >> ";
217
void Halt()
218
{
219
	char displayErrorMessage[DISPLAY_LENGTH_DEF];
220
	char longerErrorMessage[ERROR_MESSAGE_LENGTH + sizeof(flag)];
221
222
	int idx;
223
	int i,j;
224
	char aChar;
225
226
	idx = 0;
227
	strcpy(longerErrorMessage, flag);
228
	for (i = 0, j = strlen(longerErrorMessage) ; ErrorMessage[i] != 0 ; i++, j++)
229
	{
230
		aChar = ErrorMessage[i];
231
		if (aChar < ' ') aChar = ' ';
232
		longerErrorMessage[j] = aChar;
233
	}
234
	longerErrorMessage[j] = 0;
235
	while (!kbhit())
236
	{
237
		for (i = 0 ; i < strlen(longerErrorMessage + idx) && i < DISPLAY_LENGTH ; i++)
238
		{
239
			displayErrorMessage[i] = longerErrorMessage[idx + i];
240
		}
241
		if (i == strlen(longerErrorMessage + idx))
242
		{
243
	      for (j = 0 ; j < strlen(longerErrorMessage) && i < DISPLAY_LENGTH ; j++,i++)
244
	      {
245
	      	displayErrorMessage[i] = longerErrorMessage[j];
246
	      }
247
	   }
248
	   displayErrorMessage[i] = 0;
249
	   DisplayText(displayErrorMessage);
250
		MsDelay(150);
251
		if (++idx >= strlen(longerErrorMessage)) idx = 0;
252
	}
253
	getchar();
254
}
255
void SetNow() {nowTime = (Ms)MS_TIMER;}
256
Ms GetNow() {return nowTime;}
257
258
int IbRegister(int bit)
259
{
260
  int result;
261
  switch (bit)
262
  {
263
  case 0: result = IB0CR; break;
264
  case 1: result = IB1CR; break;
265
  case 2: result = IB2CR; break;
266
  case 3: result = IB3CR; break;
267
  case 4: result = IB4CR; break;
268
  case 5: result = IB5CR; break;
269
  case 6: result = IB6CR; break;
270
  case 7: result = IB7CR; break;
271
  }
272
  return result;
273
}
274
275
int ExternalAddress(int bit)
276
{
277
	int result;
278
	switch (bit)
279
	{
280
	case 0: result = 0x0000; break;
281
	case 1: result = 0x2000; break;
282
	case 2: result = 0x4000; break;
283
	case 3: result = 0x6000; break;
284
	case 4: result = 0x8000; break;
285
	case 5: result = 0xA000; break;
286
	case 6: result = 0xC000; break;
287
	case 7: result = 0xE000; break;
288
	}
289
	return result;
290
}
291
292
useix nodebug unsigned ForceSetVectExtern(int interruptNum, void *isr)
293
{
294
#asm
295
	; check for invalid vector number
296
	ld    de,0xfff0
297
	and   hl,de
298
	jr    z,.vecNumOK
299
	ld    hl,0
300
	push  hl
301
	jr    .done
302
.vecNumOK:
303
304
	; table entries are 16 bytes
305
	ld 	de,16
306
	ld 	hl,(ix+interruptNum)
307
	ld    b,h
308
	ld    c,l
309
	mul
310
311
	; the eir reg contains the external vectable offset/100h
312
	ld    a,eir
313
	ld    e,c
314
	ld    d,a
315
316
	add	hl, de	; hl now points to the table entry
317
318
	; put the jump instruction first
319
	ld    (hl),0xc3
320
	push  hl
321
	inc   hl
322
	ld		iy, hl
323
324
	; put the isr address next
325
	ld    hl,(ix+isr)
326
  	ld    (iy),hl
327
328
.done:
329
	; return the address of the vector table entry
330
	pop   hl
331
#endasm
332
}
333
334
//GetTimeOfDay function *****************************************************************
335
336
void GetTimeOfDay (struct tm *tod)
337
{
338
	unsigned long seconds;
339
340
	seconds = read_rtc();
341
	mktm(tod, seconds);
342
}
343
344
//SetTimeOfDay function *****************************************************************
345
346
void SetTimeOfDay (int year, int month, int day,
347
                   int hour, int minute, int second)
348
{
349
	struct tm tod;
350
	unsigned long seconds;
351
352
	tod.tm_sec  = second;
353
	tod.tm_min  = minute;
354
	tod.tm_hour = hour;
355
	tod.tm_mday = day;
356
	tod.tm_mon  = month;
357
	tod.tm_year = year - 1900;
358
	tod.tm_wday = 0;
359
360
   seconds = mktime(&tod);
361
	write_rtc(seconds);	
362
}
363
364
void stringPair(char *buffer, int len, int left, char *leftMsg, char *rightMsg, int right)
365
{
366
	int i;
367
	int pad;
368
369
	buffer[len] = 0;
370
371
	pad = len - left - right - strlen(leftMsg) - strlen(rightMsg) - 1;
372
	for (i = 0 ; (i < left) && len; i++)
373
	{
374
		*buffer++ = ' ';
375
		len--;
376
	}
377
378
	StrSafeCopy(buffer, leftMsg, len);
379
	buffer += strlen(leftMsg);
380
	len -= strlen(leftMsg);
381
382
	for (i = 0 ; (i < pad) && len; i++)
383
	{
384
		*buffer++ = ' ';
385
		len--;
386
	}
387
388
	StrSafeCopy(buffer, rightMsg, len);
389
	buffer += strlen(rightMsg);
390
	len -= strlen(rightMsg);
391
392
	for (i = 0 ; (i < right) && len ; i++)
393
	{
394
		*buffer++ = ' ';
395
		len--;
396
	}
397
398
	if (len) *buffer++ = '\n';
399
	*buffer++ = 0;
400
}
401
402
#asm root
403
_my_xexit::
404
   push   af
405
   ld      a,(dkSendFlags)
406
   set   DKF_SEND_STATUS,a
407
   set   DKF_SEND_ACK,a
408
   ld      (dkSendFlags),a
409
   ld      a,(dkStatusFlags)
410
   res   DKF_STAT_RUNMODE,a
411
   set   DKF_STAT_ATEXIT,a
412
   set   DKF_STAT_AT_BP,a
413
   ld      (dkStatusFlags),a
414
   ld      a,TC_DEBUG_ATBREAKPOINT
415
   ld      (dkAckToSend),a
416
   ld      a,(OPMODE)                     ;
417
   and   8
418
   jr      z, _xexit_skiprst20enable
419
   ld      a,0xc3
420
   ld      (INTVEC_BASE+RST20_OFS),a
421
422
_xexit_skiprst20enable:
423
   pop   af
424
425
   push	af ; +2
426
   push	bc ; +4
427
   push	de ; +6
428
   push	hl ; +8
429
   push	ix ; +10
430
   push 	iy ; +12
431
   exx
432
   push	bc ; +14
433
   push 	de ; +16
434
   push	hl ; +18
435
   ld		a,xpc
436
   push	af ; +20
437
438
	ld		hl,(sp+28) ; Return adr
439
	push	hl
440
	ld		hl,(sp+28) ; XPC
441
	push	hl
442
	ld		hl,(sp+28) ; Extra
443
	push	hl
444
	ld		hl,(sp+28) ; Error Code
445
	push	hl
446
	call	RuntimeHalt
447
	
448
	add	sp,8
449
450
	pop	af
451
	ld		xpc,a
452
   pop	hl
453
   pop	de
454
   pop	bc
455
   exx
456
   pop	iy
457
   pop	ix
458
   pop	hl
459
   pop	de
460
   pop	bc
461
   pop	af
462
   add   sp,8
463
   rst   0x20
464
   ipset 3
465
   ld    a,0x00
466
   ioi   ld (WDTTR),a
467
_xexitLoop:
468
   jr      _xexitLoop
469
#endasm
470
471
#if 0
472
int LowStack()
473
{
474
	char *ptr;
475
	int i;
476
	int result;
477
478
	result = 0;
479
	ptr = (char*)(STACKORG);
480
	for (i = 0 ; i < STACK_MONITOR_SIZE ; i++)
481
	{
482
		if (*ptr++ != STACK_FILL)
483
		{
484
			result = (int)ptr;
485
			break;
486
		}
487
	}
488
	return result;
489
}
490
#endif
491
int mmin(int x, int y)
492
{
493
	int result;
494
   result = x;
495
   if (y < x) result = y;
496
   return result;
497
}
498
499
int mygetcrc(char *data, int count, int accum)
500
{
501
	int remaining;
502
   int result;
503
   int chunk;
504
505
   remaining = count;
506
   result = accum;
507
   while (remaining)
508
   {
509
   	chunk = mmin(255, remaining);
510
		result = getcrc(data, chunk, result);
511
      remaining -= chunk;
512
      data += chunk;
513
   }
514
   return result;
515
}
516
517
// AccumInt boardrev B ***********************************************************
518
519
int AccumInt(int code, char *aString, int aLabelStart, int aLabelEnd, int intSize)
520
{
521
	int result;
522
	int i;
523
524
	int ints;
525
526
	result = 0;
527
	ints = 0;
528
529
	for (i = aLabelStart-1 ; i < aLabelEnd ; i++)
530
	{
531
		if (aString[i] >= '0' && aString[i] <= '9')
532
		{
533
			ints++;
534
		}
535
	}
536
537
	if (code >= '0' && code <= '9' || '.')
538
	{
539
		if (ints >= intSize)
540
		{
541
			result = 1;
542
		}
543
		else
544
		{
545
			for (i = aLabelStart-1 ; i < aLabelEnd - 1; i++)
546
			{
547
				aString[i] = aString[i+1];
548
			}
549
	    aString[i] = code;
550
		}
551
	}
552
	return result;
553
}
554
555
// UpdateDigit boardrev C ***********************************************************
556
557
void UpdateDigit(int code, char *aString, int aLabelStart, int aLabelEnd,
558
				    float aResolution, float aLowLimit, float aHighLimit, int aFast)
559
{
560
	int i;
561
   char chValue[6];
562
   float value;
563
   int charWidth;
564
   char chFormat[6];
565
566
   strncpy(chValue, aString+aLabelStart, aLabelEnd - aLabelStart);
567
   chValue[aLabelEnd - aLabelStart] = '\0';
568
   value = atof(chValue);
569
570
   code = code == UPPB ? 1 : -1;
571
   value += code * aResolution * aFast;
572
573
   if (value < aLowLimit)
574
   	value = aHighLimit;
575
   else if (value > aHighLimit)
576
   	value = aLowLimit;
577
   if (aLabelEnd > DISPLAY_LENGTH) aLabelEnd = DISPLAY_LENGTH;
578
   charWidth = aLabelEnd - aLabelStart;
579
   sprintf(chValue, "%d", charWidth);
580
   strcpy(chFormat,"%");
581
   strcat(chFormat,chValue);
582
   if (aResolution < 1.0)
583
   	strcat(chFormat,".1f");
584
   else
585
   	strcat(chFormat,".0f");
586
   sprintf(chValue, chFormat, value);
587
   strcpy(aString+aLabelStart, chValue);
588
}
589
590
void trim(char *s)
591
{
592
	
593
	int i;
594
  int j;
595
596
  i = 0;
597
598
	while((s[i]==' ')||(s[i]=='\t')) {
599
		i++;
600
	}
601
	if(i>0) {
602
		for(j=0;j<strlen(s);j++) {
603
			s[j]=s[j+i];
604
		}
605
	s[j]='\0';
606
	}
607
608
	
609
	i=strlen(s)-1;
610
	while((s[i]==' ')||(s[i]=='\t')) {
611
		i--;
612
	}
613
	if(i<(strlen(s)-1)) {
614
		s[i+1]='\0';
615
	}
616
}
617
618
619
void rtrim( char * string, char * trim )
620
{
621
	int i;
622
	for( i = strlen (string) - 1; i >= 0
623
	&& strchr ( trim, string[i] ) != NULL; i-- )
624
		
625
		string[i] = '\0';
626
}
627
628
void ltrim( char * string, char * trim )
629
{
630
	while ( string[0] != '\0' && strchr ( trim, string[0] ) != NULL )
631
	{
632
		memmove( &string[0], &string[1], strlen(string) );
633
	}
634
}
635
636
/*** BeginHeader */
637
#endif
638
/*** EndHeader */