Mercurial > public > ostc4
annotate Common/Inc/data_central.h @ 740:5078da3845c0
Added button lock after wakeup in surface mode:
During setup of diveequipment the OSTC4 is sometimes operated unintended (e.g. while equipping the jaket). To avoid this it is now possible to activate a button lock in the button lock sensitivity menu. The OSTC4 will then wakeup as usuall but if the diver wants to oerate the menus he has to press the buttons in a certain order. The button to be pressed is indicated by a blue bar. The button lock is deactivated in dive mode.
author | Ideenmodellierer |
---|---|
date | Thu, 02 Feb 2023 17:35:38 +0100 |
parents | 7b0e020513e3 |
children | b392524753fb |
rev | line source |
---|---|
38 | 1 /////////////////////////////////////////////////////////////////////////////// |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Common/Inc/data_central.h | |
5 /// \brief Common Dadatypes Declarations | |
6 /// \author Heinrichs Weikamp | |
7 /// \date 2018 | |
8 /// | |
9 /// $Id$ | |
10 /////////////////////////////////////////////////////////////////////////////// | |
11 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh | |
12 /// | |
13 /// This program is free software: you can redistribute it and/or modify | |
14 /// it under the terms of the GNU General Public License as published by | |
15 /// the Free Software Foundation, either version 3 of the License, or | |
16 /// (at your option) any later version. | |
17 /// | |
18 /// This program is distributed in the hope that it will be useful, | |
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 /// GNU General Public License for more details. | |
22 /// | |
23 /// You should have received a copy of the GNU General Public License | |
24 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 ////////////////////////////////////////////////////////////////////////////// | |
26 | |
27 #ifndef DATA_CENTRAL_H | |
28 #define DATA_CENTRAL_H | |
29 | |
30 #include <stdint.h> | |
31 | |
32 #include "settings.h" | |
33 #include "stm32f4xx_hal.h" | |
672 | 34 #include "configuration.h" |
38 | 35 |
36 #define BUEHLMANN_STRUCT_MAX_GASES 11 | |
37 #define BUEHLMANN_STRUCT_MAX_ASCENDRATES 3 | |
38 #define DECOINFO_STRUCT_MAX_STOPS 50 | |
39 | |
40 #define false 0 | |
41 #define true 1 | |
42 | |
728
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
43 #define EXT_INTERFACE_SENSOR_CNT (5u) /* 5 sensors may be connected to the external interface */ |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
44 |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
45 |
38 | 46 /* Helper structs ------------------------------------------------------------*/ |
47 | |
48 //struct SGas | |
49 //contains gasinfos of single gas for deco calculation | |
50 typedef struct | |
51 { | |
52 uint8_t nitrogen_percentage; | |
53 uint8_t helium_percentage; | |
54 uint8_t setPoint_cbar; | |
55 uint8_t change_during_ascent_depth_meter_otherwise_zero; | |
56 uint8_t GasIdInSettings; | |
662 | 57 uint8_t AppliedDiveMode; |
58 float pscr_factor; | |
38 | 59 } SGas; |
60 | |
61 typedef struct | |
62 { | |
63 float use_from_depth_bar; | |
64 float rate_bar_per_minute; | |
65 } SAscentrate; | |
66 | |
67 | |
68 typedef struct{ | |
69 uint32_t date_rtc_dr; | |
70 uint32_t time_rtc_tr; | |
71 int32_t value_int32; | |
72 } SDeviceLine; | |
73 | |
74 | |
75 typedef struct | |
76 { | |
77 uint16_t ageInMilliSeconds; | |
78 uint8_t numberOfBytes; | |
79 uint8_t status; | |
80 uint8_t data[12]; | |
81 } SDataWireless; | |
82 | |
662 | 83 |
84 typedef struct | |
85 { | |
86 uint16_t CO2_ppm; | |
87 uint16_t signalStrength; | |
88 } SCO2Sensor; | |
89 | |
38 | 90 /* Main structs -------------------------------------------------------------*/ |
91 | |
92 | |
93 //struct SDecoinfo | |
94 //contains result of deco calculation | |
95 typedef struct | |
96 { | |
97 unsigned short output_stop_length_seconds[DECOINFO_STRUCT_MAX_STOPS]; | |
98 int output_time_to_surface_seconds; | |
99 int output_ndl_seconds; | |
100 float output_ceiling_meter; | |
247
3949781096d4
feature: Relative GF to Saturation renames
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
101 float super_saturation; |
38 | 102 uint32_t tickstamp; |
103 } SDecoinfo; | |
104 | |
105 | |
106 typedef struct | |
107 { | |
108 //crushing pressure | |
109 //in/out | |
110 float max_crushing_pressure_he[16]; | |
111 float max_crushing_pressure_n2[16]; | |
112 // | |
113 float run_time_start_of_deco_zone_save; | |
114 float depth_start_of_deco_zone_save; | |
115 float max_first_stop_depth_save; | |
116 short decomode_vpm_plus_conservatism_last_dive; | |
117 _Bool deco_zone_reached; | |
118 //State variables for repetetive dives | |
119 _Bool repetitive_variables_not_valid; | |
120 float adjusted_crushing_pressure_he[16]; | |
121 float adjusted_crushing_pressure_n2[16]; | |
122 float adjusted_critical_radius_he[16]; | |
123 float adjusted_critical_radius_n2[16]; | |
124 float initial_allowable_gradient_he[16]; | |
125 float initial_allowable_gradient_n2[16]; | |
126 float max_actual_gradient[16]; | |
127 } SVpm; | |
128 | |
129 typedef struct | |
130 { | |
131 _Bool repetitive_variables_not_valid; | |
132 _Bool is_data_from_RTE_CPU; | |
133 _Bool spare2; | |
134 _Bool spare3; | |
135 float adjusted_crushing_pressure_he[16]; | |
136 float adjusted_crushing_pressure_n2[16]; | |
137 float adjusted_critical_radius_he[16]; | |
138 float adjusted_critical_radius_n2[16]; | |
139 float initial_allowable_gradient_he[16]; | |
140 float initial_allowable_gradient_n2[16]; | |
141 float max_actual_gradient[16]; | |
142 } SVpmRepetitiveData; | |
143 | |
144 //struct SDevice | |
145 //contains information about usage | |
146 typedef struct | |
147 { | |
148 SDeviceLine batteryChargeCycles; | |
149 SDeviceLine batteryChargeCompleteCycles; | |
150 SDeviceLine temperatureMinimum; | |
151 SDeviceLine temperatureMaximum; | |
152 SDeviceLine depthMaximum; | |
153 SDeviceLine diveCycles; | |
154 SDeviceLine voltageMinimum; | |
155 SDeviceLine hoursOfOperation; | |
156 SDeviceLine diveAccident; | |
157 } SDevice; | |
158 | |
159 /* | |
160 typedef struct | |
161 { | |
162 SDevice device; | |
163 SVpmRepetitiveData vpm; | |
164 } SDeviceState; | |
165 */ | |
166 | |
167 /* struct SLifeData | |
168 * contains data all actual data (pressure, stuturation, etc. as received from second ship | |
169 * and has actualGas to be send to Small CPU (second chip) | |
170 * contains data calculated from actual data after receiption from Small CPU | |
171 */ | |
172 typedef struct | |
173 { | |
174 /* from Small CPU */ | |
175 int32_t dive_time_seconds; | |
176 int32_t dive_time_seconds_without_surface_time; | |
177 uint32_t surface_time_seconds; | |
178 float pressure_ambient_bar; | |
179 float pressure_surface_bar; | |
180 float tissue_nitrogen_bar[16]; | |
181 float tissue_helium_bar[16]; | |
182 float cns; | |
183 float otu; | |
184 uint16_t desaturation_time_minutes; | |
185 uint16_t no_fly_time_minutes; | |
186 float temperature_celsius; | |
187 float compass_heading; | |
188 float compass_roll; | |
189 float compass_pitch; | |
190 int16_t compass_DX_f; | |
191 int16_t compass_DY_f; | |
192 int16_t compass_DZ_f; | |
193 uint16_t counterSecondsShallowDepth; | |
194 float ascent_rate_meter_per_min; | |
195 uint32_t timeBinaryFormat; | |
196 uint32_t dateBinaryFormat; | |
197 float battery_voltage; | |
198 float battery_charge; | |
199 uint16_t ambient_light_level; | |
200 SDataWireless wireless_data[4]; | |
201 uint8_t buttonPICdata[4]; | |
662 | 202 SCO2Sensor CO2_data; |
714
045ff7800501
Added customizable data area for specific sensor data:
Ideenmodellierer
parents:
672
diff
changeset
|
203 uint8_t extIf_sensor_Id; |
045ff7800501
Added customizable data area for specific sensor data:
Ideenmodellierer
parents:
672
diff
changeset
|
204 uint8_t UINT64ALIGNMENT; /* If your program crash check if you changed something in the life data structure ! The external sensor may contain a 64 bit ID */ |
045ff7800501
Added customizable data area for specific sensor data:
Ideenmodellierer
parents:
672
diff
changeset
|
205 uint8_t extIf_sensor_data[32]; |
728
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
206 uint8_t extIf_sensor_map[EXT_INTERFACE_SENSOR_CNT]; |
38 | 207 |
208 /* by create DiveSettings() and by setActualGas() | |
209 * is send to Small CPU2 for nitrogen calculation | |
210 * includes setpoint information | |
211 */ | |
212 SGas actualGas; | |
213 uint8_t lastDiluent_GasIdInSettings; | |
214 uint8_t gas_temp2; | |
215 | |
216 /* calculated by DataEX_copy_to_LifeData() | |
217 bottle_bar array size is made like this to have multiples of 32bit | |
218 */ | |
219 float ppO2; | |
220 float depth_meter; | |
221 float max_depth_meter; | |
222 float average_depth_meter; | |
223 float apnea_total_max_depth_meter; | |
224 float apnea_last_max_depth_meter; | |
225 int32_t apnea_last_dive_time_seconds; | |
226 uint16_t bottle_bar[2 * NUM_GASES +1]; | |
227 uint16_t bottle_bar_age_MilliSeconds[2 * NUM_GASES + 1]; | |
228 uint16_t apnea_total_counter; | |
229 | |
230 /* control of DataEX_copy_to_LifeData() | |
231 */ | |
232 uint8_t boolResetAverageDepth; | |
233 uint8_t bool_temp1; | |
234 uint8_t bool_temp2; | |
235 | |
236 /* from local sensor or direct HUD communication */ | |
237 //pp O2 Sensor | |
238 float ppO2Sensor_bar[3]; | |
239 float sensorVoltage_mV[3]; | |
240 float HUD_battery_voltage_V; | |
662 | 241 |
242 /* for PSCR Mode */ | |
243 float ppo2Simulated_bar; | |
38 | 244 } SLifeData; |
245 | |
246 | |
247 typedef struct | |
248 { | |
249 uint16_t tissue_nitrogen_desaturation_time_minutes[16]; | |
250 uint16_t tissue_helium_desaturation_time_minutes[16]; | |
251 } SLifeData2; | |
252 | |
253 | |
254 typedef struct | |
255 { | |
256 //warnings | |
257 int8_t decoMissed; | |
258 int8_t aGf; | |
259 int8_t ascentRateHigh; | |
260 int8_t ppO2Low; | |
261 int8_t ppO2High; | |
262 int8_t cnsHigh; | |
263 int8_t slowWarning; | |
264 int8_t lowBattery; | |
265 int8_t numWarnings; | |
266 int8_t sensorLinkLost; | |
267 int8_t sensorOutOfBounds[3]; | |
268 int8_t betterGas; | |
269 int8_t fallback; | |
270 int8_t betterSetpoint; | |
478
58200d756365
Development option only: Show Pressure update for a short time in the custom field (as warning)
ideenmodellierer
parents:
309
diff
changeset
|
271 #ifdef ENABLE_BOTTLE_SENSOR |
58200d756365
Development option only: Show Pressure update for a short time in the custom field (as warning)
ideenmodellierer
parents:
309
diff
changeset
|
272 int8_t newPressure; |
58200d756365
Development option only: Show Pressure update for a short time in the custom field (as warning)
ideenmodellierer
parents:
309
diff
changeset
|
273 #endif |
38 | 274 } SWarnings; |
275 | |
276 | |
277 typedef struct | |
278 { | |
279 //Events logbook only | |
280 int16_t manualMarker; | |
281 int16_t gasChange; | |
282 int16_t info_GasChange; | |
283 int16_t setpointChange; | |
284 int16_t info_SetpointChange; | |
281 | 285 int16_t manualGasSet; |
286 int16_t info_manualGasSetHe; | |
287 int16_t info_manualGasSetO2; | |
38 | 288 int16_t bailout; |
289 int16_t info_bailoutHe; | |
290 int16_t info_bailoutO2; | |
291 } SEvents; | |
292 | |
293 | |
294 | |
295 //struct SDiveSettings | |
296 //contains settings necessary for deco calculation | |
297 typedef struct | |
298 { | |
299 float last_stop_depth_bar; | |
300 float input_next_stop_increment_depth_bar; | |
301 float input_second_to_last_stop_depth_bar; | |
302 float ascentRate_meterperminute; | |
303 uint8_t diveMode; /* OC, CC, .. */ | |
304 uint8_t CCR_Mode; | |
305 uint8_t future_TTS_minutes; | |
306 | |
307 /* If beginning of dive is CCR than ccrOption is set true | |
308 * true allows returning from bailout (OC) back to CCR | |
309 * true activates CC gas and setpoint pages in dive menu | |
310 */ | |
311 uint8_t ccrOption; | |
312 uint8_t fallbackOption; | |
313 uint8_t ppo2sensors_deactivated; | |
314 | |
315 split2x4_Type deco_type; /* GF or VPM for standard and alternative seperate */ | |
316 | |
317 /* VPM conservatism, do not change during dive!!! | |
318 * do not change in between dives otherwise repetitve dive is not possible | |
319 */ | |
320 uint8_t vpm_conservatism; | |
321 | |
322 /* B�hlmann GF | |
323 * and a variable that is used by Buehlmann during the dive | |
324 * to remember the position of GF low during ascend | |
325 */ | |
326 uint8_t gf_high; | |
327 uint8_t gf_low; | |
328 | |
329 /* copy of the Settings GasList and SetpintList | |
330 * that can be modified during the dive | |
331 * especially gases can be actived and deactivated | |
332 * gas[0] and setpoint[0] are the special ones configurable during the dive | |
333 */ | |
334 SGasLine gas[1 + (2*NUM_GASES)]; | |
335 SSetpointLine setpoint[1 + NUM_GASES]; | |
336 | |
337 /* List of GasChanges in the actual order | |
338 * this is necessary for VPM and Buehlmann and will be created on start of each calculation | |
339 */ | |
340 SGas decogaslist[BUEHLMANN_STRUCT_MAX_GASES]; // unused filled with 0xFF | |
341 | |
342 /* | |
343 */ | |
344 float internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero; | |
345 uint16_t compassHeading; | |
662 | 346 |
347 uint8_t pscr_o2_drop; | |
348 uint8_t pscr_lung_ratio; | |
38 | 349 } SDiveSettings; |
350 | |
351 enum CHARGE_STATUS{ | |
352 CHARGER_off = 0, | |
353 CHARGER_running, | |
354 CHARGER_complete, | |
355 CHARGER_lostConnection | |
356 }; | |
357 | |
358 typedef struct | |
359 { | |
360 SDiveSettings diveSettings; | |
361 SLifeData lifeData; | |
362 SVpm vpm; | |
363 SEvents events; | |
364 SWarnings warnings; | |
365 SDecoinfo decolistVPM; | |
366 SDecoinfo decolistFutureVPM; | |
367 SDecoinfo decolistBuehlmann; // | |
368 SDecoinfo decolistFutureBuehlmann; | |
369 uint8_t mode; /* hw for sleep, surface, dive, .. */ | |
370 uint8_t chargeStatus; | |
371 uint8_t data_old__lost_connection_to_slave; | |
372 | |
373 uint32_t pressure_uTick_new; | |
374 uint32_t compass_uTick_new; | |
375 | |
376 uint32_t pressure_uTick_old; | |
377 uint32_t compass_uTick_old; | |
378 | |
379 uint32_t pressure_uTick_local_new; | |
380 uint32_t compass_uTick_local_new; | |
381 | |
382 uint8_t cnsHigh_at_the_end_of_dive; | |
383 uint8_t decoMissed_at_the_end_of_dive; | |
384 | |
385 uint8_t sensorErrorsRTE; | |
386 | |
387 uint8_t lastKnownBatteryPercentage; | |
388 } SDiveState; | |
389 | |
390 | |
391 typedef struct{ | |
392 uint8_t bit0:1; | |
393 uint8_t bit1:1; | |
394 uint8_t bit2:1; | |
395 uint8_t bit3:1; | |
396 uint8_t bit4:1; | |
397 uint8_t bit5:1; | |
398 uint8_t bit6:1; | |
399 uint8_t bit7:1; | |
400 } ubit8_t; | |
401 | |
402 typedef union{ | |
403 ubit8_t ub; | |
404 uint8_t uw; | |
405 } bit8_Type; | |
406 | |
407 extern SDiveState stateSim; | |
408 extern SDiveState stateDeco; | |
409 extern uint8_t decoLock; | |
271
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
410 extern const SDiveState *stateUsed; |
1303747b5ba2
cleanup: also write gas and setpoint changes in simulator mode
Jan Mulder <jlmulder@xs4all.nl>
parents:
270
diff
changeset
|
411 extern SDiveState *stateUsedWrite; |
38 | 412 |
413 enum DECO_LOCK{ | |
414 DECO_CALC_running, | |
415 DECO_CALC_ready, | |
416 DECO_CALC_FINSHED_Buehlmann, | |
417 DECO_CALC_FINSHED_vpm, | |
418 DECO_CALC_FINSHED_FutureBuehlmann, | |
419 DECO_CALC_FINSHED_Futurevpm, | |
420 DECO_CALC_init_as_is_start_of_dive, | |
421 DECO_CALC_undefined | |
422 }; | |
423 | |
728
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
424 typedef enum |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
425 { |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
426 SENSOR_NONE, |
733 | 427 SENSOR_OPTIC, |
728
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
428 SENSOR_ANALOG, |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
429 SENSOR_DIGO2, |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
430 SENSOR_CO2, |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
431 SENSOR_END |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
432 } externalInterfaceSensorType; |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
433 |
5143e927219f
Added sensor map to Firmware <=> RTE inferface:
Ideenmodellierer
parents:
714
diff
changeset
|
434 |
38 | 435 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow); |
436 | |
437 void set_stateUsedToSim(void); | |
438 void set_stateUsedToReal(void); | |
439 | |
440 _Bool is_stateUsedSetToSim(void); | |
441 | |
442 const SDiveState * stateRealGetPointer(void); | |
443 const SDiveState * stateSimGetPointer(void); | |
444 SDiveState * stateRealGetPointerWrite(void); | |
445 SDiveState * stateSimGetPointerWrite(void); | |
446 const SDevice * stateDeviceGetPointer(void); | |
447 SDevice * stateDeviceGetPointerWrite(void); | |
448 const SVpmRepetitiveData * stateVpmRepetitiveDataGetPointer(void); | |
449 SVpmRepetitiveData * stateVpmRepetitiveDataGetPointerWrite(void); | |
450 | |
451 void UpdateLifeDataTest(SDiveState * diveState); | |
452 | |
453 void setSimulationValues(int _ascent_rate_meter_per_min, int _descent_rate_meter_per_min, int _max_depth, int _bottom_time ); | |
454 | |
455 void createDiveSettings(void); | |
456 void copyDiveSettingsToSim(void); | |
457 void copyVpmRepetetiveDataToSim(void); | |
458 //void fallbackToFixedSetpoints(SLifeData *lifeData); | |
459 void setActualGasFirst(SLifeData *lifeData); | |
460 void setActualGasAir(SLifeData *lifeData); | |
461 void setActualGas(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar); | |
462 void setActualGas_ExtraGas(SLifeData *lifeData, uint8_t oxygen, uint8_t helium, uint8_t setpoint_cbar); | |
463 void setActualGas_DM(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar); | |
464 void setWeekday(RTC_DateTypeDef *sDate); | |
465 void setDate(RTC_DateTypeDef Sdate); | |
466 void setTime(RTC_TimeTypeDef Stime); | |
467 void setBatteryPercentage(uint8_t newChargePercentage); | |
468 void setButtonResponsiveness(uint8_t *ButtonSensitivyList); | |
469 void calibrateCompass(void); | |
539
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
478
diff
changeset
|
470 void compass_Inertia(float newHeading); |
d784f281833a
Added inertia simulation for compass heading:
Ideenmodellierer
parents:
478
diff
changeset
|
471 float compass_getCompensated(); |
38 | 472 void clearDeco(void); |
473 void translateDate(uint32_t datetmpreg, RTC_DateTypeDef *sDate); | |
474 void translateTime(uint32_t tmpreg, RTC_TimeTypeDef *sTime); | |
475 void updateSetpointStateUsed(void); | |
476 | |
477 uint8_t calc_MOD(uint8_t gasId); | |
478 uint8_t calc_MinOD(uint8_t gasId); | |
479 //float calc_ppO2(float input_ambient_pressure_bar, SGas* pGas); | |
480 int current_second(void); | |
481 _Bool vpm_crush(SDiveState* pDiveState); | |
482 _Bool deco_zone_reached(void); | |
270
2e58a4094770
feature, debug: make simulator write a logbook entry
Jan Mulder <jlmulder@xs4all.nl>
parents:
247
diff
changeset
|
483 void resetEvents(const SDiveState *pStateUsed); |
38 | 484 |
485 uint32_t crc32c_checksum(uint8_t* message, uint16_t length, uint8_t* message2, uint16_t length2); | |
486 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words); | |
487 uint32_t CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words); | |
488 | |
489 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData); | |
490 | |
662 | 491 uint8_t isLoopMode(uint8_t Mode); |
492 | |
38 | 493 #endif // DATA_CENTRAL_H |