aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Xml/AXmlContainer.cs
blob: 3cc716de50bed7056ec579a5d6097f80fc2b5e3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;

using Tango.Scripting.Editors.Document;

namespace Tango.Scripting.Editors.Xml
{
	/// <summary>
	/// Abstact base class for all types that can contain child nodes
	/// </summary>
	public abstract class AXmlContainer: AXmlObject
	{
		/// <summary>
		/// Children of the node.  It is read-only.
		/// Note that is has CollectionChanged event.
		/// </summary>
		public AXmlObjectCollection<AXmlObject> Children { get; private set; }
		
		/// <summary> Create new container </summary>
		protected  AXmlContainer()
		{
			this.Children = new AXmlObjectCollection<AXmlObject>();
		}
		
		#region Helpper methods
		
		ObservableCollection<AXmlElement> elements;
		
		/// <summary> Gets direcly nested elements (non-recursive) </summary>
		public ObservableCollection<AXmlElement> Elements {
			get {
				if (elements == null) {
					elements = new FilteredCollection<AXmlElement, AXmlObjectCollection<AXmlObject>>(this.Children);
				}
				return elements;
			}
		}
		
		internal AXmlObject FirstChild {
			get {
				return this.Children[0];
			}
		}
		
		internal AXmlObject LastChild {
			get {
				return this.Children[this.Children.Count - 1];
			}
		}
		
		#endregion
		
		/// <inheritdoc/>
		public override IEnumerable<AXmlObject> GetSelfAndAllChildren()
		{
			return (new AXmlObject[] { this }).Flatten(
				delegate(AXmlObject i) {
					AXmlContainer container = i as AXmlContainer;
					if (container != null)
						return container.Children;
					else
						return null;
				}
			);
		}
		
		/// <summary>
		/// Gets a child fully containg the given offset.
		/// Goes recursively down the tree.
		/// Specail case if at the end of attribute or text
		/// </summary>
		public AXmlObject GetChildAtOffset(int offset)
		{
			foreach(AXmlObject child in this.Children) {
				if ((child is AXmlAttribute || child is AXmlText) && offset == child.EndOffset) return child;
				if (child.StartOffset < offset && offset < child.EndOffset) {
					AXmlContainer container = child as AXmlContainer;
					if (container != null) {
						return container.GetChildAtOffset(offset);
					} else {
						return child;
					}
				}
			}
			return this; // No childs at offset
		}
		
		// Only these four methods should be used to modify the collection
		
		/// <summary> To be used exlucively by the parser </summary>
		internal void AddChild(AXmlObject item)
		{
			// Childs can be only added to newly parsed items
			Assert(this.Parent == null, "I have to be new");
			Assert(item.IsCached, "Added item must be in cache");
			// Do not set parent pointer
			this.Children.InsertItemAt(this.Children.Count, item);
		}
		
		/// <summary> To be used exlucively by the parser </summary>
		internal void AddChildren(IEnumerable<AXmlObject> items)
		{
			// Childs can be only added to newly parsed items
			Assert(this.Parent == null, "I have to be new");
			// Do not set parent pointer
			this.Children.InsertItemsAt(this.Children.Count, items.ToList());
		}
		
		/// <summary>
		/// To be used exclusively by the children update algorithm.
		/// Insert child and keep links consistent.
		/// </summary>
		void InsertChild(int index, AXmlObject item)
		{
			AXmlParser.Log("Inserting {0} at index {1}", item, index);
			
			Assert(this.Document != null, "Can not insert to dangling object");
			Assert(item.Parent != this, "Can not own item twice");
			
			SetParentPointersInTree(item);
			
			this.Children.InsertItemAt(index, item);
			
			this.Document.OnObjectInserted(index, item);
		}
		
		/// <summary> Recursively fix all parent pointer in a tree </summary>
		/// <remarks>
		/// Cache constraint:
		///    If cached item has parent set, then the whole subtree must be consistent and document set
		/// </remarks>
		void SetParentPointersInTree(AXmlObject item)
		{
			// All items come from the parser cache
			
			if (item.Parent == null) {
				// Dangling object - either a new parser object or removed tree (still cached)
				item.Parent = this;
				item.Document = this.Document;
				AXmlContainer container = item as AXmlContainer;
				if (container != null) {
					foreach(AXmlObject child in container.Children) {
						container.SetParentPointersInTree(child);
					}
				}
			} else if (item.Parent == this) {
				// If node is attached and then deattached, it will have null parent pointer
				//   but valid subtree - so its children will alredy have correct parent pointer
				//   like in this case
				// item.DebugCheckConsistency(false);
				// Rest of the tree is consistent - do not recurse
			} else {
				// From cache & parent set => consitent subtree
				// item.DebugCheckConsistency(false);
				// The parent (or any futher parents) can not be part of parsed document
				//   becuase otherwise this item would be included twice => safe to change parents
				// Maintain cache constraint by setting parents to null
				foreach(AXmlObject ancest in item.GetAncestors().ToList()) {
					ancest.Parent = null;
				}
				item.Parent = this;
				// Rest of the tree is consistent - do not recurse
			}
		}
		
