← Back to dashboard

File view

plc.c

1
/*******************************************************************************
2
This is the top-level program of the ISM 3100. It is the only ".c" file in the
3
project. All the rest are .lib files.
4
5
All of the #use statements appear in this file. Ordinarily, we would wanted to
6
place #use statements inside each library which depends on another library, but
7
Dynamic C seems to be slightly less quirky when we place all of the #use
8
statements in the top-level program file, and never in the library files.
9
10
This program "#use"'s all the libraries
11
12
Project was updated and modified by Robert G. DiMaggio
13
*******************************************************************************/
14
15
// BOARDREV Descriptions
16
//	  REV A - Barrett MC REV B - Few units functioning
17
//   REV B - Barrett MC REV C - Main MC Controller
18
//   REV C - ISM-4711 REV A board
19
//   REV D - ISM-4711 REV B board
20
21
22
// System Defines *************************************************************
23
24
#memmap xmem   		// Try to put as much code in xmem as possible
25
					// By default, Dynamic C will try to fill up root code first
26
#class auto    		// Local variables on the stack
27
					// By default, Dynamic C puts local variables in the heap
28
#nointerleave  		// Compile user functions before library functions
29
					// in order to get error messages sooner
30
31
// Defines ********************************************************************
32
33
#define BOARDREV 'C'  						// See above
34
#define CRASHREBOOT 1                  		// Works with new file system
35
#define FORMAT_FS 0	                  	// Must run on first compile
36
#define RS232_ON 1                     		// RS232 COMM port for printer
37
#define PRINTER_ON 1						// Use for attached RS232 printer
38
#define MODBUS_M_ON 1                  		// Modbus RS485 Master - LDN Data
39
#define MODBUS_S_ON 0                  		// Modbus RSXXX Slave  - BAS Data
40
#define ISM4711_Default 0              		// 7-11 3 ch defaults
41
#define CV_ON 1                        		// Only works with REV C
42
#define ALARM_PER_PROD 1					// 0 = Alarm outs per channel, 1 = per product
43
#define FLOWSWITCH 0 						// Flow switch for IS inputs (bitwise 0000 4321)
44
#define FLASH_DATA 1                   		// New file system
45
#define LOGGING_ON 1                   		// Only works with PLC
46
#define DISABLE_INPUT 0						// Use auth in as disable input
47
#define RESET_ALL_INPUT 1					// Use last AC in as reset all if free
48
#define COMM_AUTH_OR 0						// Comm auth priority over AC auth
49
#define ALM_OUT_WARN 0						// Turn on alarm output for pressure warnings and alarms
50
51
#define SCH2 0								// Compiled for Seattle Children's Hospital 2
52
#define WILDCO 0							// Compited for New Hamptire Wildco
53
54
int TestWord;
55
56
// ISM Libraries ***************************************************************
57
58
#use    	"plc_constants.lib"
59
#use    	"plc_types.lib"
60
#use    	"plc_utility.lib"
61
#use    	"plc_inputs.lib"
62
#use    	"plc_outputs.lib"
63
#use    	"plc_display.lib"
64
#use		"plc_configuration.lib"
65
#use     "plc_keyboard_4711.lib"
66
#use     "plc_setup_state_4711.lib"
67
#use     "plc_date_time_4711.lib"
68
#use		"plc_elec_testing.lib"
69
#use		"plc_main_state.lib"
70
71
#if MODBUS_S_ON
72
   	#use 		"BAS_MODBUS_SLAVE.LIB"
73
	#use 		"VMI_MODBUS_SLAVE.LIB"
74
   #define  MB_SLAVE_485 0
75
#endif
76
77
#if MODBUS_M_ON
78
   	#use 		"LDN_MODBUS_MASTER.LIB"
79
	#use 		"VMI_MODBUS_MASTER.LIB"
80
#endif
81
82
#if RS232_ON
83
	#use		"plc_232_print.lib"
84
#endif
85
86
#if PRINTER_ON
87
	#undef 	RS232_ON
88
   	#define	RS232_ON 1
89
   	#use		"plc_print.lib"
90
#endif
91
92
#if LOGGING_ON
93
	#use     "plc_logging.lib"
94
#endif
95
96
#if FLASH_DATA
97
	#undef XMEM_RESERVE_SIZE
98
   #define XMEM_RESERVE_SIZE        0xE000L   	// (57,344 b) Leaves 200 kb for max program size
99
   #define FS2_USE_PROGRAM_FLASH 	56  	    // KB -> XMEM_RESERVE_SIZE / 1024
100
	#use "FS2.LIB"
101
#endif
102
103
#if WILDCO
104
	#undef  ALM_OUT_WARN
105
   #define ALM_OUT_WARN 1
106
   #undef  CV_ON
107
   #define CV_ON 1
108
   #undef  ALARM_PER_PROD
109
   #define ALARM_PER_PROD 1
110
#endif
111
112
#if SCH2
113
	#undef  RS232_ON
114
	#define RS232_ON 0
115
	#undef  PRINTER_ON
116
	#define PRINTER_ON 0
117
	#undef  MODBUS_S_ON
118
	#define MODBUS_S_ON 1
119
	#undef  CV_ON
120
	#define CV_ON 1
121
	#undef  ALARM_PER_PROD
122
	#define ALARM_PER_PROD 0
123
	#undef  FLOWSWITCH
124
	#define FLOWSWITCH 1
125
	#undef  LOGGING_ON
126
	#define LOGGING_ON 0
127
#endif
128
129
// Version *********************************************************************
130
#define 	MAJOR_VERSION "5"
131
#define 	MINOR_VERSION "04"
132
#define 	VERSION_STATUS VERSION_STATUS_PRODUCTION
133
#define 	VERSION_STRING_MAX_LENGTH 16
134
135
// this will output debug info on serial port a at 115200 baud
136
#define	STDIO_DEBUG_SERIAL		SADR
137
#define	STDIO_DEBUG_BAUD		115200
138
#define	STDIO_DEBUG_ADDCR
139
140
// Flash file system setup *****************************************************
141
#if FLASH_DATA
142
   #define CONFIG_FILE 			1
143
#endif
144
145
// Logging Setup ***************************************************************
146
#if LOGGING_ON
147
	#define LOG_FILE		2
148
#endif
149
150
// ModBus Setup *************************************************************
151
#if MODBUS_S_ON
152
   #undef  MODBUS_DEBUG_PRINT
153
   #define MODBUS_DEBUG_PRINT 0x000       	//0x800 To display hex bites
154
   #undef  MODBUS_SLAVE_DEBUG_PRINT
155
   #define MODBUS_SLAVE_DEBUG_PRINT 0x000    //0x800 To display hex bites
156
   #ifndef USE_MODBUS_CRC
157
   #define USE_MODBUS_CRC
158
   #endif
159
#endif
160
161
// Function Prototypes *********************************************************
162
void  Initialize		(void);              // Initialize the program
163
void  CycleChannels		(void);					// State machine
164
void  ChannelSetup		(void);					// Setup product and channel structure
165
void  LoopStats  		(void);
166
char *VersionString  	(void);
167
#if MODBUS_S_ON
168
	void  CommStatusTick	(void);
169
#endif
170
171
// Main data structures ********************************************************
172
configStruct 			Config;
173
channelStruct  			Channel		[N_ISM];
174
productStruct  			Product		[N_PROD];
175
ldnStruct				LDNS		[N_LDN];
176
TimeStatSt				CycStat		[CYCLE_COUNTERS];
177
displayStruct  			Disp;
178
179
// Global Variables ***********************************************************
180
root void _my_xexit();
181
const char blank[2] = "";
182
183
char  		verString				[VERSION_STRING_MAX_LENGTH + 1];
184
char 		ErrorMessage			[ERROR_MESSAGE_LENGTH      + 1];
185
int 		outputWord;
186
int 		inputWord;
187
188
// Board Rev setup *************************************************************
189
const char my_id[]="PLC-5201";
190
191
/******************************************************************
192
 * 			Function Name:
193
 *
194
 *
195
 * 		Args / Parameters:
196
 *
197
 *
198
 * 		Description:
199
 *
200
 *
201
 * 		Returns:
202
 *
203
 */