		/// <summary>
		/// To be used exclusively by the children update algorithm.
		/// Remove child, set parent to null and notify the document
		/// </summary>
		void RemoveChild(int index)
		{
			AXmlObject removed = this.Children[index];
			AXmlParser.Log("Removing {0} at index {1}", removed, index);
			
			// Stop tracking if the object can not be used again
			if (!removed.IsCached)
				this.Document.Parser.TrackedSegments.RemoveParsedObject(removed);
			
			// Null parent pointer
			Assert(removed.Parent == this, "Inconsistent child");
			removed.Parent = null;
			
			this.Children.RemoveItemAt(index);
			
			this.Document.OnObjectRemoved(index, removed);
		}
		
		/// <summary> Verify that the subtree is consistent.  Only in debug build. </summary>
		/// <remarks> Parent pointers might be null or pointing somewhere else in parse tree </remarks>
		internal override void DebugCheckConsistency(bool checkParentPointers)
		{
			base.DebugCheckConsistency(checkParentPointers);
			AXmlObject prevChild = null;
			int myStartOffset = this.StartOffset;
			int myEndOffset = this.EndOffset;
			foreach(AXmlObject child in this.Children) {
				Assert(child.Length != 0, "Empty child");
				if (checkParentPointers) {
					Assert(child.Parent != null, "Null parent reference");
					Assert(child.Parent == this, "Inccorect parent reference");
				}
				if (this.Document != null) {
					Assert(child.Document != null, "Child has null document");
					Assert(child.Document == this.Document, "Child is in different document");
				}
				if (this.IsCached)
					Assert(child.IsCached, "Child not in cache");
				Assert(myStartOffset <= child.StartOffset && child.EndOffset <= myEndOffset, "Child not within parent text range");
				if (prevChild != null)
					Assert(prevChild.EndOffset <= child.StartOffset, "Overlaping childs");
				child.DebugCheckConsistency(checkParentPointers);
				prevChild = child;
			}
		}
		
		/// <remarks>
		/// Note the the method is not called recuively.
		/// Only the helper methods are recursive.
		/// </remarks>
		internal void UpdateTreeFrom(AXmlContainer srcContainer)
		{
			this.StartOffset = srcContainer.StartOffset; // Force the update
			this.UpdateDataFrom(srcContainer);
			RemoveChildrenNotIn(srcContainer.Children);
			InsertAndUpdateChildrenFrom(srcContainer.Children);
		}
		
		void RemoveChildrenNotIn(IList<AXmlObject> srcList)
		{
			Dictionary<int, AXmlObject> srcChildren = srcList.ToDictionary(i => i.StartOffset);
			for(int i = 0; i < this.Children.Count;) {
				AXmlObject child = this.Children[i];
				AXmlObject srcChild;
				
				if (srcChildren.TryGetValue(child.StartOffset, out srcChild) && child.CanUpdateDataFrom(srcChild)) {
					// Keep only one item with given offset (we might have several due to deletion)
					srcChildren.Remove(child.StartOffset);
					// If contaner that needs updating
					AXmlContainer childAsContainer = child as AXmlContainer;
					if (childAsContainer != null && child.LastUpdatedFrom != srcChild)
						childAsContainer.RemoveChildrenNotIn(((AXmlContainer)srcChild).Children);
					i++;
				} else {
					RemoveChild(i);
				}
			}
		}
		