204
int main()
205
{
206
	clockDoublerOn();
207
	Initialize();
208
	MsDelay(2000);
209
210
	// Main Program Loop
211
	while (1)
212
	{
213
214
		LoopStats();
215
216
	   	#if MODBUS_S_ON
217
	      MODBUS_Slave_Serial_tick();
218
	   	#endif
219
220
	   	#if MODBUS_M_ON
221
	      MODBUS_Master_tick();
222
	   	#endif
223
224
	   	SetNow();
225
	  	KeyboardScan();
226
	   	InputRegScan();
227
	   	MenuState();
228
	   	InputHandler();
229
	   	CycleChannels();
230
	   	WriteOutputs();
231
	   	DisplayState();
232
233
		#if MODBUS_S_ON
234
	   	CommStatusTick();
235
		#endif
236
237
	   #if PRINTER_ON
238
	      HandlePrint();
239
	   #endif
240
	}
241
}
242
243
/******************************************************************
244
 * 			Function Name:
245
 *
246
 *
247
 * 		Args / Parameters:
248
 *
249
 *
250
 * 		Description:
251
 *
252
 *
253
 * 		Returns:
254
 *
255
 */
256
void Initialize(void)
257
{
258
	uint8_t i;
259
	int result;
260
   	int clearChordDetected;
261
   	EventSt BootEvent;
262
263
	BootEvent.LogType	= SYST_LOG;;
264
	BootEvent.Code		= REBOOT;
265
	BootEvent.Status	= ALM_CLOSED;
266
	BootEvent.Notes		= 0;
267
	BootEvent.Time		= 0;
268
	BootEvent.Rate		= 0;
269
	BootEvent.Product	= 0;
270
	BootEvent.Channel	= 0;
271
272
	// Init Stat Counters
273
	for (i = 0 ; i < CYCLE_COUNTERS ; i++)
274
	{
275
		CycStat[i].LastPass		= MS_TIMER;
276
		CycStat[i].LastCycle		= MS_TIMER;
277
		CycStat[i].MaxMs			= 0;
278
		CycStat[i].AvgMs			= 0;
279
	}
280
281
	result = 0;
282
   #if FLASH_DATA
283
   	result += InitFileSystem();
284
   #endif
285
286
   #if FORMAT_FS
287
   	result += ClearConfig();
288
   #endif
289
290
   InitializeKbd(KEYSOURCE_BOTH);
291
   TestChord(&clearChordDetected);
292
   if (clearChordDetected)
293
   {
294
      result += ClearConfig();
295
	}
296
297
   printf("Initializing Structures\n");
298
   InitConfig();
299
300
   for (i = 0 ; i < N_PROD ; i++)
301
   {
302
      InitProduct(i);
303
   }
304
305
   for (i = 0 ; i < N_ISM  ; i++)
306
   {
307
      InitChannel(i);
308
   }
309
310
   	LDN_MASTER_Init();
311
312
	result = GetConfig();
313
314
   for (i = 0 ; i < N_PROD ; i++)
315
   {
316
      Product[i].Authorize = 0;
317
   }
318
   for (i = 0 ; i < N_INPUTS ; i++)
319
   {
320
      Config.Sump.Status[i] = 0;
321
   }
322
323
	Config.MenuFlag 			= 0;
324
	Config.AlarmSilenceFlag 	= 0;
325
	Config.TestCnl 				= -1;
326
	Config.ViewCnl 				= -1;
327
   	Config.TestMode 			= 0;
328
	Config.DspInputStatus 		= 0;
329
	Config.DspNetworkStatus 	= 0;
330
331
	printf("%s %s \n", PRODUCT_NAME_STRING, VersionString());
332
	printf("Compiled for board rev: %c \n" , BOARDREV);
333
334
   	printf("Init Port ...\n");
335
   	WrPortI (PDDDR, &PDDDRShadow, 0xDF);
336
	WrPortI (PDDR,  &PDDRShadow,  0x00);
337
   	WrPortI (PEDR,  &PEDRShadow,  0x07);
338
339
   	InitializeUtility		();
340
	InitializeInputs		();
341
	InitializeOutputs		();
342
	InitializeDisplay		(0);
343
	DisplayMsgCtr			(PRODUCT_NAME_STRING, VersionString());
344
	InitializeLogs			(BatteryNotOK());
345
	defineErrorHandler	(_my_xexit);
346
347
   #if RS232_ON
348
   		Initialize232 ();
349
   #endif
350
   #if PRINTER_ON
351
	   InitializePrint ();
352
	#endif
353
   #if MODBUS_S_ON
354
		BAS_SLAVE_Init ();
355
   #endif
356
   #if MODBUS_M_ON
357
   	result = MODBUS_Master_Serial_Init ();
358
   #endif
359
360
   if (CheckConfig())
361
   {
362
	   printf("Site Config ok\n");
363
	   Config.SiteConfigFlag = 1;
364
	   Disp.UpdateFlag 	    = 1;
365
	   ChannelSetup();
366
      #if LOGGING_ON
367
	  {
368
      		BootEvent.Time		= SEC_TIMER;
369
	      	AddLogEvent(&BootEvent);
370
	  }
371
	   #endif
372
      #if MODBUS_S_ON
373
   		SetAlarmReg(SYSTEM_NOT_CONFIG, 0, 0, 0);
374
      #endif
375
	}
376
	else
377
	{
378
	   printf("No Site Config \n");
379
	   Config.SiteConfigFlag = 0;
380
	   Disp.UpdateFlag 		 = 0;
381
      result = ClearConfig();
382
      #if MODBUS_S_ON
383
          SetAlarmReg(SYSTEM_NOT_CONFIG, 0, 0, 1);
384
      #endif
385
	}
386
}
387
388
/******************************************************************
389
 * 			Function Name:
390
 *
391
 *
392
 * 		Args / Parameters:
393
 *
394
 *
395
 * 		Description:
396
 *
397
 *
398
 *
399
 * 		Returns:
400
 *
401
 */
402
void CycleChannels(void)
403
{
404
	int i;
405
  	int j;
406
  	int PreviousChannel;
407
  	int result;
408
  	int N_InAuth;
409
410
  	PreviousChannel = 0;
411
412
  	if (Config.SiteConfigFlag)
413
  	{
414
		if (Config.TestCnl > -1)
415
      	MainStateHandler(&Channel[Config.TestCnl]);
416
	  	for (i = 0 ; i < Config.N_Products ; i++)
417
	  	{
418
	    	result 	= 0;
419
	    	N_InAuth = 0;
420
	    	j = Product[i].LeadTurbine;
421
422
	    	if (Product[i].Authorize)
423
	    	{
424
				Channel[j].Authorize = ON;
425
				N_InAuth = 1;
426
	    	}
427
	   		else
428
		   {
429
	    		Channel[j].Authorize = OFF;
430
		   }
431
432
	    	MainStateHandler(&Channel[j]);
433
	    	result |= (!Channel[j].PresAlmFlag && !Channel[j].SumpAlmFlag &&
434
	         		   Channel[j].RdyFlag && !Channel[j].NeverLeadFlag);
435
436
	    	PreviousChannel = j;
437
	    	j = Channel[j].NextStage;
438
439
       	while (j != Product[i].LeadTurbine)
440
	    	{
441
				if ((Product[i].Authorize > N_InAuth) && Channel[PreviousChannel].RdyFlag &&
442
						!Channel[j].NeverLeadFlag)
443
				{
444
						Channel[j].Authorize = ON;
445
						N_InAuth++;
446
				}
447
				else if (Channel[j].NeverLeadFlag && Channel[PreviousChannel].RdyFlag &&
448
						(Product[i].Authorize > N_InAuth) && result)
449
				{
450
						Channel[j].Authorize = ON;
451
						N_InAuth++;
452
				}
453
				else
454
				{
455
					Channel[j].Authorize = OFF;
456
				}
457
458
				MainStateHandler(&Channel[j]);
459
460
				result |= (!Channel[j].PresAlmFlag && !Channel[j].SumpAlmFlag &&
461
							Channel[j].RdyFlag && !Channel[j].NeverLeadFlag);
462
463
				PreviousChannel = j;
464
				j = Channel[j].NextStage;
465
	   		}
466
		}
467
	}
468
}
469
470
/******************************************************************
471
 * 			Function Name:
472
 *
473
 *
474
 * 		Args / Parameters:
475
 *
476
 *
477
 * 		Description:
478
 *
479
 *
480
 * 		Returns:
481
 *
482
 */