		void InsertAndUpdateChildrenFrom(IList<AXmlObject> srcList)
		{
			for(int i = 0; i < srcList.Count; i++) {
				// End of our list?
				if (i == this.Children.Count) {
					InsertChild(i, srcList[i]);
					continue;
				}
				AXmlObject child = this.Children[i];
				AXmlObject srcChild = srcList[i];
				
				if (child.CanUpdateDataFrom(srcChild)) { // includes offset test
					// Does it need updating?
					if (child.LastUpdatedFrom != srcChild) {
						child.UpdateDataFrom(srcChild);
						AXmlContainer childAsContainer = child as AXmlContainer;
						if (childAsContainer != null)
							childAsContainer.InsertAndUpdateChildrenFrom(((AXmlContainer)srcChild).Children);
					}
				} else {
					InsertChild(i, srcChild);
				}
			}
			Assert(this.Children.Count == srcList.Count, "List lengths differ after update");
		}
	}
}
imerIntEnable(Millisec_timerBase, TIMER_TIMA_TIMEOUT); ADCAcquireStart(0,1); } void OneMilliSecondMillisecInterrupt(UArg arg0) { MillisecMessageStruc MillisecMessage; uint32_t Tenmsec_millisecondCounter = 0; #ifndef HUNDRED_MICROSECONDS_DANCER_READ ROM_IntMasterDisable(); ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt if (MillisecRestart == true) { ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,HIGH_TASK_FREQUENCY); } else { ROM_TimerDisable(Millisec_timerBase,TIMER_A); ROM_IntMasterEnable(); return; } #endif if (msec_millisecondCounter%10 == 0) { Tenmsec_millisecondCounter = msec_millisecondCounter; } //send message to the Millisec task MillisecMessage.messageId = OneMillisec; MillisecMessage.tick = msec_millisecondCounter++; MillisecMessage.msglen = sizeof(MillisecMessageStruc); if (MillisecMsgQ != NULL) Mailbox_post(MillisecMsgQ , &MillisecMessage, BIOS_NO_WAIT); if (Tenmsec_millisecondCounter) { MillisecMessage.messageId = OneMillisec; MillisecMessage.tick = Tenmsec_millisecondCounter; MillisecMessage.msglen = sizeof(MillisecMessageStruc); if (TenMillisecMsgQ != NULL) Mailbox_post(TenMillisecMsgQ , &MillisecMessage, BIOS_NO_WAIT); } // // Enable all interrupts. // ROM_IntMasterEnable(); return ; } uint32_t PT100Activity = 0; int32_t MillisecReadFromTempSensor(uint32_t TempSensorId, MSecFptr Callback) { if (TempSensorId >= MAX_MAIN_CARD_TEMP_SENS_ID) return -1; PT100Activity++; //read request PT100Data[TempSensorId].Callback = Callback; PT100Data[TempSensorId].Active = true; return OK; } //typedef uint32_t (* MSecFptr)(uint32_t deviceID, uint32_t ReadValue); uint32_t MotorActivity = 0; int32_t MillisecSetMotorSpeed(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { if (MotorId >= NUM_OF_MOTORS) return -1; //========================== if ((MotorId == HARDWARE_MOTOR_TYPE__MOTO_WINDER)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_RDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_LDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_SCREW)) { MSBacklog[MsecLogindex]=Data; MSTick[MsecLogindex]=msec_millisecondCounter; Motor_Id[MsecLogindex]=MotorId; MsecLogindex++; if (MsecLogindex>=LOG_SIZE) MsecLogindex = 0; } //========================== SpeedSetPending[MotorId].Callback = Callback; SpeedSetPending[MotorId].Data = Data; SpeedSetPending[MotorId].Length = Length; SpeedSetPending[MotorId].DataRequired = false; if (SpeedSetPending[MotorId].Active == false) { MotorActivity++; SpeedSetPending[MotorId].Active = true; } return OK; } int MillisecFlushMsgQ(TimerMotors_t MotorId) { MillisecMotorDataStruc MotorInfo = {0}; int pend = Mailbox_getNumPendingMsgs(MotorsMsgQ[MotorId]); int i; if (pend) { for (i=0;i<pend;i++) Mailbox_pend(MotorsMsgQ[MotorId] , &MotorInfo, BIOS_NO_WAIT); } return pend; } int32_t MillisecWriteToMotor(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { MillisecMotorDataStruc MotorInfo = {0}; //========================== if ((MotorId == HARDWARE_MOTOR_TYPE__MOTO_WINDER)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_RDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_LDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_SCREW)) { MSBacklog[MsecLogindex]=Data; MSTick[MsecLogindex]=msec_millisecondCounter; Motor_Id[MsecLogindex]=MotorId; MsecLogindex++; if (MsecLogindex>=LOG_SIZE) MsecLogindex = 0; } //========================== if (MotorId >= NUM_OF_MOTORS) return -1; MotorActivity++; MotorInfo.Callback = Callback; MotorInfo.Data = Data; MotorInfo.Length = Length; MotorInfo.DataRequired = false; if (MotorsMsgQ[MotorId] != NULL) return Mailbox_post(MotorsMsgQ[MotorId] , &MotorInfo, BIOS_NO_WAIT); else return false; } int32_t MillisecReadFromMotor(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { MillisecMotorDataStruc MotorInfo = {0}; if (MotorId >= NUM_OF_MOTORS) return -1; //========================== if ((MotorId == HARDWARE_MOTOR_TYPE__MOTO_WINDER)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_RDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_LDRIVING)|| (MotorId == HARDWARE_MOTOR_TYPE__MOTO_SCREW)) { MSBacklog[MsecLogindex]=Data; Motor_Id[MsecLogindex]=MotorId; MSTick[MsecLogindex]=msec_millisecondCounter; MsecLogindex++; if (MsecLogindex>=LOG_SIZE) MsecLogindex = 0; } //========================== MotorActivity++; MotorActivity++; MotorInfo.Callback = Callback; MotorInfo.Data = Data; MotorInfo.Length = Length; MotorInfo.DataRequired = true; if (MotorsMsgQ[MotorId] != NULL) return Mailbox_post(MotorsMsgQ[MotorId] , &MotorInfo, BIOS_NO_WAIT); else return false; } uint32_t MillisecLoop(uint32_t tick) { uint8_t Motor_i; TEMPERATURE_SENSOR_ID_ENUM Sensor_i; unsigned int MotorInfo = 0; static int temp=0; //call all modules Millisec functions //test dancers and speed encoders //check all callback units (state machine waiting for completion of a change) /* bool Ten_msTick, Hundred_msTick, Onesecond_Tick,O900Millisecond_Tick,Tick98,OneMinute_Tick; Ten_msTick = (tick%eTenMillisecond == 0) ?true:false; Hundred_msTick = (tick%eHundredMillisecond == 0) ?true:false; O900Millisecond_Tick = (tick%eOneSecond == 900) ?true:false; Onesecond_Tick = (tick%eOneSecond == 0) ?true:false; OneMinute_Tick = (tick%eOneMinute == 0) ?true:false; Tick98 = (tick%eHundredMillisecond == 99) ?true:false; //gather Motor data from FPGA //ROM_IntMasterDisable(); */ #ifndef EVALUATION_BOARD FPGA_GetBusy(); //load the busy motor information to all motors FPGA_Read_LS_Safty_Ind_Reg(); //Read_FPGA_GPI_Rgisters();//FPGA_Read_limit_Switches(); #endif temp += MotorActivity; if (MotorActivity) { for (Motor_i = 0;Motor_i < NUM_OF_MOTORS;Motor_i++) { if (MotorDriverResponse[Motor_i].Busy == true) { temp++; continue; } if (MotorData[Motor_i].WaitForData == true) //Read request sent, data is waiting { if (MotorGetFPGAResponse((HardwareMotorType)Motor_i,&MotorInfo) == OK) //got the data from the FPGA { MotorData[Motor_i].WaitForData = false; if (MotorData[Motor_i].Callback) MotorData[Motor_i].Callback(Motor_i,MotorInfo); } MotorActivity--; } if (SpeedSetPending[Motor_i].Active == true) { MotorSendFPGARequest((HardwareMotorType)Motor_i,SpeedSetPending[Motor_i].Data,SpeedSetPending[Motor_i].Length); MotorActivity--; SpeedSetPending[Motor_i].Active = false; if (SpeedSetPending[Motor_i].Callback) SpeedSetPending[Motor_i].Callback(Motor_i,0); } else if (Mailbox_pend(MotorsMsgQ[Motor_i] , &MotorData[Motor_i], BIOS_NO_WAIT)==true) { if (MotorSendFPGARequest((HardwareMotorType)Motor_i,MotorData[Motor_i].Data,MotorData[Motor_i].Length) == OK) //sent the data to the FPGA { if (MotorData[Motor_i].DataRequired == true) { MotorData[Motor_i].WaitForData = true; // mark the motor for data request next round } else { if (MotorData[Motor_i].Callback) MotorData[Motor_i].Callback(Motor_i,0); // call the callback to report execution } } MotorActivity--; } } } //FPGA_GetTempSensorBusy(); //int PT100Busy[MAX_MAIN_CARD_TEMPERATURE_SENSOR_ID] = {0,0,0,0,0,0,0,0,0,0}; if (PT100Activity) { for (Sensor_i = 0;Sensor_i < MAX_MAIN_CARD_TEMP_SENS_ID;Sensor_i++) { /*if (TempSensorResponse[Sensor_i].Busy == true) { PT100Busy[Sensor_i]++; continue; }*/ if (PT100Data[Sensor_i].Active == true) { if(Sensor_i < MAX_MAIN_CARD_TEMP_SENS_ID) { TemperatureSendSensorDummyClk(Sensor_i); } PT100Data[Sensor_i].Active = false; PT100Data[Sensor_i].WaitForData = true; // mark the motor for data request next round break; // one PT100 activitiy per MS } else if (PT100Data[Sensor_i].WaitForData == true) //Read request sent, data is waiting { if(Sensor_i < MAX_MAIN_CARD_TEMP_SENS_ID) { TemperatureSensorReadFromFPGA_Res(Sensor_i); //got the data from the FPGA } /*else if(Sensor_i < MAX_HEAD_CARD_TEMP_SENS_ID) - move to the function control_HeadCard_PT100 { //HeadCard_Toggle_PT100(Sensor_i); //delay?? //HeadADCPT100_SendReadDataCommand(Sensor_i); } else if(Sensor_i < MAX_WHS_CARD_TEMP_SENS_ID) { //for WHS... } else { //TBD }*/ PT100Data[Sensor_i].WaitForData = false; PT100Data[Sensor_i].SyncRequired = true; if (PT100Data[Sensor_i].Callback) PT100Data[Sensor_i].Callback(Sensor_i,MotorInfo); break; // one PT100 activitiy per MS } else if (PT100Data[Sensor_i].SyncRequired == true) { if(Sensor_i < MAX_MAIN_CARD_TEMP_SENS_ID) { TemperatureSensorSync(Sensor_i); } /*else if(Sensor_i < MAX_HEAD_CARD_TEMP_SENS_ID) - NA move to the function control_HeadCard_PT100 { //HeadADCPT100_StartSync(Sensor_i); } else if(Sensor_i < MAX_WHS_CARD_TEMP_SENS_ID) { //StartSync WHS... } else { //TBD... }*/ PT100Data[Sensor_i].SyncRequired = false; PT100Activity--; break; // one PT100 activitiy per MS } } } #ifdef HUNDRED_MICROSECONDS_DANCER_READ SaveLogData(); #else #ifdef test_RTFU_dancer test_dancer_responce_RTFU(); #else #ifdef FOUR_WINDERS Dancer_Data[HARDWARE_DANCER_0] = Read_Dancer_Position(HARDWARE_DANCER_0); Dancer_Data[HARDWARE_DANCER_1] = Read_Dancer_Position(HARDWARE_DANCER_1); Dancer_Data[HARDWARE_DANCER_2] = Read_Dancer_Position(HARDWARE_DANCER_2); Dancer_Data[HARDWARE_DANCER_3] = Read_Dancer_Position(HARDWARE_DANCER_3); Dancer_Data[HARDWARE_DANCER_4] = Read_Dancer_Position(HARDWARE_DANCER_4); #else Dancer_Data[FEEDER_DANCER] = Read_Dancer_Position(FEEDER_DANCER); Dancer_Data[POOLER_DANCER] = Read_Dancer_Position(POOLER_DANCER); Dancer_Data[WINDER_DANCER] = Read_Dancer_Position(WINDER_DANCER); #endif #endif #endif return OK; } int TemperatureSum[MAX_HEAD_CARD_TEMP_SENS_ID]; int TemperatureMin[MAX_HEAD_CARD_TEMP_SENS_ID]; int TemperatureMax[MAX_HEAD_CARD_TEMP_SENS_ID]; int TemperatureCount[MAX_HEAD_CARD_TEMP_SENS_ID]; int TemperatureCalc[MAX_HEAD_CARD_TEMP_SENS_ID]; void MillisecUpdateTemperatures (TEMPERATURE_SENSOR_ID_ENUM SensorId,int temperature) { //if(TemperatureCount[SensorId]++>=10) // TemperatureCount[SensorId] = 0; TemperatureCount[SensorId]++; if (TemperatureMax[SensorId]<temperature) TemperatureMax[SensorId]=temperature; if (TemperatureMin[SensorId]>temperature) TemperatureMin[SensorId]=temperature; TemperatureSum[SensorId]+=temperature; } int MillisecCalculateTemperatures (TEMPERATURE_SENSOR_ID_ENUM SensorId) { int calc = 0; TemperatureSum[SensorId]-=TemperatureMax[SensorId]; TemperatureSum[SensorId]-=TemperatureMin[SensorId]; calc = TemperatureSum[SensorId] / (TemperatureCount[SensorId]-2); TemperatureSum[SensorId] = 0; TemperatureCount[SensorId] = 0; TemperatureMin[SensorId] = 30000; TemperatureMax[SensorId] = -30000; return calc; } int MillisecGetTemperatures (TEMPERATURE_SENSOR_ID_ENUM SensorId) { if (SensorId > WHS_PT100_4_0X82_1) return 0; return TemperatureCalc[SensorId]; } bool RapidPressureRead = true; float PressureSum[MAX_SYSTEM_DISPENSERS]; float PressureMin[MAX_SYSTEM_DISPENSERS]; float PressureMax[MAX_SYSTEM_DISPENSERS]; float PressureCount[MAX_SYSTEM_DISPENSERS]; float PressureCalc[MAX_SYSTEM_DISPENSERS]; void MillisecUpdatePressures (int SensorId,float Pressure) { //if(PressureCount[SensorId]++>=10) // PressureCount[SensorId] = 0; PressureCount[SensorId]++; if (PressureMax[SensorId]<Pressure) PressureMax[SensorId]=Pressure; if (PressureMin[SensorId]>Pressure) PressureMin[SensorId]=Pressure; PressureSum[SensorId]+=Pressure; } float MillisecCalculatePressures (int SensorId) { float calc = 0; PressureSum[SensorId]-=PressureMax[SensorId]; PressureSum[SensorId]-=PressureMin[SensorId]; calc = PressureSum[SensorId] / (PressureCount[SensorId]-2); PressureSum[SensorId] = 0; PressureCount[SensorId] = 0; PressureMin[SensorId] = 30000; PressureMax[SensorId] = -30000; return calc; } float MillisecGetPressures (int SensorId) { if (SensorId > MAX_SYSTEM_DISPENSERS) return 0; return PressureCalc[SensorId]; } bool getRapidPressureRead(void) { return RapidPressureRead; } void setRapidPressureRead(bool value) { RapidPressureRead = value; if (GetDiagnosticMode() == Diagnostic_Extreme_Mode) RapidPressureRead = true; } uint16_t PumpCounter = 0; uint16_t realtimetest[101]; uint32_t MillisecLowLoop(uint32_t tick) { uint8_t Motor_i,Disp_i,temp; TEMPERATURE_SENSOR_ID_ENUM Sensor_i; //static int temp=0; //call all modules Millisec functions //test dancers and speed encoders //check all callback units (state machine waiting for completion of a change) bool Ten_msTick, Fifty_msTick, Hundred_msTick , m20msecTick,m70msecTick,m90msecTick, Onesecond_Tick,Tensecond_Tick,OneMinute_Tick,TenMinutes_Tick,OneHourTick,Gradient_Tick; bool O700Millisecond_Tick,O200Millisecond_Tick,O400Millisecond_Tick,O500Millisecond_Tick,O600Millisecond_Tick; //bool O100Millisecond_Tick,O200Millisecond_Tick,O400Millisecond_Tick,O500Millisecond_Tick,O600Millisecond_Tick,O800Millisecond_Tick,O900Millisecond_Tick; Ten_msTick = (tick%eTenMillisecond == 0) ?true:false; Fifty_msTick = (tick%eHundredMillisecond == 40) ?true:false; //eFiftyMillisecond Hundred_msTick = (tick%eHundredMillisecond == 0) ?true:false; m20msecTick = (tick%eHundredMillisecond == 20) ?true:false; m70msecTick = (tick%eHundredMillisecond == 70) ?true:false; m90msecTick = (tick%eHundredMillisecond == 90) ?true:false; O700Millisecond_Tick = (tick%eOneSecond == 700) ?true:false; O200Millisecond_Tick = (tick%eOneSecond == 200) ?true:false; O400Millisecond_Tick = (tick%eOneSecond == 400) ?true:false; O500Millisecond_Tick = (tick%eOneSecond == 500) ?true:false; O600Millisecond_Tick = (tick%eOneSecond == 600) ?true:false; //O800Millisecond_Tick = (tick%eOneSecond == 800) ?true:false; //O900Millisecond_Tick = (tick%eOneSecond == 900) ?true:false; Gradient_Tick = (tick%400 == 0) ?true:false; Onesecond_Tick = (tick%eOneSecond == 0) ?true:false; Tensecond_Tick = (tick%10000 == 0) ?true:false; OneMinute_Tick = (tick%eOneMinute == 0) ?true:false; TenMinutes_Tick = (tick%eTenMinutes == 0) ?true:false; OneHourTick = (tick%eOneHour == 0) ?true:false; realtimetest[(tick%1000)/10]++; //gather Motor data from FPGA //ROM_IntMasterDisable(); int StartPT100 = 0; //Screw_ENC_Velocity_to_DAC(); - for testing the screw enc if (Head_Type > HEAD_TYPE_FLAT_WITHOUT_CARD) StartPT100 = TEMP_SENSE_ANALOG_DRYER_TEMP1; if (Ten_msTick) { Speed_Data = Read_Speed_Sensor_TypeII(); //MillisecReadFromTempSensor(Sensor_Read, NULL); //if (Sensor_Read++ >= MAX_MAIN_CARD_TEMPERATURE_SENSOR_ID) Sensor_Read = 0; if(Machine_Idle_Mode == true) Machine_Idle_Breathing_Led(); Trigger_HeaterWriting(); } if (m20msecTick) { ADC0SS0Handler(); } if(Fifty_msTick) { WHS_Read_GPI_Registers(); Trigger_PT100_Read();//call every 50mSec (minimum delay 30mSec) //Set_HeadCard_PT100();//call every 50mSec (minimum delay 30mSec) } if(m70msecTick) { AlarmHandling_ControlTrigger(0,0); } if (m90msecTick) { for (Sensor_i = StartPT100;Sensor_i < MAX_HEAD_CARD_TEMP_SENS_ID;Sensor_i++) { MillisecReadFromTempSensor(Sensor_i, NULL); } } if (Hundred_msTick) { Speed_Data = Calculate_Speed_Sensor_Velocity(); #ifndef EVALUATION_BOARD Read_Buttons_Reg(); #endif /////////////////////////////////////////////////////////////////// for (Sensor_i = StartPT100;Sensor_i < MAX_HEAD_CARD_TEMP_SENS_ID;Sensor_i++) { MillisecUpdateTemperatures (Sensor_i,TemperatureSensorRead(Sensor_i)); } if (GeneralHwReady == true) { if (watchdogCriticalAlarm == false) { Control_WD(ENABLE,10); //activate heaters/dispenser watchdog, 0.5 seconds //LOG_ERROR (1111, "Control_WD"); } } if (RapidPressureRead == true) { for (Disp_i = 0;Disp_i < MAX_SYSTEM_DISPENSERS;Disp_i++) { MillisecUpdatePressures(Disp_i, CalculateDispenserPressure(Disp_i)); } ADC_TriggerCollection(); } Trigger_InputsReading(); } if (Gradient_Tick) DispensersCollectionCall(); if (O700Millisecond_Tick) { Trigger_Heater_Current_Read(); } if (O200Millisecond_Tick) { Trigger_WHS_MAX11614_Read_allADC(); FPGA_GetAllDispensersValveBusyOCD(); temp = Read_Fans_Tacho(); DrawerFansStatus = temp & 0x1F; SystemFansStatus = temp & 0xE0; } if (O400Millisecond_Tick) { for (Motor_i = 0;Motor_i < NUM_OF_MOTORS;Motor_i++) { if (Motor_i == HARDWARE_MOTOR_TYPE__MOTO_SCREW) continue; // if (isMotorConfigured(Motor_i)) MotorGetStatusFromFPGA(Motor_i); } } if ((O500Millisecond_Tick)&&(RapidPressureRead == false)) { ADC_TriggerCollection(); } if (O600Millisecond_Tick) { Trigger_WHSReadAllFanTacho (); DrierHeaterVoltageSetup(); if (RapidPressureRead == false) { for (Disp_i = 0;Disp_i < MAX_SYSTEM_DISPENSERS;Disp_i++) { CalculateDispenserPressure(Disp_i); } } } if (Onesecond_Tick) { //char Lenstr[160]; //static int Counter = 0; MachineUpdateResponseFunc(); //KeepAliveOneSecondCall(); //TemperatureListString(Lenstr); //ReportWithPackageFilter(ThreadFilter,Lenstr,__FILE__,__LINE__,(int)Counter++,RpWarning,(int) msec_millisecondCounter,0); for (Sensor_i = StartPT100;Sensor_i < MAX_HEAD_CARD_TEMP_SENS_ID;Sensor_i++) { TemperatureCalc[Sensor_i] = MillisecCalculateTemperatures ( Sensor_i); } if (RapidPressureRead == true) { for (Disp_i = 0;Disp_i < MAX_SYSTEM_DISPENSERS;Disp_i++) { PressureCalc[Disp_i] = MillisecCalculatePressures(Disp_i); } } if (WHS_Type == WHS_TYPE_NEW) { //Trigger_WHS_PT100_Read_All(); WHS_Blower_Avarege(HEAD_FLOW_METER); WHS_Blower_Avarege(DRIER_FLOW_METER); WHS_Start_Blower_Control_Closed_Loop (); /* static uint8_t Whs_emptying_cycle = 0; // #warning TBD need to define the timing if(Whs_emptying_cycle >= 2) { waste_seq_step1();// include 1Sec delay Whs_emptying_cycle = 0; } else { Whs_emptying_cycle++; } */ } //call waste state machine Waste_StateMachine_OneSecond_Call(); //call IFS state machine midTankStateMachine(); } if (Tensecond_Tick) { //Trigger_MidTank_Pressure_Read(); for (Disp_i = 0;Disp_i < MAX_SYSTEM_DISPENSERS;Disp_i++) { Read_MidTank_Pressure_Sensor(Disp_i); } } if (OneMinute_Tick) { // MachineUpdateResponseFunc(); /* for (Motor_i = 0;Motor_i < NUM_OF_MOTORS;Motor_i++) { if (Motor_i == HARDWARE_MOTOR_TYPE__MOTO_SCREW) continue; // if (isMotorConfigured(Motor_i)) MotorGetStatusFromFPGA(Motor_i); }*/ midtankDisplay = 1-midtankDisplay; /*if (WHS_Type == WHS_TYPE_UNKNOWN) Gas_PPM_Info = Calculate_Gas_Power_Consumption();*/ // ReportWithPackageFilter(ThreadFilter,"waste tank calculate level",__FILE__,__LINE__,(int)(GetWHSWasteTankLevelMiliLiter()*1000),RpWarning,(int) msec_millisecondCounter,0); //Trigger_WHS_MAX11614_Read_allADC(); Trigger_WHS_MAX11614_Read_Gas_Sensor(); #ifdef CONTROL_DEBUG ResetControlTime(); #endif } if (TenMinutes_Tick) { /*if (WHS_Type == WHS_TYPE_NEW) { waste_seq_step1();// include 1Sec delay <- to open !!!! }*/ } if (OneHourTick) { #define PUMP_LIMIT 4 PumpCounter++; if (PumpCounter>=PUMP_LIMIT) { PumpActivation(900); PumpCounter = 0; } MidTankReading(); if (WHS_Type == WHS_TYPE_NEW) { waste_seq_step1();// include 1Sec delay <- to open !!!! } //Trigger_WHS_MAX11614_Read_Gas_Sensor(); } //ROM_IntMasterEnable(); return OK; } /****************************************************************************** * ======== messageTsk ======== * Task for this function is created statically. See the project's .cfg file. * this message task is created statically in system initialization, ******************************************************************************/ void MillisecTask(UArg arg0, UArg arg1) { MillisecMessageStruc MillisecMessage; //char str[60]; //uint16_t length; //Clock_setTimeout(HostKAClock, 1000); //Clock_start(HostKAClock); //MillisecInit(); Millisecond_Task_Handle = Task_self(); while(1) { Mailbox_pend(MillisecMsgQ , &MillisecMessage, BIOS_WAIT_FOREVER); switch (MillisecMessage.messageId) { case OneMillisec: MillisecLoop(MillisecMessage.tick); break; default: break; } } } /****************************************************************************** * ======== messageTsk ======== * Task for this function is created statically. See the project's .cfg file. * this message task is created statically in system initialization, ******************************************************************************/ void MillisecLowTask(UArg arg0, UArg arg1) { MillisecMessageStruc MillisecLowMessage; //char str[60]; //uint16_t length; //Clock_setTimeout(HostKAClock, 1000); //Clock_start(HostKAClock); //MillisecInit(); //Millisecond_Task_Handle = Task_self(); while(1) { Mailbox_pend(TenMillisecMsgQ , &MillisecLowMessage, BIOS_WAIT_FOREVER); switch (MillisecLowMessage.messageId) { case OneMillisec: MillisecLowLoop(MillisecLowMessage.tick); break; default: break; } } } /*uint32_t getMotorStatusData(int MotorId) { assert (MotorId < NUM_OF_MOTORS); return MotorStatus_Data[MotorId]; }*/ /*uint32_t getMotorSpeedData(int MotorId) { assert (MotorId < NUM_OF_MOTORS); return MotorSpeed_Data[MotorId]; } */ /*uint32_t getTemperatureSensorData(int SensorId) { assert (SensorId < MAX_MAIN_CARD_TEMPERATURE_SENSOR_ID); return TemperatureSensor_Data[SensorId]; }*/ /*uint32_t getADCData(int DeviceId) { assert (DeviceId < MAX_ADC_DEVICES); return ADC_Data[DeviceId]; }*/ float getSensorSpeedData(void) { return Speed_Data; } uint32_t getDrawerFansStatus(void) { return DrawerFansStatus; } uint8_t getGasReading(void) { return Gas_PPM_Info; } uint32_t getSystemFansStatus(void) { return SystemFansStatus; } #ifdef HUNDRED_MICROSECONDS_DANCER_READ uint32_t DancerData[NUM_OF_DANCERS]; uint32_t Control_Read_Dancer_Position(HardwareDancerType DancerId, uint32_t Parameter1, uint32_t Parameter2) { return DancerData[DancerId]; } uint32_t dancer1; uint32_t dancer2; uint32_t dancer3; uint32_t dancer1sum; uint32_t dancer2sum; uint32_t dancer3sum; uint32_t dancer_count; /*-----------------------*/ uint32_t StoreBuffer[2][128]; //char * StoreBuffer[2][512]; /*-----------------------*/ int StoreBufferId = 0; int StoreBufferCounter=0; uint32_t BufferCounter=0xEEEEEEEE; bool storeData=false; uint8_t len=0; void HundredMicroTimerInterrupt(int ARG0) { ROM_IntMasterDisable(); ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt if (MillisecRestart == true) { ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,HIGH_TASK_FREQUENCY); } else { ROM_TimerDisable(Millisec_timerBase,TIMER_A); ROM_IntMasterEnable(); return; } dancer1 = Read_Dancer_Position(WINDER_DANCER); dancer2 = Read_Dancer_Position(POOLER_DANCER); dancer3 = Read_Dancer_Position(FEEDER_DANCER); //data store - logging //double buffer switch /*-----------------------*/ if (StoreBufferCounter>125) //if (StoreBufferCounter>490) /*-----------------------*/ { StoreBufferId = 1-StoreBufferId;//switch buffer StoreBufferCounter=0; storeData = true; } //double buffer initialize /*-----------------------*/ if (StoreBufferCounter==0) { StoreBuffer[StoreBufferId][StoreBufferCounter] = BufferCounter++; StoreBufferCounter++; } /*-----------------------*/ //store data /*-----------------------*/ StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer1; StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer2; StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer3; /*-----------------------*/ //len = usprintf(&StoreBuffer[StoreBufferId][StoreBufferCounter], "%d %d %d", dancer1[dancer_count],dancer2[dancer_count],dancer3[dancer_count]); //StoreBufferCounter+=(len+1); /*-----------------------*/ dancer1sum+=dancer1; dancer2sum+=dancer2; dancer3sum+=dancer3; dancer_count++; if (dancer_count == 10) { DancerData[WINDER_DANCER] = dancer1sum/dancer_count; DancerData[POOLER_DANCER] = dancer2sum/dancer_count; DancerData[FEEDER_DANCER] = dancer3sum/dancer_count; dancer_count = 0; dancer1sum = 0; dancer2sum = 0; dancer3sum = 0; OneMilliSecondMillisecInterrupt(ARG0); } ROM_IntMasterEnable(); return ; } char MillisecPath[50] = "0://SysInfo//Millisec.txt"; FIL *FileHandle; void SaveLogData(void) { uint32_t WrittenBytes = 0; int BufferID = 1- StoreBufferId; if (storeData == true) { if (FileHandle) { f_write(FileHandle,StoreBuffer[BufferID],512,&WrittenBytes ); storeData = false; } } } void MillisecLogInit(void) { FRESULT Fresult = FR_OK; ROM_IntMasterDisable(); BufferCounter = 0; FileHandle = my_malloc(sizeof(FIL)); if (FileHandle == 0) Fresult = FR_DENIED; else Fresult = f_open(FileHandle,MillisecPath,FA_WRITE | FA_OPEN_ALWAYS|FA_CREATE_ALWAYS); ROM_IntMasterEnable(); return ; } void MillisecLogClose(void) { FRESULT Fresult = FR_OK; if (FileHandle == 0) Fresult = FR_DENIED; else { storeData = false; ROM_IntMasterDisable(); Fresult = f_close(FileHandle); my_free(FileHandle); FileHandle = 0; ROM_IntMasterEnable(); } return ; } #endif void MillisecInterrupt(UArg arg0) { #ifdef HUNDRED_MICROSECONDS_DANCER_READ HundredMicroTimerInterrupt(arg0); #else OneMilliSecondMillisecInterrupt(arg0); #endif }