483
void ChannelSetup(void)
484
{
485
	int i;
486
  	int j;
487
  	int EndTurbine;
488
   int SensorCh;
489
   int CVPos;
490
491
   for (i = 0 ; i < N_ISM  ; i++)
492
      InitChannel(i);
493
494
   for (i = 0 ; i < N_PROD ; i++)
495
   	Product[i].Authorize = 0;
496
497
   #if MODBUS_M_ON
498
		LDN_MASTER_Init();
499
	#endif
500
501
	i 					= 0;
502
	j 					= 0;
503
	Config.N_Turbines 	= 0;
504
   	Config.N_CVs 		= 0;
505
   	Config.N_PS 		= 0;
506
   	SensorCh 			= 0;
507
   	CVPos				= CV_OFFSET;
508
509
	while (i < N_PROD)
510
	{
511
	   if (Product[i].N_Turbines != 0)
512
	   {
513
	      if (Product[i].ResilVal 	 < 0 || Product[i].ResilVal    > 9999)
514
		  {
515
	        	Product[i].ResilVal 		= DEFAULT_RESIL;
516
		  }
517
518
	      if (Product[i].RunPressure  < 0 || Product[i].RunPressure  > 100)
519
		  {
520
	          Product[i].RunPressure 	= DEFAULT_HIGH_PRES;
521
		  }
522
523
	      if (Product[i].HighPressure < 0 || Product[i].HighPressure > 100)
524
		  {
525
	        	 Product[i].HighPressure 	= DEFAULT_HIGH_PRES;
526
		  }
527
528
	      if (Product[i].LowPressure  < 0 || Product[i].LowPressure  > Product[i].HighPressure)
529
		  {
530
	      	 Product[i].LowPressure 	= Product[i].HighPressure - DEFAULT_DELTA;
531
		  }
532
533
	      Config.N_Products 				= i + 1;
534
	      if (Product[i].CV.DCV + Product[i].CV.SCV + Product[i].CV.PCV  > Product[i].N_Turbines)
535
		  {
536
	          Product[i].N_Turbines 		= Product[i].CV.DCV + Product[i].CV.SCV + Product[i].CV.PCV;
537
		  }
538
	      Config.N_Turbines 			  += Product[i].N_Turbines;
539
540
	      if (Product[i].N_LeadTurbines < 1 || Product[i].N_LeadTurbines > Product[i].N_Turbines)
541
		  {
542
	          Product[i].N_LeadTurbines = Product[i].N_Turbines;
543
		  }
544
545
	      if (Product[i].N_RunTurbines  < 1 || Product[i].N_RunTurbines  > Product[i].N_Turbines)
546
		  {
547
	          Product[i].N_RunTurbines  = Product[i].N_Turbines;
548
		  }
549
550
	      Config.N_PS 					  += Product[i].N_PistonSwitches;
551
552
	      Product[i].FirstTurbine 			= j;
553
	      Product[i].LeadTurbine 			= j;
554
	      Product[i].CV.scvIOChannel 		= CVPos;
555
	      Product[i].CV.pcvIOChannel		= Product[i].CV.SCV + Product[i].CV.scvIOChannel;
556
	      Product[i].CV.dcvIOChannel		= Product[i].CV.PCV + Product[i].CV.pcvIOChannel;
557
	      CVPos 		 					= Product[i].CV.DCV + Product[i].CV.dcvIOChannel;
558
	      Config.N_CVs 					  	+= Product[i].CV.SCV;
559
	      Config.N_CVs					  	+= Product[i].CV.PCV;
560
	      Config.N_CVs					  	+= Product[i].CV.DCV;
561
	      Product[i].CV.firstAuthFlag 		= 0;
562
	      Product[i].CV.authStart 			= 0;
563
	      Product[i].RePresCount 			= 0;
564
	      Product[i].FilterFlag 			= 0;
565
	      Product[i].CheckPres 				= 0;
566
	      Product[i].ReturnFuel 			= 0;
567
	      Product[i].CheckTime 				= MS_TIMER;
568
	      EndTurbine = Product[i].N_Turbines + Product[i].FirstTurbine - 1;
569
570
	      while (j <= EndTurbine)
571
		  {
572
	       	Channel[j].ProductID 		= i + 1;
573
	       	Channel[j].Prod 				= &Product[i];
574
575
	         if (j == EndTurbine)
576
			 {
577
	            Channel[j].NextStage 	= Product[i].FirstTurbine;
578
			 }
579
580
	         else
581
			 {
582
	            Channel[j].NextStage 	= j+1;
583
			 }
584
585
	         if (j < Product[i].FirstTurbine + Product[i].N_LeadTurbines)
586
			{
587
	            Channel[j].NeverLeadFlag = OFF;
588
589
               if (j < Product[i].FirstTurbine + Product[i].N_PistonSwitches)
590
			   {
591
               	Channel[j].IOPS 		 = SensorCh;
592
            		SensorCh++;
593
               }
594
               else
595
               	Channel[j].IOPS 		= Channel[j-1].IOPS;
596
            }
597
            else
598
			{
599
	            Channel[j].NeverLeadFlag = ON;
600
               	Channel[j].IOPS 			 = Channel[j-1].IOPS;
601
            }
602
603
            Channel[j].LDN 				= &LDNS[Channel[j].IOPS];
604
            Channel[j].LDN->Active 		= 1;
605
606
	         if (!Channel[j].LeadFlag)
607
			 {
608
	            Channel[j].LeadFlag 		= OFF;
609
			 }
610
611
            Channel[j].StartTime 		= SEC_TIMER;
612
	        Channel[j].PreviousState 	= -1;
613
	        Channel[j].OnDly 				= Product[i].CV.OnDly;
614
	        Channel[j].OffDly 			= Product[i].CV.OffDly;
615
            Channel[j].ResilVal 			= Product[i].ResilVal;
616
            Channel[j].RunPressure 		= Product[i].RunPressure;
617
            Channel[j].HighPressure 	= Product[i].HighPressure;
618
            Channel[j].LowPressure 		= Product[i].LowPressure;
619
620
            if (j == Product[i].FirstTurbine)
621
			{
622
	            Channel[j].State 			= 0;
623
	            Channel[j].LeadFlag 		= 1;
624
				Channel[j].Turbine 	= 0;
625
	         }
626
	         else
627
			 {
628
               	Channel[j].ResetPbFlag 		= 0;
629
	            Channel[j].LeadFlag 		= 0;
630
	         }
631
	         j++;
632
         }
633
	   }
634
		i++;
635
	}
636
637
638
	for (i = 0 ; i < N_ISM ; i++)
639
	{
640
	   if ((Channel[i].DurationTime > 99.9 * 60 || Channel[i].DurationTime < 0) ||
641
	       (Channel[i].DelayTime    > 99.9 * 60 || Channel[i].DelayTime    < 0))
642
		{
643
	      Channel[i].DurationTime = DEFAULT_RUN;
644
	      Channel[i].DelayTime 	= DEFAULT_DELAY;
645
	    }
646
  	}
647
648
	if (CheckConfig())
649
	{
650
  		Config.SiteConfigFlag = 1;
651
      	SetTestWord();
652
      	printf("Site Config Complete\n");
653
    }
654
   else
655
   {
656
  		Config.SiteConfigFlag = 0;
657
      	ClearConfig();
658
      	printf("Site Config Incomplete\n");
659
   }
660
661
  	Config.TestCnl 	= -1;
662
  	Config.UpdateFlag =  1;
663
}
664
665
/******************************************************************
666
 * 			Function Name:
667
 *
668
 *
669
 * 		Args / Parameters:
670
 *
671
 *
672
 * 		Description:
673
 *
674
 *
675
 * 		Returns:
676
 *
677
 */
678
void LoopStats(void)
679
{
680
681
   if (CycStat[0].MaxMs < MS_TIMER - CycStat[0].LastPass)
682
   {
683
       CycStat[0].MaxMs = MS_TIMER - CycStat[0].LastPass;
684
   }
685
   if (CycStat[0].AvgMs == 0.0)
686
   {
687
       CycStat[0].AvgMs = (float)(MS_TIMER - CycStat[0].LastPass);
688
   }
689
   else
690
   {
691
   		CycStat[0].AvgMs = (CycStat[0].AvgMs + (float)(MS_TIMER - CycStat[0].LastPass)) / 2.0;
692
		CycStat[0].LastPass  = MS_TIMER;
693
   }
694
695
	if (MS_TIMER - CycStat[0].LastCycle >= DEBUG_POST_TIME)
696
	{
697
		printf("%9.4f: ", (float)MS_TIMER / 1000.0 / 60.0);
698
		printf("ML %4.1f / %6.1f ms", CycStat[0].AvgMs, (float)CycStat[0].MaxMs);
699
		if (Config.SiteConfigFlag)
700
		{
701
			printf(" | MB %4.1f / %6.1f ms\n", CycStat[1].AvgMs, (float)CycStat[1].MaxMs);
702
		}
703
		else
704
		{
705
			printf("\n");
706
		}
707
      	CycStat[0].LastCycle    = MS_TIMER;
708
      	CycStat[0].AvgMs			= 0.0;
709
      	CycStat[0].MaxMs        = 0;
710
      	CycStat[1].AvgMs			= 0.0;
711
      	CycStat[1].MaxMs        = 0;
712
	}
713
}
714
715
/******************************************************************
716
 * 			Function Name:
717
 *
718
 *
719
 * 		Args / Parameters:
720
 *
721
 *
722
 * 		Description:
723
 *
724
 *
725
 * 		Returns:
726
 *
727
 */
728
char *VersionString(void)
729
{
730
	char *result;
731
732
	memset(verString, 0, VERSION_STRING_MAX_LENGTH + 1);
733
734
	if (strlen(VERSION_PREAMBLE) + strlen(MAJOR_VERSION) + strlen(".") +
735
			strlen(MINOR_VERSION) + strlen(VERSION_STATUS) <= VERSION_STRING_MAX_LENGTH)
736
	{
737
		strcat(verString, VERSION_PREAMBLE);
738
		strcat(verString, MAJOR_VERSION);
739
		strcat(verString, ".");
740
		strcat(verString, MINOR_VERSION);
741
		strcat(verString, VERSION_STATUS);
742
	}
743
	return verString;
744
}
745
746
/******************************************************************
747
 * 			Function Name:
748
 *
749
 *
750
 * 		Args / Parameters:
751
 *
752
 *
753
 * 		Description:
754
 *
755
 *
756
 * 		Returns:
757
 *
758
 */
759
#if MODBUS_S_ON
760
	// Comm Status update tick *****************************************************
761
	void CommStatusTick(void) {
762
	   int i;
763
	   int leadCh;
764
765
	   for (i=0 ; i < Config.N_Products ; i++)
766
	   {
767
	      	leadCh = Product[i].LeadTurbine;
768
	        SetStatusReg(PROD_PRES, i, 0, (int)(Channel[leadCh].LDNPressure * 10));
769
	        SetStatusReg(FILTER_ACTIVE, i, 0, Product[i].FilterFlag);
770
	        if (Channel[leadCh].State == 6)
771
	            SetStatusReg(PLC_STATE, i, 0, COMM_REPRESSURE);
772
	        else if (Channel[leadCh].State == 1 ||
773
	                  Channel[leadCh].State == 2 ||
774
	                  Channel[leadCh].State == 3)
775
	            SetStatusReg(PLC_STATE, i, 0, COMM_DISPENSE);
776
	        else if (Channel[leadCh].State == 5 ||
777
	                  Channel[leadCh].State == 23)
778
	            SetStatusReg(PLC_STATE, i, 0, COMM_ALARM);
779
	        else if (Channel[leadCh].State == 4)
780
	            SetStatusReg(PLC_STATE, i, 0, COMM_VENT);
781
	        else if (Channel[leadCh].State >= 7 && Channel[leadCh].State <= 22)
782
	            SetStatusReg(PLC_STATE, i, 0, COMM_TEST);
783
	        else if (Channel[leadCh].State == 24)
784
	            SetStatusReg(PLC_STATE, i, 0, COMM_FILTER);
785
	        else
786
	            SetStatusReg(PLC_STATE, i, 0, COMM_IDLE);
787
	   }
788
	}
789
#endif